[gtk+] entry: Convert to gsk



commit 8de8525b447638df84577334ae9316f0f23947f4
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Sep 1 14:42:29 2017 -0400

    entry: Convert to gsk
    
    This introduces a new css node for block cursor styling.

 gtk/gtkentry.c |  130 +++++++++++++++++++++++++++++---------------------------
 1 files changed, 68 insertions(+), 62 deletions(-)
---
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 4f75ff7..f7735d2 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -125,6 +125,7 @@
  * ├── undershoot.left
  * ├── undershoot.right
  * ├── [selection]
+ * ├── [block-cursor]
  * ├── [progress[.pulse]]
  * ╰── [window.popup]
  * ]|
@@ -138,6 +139,9 @@
  *
  * When the entry has a selection, it adds a subnode with the name selection.
  *
+ * When the entry is in overwrite mode, it adds a subnode with the name block-cursor
+ * that determines how the block cursor is drawn.
+ *
  * When the entry shows progress, it adds a subnode with the name progress.
  * The node has the style class .pulse when the shown progress is pulsing.
  *
@@ -204,6 +208,7 @@ struct _GtkEntryPrivate
 
   GtkWidget     *progress_widget;
   GtkCssNode    *selection_node;
+  GtkCssNode    *block_cursor_node;
   GtkCssNode    *undershoot_node[2];
 
   int           text_x;
@@ -559,9 +564,9 @@ static void         gtk_entry_set_positions            (GtkEntry       *entry,
                                                        gint            current_pos,
                                                        gint            selection_bound);
 static void         gtk_entry_draw_text                (GtkEntry       *entry,
-                                                        cairo_t        *cr);
+                                                        GtkSnapshot    *snapshot);
 static void         gtk_entry_draw_cursor              (GtkEntry       *entry,
-                                                        cairo_t        *cr,
+                                                        GtkSnapshot    *snapshot,
                                                        CursorType      type);
 static PangoLayout *gtk_entry_ensure_layout            (GtkEntry       *entry,
                                                         gboolean        include_preedit);
@@ -2872,6 +2877,9 @@ update_node_state (GtkEntry *entry)
   if (priv->selection_node)
     gtk_css_node_set_state (priv->selection_node, state);
 
+  if (priv->block_cursor_node)
+    gtk_css_node_set_state (priv->block_cursor_node, state);
+
   gtk_css_node_set_state (priv->undershoot_node[0], state);
   gtk_css_node_set_state (priv->undershoot_node[1], state);
 }
