[gnome-builder/wip/alexl/emacs-css-keys: 3/5] GbSourceView: Add set-mode action to let you set modes



commit a7df2f035cf08121be2d9df7f3136af7f312cbd6
Author: Alexander Larsson <alexl redhat com>
Date:   Wed Feb 18 15:30:26 2015 +0100

    GbSourceView: Add set-mode action to let you set modes
    
    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;
    }

 src/editor/gb-source-view.c |   47 +++++++++++++++++++++++++++++++++++++++++++
 src/editor/gb-source-view.h |    3 ++
 2 files changed, 50 insertions(+), 0 deletions(-)
---
diff --git a/src/editor/gb-source-view.c b/src/editor/gb-source-view.c
index 47cb7ec..d033034 100644
--- a/src/editor/gb-source-view.c
+++ b/src/editor/gb-source-view.c
@@ -45,6 +45,7 @@
 #include "gb-source-view.h"
 #include "gb-source-vim.h"
 #include "gb-source-emacs.h" 
+#include "gb-source-view-mode.h"
 #include "gb-widget.h"
 
 enum {
@@ -63,6 +64,7 @@ struct _GbSourceViewPrivate
   GbSourceVim                 *vim;
   GbSourceEmacs               *emacs;
   GtkCssProvider              *css_provider;
+  GbSourceViewMode            *mode;
 
   GSettings                   *language_settings;
   GSettings                   *editor_settings;
@@ -113,6 +115,7 @@ enum {
   PUSH_SNIPPET,
   REQUEST_DOCUMENTATION,
   DROP_URIS,
+  SET_MODE,
   LAST_SIGNAL
 };
 
@@ -1455,6 +1458,17 @@ gb_source_view_key_press_event (GtkWidget   *widget,
 
   priv = view->priv;
 
+  if (priv->mode)
+    {
+      gboolean handled, remove;
+      handled = gb_source_view_mode_do_event (priv->mode, event, &remove);
+      if (remove)
+        g_clear_object (&priv->mode);
+
+      if (handled)
+        return TRUE;
+    }
+
   /*
    * Handle movement through the tab stops of the current snippet if needed.
    */
@@ -1858,6 +1872,25 @@ gb_source_view_request_documentation (GbSourceView *view)
 }
 
 static void
+gb_source_view_set_mode (GbSourceView           *view,
+                         const gchar            *mode,
+                         gboolean                transient)
+{
+  GbSourceViewPrivate *priv = view->priv;
+
+  ENTRY;
+
+  g_return_if_fail (GB_IS_SOURCE_VIEW (view));
+
+  g_clear_object (&priv->mode);
+
+  if (mode != NULL)
+    priv->mode = gb_source_view_mode_new (GTK_WIDGET (view), mode, GB_SOURCE_VIEW_MODE_TYPE_TRANSIENT);
+
+  EXIT;
+ }
+
+static void
 gb_source_view_grab_focus (GtkWidget *widget)
 {
   invalidate_window (GB_SOURCE_VIEW (widget));
@@ -2089,6 +2122,7 @@ gb_source_view_finalize (GObject *object)
   g_clear_object (&priv->vim);
   g_clear_object (&priv->emacs);
   g_clear_object (&priv->css_provider);
+  g_clear_object (&priv->mode);
 
   G_OBJECT_CLASS (gb_source_view_parent_class)->finalize (object);
 }
@@ -2223,6 +2257,7 @@ gb_source_view_class_init (GbSourceViewClass *klass)
   klass->draw_layer = gb_source_view_real_draw_layer;
   klass->display_documentation = gb_source_view_display_documentation;
   klass->request_documentation = gb_source_view_request_documentation;
+  klass->set_mode = gb_source_view_set_mode;
 
   gParamSpecs [PROP_ENABLE_WORD_COMPLETION] =
     g_param_spec_boolean ("enable-word-completion",
@@ -2386,6 +2421,18 @@ gb_source_view_class_init (GbSourceViewClass *klass)
                   1,
                   G_TYPE_STRV);
 
+  gSignals [SET_MODE] =
+    g_signal_new ("set-mode",
+                  GB_TYPE_SOURCE_VIEW,
+                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                  G_STRUCT_OFFSET (GbSourceViewClass, set_mode),
+                  NULL, NULL,
+                  g_cclosure_marshal_generic,
+                  G_TYPE_NONE,
+                  2,
+                  G_TYPE_STRING,
+                  GB_TYPE_SOURCE_VIEW_MODE_TYPE);
+
   binding_set = gtk_binding_set_by_class (klass);
   gtk_binding_entry_add_signal (binding_set,
                                 GDK_KEY_k,
diff --git a/src/editor/gb-source-view.h b/src/editor/gb-source-view.h
index e1b8bbf..d25f3de 100644
--- a/src/editor/gb-source-view.h
+++ b/src/editor/gb-source-view.h
@@ -69,6 +69,9 @@ struct _GbSourceViewClass
                                  const gchar            *search_text);
   void (*drop_uris)             (GbSourceViewClass      *view,
                                  const gchar            **uri_list);
+  void (*set_mode)              (GbSourceView           *view,
+                                 const gchar            *mode,
+                                 gboolean                transient);
 };
 
 void                  gb_source_view_begin_search         (GbSourceView         *view,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]