[gnome-builder/wip/chergert/panel-addin-idea] wip



commit c2e83c77773023322a34436b7a405289fd697cbd
Author: Christian Hergert <christian hergert me>
Date:   Wed Sep 30 04:32:47 2015 -0700

    wip

 data/theme/Adwaita-shared.css                      |    2 +-
 plugins/symbol-tree/Makefile.am                    |   37 ++--
 .../{symbol-tree.ui => gb-symbol-tree-panel.ui}    |    3 +-
 plugins/symbol-tree/gb-symbol-tree-panel.vala      |  215 ++++++++++++++++++++
 ...rce.xml => gb-symbol-tree-plugin.gresource.xml} |    2 +-
 plugins/symbol-tree/symbol-tree.plugin             |    2 +-
 src/Makefile.am                                    |    3 +
 src/gb-enums.c.in                                  |    1 +
 src/gnome-builder.h                                |    1 +
 src/tree/gb-tree.c                                 |    2 +-
 src/workbench/gb-workbench-private.h               |    2 +
 src/workbench/gb-workbench.c                       |  104 +++++++++-
 src/workspace/gb-panel-addin.c                     |   85 ++++++++
 src/workspace/gb-panel-addin.h                     |   61 ++++++
 14 files changed, 491 insertions(+), 29 deletions(-)