@@ -3272,7 +3280,6 @@ gtk_entry_snapshot (GtkWidget   *widget,
   GtkEntry *entry = GTK_ENTRY (widget);
   GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
   int width, height;
-  cairo_t *cr;
   int i;
 
   gtk_widget_get_content_size (widget, &width, &height);
@@ -3282,27 +3289,17 @@ gtk_entry_snapshot (GtkWidget   *widget,
     gtk_widget_snapshot_child (widget, priv->progress_widget, snapshot);
 
   /* Draw text and cursor */
-  /* We add 1 to priv->text_width here simply because we might draw the
-   * cursor at the very right, one pixel after all the text. */
-  cr = gtk_snapshot_append_cairo (snapshot,
-                                  &GRAPHENE_RECT_INIT (priv->text_x,
-                                                       0,
-                                                       priv->text_width + 1,
-                                                       height),
-                                  "Entry Text");
 
   if (priv->dnd_position != -1)
-    gtk_entry_draw_cursor (GTK_ENTRY (widget), cr, CURSOR_DND);
+    gtk_entry_draw_cursor (GTK_ENTRY (widget), snapshot, CURSOR_DND);
 
-  gtk_entry_draw_text (GTK_ENTRY (widget), cr);
+  gtk_entry_draw_text (GTK_ENTRY (widget), snapshot);
 
   /* When no text is being displayed at all, don't show the cursor */
   if (gtk_entry_get_display_mode (entry) != DISPLAY_BLANK &&
       gtk_widget_has_focus (widget) &&
       priv->selection_bound == priv->current_pos && priv->cursor_visible)
-    gtk_entry_draw_cursor (GTK_ENTRY (widget), cr, CURSOR_STANDARD);
-
-  cairo_destroy (cr);
+    gtk_entry_draw_cursor (GTK_ENTRY (widget), snapshot, CURSOR_STANDARD);
 
   /* Draw icons */
   for (i = 0; i < MAX_ICONS; i++)
@@ -5162,6 +5159,29 @@ gtk_entry_toggle_overwrite (GtkEntry *entry)
   GtkEntryPrivate *priv = entry->priv;
 
   priv->overwrite_mode = !priv->overwrite_mode;
+
+  if (priv->overwrite_mode)
+    {
+      if (!priv->block_cursor_node)
+        {
+          GtkCssNode *widget_node = gtk_widget_get_css_node (GTK_WIDGET (entry));
+
+          priv->block_cursor_node = gtk_css_node_new ();
+          gtk_css_node_set_name (priv->block_cursor_node, I_("block-cursor"));
+          gtk_css_node_set_parent (priv->block_cursor_node, widget_node);
+          gtk_css_node_set_state (priv->block_cursor_node, gtk_css_node_get_state (widget_node));
+          g_object_unref (priv->block_cursor_node);
+        }
+    }
+  else
+    {
+      if (priv->block_cursor_node)
+        {
+          gtk_css_node_set_parent (priv->block_cursor_node, NULL);
+          priv->block_cursor_node = NULL;
+        }
+    }
+
   gtk_entry_pend_cursor_blink (entry);
   gtk_widget_queue_draw (GTK_WIDGET (entry));
 }
@@ -5653,9 +5673,11 @@ get_layout_position (GtkEntry *entry,
     *y = y_pos;
 }
 
+#define GRAPHENE_RECT_FROM_RECT(_r) (GRAPHENE_RECT_INIT ((_r)->x, (_r)->y, (_r)->width, (_r)->height))
+
 static void
-gtk_entry_draw_text (GtkEntry *entry,
-                     cairo_t  *cr)
+gtk_entry_draw_text (GtkEntry    *entry,
+                     GtkSnapshot *snapshot)
 {
   GtkEntryPrivate *priv = entry->priv;
   GtkWidget *widget = GTK_WIDGET (entry);
@@ -5673,14 +5695,12 @@ gtk_entry_draw_text (GtkEntry *entry,
   gtk_widget_get_content_size (widget, &width, &height);
   layout = gtk_entry_ensure_layout (entry, TRUE);
 
-  cairo_save (cr);
-
   gtk_entry_get_layout_offsets (entry, &x, &y);
 
   if (show_placeholder_text (entry))
     pango_layout_set_width (layout, PANGO_SCALE * priv->text_width);
 
-  gtk_render_layout (context, cr, x, y, layout);
+  gtk_snapshot_render_layout (snapshot, context, x, y, layout);
 
   if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
     {
@@ -5688,6 +5708,7 @@ gtk_entry_draw_text (GtkEntry *entry,
       gint start_index = g_utf8_offset_to_pointer (text, start_pos) - text;
       gint end_index = g_utf8_offset_to_pointer (text, end_pos) - text;
       cairo_region_t *clip;
+      cairo_rectangle_int_t clip_extents;
       gint range[2];
 
       range[0] = MIN (start_index, end_index);
@@ -5696,23 +5717,23 @@ gtk_entry_draw_text (GtkEntry *entry,
       gtk_style_context_save_to_node (context, priv->selection_node);
 
       clip = gdk_pango_layout_get_clip_region (layout, x, y, range, 1);
-      gdk_cairo_region (cr, clip);
-      cairo_clip (cr);
-      cairo_region_destroy (clip);
+      cairo_region_get_extents (clip, &clip_extents);
 
-      gtk_render_background (context, cr, 0, 0, width, height);
-      gtk_render_layout (context, cr, x, y, layout);
+      gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_FROM_RECT (&clip_extents), "Selected Text");
+      gtk_snapshot_render_background (snapshot, context, 0, 0, width, height);
+      gtk_snapshot_render_layout (snapshot, context, x, y, layout);
+      gtk_snapshot_pop (snapshot);
+
+      cairo_region_destroy (clip);
 
       gtk_style_context_restore (context);
     }
-
-  cairo_restore (cr);
 }
 
 static void
-gtk_entry_draw_cursor (GtkEntry  *entry,
-                       cairo_t   *cr,
-                      CursorType type)
+gtk_entry_draw_cursor (GtkEntry    *entry,
+                       GtkSnapshot *snapshot,
+                      CursorType   type)
 {
   GtkEntryPrivate *priv = entry->priv;
   GtkWidget *widget = GTK_WIDGET (entry);
@@ -5724,12 +5745,14 @@ gtk_entry_draw_cursor (GtkEntry  *entry,
   PangoLayout *layout;
   const char *text;
   gint x, y;
+  int width, height;
 
   context = gtk_widget_get_style_context (widget);
 
   layout = gtk_entry_ensure_layout (entry, TRUE);
   text = pango_layout_get_text (layout);
   gtk_entry_get_layout_offsets (entry, &x, &y);
+  gtk_widget_get_content_size (widget, &width, &height);
 
   if (type == CURSOR_DND)
     cursor_index = g_utf8_offset_to_pointer (text, priv->dnd_position) - text;
@@ -5743,44 +5766,27 @@ gtk_entry_draw_cursor (GtkEntry  *entry,
                                                       cursor_index, &cursor_rect, &block_at_line_end);
   if (!block)
     {
-      gtk_render_insertion_cursor (context, cr,
-                                   x, y,
-                                   layout, cursor_index, priv->resolved_dir);
+      gtk_snapshot_render_insertion_cursor (snapshot, context,
+                                            x, y,
+                                            layout, cursor_index, priv->resolved_dir);
     }
   else /* overwrite_mode */
     {
-      GdkRGBA cursor_color;
-      GdkRectangle rect;
+      graphene_rect_t bounds;
 
-      cairo_save (cr);
+      bounds.origin.x = PANGO_PIXELS (cursor_rect.x) + x;
+      bounds.origin.y = PANGO_PIXELS (cursor_rect.y) + y;
+      bounds.size.width = PANGO_PIXELS (cursor_rect.width);
+      bounds.size.height = PANGO_PIXELS (cursor_rect.height);
 
-      rect.x = PANGO_PIXELS (cursor_rect.x) + x;
-      rect.y = PANGO_PIXELS (cursor_rect.y) + y;
-      rect.width = PANGO_PIXELS (cursor_rect.width);
-      rect.height = PANGO_PIXELS (cursor_rect.height);
+      gtk_style_context_save_to_node (context, priv->block_cursor_node);
 
-      _gtk_style_context_get_cursor_color (context, &cursor_color, NULL);
-      gdk_cairo_set_source_rgba (cr, &cursor_color);
-      gdk_cairo_rectangle (cr, &rect);
-      cairo_fill (cr);
+      gtk_snapshot_push_clip (snapshot, &bounds, "Block Cursor");
+      gtk_snapshot_render_background (snapshot, context,  0, 0, width, height);
+      gtk_snapshot_render_layout (snapshot, context,  x, y, layout);
+      gtk_snapshot_pop (snapshot);
 
-      if (!block_at_line_end)
-        {
-          GdkRGBA color;
-
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-          gtk_style_context_get_background_color (context,
-                                                  &color);
-G_GNUC_END_IGNORE_DEPRECATIONS
-
-          gdk_cairo_rectangle (cr, &rect);
-          cairo_clip (cr);
-          cairo_move_to (cr, x, y);
-          gdk_cairo_set_source_rgba (cr, &color);
-          pango_cairo_show_layout (cr, layout);
-        }
-
-      cairo_restore (cr);
+      gtk_style_context_restore (context);
     }
 }
 


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