summaryrefslogtreecommitdiff
path: root/gtk/gtktextview.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2015-10-30 19:49:02 -0400
committerMatthias Clasen <mclasen@redhat.com>2015-10-30 19:49:02 -0400
commit844f60f1f22722b3c27a72e1c981cf499ff945c0 (patch)
treebbea3c74d69d49f86152c54826a8b0984616fa85 /gtk/gtktextview.c
parent2b998aaad7146b1ac300eefc39ed6fb851a763b8 (diff)
downloadgtk+-844f60f1f22722b3c27a72e1c981cf499ff945c0.tar.gz
text view: Convert to CSS nodes
Use subnodes for the border windows, and add children to the right subnodes.
Diffstat (limited to 'gtk/gtktextview.c')
-rw-r--r--gtk/gtktextview.c209
1 files changed, 166 insertions, 43 deletions
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 8f8d2ce7a2..4227d4d15b 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -643,6 +643,7 @@ struct _GtkTextWindow
GtkWidget *widget;
GdkWindow *window;
GdkWindow *bin_window;
+ GtkCssNode *css_node;
GtkRequisition requisition;
GdkRectangle allocation;
};
@@ -1648,7 +1649,7 @@ gtk_text_view_init (GtkTextView *text_view)
GtkWidget *widget = GTK_WIDGET (text_view);
GtkTargetList *target_list;
GtkTextViewPrivate *priv;
- GtkStyleContext *style_context;
+ GtkStyleContext *context;
text_view->priv = gtk_text_view_get_instance_private (text_view);
priv = text_view->priv;
@@ -1657,8 +1658,9 @@ gtk_text_view_init (GtkTextView *text_view)
priv->pixel_cache = _gtk_pixel_cache_new ();
- style_context = gtk_widget_get_style_context (GTK_WIDGET (text_view));
- _gtk_pixel_cache_set_style_context (priv->pixel_cache, style_context);
+ context = gtk_widget_get_style_context (GTK_WIDGET (text_view));
+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
+ _gtk_pixel_cache_set_style_context (priv->pixel_cache, context);
/* Set up default style */
priv->wrap_mode = GTK_WRAP_NONE;
@@ -4731,14 +4733,9 @@ text_window_set_padding (GtkTextView *text_view,
priv = text_view->priv;
- gtk_style_context_save (style_context);
- gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_VIEW);
-
state = gtk_widget_get_state_flags (GTK_WIDGET (text_view));
gtk_style_context_get_padding (style_context, state, &padding);
- gtk_style_context_restore (style_context);
-
if (padding.left != priv->left_padding ||
padding.right != priv->right_padding ||
padding.top != priv->top_padding ||
@@ -5789,8 +5786,7 @@ draw_text (cairo_t *cr,
gdk_cairo_get_clip_rectangle (cr, &bg_rect);
context = gtk_widget_get_style_context (widget);
- gtk_style_context_save (context);
- gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
+ gtk_style_context_save_to_node (context, text_view->priv->text_window->css_node);
gtk_render_background (context, cr,
bg_rect.x, bg_rect.y,
bg_rect.width, bg_rect.height);
@@ -5814,23 +5810,22 @@ draw_text (cairo_t *cr,
}
static void
-paint_border_window (GtkTextView *text_view,
- cairo_t *cr,
- GtkTextWindowType type,
- GtkStyleContext *context,
- const char *class)
+paint_border_window (GtkTextView *text_view,
+ cairo_t *cr,
+ GtkTextWindow *text_window,
+ GtkStyleContext *context)
{
GdkWindow *window;
- window = gtk_text_view_get_window (text_view, type);
+ if (text_window == NULL)
+ return;
- if (window != NULL &&
- gtk_cairo_should_draw_window (cr, window))
+ window = gtk_text_view_get_window (text_view, text_window->type);
+ if (gtk_cairo_should_draw_window (cr, window))
{
gint w, h;
- gtk_style_context_save (context);
- gtk_style_context_add_class (context, class);
+ gtk_style_context_save_to_node (context, text_window->css_node);
w = gdk_window_get_width (window);
h = gdk_window_get_height (window);
@@ -5860,12 +5855,10 @@ gtk_text_view_draw (GtkWidget *widget,
if (gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
{
- gtk_style_context_save (context);
gtk_render_background (context, cr,
0, 0,
gtk_widget_get_allocated_width (widget),
gtk_widget_get_allocated_height (widget));
- gtk_style_context_restore (context);
}
window = gtk_text_view_get_window (GTK_TEXT_VIEW (widget),
@@ -5898,10 +5891,10 @@ gtk_text_view_draw (GtkWidget *widget,
cairo_restore (cr);
}
- paint_border_window (GTK_TEXT_VIEW (widget), cr, GTK_TEXT_WINDOW_LEFT, context, GTK_STYLE_CLASS_LEFT);
- paint_border_window (GTK_TEXT_VIEW (widget), cr, GTK_TEXT_WINDOW_RIGHT, context, GTK_STYLE_CLASS_RIGHT);
- paint_border_window (GTK_TEXT_VIEW (widget), cr, GTK_TEXT_WINDOW_TOP, context, GTK_STYLE_CLASS_TOP);
- paint_border_window (GTK_TEXT_VIEW (widget), cr, GTK_TEXT_WINDOW_BOTTOM, context, GTK_STYLE_CLASS_BOTTOM);
+ paint_border_window (GTK_TEXT_VIEW (widget), cr, priv->left_window, context);
+ paint_border_window (GTK_TEXT_VIEW (widget), cr, priv->right_window, context);
+ paint_border_window (GTK_TEXT_VIEW (widget), cr, priv->top_window, context);
+ paint_border_window (GTK_TEXT_VIEW (widget), cr, priv->bottom_window, context);
/* Propagate exposes to all unanchored children.
* Anchored children are handled in gtk_text_view_paint().
@@ -7772,9 +7765,6 @@ gtk_text_view_set_attributes_from_style (GtkTextView *text_view,
context = gtk_widget_get_style_context (GTK_WIDGET (text_view));
state = gtk_widget_get_state_flags (GTK_WIDGET (text_view));
- gtk_style_context_save (context);
- gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
-
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gtk_style_context_get_background_color (context, state, &bg_color);
G_GNUC_END_IGNORE_DEPRECATIONS
@@ -7792,8 +7782,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS
pango_font_description_free (values->font);
gtk_style_context_get (context, state, "font", &values->font, NULL);
-
- gtk_style_context_restore (context);
}
static void
@@ -9694,6 +9682,62 @@ gtk_text_view_selection_bubble_popup_set (GtkTextView *text_view)
/* Child GdkWindows */
+static void
+node_style_changed_cb (GtkCssNode *node,
+ GtkCssStyle *old_style,
+ GtkCssStyle *new_style,
+ GtkWidget *widget)
+{
+ GtkBitmask *changes;
+ static GtkBitmask *affects_size = NULL;
+
+ if (G_UNLIKELY (affects_size == NULL))
+ affects_size = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_CLIP);
+
+ changes = _gtk_bitmask_new ();
+ changes = gtk_css_style_add_difference (changes, old_style, new_style);
+
+ if (_gtk_bitmask_intersects (changes, affects_size))
+ gtk_widget_queue_resize (widget);
+ else
+ gtk_widget_queue_draw (widget);
+
+ _gtk_bitmask_free (changes);
+}
+
+static void
+update_node_ordering (GtkWidget *widget)
+{
+ GtkTextViewPrivate *priv = GTK_TEXT_VIEW (widget)->priv;
+ GtkCssNode *widget_node, *sibling;
+
+ if (priv->text_window == NULL)
+ return;
+
+ widget_node = gtk_widget_get_css_node (widget);
+ sibling = priv->text_window->css_node;
+
+ if (priv->left_window)
+ {
+ gtk_css_node_insert_before (widget_node, priv->left_window->css_node, sibling);
+ sibling = priv->left_window->css_node;
+ }
+ if (priv->top_window)
+ {
+ gtk_css_node_insert_before (widget_node, priv->top_window->css_node, sibling);
+ }
+
+ sibling = priv->text_window->css_node;
+ if (priv->right_window)
+ {
+ gtk_css_node_insert_after (widget_node, priv->right_window->css_node, sibling);
+ sibling = priv->right_window->css_node;
+ }
+ if (priv->bottom_window)
+ {
+ gtk_css_node_insert_after (widget_node, priv->bottom_window->css_node, sibling);
+ }
+}
static GtkTextWindow*
text_window_new (GtkTextWindowType type,
@@ -9702,6 +9746,7 @@ text_window_new (GtkTextWindowType type,
gint height_request)
{
GtkTextWindow *win;
+ GtkCssNode *widget_node;
win = g_slice_new (GtkTextWindow);
@@ -9716,6 +9761,37 @@ text_window_new (GtkTextWindowType type,
win->allocation.x = 0;
win->allocation.y = 0;
+ widget_node = gtk_widget_get_css_node (widget);
+ win->css_node = gtk_css_node_new ();
+ gtk_css_node_set_parent (win->css_node, widget_node);
+ gtk_css_node_set_state (win->css_node, gtk_css_node_get_state (widget_node));
+ g_signal_connect_object (win->css_node, "style-changed", G_CALLBACK (node_style_changed_cb), widget, 0);
+ if (type == GTK_TEXT_WINDOW_TEXT)
+ {
+ gtk_css_node_set_name (win->css_node, I_("text"));
+ }
+ else
+ {
+ gtk_css_node_set_name (win->css_node, I_("border"));
+ switch (type)
+ {
+ case GTK_TEXT_WINDOW_LEFT:
+ gtk_css_node_add_class (win->css_node, g_quark_from_static_string (GTK_STYLE_CLASS_LEFT));
+ break;
+ case GTK_TEXT_WINDOW_RIGHT:
+ gtk_css_node_add_class (win->css_node, g_quark_from_static_string (GTK_STYLE_CLASS_RIGHT));
+ break;
+ case GTK_TEXT_WINDOW_TOP:
+ gtk_css_node_add_class (win->css_node, g_quark_from_static_string (GTK_STYLE_CLASS_TOP));
+ break;
+ case GTK_TEXT_WINDOW_BOTTOM:
+ gtk_css_node_add_class (win->css_node, g_quark_from_static_string (GTK_STYLE_CLASS_BOTTOM));
+ break;
+ default: /* no extra style class */ ;
+ }
+ }
+ g_object_unref (win->css_node);
+
return win;
}
@@ -9725,6 +9801,8 @@ text_window_free (GtkTextWindow *win)
if (win->window)
text_window_unrealize (win);
+ gtk_css_node_set_parent (win->css_node, NULL);
+
g_slice_free (GtkTextWindow, win);
}
@@ -9761,8 +9839,7 @@ gtk_text_view_queue_draw_region (GtkWidget *widget,
in normal scrolling cases anyway. */
_gtk_pixel_cache_invalidate (text_view->priv->pixel_cache, NULL);
- GTK_WIDGET_CLASS (gtk_text_view_parent_class)->queue_draw_region (widget,
- region);
+ GTK_WIDGET_CLASS (gtk_text_view_parent_class)->queue_draw_region (widget, region);
}
static void
@@ -10145,6 +10222,47 @@ gtk_text_view_get_window (GtkTextView *text_view,
return NULL;
}
+static GtkCssNode *
+gtk_text_view_get_css_node (GtkTextView *text_view,
+ GtkTextWindowType win)
+{
+ GtkTextViewPrivate *priv = text_view->priv;
+
+ switch (win)
+ {
+ case GTK_TEXT_WINDOW_WIDGET:
+ return gtk_widget_get_css_node (GTK_WIDGET (text_view));
+
+ case GTK_TEXT_WINDOW_TEXT:
+ return priv->text_window->css_node;
+
+ case GTK_TEXT_WINDOW_LEFT:
+ if (priv->left_window)
+ return priv->left_window->css_node;
+ break;
+
+ case GTK_TEXT_WINDOW_RIGHT:
+ if (priv->right_window)
+ return priv->right_window->css_node;
+ break;
+
+ case GTK_TEXT_WINDOW_TOP:
+ if (priv->top_window)
+ return priv->top_window->css_node;
+ break;
+
+ case GTK_TEXT_WINDOW_BOTTOM:
+ if (priv->bottom_window)
+ return priv->bottom_window->css_node;
+ break;
+
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
/**
* gtk_text_view_get_window_type:
* @text_view: a #GtkTextView
@@ -10485,12 +10603,11 @@ set_window_width (GtkTextView *text_view,
{
if (*winp == NULL)
{
- *winp = text_window_new (type,
- GTK_WIDGET (text_view),
- width, 0);
+ *winp = text_window_new (type, GTK_WIDGET (text_view), width, 0);
/* if the widget is already realized we need to realize the child manually */
if (gtk_widget_get_realized (GTK_WIDGET (text_view)))
text_window_realize (*winp, GTK_WIDGET (text_view));
+ update_node_ordering (GTK_WIDGET (text_view));
}
else
{
@@ -10524,13 +10641,12 @@ set_window_height (GtkTextView *text_view,
{
if (*winp == NULL)
{
- *winp = text_window_new (type,
- GTK_WIDGET (text_view),
- 0, height);
+ *winp = text_window_new (type, GTK_WIDGET (text_view), 0, height);
/* if the widget is already realized we need to realize the child manually */
if (gtk_widget_get_realized (GTK_WIDGET (text_view)))
text_window_realize (*winp, GTK_WIDGET (text_view));
+ update_node_ordering (GTK_WIDGET (text_view));
}
else
{
@@ -10738,12 +10854,19 @@ static void
add_child (GtkTextView *text_view,
GtkTextViewChild *vc)
{
- text_view->priv->children = g_slist_prepend (text_view->priv->children,
- vc);
+ GtkCssNode *parent;
+
+ text_view->priv->children = g_slist_prepend (text_view->priv->children, vc);
if (gtk_widget_get_realized (GTK_WIDGET (text_view)))
text_view_child_set_parent_window (text_view, vc);
-
+
+ parent = gtk_text_view_get_css_node (text_view, vc->type);
+ if (parent == NULL)
+ parent = gtk_widget_get_css_node (GTK_WIDGET (text_view));
+
+ gtk_css_node_set_parent (gtk_widget_get_css_node (vc->widget), parent);
+
gtk_widget_set_parent (vc->widget, GTK_WIDGET (text_view));
}
@@ -11151,7 +11274,7 @@ gtk_text_view_set_monospace (GtkTextView *text_view,
g_return_if_fail (GTK_IS_TEXT_VIEW (text_view));
- context = gtk_widget_get_style_context (GTK_WIDGET (text_view));
+ context = gtk_widget_get_style_context (GTK_WIDGET (text_view));
has_monospace = gtk_style_context_has_class (context, GTK_STYLE_CLASS_MONOSPACE);
if (has_monospace != monospace)