[gnome-builder] source-map: Refactor IdeSourceMap via extending GtkSourceMap



commit aae0b212fe95ad635161be7f5fae01176b1bf208
Author: Dimitris Zenios <dimitris zenios gmail com>
Date:   Wed May 20 02:13:35 2015 +0300

    source-map: Refactor IdeSourceMap via extending GtkSourceMap

 libide/ide-source-map.c |  891 ++++-------------------------------------------
 libide/ide-source-map.h |    6 +-
 2 files changed, 71 insertions(+), 826 deletions(-)
---
diff --git a/libide/ide-source-map.c b/libide/ide-source-map.c
index 79aaa08..3df90be 100644
--- a/libide/ide-source-map.c
+++ b/libide/ide-source-map.c
@@ -20,44 +20,27 @@
 
 #include <glib/gi18n.h>
 
+#include "egg-signal-group.h"
 #include "ide-buffer.h"
 #include "ide-line-change-gutter-renderer.h"
-#include "ide-macros.h"
-#include "ide-pango.h"
 #include "ide-source-map.h"
 #include "ide-source-view.h"
 
-#define DEFAULT_WIDTH        100
 #define CONCEAL_TIMEOUT      2000
 
 struct _IdeSourceMap
 {
-  GtkOverlay               parent_instance;
+  GtkSourceMap               parent_instance;
 
-  PangoFontDescription    *font_desc;
-
-  GtkCssProvider          *view_css_provider;
-  GtkCssProvider          *box_css_provider;
-
-  GtkSourceView           *child_view;
-  GtkEventBox             *overlay_box;
-  GtkSourceView           *view;
-  GtkSourceGutterRenderer *line_renderer;
-
-  guint                    delayed_conceal_timeout;
-
-  guint                    in_press : 1;
-  guint                    show_map : 1;
+  EggSignalGroup            *signal_group;
+  GtkTextBuffer             *buffer;
+  GtkSourceGutterRenderer   *line_renderer;
+  guint                      delayed_conceal_timeout;
+  guint                      show_map : 1;
 };
 
-G_DEFINE_TYPE (IdeSourceMap, ide_source_map, GTK_TYPE_OVERLAY)
+G_DEFINE_TYPE (IdeSourceMap, ide_source_map, GTK_SOURCE_TYPE_MAP)
 
