[gtksourceview/wip/grid] Provide a way to draw background patterns



commit f10009a7a8ed644d9e6651c253b0276538ddfd15
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Wed Jan 21 14:23:10 2015 +0100

    Provide a way to draw background patterns
    
    A new property background-pattern is added to support
    different kind of patterns. For now only Grid is supported.
    Also a new background-pattern style has been added so it
    can be used by the style schemes.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=742148

 docs/reference/gtksourceview-3.0-sections.txt |    3 +
 gtksourceview/gtksourcestylescheme.c          |   18 +++
 gtksourceview/gtksourcestylescheme.h          |    5 +
 gtksourceview/gtksourcetypes.h                |   13 +++
 gtksourceview/gtksourceview.c                 |  142 ++++++++++++++++++++++++-
 gtksourceview/gtksourceview.h                 |    5 +
 tests/test-widget.c                           |   27 +++++
 tests/test-widget.ui                          |   15 +++
 8 files changed, 227 insertions(+), 1 deletions(-)
---
diff --git a/docs/reference/gtksourceview-3.0-sections.txt b/docs/reference/gtksourceview-3.0-sections.txt
index 8b3e2bd..7b86ced 100644
--- a/docs/reference/gtksourceview-3.0-sections.txt
+++ b/docs/reference/gtksourceview-3.0-sections.txt
@@ -801,6 +801,7 @@ GtkSourceView
 GtkSourceSmartHomeEndType
 GtkSourceDrawSpacesFlags
 GtkSourceViewGutterPosition
+GtkSourceBackgroundPatternType
 gtk_source_view_new
 gtk_source_view_new_with_buffer
 gtk_source_view_set_show_line_numbers
@@ -834,6 +835,8 @@ gtk_source_view_set_draw_spaces
 gtk_source_view_get_draw_spaces
 gtk_source_view_get_completion
 gtk_source_view_get_gutter
+gtk_source_view_set_background_pattern
+gtk_source_view_get_background_pattern
 <SUBSECTION Standard>
 GtkSourceViewClass
 GTK_SOURCE_IS_VIEW
diff --git a/gtksourceview/gtksourcestylescheme.c b/gtksourceview/gtksourcestylescheme.c
index 7c7207c..25ad907 100644
--- a/gtksourceview/gtksourcestylescheme.c
+++ b/gtksourceview/gtksourcestylescheme.c
@@ -54,6 +54,7 @@
 #define STYLE_LINE_NUMBERS             "line-numbers"
 #define STYLE_RIGHT_MARGIN             "right-margin"
 #define STYLE_DRAW_SPACES              "draw-spaces"
+#define STYLE_BACKGROUND_PATTERN       "background-pattern"
 
 #define STYLE_SCHEME_VERSION           "1.0"
 
@@ -634,6 +635,23 @@ _gtk_source_style_scheme_get_current_line_color (GtkSourceStyleScheme *scheme,
        return get_color (style, FALSE, color);
 }
 
