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 @@ - - - - - - - image/svg+xml - - - - - - - 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 @@ + + + + + + + image/svg+xml + + + + + + 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 @@ + +image/svg+xml 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 @@ - - - - - - - image/svg+xml - - - - - - - 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 (); + } + } }