[geary/mjog/mail-merge-plugin: 32/71] Components.InfoBarStack: Support additional stack queue algorithms




commit 87e5de6504fec709132a8df4fac4386805741238
Author: Michael Gratton <mike vee net>
Date:   Thu Apr 30 09:08:09 2020 +1000

    Components.InfoBarStack: Support additional stack queue algorithms
    
    In addition to just showing the most-recenly-added info bar, also
    support choosing an info bar based on a priority queue.

 .../application/application-main-window.vala       |  5 +-
 .../components/components-info-bar-stack.vala      | 77 +++++++++++++++++++++-
 2 files changed, 79 insertions(+), 3 deletions(-)
---
diff --git a/src/client/application/application-main-window.vala 
b/src/client/application/application-main-window.vala
index 0a1e2dc87..6e38b87f6 100644
--- a/src/client/application/application-main-window.vala
+++ b/src/client/application/application-main-window.vala
@@ -283,7 +283,7 @@ public class Application.MainWindow :
     public ConversationViewer conversation_viewer { get; private set; }
 
     public Components.InfoBarStack conversation_list_info_bars {
-        get; private set; default = new Components.InfoBarStack();
+        get; private set; default = new Components.InfoBarStack(SINGLE);
     }
 
     public StatusBar status_bar { get; private set; default = new StatusBar(); }
@@ -333,7 +333,8 @@ public class Application.MainWindow :
     [GtkChild]
     private Gtk.Overlay overlay;
 
-    private Components.InfoBarStack info_bars = new Components.InfoBarStack();
+    private Components.InfoBarStack info_bars =
+        new Components.InfoBarStack(SINGLE);
 
     private Components.InfoBar offline_infobar;
 
diff --git a/src/client/components/components-info-bar-stack.vala 
b/src/client/components/components-info-bar-stack.vala
index 8bebed984..cbe63e051 100644
--- a/src/client/components/components-info-bar-stack.vala
+++ b/src/client/components/components-info-bar-stack.vala
@@ -15,6 +15,31 @@
 public class Components.InfoBarStack : Gtk.Frame, Geary.BaseInterface {
 
 
+    /**
+     * GLib.Object data key for priority queue value.
+     *
+     * @see StackType.PRIORITY_QUEUE
+     * @see priority_queue_comparator
+     */
+    public const string PRIORITY_QUEUE_KEY =
+        "Components.InfoBarStack.PRIORITY_QUEUE_KEY";
+
+
+    /** Supported stack algorithms. */
+    public enum StackType {
+        /** Always shows the most recently added info bar. */
+        SINGLE,
+
+        /**
+         * Shows the highest priority infobar.
+         *
+         * @see priority_queue_comparator
+         */
+        PRIORITY_QUEUE;
+
+    }
+
+
     private class SingletonQueue : Gee.AbstractQueue<Gtk.InfoBar> {
 
         public override bool read_only {
@@ -88,6 +113,37 @@ public class Components.InfoBarStack : Gtk.Frame, Geary.BaseInterface {
     }
 
 
+    /**
+     * Comparator used for the priority queue algorithm.
+     *
+     * When {@link algorithm} is set to {@link
+     * StackType.PRIORITY_QUEUE}, this comparator is used for the
+     * priority queue to compare info bars. It uses an integer value
+     * stored via GLib.Object.set_data with {@link PRIORITY_QUEUE_KEY}
+     * as a key to determine the relative priority between two info
+     * bars.
+     *
+     * @see algorithm
+     * @see StackType.PRIORITY_QUEUE
+     */
+    public static int priority_queue_comparator(Gtk.InfoBar a, Gtk.InfoBar b) {
+        return (
+            b.get_data<int>(PRIORITY_QUEUE_KEY) -
+            a.get_data<int>(PRIORITY_QUEUE_KEY)
+        );
+    }
+
+
+    /** The algorithm used when showing info bars. */
+    public StackType algorithm {
+        get { return this._algorithm; }
+        construct set {
+            this._algorithm = value;
+            update_queue_type();
+        }
+    }
+    private StackType _algorithm = SINGLE;
+
     /** Determines if an info bar is currently being shown. */
     public bool has_current {
         get { return (this.current_info_bar != null); }
@@ -98,12 +154,17 @@ public class Components.InfoBarStack : Gtk.Frame, Geary.BaseInterface {
         get { return get_child() as Gtk.InfoBar; }
     }
 
-    private Gee.Queue<Gtk.InfoBar> available = new SingletonQueue();
+    private Gee.Queue<Gtk.InfoBar> available;
     private int last_allocated_height = 0;
 
 
     construct {
         get_style_context().add_class("geary-info-bar-stack");
+        update_queue_type();
+    }
+
+    public InfoBarStack(StackType algorithm) {
+        Object(algorithm: algorithm);
     }
 
     /**
@@ -167,6 +228,20 @@ public class Components.InfoBarStack : Gtk.Frame, Geary.BaseInterface {
         }
     }
 
+    private void update_queue_type() {
+        switch (this._algorithm) {
+        case SINGLE:
+            this.available = new SingletonQueue();
+            break;
+        case PRIORITY_QUEUE:
+            this.available = new Gee.PriorityQueue<Gtk.InfoBar>(
+                InfoBarStack.priority_queue_comparator
+            );
+            break;
+        }
+        update();
+    }
+
     private void on_allocation_changed() {
         var current = this.current_info_bar;
         if (current != null) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]