[gnome-builder] editor: add IdeEditorAddin
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] editor: add IdeEditorAddin
- Date: Wed, 19 Jul 2017 11:18:58 +0000 (UTC)
commit d12db0b2508fe0bca94769264bfa328efbb5c782
Author: Christian Hergert <chergert redhat com>
Date: Fri Jul 14 15:48:16 2017 -0700
editor: add IdeEditorAddin
This addin interface is used to extend the editor perspective.
This can be handy over the workbench addin because it allows you
to write a bit less code and use some of the view tracking that
is specific to the editor perspective.
libide/editor/ide-editor-addin.c | 149 ++++++++++++++++++++++++++++++++
libide/editor/ide-editor-addin.h | 52 +++++++++++
libide/editor/ide-editor-perspective.c | 121 ++++++++++++++++++++++++++
libide/ide.h | 1 +
libide/meson.build | 2 +
5 files changed, 325 insertions(+), 0 deletions(-)
---
diff --git a/libide/editor/ide-editor-addin.c b/libide/editor/ide-editor-addin.c
new file mode 100644
index 0000000..982847c
--- /dev/null
+++ b/libide/editor/ide-editor-addin.c
@@ -0,0 +1,149 @@
+/* ide-editor-addin.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat 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/>.
+ */
+
+#define G_LOG_DOMAIN "ide-editor-addin"
+
+#include "editor/ide-editor-addin.h"
+#include "editor/ide-editor-private.h"
+
+/**
+ * SECTION:ide-editor-addin
+ * @title: IdeEditorAddin
+ * @short_description: Addins for the editor perspective
+ *
+ * The #IdeEditorAddin interface provides a simplified interface for
+ * plugins that want to perform operations in, or extend, the editor
+ * perspective.
+ *
+ * This differs from the #IdeWorkbenchAddin in that you are given access
+ * to the editor perspective directly. This can be convenient if all you
+ * need to do is add panels or perform view tracking of the current
+ * focus view.
+ */
+
+G_DEFINE_INTERFACE (IdeEditorAddin, ide_editor_addin, G_TYPE_OBJECT)
+
+static void
+ide_editor_addin_default_init (IdeEditorAddinInterface *iface)
+{
+}
+
+/**
+ * ide_editor_addin_load:
+ * @self: an #IdeEditorAddin
+ * @perspective: an #IdeEditorPeprsective
+ *
+ * This method is called to load the addin.
+ *
+ * The addin should add any necessary UI components.
+ *
+ * Since: 3.26
+ */
+void
+ide_editor_addin_load (IdeEditorAddin *self,
+ IdeEditorPerspective *perspective)
+{
+ g_return_if_fail (IDE_IS_EDITOR_ADDIN (self));
+ g_return_if_fail (IDE_IS_EDITOR_PERSPECTIVE (perspective));
+
+ if (IDE_EDITOR_ADDIN_GET_IFACE (self)->load)
+ IDE_EDITOR_ADDIN_GET_IFACE (self)->load (self, perspective);
+}
+
+/**
+ * ide_editor_addin_unload:
+ * @self: an #IdeEditorAddin
+ * @perspective: an #IdeEditorPerspective
+ *
+ * This method is called to unload the addin.
+ *
+ * The addin is responsible for undoing anything it setup in load
+ * and cancel any in-flight or pending tasks immediately.
+ *
+ * Since: 3.26
+ */
+void
+ide_editor_addin_unload (IdeEditorAddin *self,
+ IdeEditorPerspective *perspective)
+{
+ g_return_if_fail (IDE_IS_EDITOR_ADDIN (self));
+ g_return_if_fail (IDE_IS_EDITOR_PERSPECTIVE (perspective));
+
+ if (IDE_EDITOR_ADDIN_GET_IFACE (self)->unload)
+ IDE_EDITOR_ADDIN_GET_IFACE (self)->unload (self, perspective);
+}
+
+/**
+ * ide_editor_addin_view_set:
+ * @self: an #IdeEditorAddin
+ * @view: (nullable): an #IdeLayoutView or %NULL
+ *
+ * This function is called when the current view has changed in the
+ * editor perspective. This could happen when the user focus another
+ * view, either with the keyboard, mouse, touch, or by opening a new
+ * buffer.
+ *
+ * Note that @view may not be an #IdeEditorView, so consumers of this
+ * interface should take appropriate action based on the type.
+ *
+ * When the last view is removed, @view will be %NULL to indicate to the
+ * addin that there is no active view.
+ *
+ * Since: 3.26
+ */
+void
+ide_editor_addin_view_set (IdeEditorAddin *self,
+ IdeLayoutView *view)
+{
+ g_return_if_fail (IDE_IS_EDITOR_ADDIN (self));
+ g_return_if_fail (!view || IDE_IS_LAYOUT_VIEW (view));
+
+ if (IDE_EDITOR_ADDIN_GET_IFACE (self)->view_set)
+ IDE_EDITOR_ADDIN_GET_IFACE (self)->view_set (self, view);
+}
+
+/**
+ * ide_editor_addin_find_by_module_name:
+ * @editor: an #IdeEditorPerspective
+ * @module_name: the module name of the addin
+ *
+ * This function allows locating an #IdeEditorAddin that is attached
+ * to the #IdeEditorPerspective by the addin module name. The module name
+ * should match the value specified in the ".plugin" module definition.
+ *
+ * Returns: (transfer none) (nullable): An #IdeEditorAddin or %NULL
+ */
+IdeEditorAddin *
+ide_editor_addin_find_by_module_name (IdeEditorPerspective *editor,
+ const gchar *module_name)
+{
+ PeasExtension *ret = NULL;
+ PeasPluginInfo *plugin_info;
+
+ g_return_val_if_fail (IDE_IS_EDITOR_PERSPECTIVE (editor), NULL);
+ g_return_val_if_fail (module_name != NULL, NULL);
+
+ plugin_info = peas_engine_get_plugin_info (peas_engine_get_default (), module_name);
+
+ if (plugin_info != NULL)
+ ret = peas_extension_set_get_extension (editor->addins, plugin_info);
+ else
+ g_warning ("No such module found \"%s\"", module_name);
+
+ return ret ? IDE_EDITOR_ADDIN (ret) : NULL;
+}
diff --git a/libide/editor/ide-editor-addin.h b/libide/editor/ide-editor-addin.h
new file mode 100644
index 0000000..1a9e995
--- /dev/null
+++ b/libide/editor/ide-editor-addin.h
@@ -0,0 +1,52 @@
+/* ide-editor-addin.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat 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/>.
+ */
+
+#pragma once
+
+#include "editor/ide-editor-perspective.h"
+#include "layout/ide-layout-view.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_EDITOR_ADDIN (ide_editor_addin_get_type())
+
+G_DECLARE_INTERFACE (IdeEditorAddin, ide_editor_addin, IDE, EDITOR_ADDIN, GObject)
+
+struct _IdeEditorAddinInterface
+{
+ GTypeInterface parent_iface;
+
+ void (*load) (IdeEditorAddin *self,
+ IdeEditorPerspective *perspective);
+ void (*unload) (IdeEditorAddin *self,
+ IdeEditorPerspective *perspective);
+ void (*view_set) (IdeEditorAddin *self,
+ IdeLayoutView *view);
+};
+
+void ide_editor_addin_load (IdeEditorAddin *self,
+ IdeEditorPerspective *perspective);
+void ide_editor_addin_unload (IdeEditorAddin *self,
+ IdeEditorPerspective *perspective);
+void ide_editor_addin_view_set (IdeEditorAddin *self,
+ IdeLayoutView *view);
+
+IdeEditorAddin *ide_editor_addin_find_by_module_name (IdeEditorPerspective *editor,
+ const gchar *module_name);
+
+G_END_DECLS
diff --git a/libide/editor/ide-editor-perspective.c b/libide/editor/ide-editor-perspective.c
index 9e9bacb..b6111b5 100644
--- a/libide/editor/ide-editor-perspective.c
+++ b/libide/editor/ide-editor-perspective.c
@@ -23,6 +23,7 @@
#include "buffers/ide-buffer.h"
#include "buffers/ide-buffer-manager.h"
#include "diagnostics/ide-source-location.h"
+#include "editor/ide-editor-addin.h"
#include "editor/ide-editor-perspective.h"
#include "editor/ide-editor-private.h"
#include "editor/ide-editor-properties.h"
@@ -48,6 +49,107 @@ G_DEFINE_TYPE_WITH_CODE (IdeEditorPerspective, ide_editor_perspective, IDE_TYPE_
G_IMPLEMENT_INTERFACE (IDE_TYPE_PERSPECTIVE, perspective_iface_init))
static void
+ide_editor_perspective_addin_added (PeasExtensionSet *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ IdeEditorPerspective *self = user_data;
+ IdeEditorAddin *addin = (IdeEditorAddin *)exten;
+ IdeLayoutView *view;
+
+ g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+ g_assert (IDE_IS_EDITOR_ADDIN (addin));
+ g_assert (PEAS_IS_EXTENSION_SET (set));
+ g_assert (plugin_info != NULL);
+
+ ide_editor_addin_load (addin, self);
+
+ view = ide_layout_grid_get_current_view (self->grid);
+ if (view != NULL)
+ ide_editor_addin_view_set (addin, view);
+}
+
+static void
+ide_editor_perspective_addin_removed (PeasExtensionSet *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ IdeEditorPerspective *self = user_data;
+ IdeEditorAddin *addin = (IdeEditorAddin *)exten;
+ IdeLayoutView *view;
+
+ g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+ g_assert (IDE_IS_EDITOR_ADDIN (addin));
+ g_assert (PEAS_IS_EXTENSION_SET (set));
+ g_assert (plugin_info != NULL);
+
+ view = ide_layout_grid_get_current_view (self->grid);
+ if (view != NULL)
+ ide_editor_addin_view_set (addin, NULL);
+
+ ide_editor_addin_unload (addin, self);
+}
+
+static void
+ide_editor_perspective_hierarchy_changed (GtkWidget *widget,
+ GtkWidget *old_toplevel)
+{
+ IdeEditorPerspective *self = (IdeEditorPerspective *)widget;
+
+ g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+ g_assert (!old_toplevel || GTK_IS_WIDGET (old_toplevel));
+
+ if (self->addins == NULL)
+ {
+ GtkWidget *toplevel;
+
+ /*
+ * If we just got a new toplevel and it is a workbench,
+ * and we have not yet created our addins, do so now.
+ */
+
+ toplevel = gtk_widget_get_ancestor (widget, IDE_TYPE_WORKBENCH);
+
+ if (toplevel != NULL)
+ {
+ self->addins = peas_extension_set_new (peas_engine_get_default (),
+ IDE_TYPE_EDITOR_ADDIN,
+ NULL);
+ g_signal_connect (self->addins,
+ "extension-added",
+ G_CALLBACK (ide_editor_perspective_addin_added),
+ self);
+ g_signal_connect (self->addins,
+ "extension-removed",
+ G_CALLBACK (ide_editor_perspective_addin_removed),
+ self);
+ peas_extension_set_foreach (self->addins,
+ ide_editor_perspective_addin_added,
+ self);
+ }
+ }
+}
+
+static void
+ide_editor_perspective_addins_view_set (PeasExtensionSet *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ IdeEditorAddin *addin = (IdeEditorAddin *)exten;
+ IdeLayoutView *view = user_data;
+
+ g_assert (PEAS_IS_EXTENSION_SET (set));
+ g_assert (plugin_info != NULL);
+ g_assert (IDE_IS_EDITOR_ADDIN (addin));
+ g_assert (!view || IDE_IS_LAYOUT_VIEW (view));
+
+ ide_editor_addin_view_set (addin, view);
+}
+
+static void
ide_editor_perspective_notify_current_view (IdeEditorPerspective *self,
GParamSpec *pspec,
IdeLayoutGrid *grid)
@@ -64,6 +166,10 @@ ide_editor_perspective_notify_current_view (IdeEditorPerspective *self,
ide_editor_properties_set_view (self->properties, IDE_EDITOR_VIEW (view));
else
ide_editor_properties_set_view (self->properties, NULL);
+
+ peas_extension_set_foreach (self->addins,
+ ide_editor_perspective_addins_view_set,
+ view);
}
static void
@@ -107,12 +213,27 @@ ide_editor_perspective_create_edge (DzlDockBin *dock_bin,
}
static void
+ide_editor_perspective_destroy (GtkWidget *widget)
+{
+ IdeEditorPerspective *self = (IdeEditorPerspective *)widget;
+
+ g_assert (IDE_IS_EDITOR_PERSPECTIVE (self));
+
+ g_clear_object (&self->addins);
+
+ GTK_WIDGET_CLASS (ide_editor_perspective_parent_class)->destroy (widget);
+}
+
+static void
ide_editor_perspective_class_init (IdeEditorPerspectiveClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
DzlDockBinClass *dock_bin_class = DZL_DOCK_BIN_CLASS (klass);
+ widget_class->destroy = ide_editor_perspective_destroy;
+ widget_class->hierarchy_changed = ide_editor_perspective_hierarchy_changed;
+
container_class->add = ide_editor_perspective_add;
dock_bin_class->create_edge = ide_editor_perspective_create_edge;
diff --git a/libide/ide.h b/libide/ide.h
index 54508dd..b6ca24a 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -72,6 +72,7 @@ G_BEGIN_DECLS
#include "diagnostics/ide-source-range.h"
#include "doap/ide-doap-person.h"
#include "doap/ide-doap.h"
+#include "editor/ide-editor-addin.h"
#include "editor/ide-editor-perspective.h"
#include "editor/ide-editor-sidebar.h"
#include "editor/ide-editor-view-addin.h"
diff --git a/libide/meson.build b/libide/meson.build
index eac7089..99e7635 100644
--- a/libide/meson.build
+++ b/libide/meson.build
@@ -98,6 +98,7 @@ libide_public_headers = [
'directory/ide-directory-vcs.h',
'doap/ide-doap-person.h',
'doap/ide-doap.h',
+ 'editor/ide-editor-addin.h',
'editor/ide-editor-perspective.h',
'editor/ide-editor-sidebar.h',
'editor/ide-editor-view-addin.h',
@@ -294,6 +295,7 @@ libide_public_sources = [
'directory/ide-directory-vcs.c',
'doap/ide-doap-person.c',
'doap/ide-doap.c',
+ 'editor/ide-editor-addin.c',
'editor/ide-editor-perspective.c',
'editor/ide-editor-sidebar.c',
'editor/ide-editor-view-addin.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]