---
diff --git a/data/theme/Adwaita-shared.css b/data/theme/Adwaita-shared.css
index 494135d..e6eecf2 100644
--- a/data/theme/Adwaita-shared.css
+++ b/data/theme/Adwaita-shared.css
@@ -143,7 +143,7 @@ DhSidebar GtkSearchEntry {
 /*
  * Adjust symbol panel styling.
  */
-SymbolTree GtkSearchEntry {
+GbSymbolTreePanel GtkSearchEntry {
   border-left: none;
   border-right: none;
   border-top: none;
diff --git a/plugins/symbol-tree/Makefile.am b/plugins/symbol-tree/Makefile.am
index 7ccc1eb..27efbac 100644
--- a/plugins/symbol-tree/Makefile.am
+++ b/plugins/symbol-tree/Makefile.am
@@ -6,20 +6,27 @@ CLEANFILES =
 EXTRA_DIST = $(plugin_DATA)
 
 plugindir = $(libdir)/gnome-builder/plugins
-plugin_LTLIBRARIES = libsymbol-tree.la
+plugin_LTLIBRARIES = libsymbol-tree-plugin.la
 dist_plugin_DATA = symbol-tree.plugin
 
-libsymbol_tree_la_SOURCES = \
-       symbol-tree-builder.c \
-       symbol-tree-builder.h \
-       symbol-tree-resources.c \
-       symbol-tree-resources.h \
-       symbol-tree.c \
-       symbol-tree.h \
+libsymbol_tree_plugin_la_SOURCES = \
+       gb-symbol-tree-panel.vala \
+       gb-symbol-tree-resources.c \
+       gb-symbol-tree-resources.h \
+       $(NULL)
+
+libsymbol_tree_plugin_la_VALAFLAGS = \
+       --gresources gb-symbol-tree-plugin.gresource.xml \
+       --target-glib=2.38 \
+       --vapidir $(top_builddir)/libide \
+       --vapidir $(top_builddir)/src \
+       --pkg libide-1.0 \
+       --pkg gnome-builder-1.0 \
        $(NULL)
 
 # XXX: temporary, since we need to extract lots of src/ into plugins
-libsymbol_tree_la_CFLAGS = \
+libsymbol_tree_plugin_la_CFLAGS = \
+       -DGETTEXT_PACKAGE="\"gnome-builder\"" \
        $(BUILDER_CFLAGS) \
        -I$(top_srcdir)/src \
        -I$(top_srcdir)/src/documents \
@@ -33,21 +40,21 @@ libsymbol_tree_la_CFLAGS = \
        -I$(top_srcdir)/contrib/egg \
        $(NULL)
 
-libsymbol_tree_la_LIBADD = \
+libsymbol_tree_plugin_la_LIBADD = \
        $(BUILDER_LIBS) \
        $(top_builddir)/libide/libide-1.0.la \
        $(NULL)
 
-libsymbol_tree_la_LDFLAGS = \
+libsymbol_tree_plugin_la_LDFLAGS = \
        $(OPTIMIZE_LDFLAGS) \
        -avoid-version \
        -module \
        $(NULL)
 
-glib_resources_c = symbol-tree-resources.c
-glib_resources_h = symbol-tree-resources.h
-glib_resources_xml = symbol-tree.gresource.xml
-glib_resources_namespace = symbol_tree
+glib_resources_c = gb-symbol-tree-resources.c
+glib_resources_h = gb-symbol-tree-resources.h
+glib_resources_xml = gb-symbol-tree-plugin.gresource.xml
+glib_resources_namespace = gb_symbol_tree
 include $(top_srcdir)/build/autotools/Makefile.am.gresources
 
 include $(top_srcdir)/plugins/Makefile.plugin
diff --git a/plugins/symbol-tree/symbol-tree.ui b/plugins/symbol-tree/gb-symbol-tree-panel.ui
similarity index 85%
rename from plugins/symbol-tree/symbol-tree.ui
rename to plugins/symbol-tree/gb-symbol-tree-panel.ui
index 5cd0a80..283cbf7 100644
--- a/plugins/symbol-tree/symbol-tree.ui
+++ b/plugins/symbol-tree/gb-symbol-tree-panel.ui
@@ -1,13 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.16 -->
-  <template class="SymbolTree" parent="GtkBox">
+  <template class="GbSymbolTreePanel" parent="GtkBox">
     <property name="vexpand">true</property>
     <property name="visible">true</property>
     <property name="orientation">vertical</property>
     <child>
       <object class="GtkSearchEntry" id="search_entry">
         <property name="visible">true</property>
+       <signal name="changed" handler="on_search_entry_changed" object="GbSymbolTreePanel" swapped="yes"/>
       </object>
     </child>
     <child>
diff --git a/plugins/symbol-tree/gb-symbol-tree-panel.vala b/plugins/symbol-tree/gb-symbol-tree-panel.vala
new file mode 100644
index 0000000..741426f
--- /dev/null
+++ b/plugins/symbol-tree/gb-symbol-tree-panel.vala
@@ -0,0 +1,215 @@
+/* symbol-tree.vala
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+using Gb;
+using GLib;
+using Gtk;
+using Ide;
+using Peas;
+
+namespace Gb
+{
+       [GtkTemplate (ui = "/org/gnome/builder/plugins/symbol-tree/gb-symbol-tree-panel.ui")]
+       public class SymbolTreePanel: Gtk.Box, Gb.PanelAddin
+       {
+               [GtkChild]
+               Gtk.SearchEntry search_entry;
+
+               [GtkChild]
+               Gb.Tree tree;
+
+               weak Gb.View? _current_view;
+               TreeBuilder tree_builder;
+               ulong handler_id;
+
+               construct {
+                       this.tree_builder = new SymbolTreeBuilder ();
+               }
+
+               ~SymbolTreePanel ()
+               {
+stdout.printf ("FINALIZE\n");
+               }
+
+               public Gb.View? current_view {
+                       get { return this._current_view; }
+                       set {
+                               if (this._current_view != value) {
+                                       if (value == null) {
+                                               this._current_view = null;
+                                               this.reload ();
+                                       }
+                                       this._current_view = value;
+                                       this.reload ();
+                               }
+                       }
+               }
+
+               public Gb.PanelPosition get_position () { return Gb.PanelPosition.RIGHT; }
+               public unowned string get_icon_name () { return _("lang-function-symbolic"); }
+               public unowned string get_title () { return _("Symbol Tree"); }
+
+               public void load (Gb.Workbench workbench)
+               {
+                       this.handler_id = workbench.notify["active-view"].connect (() => {
+                               var view = workbench.get_active_view ();
+                               if (view is Gb.EditorView)
+                                       this.current_view = (Gb.View)view;
+                               else
+                                       this.current_view = null;
+                       });
+               }
+
+               public void unload (Gb.Workbench workbench)
+               {
+stdout.printf ("unload.....\n");
+                       workbench.disconnect (this.handler_id);
+               }
+
+               [GtkCallback]
+               void on_search_entry_changed (Gtk.Editable editable) {
+                       var text = search_entry.get_text ();
+
+                       if (text == null || text[0] == 0) {
+                               this.tree.set_filter (null);
+                               return;
+                       }
+
+                       var pattern = new Ide.PatternSpec (text);
+                       this.tree.set_filter ((tree, node) => {
+                               return pattern.match (node.text);
+                       });
+               }
+
+               public void reload ()
+               {
+                       /* Clear existing state */
+                       this.search_entry.text = "";
+                       this.tree.root = new Gb.TreeNode ();
+
+                       if (this._current_view == null)
+                               return;
+
+                       var document = this._current_view.document;
+                       if (!(document is Ide.Buffer))
+                               return;
+               }
+       }
+
+       public class SymbolTreeBuilder: Gb.TreeBuilder
+       {
+               Ide.SymbolTree? find_symbol_tree (Gb.TreeNode? node)
+               {
+                       if (node == null)
+                               return null;
+                       if (node.item is Ide.SymbolTree)
+                               return (Ide.SymbolTree)node.item;
+                       return find_symbol_tree (node.parent);
+               }
+
+               public override void build_node (Gb.TreeNode node)
+               {
+                       if (!(node.item is Ide.SymbolNode))
+                               return;
+
+                       var symbol_tree = find_symbol_tree (node);
+                       var parent = node.item as Ide.SymbolNode;
+                       var n_children = symbol_tree.get_n_children (parent);
+
+                       for (var i = 0; i < n_children; i++) {
+                               var symbol = symbol_tree.get_nth_child (parent, i);
+                               unowned string? icon_name;
+
+                               switch (symbol.kind) {
+                               case Ide.SymbolKind.FUNCTION:
+                                       icon_name = "lang-function-symbolic";
+                                       break;
+
+                               case Ide.SymbolKind.ENUM:
+                                       icon_name = "lang-enum-symbolic";
+                                       break;
+
+                               case Ide.SymbolKind.ENUM_VALUE:
+                                       icon_name = "lang-enum-value-symbolic";
+                                       break;
+
+                               case Ide.SymbolKind.STRUCT:
+                                       icon_name = "lang-struct-symbolic";
+                                       break;
+
+                               case Ide.SymbolKind.CLASS:
+                                       icon_name = "lang-class-symbolic";
+                                       break;
+
+                               case Ide.SymbolKind.METHOD:
+                                       icon_name = "lang-method-symbolic";
+                                       break;
+
+                               case Ide.SymbolKind.UNION:
+                                       icon_name = "lang-union-symbolic";
+                                       break;
+
+                               case Ide.SymbolKind.SCALAR:
+                               case Ide.SymbolKind.FIELD:
+                               case Ide.SymbolKind.VARIABLE:
+                                       icon_name = "lang-variable-symbolic";
+                                       break;
+
+                               case Ide.SymbolKind.NONE:
+                               default:
+                                       icon_name = null;
+                                       break;
+                               }
+
+                               var child = new Gb.TreeNode () {
+                                       text = symbol.name,
+                                       icon_name = icon_name,
+                                       item = symbol
+                               };
+
+                               node.append (child);
+                       }
+               }
+
+               public override bool node_activated (Gb.TreeNode node)
+               {
+                       var workbench = this.tree.get_ancestor (typeof (Gb.Workbench)) as Gb.Workbench;
+                       var view_grid = workbench.get_view_grid () as Gb.ViewGrid;
+                       var stack = view_grid.get_last_focus () as Gb.ViewStack;
+
+                       if (node.item is Ide.SymbolNode) {
+                               var symbol_node = node.item as Ide.SymbolNode;
+                               var location = symbol_node.get_location ();
+                               if (location != null) {
+                                       stack.focus_location (location);
+                                       return true;
+                               }
+                       }
+
+                       return false;
+               }
+       }
+}
+
+[ModuleInit]
+public void peas_register_types (GLib.TypeModule module)
+{
+       var peas = (Peas.ObjectModule)module;
+
+       peas.register_extension_type (typeof (Gb.PanelAddin), typeof (Gb.SymbolTreePanel));
+}
diff --git a/plugins/symbol-tree/symbol-tree.gresource.xml 
b/plugins/symbol-tree/gb-symbol-tree-plugin.gresource.xml
similarity index 77%
rename from plugins/symbol-tree/symbol-tree.gresource.xml
rename to plugins/symbol-tree/gb-symbol-tree-plugin.gresource.xml
index 4b10ecf..b95833b 100644
--- a/plugins/symbol-tree/symbol-tree.gresource.xml
+++ b/plugins/symbol-tree/gb-symbol-tree-plugin.gresource.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <gresources>
   <gresource prefix="/org/gnome/builder/plugins/symbol-tree">
