[gnome-builder] editor: bring back stack controls
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] editor: bring back stack controls
- Date: Wed, 19 Jul 2017 11:01:38 +0000 (UTC)
commit a31ea64157398f2588e18862912b9eb524bf884a
Author: Christian Hergert <chergert redhat com>
Date: Wed Jun 28 00:49:48 2017 -0700
editor: bring back stack controls
We need these until we have an alternate solution for accessing
their features.
libide/editor/ide-editor-layout-stack-addin.c | 113 ++++++++
libide/editor/ide-editor-layout-stack-addin.h | 29 ++
libide/editor/ide-editor-layout-stack-controls.c | 300 +++++++++++++++++++++
libide/editor/ide-editor-layout-stack-controls.h | 51 ++++
libide/editor/ide-editor-layout-stack-controls.ui | 85 ++++++
libide/editor/ide-editor-plugin.c | 6 +-
libide/layout/ide-layout-stack-addin.h | 9 +-
libide/layout/ide-layout-stack.c | 99 +++++++
libide/libide.gresource.xml | 1 +
libide/meson.build | 8 +-
10 files changed, 691 insertions(+), 10 deletions(-)
---
diff --git a/libide/editor/ide-editor-layout-stack-addin.c b/libide/editor/ide-editor-layout-stack-addin.c
new file mode 100644
index 0000000..aec5260
--- /dev/null
+++ b/libide/editor/ide-editor-layout-stack-addin.c
@@ -0,0 +1,113 @@
+/* ide-editor-layout-stack-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-layout-stack-addin.h"
+
+#include <dazzle.h>
+
+#include "editor/ide-editor-layout-stack-addin.h"
+#include "editor/ide-editor-layout-stack-controls.h"
+#include "editor/ide-editor-view.h"
+#include "layout/ide-layout-stack-header.h"
+
+struct _IdeEditorLayoutStackAddin
+{
+ GObject parent_instance;
+ IdeEditorLayoutStackControls *controls;
+};
+
+static void
+ide_editor_layout_stack_addin_load (IdeLayoutStackAddin *addin,
+ IdeLayoutStack *stack)
+{
+ IdeEditorLayoutStackAddin *self = (IdeEditorLayoutStackAddin *)addin;
+ GtkWidget *header;
+
+ g_assert (IDE_IS_EDITOR_LAYOUT_STACK_ADDIN (self));
+ g_assert (IDE_IS_LAYOUT_STACK (stack));
+
+ header = ide_layout_stack_get_titlebar (stack);
+
+ self->controls = g_object_new (IDE_TYPE_EDITOR_LAYOUT_STACK_CONTROLS, NULL);
+ g_signal_connect (self->controls,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &self->controls);
+ gtk_container_add_with_properties (GTK_CONTAINER (header), GTK_WIDGET (self->controls),
+ "pack-type", GTK_PACK_END,
+ "priority", 100,
+ NULL);
+}
+
+static void
+ide_editor_layout_stack_addin_unload (IdeLayoutStackAddin *addin,
+ IdeLayoutStack *stack)
+{
+ IdeEditorLayoutStackAddin *self = (IdeEditorLayoutStackAddin *)addin;
+
+ g_assert (IDE_IS_EDITOR_LAYOUT_STACK_ADDIN (self));
+ g_assert (IDE_IS_LAYOUT_STACK (stack));
+
+ if (self->controls != NULL)
+ gtk_widget_destroy (GTK_WIDGET (self->controls));
+}
+
+static void
+ide_editor_layout_stack_addin_set_view (IdeLayoutStackAddin *addin,
+ IdeLayoutView *view)
+{
+ IdeEditorLayoutStackAddin *self = (IdeEditorLayoutStackAddin *)addin;
+
+ g_assert (IDE_IS_EDITOR_LAYOUT_STACK_ADDIN (self));
+ g_assert (!view || IDE_IS_LAYOUT_VIEW (view));
+
+ if (IDE_IS_EDITOR_VIEW (view))
+ {
+ ide_editor_layout_stack_controls_set_view (self->controls, IDE_EDITOR_VIEW (view));
+ gtk_widget_show (GTK_WIDGET (self->controls));
+ }
+ else
+ {
+ ide_editor_layout_stack_controls_set_view (self->controls, NULL);
+ gtk_widget_hide (GTK_WIDGET (self->controls));
+ }
+}
+
+static void
+layout_stack_addin_iface_init (IdeLayoutStackAddinInterface *iface)
+{
+ iface->load = ide_editor_layout_stack_addin_load;
+ iface->unload = ide_editor_layout_stack_addin_unload;
+ iface->set_view = ide_editor_layout_stack_addin_set_view;
+}
+
+G_DEFINE_TYPE_WITH_CODE (IdeEditorLayoutStackAddin,
+ ide_editor_layout_stack_addin,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_LAYOUT_STACK_ADDIN,
+ layout_stack_addin_iface_init))
+
+static void
+ide_editor_layout_stack_addin_class_init (IdeEditorLayoutStackAddinClass *klass)
+{
+}
+
+static void
+ide_editor_layout_stack_addin_init (IdeEditorLayoutStackAddin *self)
+{
+}
diff --git a/libide/editor/ide-editor-layout-stack-addin.h b/libide/editor/ide-editor-layout-stack-addin.h
new file mode 100644
index 0000000..0c4609a
--- /dev/null
+++ b/libide/editor/ide-editor-layout-stack-addin.h
@@ -0,0 +1,29 @@
+/* ide-editor-layout-stack-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 "layout/ide-layout-stack-addin.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_EDITOR_LAYOUT_STACK_ADDIN (ide_editor_layout_stack_addin_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeEditorLayoutStackAddin, ide_editor_layout_stack_addin, IDE,
EDITOR_LAYOUT_STACK_ADDIN, GObject)
+
+G_END_DECLS
diff --git a/libide/editor/ide-editor-layout-stack-controls.c
b/libide/editor/ide-editor-layout-stack-controls.c
new file mode 100644
index 0000000..c74c17c
--- /dev/null
+++ b/libide/editor/ide-editor-layout-stack-controls.c
@@ -0,0 +1,300 @@
+/* ide-editor-layout-stack-controls.c
+ *
+ * Copyright (C) 2016 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-layout-stack-controls"
+
+#include <glib/gi18n.h>
+
+#include "editor/ide-editor-layout-stack-controls.h"
+#include "editor/ide-editor-private.h"
+
+G_DEFINE_TYPE (IdeEditorLayoutStackControls, ide_editor_layout_stack_controls, GTK_TYPE_BOX)
+
+static void
+document_cursor_moved (IdeEditorLayoutStackControls *self,
+ const GtkTextIter *iter,
+ GtkTextBuffer *buffer)
+{
+ IdeSourceView *source_view;
+ GtkTextIter bounds;
+ GtkTextMark *mark;
+ gchar str[32];
+ guint line;
+ gint column;
+ gint column2;
+
+ g_assert (IDE_IS_EDITOR_LAYOUT_STACK_CONTROLS (self));
+ g_assert (iter != NULL);
+ g_assert (IDE_IS_BUFFER (buffer));
+
+ if (self->view == NULL)
+ return;
+
+ source_view = ide_editor_view_get_view (self->view);
+
+ ide_source_view_get_visual_position (source_view, &line, (guint *)&column);
+
+ mark = gtk_text_buffer_get_selection_bound (buffer);
+ gtk_text_buffer_get_iter_at_mark (buffer, &bounds, mark);
+
+ g_snprintf (str, sizeof str, "%d", line + 1);
+ dzl_simple_label_set_label (self->line_label, str);
+
+ g_snprintf (str, sizeof str, "%d", column + 1);
+ dzl_simple_label_set_label (self->column_label, str);
+
+ if (!gtk_widget_has_focus (GTK_WIDGET (source_view)) ||
+ gtk_text_iter_equal (&bounds, iter) ||
+ (gtk_text_iter_get_line (iter) != gtk_text_iter_get_line (&bounds)))
+ {
+ gtk_widget_set_visible (GTK_WIDGET (self->range_label), FALSE);
+ return;
+ }
+
+ /* We have a selection that is on the same line.
+ * Lets give some detail as to how long the selection is.
+ */
+ column2 = gtk_source_view_get_visual_column (GTK_SOURCE_VIEW (source_view), &bounds);
+
+ g_snprintf (str, sizeof str, "%u", ABS (column2 - column));
+ gtk_label_set_label (self->range_label, str);
+ gtk_widget_set_visible (GTK_WIDGET (self->range_label), TRUE);
+}
+
+
+static void
+goto_line_activate (IdeEditorLayoutStackControls *self,
+ const gchar *text,
+ DzlSimplePopover *popover)
+{
+ gint64 value;
+
+ g_assert (IDE_IS_EDITOR_LAYOUT_STACK_CONTROLS (self));
+ g_assert (DZL_IS_SIMPLE_POPOVER (popover));
+
+ if (self->view == NULL)
+ return;
+
+ if (!ide_str_empty0 (text))
+ {
+ value = g_ascii_strtoll (text, NULL, 10);
+
+ if ((value > 0) && (value < G_MAXINT))
+ {
+ IdeSourceView *source_view;
+ GtkTextBuffer *buffer = GTK_TEXT_BUFFER (self->view->buffer);
+ GtkTextIter iter;
+
+ source_view = ide_editor_view_get_view (self->view);
+
+ gtk_widget_grab_focus (GTK_WIDGET (self->view));
+ gtk_text_buffer_get_iter_at_line (buffer, &iter, value - 1);
+ gtk_text_buffer_select_range (buffer, &iter, &iter);
+ ide_source_view_scroll_to_iter (source_view, &iter, 0.25, TRUE, 1.0, 0.5, TRUE);
+ }
+ }
+}
+
+static gboolean
+goto_line_insert_text (IdeEditorLayoutStackControls *self,
+ guint position,
+ const gchar *chars,
+ guint n_chars,
+ DzlSimplePopover *popover)
+{
+ g_assert (IDE_IS_EDITOR_LAYOUT_STACK_CONTROLS (self));
+ g_assert (DZL_IS_SIMPLE_POPOVER (popover));
+ g_assert (chars != NULL);
+
+ for (; *chars; chars = g_utf8_next_char (chars))
+ {
+ if (!g_unichar_isdigit (g_utf8_get_char (chars)))
+ return GDK_EVENT_STOP;
+ }
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+static void
+goto_line_changed (IdeEditorLayoutStackControls *self,
+ DzlSimplePopover *popover)
+{
+ gchar *message;
+ const gchar *text;
+ GtkTextIter begin;
+ GtkTextIter end;
+
+ g_assert (IDE_IS_EDITOR_LAYOUT_STACK_CONTROLS (self));
+ g_assert (DZL_IS_SIMPLE_POPOVER (popover));
+
+ if (self->view == NULL)
+ return;
+
+ text = dzl_simple_popover_get_text (popover);
+
+ gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (self->view->buffer), &begin, &end);
+
+ if (!ide_str_empty0 (text))
+ {
+ gint64 value;
+
+ value = g_ascii_strtoll (text, NULL, 10);
+
+ if (value > 0)
+ {
+ if (value <= gtk_text_iter_get_line (&end) + 1)
+ {
+ dzl_simple_popover_set_message (popover, NULL);
+ dzl_simple_popover_set_ready (popover, TRUE);
+ return;
+ }
+ }
+ }
+
+ /* translators: the user selected a number outside the value range for the document. */
+ message = g_strdup_printf (_("Provide a number between 1 and %u"),
+ gtk_text_iter_get_line (&end) + 1);
+ dzl_simple_popover_set_message (popover, message);
+ dzl_simple_popover_set_ready (popover, FALSE);
+
+ g_free (message);
+}
+
+static void
+warning_button_clicked (IdeEditorLayoutStackControls *self,
+ GtkButton *button)
+{
+ IdeSourceView *source_view;
+
+ g_assert (IDE_IS_EDITOR_LAYOUT_STACK_CONTROLS (self));
+ g_assert (GTK_IS_BUTTON (button));
+
+ if (self->view == NULL)
+ return;
+
+ source_view = ide_editor_view_get_view (self->view);
+ gtk_widget_grab_focus (GTK_WIDGET (source_view));
+ g_signal_emit_by_name (source_view, "move-error", GTK_DIR_DOWN);
+}
+
+static void
+ide_editor_layout_stack_controls_finalize (GObject *object)
+{
+ IdeEditorLayoutStackControls *self = (IdeEditorLayoutStackControls *)object;
+
+ g_clear_object (&self->buffer_bindings);
+ g_clear_object (&self->buffer_signals);
+
+ self->view = NULL;
+
+ G_OBJECT_CLASS (ide_editor_layout_stack_controls_parent_class)->finalize (object);
+}
+
+static void
+ide_editor_layout_stack_controls_class_init (IdeEditorLayoutStackControlsClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = ide_editor_layout_stack_controls_finalize;
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/ui/ide-editor-layout-stack-controls.ui");
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorLayoutStackControls, column_label);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorLayoutStackControls, goto_line_popover);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorLayoutStackControls, goto_line_button);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorLayoutStackControls, line_label);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorLayoutStackControls, range_label);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorLayoutStackControls, warning_button);
+}
+
+static void
+ide_editor_layout_stack_controls_init (IdeEditorLayoutStackControls *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ g_signal_connect_object (self->goto_line_popover,
+ "activate",
+ G_CALLBACK (goto_line_activate),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (self->goto_line_popover,
+ "insert-text",
+ G_CALLBACK (goto_line_insert_text),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (self->goto_line_popover,
+ "changed",
+ G_CALLBACK (goto_line_changed),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (self->warning_button,
+ "clicked",
+ G_CALLBACK (warning_button_clicked),
+ self,
+ G_CONNECT_SWAPPED);
+
+ self->buffer_bindings = dzl_binding_group_new ();
+
+ dzl_binding_group_bind (self->buffer_bindings, "has-diagnostics",
+ self->warning_button, "visible",
+ G_BINDING_SYNC_CREATE);
+
+ self->buffer_signals = dzl_signal_group_new (IDE_TYPE_BUFFER);
+
+ dzl_signal_group_connect_object (self->buffer_signals,
+ "cursor-moved",
+ G_CALLBACK (document_cursor_moved),
+ self,
+ G_CONNECT_SWAPPED);
+}
+
+void
+ide_editor_layout_stack_controls_set_view (IdeEditorLayoutStackControls *self,
+ IdeEditorView *view)
+{
+ g_return_if_fail (IDE_IS_EDITOR_LAYOUT_STACK_CONTROLS (self));
+ g_return_if_fail (!view || IDE_IS_EDITOR_VIEW (view));
+
+ if (self->view == view)
+ return;
+
+ dzl_binding_group_set_source (self->buffer_bindings, NULL);
+ dzl_signal_group_set_target (self->buffer_signals, NULL);
+
+ if (self->view != NULL)
+ {
+ g_signal_handlers_disconnect_by_func (self->view,
+ G_CALLBACK (gtk_widget_destroyed),
+ &self->view);
+ self->view = NULL;
+ }
+
+ if (view != NULL)
+ {
+ self->view = view;
+ g_signal_connect (view,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &self->view);
+ dzl_binding_group_set_source (self->buffer_bindings, view->buffer);
+ dzl_signal_group_set_target (self->buffer_signals, view->buffer);
+ }
+}
diff --git a/libide/editor/ide-editor-layout-stack-controls.h
b/libide/editor/ide-editor-layout-stack-controls.h
new file mode 100644
index 0000000..f63d806
--- /dev/null
+++ b/libide/editor/ide-editor-layout-stack-controls.h
@@ -0,0 +1,51 @@
+/* ide-editor-layout-stack-controls.h
+ *
+ * Copyright (C) 2016 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 <gtk/gtk.h>
+#include <dazzle.h>
+
+#include "editor/ide-editor-view.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_EDITOR_LAYOUT_STACK_CONTROLS (ide_editor_layout_stack_controls_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeEditorLayoutStackControls, ide_editor_layout_stack_controls, IDE,
EDITOR_LAYOUT_STACK_CONTROLS, GtkBox)
+
+struct _IdeEditorLayoutStackControls
+{
+ GtkBox parent_instance;
+
+ IdeEditorView *view;
+ DzlBindingGroup *buffer_bindings;
+ DzlSignalGroup *buffer_signals;
+
+ DzlSimplePopover *goto_line_popover;
+ GtkMenuButton *goto_line_button;
+ GtkButton *warning_button;
+ DzlSimpleLabel *line_label;
+ DzlSimpleLabel *column_label;
+ GtkLabel *range_label;
+};
+
+void ide_editor_layout_stack_controls_set_view (IdeEditorLayoutStackControls *self,
+ IdeEditorView *view);
+
+G_END_DECLS
diff --git a/libide/editor/ide-editor-layout-stack-controls.ui
b/libide/editor/ide-editor-layout-stack-controls.ui
new file mode 100644
index 0000000..af07c68
--- /dev/null
+++ b/libide/editor/ide-editor-layout-stack-controls.ui
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="IdeEditorLayoutStackControls">
+ <property name="orientation">horizontal</property>
+ <child>
+ <object class="GtkButton" id="warning_button">
+ <property name="visible">false</property>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">dialog-warning-symbolic</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="goto_line_button">
+ <property name="popover">goto_line_popover</property>
+ <property name="focus-on-click">false</property>
+ <property name="tooltip-text" translatable="yes">Go to line number</property>
+ <property name="valign">baseline</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkBox">
+ <property name="valign">baseline</property>
+ <property name="visible">true</property>
+ <child type="center">
+ <object class="GtkLabel">
+ <property name="label">:</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="DzlSimpleLabel" id="line_label">
+ <property name="label">1</property>
+ <property name="width-chars">3</property>
+ <property name="xalign">1.0</property>
+ <property name="valign">baseline</property>
+ <property name="visible">true</property>
+ </object>
+ <packing>
+ <property name="pack-type">start</property>
+ </packing>
+ </child>
+ <child>
+ <object class="DzlSimpleLabel" id="column_label">
+ <property name="label">1</property>
+ <property name="width-chars">3</property>
+ <property name="xalign">0.0</property>
+ <property name="valign">baseline</property>
+ <property name="visible">true</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="pack-type">end</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="range_label">
+ <property name="valign">baseline</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ <property name="pack-type">end</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="DzlSimplePopover" id="goto_line_popover">
+ <property name="title" translatable="yes">Go to Line</property>
+ <property name="button-text" translatable="yes">Go</property>
+ </object>
+</interface>
diff --git a/libide/editor/ide-editor-plugin.c b/libide/editor/ide-editor-plugin.c
index 59d2d7b..3449902 100644
--- a/libide/editor/ide-editor-plugin.c
+++ b/libide/editor/ide-editor-plugin.c
@@ -20,12 +20,12 @@
#include <libpeas/peas.h>
+#include "editor/ide-editor-layout-stack-addin.h"
#include "editor/ide-editor-workbench-addin.h"
void
ide_editor_register_types (PeasObjectModule *module)
{
- peas_object_module_register_extension_type (module,
- IDE_TYPE_WORKBENCH_ADDIN,
- IDE_TYPE_EDITOR_WORKBENCH_ADDIN);
+ peas_object_module_register_extension_type (module, IDE_TYPE_LAYOUT_STACK_ADDIN,
IDE_TYPE_EDITOR_LAYOUT_STACK_ADDIN);
+ peas_object_module_register_extension_type (module, IDE_TYPE_WORKBENCH_ADDIN,
IDE_TYPE_EDITOR_WORKBENCH_ADDIN);
}
diff --git a/libide/layout/ide-layout-stack-addin.h b/libide/layout/ide-layout-stack-addin.h
index e021760..cee30c6 100644
--- a/libide/layout/ide-layout-stack-addin.h
+++ b/libide/layout/ide-layout-stack-addin.h
@@ -16,13 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef IDE_LAYOUT_STACK_ADDIN_H
-#define IDE_LAYOUT_STACK_ADDIN_H
+#pragma once
#include <gtk/gtk.h>
-#include "layout/ide-layout-stack.h"
-#include "layout/ide-layout-view.h"
+#include "ide-layout-stack.h"
+#include "ide-layout-view.h"
G_BEGIN_DECLS
@@ -50,5 +49,3 @@ void ide_layout_stack_addin_set_view (IdeLayoutStackAddin *self,
IdeLayoutView *view);
G_END_DECLS
-
-#endif /* IDE_LAYOUT_STACK_ADDIN_H */
diff --git a/libide/layout/ide-layout-stack.c b/libide/layout/ide-layout-stack.c
index 6db2a55..71c91c3 100644
--- a/libide/layout/ide-layout-stack.c
+++ b/libide/layout/ide-layout-stack.c
@@ -20,8 +20,10 @@
#include <dazzle.h>
#include <glib/gi18n.h>
+#include <libpeas/peas.h>
#include "ide-layout-stack.h"
+#include "ide-layout-stack-addin.h"
#include "ide-layout-stack-header.h"
#include "ide-layout-private.h"
#include "ide-shortcut-label.h"
@@ -49,6 +51,7 @@ typedef struct
DzlBindingGroup *bindings;
DzlSignalGroup *signals;
GPtrArray *views;
+ PeasExtensionSet *addins;
DzlBox *empty_state;
DzlEmptyState *failed_state;
@@ -124,6 +127,23 @@ ide_layout_stack_bindings_notify_source (IdeLayoutStack *self,
}
static void
+ide_layout_stack_notify_addin_of_view (PeasExtensionSet *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ IdeLayoutStackAddin *addin = (IdeLayoutStackAddin *)exten;
+ IdeLayoutView *view = user_data;
+
+ g_assert (PEAS_IS_EXTENSION_SET (set));
+ g_assert (plugin_info != NULL);
+ g_assert (IDE_IS_LAYOUT_STACK_ADDIN (addin));
+ g_assert (!view || IDE_IS_LAYOUT_VIEW (view));
+
+ ide_layout_stack_addin_set_view (addin, view);
+}
+
+static void
ide_layout_stack_notify_visible_child (IdeLayoutStack *self,
GParamSpec *pspec,
GtkStack *stack)
@@ -134,6 +154,9 @@ ide_layout_stack_notify_visible_child (IdeLayoutStack *self,
g_assert (IDE_IS_LAYOUT_STACK (self));
g_assert (GTK_IS_STACK (stack));
+ if (gtk_widget_in_destruction (GTK_WIDGET (self)))
+ return;
+
visible_child = gtk_stack_get_visible_child (priv->stack);
/*
@@ -162,6 +185,10 @@ ide_layout_stack_notify_visible_child (IdeLayoutStack *self,
/* Ensure action state is up to date */
_ide_layout_stack_update_actions (self);
+ peas_extension_set_foreach (priv->addins,
+ ide_layout_stack_notify_addin_of_view,
+ visible_child);
+
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_VISIBLE_CHILD]);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_HAS_VIEW]);
}
@@ -311,6 +338,75 @@ ide_layout_stack_real_agree_to_close_finish (IdeLayoutStack *self,
}
static void
+ide_layout_stack_addin_added (PeasExtensionSet *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ IdeLayoutStackAddin *addin = (IdeLayoutStackAddin *)exten;
+ IdeLayoutStack *self = user_data;
+ IdeLayoutView *visible_child;
+
+ g_assert (IDE_IS_LAYOUT_STACK (self));
+ g_assert (PEAS_IS_EXTENSION_SET (set));
+ g_assert (plugin_info != NULL);
+ g_assert (IDE_IS_LAYOUT_STACK_ADDIN (addin));
+
+ ide_layout_stack_addin_load (addin, self);
+
+ visible_child = ide_layout_stack_get_visible_child (self);
+
+ if (visible_child != NULL)
+ ide_layout_stack_addin_set_view (addin, visible_child);
+}
+
+static void
+ide_layout_stack_addin_removed (PeasExtensionSet *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ IdeLayoutStackAddin *addin = (IdeLayoutStackAddin *)exten;
+ IdeLayoutStack *self = user_data;
+
+ g_assert (IDE_IS_LAYOUT_STACK (self));
+ g_assert (PEAS_IS_EXTENSION_SET (set));
+ g_assert (plugin_info != NULL);
+ g_assert (IDE_IS_LAYOUT_STACK_ADDIN (addin));
+
+ ide_layout_stack_addin_unload (addin, self);
+}
+
+static void
+ide_layout_stack_constructed (GObject *object)
+{
+ IdeLayoutStack *self = (IdeLayoutStack *)object;
+ IdeLayoutStackPrivate *priv = ide_layout_stack_get_instance_private (self);
+
+ g_assert (IDE_IS_LAYOUT_STACK (self));
+
+ G_OBJECT_CLASS (ide_layout_stack_parent_class)->constructed (object);
+
+ priv->addins = peas_extension_set_new (peas_engine_get_default (),
+ IDE_TYPE_LAYOUT_STACK_ADDIN,
+ NULL);
+
+ g_signal_connect (priv->addins,
+ "extension-added",
+ G_CALLBACK (ide_layout_stack_addin_added),
+ self);
+
+ g_signal_connect (priv->addins,
+ "extension-removed",
+ G_CALLBACK (ide_layout_stack_addin_removed),
+ self);
+
+ peas_extension_set_foreach (priv->addins,
+ ide_layout_stack_addin_added,
+ self);
+}
+
+static void
ide_layout_stack_destroy (GtkWidget *widget)
{
IdeLayoutStack *self = (IdeLayoutStack *)widget;
@@ -318,6 +414,8 @@ ide_layout_stack_destroy (GtkWidget *widget)
g_assert (IDE_IS_LAYOUT_STACK (self));
+ g_clear_object (&priv->addins);
+
if (priv->bindings != NULL)
{
dzl_binding_group_set_source (priv->bindings, NULL);
@@ -384,6 +482,7 @@ ide_layout_stack_class_init (IdeLayoutStackClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+ object_class->constructed = ide_layout_stack_constructed;
object_class->get_property = ide_layout_stack_get_property;
object_class->set_property = ide_layout_stack_set_property;
diff --git a/libide/libide.gresource.xml b/libide/libide.gresource.xml
index ac4239e..c47f8ef 100644
--- a/libide/libide.gresource.xml
+++ b/libide/libide.gresource.xml
@@ -55,6 +55,7 @@
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-layout-stack-header.ui">layout/ide-layout-stack-header.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-layout-stack.ui">layout/ide-layout-stack.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-editor-perspective.ui">editor/ide-editor-perspective.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks"
alias="ide-editor-layout-stack-controls.ui">editor/ide-editor-layout-stack-controls.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-editor-search-bar.ui">editor/ide-editor-search-bar.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-editor-spell-widget.ui">spellcheck/ide-editor-spell-widget.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="ide-editor-view.ui">editor/ide-editor-view.ui</file>
diff --git a/libide/meson.build b/libide/meson.build
index 5c870a5..099bf97 100644
--- a/libide/meson.build
+++ b/libide/meson.build
@@ -126,6 +126,7 @@ libide_public_headers = [
'layout/ide-layout-grid.h',
'layout/ide-layout-grid-column.h',
'layout/ide-layout-stack.h',
+ 'layout/ide-layout-stack-addin.h',
'layout/ide-layout-stack-header.h',
'layout/ide-layout-view.h',
'layout/ide-layout-pane.h',
@@ -324,8 +325,9 @@ libide_public_sources = [
'layout/ide-layout-grid.c',
'layout/ide-layout-grid-column.c',
'layout/ide-layout-pane.c',
- 'layout/ide-layout-stack-header.c',
'layout/ide-layout-stack.c',
+ 'layout/ide-layout-stack-addin.c',
+ 'layout/ide-layout-stack-header.c',
'layout/ide-layout-view.c',
'layout/ide-layout.c',
'local/ide-local-device.c',
@@ -456,6 +458,10 @@ libide_sources = libide_generated_headers + libide_public_sources + [
'buildui/ide-environment-editor-row.h',
'buildui/ide-environment-editor.c',
'buildui/ide-environment-editor.h',
+ 'editor/ide-editor-layout-stack-addin.c',
+ 'editor/ide-editor-layout-stack-addin.h',
+ 'editor/ide-editor-layout-stack-controls.c',
+ 'editor/ide-editor-layout-stack-controls.h',
'editor/ide-editor-perspective-actions.c',
'editor/ide-editor-perspective-shortcuts.c',
'editor/ide-editor-plugin.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]