[gnome-todo/gbsneto/planning: 5/6] WIP Planning Workspace
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-todo/gbsneto/planning: 5/6] WIP Planning Workspace
- Date: Tue, 5 May 2020 15:58:29 +0000 (UTC)
commit 3227fc3cb500d46df7061d5cf62b8affcd249cc0
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Sun May 3 08:43:34 2020 -0300
WIP Planning Workspace
src/engine/gtd-plugin-manager.c | 1 +
src/plugins/meson.build | 1 +
.../planning-workspace/gtd-planning-workspace.c | 337 +++++++++++++++++++++
.../planning-workspace/gtd-planning-workspace.h | 30 ++
.../planning-workspace/gtd-planning-workspace.ui | 61 ++++
src/plugins/planning-workspace/meson.build | 13 +
.../planning-workspace/planning-workspace-plugin.c | 31 ++
.../planning-workspace.gresource.xml | 7 +
.../planning-workspace/planning-workspace.plugin | 14 +
9 files changed, 495 insertions(+)
---
diff --git a/src/engine/gtd-plugin-manager.c b/src/engine/gtd-plugin-manager.c
index c666282..6691566 100644
--- a/src/engine/gtd-plugin-manager.c
+++ b/src/engine/gtd-plugin-manager.c
@@ -48,6 +48,7 @@ static guint signals[NUM_SIGNALS] = { 0, };
static const gchar * const default_plugins[] = {
"eds",
+ "planning-workspace",
"task-lists-workspace",
"inbox-panel",
"night-light",
diff --git a/src/plugins/meson.build b/src/plugins/meson.build
index 39ee21b..701a8cf 100644
--- a/src/plugins/meson.build
+++ b/src/plugins/meson.build
@@ -20,6 +20,7 @@ subdir('inbox-panel')
subdir('next-week-panel')
subdir('night-light')
subdir('peace')
+subdir('planning-workspace')
subdir('scheduled-panel')
subdir('task-lists-workspace')
subdir('today-panel')
diff --git a/src/plugins/planning-workspace/gtd-planning-workspace.c
b/src/plugins/planning-workspace/gtd-planning-workspace.c
new file mode 100644
index 0000000..65aee82
--- /dev/null
+++ b/src/plugins/planning-workspace/gtd-planning-workspace.c
@@ -0,0 +1,337 @@
+/* gtd-planning-workspace.c
+ *
+ * Copyright 2020 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "GtdPlanningWorkspace"
+
+#include "gtd-planning-workspace.h"
+
+#include "gnome-todo.h"
+
+#include <glib/gi18n.h>
+
+struct _GtdPlanningWorkspace
+{
+ GtkBin parent;
+
+ GtkListBox *planners_listbox;
+ GtkWidget *planners_menu_button;
+ GtkStack *stack;
+
+ PeasExtensionSet *planners_set;
+ GListStore *planners;
+ GtdPlanner *active_planner;
+};
+
+static void gtd_workspace_iface_init (GtdWorkspaceInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtdPlanningWorkspace, gtd_planning_workspace, GTK_TYPE_BIN,
+ G_IMPLEMENT_INTERFACE (GTD_TYPE_WORKSPACE, gtd_workspace_iface_init))
+
+enum
+{
+ PROP_0,
+ PROP_ICON,
+ PROP_TITLE,
+ N_PROPS,
+};
+
+
+/*
+ * Callbacks
+ */
+
+static gint
+compare_planners_func (gconstpointer a,
+ gconstpointer b,
+ gpointer user_data)
+{
+ gint a_priority;
+ gint b_priority;
+
+ a_priority = gtd_planner_get_priority ((GtdPlanner *)a);
+ b_priority = gtd_planner_get_priority ((GtdPlanner *)b);
+
+ return b_priority - a_priority;
+}
+
+static void
+on_planner_added_cb (PeasExtensionSet *extension_set,
+ PeasPluginInfo *plugin_info,
+ GtdPlanner *planner,
+ GtdPlanningWorkspace *self)
+{
+ g_list_store_insert_sorted (self->planners, planner, compare_planners_func, NULL);
+
+ gtk_stack_add_titled (self->stack,
+ GTK_WIDGET (planner),
+ gtd_planner_get_id (planner),
+ gtd_planner_get_title (planner));
+}
+
+static void
+on_planner_removed_cb (PeasExtensionSet *extension_set,
+ PeasPluginInfo *plugin_info,
+ GtdPlanner *planner,
+ GtdPlanningWorkspace *self)
+{
+ guint position;
+
+ g_object_ref (planner);
+
+ g_list_store_find (self->planners, planner, &position);
+ g_list_store_remove (self->planners, position);
+
+ gtk_container_remove (GTK_CONTAINER (self->stack), GTK_WIDGET (planner));
+
+ g_object_unref (planner);
+}
+
+static void
+on_stack_visible_child_cb (GtkStack *stack,
+ GParamSpec *pspec,
+ GtdPlanningWorkspace *self)
+{
+ GtdPlanner *planner;
+ GtkWidget *visible_child;
+
+ visible_child = gtk_stack_get_visible_child (stack);
+ planner = GTD_PLANNER (visible_child);
+
+ if (self->active_planner)
+ gtd_planner_deactivate (self->active_planner);
+
+ self->active_planner = planner;
+
+ if (planner)
+ {
+ g_autoptr (GIcon) icon = gtd_planner_get_icon (planner);
+
+ gtd_planner_activate (planner);
+ gtd_menu_button_set_gicon (GTD_MENU_BUTTON (self->planners_menu_button), icon);
+ }
+}
+
+static GtkWidget*
+create_planner_row_func (gpointer item,
+ gpointer user_data)
+{
+ g_autoptr (GIcon) icon = NULL;
+ GtdPlanner *planner;
+ GtkWidget *label;
+ GtkWidget *image;
+ GtkWidget *box;
+
+ planner = GTD_PLANNER (item);
+
+ 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);
+
+ icon = gtd_planner_get_icon (planner);
+ image = gtk_image_new_from_gicon (icon);
+
+ label = gtk_label_new (gtd_planner_get_title (planner));
+ gtk_widget_set_hexpand (label, TRUE);
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+
+ gtk_container_add (GTK_CONTAINER (box), image);
+ gtk_container_add (GTK_CONTAINER (box), label);
+
+ return box;
+}
+
+static void
+on_planners_listbox_row_activated_cb (GtkListBox *listbox,
+ GtkListBoxRow *row,
+ GtdPlanningWorkspace *self)
+{
+ g_autoptr (GtdPlanner) planner = NULL;
+
+ planner = g_list_model_get_item (G_LIST_MODEL (self->planners),
+ gtk_list_box_row_get_index (row));
+
+ gtk_stack_set_visible_child (self->stack, GTK_WIDGET (planner));
+
+ gtd_menu_button_popdown (GTD_MENU_BUTTON (self->planners_menu_button));
+}
+
+static void
+on_show_planner_action_activated_cb (GtkWidget *widget,
+ const gchar *action_name,
+ GVariant *parameter)
+{
+ GtdPlanningWorkspace *self;
+ const gchar *planner_id;
+
+ self = GTD_PLANNING_WORKSPACE (widget);
+ planner_id = g_variant_get_string (parameter, NULL);
+ gtk_stack_set_visible_child_name (self->stack, planner_id);
+}
+
+/*
+ * GtdWorkspace implementation
+ */
+
+static const gchar*
+gtd_planning_workspace_get_id (GtdWorkspace *workspace)
+{
+ return "planning";
+}
+
+static const gchar*
+gtd_planning_workspace_get_title (GtdWorkspace *workspace)
+{
+ return _("Planning");
+}
+
+static gint
+gtd_planning_workspace_get_priority (GtdWorkspace *workspace)
+{
+ return 1500;
+}
+
+static GIcon*
+gtd_planning_workspace_get_icon (GtdWorkspace *workspace)
+{
+ return g_themed_icon_new ("document-send-symbolic");
+}
+
+static void
+gtd_planning_workspace_activate (GtdWorkspace *workspace)
+{
+ GtdPlanningWorkspace *self = GTD_PLANNING_WORKSPACE (workspace);
+ GtdWindow *window = GTD_WINDOW (gtk_widget_get_root (GTK_WIDGET (self)));
+
+ gtd_window_embed_widget_in_header (window, self->planners_menu_button, GTK_POS_LEFT);
+}
+
+static void
+gtd_workspace_iface_init (GtdWorkspaceInterface *iface)
+{
+ iface->get_id = gtd_planning_workspace_get_id;
+ iface->get_title = gtd_planning_workspace_get_title;
+ iface->get_priority = gtd_planning_workspace_get_priority;
+ iface->get_icon = gtd_planning_workspace_get_icon;
+ iface->activate = gtd_planning_workspace_activate;
+}
+
+static void
+gtd_planning_workspace_destroy (GtkWidget *widget)
+{
+ GtdPlanningWorkspace *self = (GtdPlanningWorkspace *)widget;
+
+ g_clear_object (&self->planners_set);
+
+ GTK_WIDGET_CLASS (gtd_planning_workspace_parent_class)->destroy (widget);
+}
+
+/*
+ * GObject overrides
+ */
+
+static void
+gtd_planning_workspace_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtdWorkspace *workspace = GTD_WORKSPACE (object);
+
+ switch (prop_id)
+ {
+ case PROP_ICON:
+ g_value_take_object (value, gtd_workspace_get_icon (workspace));
+ break;
+
+ case PROP_TITLE:
+ g_value_set_string (value, gtd_workspace_get_title (workspace));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtd_planning_workspace_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+}
+
+static void
+gtd_planning_workspace_class_init (GtdPlanningWorkspaceClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = gtd_planning_workspace_get_property;
+ object_class->set_property = gtd_planning_workspace_set_property;
+
+ widget_class->destroy = gtd_planning_workspace_destroy;
+
+ g_object_class_override_property (object_class, PROP_ICON, "icon");
+ g_object_class_override_property (object_class, PROP_TITLE, "title");
+
+ g_type_ensure (GTD_TYPE_MENU_BUTTON);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/todo/plugins/planning-workspace/gtd-planning-workspace.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, GtdPlanningWorkspace, planners_listbox);
+ gtk_widget_class_bind_template_child (widget_class, GtdPlanningWorkspace, planners_menu_button);
+ gtk_widget_class_bind_template_child (widget_class, GtdPlanningWorkspace, stack);
+
+ gtk_widget_class_bind_template_callback (widget_class, on_planners_listbox_row_activated_cb);
+ gtk_widget_class_bind_template_callback (widget_class, on_stack_visible_child_cb);
+
+ gtk_widget_class_install_action (widget_class,
+ "planning.activate-planner",
+ "s",
+ on_show_planner_action_activated_cb);
+}
+
+static void
+gtd_planning_workspace_init (GtdPlanningWorkspace *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ self->planners = g_list_store_new (GTD_TYPE_PLANNER);
+ self->planners_set = peas_extension_set_new (peas_engine_get_default (),
+ GTD_TYPE_PLANNER,
+ NULL);
+ peas_extension_set_foreach (self->planners_set,
+ (PeasExtensionSetForeachFunc) on_planner_added_cb,
+ self);
+
+ g_object_connect (self->planners_set,
+ "signal::extension-added", G_CALLBACK (on_planner_added_cb), self,
+ "signal::extension-removed", G_CALLBACK (on_planner_removed_cb), self,
+ NULL);
+
+ gtk_list_box_bind_model (self->planners_listbox,
+ G_LIST_MODEL (self->planners),
+ create_planner_row_func,
+ self,
+ NULL);
+}
diff --git a/src/plugins/planning-workspace/gtd-planning-workspace.h
b/src/plugins/planning-workspace/gtd-planning-workspace.h
new file mode 100644
index 0000000..5df4cbc
--- /dev/null
+++ b/src/plugins/planning-workspace/gtd-planning-workspace.h
@@ -0,0 +1,30 @@
+/* gtd-planning-workspace.h
+ *
+ * Copyright 2020 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTD_TYPE_PLANNING_WORKSPACE (gtd_planning_workspace_get_type())
+G_DECLARE_FINAL_TYPE (GtdPlanningWorkspace, gtd_planning_workspace, GTD, PLANNING_WORKSPACE, GtkBin)
+
+G_END_DECLS
diff --git a/src/plugins/planning-workspace/gtd-planning-workspace.ui
b/src/plugins/planning-workspace/gtd-planning-workspace.ui
new file mode 100644
index 0000000..915b9c6
--- /dev/null
+++ b/src/plugins/planning-workspace/gtd-planning-workspace.ui
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="GtdPlanningWorkspace" parent="GtkBin">
+
+ <!-- Planners Stack -->
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="hexpand">true</property>
+ <property name="vexpand">true</property>
+ <property name="transition_duration">250</property>
+ <property name="transition_type">crossfade</property>
+ <signal name="notify::visible-child" handler="on_stack_visible_child_cb"
object="GtdPlanningWorkspace" swapped="no"/>
+ <style>
+ <class name="background"/>
+ </style>
+ </object>
+ </child>
+
+ </template>
+
+ <!-- Planners Popover -->
+ <object class="GtdMenuButton" id="planners_menu_button">
+ <property name="can_focus">1</property>
+ <property name="receives_default">1</property>
+ <property name="popover">
+ <object class="GtkPopover">
+ <property name="can_focus">False</property>
+ <property name="position">bottom</property>
+ <style>
+ <class name="custom-menu" />
+ </style>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Switch Planner</property>
+ <style>
+ <class name="title" />
+ </style>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkListBox" id="planners_listbox">
+ <property name="selection-mode">none</property>
+ <signal name="row-activated" handler="on_planners_listbox_row_activated_cb"
object="GtdPlanningWorkspace" swapped="no" />
+ <style>
+ <class name="transparent" />
+ </style>
+ </object>
+ </child>
+
+ </object>
+ </child>
+ </object>
+ </property>
+ </object>
+
+</interface>
diff --git a/src/plugins/planning-workspace/meson.build b/src/plugins/planning-workspace/meson.build
new file mode 100644
index 0000000..c4dd704
--- /dev/null
+++ b/src/plugins/planning-workspace/meson.build
@@ -0,0 +1,13 @@
+plugins_ldflags += ['-Wl,--undefined=planning_workspace_plugin_register_types']
+
+plugins_sources += files(
+ 'gtd-planning-workspace.c',
+ 'planning-workspace-plugin.c',
+)
+
+plugins_sources += gnome.compile_resources(
+ 'planning-workspace',
+ 'planning-workspace.gresource.xml',
+ c_name: 'planning_workspace',
+ export: true,
+)
diff --git a/src/plugins/planning-workspace/planning-workspace-plugin.c
b/src/plugins/planning-workspace/planning-workspace-plugin.c
new file mode 100644
index 0000000..6ea0a50
--- /dev/null
+++ b/src/plugins/planning-workspace/planning-workspace-plugin.c
@@ -0,0 +1,31 @@
+/* planning-workspace-plugin.c
+ *
+ * Copyright 2020 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "gnome-todo.h"
+
+#include "gtd-planning-workspace.h"
+
+G_MODULE_EXPORT void
+planning_workspace_plugin_register_types (PeasObjectModule *module)
+{
+ peas_object_module_register_extension_type (module,
+ GTD_TYPE_WORKSPACE,
+ GTD_TYPE_PLANNING_WORKSPACE);
+}
diff --git a/src/plugins/planning-workspace/planning-workspace.gresource.xml
b/src/plugins/planning-workspace/planning-workspace.gresource.xml
new file mode 100644
index 0000000..d409f93
--- /dev/null
+++ b/src/plugins/planning-workspace/planning-workspace.gresource.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/todo/plugins/planning-workspace">
+ <file>gtd-planning-workspace.ui</file>
+ <file>planning-workspace.plugin</file>
+ </gresource>
+</gresources>
diff --git a/src/plugins/planning-workspace/planning-workspace.plugin
b/src/plugins/planning-workspace/planning-workspace.plugin
new file mode 100644
index 0000000..869614a
--- /dev/null
+++ b/src/plugins/planning-workspace/planning-workspace.plugin
@@ -0,0 +1,14 @@
+[Plugin]
+Name = Planning Workspace
+Module = planning-workspace
+Description = Plugin implementing the planning workspace
+Version = @VERSION@
+Authors = Georges Basile Stavracas Neto <gbsneto gnome org>
+Copyright = Copyleft © The To Do maintainers
+Website = https://wiki.gnome.org/Apps/Todo
+Builtin = true
+Hidden = true
+License = GPL
+Loader = C
+Embedded = planning_workspace_plugin_register_types
+Depends =
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]