-    <file>symbol-tree.ui</file>
+    <file>gb-symbol-tree-panel.ui</file>
   </gresource>
 </gresources>
diff --git a/plugins/symbol-tree/symbol-tree.plugin b/plugins/symbol-tree/symbol-tree.plugin
index bdf932f..0ed81a0 100644
--- a/plugins/symbol-tree/symbol-tree.plugin
+++ b/plugins/symbol-tree/symbol-tree.plugin
@@ -1,5 +1,5 @@
 [Plugin]
-Module=symbol-tree
+Module=symbol-tree-plugin
 Name=Symbol Tree
 Description=Provides a Symbol Tree for the currently focused document.
 Authors=Christian Hergert <christian hergert me>
diff --git a/src/Makefile.am b/src/Makefile.am
index 94bc134..6ad47e3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,6 +36,8 @@ libgnome_builder_public_sources = \
        views/gb-view-stack.h \
        views/gb-view-grid.c \
        views/gb-view-grid.h \
+       workspace/gb-panel-addin.c \
+       workspace/gb-panel-addin.h \
        workbench/gb-workbench.c \
        workbench/gb-workbench.h \
        $(NULL)
@@ -195,6 +197,7 @@ glib_enum_h = gb-enums.h
 glib_enum_c = gb-enums.c
 glib_enum_headers =  \
        views/gb-view-stack-split.h \