-enum {
-  PROP_0,
-  PROP_FONT_DESC,
-  PROP_VIEW,
-  LAST_PROP
-};
 
 enum {
   SHOW_MAP,
@@ -65,7 +48,6 @@ enum {
   LAST_SIGNAL
 };
 
-static GParamSpec *gParamSpecs [LAST_PROP];
 static guint gSignals [LAST_SIGNAL];
 
 static gboolean
@@ -166,210 +148,6 @@ ide_source_map__scroll_event (IdeSourceMap   *self,
 }
 
 static void
-ide_source_map_rebuild_css (IdeSourceMap *self)
-{
-  g_assert (IDE_IS_SOURCE_MAP (self));
-
-  if (self->font_desc != NULL)
-    {
-      gchar *css;
-      gchar *tmp;
-
-      tmp = ide_pango_font_description_to_css (self->font_desc);
-      css = g_strdup_printf ("GtkSourceView { %s }\n", tmp ?: "");
-      gtk_css_provider_load_from_data (self->view_css_provider, css, -1, NULL);
-      g_free (css);
-      g_free (tmp);
-    }
-
-  if (self->view != NULL)
-    {
-      GtkSourceStyleScheme *style_scheme;
-      GtkTextBuffer *buffer;
-
-      buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->view));
-      style_scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (buffer));
-
-      if (style_scheme != NULL)
-        {
-          g_autofree gchar *background = NULL;
-          GtkSourceStyle *style;
-
-          if (!(style = gtk_source_style_scheme_get_style (style_scheme, "map-overlay")) &&
-              !(style = gtk_source_style_scheme_get_style (style_scheme, "selection")))
-            return;
-
-          g_object_get (style,
-                        "background", &background,
-                        NULL);
-
-          if ((background != NULL) && *background == '#')
-            {
-              gchar *css;
-
-              css = g_strdup_printf ("IdeSourceMap GtkEventBox {"
-                                     "  background-color: %s;"
-                                     "  opacity: 0.75;"
-                                     "  border-top: 1px solid shade(%s,0.9);"
-                                     "  border-bottom: 1px solid shade(%s,0.9);"
-                                     " }\n",
-                                     background, background, background);
-              gtk_css_provider_load_from_data (self->box_css_provider, css, -1, NULL);
-              g_free (css);
-            }
-        }
-    }
-}
-
-/**
- * ide_source_map_get_view:
- *
- * Gets the #IdeSourceMap:view property, which is the view this widget is mapping.
- *
- * Returns: (transfer none) (nullable): A #GtkSourceView or %NULL.
- */
-GtkSourceView *
-ide_source_map_get_view (IdeSourceMap *self)
-{
-  g_return_val_if_fail (IDE_IS_SOURCE_MAP (self), NULL);
-
-  return self->view;
-}
-
-static void
-update_scrubber_height (IdeSourceMap *self)
-{
-  GtkAllocation alloc;
-  gdouble ratio;
-  gint child_height;
-  gint view_height;
-
-  g_assert (self != NULL);
-  g_assert (self->view != NULL);
-  g_assert (self->child_view != NULL);
-
-  gtk_widget_get_allocation (GTK_WIDGET (self->view), &alloc);
-  gtk_widget_get_preferred_height (GTK_WIDGET (self->view), NULL, &view_height);
-  gtk_widget_get_preferred_height (GTK_WIDGET (self->child_view), NULL, &child_height);
-
-  ratio = alloc.height / (gdouble)view_height;
-  child_height *= ratio;
-
-  if (child_height > 0)
-    g_object_set (self->overlay_box,
-                  "height-request", child_height,
-                  NULL);
-}
-
-static void
-update_child_vadjustment (IdeSourceMap *self)
-{
-  GtkAdjustment *vadj;
-  GtkAdjustment *child_vadj;
-  gdouble value;
-  gdouble upper;
-  gdouble page_size;
-  gdouble child_value;
-  gdouble child_upper;
-  gdouble child_page_size;
-  gdouble new_value = 0.0;
-
-  g_assert (IDE_IS_SOURCE_MAP (self));
-
-  vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (self->view));
-  child_vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (self->child_view));
-
-  g_object_get (vadj,
-                "upper", &upper,
-                "value", &value,
-                "page-size", &page_size,
-                NULL);
-
-  g_object_get (child_vadj,
-                "upper", &child_upper,
-                "value", &child_value,
-                "page-size", &child_page_size,
-                NULL);
-
-  /*
-   * TODO: Technically we should take into account lower here, but in practice
-   *       it is always 0.0.
-   */
-
-  if (child_page_size < child_upper)
-    new_value = (value / (upper - page_size)) * (child_upper - child_page_size);
-
-  gtk_adjustment_set_value (child_vadj, new_value);
-}
-
-static void
-ide_source_map__view_vadj_value_changed (IdeSourceMap  *self,
-                                         GtkAdjustment *vadj)
-{
-  gdouble page_size;
-  gdouble upper;
-  gdouble lower;
-
-  g_assert (IDE_IS_SOURCE_MAP (self));
-  g_assert (GTK_IS_ADJUSTMENT (vadj));
-
-  gtk_widget_queue_resize (GTK_WIDGET (self->overlay_box));
-
-  g_object_get (vadj,
-                "lower", &lower,
-                "page-size", &page_size,
-                "upper", &upper,
-                NULL);
-
-  update_child_vadjustment (self);
-}
-
-static void
-ide_source_map__view_vadj_notify_upper (IdeSourceMap  *self,
-                                        GParamSpec    *pspec,
-                                        GtkAdjustment *vadj)
-{
-  g_assert (IDE_IS_SOURCE_MAP (self));
-  g_assert (GTK_IS_ADJUSTMENT (vadj));
-
-  update_scrubber_height (self);
-}
-
-static gboolean
-transform_font_desc (GBinding     *binding,
-                     const GValue *from_value,
-                     GValue       *to_value,
-                     gpointer      user_data)
-{
-  const PangoFontDescription *font_desc;
-  PangoFontDescription *copy = NULL;
-
-  font_desc = g_value_get_boxed (from_value);
-
-  if (font_desc != NULL)
-    {
-      copy = pango_font_description_copy (font_desc);
-      pango_font_description_set_size (copy, PANGO_SCALE);
-      pango_font_description_set_weight (copy, PANGO_WEIGHT_HEAVY);
-    }
-
-  g_value_take_boxed (to_value, copy);
-
-  return TRUE;
-}
-
-static void
-ide_source_map__buffer_notify_style_scheme (IdeSourceMap  *self,
-                                            GParamSpec    *pspec,
-                                            GtkTextBuffer *buffer)
-{
-  g_assert (IDE_IS_SOURCE_MAP (self));
-  g_assert (GTK_IS_TEXT_BUFFER (buffer));
-
-  ide_source_map_rebuild_css (self);
-}
-
-static void
 ide_source_map__buffer_line_flags_changed (IdeSourceMap *self,
                                            IdeBuffer    *buffer)
 {
@@ -390,425 +168,37 @@ ide_source_map__view_notify_buffer (IdeSourceMap  *self,
   g_assert (GTK_SOURCE_IS_VIEW (view));
 
   buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-  g_signal_connect_object (buffer,
-                           "notify::style-scheme",
-                           G_CALLBACK (ide_source_map__buffer_notify_style_scheme),
-                           self,
-                           G_CONNECT_SWAPPED);
-
-  if (IDE_IS_BUFFER (buffer))
-    g_signal_connect_object (buffer,
-                             "line-flags-changed",
-                             G_CALLBACK (ide_source_map__buffer_line_flags_changed),
-                             self,
-                             G_CONNECT_SWAPPED);
-
-  ide_source_map_rebuild_css (self);
-}
-
-void
-ide_source_map_set_view (IdeSourceMap  *self,
-                         GtkSourceView *view)
-{
-  g_return_if_fail (IDE_IS_SOURCE_MAP (self));
-  g_return_if_fail (!view || GTK_SOURCE_IS_VIEW (view));
-
-  if (ide_set_weak_pointer (&self->view, view))
+  if (self->buffer != buffer)
     {
-      if (view != NULL)
+      if (self->buffer != NULL)
         {
-          GtkAdjustment *vadj;
-          GtkTextBuffer *buffer;
-
-          g_object_bind_property (self->view, "buffer",
-                                  self->child_view, "buffer",
-                                  G_BINDING_SYNC_CREATE);
-          g_object_bind_property (self->view, "indent-width",
-                                  self->child_view, "indent-width",
-                                  G_BINDING_SYNC_CREATE);
-          g_object_bind_property (self->view, "tab-width",
-                                  self->child_view, "tab-width",
-                                  G_BINDING_SYNC_CREATE);
-
-          g_signal_connect_object (view,
-                                   "notify::buffer",
-                                   G_CALLBACK (ide_source_map__view_notify_buffer),
-                                   self,
-                                   G_CONNECT_SWAPPED);
-          g_signal_connect_object (view,
-                                   "enter-notify-event",
-                                   G_CALLBACK (ide_source_map__enter_notify_event),
-                                   self,
-                                   G_CONNECT_SWAPPED);
-          g_signal_connect_object (view,
-                                   "leave-notify-event",
-                                   G_CALLBACK (ide_source_map__leave_notify_event),
-                                   self,
-                                   G_CONNECT_SWAPPED);
-          g_signal_connect_object (view,
-                                   "motion-notify-event",
-                                   G_CALLBACK (ide_source_map__motion_notify_event),
-                                   self,
-                                   G_CONNECT_SWAPPED);
-          g_signal_connect_object (view,
-                                   "scroll-event",
-                                   G_CALLBACK (ide_source_map__scroll_event),
-                                   self,
-                                   G_CONNECT_SWAPPED);
-
-          buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-          ide_source_map__buffer_notify_style_scheme (self, NULL, buffer);
-
-          /*
-           * TODO: Not sure what we should do about this in terms of abstraction.
-           */
-          if (IDE_IS_SOURCE_VIEW (self->view))
-            g_object_bind_property_full (self->view, "font-desc",
-                                         self, "font-desc",
-                                         G_BINDING_SYNC_CREATE,
-                                         transform_font_desc,
-                                         NULL, NULL, NULL);
-
-          vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (self->view));
-
-          g_signal_connect_object (vadj,
-                                   "value-changed",
-                                   G_CALLBACK (ide_source_map__view_vadj_value_changed),
-                                   self,
-                                   G_CONNECT_SWAPPED);
+          g_signal_handlers_disconnect_by_func (self->buffer,
+                                                G_CALLBACK (ide_source_map__buffer_line_flags_changed),
+                                                self);
+          ide_clear_weak_pointer (&self->buffer);
+        }
 
-          g_signal_connect_object (vadj,
-                                   "notify::upper",
-                                   G_CALLBACK (ide_source_map__view_vadj_notify_upper),
+      if (IDE_IS_BUFFER (buffer))
+        {
+          ide_set_weak_pointer (&self->buffer, buffer);
+          g_signal_connect_object (buffer,
+                                   "line-flags-changed",
+                                   G_CALLBACK (ide_source_map__buffer_line_flags_changed),
                                    self,
                                    G_CONNECT_SWAPPED);
-
-          if ((gtk_widget_get_events (GTK_WIDGET (self->view)) & GDK_ENTER_NOTIFY_MASK) == 0)
-            gtk_widget_add_events (GTK_WIDGET (self->view), GDK_ENTER_NOTIFY_MASK);
-
-          if ((gtk_widget_get_events (GTK_WIDGET (self->view)) & GDK_LEAVE_NOTIFY_MASK) == 0)
-            gtk_widget_add_events (GTK_WIDGET (self->view), GDK_LEAVE_NOTIFY_MASK);
-
-          ide_source_map_rebuild_css (self);
         }
-
-      g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_VIEW]);
     }
 }
 
 static void