+/*
+ * Returns TRUE if the style for background-pattern-color is set in the scheme
+ */
+gboolean
+_gtk_source_style_scheme_get_background_pattern_color (GtkSourceStyleScheme *scheme,
+                                                       GdkRGBA              *color)
+{
+       GtkSourceStyle *style;
+
+       g_return_val_if_fail (GTK_SOURCE_IS_STYLE_SCHEME (scheme), FALSE);
+       g_return_val_if_fail (color != NULL, FALSE);
+
+       style = gtk_source_style_scheme_get_style (scheme, STYLE_BACKGROUND_PATTERN);
+
+       return get_color (style, FALSE, color);
+}
+
 static void
 update_cursor_colors (GtkWidget      *widget,
                      GtkSourceStyle *style_primary,
diff --git a/gtksourceview/gtksourcestylescheme.h b/gtksourceview/gtksourcestylescheme.h
index f7bbca0..8a37ee5 100644
--- a/gtksourceview/gtksourcestylescheme.h
+++ b/gtksourceview/gtksourcestylescheme.h
@@ -104,6 +104,11 @@ GtkSourceStyle          *_gtk_source_style_scheme_get_draw_spaces_style            
(GtkSou
 G_GNUC_INTERNAL
 gboolean                _gtk_source_style_scheme_get_current_line_color        (GtkSourceStyleScheme *scheme,
                                                                                 GdkRGBA              *color);
+
+G_GNUC_INTERNAL
+gboolean                _gtk_source_style_scheme_get_background_pattern_color  (GtkSourceStyleScheme *scheme,
+                                                                                GdkRGBA              *color);
+
 G_END_DECLS
 
 #endif  /* __GTK_SOURCE_STYLE_SCHEME_H__ */
diff --git a/gtksourceview/gtksourcetypes.h b/gtksourceview/gtksourcetypes.h
index 5c1af72..6d60a65 100644
--- a/gtksourceview/gtksourcetypes.h
+++ b/gtksourceview/gtksourcetypes.h
@@ -96,6 +96,19 @@ typedef enum
        GTK_SOURCE_COMPRESSION_TYPE_GZIP
 } GtkSourceCompressionType;
 
+/**
+ * GtkSourceBackgroundPatternType:
+ * @GTK_SOURCE_BACKGROUND_PATTERN_TYPE_NONE: no pattern
+ * @GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID: grid pattern
+ *
+ * Since: 3.16
+ */
+typedef enum
+{
+       GTK_SOURCE_BACKGROUND_PATTERN_TYPE_NONE,
+       GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID
+} GtkSourceBackgroundPatternType;
+
 G_END_DECLS
 
 #endif /* __GTK_SOURCE_TYPES_H__ */
diff --git a/gtksourceview/gtksourceview.c b/gtksourceview/gtksourceview.c
index 19c5c70..c743779 100644
--- a/gtksourceview/gtksourceview.c
+++ b/gtksourceview/gtksourceview.c
@@ -150,7 +150,8 @@ enum {
        PROP_SMART_HOME_END,
        PROP_HIGHLIGHT_CURRENT_LINE,
        PROP_INDENT_ON_TAB,
-       PROP_DRAW_SPACES
+       PROP_DRAW_SPACES,
+       PROP_BACKGROUND_PATTERN
 };
 
 struct _GtkSourceViewPrivate
@@ -181,6 +182,8 @@ struct _GtkSourceViewPrivate
        guint            tab_width;
        gint             indent_width;
        GtkSourceSmartHomeEndType smart_home_end;
+       GtkSourceBackgroundPatternType background_pattern;
+       GdkRGBA background_pattern_color;
 
        guint            tabs_set : 1;
        guint            show_line_numbers : 1;
@@ -192,6 +195,7 @@ struct _GtkSourceViewPrivate
        guint            show_right_margin  : 1;
        guint            style_scheme_applied : 1;
        guint            current_line_color_set : 1;
+       guint            background_pattern_color_set : 1;
 };
 
 typedef struct _MarkCategory MarkCategory;
@@ -539,6 +543,22 @@ gtk_source_view_class_init (GtkSourceViewClass *klass)
                                                             0,
                                                             G_PARAM_READWRITE));
 