+       workspace/gb-panel-addin.h \
        $(NULL)
 include $(top_srcdir)/build/autotools/Makefile.am.enums
 
diff --git a/src/gb-enums.c.in b/src/gb-enums.c.in
index f4df828..5f4ec5d 100644
--- a/src/gb-enums.c.in
+++ b/src/gb-enums.c.in
@@ -6,6 +6,7 @@
 #include "ide-enums.h"
 
 #include "gb-view-stack-split.h"
+#include "gb-panel-addin.h"
 
 /*** END file-header ***/
 
diff --git a/src/gnome-builder.h b/src/gnome-builder.h
index 59c5f18..0f3c913 100644
--- a/src/gnome-builder.h
+++ b/src/gnome-builder.h
@@ -34,6 +34,7 @@
 #include "views/gb-view-stack.h"
 #include "views/gb-view-stack-split.h"
 #include "workbench/gb-workbench.h"
+#include "workspace/gb-panel-addin.h"
 
 #include "gb-enums.h"
 
diff --git a/src/tree/gb-tree.c b/src/tree/gb-tree.c
index 7369c2b..9dc5b5e 100644
--- a/src/tree/gb-tree.c
+++ b/src/tree/gb-tree.c
@@ -1636,7 +1636,7 @@ gb_tree_model_filter_visible_func (GtkTreeModel *model,
 /**
  * gb_tree_set_filter:
  * @self: A #GbTree
- * @filter_func: (scope notified): A callback to determien visibility.
+ * @filter_func: (allow-none) (scope notified): A callback to determien visibility.
  * @filter_data: User data for @filter_func.
  * @filter_data_destroy: Destroy notify for @filter_data.
  *
diff --git a/src/workbench/gb-workbench-private.h b/src/workbench/gb-workbench-private.h
index 8ec7d8e..429e991 100644
--- a/src/workbench/gb-workbench-private.h
+++ b/src/workbench/gb-workbench-private.h
@@ -24,6 +24,7 @@
 #include <libpeas/peas.h>
 #include <ide.h>
 
+#include "gb-panel-addin.h"
 #include "gb-project-tree.h"
 #include "gb-search-box.h"
 #include "gb-slider.h"
@@ -42,6 +43,7 @@ struct _GbWorkbench
   GCancellable           *unload_cancellable;
   gchar                  *current_folder_uri;
   PeasExtensionSet       *extensions;
+  PeasExtensionSet       *panel_addins;
 
   /* Weak Reference */
   GtkWidget              *active_view;
diff --git a/src/workbench/gb-workbench.c b/src/workbench/gb-workbench.c
index 1ba2ef7..6a65e0f 100644
--- a/src/workbench/gb-workbench.c
+++ b/src/workbench/gb-workbench.c
@@ -466,6 +466,66 @@ gb_workbench__extension_removed (PeasExtensionSet *set,
 }
 
 static void
+gb_workbench__panel_added (PeasExtensionSet *set,
+                           PeasPluginInfo   *plugin_info,
+                           GbPanelAddin     *addin,
+                           GbWorkbench      *self)
+{
+  GbPanelPosition position;
+  GtkWidget *pane;
+
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+  g_assert (GB_IS_PANEL_ADDIN (addin));
+  g_assert (GB_IS_WORKBENCH (self));
+
+  g_object_ref_sink (addin);
+
+  position = gb_panel_addin_get_position (addin);
+
+  switch (position)
+    {
+    case GB_PANEL_LEFT:
+      pane = gb_workspace_get_left_pane (self->workspace);
+      break;
+
+    case GB_PANEL_RIGHT:
+      pane = gb_workspace_get_right_pane (self->workspace);
+      break;
+
+    case GB_PANEL_BOTTOM:
+      pane = gb_workspace_get_bottom_pane (self->workspace);
+      break;
+
+    default:
+      g_warning ("Unknown panel position: %02x", position);
+      return;
+    }
+
+  gb_workspace_pane_add_page (GB_WORKSPACE_PANE (pane),
+                              GTK_WIDGET (addin),
+                              gb_panel_addin_get_title (addin),
+                              gb_panel_addin_get_icon_name (addin));
+
+  gb_panel_addin_load (addin, self);
+}
+
+static void
+gb_workbench__panel_removed (PeasExtensionSet *set,
+                             PeasPluginInfo   *plugin_info,
+                             GbPanelAddin     *addin,
+                             GbWorkbench      *self)
+{
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+  g_assert (GB_IS_PANEL_ADDIN (addin));
+  g_assert (GB_IS_WORKBENCH (self));
+
+  gb_panel_addin_unload (addin, self);
+  gtk_widget_destroy (GTK_WIDGET (addin));
+}
+
+static void
 gb_workbench_constructed (GObject *object)
 {
   GbWorkbench *self = (GbWorkbench *)object;
@@ -498,6 +558,21 @@ gb_workbench_constructed (GObject *object)
                     G_CALLBACK (gb_workbench__extension_removed),
                     self);
 
+  self->panel_addins = peas_extension_set_new (peas_engine_get_default (),
+                                               GB_TYPE_PANEL_ADDIN,
+                                               NULL);
+  peas_extension_set_foreach (self->panel_addins,
+                              (PeasExtensionSetForeachFunc)gb_workbench__panel_added,
+                              self);
+  g_signal_connect (self->panel_addins,
+                    "extension-added",
+                    G_CALLBACK (gb_workbench__panel_added),
+                    self);
+  g_signal_connect (self->panel_addins,
+                    "extension-removed",
+                    G_CALLBACK (gb_workbench__panel_removed),
+                    self);
+
   gtk_widget_grab_focus (GTK_WIDGET (self->workspace));
 
   IDE_EXIT;
@@ -560,6 +635,16 @@ chainup:
 }
 
 static void
