[gnome-builder/wip/libide] libide: add IdeSourceView::capture-modifier and ::clear-modifier
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/libide] libide: add IdeSourceView::capture-modifier and ::clear-modifier
- Date: Wed, 11 Mar 2015 03:39:01 +0000 (UTC)
commit 1fa117a3c43c59a48a58cb227ae2a29713339e36
Author: Christian Hergert <christian hergert me>
Date: Tue Mar 10 20:37:02 2015 -0700
libide: add IdeSourceView::capture-modifier and ::clear-modifier
These signals help in the process of waiting for a modifier key. This can
be used to pass to movements that require additional input.
The capture-modifier signal will block the main loop (similar to that of
gtk_dialog_run() until the key as been pressed or focus leaves). After
which, the signal bindings can continue.
libide/ide-source-view-movements.c | 3 +
libide/ide-source-view-movements.h | 1 +
libide/ide-source-view.c | 96 +++++++++++++++++++++++++++++++++++-
libide/ide-source-view.h | 2 +
4 files changed, 101 insertions(+), 1 deletions(-)
---
diff --git a/libide/ide-source-view-movements.c b/libide/ide-source-view-movements.c
index fe9ef6f..9495812 100644
--- a/libide/ide-source-view-movements.c
+++ b/libide/ide-source-view-movements.c
@@ -44,6 +44,7 @@ typedef struct
GtkTextIter insert; /* Current insert cursor location */
GtkTextIter selection; /* Current selection cursor location */
gint count; /* Repeat count for movement */
+ gunichar modifier; /* For forward/backward char search */
guint extend_selection : 1; /* If selection should be extended */
guint exclusive : 1; /* See ":help exclusive" in vim */
guint ignore_select : 1; /* Don't update selection after movement */
@@ -1184,6 +1185,7 @@ _ide_source_view_apply_movement (IdeSourceView *self,
gboolean extend_selection,
gboolean exclusive,
guint count,
+ gunichar modifier,
gint *target_offset)
{
Movement mv = { 0 };
@@ -1219,6 +1221,7 @@ _ide_source_view_apply_movement (IdeSourceView *self,
mv.count = count;
mv.ignore_select = FALSE;
mv.ignore_target_offset = FALSE;
+ mv.modifier = modifier;
ide_source_view_movements_get_selection (&mv);
diff --git a/libide/ide-source-view-movements.h b/libide/ide-source-view-movements.h
index 4f17fee..0cfcb7b 100644
--- a/libide/ide-source-view-movements.h
+++ b/libide/ide-source-view-movements.h
@@ -28,6 +28,7 @@ void _ide_source_view_apply_movement (IdeSourceView *source_view,
gboolean extend_selection,
gboolean exclusive,
guint count,
+ gunichar modifier,
gint *target_offset);
G_END_DECLS
diff --git a/libide/ide-source-view.c b/libide/ide-source-view.c
index f3316a0..eb6cea4 100644
--- a/libide/ide-source-view.c
+++ b/libide/ide-source-view.c
@@ -110,6 +110,7 @@ typedef struct
guint change_sequence;
gint target_line_offset;
+ gunichar modifier;
guint count;
guint scroll_offset;
@@ -127,6 +128,7 @@ typedef struct
guint show_grid_lines : 1;
guint show_line_changes : 1;
guint snippet_completion : 1;
+ guint waiting_for_capture : 1;
} IdeSourceViewPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (IdeSourceView, ide_source_view, GTK_SOURCE_TYPE_VIEW)
@@ -151,8 +153,10 @@ enum {
ACTION,
APPEND_TO_COUNT,
AUTO_INDENT,
+ CAPTURE_MODIFIER,
CHANGE_CASE,
CLEAR_COUNT,
+ CLEAR_MODIFIER,
CLEAR_SELECTION,
CLEAR_SNIPPETS,
CYCLE_COMPLETION,
@@ -1618,6 +1622,33 @@ ide_source_view_do_mode (IdeSourceView *self,
}
static gboolean
+is_modifier_key (GdkEventKey *event)
+{
+ static const guint modifier_keyvals[] = {
+ GDK_KEY_Shift_L, GDK_KEY_Shift_R, GDK_KEY_Shift_Lock,
+ GDK_KEY_Caps_Lock, GDK_KEY_ISO_Lock, GDK_KEY_Control_L,
+ GDK_KEY_Control_R, GDK_KEY_Meta_L, GDK_KEY_Meta_R,
+ GDK_KEY_Alt_L, GDK_KEY_Alt_R, GDK_KEY_Super_L, GDK_KEY_Super_R,
+ GDK_KEY_Hyper_L, GDK_KEY_Hyper_R, GDK_KEY_ISO_Level3_Shift,
+ GDK_KEY_ISO_Next_Group, GDK_KEY_ISO_Prev_Group,
+ GDK_KEY_ISO_First_Group, GDK_KEY_ISO_Last_Group,
+ GDK_KEY_Mode_switch, GDK_KEY_Num_Lock, GDK_KEY_Multi_key,
+ GDK_KEY_Scroll_Lock,
+ 0
+ };
+ const guint *ac_val;
+
+ ac_val = modifier_keyvals;
+ while (*ac_val)
+ {
+ if (event->keyval == *ac_val++)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
ide_source_view_key_press_event (GtkWidget *widget,
GdkEventKey *event)
{
@@ -1631,6 +1662,13 @@ ide_source_view_key_press_event (GtkWidget *widget,
g_assert (IDE_IS_SOURCE_VIEW (self));
+ if (priv->waiting_for_capture)
+ {
+ if (!is_modifier_key (event))
+ priv->modifier = gdk_keyval_to_unicode (event->keyval);
+ return TRUE;
+ }
+
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self));
insert = gtk_text_buffer_get_insert (buffer);
@@ -1886,6 +1924,19 @@ ide_source_view_real_auto_indent (IdeSourceView *self)
}
static void
+ide_source_view_real_capture_modifier (IdeSourceView *self)
+{
+ IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
+
+ g_assert (IDE_IS_SOURCE_VIEW (self));
+
+ priv->waiting_for_capture = TRUE;
+ while ((priv->modifier == 0) && gtk_widget_has_focus (GTK_WIDGET (self)))
+ gtk_main_iteration ();
+ priv->waiting_for_capture = FALSE;
+}
+
+static void
ide_source_view_real_change_case (IdeSourceView *self,
GtkSourceChangeCaseType type)
{
@@ -1913,6 +1964,16 @@ ide_source_view_real_clear_count (IdeSourceView *self)
}
static void
+ide_source_view_real_clear_modifier (IdeSourceView *self)
+{
+ IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
+
+ g_assert (IDE_IS_SOURCE_VIEW (self));
+
+ priv->modifier = 0;
+}
+
+static void
ide_source_view_real_clear_selection (IdeSourceView *self)
{
GtkTextView *text_view = (GtkTextView *)self;
@@ -2437,7 +2498,7 @@ ide_source_view_real_movement (IdeSourceView *self,
count = priv->count;
_ide_source_view_apply_movement (self, movement, extend_selection, exclusive,
- count, &priv->target_line_offset);
+ count, priv->modifier, &priv->target_line_offset);
}
static void
@@ -3210,8 +3271,10 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
klass->action = ide_source_view_real_action;
klass->append_to_count = ide_source_view_real_append_to_count;
klass->auto_indent = ide_source_view_real_auto_indent;
+ klass->capture_modifier = ide_source_view_real_capture_modifier;
klass->change_case = ide_source_view_real_change_case;
klass->clear_count = ide_source_view_real_clear_count;
+ klass->clear_modifier = ide_source_view_real_clear_modifier;
klass->clear_snippets = ide_source_view_clear_snippets;
klass->clear_selection = ide_source_view_real_clear_selection;
klass->cycle_completion = ide_source_view_real_cycle_completion;
@@ -3361,6 +3424,27 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
G_TYPE_NONE,
0);
+ /**
+ * IdeSourceView::capture-modifier:
+ *
+ * This signal will block the main loop in a similar fashion to how
+ * gtk_dialog_run() performs until a key-press has occurred that can be
+ * captured for use in movements.
+ *
+ * Pressing Escape or unfocusing the widget will break from this loop.
+ *
+ * Use of this signal is not recommended except in very specific cases.
+ */
+ gSignals [CAPTURE_MODIFIER] =
+ g_signal_new ("capture-modifier",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (IdeSourceViewClass, capture_modifier),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
gSignals [CHANGE_CASE] =
g_signal_new ("change-case",
G_TYPE_FROM_CLASS (klass),
@@ -3382,6 +3466,16 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
G_TYPE_NONE,
0);
+ gSignals [CLEAR_MODIFIER] =
+ g_signal_new ("clear-modifier",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (IdeSourceViewClass, clear_modifier),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
gSignals [CLEAR_SELECTION] =
g_signal_new ("clear-selection",
G_TYPE_FROM_CLASS (klass),
diff --git a/libide/ide-source-view.h b/libide/ide-source-view.h
index d8fddfa..ababfda 100644
--- a/libide/ide-source-view.h
+++ b/libide/ide-source-view.h
@@ -206,9 +206,11 @@ struct _IdeSourceViewClass
void (*append_to_count) (IdeSourceView *self,
gint digit);
void (*auto_indent) (IdeSourceView *self);
+ void (*capture_modifier) (IdeSourceView *self);
void (*change_case) (IdeSourceView *self,
GtkSourceChangeCaseType type);
void (*clear_count) (IdeSourceView *self);
+ void (*clear_modifier) (IdeSourceView *self);
void (*clear_selection) (IdeSourceView *self);
void (*clear_snippets) (IdeSourceView *self);
void (*cycle_completion) (IdeSourceView *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]