-ide_source_map_set_font_desc (IdeSourceMap               *self,
-                              const PangoFontDescription *font_desc)
+ide_source_map__view_changed (IdeSourceMap *self,
+                              GParamSpec   *psepct,
+                              gpointer      data)
 {
-  g_assert (IDE_IS_SOURCE_MAP (self));
-  g_assert (font_desc != NULL);
-
-  if (font_desc != self->font_desc)
-    {
-      if (self->font_desc)
-        g_clear_pointer (&self->font_desc, pango_font_description_free);
-
-      if (font_desc)
-        self->font_desc = pango_font_description_copy (font_desc);
-    }
-
-  ide_source_map_rebuild_css (self);
-}
-
-static void
-ide_source_map_set_font_name (IdeSourceMap *self,
-                              const gchar  *font_name)
-{
-  PangoFontDescription *font_desc;
-
-  g_assert (IDE_IS_SOURCE_MAP (self));
-
-  if (font_name == NULL)
-    font_name = "Monospace 1";
-
-  font_desc = pango_font_description_from_string (font_name);
-  ide_source_map_set_font_desc (self, font_desc);
-  pango_font_description_free (font_desc);
-}
-
-static void
-ide_source_map_get_preferred_width (GtkWidget *widget,
-                                    gint      *mininum_width,
-                                    gint      *natural_width)
-{
-  IdeSourceMap *self = (IdeSourceMap *)widget;
-  PangoLayout *layout;
-  guint right_margin_position;
-  gint height;
-  gint width;
-
-  g_assert (IDE_IS_SOURCE_MAP (self));
-  g_assert (mininum_width != NULL);
-  g_assert (natural_width != NULL);
-
-  if (self->font_desc == NULL)
-    {
-      *mininum_width = *natural_width = DEFAULT_WIDTH;
-      return;
-    }
-
-  layout = gtk_widget_create_pango_layout (GTK_WIDGET (self->child_view), "X");
-  pango_layout_get_pixel_size (layout, &width, &height);
-  g_clear_object (&layout);
-
-  right_margin_position = gtk_source_view_get_right_margin_position (self->view);
-  width *= right_margin_position;
-
-  *mininum_width = *natural_width = width;
-}
-
-static void
-ide_source_map_get_preferred_height (GtkWidget *widget,
-                                     gint      *minimum_height,
-                                     gint      *natural_height)
-{
-  IdeSourceMap *self = (IdeSourceMap *)widget;
-
-  g_assert (GTK_IS_WIDGET (widget));
-  g_assert (IDE_IS_SOURCE_MAP (self));
-  g_assert (minimum_height != NULL);
-  g_assert (natural_height != NULL);
-
-  if (self->view == NULL)
-    {
-      *minimum_height = *natural_height = 0;
-      return;
-    }
-
-  gtk_widget_get_preferred_height (GTK_WIDGET (self->child_view),
-                                   minimum_height, natural_height);
-
-  *minimum_height = 0;
-}
-
-static gboolean
-ide_source_map_get_child_position (GtkOverlay   *overlay,
-                                   GtkWidget    *child,
-                                   GdkRectangle *alloc)
-{
-  IdeSourceMap *self = (IdeSourceMap *)overlay;
-  GtkTextIter iter;
-  GdkRectangle visible_area;
-  GdkRectangle loc;
-  GtkAllocation our_alloc;
-
-  g_assert (IDE_IS_SOURCE_MAP (self));
-  g_assert (GTK_IS_OVERLAY (overlay));
-  g_assert (GTK_IS_WIDGET (child));
-  g_assert (alloc != NULL);
-
-  if (self->view == NULL)
-    return FALSE;
-
-  gtk_widget_get_allocation (GTK_WIDGET (overlay), &our_alloc);
-
-  alloc->x = 0;
-  alloc->width = our_alloc.width;
-
-  gtk_widget_get_preferred_height (child, NULL, &alloc->height);
-
-  gtk_text_view_get_visible_rect (GTK_TEXT_VIEW (self->view), &visible_area);
-  gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (self->view), &iter, visible_area.x,
-                                      visible_area.y);
-  gtk_text_view_get_iter_location (GTK_TEXT_VIEW (self->child_view), &iter, &loc);
-  gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (self->child_view),
-                                         GTK_TEXT_WINDOW_WIDGET,
-                                         loc.x, loc.y,
-                                         NULL, &alloc->y);
-
-  return TRUE;
-}
-
-static gboolean
-ide_source_map__child_view_button_press_event (IdeSourceMap   *self,
-                                               GdkEventButton *event,
-                                               GtkSourceView  *child_view)
-{
-  GtkTextIter iter;
-
-  g_assert (IDE_IS_SOURCE_MAP (self));
-  g_assert (event != NULL);
-  g_assert (GTK_SOURCE_IS_VIEW (child_view));
-
-  if (self->view != NULL)
-    {
-      gint x;
-      gint y;
-
-      gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (child_view), GTK_TEXT_WINDOW_WIDGET,
-                                             event->x, event->y, &x, &y);
-      gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (child_view), &iter, x, y);
-      gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (self->view), &iter, 0.0, TRUE, 1.0, 0.5);
-    }
-
-  return GDK_EVENT_STOP;
-}
-
-static void
-ide_source_map__child_view_state_flags_changed (GtkWidget     *widget,
-                                                GtkStateFlags  flags,
-                                                GtkWidget     *child_view)
-{
-  GdkWindow *window;
-
-  g_assert (IDE_IS_SOURCE_MAP (widget));
-  g_assert (GTK_SOURCE_IS_VIEW (child_view));
-
-  window = gtk_text_view_get_window (GTK_TEXT_VIEW (child_view), GTK_TEXT_WINDOW_TEXT);
-  if (window != NULL)
-    gdk_window_set_cursor (window, NULL);
-}
-
-static void
-ide_source_map__child_view_realize_after (GtkWidget *widget,
-                                          GtkWidget *child_view)
-{
-  g_assert (IDE_IS_SOURCE_MAP (widget));
-  g_assert (GTK_SOURCE_IS_VIEW (child_view));
-
-  ide_source_map__child_view_state_flags_changed (widget, 0, child_view);
-}
-
-static gboolean
-ide_source_map__overlay_box_button_press_event (IdeSourceMap   *self,
-                                                GdkEventButton *event,
-                                                GtkEventBox    *overlay_box)
-{
-  g_assert (IDE_IS_SOURCE_MAP (self));
-  g_assert (event != NULL);
-  g_assert (GTK_IS_EVENT_BOX (overlay_box));
-
-  gtk_grab_add (GTK_WIDGET (overlay_box));
-
-  self->in_press = TRUE;
-
-  return GDK_EVENT_PROPAGATE;
-}
-
-static gboolean
-ide_source_map__overlay_box_button_release_event (IdeSourceMap   *self,
-                                                  GdkEventButton *event,
-                                                  GtkEventBox    *overlay_box)
-{
-  g_assert (IDE_IS_SOURCE_MAP (self));
-  g_assert (event != NULL);
-  g_assert (GTK_IS_EVENT_BOX (overlay_box));
-
-  self->in_press = FALSE;
-
-  gtk_grab_remove (GTK_WIDGET (overlay_box));
-
-  return GDK_EVENT_PROPAGATE;
-}
-
-static gboolean
-ide_source_map__overlay_box_motion_notify_event (IdeSourceMap   *self,
-                                                 GdkEventMotion *event,
-                                                 GtkEventBox    *overlay_box)
-{
-  g_assert (IDE_IS_SOURCE_MAP (self));
-  g_assert (event != NULL);
-  g_assert (GTK_IS_EVENT_BOX (overlay_box));
-
-  if (self->in_press && (self->view != NULL))
-    {
-      GtkAllocation alloc;
-      GtkAllocation child_alloc;
-      GtkTextBuffer *buffer;
-      GdkRectangle rect;
-      GtkTextIter iter;
-      gdouble ratio;
-      gint child_height;
-      gint x;
-      gint y;
-
-      gtk_widget_get_allocation (GTK_WIDGET (overlay_box), &alloc);
-      gtk_widget_get_allocation (GTK_WIDGET (self->child_view), &child_alloc);
-
-      gtk_widget_translate_coordinates (GTK_WIDGET (overlay_box),
-                                        GTK_WIDGET (self->child_view),
-                                        event->x, event->y, &x, &y);
-
-      buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->child_view));
-      gtk_text_buffer_get_end_iter (buffer, &iter);
-      gtk_text_view_get_iter_location (GTK_TEXT_VIEW (self->child_view), &iter, &rect);
-
-      child_height = MIN (child_alloc.height, (rect.y + rect.height));
-
-      y = CLAMP (y, child_alloc.y, child_alloc.y + child_height) - child_alloc.y;
-      ratio = (gdouble)y / (gdouble)child_height;
-      y = (rect.y + rect.height) * ratio;
-
-      gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (self->child_view), &iter, x, y);
-
-      gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (self->view), &iter, 0.0, TRUE, 1.0, 0.5);
-    }
-
-  return GDK_EVENT_PROPAGATE;
-}
-
-static void
-ide_source_map_size_allocate (GtkWidget     *widget,
-                              GtkAllocation *alloc)
-{
-  IdeSourceMap *self = (IdeSourceMap *)widget;
-
-  GTK_WIDGET_CLASS (ide_source_map_parent_class)->size_allocate (widget, alloc);
-
-  update_scrubber_height (self);
-}
-
-static gboolean
-ide_source_map_do_scroll_event (IdeSourceMap   *self,
-                                GdkEventScroll *event,
-                                GtkWidget      *widget)
-{
-  g_assert (IDE_IS_SOURCE_MAP (self));
-  g_assert (event != NULL);
-  g_assert (GTK_IS_WIDGET (widget));
-
-#define SCROLL_ACCELERATION 4
-
-  /*
-   * TODO: This doesn't propagate kinetic scrolling or anything.
-   *       We should probably make something that does that.
-   */
-  if (self->view != NULL)
-    {
-      gdouble x;
-      gdouble y;
-      gint count = 0;
-
-      if (event->direction == GDK_SCROLL_UP)
-        {
-          count = -SCROLL_ACCELERATION;
-        }
-      else if (event->direction == GDK_SCROLL_DOWN)
-        {
-          count = SCROLL_ACCELERATION;
-        }
-      else
-        {
-          gdk_event_get_scroll_deltas ((GdkEvent *)event, &x, &y);
-
-          if (y > 0)
-            count = SCROLL_ACCELERATION;
-          else if (y < 0)
-            count = -SCROLL_ACCELERATION;
-        }
-
-      if (count != 0)
-        g_signal_emit_by_name (self->view, "move-viewport", GTK_SCROLL_STEPS, count);
-    }
-
-#undef SCROLL_ACCELERATION
+  g_return_if_fail (IDE_IS_SOURCE_MAP (self));
 
-  return GDK_EVENT_PROPAGATE;
+  egg_signal_group_set_target (self->signal_group,
+                               gtk_source_map_get_view (GTK_SOURCE_MAP (self)));
 }
 
 static void