+gb_workbench_real_unload (GbWorkbench *self,
+                          IdeContext  *context)
+{
+  g_assert (GB_IS_WORKBENCH (self));
+  g_assert (IDE_IS_CONTEXT (context));
+
+  g_clear_object (&self->panel_addins);
+}
+
+static void
 gb_workbench_dispose (GObject *object)
 {
   GbWorkbench *self = (GbWorkbench *)object;
@@ -584,9 +669,9 @@ gb_workbench_finalize (GObject *object)
 
   IDE_ENTRY;
 
+  g_clear_object (&self->extensions);
   g_clear_object (&self->context);
   g_clear_pointer (&self->current_folder_uri, g_free);
-  g_clear_object (&self->extensions);
 
   G_OBJECT_CLASS (gb_workbench_parent_class)->finalize (object);
 
@@ -692,14 +777,14 @@ gb_workbench_class_init (GbWorkbenchClass *klass)
   g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
 
   gSignals [UNLOAD] =
-    g_signal_new ("unload",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL, NULL,
-                  G_TYPE_NONE,
-                  1,
-                  IDE_TYPE_CONTEXT);
+    g_signal_new_class_handler ("unload",
+                                G_TYPE_FROM_CLASS (klass),
+                                G_SIGNAL_RUN_FIRST,
+                                G_CALLBACK (gb_workbench_real_unload),
+                                NULL, NULL, NULL,
+                                G_TYPE_NONE,
+                                1,
+                                IDE_TYPE_CONTEXT);
 
   GB_WIDGET_CLASS_TEMPLATE (klass, "gb-workbench.ui");
   GB_WIDGET_CLASS_BIND (klass, GbWorkbench, gear_menu_button);
@@ -715,6 +800,7 @@ gb_workbench_class_init (GbWorkbenchClass *klass)
   g_type_ensure (GB_TYPE_VIEW_GRID);
   g_type_ensure (GB_TYPE_WORKSPACE);
   g_type_ensure (GB_TYPE_WORKSPACE_PANE);
+  g_type_ensure (GB_TYPE_PANEL_ADDIN);
   g_type_ensure (GEDIT_TYPE_MENU_STACK_SWITCHER);
 }
 
