[gnome-builder/wip/libide] libide: add IdeSourceView:mode property
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/libide] libide: add IdeSourceView:mode property
- Date: Wed, 4 Mar 2015 00:16:25 +0000 (UTC)
commit d9fbce2d20f501a2745a8d43e2f76f92df1441a9
Author: Christian Hergert <christian hergert me>
Date: Tue Mar 3 15:51:43 2015 -0800
libide: add IdeSourceView:mode property
This is a fairly straightforward port of Alex's work on GbSourceViewMode
but down into LibIDE.
--
This lets you set up modal keyboar accelerators.
For instance, you can emulate the emacs "c-x c-c" exit keybinding with
this CSS snippet:
@binding-set bindings-emacs {
bind "<ctrl>x" { "set-mode" ("emacs-x", transient) };
}
@binding-set bindings-emacs-x {
bind "<ctrl>c" { "action" ("app", "quit", "") };
}
GbSourceView {
gtk-key-bindings: bindings-emacs;
}
GbSourceViewMode.emacs-x {
gtk-key-bindings: bindings-emacs-x;
}
libide/.gitignore | 2 +
libide/Makefile.am | 21 ++++++++++++++-
libide/ide-enums.c.template | 41 ++++++++++++++++++++++++++++++
libide/ide-enums.h.template | 24 +++++++++++++++++
libide/ide-source-view-mode.c | 1 +
libide/ide-source-view-mode.h | 18 -------------
libide/ide-source-view.c | 56 +++++++++++++++++++++++++++++++++++++++++
libide/ide-source-view.h | 18 +++++++++++++
libide/ide.h | 1 +
9 files changed, 163 insertions(+), 19 deletions(-)
---
diff --git a/libide/.gitignore b/libide/.gitignore
new file mode 100644
index 0000000..071b813
--- /dev/null
+++ b/libide/.gitignore
@@ -0,0 +1,2 @@
+ide-enums.c
+ide-enums.h
diff --git a/libide/Makefile.am b/libide/Makefile.am
index 4012c4b..518687c 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -302,9 +302,15 @@ else
AM_CPPFLAGS += -DIDE_DISABLE_DEBUG
endif
+libide_1_0_la_type_headers = \
+ libide/ide-source-view.h \
+ $(NULL)
+
libide_1_0_la_built_sources = \
libide/resources/ide-resources.c \
libide/resources/ide-resources.h \
+ libide/ide-enums.c \
+ libide/ide-enums.h \
$(NULL)
libide_resource_files = $(shell glib-compile-resources --sourcedir=$(top_srcdir)/libide/resources
--generate-dependencies $(top_srcdir)/libide/resources/libide.gresource.xml)
@@ -313,6 +319,13 @@ libide/resources/ide-resources.c: libide/resources/libide.gresource.xml $(libide
libide/resources/ide-resources.h: libide/resources/libide.gresource.xml $(libide_resource_files)
$(AM_V_GEN)glib-compile-resources --target=$@ --sourcedir=$(top_srcdir)/libide/resources
--generate-header --c-name ide $(top_srcdir)/libide/resources/libide.gresource.xml
+libide/ide-enums.h: $(libide_1_0_la_type_headers) libide/ide-enums.h.template
+ $(AM_V_GEN) ( cd $(srcdir) && glib-mkenums --template libide/ide-enums.h.template
$(libide_1_0_la_type_headers) ) > libide/ide-enums.h.tmp
+ @ mv libide/ide-enums.h.tmp libide/ide-enums.h
+libide/ide-enums.c: $(libide_1_0_la_type_headers) libide/ide-enums.c.template
+ $(AM_V_GEN) ( cd $(srcdir) && glib-mkenums --template libide/ide-enums.c.template
$(libide_1_0_la_type_headers) ) > libide/ide-enums.c.tmp
+ @ mv libide/ide-enums.c.tmp libide/ide-enums.c
+
nodist_libide_1_0_la_SOURCES = \
$(libide_1_0_la_built_sources) \
$(NULL)
@@ -324,6 +337,8 @@ DISTCLEANFILES += $(libide_1_0_la_built_sources)
EXTRA_DIST += \
$(libide_resource_files) \
libide/resources/libide.gresource.xml \
+ libide/ide-enums.c.template \
+ libide/ide-enums.h.template \
$(libide_1_0_la_built_sources) \
$(NULL)
@@ -335,7 +350,11 @@ INTROSPECTION_SCANNER_ARGS = --add-include-path=$(top_srcdir)/libide --warn-all
INTROSPECTION_COMPILER_ARGS = --includedir=$(top_srcdir)/libide
if HAVE_INTROSPECTION
-introspection_sources = $(libide_1_0_la_public_sources)
+introspection_sources = \
+ $(libide_1_0_la_public_sources) \
+ libide/ide-enums.c \
+ libide/ide-enums.h \
+ $(NULL)
Ide-1.0.gir: libide-1.0.la
Ide_1_0_gir_INCLUDES = Gio-2.0 GtkSource-3.0 Ggit-1.0
diff --git a/libide/ide-enums.c.template b/libide/ide-enums.c.template
new file mode 100644
index 0000000..a033aef
--- /dev/null
+++ b/libide/ide-enums.c.template
@@ -0,0 +1,41 @@
+/*** BEGIN file-header ***/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "ide-enums.h"
+
+#include "ide-source-view.h"
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+ enum_name@_get_type (void)
+{
+ static GType etype = 0;
+ if (G_UNLIKELY(etype == 0)) {
+ static const G Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+ etype = g_ type@_register_static (g_intern_static_string ("@EnumName@"), values);
+ }
+ return etype;
+}
+
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+
+/*** END file-tail ***/
diff --git a/libide/ide-enums.h.template b/libide/ide-enums.h.template
new file mode 100644
index 0000000..3722cdc
--- /dev/null
+++ b/libide/ide-enums.h.template
@@ -0,0 +1,24 @@
+/*** BEGIN file-header ***/
+#ifndef __IDE_ENUMS_H__
+#define __IDE_ENUMS_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name _get_type (void);
+#define @ENUMPREFIX _TYPE_@ENUMSHORT@ (@enum_name _get_type ())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* __IDE_ENUMS_H__ */
+/*** END file-tail ***/
diff --git a/libide/ide-source-view-mode.c b/libide/ide-source-view-mode.c
index fbee293..15a5abd 100644
--- a/libide/ide-source-view-mode.c
+++ b/libide/ide-source-view-mode.c
@@ -20,6 +20,7 @@
#include <glib/gi18n.h>
+#include "ide-source-view.h"
#include "ide-source-view-mode.h"
typedef struct
diff --git a/libide/ide-source-view-mode.h b/libide/ide-source-view-mode.h
index e705b3e..7f72b3c 100644
--- a/libide/ide-source-view-mode.h
+++ b/libide/ide-source-view-mode.h
@@ -21,7 +21,6 @@
#include <gtk/gtk.h>
-#include "ide-source-view.h"
#include "ide-types.h"
G_BEGIN_DECLS
@@ -47,23 +46,6 @@ struct _IdeSourceViewModeClass
GtkWidgetClass parent_class;
};
-/**
- * IdeSourceViewModeType:
- * @IDE_SOURCE_VIEW_MODE_TRANSIENT: Transient
- * @IDE_SOURCE_VIEW_MODE_PERMANENT: Permanent
- * @IDE_SOURCE_VIEW_MODE_MODAL: Modal
- *
- * The type of keyboard mode.
- */
-typedef enum
-{
- IDE_SOURCE_VIEW_MODE_TYPE_TRANSIENT,
- IDE_SOURCE_VIEW_MODE_TYPE_PERMANENT,
- IDE_SOURCE_VIEW_MODE_TYPE_MODAL
-} IdeSourceViewModeType;
-
-GType ide_source_view_mode_get_type (void);
-
G_END_DECLS
#endif /* IDE_SOURCE_VIEW_MODE_H */
diff --git a/libide/ide-source-view.c b/libide/ide-source-view.c
index edca35e..42eb579 100644
--- a/libide/ide-source-view.c
+++ b/libide/ide-source-view.c
@@ -26,10 +26,13 @@
#include "ide-box-theatric.h"
#include "ide-buffer.h"
#include "ide-context.h"
+#include "ide-debug.h"
#include "ide-diagnostic.h"
+#include "ide-enums.h"
#include "ide-file.h"
#include "ide-file-settings.h"
#include "ide-highlighter.h"
+#include "ide-internal.h"
#include "ide-indenter.h"
#include "ide-language.h"
#include "ide-line-change-gutter-renderer.h"
@@ -43,6 +46,7 @@
#include "ide-source-snippets-manager.h"
#include "ide-source-location.h"
#include "ide-source-view.h"
+#include "ide-source-view-mode.h"
#define DEFAULT_FONT_DESC "Monospace 11"
#define ANIMATION_X_GROW 50
@@ -57,6 +61,7 @@ typedef struct
IdeIndenter *indenter;
GtkSourceGutterRenderer *line_change_renderer;
GtkSourceGutterRenderer *line_diagnostics_renderer;
+ IdeSourceViewMode *mode;
GQueue *snippets;
GtkSourceCompletionProvider *snippets_provider;
@@ -99,6 +104,7 @@ enum {
JUMP,
PUSH_SNIPPET,
POP_SNIPPET,
+ SET_MODE,
LAST_SIGNAL
};
@@ -1124,6 +1130,24 @@ ide_source_view_key_press_event (GtkWidget *widget,
g_assert (IDE_IS_SOURCE_VIEW (self));
+ /*
+ * If we are in a non-default mode, dispatch the event to the mode. This allows custom
+ * keybindings like Emacs and Vim to be implemented using gtk-bindings CSS.
+ */
+ if (priv->mode)
+ {
+ gboolean handled;
+ gboolean remove = FALSE;
+
+ handled = _ide_source_view_mode_do_event (priv->mode, event, &remove);
+
+ if (remove)
+ g_clear_object (&priv->mode);
+
+ if (handled)
+ return TRUE;
+ }
+
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self));
/*
@@ -1332,6 +1356,25 @@ ide_source_view_real_jump (IdeSourceView *self,
}
static void
+ide_source_view_real_set_mode (IdeSourceView *self,
+ const gchar *mode,
+ IdeSourceViewModeType type)
+{
+ IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_SOURCE_VIEW (self));
+
+ g_clear_object (&priv->mode);
+
+ if (mode != NULL)
+ priv->mode = _ide_source_view_mode_new (GTK_WIDGET (self), mode, type);
+
+ IDE_EXIT;
+}
+
+static void
ide_source_view_constructed (GObject *object)
{
IdeSourceView *self = (IdeSourceView *)object;
@@ -1373,6 +1416,7 @@ ide_source_view_dispose (GObject *object)
g_clear_object (&priv->line_diagnostics_renderer);
g_clear_object (&priv->snippets_provider);
g_clear_object (&priv->css_provider);
+ g_clear_object (&priv->mode);
if (priv->buffer)
{
@@ -1504,6 +1548,7 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
widget_class->query_tooltip = ide_source_view_query_tooltip;
klass->jump = ide_source_view_real_jump;
+ klass->set_mode = ide_source_view_real_set_mode;
g_object_class_override_property (object_class, PROP_AUTO_INDENT, "auto-indent");
@@ -1580,6 +1625,17 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
1,
GTK_TYPE_TEXT_ITER);
+ gSignals [SET_MODE] = g_signal_new ("set-mode",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (IdeSourceViewClass, set_mode),
+ NULL, NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_STRING,
+ IDE_TYPE_SOURCE_VIEW_MODE_TYPE);
+
gSignals [POP_SNIPPET] = g_signal_new ("pop-snippet",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
diff --git a/libide/ide-source-view.h b/libide/ide-source-view.h
index 0194e87..f0ee91e 100644
--- a/libide/ide-source-view.h
+++ b/libide/ide-source-view.h
@@ -36,6 +36,21 @@ G_BEGIN_DECLS
typedef struct _IdeSourceView IdeSourceView;
typedef struct _IdeSourceViewClass IdeSourceViewClass;
+/**
+ * IdeSourceViewModeType:
+ * @IDE_SOURCE_VIEW_MODE_TRANSIENT: Transient
+ * @IDE_SOURCE_VIEW_MODE_PERMANENT: Permanent
+ * @IDE_SOURCE_VIEW_MODE_MODAL: Modal
+ *
+ * The type of keyboard mode.
+ */
+typedef enum
+{
+ IDE_SOURCE_VIEW_MODE_TYPE_TRANSIENT,
+ IDE_SOURCE_VIEW_MODE_TYPE_PERMANENT,
+ IDE_SOURCE_VIEW_MODE_TYPE_MODAL
+} IdeSourceViewModeType;
+
G_DEFINE_AUTOPTR_CLEANUP_FUNC (IdeSourceView, g_object_unref)
struct _IdeSourceView
@@ -55,6 +70,9 @@ struct _IdeSourceViewClass
IdeSourceSnippet *snippet,
IdeSourceSnippetContext *context,
const GtkTextIter *location);
+ void (*set_mode) (IdeSourceView *self,
+ const gchar *mode,
+ IdeSourceViewModeType type);
};
void ide_source_view_clear_snippets (IdeSourceView *self);
diff --git a/libide/ide.h b/libide/ide.h
index 5f7ba98..84eb0ae 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -42,6 +42,7 @@ G_BEGIN_DECLS
#include "ide-diagnostics.h"
#include "ide-diagnostician.h"
#include "ide-diagnostic-provider.h"
+#include "ide-enums.h"
#include "ide-executable.h"
#include "ide-executer.h"
#include "ide-file.h"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]