[gnome-todo] window: Add a workspace selector popover
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-todo] window: Add a workspace selector popover
- Date: Tue, 28 Apr 2020 17:00:28 +0000 (UTC)
commit e931d4ddedb31e254db3d5a5bd5c54d4e6b85177
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Tue Apr 28 12:05:45 2020 -0300
window: Add a workspace selector popover
Pretty simple popover, doesn't do fancy for now.
src/gtd-window.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/gtd-window.ui | 33 +++++++++++++++++
2 files changed, 139 insertions(+), 2 deletions(-)
---
diff --git a/src/gtd-window.c b/src/gtd-window.c
index 06ee817..d96b809 100644
--- a/src/gtd-window.c
+++ b/src/gtd-window.c
@@ -24,6 +24,7 @@
#include "interfaces/gtd-provider.h"
#include "interfaces/gtd-panel.h"
#include "interfaces/gtd-workspace.h"
+#include "widgets/gtd-menu-button.h"
#include "gtd-application.h"
#include "gtd-debug.h"
#include "gtd-enum-types.h"
@@ -61,12 +62,15 @@ struct _GtdWindow
GtkStack *stack;
GtkWidget *workspace_box_end;
GtkWidget *workspace_box_start;
+ GtkListBox *workspaces_listbox;
+ GtdMenuButton *workspaces_menu_button;
GtdNotificationWidget *notification_widget;
GPtrArray *workspace_header_widgets;
GtdWorkspace *current_workspace;
+ GListStore *workspaces;
};
typedef struct
@@ -79,7 +83,9 @@ typedef struct
G_DEFINE_TYPE (GtdWindow, gtd_window, GTK_TYPE_APPLICATION_WINDOW)
-
+static gint compare_workspaced_func (gconstpointer a,
+ gconstpointer b,
+ gpointer user_data);
static void
setup_development_build (GtdWindow *self)
@@ -178,6 +184,20 @@ add_workspace (GtdWindow *self,
workspace_id = gtd_workspace_get_id (workspace);
gtk_stack_add_named (self->stack, GTK_WIDGET (workspace), workspace_id);
+ g_list_store_insert_sorted (self->workspaces, workspace, compare_workspaced_func, self);
+}
+
+static void
+remove_workspace (GtdWindow *self,
+ GtdWorkspace *workspace)
+{
+ guint position;
+
+ if (!g_list_store_find (self->workspaces, workspace, &position))
+ return;
+
+ gtk_container_remove (GTK_CONTAINER (self->stack), GTK_WIDGET (workspace));
+ g_list_store_remove (self->workspaces, position);
}
static void
@@ -210,11 +230,27 @@ remove_all_workspace_header_widgets (GtdWindow *self)
* Callbacks
*/
+
+static gint
+compare_workspaced_func (gconstpointer a,
+ gconstpointer b,
+ gpointer user_data)
+{
+ gint a_priority;
+ gint b_priority;
+
+ a_priority = gtd_workspace_get_priority ((GtdWorkspace *)a);
+ b_priority = gtd_workspace_get_priority ((GtdWorkspace *)b);
+
+ return b_priority - a_priority;
+}
+
static void
on_stack_visible_child_cb (GtkStack *stack,
GParamSpec *pspec,
GtdWindow *self)
{
+ g_autoptr (GIcon) workspace_icon = NULL;
GtdWorkspace *new_workspace;
GTD_ENTRY;
@@ -230,6 +266,9 @@ on_stack_visible_child_cb (GtkStack *stack,
self->current_workspace = new_workspace;
gtd_workspace_activate (new_workspace);
+ workspace_icon = gtd_workspace_get_icon (new_workspace);
+ gtd_menu_button_set_gicon (self->workspaces_menu_button, workspace_icon);
+
GTD_EXIT;
}
@@ -298,11 +337,54 @@ on_manager_workspace_removed_cb (GtdManager *manager,
{
GTD_ENTRY;
- g_message ("Workspace removed");
+ remove_workspace (self, workspace);
GTD_EXIT;
}
+static void
+on_workspaces_listbox_row_activated_cb (GtkListBox *workspaces_listbox,
+ GtkListBoxRow *row,
+ GtdWindow *self)
+{
+ g_autoptr (GtdWorkspace) workspace = NULL;
+
+ workspace = g_list_model_get_item (G_LIST_MODEL (self->workspaces),
+ gtk_list_box_row_get_index (row));
+
+ gtk_stack_set_visible_child (self->stack, GTK_WIDGET (workspace));
+
+ gtd_menu_button_popdown (self->workspaces_menu_button);
+}
+
+static GtkWidget*
+create_workspace_row_func (gpointer item,
+ gpointer user_data)
+{
+ GtkWidget *label;
+ GtkWidget *image;
+ GtkWidget *box;
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+ gtk_widget_set_margin_start (box, 6);
+ gtk_widget_set_margin_end (box, 6);
+ gtk_widget_set_margin_top (box, 3);
+ gtk_widget_set_margin_bottom (box, 3);
+
+ image = gtk_image_new ();
+ g_object_bind_property (item, "icon", image, "gicon", G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+
+ label = gtk_label_new ("");
+ gtk_widget_set_hexpand (label, TRUE);
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+ g_object_bind_property (item, "title", label, "label", G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+
+ gtk_container_add (GTK_CONTAINER (box), image);
+ gtk_container_add (GTK_CONTAINER (box), label);
+
+ return box;
+}
+
/*
* GtkWindow overrides
@@ -337,6 +419,16 @@ gtd_window_unmap (GtkWidget *widget)
* GObject overrides
*/
+static void
+gtd_window_dispose (GObject *object)
+{
+ GtdWindow *self = GTD_WINDOW (object);
+
+ g_clear_object (&self->workspaces);
+
+ G_OBJECT_CLASS (gtd_window_parent_class)->dispose (object);
+}
+
static void
gtd_window_constructed (GObject *object)
{
@@ -372,10 +464,12 @@ gtd_window_class_init (GtdWindowClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ object_class->dispose = gtd_window_dispose;
object_class->constructed = gtd_window_constructed;
widget_class->unmap = gtd_window_unmap;
+ g_type_ensure (GTD_TYPE_MENU_BUTTON);
g_type_ensure (GTD_TYPE_NOTIFICATION_WIDGET);
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/gtd-window.ui");
@@ -385,17 +479,27 @@ gtd_window_class_init (GtdWindowClass *klass)
gtk_widget_class_bind_template_child (widget_class, GtdWindow, stack);
gtk_widget_class_bind_template_child (widget_class, GtdWindow, workspace_box_end);
gtk_widget_class_bind_template_child (widget_class, GtdWindow, workspace_box_start);
+ gtk_widget_class_bind_template_child (widget_class, GtdWindow, workspaces_menu_button);
+ gtk_widget_class_bind_template_child (widget_class, GtdWindow, workspaces_listbox);
gtk_widget_class_bind_template_callback (widget_class, on_stack_visible_child_cb);
+ gtk_widget_class_bind_template_callback (widget_class, on_workspaces_listbox_row_activated_cb);
}
static void
gtd_window_init (GtdWindow *self)
{
self->workspace_header_widgets = g_ptr_array_new_with_free_func (g_object_unref);
+ self->workspaces = g_list_store_new (GTD_TYPE_WORKSPACE);
gtk_widget_init_template (GTK_WIDGET (self));
+ gtk_list_box_bind_model (self->workspaces_listbox,
+ G_LIST_MODEL (self->workspaces),
+ create_workspace_row_func,
+ self,
+ NULL);
+
/* Development build */
if (is_development_build ())
setup_development_build (self);
diff --git a/src/gtd-window.ui b/src/gtd-window.ui
index afd7375..493926f 100644
--- a/src/gtd-window.ui
+++ b/src/gtd-window.ui
@@ -40,6 +40,15 @@
<object class="GtkHeaderBar" id="headerbar">
<property name="hexpand">1</property>
<property name="show-title-buttons">1</property>
+
+ <!-- Workspace Button -->
+ <child>
+ <object class="GtdMenuButton" id="workspaces_menu_button">
+ <property name="can_focus">1</property>
+ <property name="popover">workspaces_popover</property>
+ </object>
+ </child>
+
<child>
<object class="GtkBox" id="workspace_box_start">
<property name="spacing">6</property>
@@ -62,6 +71,30 @@
</child>
</template>
+ <!-- Workspaces Popover -->
+ <object class="GtkPopover" id="workspaces_popover">
+ <child>
+ <object class="GtkBox">
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <property name="width-request">150</property>
+
+ <child>
+ <object class="GtkListBox" id="workspaces_listbox">
+ <property name="selection-mode">none</property>
+ <signal name="row-activated" handler="on_workspaces_listbox_row_activated_cb" object="GtdWindow"
swapped="no" />
+ <style>
+ <class name="transparent" />
+ </style>
+ </object>
+ </child>
+
+ </object>
+ </child>
+ </object>
+
<menu id="app-menu">
<section>
<item>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]