diff --git a/src/workspace/gb-panel-addin.c b/src/workspace/gb-panel-addin.c
new file mode 100644
index 0000000..6a6b052
--- /dev/null
+++ b/src/workspace/gb-panel-addin.c
@@ -0,0 +1,85 @@
+/* gb-panel-addin.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#define G_LOG_DOMAIN "gb-panel-addin"
+
+#include <ide.h>
+
+#include "gb-panel-addin.h"
+
+G_DEFINE_INTERFACE (GbPanelAddin, gb_panel_addin, GTK_TYPE_WIDGET)
+
+GbPanelPosition
+gb_panel_addin_get_position (GbPanelAddin *self)
+{
+  g_return_val_if_fail (GB_IS_PANEL_ADDIN (self), GB_PANEL_LEFT);
+
+  if (GB_PANEL_ADDIN_GET_IFACE (self)->get_position)
+    return GB_PANEL_ADDIN_GET_IFACE (self)->get_position (self);
+
+  return GB_PANEL_LEFT;
+}
+
+const gchar *
+gb_panel_addin_get_icon_name (GbPanelAddin *self)
+{
+  g_return_val_if_fail (GB_IS_PANEL_ADDIN (self), NULL);
+
+  if (GB_PANEL_ADDIN_GET_IFACE (self)->get_icon_name)
+    return GB_PANEL_ADDIN_GET_IFACE (self)->get_icon_name (self);
+
+  return NULL;
+}
+
+const gchar *
+gb_panel_addin_get_title (GbPanelAddin *self)
+{
+  g_return_val_if_fail (GB_IS_PANEL_ADDIN (self), NULL);
+
+  if (GB_PANEL_ADDIN_GET_IFACE (self)->get_title)
+    return GB_PANEL_ADDIN_GET_IFACE (self)->get_title (self);
+
+  return NULL;
+}
+
+void
+gb_panel_addin_load (GbPanelAddin *self,
+                     GbWorkbench  *workbench)
+{
+  g_return_if_fail (GB_IS_PANEL_ADDIN (self));
+  g_return_if_fail (GB_IS_WORKBENCH (workbench));
+
+  if (GB_PANEL_ADDIN_GET_IFACE (self)->load)
+    GB_PANEL_ADDIN_GET_IFACE (self)->load (self, workbench);
+}
+
+void
+gb_panel_addin_unload (GbPanelAddin *self,
+                       GbWorkbench  *workbench)
+{
+  g_return_if_fail (GB_IS_PANEL_ADDIN (self));
+  g_return_if_fail (GB_IS_WORKBENCH (workbench));
+
+  if (GB_PANEL_ADDIN_GET_IFACE (self)->unload)
+    GB_PANEL_ADDIN_GET_IFACE (self)->unload (self, workbench);
+}
+
+static void
+gb_panel_addin_default_init (GbPanelAddinInterface *iface)
+{
+}
diff --git a/src/workspace/gb-panel-addin.h b/src/workspace/gb-panel-addin.h
new file mode 100644
index 0000000..c0ee12d
--- /dev/null
+++ b/src/workspace/gb-panel-addin.h
@@ -0,0 +1,61 @@
+/* gb-panel-addin.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#ifndef GB_PANEL_ADDIN_H
+#define GB_PANEL_ADDIN_H
+
+#include "gb-enums.h"
+#include "gb-workbench.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_PANEL_ADDIN (gb_panel_addin_get_type())
+
+G_DECLARE_INTERFACE (GbPanelAddin, gb_panel_addin, GB, PANEL_ADDIN, GtkWidget)
+
+typedef enum
+{
+  GB_PANEL_LEFT,
+  GB_PANEL_RIGHT,
+  GB_PANEL_BOTTOM,
+} GbPanelPosition;
+
+struct _GbPanelAddinInterface
+{
+  GTypeInterface parent_instance;
+
+  const gchar     *(*get_icon_name) (GbPanelAddin *self);
+  const gchar     *(*get_title)     (GbPanelAddin *self);
+  GbPanelPosition  (*get_position)  (GbPanelAddin *self);
+  void             (*load)          (GbPanelAddin *self,
+                                     GbWorkbench  *workbench);
+  void             (*unload)        (GbPanelAddin *self,
+                                     GbWorkbench  *workbench);
+};
+
+const gchar     *gb_panel_addin_get_title     (GbPanelAddin *self);
+const gchar     *gb_panel_addin_get_icon_name (GbPanelAddin *self);
+GbPanelPosition  gb_panel_addin_get_position  (GbPanelAddin *self);
+void             gb_panel_addin_load          (GbPanelAddin *self,
+                                               GbWorkbench  *workbench);
+void             gb_panel_addin_unload        (GbPanelAddin *self,
+                                               GbWorkbench  *workbench);
+
+G_END_DECLS
+
+#endif /* GB_PANEL_ADDIN_H */


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