[gnome-todo/wip/gbsneto/plugins: 11/18] window: load plugins' header widgets
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-todo/wip/gbsneto/plugins: 11/18] window: load plugins' header widgets
- Date: Mon, 18 Jan 2016 19:05:38 +0000 (UTC)
commit 5ff478fb665f6c5484f551f629627026d1dfb516
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Sat Jan 16 15:09:10 2016 -0200
window: load plugins' header widgets
They are loaded into the headerbar and positioned
according to their halign property.
data/ui/window.ui | 40 +++++++
plugins/eds/gtd-plugin-eds.c | 7 +
src/gtd-window.c | 238 +++++++++++++++++++++++++++++++++----
src/interfaces/gtd-activatable.c | 17 +++
src/interfaces/gtd-activatable.h | 4 +
5 files changed, 280 insertions(+), 26 deletions(-)
---
diff --git a/data/ui/window.ui b/data/ui/window.ui
index 0004a56..a115b7d 100644
--- a/data/ui/window.ui
+++ b/data/ui/window.ui
@@ -52,6 +52,26 @@
</object>
</child>
<child>
+ <object class="GtkBox" id="panel_box_start">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ </object>
+ <packing>
+ <property name="pack_type">start</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="extension_box_start">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ </object>
+ <packing>
+ <property name="pack_type">start</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkButton" id="cancel_selection_button">
<property name="visible">False</property>
<property name="can_focus">True</property>
@@ -82,6 +102,26 @@
<property name="pack_type">end</property>
</packing>
</child>
+ <child>
+ <object class="GtkBox" id="panel_box_end">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="extension_box_end">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
</object>
</child>
</template>
diff --git a/plugins/eds/gtd-plugin-eds.c b/plugins/eds/gtd-plugin-eds.c
index b644128..6ca83a3 100644
--- a/plugins/eds/gtd-plugin-eds.c
+++ b/plugins/eds/gtd-plugin-eds.c
@@ -116,6 +116,12 @@ peas_activatable_iface_init (PeasActivatableInterface *iface)
/*
* GtdActivatable interface implementation
*/
+static GList*
+gtd_plugin_eds_get_header_widgets (GtdActivatable *activatable)
+{
+ return NULL;
+}
+
static GtkWidget*
gtd_plugin_eds_get_preferences_panel (GtdActivatable *activatable)
{
@@ -141,6 +147,7 @@ gtd_plugin_eds_get_providers (GtdActivatable *activatable)
static void
gtd_activatable_iface_init (GtdActivatableInterface *iface)
{
+ iface->get_header_widgets = gtd_plugin_eds_get_header_widgets;
iface->get_preferences_panel = gtd_plugin_eds_get_preferences_panel;
iface->get_panels = gtd_plugin_eds_get_panels;
iface->get_providers = gtd_plugin_eds_get_providers;
diff --git a/src/gtd-window.c b/src/gtd-window.c
index a24392c..1b9f73e 100644
--- a/src/gtd-window.c
+++ b/src/gtd-window.c
@@ -16,13 +16,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "interfaces/gtd-activatable.h"
#include "interfaces/gtd-provider.h"
#include "interfaces/gtd-panel.h"
#include "views/gtd-list-selector-panel.h"
+#include "plugin/gtd-plugin-manager.h"
#include "gtd-application.h"
#include "gtd-enum-types.h"
#include "gtd-task-list-view.h"
#include "gtd-manager.h"
+#include "gtd-manager-protected.h"
#include "gtd-notification.h"
#include "gtd-notification-widget.h"
#include "gtd-provider-dialog.h"
@@ -43,6 +46,12 @@ typedef struct
GtkStackSwitcher *stack_switcher;
GtdProviderDialog *provider_dialog;
+ /* boxes */
+ GtkWidget *extension_box_end;
+ GtkWidget *extension_box_start;
+ GtkWidget *panel_box_end;
+ GtkWidget *panel_box_start;
+
GtdPanel *active_panel;
/* mode */
@@ -91,6 +100,172 @@ typedef struct
} ErrorData;
static void
+add_widgets (GtdWindow *window,
+ GtkWidget *container_start,
+ GtkWidget *container_end,
+ GList *widgets)
+{
+ GtdWindowPrivate *priv = gtd_window_get_instance_private (window);
+ GList *l;
+
+ for (l = widgets; l != NULL; l = l->next)
+ {
+ switch (gtk_widget_get_halign (l->data))
+ {
+ case GTK_ALIGN_START:
+ gtk_box_pack_start (GTK_BOX (container_start),
+ l->data,
+ FALSE,
+ FALSE,
+ 0);
+ break;
+
+ case GTK_ALIGN_CENTER:
+ gtk_header_bar_set_custom_title (priv->headerbar, l->data);
+ break;
+
+ case GTK_ALIGN_END:
+ gtk_box_pack_end (GTK_BOX (container_end),
+ l->data,
+ FALSE,
+ FALSE,
+ 0);
+ break;
+
+ case GTK_ALIGN_BASELINE:
+ case GTK_ALIGN_FILL:
+ default:
+ gtk_box_pack_start (GTK_BOX (container_start),
+ l->data,
+ FALSE,
+ FALSE,
+ 0);
+ break;
+ }
+ }
+}
+
+static void
+remove_widgets (GtdWindow *window,
+ GtkWidget *container_start,
+ GtkWidget *container_end,
+ GList *widgets)
+{
+ GtdWindowPrivate *priv = gtd_window_get_instance_private (window);
+ GList *l;
+
+ for (l = widgets; l != NULL; l = l->next)
+ {
+ GtkWidget *container;
+
+ if (gtk_widget_get_halign (l->data) == GTK_ALIGN_END)
+ container = container_end;
+ else if (gtk_widget_get_halign (l->data) == GTK_ALIGN_CENTER)
+ container = GTK_WIDGET (priv->headerbar);
+ else
+ container = container_start;
+
+ g_object_ref (l->data);
+ gtk_container_remove (GTK_CONTAINER (container), l->data);
+ }
+}
+
+static void
+on_active_change (GtdActivatable *activatable,
+ GParamSpec *pspec,
+ GtdWindow *window)
+{
+ GtdWindowPrivate *priv;
+ GList *header_widgets;
+ gboolean active;
+
+ priv = gtd_window_get_instance_private (window);
+ header_widgets = gtd_activatable_get_header_widgets (activatable);
+
+ g_object_get (activatable,
+ "active", &active,
+ NULL);
+
+ if (active)
+ {
+ add_widgets (window,
+ priv->extension_box_start,
+ priv->extension_box_end,
+ header_widgets);
+ }
+ else
+ {
+ remove_widgets (window,
+ priv->extension_box_start,
+ priv->extension_box_end,
+ header_widgets);
+ }
+
+ g_list_free (header_widgets);
+}
+
+static void
+plugin_loaded (GtdWindow *window,
+ gpointer unused_field,
+ GtdActivatable *activatable)
+{
+ GtdWindowPrivate *priv = gtd_window_get_instance_private (window);
+ gboolean active;
+
+ g_object_get (activatable,
+ "active", &active,
+ NULL);
+
+ if (active)
+ {
+ GList *header_widgets;
+
+ header_widgets = gtd_activatable_get_header_widgets (activatable);
+
+ add_widgets (window,
+ priv->extension_box_start,
+ priv->extension_box_end,
+ header_widgets);
+
+ g_list_free (header_widgets);
+ }
+
+ g_signal_connect (activatable,
+ "notify::active",
+ G_CALLBACK (on_active_change),
+ window);
+}
+
+static void
+plugin_unloaded (GtdWindow *window,
+ gpointer unused_field,
+ GtdActivatable *activatable)
+{
+ GtdWindowPrivate *priv = gtd_window_get_instance_private (window);
+ gboolean active;
+
+ g_object_get (activatable,
+ "active", &active,
+ NULL);
+
+ if (active)
+ {
+ GList *header_widgets;
+
+ header_widgets = gtd_activatable_get_header_widgets (activatable);
+
+ remove_widgets (window,
+ priv->extension_box_start,
+ priv->extension_box_end,
+ header_widgets);
+ }
+
+ g_signal_handlers_disconnect_by_func (activatable,
+ on_active_change,
+ window);
+}
+
+static void
update_panel_menu (GtdWindow *window)
{
GtdWindowPrivate *priv = gtd_window_get_instance_private (window);
@@ -321,7 +496,6 @@ gtd_window__stack_visible_child_cb (GtdWindow *window,
GtkWidget *visible_child;
GtdPanel *panel;
GList *header_widgets;
- GList *l;
priv = gtd_window_get_instance_private (window);
visible_child = gtk_stack_get_visible_child (stack);
@@ -337,8 +511,10 @@ gtd_window__stack_visible_child_cb (GtdWindow *window,
gtd_window__panel_menu_changed,
window);
- for (l = header_widgets; l != NULL; l = l->next)
- gtk_container_remove (GTK_CONTAINER (priv->headerbar), l->data);
+ remove_widgets (window,
+ priv->panel_box_start,
+ priv->panel_box_end,
+ header_widgets);
g_list_free (header_widgets);
}
@@ -346,29 +522,10 @@ gtd_window__stack_visible_child_cb (GtdWindow *window,
/* Add current panel's header widgets */
header_widgets = gtd_panel_get_header_widgets (panel);
- for (l = header_widgets; l != NULL; l = l->next)
- {
- switch (gtk_widget_get_halign (l->data))
- {
- case GTK_ALIGN_START:
- gtk_header_bar_pack_start (priv->headerbar, l->data);
- break;
-
- case GTK_ALIGN_CENTER:
- gtk_header_bar_set_custom_title (priv->headerbar, l->data);
- break;
-
- case GTK_ALIGN_END:
- gtk_header_bar_pack_end (priv->headerbar, l->data);
- break;
-
- case GTK_ALIGN_BASELINE:
- case GTK_ALIGN_FILL:
- default:
- gtk_header_bar_pack_start (priv->headerbar, l->data);
- break;
- }
- }
+ add_widgets (window,
+ priv->panel_box_start,
+ priv->panel_box_end,
+ header_widgets);
g_list_free (header_widgets);
@@ -583,6 +740,30 @@ gtd_window_set_property (GObject *object,
case PROP_MANAGER:
self->priv->manager = g_value_get_object (value);
+ /* Add plugins' header widgets, and setup for new plugins */
+ {
+ GtdPluginManager *plugin_manager;
+ GList *plugins;
+
+ plugin_manager = gtd_manager_get_plugin_manager (self->priv->manager);
+ plugins = gtd_plugin_manager_get_loaded_plugins (plugin_manager);
+
+ for (l = plugins; l != NULL; l = l->next)
+ plugin_loaded (self, NULL, l->data);
+
+ g_signal_connect_swapped (plugin_manager,
+ "plugin-loaded",
+ G_CALLBACK (plugin_loaded),
+ self);
+
+ g_signal_connect_swapped (plugin_manager,
+ "plugin-unloaded",
+ G_CALLBACK (plugin_unloaded),
+ self);
+
+ g_list_free (plugins);
+ }
+
g_signal_connect (self->priv->manager,
"notify::ready",
G_CALLBACK (gtd_window__manager_ready_changed),
@@ -677,6 +858,11 @@ gtd_window_class_init (GtdWindowClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, stack);
gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, stack_switcher);
+ gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, extension_box_end);
+ gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, extension_box_start);
+ gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, panel_box_end);
+ gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, panel_box_start);
+
gtk_widget_class_bind_template_callback (widget_class, gtd_window__cancel_selection_button_clicked);
gtk_widget_class_bind_template_callback (widget_class, gtd_window__stack_visible_child_cb);
}
diff --git a/src/interfaces/gtd-activatable.c b/src/interfaces/gtd-activatable.c
index f14c567..1be8016 100644
--- a/src/interfaces/gtd-activatable.c
+++ b/src/interfaces/gtd-activatable.c
@@ -180,6 +180,23 @@ gtd_activatable_default_init (GtdActivatableInterface *iface)
}
/**
+ * gtd_activatable_get_header_widgets:
+ * @activatable: a #GtdActivatable
+ *
+ * Retrieve the list header widgets of @activatable if any.
+ *
+ * Returns: (transfer container) (element-type #GtkWidget): a #GList
+ */
+GList*
+gtd_activatable_get_header_widgets (GtdActivatable *activatable)
+{
+ g_return_val_if_fail (GTD_IS_ACTIVATABLE (activatable), NULL);
+ g_return_val_if_fail (GTD_ACTIVATABLE_GET_IFACE (activatable)->get_header_widgets, NULL);
+
+ return GTD_ACTIVATABLE_GET_IFACE (activatable)->get_header_widgets (activatable);
+}
+
+/**
* gtd_activatable_get_preferences_panel:
* @activatable: a #GtdActivatable
*
diff --git a/src/interfaces/gtd-activatable.h b/src/interfaces/gtd-activatable.h
index b7f45e1..a017dd3 100644
--- a/src/interfaces/gtd-activatable.h
+++ b/src/interfaces/gtd-activatable.h
@@ -33,6 +33,8 @@ struct _GtdActivatableInterface
{
PeasActivatableInterface parent;
+ GList* (*get_header_widgets) (GtdActivatable *activatable);
+
GtkWidget* (*get_preferences_panel) (GtdActivatable *activatable);
GList* (*get_panels) (GtdActivatable *activatable);
@@ -40,6 +42,8 @@ struct _GtdActivatableInterface
GList* (*get_providers) (GtdActivatable *activatable);
};
+GList* gtd_activatable_get_header_widgets (GtdActivatable *activatable);
+
GtkWidget* gtd_activatable_get_preferences_panel (GtdActivatable *activatable);
GList* gtd_activatable_get_panels (GtdActivatable *activatable);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]