diff --git a/demo/GraniteDemo.vala b/demo/GraniteDemo.vala
index 19cdb557a..bbaf4a510 100644
--- a/demo/GraniteDemo.vala
+++ b/demo/GraniteDemo.vala
@@ -48,40 +48,61 @@ public class Granite.Demo : Gtk.Application {
main_stack.add_titled (dialogs_view, "dialogs", "Dialogs");
main_stack.add_titled (application_view, "application", "Application");
- var stack_sidebar = new Gtk.StackSidebar ();
- stack_sidebar.stack = main_stack;
+ var gtk_settings = Gtk.Settings.get_default ();
+
+ var mode_switch = new Granite.ModeSwitch.from_icon_name (
+ "display-brightness-symbolic",
+ "weather-clear-night-symbolic"
+ ) {
+ primary_icon_tooltip_text = ("Light background"),
+ secondary_icon_tooltip_text = ("Dark background"),
+ valign = CENTER
+ };
+ mode_switch.bind_property ("active", gtk_settings, "gtk-application-prefer-dark-theme", BIDIRECTIONAL);
+
+ var end_header = new Gtk.HeaderBar () {
+ show_title_buttons = false
+ };
+ end_header.add_css_class (Granite.STYLE_CLASS_FLAT);
+ end_header.pack_end (new Gtk.WindowControls (END));
+ end_header.pack_end (mode_switch);
+
+ var end_box = new Gtk.Box (VERTICAL, 0);
+ end_box.append (end_header);
+ end_box.append (main_stack);
+
+ var start_header = new Gtk.HeaderBar () {
+ show_title_buttons = false,
+ title_widget = new Gtk.Label ("")
+ };
+ start_header.add_css_class (Granite.STYLE_CLASS_FLAT);
+ start_header.pack_start (new Gtk.WindowControls (START));
+
+ var stack_sidebar = new Gtk.StackSidebar () {
+ stack = main_stack,
+ vexpand = true
+ };
+
+ var start_box = new Gtk.Box (VERTICAL, 0);
+ start_box.append (start_header);
+ start_box.append (stack_sidebar);
+ start_box.add_css_class (Granite.STYLE_CLASS_SIDEBAR);
var paned = new Gtk.Paned (Gtk.Orientation.HORIZONTAL) {
- start_child = stack_sidebar,
- end_child = main_stack,
+ start_child = start_box,
+ end_child = end_box,
resize_start_child = false,
shrink_end_child = false,
shrink_start_child = false
};
- var gtk_settings = Gtk.Settings.get_default ();
-
- var mode_switch = new Granite.ModeSwitch.from_icon_name (
- "display-brightness-symbolic",
- "weather-clear-night-symbolic"
- );
- mode_switch.primary_icon_tooltip_text = ("Light background");
- mode_switch.secondary_icon_tooltip_text = ("Dark background");
- mode_switch.valign = Gtk.Align.CENTER;
- mode_switch.bind_property ("active", gtk_settings, "gtk-application-prefer-dark-theme", GLib.BindingFlags.BIDIRECTIONAL);
-
var granite_settings = Granite.Settings.get_default ();
gtk_settings.gtk_application_prefer_dark_theme = granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK;
- var headerbar = new Gtk.HeaderBar ();
- headerbar.add_css_class ("default-decoration");
- headerbar.show_title_buttons = true;
- headerbar.pack_end (mode_switch);
-
window.child = paned;
window.set_default_size (900, 600);
window.set_size_request (750, 500);
- window.set_titlebar (headerbar);
+ window.titlebar = new Gtk.Grid () { visible = false };
window.title = "Granite Demo";
add_window (window);
diff --git a/lib/Icons/icons.gresource.xml b/lib/Icons/icons.gresource.xml
index 62f5a346a..bc0008839 100644
--- a/lib/Icons/icons.gresource.xml
+++ b/lib/Icons/icons.gresource.xml
@@ -25,8 +25,8 @@
scalable/adw-tab-icon-missing-symbolic.svg
scalable/adw-tab-overflow-symbolic.svg
- scalable/check-active-symbolic.svg
- scalable/check-mixed-symbolic.svg
+ scalable/check-checked.svg
+ scalable/check-indeterminate.svg
scalable/pager-checked-symbolic.svg
diff --git a/lib/Icons/scalable/check-active-symbolic.svg b/lib/Icons/scalable/check-active-symbolic.svg
deleted file mode 100644
index fb711dbb3..000000000
--- a/lib/Icons/scalable/check-active-symbolic.svg
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
diff --git a/lib/Icons/scalable/check-checked.svg b/lib/Icons/scalable/check-checked.svg
new file mode 100644
index 000000000..7647fb890
--- /dev/null
+++ b/lib/Icons/scalable/check-checked.svg
@@ -0,0 +1,30 @@
+
+
diff --git a/lib/Icons/scalable/check-indeterminate.svg b/lib/Icons/scalable/check-indeterminate.svg
new file mode 100644
index 000000000..014197d67
--- /dev/null
+++ b/lib/Icons/scalable/check-indeterminate.svg
@@ -0,0 +1,25 @@
+
+
diff --git a/lib/Icons/scalable/check-mixed-symbolic.svg b/lib/Icons/scalable/check-mixed-symbolic.svg
deleted file mode 100644
index 745126524..000000000
--- a/lib/Icons/scalable/check-mixed-symbolic.svg
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
diff --git a/lib/Styles/Gtk/Arrow.scss b/lib/Styles/Gtk/Arrow.scss
new file mode 100644
index 000000000..eceefa7a1
--- /dev/null
+++ b/lib/Styles/Gtk/Arrow.scss
@@ -0,0 +1,21 @@
+arrow {
+ -gtk-icon-source: -gtk-icontheme("pan-down-symbolic");
+ min-height: rem(16px);
+ min-width: rem(16px);
+
+ &.down {
+ -gtk-icon-source: -gtk-icontheme("pan-down-symbolic");
+ }
+
+ &.left {
+ -gtk-icon-source: -gtk-icontheme("pan-start-symbolic");
+ }
+
+ &.right {
+ -gtk-icon-source: -gtk-icontheme("pan-end-symbolic");
+ }
+
+ &.up {
+ -gtk-icon-source: -gtk-icontheme("pan-up-symbolic");
+ }
+}
diff --git a/lib/Styles/Gtk/CheckRadio.scss b/lib/Styles/Gtk/CheckRadio.scss
new file mode 100644
index 000000000..e1d3912e5
--- /dev/null
+++ b/lib/Styles/Gtk/CheckRadio.scss
@@ -0,0 +1,40 @@
+check,
+radio {
+ background-color: scale-color($toplevel-border-color, $alpha: -50%); // FIXME: abstract as trough color?
+ -gtk-icon-size: 1em;
+ min-height: 1em;
+ min-width: 1em;
+ padding: 1px;
+
+ &:checked {
+ background-color: $BLUEBERRY_500; // FIXME: use accent color
+ color: white;
+ -gtk-icon-source: -gtk-icontheme("check-checked-symbolic");
+ }
+
+ &:indeterminate {
+ color: rgba($fg-color, 0.5);
+ -gtk-icon-source: -gtk-icontheme("check-indeterminate-symbolic");
+ }
+}
+
+check {
+ border-radius: rem($window_radius / 3);
+
+ &:checked {
+ -gtk-icon-source: -gtk-icontheme("check-checked-symbolic");
+ }
+}
+
+radio {
+ border-radius: 50%;
+
+ &:checked {
+ -gtk-icon-source: -gtk-icontheme("pager-checked-symbolic");
+ }
+}
+
+radiobutton,
+checkbutton {
+ border-spacing: 0.5em; // FIXME: abstract button spacing?
+}
diff --git a/lib/Styles/Gtk/Index.scss b/lib/Styles/Gtk/Index.scss
index 9f3dc5f5e..815f34c26 100644
--- a/lib/Styles/Gtk/Index.scss
+++ b/lib/Styles/Gtk/Index.scss
@@ -1,4 +1,6 @@
+@import 'Arrow.scss';
@import 'Button.scss';
+@import 'CheckRadio.scss';
@import 'HeaderBar.scss';
@import 'Image.scss';
@import 'Popover.scss';
diff --git a/lib/Styles/Gtk/Popover.scss b/lib/Styles/Gtk/Popover.scss
index 9496386ac..ee444889c 100644
--- a/lib/Styles/Gtk/Popover.scss
+++ b/lib/Styles/Gtk/Popover.scss
@@ -21,31 +21,70 @@ popover {
highlight(),
0 0 0 1px $toplevel-border-color,
shadow(2);
- padding: rem(6px);
+ padding: rem(6px); // FIXME: abstract button spacing?
}
}
-.menuitem,
-modelbutton {
+.model {
border-radius: rem($window_radius / 2);
- border-spacing: rem(6px);
- min-width: rem(150px);
+ padding: rem(6px); // FIXME: abstract button spacing?
transition:
background duration("expand") easing(),
transform duration("expand") easing("ease-out-back");
- padding: rem(6px);
- &:hover {
+ &.image-button {
+ background: rgba($fg_color, 0.05);
+ }
+
+ &.circular {
+ padding: rem(9px);
+ }
+
+ // Focus and hover are synonymous in Popovers
+ &:hover,
+ &:focus {
background: rgba($fg_color, 0.1);
}
&:active {
background: rgba($fg-color, 0.15);
- // There's an optical illusion because items are wider than
- // they are tall, so compensate by scaling y a little extra
- transform: scale(0.98, 0.96);
+ transform: scale(0.95);
transition:
background duration("collapse") easing(),
transform duration("collapse") easing();
}
}
+
+.menuitem,
+modelbutton {
+ @extend .model;
+
+ border-spacing: rem(6px); // FIXME: abstract button spacing?
+ min-width: rem(150px);
+
+ &:active {
+ // There's an optical illusion because items are wider than
+ // they are tall, so compensate by scaling y a little extra
+ transform: scale(0.98, 0.96);
+ }
+}
+
+.menu {
+ .circular-buttons,
+ .inline-buttons {
+ border-spacing: rem(6px); // FIXME: abstract button spacing?
+ padding: rem(6px);
+
+ > box {
+ border-spacing: rem(6px); // FIXME: abstract button spacing?
+ }
+ }
+
+ .title {
+ @extend .title-4;
+
+ &.separator {
+ padding: rem(6px); // FIXME: abstract button spacing?
+ }
+ }
+}
diff --git a/lib/Widgets/SwitchModelButton.vala b/lib/Widgets/SwitchModelButton.vala
index 7b45e0412..10b2cfc00 100644
--- a/lib/Widgets/SwitchModelButton.vala
+++ b/lib/Widgets/SwitchModelButton.vala
@@ -56,17 +56,16 @@ public class Granite.SwitchModelButton : Gtk.ToggleButton {
child = description_label
};
+ layout_manager = new Gtk.BoxLayout (HORIZONTAL);
+
+ var box = new Gtk.Box (VERTICAL, 0);
+ box.append (label);
+ box.set_parent (this);
+
var button_switch = new Gtk.Switch () {
valign = Gtk.Align.START
};
-
- var grid = new Gtk.Grid () {
- column_spacing = 12
- };
- grid.attach (label, 0, 0);
- grid.attach (button_switch, 1, 0, 1, 2);
-
- child = grid;
+ button_switch.set_parent (this);
bind_property ("text", label, "label");
bind_property ("description", description_label, "label");
@@ -82,11 +81,17 @@ public class Granite.SwitchModelButton : Gtk.ToggleButton {
notify["description"].connect (() => {
if (description == null || description == "") {
- grid.remove (description_revealer);
+ box.remove (description_revealer);
} else {
- grid.attach (description_revealer, 0, 1);
+ box.append (description_revealer);
button_switch.bind_property ("active", description_revealer, "reveal-child", GLib.BindingFlags.SYNC_CREATE);
}
});
}
+
+ ~SwitchModelButton () {
+ while (get_first_child () != null) {
+ get_first_child ().unparent ();
+ }
+ }
}