@@ -822,88 +212,19 @@ ide_source_map_destroy (GtkWidget *widget)
       self->delayed_conceal_timeout = 0;
     }
 
-  g_clear_object (&self->box_css_provider);
-  g_clear_object (&self->view_css_provider);
-  g_clear_pointer (&self->font_desc, pango_font_description_free);
-  ide_clear_weak_pointer (&self->view);
+  ide_clear_weak_pointer (&self->buffer);
+  g_clear_object (&self->signal_group);
 
   GTK_WIDGET_CLASS (ide_source_map_parent_class)->destroy (widget);
 }
 
-static void
-ide_source_map_get_property (GObject    *object,
-                             guint       prop_id,
-                             GValue     *value,
-                             GParamSpec *pspec)
-{
-  IdeSourceMap *self = IDE_SOURCE_MAP (object);
-
-  switch (prop_id)
-    {
-    case PROP_VIEW:
-      g_value_set_object (value, ide_source_map_get_view (self));
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
-}
-
-static void
-ide_source_map_set_property (GObject      *object,
-                             guint         prop_id,
-                             const GValue *value,
-                             GParamSpec   *pspec)
-{
-  IdeSourceMap *self = IDE_SOURCE_MAP (object);
-
-  switch (prop_id)
-    {
-    case PROP_FONT_DESC:
-      ide_source_map_set_font_desc (self, g_value_get_boxed (value));
-      break;
-
-    case PROP_VIEW:
-      ide_source_map_set_view (self, g_value_get_object (value));
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
-}
 
 static void
 ide_source_map_class_init (IdeSourceMapClass *klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-  GtkOverlayClass *overlay_class = GTK_OVERLAY_CLASS (klass);
-
-  object_class->get_property = ide_source_map_get_property;
-  object_class->set_property = ide_source_map_set_property;
 
   widget_class->destroy = ide_source_map_destroy;
-  widget_class->get_preferred_height = ide_source_map_get_preferred_height;
-  widget_class->get_preferred_width = ide_source_map_get_preferred_width;
-  widget_class->size_allocate = ide_source_map_size_allocate;
-
-  overlay_class->get_child_position = ide_source_map_get_child_position;
-
-  gParamSpecs [PROP_VIEW] =
-    g_param_spec_object ("view",
-                         _("View"),
-                         _("The view this widget is mapping."),
-                         GTK_SOURCE_TYPE_VIEW,
-                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  gParamSpecs [PROP_FONT_DESC] =
-    g_param_spec_boxed ("font-desc",
-                        _("Font Description"),
-                        _("The Pango font description to use."),
-                        PANGO_TYPE_FONT_DESCRIPTION,
-                        (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
 
   gSignals [HIDE_MAP] =
     g_signal_new ("hide-map",
@@ -929,147 +250,75 @@ ide_source_map_class_init (IdeSourceMapClass *klass)
 static void
 ide_source_map_init (IdeSourceMap *self)
 {
-  GtkSourceCompletion *completion;
   GtkSourceGutter *gutter;
-  GtkStyleContext *context;
+  GtkSourceView *child_view = gtk_source_map_get_child_view (GTK_SOURCE_MAP (self));
 
-  self->child_view = g_object_new (GTK_SOURCE_TYPE_VIEW,
-                                   "auto-indent", FALSE,
-                                   "can-focus", FALSE,
-                                   "draw-spaces", 0,
-                                   "editable", FALSE,
-                                   "expand", FALSE,
-                                   "monospace", TRUE,
-                                   "show-line-numbers", FALSE,
-                                   "show-line-marks", FALSE,
-                                   "show-right-margin", FALSE,
-                                   "visible", TRUE,
-                                   NULL);
-  g_signal_connect_object (self->child_view,
-                           "button-press-event",
-                           G_CALLBACK (ide_source_map__child_view_button_press_event),
-                           self,
-                           G_CONNECT_SWAPPED);
-  gtk_widget_add_events (GTK_WIDGET (self->child_view), GDK_SCROLL_MASK);
-  g_signal_connect_object (self->child_view,
-                           "scroll-event",
-                           G_CALLBACK (ide_source_map_do_scroll_event),
-                           self,
-                           G_CONNECT_SWAPPED);
-  g_signal_connect_object (self->child_view,
-                           "state-flags-changed",
-                           G_CALLBACK (ide_source_map__child_view_state_flags_changed),
-                           self,
-                           G_CONNECT_SWAPPED | G_CONNECT_AFTER);
-  g_signal_connect_object (self->child_view,
-                           "realize",
-                           G_CALLBACK (ide_source_map__child_view_realize_after),
-                           self,
-                           G_CONNECT_SWAPPED | G_CONNECT_AFTER);
-  self->view_css_provider = gtk_css_provider_new ();
-  context = gtk_widget_get_style_context (GTK_WIDGET (self->child_view));
-  gtk_style_context_add_provider (context,
-                                  GTK_STYLE_PROVIDER (self->view_css_provider),
-                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-  gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->child_view));
-
-  /*
-   * TODO:
-   *
-   * nacho/pbor/gsv maintainers
-   *
-   * We should make this packable via GtkBuilder or an internal-child or something.
-   * That way, we can have GtkSourceMap in gb-editor-frame.ui and Builder can just
-   * add this there.
-   */
-  gutter = gtk_source_view_get_gutter (self->child_view, GTK_TEXT_WINDOW_LEFT);
+  gutter = gtk_source_view_get_gutter (child_view, GTK_TEXT_WINDOW_LEFT);
   self->line_renderer = g_object_new (IDE_TYPE_LINE_CHANGE_GUTTER_RENDERER,
                                       "size", 2,
                                       "visible", TRUE,
                                       NULL);
   gtk_source_gutter_insert (gutter, self->line_renderer, 0);
 
-  self->overlay_box = g_object_new (GTK_TYPE_EVENT_BOX,
-                                    "opacity", 0.5,
-                                    "visible", TRUE,
-                                    "height-request", 10,
-                                    "width-request", 100,
-                                    NULL);
-  g_signal_connect_object (self->overlay_box,
-                           "button-press-event",
-                           G_CALLBACK (ide_source_map__overlay_box_button_press_event),
-                           self,
-                           G_CONNECT_SWAPPED);
-  g_signal_connect_object (self->overlay_box,
-                           "scroll-event",
-                           G_CALLBACK (ide_source_map_do_scroll_event),
-                           self,
-                           G_CONNECT_SWAPPED);
-  g_signal_connect_object (self->overlay_box,
-                           "button-release-event",
-                           G_CALLBACK (ide_source_map__overlay_box_button_release_event),
-                           self,
-                           G_CONNECT_SWAPPED);
-  g_signal_connect_object (self->overlay_box,
-                           "motion-notify-event",
-                           G_CALLBACK (ide_source_map__overlay_box_motion_notify_event),
+  /* View */
+  self->signal_group = egg_signal_group_new (GTK_SOURCE_TYPE_VIEW);
+
+  g_signal_connect_object (self,
+                           "notify::view",
+                           G_CALLBACK (ide_source_map__view_changed),
                            self,
                            G_CONNECT_SWAPPED);
-  context = gtk_widget_get_style_context (GTK_WIDGET (self->overlay_box));
-  self->box_css_provider = gtk_css_provider_new ();
-  gtk_style_context_add_provider (context,
-                                  GTK_STYLE_PROVIDER (self->box_css_provider),
-                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 
-  gtk_overlay_add_overlay (GTK_OVERLAY (self), GTK_WIDGET (self->overlay_box));
+  egg_signal_group_connect_object (self->signal_group,
+                                   "notify::buffer",
+                                   G_CALLBACK (ide_source_map__view_notify_buffer),
+                                   self,
+                                   G_CONNECT_SWAPPED);
 
-  completion = gtk_source_view_get_completion (self->child_view);
-  gtk_source_completion_block_interactive (completion);
+  egg_signal_group_connect_object (self->signal_group,
+                                   "enter-notify-event",
+                                   G_CALLBACK (ide_source_map__enter_notify_event),
+                                   self,
+                                   G_CONNECT_SWAPPED);
 
-  ide_source_map_set_font_name (self, "Monospace 1");
+  egg_signal_group_connect_object (self->signal_group,
+                                   "leave-notify-event",
+                                   G_CALLBACK (ide_source_map__leave_notify_event),
+                                   self,
+                                   G_CONNECT_SWAPPED);
 
-  gtk_widget_add_events (GTK_WIDGET (self->overlay_box),
-                         (GDK_SCROLL_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK));
-  gtk_widget_add_events (GTK_WIDGET (self->child_view),
-                         (GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK));
+  egg_signal_group_connect_object (self->signal_group,
+                                   "motion-notify-event",
+                                   G_CALLBACK (ide_source_map__motion_notify_event),
+                                   self,
+                                   G_CONNECT_SWAPPED);
 
-  g_signal_connect_object (self->overlay_box,
-                           "enter-notify-event",
-                           G_CALLBACK (ide_source_map__enter_notify_event),
-                           self,
-                           G_CONNECT_SWAPPED);
-  g_signal_connect_object (self->overlay_box,
-                           "leave-notify-event",
-                           G_CALLBACK (ide_source_map__leave_notify_event),
-                           self,
-                           G_CONNECT_SWAPPED);
-  g_signal_connect_object (self->overlay_box,
-                           "motion-notify-event",
-                           G_CALLBACK (ide_source_map__motion_notify_event),
-                           self,
-                           G_CONNECT_SWAPPED);
-  g_signal_connect_object (self->overlay_box,
-                           "scroll-event",
-                           G_CALLBACK (ide_source_map__scroll_event),
-                           self,
-                           G_CONNECT_SWAPPED);
+  egg_signal_group_connect_object (self->signal_group,
+                                   "scroll-event",
+                                   G_CALLBACK (ide_source_map__scroll_event),
+                                   self,
+                                   G_CONNECT_SWAPPED);
 
-  g_signal_connect_object (self->child_view,
+  /* Child view */
+  g_signal_connect_object (child_view,
                            "enter-notify-event",
                            G_CALLBACK (ide_source_map__enter_notify_event),
                            self,
                            G_CONNECT_SWAPPED);
-  g_signal_connect_object (self->child_view,
+
+  g_signal_connect_object (child_view,
                            "leave-notify-event",
                            G_CALLBACK (ide_source_map__leave_notify_event),
                            self,
                            G_CONNECT_SWAPPED);
-  g_signal_connect_object (self->child_view,
+
+  g_signal_connect_object (child_view,
                            "motion-notify-event",
                            G_CALLBACK (ide_source_map__motion_notify_event),
                            self,
                            G_CONNECT_SWAPPED);
-  g_signal_connect_object (self->child_view,
+
+  g_signal_connect_object (child_view,
                            "scroll-event",
                            G_CALLBACK (ide_source_map__scroll_event),
                            self,
diff --git a/libide/ide-source-map.h b/libide/ide-source-map.h
index 4699f7d..1f9548b 100644
--- a/libide/ide-source-map.h
+++ b/libide/ide-source-map.h
@@ -26,11 +26,7 @@ G_BEGIN_DECLS
 #define IDE_TYPE_SOURCE_MAP            (ide_source_map_get_type())
 
 G_DECLARE_FINAL_TYPE (IdeSourceMap, ide_source_map,
-                      IDE, SOURCE_MAP, GtkOverlay)
-
-GtkSourceView *ide_source_map_get_view (IdeSourceMap  *self);
-void           ide_source_map_set_view (IdeSourceMap  *self,
-                                        GtkSourceView *view);
+                      IDE, SOURCE_MAP, GtkSourceMap)
 
 G_END_DECLS
 


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