+       /**
+        * GtkSourceView:background-pattern:
+        *
+        * Set to draw a specific background pattern on the view.
+        *
+        * Since: 3.16
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_BACKGROUND_PATTERN,
+                                        g_param_spec_enum ("background-pattern",
+                                                           "Background pattern",
+                                                           "Set to draw a specific background pattern on the 
view",
+                                                           GTK_SOURCE_TYPE_BACKGROUND_PATTERN_TYPE,
+                                                           0,
+                                                           G_PARAM_READWRITE));
+
        signals [UNDO] =
                g_signal_new ("undo",
                              G_TYPE_FROM_CLASS (klass),
@@ -942,6 +962,11 @@ gtk_source_view_set_property (GObject      *object,
                                                         g_value_get_flags (value));
                        break;
 
+               case PROP_BACKGROUND_PATTERN:
+                       gtk_source_view_set_background_pattern (view,
+                                                               g_value_get_enum (value));
+                       break;
+
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                        break;
@@ -1026,6 +1051,11 @@ gtk_source_view_get_property (GObject    *object,
                                           gtk_source_view_get_draw_spaces (view));
                        break;
 
+               case PROP_BACKGROUND_PATTERN:
+                       g_value_set_enum (value,
+                                         gtk_source_view_get_background_pattern (view));
+                       break;
+
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                        break;
@@ -2667,6 +2697,58 @@ gtk_source_view_draw_layer (GtkTextView *text_view,
                        }
                }
 
+               if (view->priv->background_pattern == GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID &&
+                   view->priv->background_pattern_color_set)
+               {
+                       GdkRectangle clip;
+                       GdkRectangle vis;
+                       gdouble x;
+                       gdouble y;
+                       PangoContext *context;
+                       PangoLayout *layout;
+                       int grid_width = 16;
+                       int grid_height = 16;
+
+                       context = gtk_widget_get_pango_context (GTK_WIDGET (view));
+                       layout = pango_layout_new (context);
+                       pango_layout_set_text (layout, "X", 1);
+                       pango_layout_get_pixel_size (layout, &grid_width, &grid_height);
+                       g_object_unref (layout);
+
+                       /* each character becomes 2 stacked boxes. */
+                       grid_height /= 2;
+
+                       cairo_save (cr);
+                       cairo_set_line_width (cr, 1.0);
+                       gdk_cairo_get_clip_rectangle (cr, &clip);
+                       gtk_text_view_get_visible_rect (text_view, &vis);
+
+                       gdk_cairo_set_source_rgba (cr, &view->priv->background_pattern_color);
+
+                       /*
+                       * The following constants come from gtktextview.c pixel cache
+                       * settings. Sadly, I didn't expose those in public API so we have to
+                       * just keep them in sync here. 64 for X, height/2 for Y.
+                       */
+                       x = (grid_width - (vis.x % grid_width)) - (64 / grid_width * grid_width) - grid_width 
+ 2;
+                       y = (grid_height - (vis.y % grid_height)) - (vis.height / 2 / grid_height * 
grid_height) - grid_height;
+
+                       for (; x <= clip.x + clip.width; x += grid_width)
+                       {
+                               cairo_move_to (cr, x + .5, clip.y - .5);
+                               cairo_line_to (cr, x + .5, clip.y + clip.height - .5);
+                       }
+
+                       for (; y <= clip.y + clip.height; y += grid_height)
+                       {
+                               cairo_move_to (cr, clip.x + .5, y - .5);
+                               cairo_line_to (cr, clip.x + clip.width + .5, y - .5);
+                       }
+
+                       cairo_stroke (cr);
+                       cairo_restore (cr);
+               }
+
                gtk_source_view_paint_marks_background (view, cr);
        }
 
@@ -4294,6 +4376,17 @@ gtk_source_view_style_updated (GtkWidget *widget)
 }
 
 static void
+update_background_pattern_color (GtkSourceView *view)
+{
+       if (view->priv->style_scheme)
+       {
+               view->priv->background_pattern_color_set =
+                       _gtk_source_style_scheme_get_background_pattern_color (view->priv->style_scheme,
+                                                                              
&view->priv->background_pattern_color);
+       }
+}
+
+static void
 update_current_line_color (GtkSourceView *view)
 {
        if (view->priv->style_scheme)
@@ -4445,6 +4538,7 @@ gtk_source_view_realize (GtkWidget *widget)
                view->priv->style_scheme_applied = TRUE;
        }
 
+       update_background_pattern_color (view);
        update_current_line_color (view);
        update_right_margin_colors (view);
        update_spaces_color (view);
@@ -4484,6 +4578,7 @@ gtk_source_view_update_style_scheme (GtkSourceView *view)
                if (gtk_widget_get_realized (GTK_WIDGET (view)))
                {
                        _gtk_source_style_scheme_apply (new_scheme, GTK_WIDGET (view));
+                       update_background_pattern_color (view);
                        update_current_line_color (view);
                        update_right_margin_colors (view);
                        update_spaces_color (view);
@@ -4646,3 +4741,48 @@ gtk_source_view_get_mark_attributes (GtkSourceView           *view,
        }
        return NULL;
 }
