[gnome-builder] symbol-tree: track current scope when cursor moves
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] symbol-tree: track current scope when cursor moves
- Date: Wed, 19 Jul 2017 11:07:01 +0000 (UTC)
commit 4a43db86b01bc1597f586333f6ca21f490921065
Author: Christian Hergert <chergert redhat com>
Date: Mon Jul 3 16:08:06 2017 -0700
symbol-tree: track current scope when cursor moves
This uses a ½ second delay when the cursor moves to update the
name of the scope in the Document Symbols stack header.
Currently there are no implementations of this IdeSymbolResolver
interface feature, but those will come shortly.
Signed-off-by: Christian Hergert <chergert redhat com>
.../symbol-tree/gbp-symbol-layout-stack-addin.c | 91 +++++++++++++++++++-
plugins/symbol-tree/gbp-symbol-menu-button.c | 35 +++++++-
plugins/symbol-tree/gbp-symbol-menu-button.h | 2 +
plugins/symbol-tree/gbp-symbol-menu-button.ui | 19 ++++-
4 files changed, 144 insertions(+), 3 deletions(-)
---
diff --git a/plugins/symbol-tree/gbp-symbol-layout-stack-addin.c
b/plugins/symbol-tree/gbp-symbol-layout-stack-addin.c
index f9015ba..f03362d 100644
--- a/plugins/symbol-tree/gbp-symbol-layout-stack-addin.c
+++ b/plugins/symbol-tree/gbp-symbol-layout-stack-addin.c
@@ -23,24 +23,107 @@
#include "gbp-symbol-layout-stack-addin.h"
#include "gbp-symbol-menu-button.h"
+#define CURSOR_MOVED_DELAY_MSEC 500
+
struct _GbpSymbolLayoutStackAddin {
GObject parent_instance;
GbpSymbolMenuButton *button;
GCancellable *cancellable;
+ GCancellable *scope_cancellable;
DzlSignalGroup *buffer_signals;
+
+ guint cursor_moved_handler;
};
static void
+gbp_symbol_layout_stack_addin_find_scope_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeSymbolResolver *symbol_resolver = (IdeSymbolResolver *)object;
+ g_autoptr(GbpSymbolLayoutStackAddin) self = user_data;
+ g_autoptr(IdeSymbol) symbol = NULL;
+ g_autoptr(GError) error = NULL;
+
+ g_assert (IDE_IS_SYMBOL_RESOLVER (symbol_resolver));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (GBP_IS_SYMBOL_LAYOUT_STACK_ADDIN (self));
+
+ symbol = ide_symbol_resolver_find_nearest_scope_finish (symbol_resolver, result, &error);
+
+ if (error != NULL &&
+ !(g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)))
+ g_warning ("Failed to find nearest scope: %s", error->message);
+
+ if (self->button != NULL)
+ gbp_symbol_menu_button_set_symbol (self->button, symbol);
+}
+
+static gboolean
+gbp_symbol_layout_stack_addin_cursor_moved_cb (gpointer user_data)
+{
+ GbpSymbolLayoutStackAddin *self = user_data;
+ IdeBuffer *buffer;
+
+ g_assert (GBP_IS_SYMBOL_LAYOUT_STACK_ADDIN (self));
+
+ g_cancellable_cancel (self->scope_cancellable);
+ g_clear_object (&self->scope_cancellable);
+
+ buffer = dzl_signal_group_get_target (self->buffer_signals);
+
+ if (buffer != NULL)
+ {
+ IdeSymbolResolver *symbol_resolver = ide_buffer_get_symbol_resolver (buffer);
+
+ if (symbol_resolver != NULL)
+ {
+ g_autoptr(IdeSourceLocation) location = ide_buffer_get_insert_location (buffer);
+
+ self->scope_cancellable = g_cancellable_new ();
+
+ ide_symbol_resolver_find_nearest_scope_async (symbol_resolver,
+ location,
+ self->scope_cancellable,
+ gbp_symbol_layout_stack_addin_find_scope_cb,
+ g_object_ref (self));
+ }
+ }
+
+ self->cursor_moved_handler = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
gbp_symbol_layout_stack_addin_cursor_moved (GbpSymbolLayoutStackAddin *self,
const GtkTextIter *location,
IdeBuffer *buffer)
{
+ GSource *source;
+ gint64 ready_time;
+
g_assert (GBP_IS_SYMBOL_LAYOUT_STACK_ADDIN (self));
g_assert (location != NULL);
g_assert (IDE_IS_BUFFER (buffer));
- /* TODO: Delay a bit so we aren't super active */
+ if (self->cursor_moved_handler == 0)
+ {
+ self->cursor_moved_handler =
+ gdk_threads_add_timeout_full (G_PRIORITY_LOW,
+ CURSOR_MOVED_DELAY_MSEC,
+ gbp_symbol_layout_stack_addin_cursor_moved_cb,
+ g_object_ref (self),
+ g_object_unref);
+ return;
+ }
+
+ /* Try to reuse our existing GSource if we can */
+ ready_time = g_get_monotonic_time () + (CURSOR_MOVED_DELAY_MSEC * 1000);
+ source = g_main_context_find_source_by_id (NULL, self->cursor_moved_handler);
+ g_source_set_ready_time (source, ready_time);
}
static void
@@ -163,8 +246,14 @@ gbp_symbol_layout_stack_addin_unbind (GbpSymbolLayoutStackAddin *self,
g_assert (GBP_IS_SYMBOL_LAYOUT_STACK_ADDIN (self));
g_assert (DZL_IS_SIGNAL_GROUP (buffer_signals));
+ ide_clear_source (&self->cursor_moved_handler);
+
g_cancellable_cancel (self->cancellable);
g_clear_object (&self->cancellable);
+
+ g_cancellable_cancel (self->scope_cancellable);
+ g_clear_object (&self->scope_cancellable);
+
gtk_widget_hide (GTK_WIDGET (self->button));
}
diff --git a/plugins/symbol-tree/gbp-symbol-menu-button.c b/plugins/symbol-tree/gbp-symbol-menu-button.c
index 9cb0e9e..b30fc33 100644
--- a/plugins/symbol-tree/gbp-symbol-menu-button.c
+++ b/plugins/symbol-tree/gbp-symbol-menu-button.c
@@ -16,7 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define G_LOG_DOMAIN "gbp-symbol-menu-button.h"
+#define G_LOG_DOMAIN "gbp-symbol-menu-button"
+
+#include <glib/gi18n.h>
#include "gbp-symbol-menu-button.h"
#include "gbp-symbol-tree-builder.h"
@@ -33,6 +35,8 @@ struct _GbpSymbolMenuButton
DzlTreeBuilder *tree_builder;
GtkPopover *popover;
GtkSearchEntry *search_entry;
+ GtkImage *symbol_icon;
+ GtkLabel *symbol_title;
};
enum {
@@ -173,6 +177,8 @@ gbp_symbol_menu_button_class_init (GbpSymbolMenuButtonClass *klass)
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/plugins/symbol-tree-plugin/gbp-symbol-menu-button.ui");
gtk_widget_class_bind_template_child (widget_class, GbpSymbolMenuButton, popover);
gtk_widget_class_bind_template_child (widget_class, GbpSymbolMenuButton, search_entry);
+ gtk_widget_class_bind_template_child (widget_class, GbpSymbolMenuButton, symbol_icon);
+ gtk_widget_class_bind_template_child (widget_class, GbpSymbolMenuButton, symbol_title);
gtk_widget_class_bind_template_child (widget_class, GbpSymbolMenuButton, tree);
gtk_widget_class_bind_template_child (widget_class, GbpSymbolMenuButton, tree_builder);
@@ -248,3 +254,30 @@ gbp_symbol_menu_button_set_symbol_tree (GbpSymbolMenuButton *self,
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SYMBOL_TREE]);
}
}
+
+void
+gbp_symbol_menu_button_set_symbol (GbpSymbolMenuButton *self,
+ IdeSymbol *symbol)
+{
+ const gchar *title = _("Document Outline");
+ const gchar *icon_name = NULL;
+
+ g_assert (GBP_IS_SYMBOL_MENU_BUTTON (self));
+
+ if (symbol != NULL)
+ {
+ IdeSymbolKind kind = ide_symbol_get_kind (symbol);
+
+ icon_name = ide_symbol_kind_get_icon_name (kind);
+ }
+
+ g_object_set (self->symbol_icon,
+ "icon-name", icon_name,
+ "visible", (symbol != NULL),
+ NULL);
+
+ g_object_set (self->symbol_title,
+ "label", title,
+ "visible", (symbol != NULL),
+ NULL);
+}
diff --git a/plugins/symbol-tree/gbp-symbol-menu-button.h b/plugins/symbol-tree/gbp-symbol-menu-button.h
index 9a11c2b..5f1a4a0 100644
--- a/plugins/symbol-tree/gbp-symbol-menu-button.h
+++ b/plugins/symbol-tree/gbp-symbol-menu-button.h
@@ -26,6 +26,8 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GbpSymbolMenuButton, gbp_symbol_menu_button, GBP, SYMBOL_MENU_BUTTON, GtkMenuButton)
+void gbp_symbol_menu_button_set_symbol (GbpSymbolMenuButton *self,
+ IdeSymbol *symbol);
IdeSymbolTree *gbp_symbol_menu_button_get_symbol_tree (GbpSymbolMenuButton *self);
void gbp_symbol_menu_button_set_symbol_tree (GbpSymbolMenuButton *self,
IdeSymbolTree *symbol_tree);
diff --git a/plugins/symbol-tree/gbp-symbol-menu-button.ui b/plugins/symbol-tree/gbp-symbol-menu-button.ui
index e71133f..be96ba7 100644
--- a/plugins/symbol-tree/gbp-symbol-menu-button.ui
+++ b/plugins/symbol-tree/gbp-symbol-menu-button.ui
@@ -54,7 +54,24 @@
</child>
</object>
<template class="GbpSymbolMenuButton" parent="GtkMenuButton">
- <property name="label" translatable="yes">Document Outline</property>
<property name="popover">popover</property>
+ <child>
+ <object class="GtkBox">
+ <property name="hexpand">true</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkImage" id="symbol_icon">
+ <property name="hexpand">true</property>
+ <property name="halign">end</property>
+ </object>
+ </child>
+ <child type="center">
+ <object class="GtkLabel" id="symbol_title">
+ <property name="label" translatable="yes">Document Outline</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
</template>
</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]