diff --git a/src/Widgets/IndicatorBar.vala b/src/Widgets/IndicatorBar.vala index 325eedeb..9b673d4c 100644 --- a/src/Widgets/IndicatorBar.vala +++ b/src/Widgets/IndicatorBar.vala @@ -17,45 +17,28 @@ * Boston, MA 02110-1301 USA. */ -public class Wingpanel.Widgets.IndicatorBar : Gtk.Box { - private Gee.List sorted_items; +public class Wingpanel.Widgets.IndicatorBar : Granite.Bin { + public ListModel indicator_entries { private get; construct; } - construct { - sorted_items = new Gee.ArrayList (); - } - - public void insert_sorted (IndicatorEntry item) { - item.indicator_bar = this; + private Gtk.FlowBox flow_box; - if (!(item in sorted_items)) { - sorted_items.add (item); - sorted_items.sort (IndicatorEntry.compare_func); - } + public IndicatorBar (ListModel indicator_entries) { + Object (indicator_entries: indicator_entries); + } - if (item.base_indicator.visible) { - Gtk.Widget? previous = null; - foreach (var i in sorted_items) { - if (i == item) { - break; - } + construct { + flow_box = new Gtk.FlowBox () { + orientation = HORIZONTAL, + selection_mode = NONE + }; + flow_box.bind_model (indicator_entries, (indicator_entry) => (IndicatorEntry) indicator_entry); - if (i.base_indicator.visible) { - previous = i; - } - } + indicator_entries.items_changed.connect (update_flow_box_max_children); - if (item.get_parent () != this) { - insert_child_after (item, previous); - } - } + child = flow_box; } - public void remove_indicator (Indicator indicator) { - foreach (var entry in sorted_items) { - if (entry.base_indicator.code_name == indicator.code_name) { - sorted_items.remove (entry); - remove (entry); - } - } + private void update_flow_box_max_children () { + flow_box.max_children_per_line = indicator_entries.get_n_items (); } } diff --git a/src/Widgets/IndicatorEntry.vala b/src/Widgets/IndicatorEntry.vala index c5a81404..e2283c6b 100644 --- a/src/Widgets/IndicatorEntry.vala +++ b/src/Widgets/IndicatorEntry.vala @@ -24,7 +24,6 @@ public class Wingpanel.Widgets.IndicatorEntry : Granite.Bin { public Indicator base_indicator { get; construct; } public Services.PopoverManager popover_manager { get; construct; } - public IndicatorBar? indicator_bar; public Gtk.Widget display_widget { get; private set; } private Gtk.Widget _indicator_widget = null; @@ -38,6 +37,12 @@ public class Wingpanel.Widgets.IndicatorEntry : Granite.Bin { } } + public bool should_show_indicator { + get { + return revealer.reveal_child || revealer.child_revealed; + } + } + /* The order in which the indicators are shown from left to right. */ private static Gee.HashMap indicator_order = new Gee.HashMap (); @@ -89,6 +94,21 @@ public class Wingpanel.Widgets.IndicatorEntry : Granite.Bin { }; revealer.add_css_class ("composited-indicator"); + switch (base_indicator.code_name) { + case Indicator.APP_LAUNCHER: + revealer.transition_type = SLIDE_RIGHT; + break; + case Indicator.DATETIME: + revealer.transition_type = SLIDE_DOWN; + break; + default: + revealer.transition_type = SLIDE_LEFT; + break; + } + + revealer.notify["child-revealed"].connect (() => notify_property ("should-show-indicator")); + revealer.notify["reveal-child"].connect (() => notify_property ("should-show-indicator")); + child = revealer; if (base_indicator.visible) { @@ -100,21 +120,14 @@ public class Wingpanel.Widgets.IndicatorEntry : Granite.Bin { }); base_indicator.notify["visible"].connect (() => { - if (indicator_bar != null) { - /* order will be changed so close all open popovers */ - popover_manager.close (); - - if (base_indicator.visible) { - popover_manager.register_indicator (this); - indicator_bar.insert_sorted (this); - set_reveal (base_indicator.visible); - } else { - set_reveal (base_indicator.visible); - popover_manager.unregister_indicator (this); - // reorder indicators when indicator is invisible - display_widget.unmap.connect (indicator_unmapped); - } + /* order will be changed so close all open popovers */ + popover_manager.close (); + + if (base_indicator.visible) { + popover_manager.register_indicator (this); + set_reveal (base_indicator.visible); } else { + popover_manager.unregister_indicator (this); set_reveal (base_indicator.visible); } }); @@ -141,15 +154,6 @@ public class Wingpanel.Widgets.IndicatorEntry : Granite.Bin { set_reveal (base_indicator.visible); } - private void indicator_unmapped () { - base_indicator.get_display_widget ().unmap.disconnect (indicator_unmapped); - indicator_bar.remove (this); - } - - public void set_transition_type (Gtk.RevealerTransitionType transition_type) { - revealer.set_transition_type (transition_type); - } - private void set_reveal (bool reveal) { if (!reveal && popover_manager.get_visible (this)) { popover_manager.current_indicator = null; diff --git a/src/Widgets/Panel.vala b/src/Widgets/Panel.vala index 4bf806b2..5a2af055 100644 --- a/src/Widgets/Panel.vala +++ b/src/Widgets/Panel.vala @@ -26,6 +26,11 @@ public class Wingpanel.Widgets.Panel : Granite.Bin { private IndicatorBar left_menubar; private IndicatorBar center_menubar; + private ListStore all_indicator_entries; + private Gtk.CustomFilter visible_indicator_entries_filter; + private Gtk.FilterListModel visible_indicator_entries; + private Gtk.SortListModel sorted_indicator_entries; + private Gtk.CenterBox box; private Gtk.GestureClick gesture_controller; @@ -44,13 +49,39 @@ public class Wingpanel.Widgets.Panel : Granite.Bin { hexpand = true; vexpand = true; - left_menubar = new IndicatorBar () { + all_indicator_entries = new ListStore (typeof (IndicatorEntry)); + + visible_indicator_entries_filter = new Gtk.CustomFilter (visible_indicators_filter_func); + visible_indicator_entries = new Gtk.FilterListModel ( + all_indicator_entries, + visible_indicator_entries_filter + ); + + sorted_indicator_entries = new Gtk.SortListModel ( + visible_indicator_entries, + new Gtk.CustomSorter (IndicatorEntry.compare_func) + ); + + var left_indicator_entries = new Gtk.FilterListModel ( + sorted_indicator_entries, + new Gtk.CustomFilter (left_indicators_filter_func) + ); + var center_indicator_entries = new Gtk.FilterListModel ( + sorted_indicator_entries, + new Gtk.CustomFilter (center_indicators_filter_func) + ); + var right_indicator_entries = new Gtk.FilterListModel ( + sorted_indicator_entries, + new Gtk.CustomFilter (right_indicators_filter_func) + ); + + left_menubar = new IndicatorBar (left_indicator_entries) { halign = START }; - center_menubar = new IndicatorBar (); + center_menubar = new IndicatorBar (center_indicator_entries); - right_menubar = new IndicatorBar () { + right_menubar = new IndicatorBar (right_indicator_entries) { halign = END }; @@ -65,11 +96,9 @@ public class Wingpanel.Widgets.Panel : Granite.Bin { indicator_manager.indicator_added.connect (add_indicator); indicator_manager.indicator_removed.connect (remove_indicator); - indicator_manager.get_indicators ().@foreach ((indicator) => { + foreach (var indicator in indicator_manager.get_indicators ()) { add_indicator (indicator); - - return true; - }); + } gesture_controller = new Gtk.GestureClick (); add_controller (gesture_controller); @@ -154,62 +183,66 @@ public class Wingpanel.Widgets.Panel : Granite.Bin { } } - private IndicatorEntry? get_next_indicator (IndicatorEntry current) { - Gtk.Widget? sibling = current.get_next_sibling (); - - if (sibling != null) { - return (IndicatorEntry) sibling; + private IndicatorEntry get_next_indicator (IndicatorEntry current) { + var current_entry_pos = 0u; + for (var i = 0; i < sorted_indicator_entries.get_n_items (); i++) { + var indicator_entry = (IndicatorEntry) sorted_indicator_entries.get_item (i); + if (indicator_entry == current) { + current_entry_pos = i; + break; + } } - switch (current.base_indicator.code_name) { - case Indicator.APP_LAUNCHER: - return (IndicatorEntry) center_menubar.get_last_child (); - case Indicator.DATETIME: - return (IndicatorEntry) right_menubar.get_last_child (); - default: - return (IndicatorEntry) left_menubar.get_last_child (); - } + var new_entry_pos = (current_entry_pos + 1).clamp (0, sorted_indicator_entries.get_n_items ()); + return (IndicatorEntry) sorted_indicator_entries.get_item (new_entry_pos); } private IndicatorEntry? get_previous_indicator (IndicatorEntry current) { - Gtk.Widget? sibling = current.get_prev_sibling (); - - if (sibling != null) { - return (IndicatorEntry) sibling; + var current_entry_pos = 0u; + for (var i = 0; i < sorted_indicator_entries.get_n_items (); i++) { + var indicator_entry = (IndicatorEntry) sorted_indicator_entries.get_item (i); + if (indicator_entry == current) { + current_entry_pos = i; + break; + } } - switch (current.base_indicator.code_name) { - case Indicator.APP_LAUNCHER: - return (IndicatorEntry) right_menubar.get_last_child (); - case Indicator.DATETIME: - return (IndicatorEntry) left_menubar.get_last_child (); - default: - return (IndicatorEntry) center_menubar.get_last_child (); - } + var new_entry_pos = (current_entry_pos - 1).clamp (0, sorted_indicator_entries.get_n_items ()); + return (IndicatorEntry) sorted_indicator_entries.get_item (new_entry_pos); } private void add_indicator (Indicator indicator) { var indicator_entry = new IndicatorEntry (indicator, popover_manager); - switch (indicator.code_name) { - case Indicator.APP_LAUNCHER: - indicator_entry.set_transition_type (Gtk.RevealerTransitionType.SLIDE_RIGHT); - left_menubar.insert_sorted (indicator_entry); - break; - case Indicator.DATETIME: - indicator_entry.set_transition_type (Gtk.RevealerTransitionType.SLIDE_DOWN); - center_menubar.insert_sorted (indicator_entry); - break; - default: - indicator_entry.set_transition_type (Gtk.RevealerTransitionType.SLIDE_LEFT); - right_menubar.insert_sorted (indicator_entry); - break; - } + all_indicator_entries.append (indicator_entry); + + indicator_entry.notify["should-show-indicator"].connect (() => + visible_indicator_entries_filter.changed (DIFFERENT) + ); } private void remove_indicator (Indicator indicator) { - left_menubar.remove_indicator (indicator); - center_menubar.remove_indicator (indicator); - right_menubar.remove_indicator (indicator); + for (var i = 0; i < all_indicator_entries.get_n_items (); i++) { + var indicator_entry = (IndicatorEntry) all_indicator_entries.get_item (i); + if (indicator_entry.base_indicator == indicator) { + all_indicator_entries.remove (i); + } + } + } + + private static bool visible_indicators_filter_func (Object item) requires (item is IndicatorEntry) { + return ((IndicatorEntry) item).should_show_indicator; + } + + private static bool left_indicators_filter_func (Object item) requires (item is IndicatorEntry) { + return ((IndicatorEntry) item).base_indicator.code_name == Indicator.APP_LAUNCHER; + } + + private static bool center_indicators_filter_func (Object item) requires (item is IndicatorEntry) { + return ((IndicatorEntry) item).base_indicator.code_name == Indicator.DATETIME; + } + + private static bool right_indicators_filter_func (Object item) requires (item is IndicatorEntry) { + return !left_indicators_filter_func (item) && !center_indicators_filter_func (item); } }