+
+/**
+ * gtk_source_view_set_background_pattern:
+ * @view: a #GtkSourceView.
+ * @background_pattern: #GtkSourceBackgroundPatternType specifing how
+ * the background pattern should be be displayed.
+ *
+ * Set if and how the background pattern should be displayed.
+ *
+ * Since: 3.16
+ **/
+void
+gtk_source_view_set_background_pattern (GtkSourceView                  *view,
+                                        GtkSourceBackgroundPatternType  background_pattern)
+{
+       g_return_if_fail (GTK_SOURCE_IS_VIEW (view));
+
+       if (view->priv->background_pattern == background_pattern)
+               return;
+
+       view->priv->background_pattern = background_pattern;
+
+       gtk_widget_queue_draw (GTK_WIDGET (view));
+
+       g_object_notify (G_OBJECT (view), "background-pattern");
+}
+
+/**
+ * gtk_source_view_get_background_pattern:
+ * @view: a #GtkSourceView
+ *
+ * Returns the #GtkSourceBackgroundPatternType specifying if and how
+ * the background pattern should be displayed for this @view.
+ *
+ * Returns: the #GtkSourceBackgroundPatternType.
+ *
+ * Since: 3.16
+ **/
+GtkSourceBackgroundPatternType
+gtk_source_view_get_background_pattern (GtkSourceView *view)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_VIEW (view), 0);
+
+       return view->priv->background_pattern;
+}
diff --git a/gtksourceview/gtksourceview.h b/gtksourceview/gtksourceview.h
index 459d743..69bf664 100644
--- a/gtksourceview/gtksourceview.h
+++ b/gtksourceview/gtksourceview.h
@@ -216,5 +216,10 @@ GtkSourceCompletion *
 GtkSourceGutter *gtk_source_view_get_gutter            (GtkSourceView     *view,
                                                          GtkTextWindowType  window_type);
 
+void            gtk_source_view_set_background_pattern (GtkSourceView                  *view,
+                                                         GtkSourceBackgroundPatternType  background_pattern);
+GtkSourceBackgroundPatternType
+                gtk_source_view_get_background_pattern (GtkSourceView   *view);
+
 G_END_DECLS
 #endif                         /* end of SOURCE_VIEW_H__ */
diff --git a/tests/test-widget.c b/tests/test-widget.c
index 18f9a9a..2b06090 100644
--- a/tests/test-widget.c
+++ b/tests/test-widget.c
@@ -56,6 +56,7 @@ struct _TestWidgetPrivate
        GtkSpinButton *indent_width_spinbutton;
        GtkLabel *cursor_position_info;
        GtkSourceStyleSchemeChooserButton *chooser_button;
+       GtkComboBoxText *background_pattern;
 };
 
 GType test_widget_get_type (void);
@@ -917,6 +918,26 @@ add_source_mark_attributes (GtkSourceView *view)
 }
 
 static void
+on_background_pattern_changed (GtkComboBox *combobox,
+                               TestWidget  *self)
+{
+       gchar *text;
+
+       text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combobox));
+
+       if (g_str_equal (text, "Grid"))
+       {
+               gtk_source_view_set_background_pattern (self->priv->view,
+                                                       GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID);
+       }
+       else
+       {
+               gtk_source_view_set_background_pattern (self->priv->view,
+                                                       GTK_SOURCE_BACKGROUND_PATTERN_TYPE_NONE);
+       }
+}
+
+static void
 test_widget_dispose (GObject *object)
 {
        TestWidget *self = TEST_WIDGET (object);
@@ -961,6 +982,7 @@ test_widget_class_init (TestWidgetClass *klass)
        gtk_widget_class_bind_template_child_private (widget_class, TestWidget, indent_width_spinbutton);
        gtk_widget_class_bind_template_child_private (widget_class, TestWidget, cursor_position_info);
        gtk_widget_class_bind_template_child_private (widget_class, TestWidget, chooser_button);
+       gtk_widget_class_bind_template_child_private (widget_class, TestWidget, background_pattern);
 }
 
 static void
@@ -1013,6 +1035,11 @@ test_widget_init (TestWidget *self)
                                "style-scheme",
                                G_BINDING_SYNC_CREATE);
 
+       g_signal_connect (self->priv->background_pattern,
+                         "changed",
+                         G_CALLBACK (on_background_pattern_changed),
+                         self);
+
        open_file (self, TOP_SRCDIR "/gtksourceview/gtksourcebuffer.c");
 }
 
diff --git a/tests/test-widget.ui b/tests/test-widget.ui
index a254064..0578526 100644
--- a/tests/test-widget.ui
+++ b/tests/test-widget.ui
@@ -281,6 +281,21 @@
                     <property name="top_attach">0</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkComboBoxText" id="background_pattern">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="active">0</property>
+                    <items>
+                      <item translatable="yes">None</item>
+                      <item translatable="yes">Grid</item>
+                    </items>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
               </object>
               <packing>
                 <property name="left_attach">0</property>


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