Compare commits
18 Commits
ci-meson-j
...
wip/cssnod
Author | SHA1 | Date | |
---|---|---|---|
|
1af58dc4ee | ||
|
cb1cf06744 | ||
|
c5d00ae119 | ||
|
15582ef9c1 | ||
|
0e57785af7 | ||
|
52f58f1637 | ||
|
cd87252130 | ||
|
85d86d61de | ||
|
0d01ceb415 | ||
|
aa005486de | ||
|
cdd26d0d01 | ||
|
f408c59869 | ||
|
4326e38b90 | ||
|
0f488064a2 | ||
|
e6c7e038c8 | ||
|
18bd973014 | ||
|
dae2d9ec27 | ||
|
c0c79eee03 |
@@ -399,6 +399,7 @@ gtk_private_h_sources = \
|
||||
gtkcssmatcherprivate.h \
|
||||
gtkcssnodeprivate.h \
|
||||
gtkcssnodedeclarationprivate.h \
|
||||
gtkcssnodeutilsprivate.h \
|
||||
gtkcssnumbervalueprivate.h \
|
||||
gtkcssparserprivate.h \
|
||||
gtkcsspathnodeprivate.h \
|
||||
@@ -633,6 +634,7 @@ gtk_base_c_sources = \
|
||||
gtkcssmatcher.c \
|
||||
gtkcssnode.c \
|
||||
gtkcssnodedeclaration.c \
|
||||
gtkcssnodeutils.c \
|
||||
gtkcssnumbervalue.c \
|
||||
gtkcssparser.c \
|
||||
gtkcsspathnode.c \
|
||||
|
185
gtk/gtkbox.c
185
gtk/gtkbox.c
@@ -78,6 +78,7 @@
|
||||
#include "gtkbox.h"
|
||||
#include "gtkboxprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkcssnodeutilsprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkorientable.h"
|
||||
#include "gtkorientableprivate.h"
|
||||
@@ -436,14 +437,12 @@ static gboolean
|
||||
gtk_box_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkAllocation alloc;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
gtk_widget_get_allocation (widget, &alloc);
|
||||
|
||||
gtk_render_background (context, cr, 0, 0, alloc.width, alloc.height);
|
||||
gtk_render_frame (context, cr, 0, 0, alloc.width, alloc.height);
|
||||
gtk_css_node_draw (gtk_widget_get_css_node (widget),
|
||||
cr,
|
||||
gtk_widget_get_allocated_width (widget),
|
||||
gtk_widget_get_allocated_height (widget),
|
||||
NULL,
|
||||
widget);
|
||||
|
||||
return GTK_WIDGET_CLASS (gtk_box_parent_class)->draw (widget, cr);
|
||||
}
|
||||
@@ -473,9 +472,13 @@ count_expand_children (GtkBox *box,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
gtk_box_size_allocate_no_center (GtkCssNode *cssnode,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (data);
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
GtkBoxChild *child;
|
||||
@@ -485,12 +488,12 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
|
||||
GtkTextDirection direction;
|
||||
GtkAllocation child_allocation;
|
||||
GtkAllocation child_clip;
|
||||
GtkRequestedSize *sizes;
|
||||
gint child_minimum_baseline, child_natural_baseline;
|
||||
gint minimum_above, natural_above;
|
||||
gint minimum_below, natural_below;
|
||||
gboolean have_baseline;
|
||||
gint baseline;
|
||||
|
||||
GtkPackType packing;
|
||||
|
||||
@@ -500,8 +503,7 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
gint x = 0, y = 0, i;
|
||||
gint child_size;
|
||||
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
*out_clip = *allocation;
|
||||
|
||||
count_expand_children (box, &nvis_children, &nexpand_children);
|
||||
|
||||
@@ -680,7 +682,6 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (baseline == -1 && have_baseline)
|
||||
{
|
||||
gint height = MAX (1, allocation->height);
|
||||
@@ -799,18 +800,21 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
gtk_widget_size_allocate_with_baseline (child->widget, &child_allocation, baseline);
|
||||
|
||||
gtk_widget_get_clip (child->widget, &child_clip);
|
||||
gdk_rectangle_union (out_clip, out_clip, &child_clip);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
_gtk_widget_set_simple_clip (widget, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
gtk_box_size_allocate_with_center (GtkCssNode *cssnode,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (data);
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
GtkBoxPrivate *priv = box->priv;
|
||||
GtkBoxChild *child;
|
||||
@@ -818,14 +822,13 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
gint nvis[2];
|
||||
gint nexp[2];
|
||||
GtkTextDirection direction;
|
||||
GtkAllocation child_allocation;
|
||||
GtkAllocation child_allocation, child_clip;
|
||||
GtkRequestedSize *sizes[2];
|
||||
GtkRequestedSize center_req;
|
||||
gint child_minimum_baseline, child_natural_baseline;
|
||||
gint minimum_above, natural_above;
|
||||
gint minimum_below, natural_below;
|
||||
gboolean have_baseline;
|
||||
gint baseline;
|
||||
gint idx[2];
|
||||
gint center_pos;
|
||||
gint center_size;
|
||||
@@ -839,8 +842,6 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
gint x = 0, y = 0, i;
|
||||
gint child_size;
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
nvis[0] = nvis[1] = 0;
|
||||
nexp[0] = nexp[1] = 0;
|
||||
for (children = priv->children; children; children = children->next)
|
||||
@@ -872,6 +873,8 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
min_size[0] = nat_size[0] = nvis[0] * priv->spacing;
|
||||
min_size[1] = nat_size[1] = nvis[1] * priv->spacing;
|
||||
|
||||
*out_clip = *allocation;
|
||||
|
||||
/* Retrieve desired size for visible children. */
|
||||
idx[0] = idx[1] = 0;
|
||||
for (children = priv->children; children; children = children->next)
|
||||
@@ -1026,7 +1029,6 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
if (baseline == -1 && have_baseline)
|
||||
{
|
||||
gint height = MAX (1, allocation->height);
|
||||
@@ -1140,6 +1142,8 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
gtk_widget_size_allocate_with_baseline (child->widget, &child_allocation, baseline);
|
||||
gtk_widget_get_clip (child->widget, &child_clip);
|
||||
gdk_rectangle_union (out_clip, out_clip, &child_clip);
|
||||
|
||||
i++;
|
||||
}
|
||||
@@ -1171,9 +1175,10 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
child_allocation.y = center_pos;
|
||||
child_allocation.height = center_size;
|
||||
}
|
||||
gtk_widget_size_allocate_with_baseline (priv->center->widget, &child_allocation, baseline);
|
||||
|
||||
_gtk_widget_set_simple_clip (widget, NULL);
|
||||
gtk_widget_size_allocate_with_baseline (priv->center->widget, &child_allocation, baseline);
|
||||
gtk_widget_get_clip (priv->center->widget, &child_clip);
|
||||
gdk_rectangle_union (out_clip, out_clip, &child_clip);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1181,12 +1186,20 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
GtkAllocation clip;
|
||||
|
||||
if (box->priv->center &&
|
||||
gtk_widget_get_visible (box->priv->center->widget))
|
||||
gtk_box_size_allocate_with_center (widget, allocation);
|
||||
else
|
||||
gtk_box_size_allocate_no_center (widget, allocation);
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
gtk_css_node_allocate (gtk_widget_get_css_node (widget),
|
||||
allocation,
|
||||
gtk_widget_get_allocated_baseline (widget),
|
||||
&clip,
|
||||
box->priv->center && gtk_widget_get_visible (box->priv->center->widget)
|
||||
? gtk_box_size_allocate_with_center
|
||||
: gtk_box_size_allocate_no_center,
|
||||
box);
|
||||
|
||||
gtk_widget_set_clip (widget, &clip);
|
||||
}
|
||||
|
||||
static GType
|
||||
@@ -1666,22 +1679,6 @@ gtk_box_get_size (GtkWidget *widget,
|
||||
*natural_baseline = nat_baseline;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
|
||||
gint avail_size,
|
||||
@@ -1965,19 +1962,74 @@ gtk_box_compute_size_for_orientation (GtkBox *box,
|
||||
*natural_size = required_natural;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_size (GtkCssNode *cssnode,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget = data;
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
GtkBoxPrivate *priv = box->priv;
|
||||
|
||||
if (for_size < 0)
|
||||
{
|
||||
gtk_box_get_size (widget, orientation, minimum, natural, minimum_baseline, natural_baseline);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (priv->orientation == orientation)
|
||||
gtk_box_compute_size_for_orientation (box, for_size, minimum, natural);
|
||||
else
|
||||
gtk_box_compute_size_for_opposing_orientation (box, for_size, minimum, natural, minimum_baseline, natural_baseline);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_css_node_get_preferred_size (gtk_widget_get_css_node (widget),
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
minimum_size, natural_size,
|
||||
NULL, NULL,
|
||||
gtk_box_get_preferred_size,
|
||||
widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
{
|
||||
gtk_css_node_get_preferred_size (gtk_widget_get_css_node (widget),
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
minimum_size, natural_size,
|
||||
NULL, NULL,
|
||||
gtk_box_get_preferred_size,
|
||||
widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint height,
|
||||
gint *minimum_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
|
||||
if (private->orientation == GTK_ORIENTATION_VERTICAL)
|
||||
gtk_box_compute_size_for_opposing_orientation (box, height, minimum_width, natural_width, NULL, NULL);
|
||||
else
|
||||
gtk_box_compute_size_for_orientation (box, height, minimum_width, natural_width);
|
||||
gtk_css_node_get_preferred_size (gtk_widget_get_css_node (widget),
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
height,
|
||||
minimum_width, natural_width,
|
||||
NULL, NULL,
|
||||
gtk_box_get_preferred_size,
|
||||
widget);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1988,24 +2040,13 @@ gtk_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
|
||||
if (width < 0)
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_height, natural_height, minimum_baseline, natural_baseline);
|
||||
else
|
||||
{
|
||||
if (private->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
gtk_box_compute_size_for_opposing_orientation (box, width, minimum_height, natural_height, minimum_baseline, natural_baseline);
|
||||
else
|
||||
{
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
gtk_box_compute_size_for_orientation (box, width, minimum_height, natural_height);
|
||||
}
|
||||
}
|
||||
gtk_css_node_get_preferred_size (gtk_widget_get_css_node (widget),
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
width,
|
||||
minimum_height, natural_height,
|
||||
minimum_baseline, natural_baseline,
|
||||
gtk_box_get_preferred_size,
|
||||
widget);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -306,7 +306,7 @@ static gboolean
|
||||
gtk_css_matcher_node_has_class (const GtkCssMatcher *matcher,
|
||||
GQuark class_name)
|
||||
{
|
||||
return gtk_css_node_has_class (matcher->node.node, class_name);
|
||||
return gtk_css_node_has_qclass (matcher->node.node, class_name);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@@ -579,6 +579,12 @@ gtk_css_node_init (GtkCssNode *cssnode)
|
||||
cssnode->visible = TRUE;
|
||||
}
|
||||
|
||||
GtkCssNode *
|
||||
gtk_css_node_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_CSS_NODE, NULL);
|
||||
}
|
||||
|
||||
static GdkFrameClock *
|
||||
gtk_css_node_get_frame_clock_or_null (GtkCssNode *cssnode)
|
||||
{
|
||||
@@ -944,6 +950,22 @@ gtk_css_node_get_state (GtkCssNode *cssnode)
|
||||
return gtk_css_node_declaration_get_state (cssnode->decl);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_node_add_state (GtkCssNode *cssnode,
|
||||
GtkStateFlags state_flags)
|
||||
{
|
||||
gtk_css_node_set_state (cssnode,
|
||||
gtk_css_node_get_state (cssnode) | state_flags);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_node_remove_state (GtkCssNode *cssnode,
|
||||
GtkStateFlags state_flags)
|
||||
{
|
||||
gtk_css_node_set_state (cssnode,
|
||||
gtk_css_node_get_state (cssnode) & ~state_flags);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_node_set_junction_sides (GtkCssNode *cssnode,
|
||||
GtkJunctionSides junction_sides)
|
||||
@@ -966,7 +988,7 @@ gtk_css_node_clear_classes (GtkCssNode *cssnode)
|
||||
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
gtk_css_node_remove_class (cssnode, GPOINTER_TO_UINT (l->data));
|
||||
gtk_css_node_remove_class (cssnode, l->data);
|
||||
}
|
||||
|
||||
g_list_free (list);
|
||||
@@ -986,7 +1008,7 @@ gtk_css_node_set_classes (GtkCssNode *cssnode,
|
||||
{
|
||||
for (i = 0; classes[i] != NULL; i++)
|
||||
{
|
||||
gtk_css_node_add_class (cssnode, g_quark_from_string (classes[i]));
|
||||
gtk_css_node_add_class (cssnode, classes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1016,9 +1038,13 @@ gtk_css_node_get_classes (GtkCssNode *cssnode)
|
||||
|
||||
void
|
||||
gtk_css_node_add_class (GtkCssNode *cssnode,
|
||||
GQuark style_class)
|
||||
const char *style_class)
|
||||
{
|
||||
if (gtk_css_node_declaration_add_class (&cssnode->decl, style_class))
|
||||
GQuark class_quark;
|
||||
|
||||
class_quark = g_quark_from_string (style_class);
|
||||
|
||||
if (gtk_css_node_declaration_add_class (&cssnode->decl, class_quark))
|
||||
{
|
||||
gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_CLASS);
|
||||
g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_CLASSES]);
|
||||
@@ -1027,9 +1053,15 @@ gtk_css_node_add_class (GtkCssNode *cssnode,
|
||||
|
||||
void
|
||||
gtk_css_node_remove_class (GtkCssNode *cssnode,
|
||||
GQuark style_class)
|
||||
const char *style_class)
|
||||
{
|
||||
if (gtk_css_node_declaration_remove_class (&cssnode->decl, style_class))
|
||||
GQuark class_quark;
|
||||
|
||||
class_quark = g_quark_try_string (style_class);
|
||||
if (class_quark == 0)
|
||||
return;
|
||||
|
||||
if (gtk_css_node_declaration_remove_class (&cssnode->decl, class_quark))
|
||||
{
|
||||
gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_CLASS);
|
||||
g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_CLASSES]);
|
||||
@@ -1038,15 +1070,43 @@ gtk_css_node_remove_class (GtkCssNode *cssnode,
|
||||
|
||||
gboolean
|
||||
gtk_css_node_has_class (GtkCssNode *cssnode,
|
||||
GQuark style_class)
|
||||
const char *style_class)
|
||||
{
|
||||
GQuark class_quark;
|
||||
|
||||
class_quark = g_quark_try_string (style_class);
|
||||
if (class_quark == 0)
|
||||
return FALSE;
|
||||
|
||||
return gtk_css_node_has_qclass (cssnode, class_quark);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_node_has_qclass (GtkCssNode *cssnode,
|
||||
GQuark style_class)
|
||||
{
|
||||
return gtk_css_node_declaration_has_class (cssnode->decl, style_class);
|
||||
}
|
||||
|
||||
static void
|
||||
quarks_to_strings (GList *list)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
l->data = (char *) g_quark_to_string (GPOINTER_TO_UINT (l->data));
|
||||
}
|
||||
}
|
||||
|
||||
GList *
|
||||
gtk_css_node_list_classes (GtkCssNode *cssnode)
|
||||
{
|
||||
return gtk_css_node_declaration_list_classes (cssnode->decl);
|
||||
GList *list = gtk_css_node_declaration_list_classes (cssnode->decl);
|
||||
|
||||
quarks_to_strings (list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -95,6 +95,8 @@ struct _GtkCssNodeClass
|
||||
|
||||
GType gtk_css_node_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkCssNode * gtk_css_node_new (void);
|
||||
|
||||
void gtk_css_node_set_parent (GtkCssNode *cssnode,
|
||||
GtkCssNode *parent);
|
||||
void gtk_css_node_set_after (GtkCssNode *cssnode,
|
||||
@@ -120,6 +122,10 @@ const char * gtk_css_node_get_id (GtkCssNode *
|
||||
void gtk_css_node_set_state (GtkCssNode *cssnode,
|
||||
GtkStateFlags state_flags);
|
||||
GtkStateFlags gtk_css_node_get_state (GtkCssNode *cssnode);
|
||||
void gtk_css_node_add_state (GtkCssNode *cssnode,
|
||||
GtkStateFlags state_flags);
|
||||
void gtk_css_node_remove_state (GtkCssNode *cssnode,
|
||||
GtkStateFlags state_flags);
|
||||
void gtk_css_node_set_junction_sides (GtkCssNode *cssnode,
|
||||
GtkJunctionSides junction_sides);
|
||||
GtkJunctionSides gtk_css_node_get_junction_sides (GtkCssNode *cssnode);
|
||||
@@ -127,10 +133,12 @@ void gtk_css_node_set_classes (GtkCssNode *
|
||||
const char **classes);
|
||||
char ** gtk_css_node_get_classes (GtkCssNode *cssnode);
|
||||
void gtk_css_node_add_class (GtkCssNode *cssnode,
|
||||
GQuark style_class);
|
||||
const char *style_class);
|
||||
void gtk_css_node_remove_class (GtkCssNode *cssnode,
|
||||
GQuark style_class);
|
||||
const char *style_class);
|
||||
gboolean gtk_css_node_has_class (GtkCssNode *cssnode,
|
||||
const char *style_class);
|
||||
gboolean gtk_css_node_has_qclass (GtkCssNode *cssnode,
|
||||
GQuark style_class);
|
||||
GList * gtk_css_node_list_classes (GtkCssNode *cssnode);
|
||||
void gtk_css_node_add_region (GtkCssNode *cssnode,
|
||||
|
300
gtk/gtkcssnodeutils.c
Normal file
300
gtk/gtkcssnodeutils.c
Normal file
@@ -0,0 +1,300 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2014 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcssnodeutilsprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssstyleprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkrenderbackgroundprivate.h"
|
||||
#include "gtkrenderborderprivate.h"
|
||||
|
||||
void
|
||||
gtk_css_node_style_changed_for_widget (GtkCssNode *node,
|
||||
GtkCssStyle *old_style,
|
||||
GtkCssStyle *new_style,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
static GtkBitmask *affects_size = NULL;
|
||||
GtkBitmask *changes;
|
||||
|
||||
changes = gtk_css_style_get_difference (old_style, new_style);
|
||||
|
||||
if (G_UNLIKELY (affects_size == NULL))
|
||||
affects_size = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_CLIP);
|
||||
|
||||
if (_gtk_bitmask_intersects (changes, affects_size))
|
||||
gtk_widget_queue_resize (widget);
|
||||
else
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
_gtk_bitmask_free (changes);
|
||||
}
|
||||
|
||||
static gint
|
||||
get_number (GtkCssStyle *style,
|
||||
guint property)
|
||||
{
|
||||
double d = _gtk_css_number_value_get (gtk_css_style_get_value (style, property), 100);
|
||||
|
||||
if (d < 1)
|
||||
return ceil (d);
|
||||
else
|
||||
return floor (d);
|
||||
}
|
||||
|
||||
static void
|
||||
get_box_margin (GtkCssStyle *style,
|
||||
GtkBorder *margin)
|
||||
{
|
||||
margin->top = get_number (style, GTK_CSS_PROPERTY_MARGIN_TOP);
|
||||
margin->left = get_number (style, GTK_CSS_PROPERTY_MARGIN_LEFT);
|
||||
margin->bottom = get_number (style, GTK_CSS_PROPERTY_MARGIN_BOTTOM);
|
||||
margin->right = get_number (style, GTK_CSS_PROPERTY_MARGIN_RIGHT);
|
||||
}
|
||||
|
||||
static void
|
||||
get_box_border (GtkCssStyle *style,
|
||||
GtkBorder *border)
|
||||
{
|
||||
border->top = get_number (style, GTK_CSS_PROPERTY_BORDER_TOP_WIDTH);
|
||||
border->left = get_number (style, GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH);
|
||||
border->bottom = get_number (style, GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH);
|
||||
border->right = get_number (style, GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH);
|
||||
}
|
||||
|
||||
static void
|
||||
get_box_padding (GtkCssStyle *style,
|
||||
GtkBorder *border)
|
||||
{
|
||||
border->top = get_number (style, GTK_CSS_PROPERTY_PADDING_TOP);
|
||||
border->left = get_number (style, GTK_CSS_PROPERTY_PADDING_LEFT);
|
||||
border->bottom = get_number (style, GTK_CSS_PROPERTY_PADDING_BOTTOM);
|
||||
border->right = get_number (style, GTK_CSS_PROPERTY_PADDING_RIGHT);
|
||||
}
|
||||
|
||||
static void
|
||||
get_content_size_func_default (GtkCssNode *cssnode,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer unused)
|
||||
{
|
||||
*minimum = 0;
|
||||
*natural = 0;
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = 0;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = 0;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_node_get_preferred_size (GtkCssNode *cssnode,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
GtkCssNodeSizeFunc get_content_size_func,
|
||||
gpointer get_content_size_data)
|
||||
{
|
||||
GtkCssStyle *style;
|
||||
GtkBorder margin, border, padding;
|
||||
int min_size, extra_size, extra_opposite, extra_baseline;
|
||||
|
||||
if (!get_content_size_func)
|
||||
get_content_size_func = get_content_size_func_default;
|
||||
style = gtk_css_node_get_style (cssnode);
|
||||
get_box_margin (style, &margin);
|
||||
get_box_border (style, &border);
|
||||
get_box_padding (style, &padding);
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
extra_size = margin.left + margin.right + border.left + border.right + padding.left + padding.right;
|
||||
extra_opposite = margin.top + margin.bottom + border.top + border.bottom + padding.top + padding.bottom;
|
||||
extra_baseline = margin.left + border.left + padding.left;
|
||||
min_size = get_number (style, GTK_CSS_PROPERTY_MIN_WIDTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
extra_size = margin.top + margin.bottom + border.top + border.bottom + padding.top + padding.bottom;
|
||||
extra_opposite = margin.left + margin.right + border.left + border.right + padding.left + padding.right;
|
||||
extra_baseline = margin.top + border.top + padding.top;
|
||||
min_size = get_number (style, GTK_CSS_PROPERTY_MIN_HEIGHT);
|
||||
}
|
||||
|
||||
if (for_size > -1)
|
||||
for_size -= extra_opposite;
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = -1;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = -1;
|
||||
|
||||
get_content_size_func (cssnode,
|
||||
orientation,
|
||||
for_size,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline,
|
||||
get_content_size_data);
|
||||
|
||||
g_warn_if_fail (*minimum <= *natural);
|
||||
|
||||
*minimum = MAX (min_size, *minimum);
|
||||
*natural = MAX (min_size, *natural);
|
||||
|
||||
*minimum += extra_size;
|
||||
*natural += extra_size;
|
||||
|
||||
if (minimum_baseline && *minimum_baseline > -1)
|
||||
*minimum_baseline += extra_baseline;
|
||||
if (natural_baseline && *natural_baseline > -1)
|
||||
*natural_baseline += extra_baseline;
|
||||
}
|
||||
|
||||
static void
|
||||
allocate_func_default (GtkCssNode *cssnode,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip,
|
||||
gpointer unused)
|
||||
{
|
||||
*out_clip = *allocation;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_node_allocate (GtkCssNode *cssnode,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip,
|
||||
GtkCssNodeAllocateFunc allocate_func,
|
||||
gpointer allocate_data)
|
||||
{
|
||||
GtkAllocation content_allocation, clip;
|
||||
GtkBorder margin, border, padding, shadow, extents;
|
||||
GtkCssStyle *style;
|
||||
|
||||
if (out_clip == NULL)
|
||||
out_clip = &clip;
|
||||
if (!allocate_func)
|
||||
allocate_func = allocate_func_default;
|
||||
style = gtk_css_node_get_style (cssnode);
|
||||
get_box_margin (style, &margin);
|
||||
get_box_border (style, &border);
|
||||
get_box_padding (style, &padding);
|
||||
extents.top = margin.top + border.top + padding.top;
|
||||
extents.right = margin.right + border.right + padding.right;
|
||||
extents.bottom = margin.bottom + border.bottom + padding.bottom;
|
||||
extents.left = margin.left + border.left + padding.left;
|
||||
|
||||
content_allocation.x = allocation->x + extents.left;
|
||||
content_allocation.y = allocation->y + extents.top;
|
||||
content_allocation.width = allocation->width - extents.left - extents.right;
|
||||
content_allocation.height = allocation->height - extents.top - extents.bottom;
|
||||
if (baseline >= 0)
|
||||
baseline += extents.top;
|
||||
|
||||
g_assert (content_allocation.width >= 0);
|
||||
g_assert (content_allocation.height >= 0);
|
||||
|
||||
allocate_func (cssnode, &content_allocation, baseline, out_clip, allocate_data);
|
||||
|
||||
_gtk_css_shadows_value_get_extents (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BOX_SHADOW), &shadow);
|
||||
out_clip->x -= extents.left + shadow.left - margin.left;
|
||||
out_clip->y -= extents.top + shadow.top - margin.top;
|
||||
out_clip->width += extents.left + extents.right + shadow.left + shadow.right - margin.left - margin.right;
|
||||
out_clip->height += extents.top + extents.bottom + shadow.top + shadow.bottom - margin.top - margin.bottom;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
draw_contents_func_default (GtkCssNode *cssnode,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer unused)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_node_draw (GtkCssNode *cssnode,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
GtkCssNodeDrawFunc draw_contents_func,
|
||||
gpointer draw_contents_data)
|
||||
{
|
||||
GtkBorder margin, border, padding;
|
||||
gboolean draw_focus;
|
||||
GtkCssStyle *style;
|
||||
int contents_width, contents_height;
|
||||
|
||||
if (draw_contents_func == NULL)
|
||||
draw_contents_func = draw_contents_func_default;
|
||||
style = gtk_css_node_get_style (cssnode);
|
||||
get_box_margin (style, &margin);
|
||||
get_box_border (style, &border);
|
||||
get_box_padding (style, &padding);
|
||||
|
||||
gtk_css_style_render_background (style,
|
||||
cr,
|
||||
margin.left,
|
||||
margin.top,
|
||||
width - margin.left - margin.right,
|
||||
height - margin.top - margin.bottom,
|
||||
gtk_css_node_get_junction_sides (cssnode));
|
||||
gtk_css_style_render_border (style,
|
||||
cr,
|
||||
margin.left,
|
||||
margin.top,
|
||||
width - margin.left - margin.right,
|
||||
height - margin.top - margin.bottom,
|
||||
0,
|
||||
gtk_css_node_get_junction_sides (cssnode));
|
||||
|
||||
cairo_translate (cr,
|
||||
margin.left + border.left + padding.left,
|
||||
margin.top + border.top + padding.top);
|
||||
contents_width = width - margin.left - margin.right - border.left - border.right - padding.left - padding.right;
|
||||
contents_height = height - margin.top - margin.bottom - border.top - border.bottom - padding.top - padding.bottom;
|
||||
|
||||
draw_focus = draw_contents_func (cssnode, cr, contents_width, contents_height, draw_contents_data);
|
||||
|
||||
cairo_translate (cr,
|
||||
- (margin.left + border.left + padding.left),
|
||||
- (margin.top + border.top + padding.top));
|
||||
|
||||
if (draw_focus)
|
||||
gtk_css_style_render_outline (style,
|
||||
cr,
|
||||
margin.left,
|
||||
margin.top,
|
||||
width - margin.left - margin.right,
|
||||
height - margin.top - margin.bottom);
|
||||
}
|
||||
|
||||
|
75
gtk/gtkcssnodeutilsprivate.h
Normal file
75
gtk/gtkcssnodeutilsprivate.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2014 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_NODE_UTILS_PRIVATE_H__
|
||||
#define __GTK_CSS_NODE_UTILS_PRIVATE_H__
|
||||
|
||||
#include <gtk/gtkwidget.h>
|
||||
#include "gtk/gtkcssnodeprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gtk_css_node_style_changed_for_widget (GtkCssNode *node,
|
||||
GtkCssStyle *old_style,
|
||||
GtkCssStyle *new_style,
|
||||
GtkWidget *widget);
|
||||
|
||||
typedef void (* GtkCssNodeSizeFunc) (GtkCssNode *cssnode,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer get_content_size_data);
|
||||
void gtk_css_node_get_preferred_size (GtkCssNode *cssnode,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
GtkCssNodeSizeFunc get_content_size_func,
|
||||
gpointer get_content_size_data);
|
||||
|
||||
typedef void (* GtkCssNodeAllocateFunc) (GtkCssNode *cssnode,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip,
|
||||
gpointer allocate_data);
|
||||
void gtk_css_node_allocate (GtkCssNode *cssnode,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip,
|
||||
GtkCssNodeAllocateFunc allocate_func,
|
||||
gpointer allocate_data);
|
||||
|
||||
typedef gboolean (* GtkCssNodeDrawFunc) (GtkCssNode *cssnode,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data);
|
||||
void gtk_css_node_draw (GtkCssNode *cssnode,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
GtkCssNodeDrawFunc draw_contents_func,
|
||||
gpointer draw_contents_data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_NODE_UTILS_PRIVATE_H__ */
|
@@ -804,6 +804,15 @@ border_image_width_parse (GtkCssStyleProperty *property,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
minmax_parse (GtkCssStyleProperty *property,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
return _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH
|
||||
| GTK_CSS_POSITIVE_ONLY);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
transition_property_parse_one (GtkCssParser *parser)
|
||||
{
|
||||
@@ -1529,6 +1538,25 @@ _gtk_css_style_property_init_properties (void)
|
||||
NULL,
|
||||
_gtk_css_transform_value_new_none ());
|
||||
|
||||
gtk_css_style_property_register ("min-width",
|
||||
GTK_CSS_PROPERTY_MIN_WIDTH,
|
||||
G_TYPE_NONE,
|
||||
GTK_STYLE_PROPERTY_ANIMATED,
|
||||
GTK_CSS_AFFECTS_SIZE,
|
||||
minmax_parse,
|
||||
NULL,
|
||||
NULL,
|
||||
_gtk_css_number_value_new (0, GTK_CSS_PX));
|
||||
gtk_css_style_property_register ("min-height",
|
||||
GTK_CSS_PROPERTY_MIN_HEIGHT,
|
||||
G_TYPE_NONE,
|
||||
GTK_STYLE_PROPERTY_ANIMATED,
|
||||
GTK_CSS_AFFECTS_SIZE,
|
||||
minmax_parse,
|
||||
NULL,
|
||||
NULL,
|
||||
_gtk_css_number_value_new (0, GTK_CSS_PX));
|
||||
|
||||
gtk_css_style_property_register ("transition-property",
|
||||
GTK_CSS_PROPERTY_TRANSITION_PROPERTY,
|
||||
G_TYPE_NONE,
|
||||
|
@@ -164,6 +164,8 @@ enum { /*< skip >*/
|
||||
GTK_CSS_PROPERTY_ICON_SHADOW,
|
||||
GTK_CSS_PROPERTY_ICON_STYLE,
|
||||
GTK_CSS_PROPERTY_ICON_TRANSFORM,
|
||||
GTK_CSS_PROPERTY_MIN_WIDTH,
|
||||
GTK_CSS_PROPERTY_MIN_HEIGHT,
|
||||
GTK_CSS_PROPERTY_TRANSITION_PROPERTY,
|
||||
GTK_CSS_PROPERTY_TRANSITION_DURATION,
|
||||
GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION,
|
||||
|
321
gtk/gtkentry.c
321
gtk/gtkentry.c
@@ -34,6 +34,7 @@
|
||||
#include "gtkbindings.h"
|
||||
#include "gtkcelleditable.h"
|
||||
#include "gtkclipboard.h"
|
||||
#include "gtkcssnodeutilsprivate.h"
|
||||
#include "gtkdebug.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkentry.h"
|
||||
@@ -174,6 +175,8 @@ struct _GtkEntryPrivate
|
||||
GtkGesture *drag_gesture;
|
||||
GtkGesture *multipress_gesture;
|
||||
|
||||
GtkCssNode *progress_node;
|
||||
|
||||
gfloat xalign;
|
||||
|
||||
gint ascent; /* font ascent in pango units */
|
||||
@@ -235,12 +238,12 @@ struct _GtkEntryPrivate
|
||||
struct _EntryIconInfo
|
||||
{
|
||||
GdkWindow *window;
|
||||
GtkCssNode *css_node;
|
||||
gchar *tooltip;
|
||||
guint insensitive : 1;
|
||||
guint nonactivatable : 1;
|
||||
guint prelight : 1;
|
||||
guint in_drag : 1;
|
||||
guint pressed : 1;
|
||||
|
||||
GdkDragAction actions;
|
||||
GtkTargetList *target_list;
|
||||
@@ -1509,13 +1512,17 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
* icons prelight on mouseover.
|
||||
*
|
||||
* Since: 2.16
|
||||
*
|
||||
* Deprecated: 3.18: Activatable icons are always prelit on hover.
|
||||
* Just don't style the :hover style if you don't want them to
|
||||
* look different.
|
||||
*/
|
||||
gtk_widget_class_install_style_property (widget_class,
|
||||
g_param_spec_boolean ("icon-prelight",
|
||||
P_("Icon Prelight"),
|
||||
P_("Whether activatable icons should prelight when hovered"),
|
||||
TRUE,
|
||||
GTK_PARAM_READABLE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
GTK_PARAM_READABLE|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_DEPRECATED));
|
||||
|
||||
/**
|
||||
* GtkEntry:progress-border:
|
||||
@@ -2691,7 +2698,7 @@ find_invisible_char (GtkWidget *widget)
|
||||
static void
|
||||
gtk_entry_init (GtkEntry *entry)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkCssNode *widget_node;
|
||||
GtkEntryPrivate *priv;
|
||||
|
||||
entry->priv = gtk_entry_get_instance_private (entry);
|
||||
@@ -2735,8 +2742,8 @@ gtk_entry_init (GtkEntry *entry)
|
||||
g_signal_connect (priv->im_context, "delete-surrounding",
|
||||
G_CALLBACK (gtk_entry_delete_surrounding_cb), entry);
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (entry));
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_ENTRY);
|
||||
widget_node = gtk_widget_get_css_node (GTK_WIDGET (entry));
|
||||
gtk_css_node_add_class (widget_node, GTK_STYLE_CLASS_ENTRY);
|
||||
|
||||
gtk_entry_update_cached_style_values (entry);
|
||||
|
||||
@@ -2753,6 +2760,16 @@ gtk_entry_init (GtkEntry *entry)
|
||||
G_CALLBACK (gtk_entry_multipress_gesture_pressed), entry);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->multipress_gesture), 0);
|
||||
gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (priv->multipress_gesture), TRUE);
|
||||
|
||||
priv->progress_node = gtk_css_node_new ();
|
||||
gtk_css_node_set_widget_type (priv->progress_node, GTK_TYPE_ENTRY);
|
||||
gtk_css_node_add_class (priv->progress_node, GTK_STYLE_CLASS_ENTRY);
|
||||
gtk_css_node_add_class (priv->progress_node, GTK_STYLE_CLASS_PROGRESSBAR);
|
||||
gtk_css_node_set_parent (priv->progress_node, widget_node);
|
||||
gtk_css_node_set_state (priv->progress_node, gtk_css_node_get_state (widget_node));
|
||||
g_signal_connect_object (priv->progress_node, "style-changed", G_CALLBACK (gtk_css_node_style_changed_for_widget), entry, 0);
|
||||
g_object_unref (priv->progress_node);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2791,47 +2808,6 @@ gtk_entry_ensure_text_handles (GtkEntry *entry)
|
||||
G_CALLBACK (gtk_entry_handle_drag_finished), entry);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_prepare_context_for_icon (GtkEntry *entry,
|
||||
GtkStyleContext *context,
|
||||
GtkEntryIconPosition icon_pos)
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
EntryIconInfo *icon_info = priv->icons[icon_pos];
|
||||
GtkWidget *widget;
|
||||
GtkStateFlags state;
|
||||
|
||||
widget = GTK_WIDGET (entry);
|
||||
state = gtk_widget_get_state_flags (widget);
|
||||
|
||||
state &= ~(GTK_STATE_FLAG_PRELIGHT);
|
||||
|
||||
if ((state & GTK_STATE_FLAG_INSENSITIVE) || icon_info->insensitive)
|
||||
state |= GTK_STATE_FLAG_INSENSITIVE;
|
||||
else if (icon_info->prelight)
|
||||
state |= GTK_STATE_FLAG_PRELIGHT;
|
||||
|
||||
gtk_style_context_save (context);
|
||||
|
||||
gtk_style_context_set_state (context, state);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_IMAGE);
|
||||
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
|
||||
{
|
||||
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
|
||||
else
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
|
||||
else
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
get_icon_width (GtkEntry *entry,
|
||||
GtkEntryIconPosition icon_pos)
|
||||
@@ -2847,7 +2823,7 @@ get_icon_width (GtkEntry *entry,
|
||||
return 0;
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (entry));
|
||||
gtk_entry_prepare_context_for_icon (entry, context, icon_pos);
|
||||
gtk_style_context_save_to_node (context, priv->icons[icon_pos]->css_node);
|
||||
state = gtk_style_context_get_state (context);
|
||||
gtk_style_context_get_padding (context, state, &padding);
|
||||
|
||||
@@ -3002,6 +2978,8 @@ gtk_entry_finalize (GObject *object)
|
||||
{
|
||||
if ((icon_info = priv->icons[i]) != NULL)
|
||||
{
|
||||
g_object_unref (icon_info->css_node);
|
||||
|
||||
if (icon_info->target_list != NULL)
|
||||
{
|
||||
gtk_target_list_unref (icon_info->target_list);
|
||||
@@ -3213,12 +3191,85 @@ realize_icon_info (GtkWidget *widget,
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
update_state_for_icon_infos (GtkWidget *widget)
|
||||
{
|
||||
GtkCssNode *cssnode, *first_node, *last_node;
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
GtkStateFlags state;
|
||||
#define NOT_INHERITED (GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_ACTIVE)
|
||||
|
||||
cssnode = gtk_widget_get_css_node (widget);
|
||||
state = gtk_widget_get_state_flags (widget);
|
||||
|
||||
if (priv->icons[GTK_ENTRY_ICON_PRIMARY])
|
||||
gtk_css_node_set_state (priv->icons[GTK_ENTRY_ICON_PRIMARY]->css_node,
|
||||
(state & ~NOT_INHERITED)
|
||||
| (gtk_css_node_get_state (priv->icons[GTK_ENTRY_ICON_PRIMARY]->css_node) & NOT_INHERITED)
|
||||
| (priv->icons[GTK_ENTRY_ICON_PRIMARY]->insensitive ? GTK_STATE_FLAG_INSENSITIVE : 0));
|
||||
if (priv->icons[GTK_ENTRY_ICON_SECONDARY])
|
||||
gtk_css_node_set_state (priv->icons[GTK_ENTRY_ICON_SECONDARY]->css_node,
|
||||
(state & ~NOT_INHERITED)
|
||||
| (gtk_css_node_get_state (priv->icons[GTK_ENTRY_ICON_SECONDARY]->css_node) & NOT_INHERITED)
|
||||
| (priv->icons[GTK_ENTRY_ICON_SECONDARY]->insensitive ? GTK_STATE_FLAG_INSENSITIVE : 0));
|
||||
|
||||
if (state & GTK_STATE_FLAG_DIR_RTL)
|
||||
{
|
||||
first_node = priv->icons[GTK_ENTRY_ICON_SECONDARY] ? priv->icons[GTK_ENTRY_ICON_SECONDARY]->css_node : NULL;
|
||||
last_node = priv->icons[GTK_ENTRY_ICON_PRIMARY] ? priv->icons[GTK_ENTRY_ICON_PRIMARY]->css_node : NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_node = priv->icons[GTK_ENTRY_ICON_PRIMARY] ? priv->icons[GTK_ENTRY_ICON_PRIMARY]->css_node : NULL;
|
||||
last_node = priv->icons[GTK_ENTRY_ICON_SECONDARY] ? priv->icons[GTK_ENTRY_ICON_SECONDARY]->css_node : NULL;
|
||||
}
|
||||
|
||||
if (first_node)
|
||||
{
|
||||
if (first_node != gtk_css_node_get_first_child (cssnode))
|
||||
gtk_css_node_set_before (first_node, gtk_css_node_get_first_child (cssnode));
|
||||
gtk_css_node_remove_class (first_node, GTK_STYLE_CLASS_RIGHT);
|
||||
gtk_css_node_add_class (first_node, GTK_STYLE_CLASS_LEFT);
|
||||
}
|
||||
if (last_node)
|
||||
{
|
||||
if (last_node != gtk_css_node_get_last_child (cssnode))
|
||||
gtk_css_node_set_after (last_node, gtk_css_node_get_last_child (cssnode));
|
||||
gtk_css_node_remove_class (last_node, GTK_STYLE_CLASS_LEFT);
|
||||
gtk_css_node_add_class (last_node, GTK_STYLE_CLASS_RIGHT);
|
||||
}
|
||||
|
||||
#undef NOT_INHERITED
|
||||
}
|
||||
|
||||
static void
|
||||
icon_node_style_changed_cb (GtkCssNode *node,
|
||||
GtkCssStyle *old_style,
|
||||
GtkCssStyle *new_style,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
GtkIconHelper *icon_helper;
|
||||
|
||||
gtk_css_node_style_changed_for_widget (node, old_style, new_style, widget);
|
||||
|
||||
if (priv->icons[GTK_ENTRY_ICON_PRIMARY] && priv->icons[GTK_ENTRY_ICON_PRIMARY]->css_node == node)
|
||||
icon_helper = priv->icons[GTK_ENTRY_ICON_PRIMARY]->icon_helper;
|
||||
else
|
||||
icon_helper = priv->icons[GTK_ENTRY_ICON_SECONDARY]->icon_helper;
|
||||
|
||||
_gtk_icon_helper_invalidate (icon_helper);
|
||||
}
|
||||
|
||||
static EntryIconInfo*
|
||||
construct_icon_info (GtkWidget *widget,
|
||||
GtkEntryIconPosition icon_pos)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
GtkCssNode *widget_node;
|
||||
EntryIconInfo *icon_info;
|
||||
|
||||
g_return_val_if_fail (priv->icons[icon_pos] == NULL, NULL);
|
||||
@@ -3229,6 +3280,14 @@ construct_icon_info (GtkWidget *widget,
|
||||
icon_info->icon_helper = _gtk_icon_helper_new ();
|
||||
_gtk_icon_helper_set_force_scale_pixbuf (icon_info->icon_helper, TRUE);
|
||||
|
||||
icon_info->css_node = gtk_css_node_new ();
|
||||
widget_node = gtk_widget_get_css_node (widget);
|
||||
gtk_css_node_add_class (icon_info->css_node, GTK_STYLE_CLASS_ENTRY);
|
||||
gtk_css_node_add_class (icon_info->css_node, GTK_STYLE_CLASS_IMAGE);
|
||||
gtk_css_node_set_parent (icon_info->css_node, widget_node);
|
||||
g_signal_connect_object (icon_info->css_node, "style-changed", G_CALLBACK (icon_node_style_changed_cb), widget, 0);
|
||||
update_state_for_icon_infos (widget);
|
||||
|
||||
if (gtk_widget_get_realized (widget))
|
||||
realize_icon_info (widget, icon_pos);
|
||||
|
||||
@@ -3429,14 +3488,19 @@ _gtk_entry_get_borders (GtkEntry *entry,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gtk_entry_get_content_width (GtkCssNode *cssnode,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer data)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkWidget *widget = GTK_WIDGET(data);
|
||||
GtkEntry *entry = GTK_ENTRY (data);
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
PangoFontMetrics *metrics;
|
||||
GtkBorder borders;
|
||||
PangoContext *context;
|
||||
gint icon_width, i;
|
||||
gint min, nat;
|
||||
@@ -3444,8 +3508,6 @@ gtk_entry_get_preferred_width (GtkWidget *widget,
|
||||
gint digit_width;
|
||||
gint char_pixels;
|
||||
|
||||
_gtk_entry_get_borders (entry, &borders);
|
||||
|
||||
context = gtk_widget_get_pango_context (widget);
|
||||
metrics = pango_context_get_metrics (context,
|
||||
pango_context_get_font_description (context),
|
||||
@@ -3458,14 +3520,14 @@ gtk_entry_get_preferred_width (GtkWidget *widget,
|
||||
pango_font_metrics_unref (metrics);
|
||||
|
||||
if (priv->width_chars < 0)
|
||||
min = MIN_ENTRY_WIDTH + borders.left + borders.right;
|
||||
min = MIN_ENTRY_WIDTH;
|
||||
else
|
||||
min = char_pixels * priv->width_chars + borders.left + borders.right;
|
||||
min = char_pixels * priv->width_chars;
|
||||
|
||||
if (priv->max_width_chars < 0)
|
||||
nat = MIN_ENTRY_WIDTH + borders.left + borders.right;
|
||||
nat = MIN_ENTRY_WIDTH;
|
||||
else
|
||||
nat = char_pixels * priv->max_width_chars + borders.left + borders.right;
|
||||
nat = char_pixels * priv->max_width_chars;
|
||||
|
||||
icon_width = 0;
|
||||
for (i = 0; i < MAX_ICONS; i++)
|
||||
@@ -3479,17 +3541,33 @@ gtk_entry_get_preferred_width (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
gtk_entry_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
gtk_css_node_get_preferred_size (gtk_widget_get_css_node (widget),
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
minimum, natural,
|
||||
NULL, NULL,
|
||||
gtk_entry_get_content_width,
|
||||
widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_get_content_height (GtkCssNode *cssnode,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET(data);
|
||||
GtkEntry *entry = GTK_ENTRY (data);
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
PangoFontMetrics *metrics;
|
||||
GtkBorder borders;
|
||||
PangoContext *context;
|
||||
gint height, baseline;
|
||||
PangoLayout *layout;
|
||||
@@ -3505,14 +3583,11 @@ gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
priv->descent = pango_font_metrics_get_descent (metrics);
|
||||
pango_font_metrics_unref (metrics);
|
||||
|
||||
_gtk_entry_get_borders (entry, &borders);
|
||||
pango_layout_get_pixel_size (layout, NULL, &height);
|
||||
|
||||
height = MAX (height, PANGO_PIXELS (priv->ascent + priv->descent));
|
||||
height += borders.top + borders.bottom;
|
||||
|
||||
baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
|
||||
baseline += borders.top;
|
||||
|
||||
*minimum = height;
|
||||
*natural = height;
|
||||
@@ -3522,6 +3597,23 @@ gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
*natural_baseline = baseline;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
gtk_css_node_get_preferred_size (gtk_widget_get_css_node (widget),
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
width,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline,
|
||||
gtk_entry_get_content_height,
|
||||
widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
@@ -3736,7 +3828,6 @@ should_prelight (GtkEntry *entry,
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
EntryIconInfo *icon_info = priv->icons[icon_pos];
|
||||
gboolean prelight;
|
||||
|
||||
if (!icon_info)
|
||||
return FALSE;
|
||||
@@ -3744,14 +3835,7 @@ should_prelight (GtkEntry *entry,
|
||||
if (icon_info->nonactivatable && icon_info->target_list == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (icon_info->pressed)
|
||||
return FALSE;
|
||||
|
||||
gtk_widget_style_get (GTK_WIDGET (entry),
|
||||
"icon-prelight", &prelight,
|
||||
NULL);
|
||||
|
||||
return prelight;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3782,7 +3866,7 @@ draw_icon (GtkWidget *widget,
|
||||
gtk_cairo_transform_to_window (cr, widget, icon_info->window);
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
gtk_entry_prepare_context_for_icon (entry, context, icon_pos);
|
||||
gtk_style_context_save_to_node (context, priv->icons[icon_pos]->css_node);
|
||||
_gtk_icon_helper_get_size (icon_info->icon_helper, context,
|
||||
&pix_width, &pix_height);
|
||||
state = gtk_style_context_get_state (context);
|
||||
@@ -3839,18 +3923,6 @@ gtk_entry_draw_frame (GtkWidget *widget,
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_prepare_context_for_progress (GtkEntry *entry,
|
||||
GtkStyleContext *context)
|
||||
{
|
||||
GtkEntryPrivate *private = entry->priv;
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_PROGRESSBAR);
|
||||
if (private->progress_pulse_mode)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_PULSE);
|
||||
}
|
||||
|
||||
static void
|
||||
get_progress_area (GtkWidget *widget,
|
||||
gint *x,
|
||||
@@ -3899,7 +3971,7 @@ get_progress_area (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_entry_prepare_context_for_progress (entry, context);
|
||||
gtk_style_context_save_to_node (context, private->progress_node);
|
||||
gtk_style_context_get_margin (context, state, &margin);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
@@ -3953,7 +4025,7 @@ gtk_entry_draw_progress (GtkWidget *widget,
|
||||
if ((width <= 0) || (height <= 0))
|
||||
return;
|
||||
|
||||
gtk_entry_prepare_context_for_progress (entry, context);
|
||||
gtk_style_context_save_to_node (context, entry->priv->progress_node);
|
||||
gtk_render_background (context, cr, x, y, width, height);
|
||||
gtk_render_frame (context, cr, x, y, width, height);
|
||||
|
||||
@@ -4023,10 +4095,7 @@ gtk_entry_enter_notify (GtkWidget *widget,
|
||||
if (icon_info != NULL && event->window == icon_info->window)
|
||||
{
|
||||
if (should_prelight (entry, i))
|
||||
{
|
||||
icon_info->prelight = TRUE;
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
gtk_css_node_add_state (icon_info->css_node, GTK_STATE_FLAG_PRELIGHT);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -4051,13 +4120,10 @@ gtk_entry_leave_notify (GtkWidget *widget,
|
||||
{
|
||||
/* a grab means that we may never see the button release */
|
||||
if (event->mode == GDK_CROSSING_GRAB || event->mode == GDK_CROSSING_GTK_GRAB)
|
||||
icon_info->pressed = FALSE;
|
||||
gtk_css_node_remove_state (icon_info->css_node, GTK_STATE_FLAG_ACTIVE);
|
||||
|
||||
if (should_prelight (entry, i))
|
||||
{
|
||||
icon_info->prelight = FALSE;
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
gtk_css_node_remove_state (icon_info->css_node, GTK_STATE_FLAG_PRELIGHT);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -4297,15 +4363,10 @@ gtk_entry_event (GtkWidget *widget,
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
if (should_prelight (GTK_ENTRY (widget), i))
|
||||
{
|
||||
icon_info->prelight = FALSE;
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
priv->start_x = x;
|
||||
priv->start_y = y;
|
||||
icon_info->pressed = TRUE;
|
||||
gtk_css_node_add_state (icon_info->css_node, GTK_STATE_FLAG_ACTIVE);
|
||||
icon_info->device = device;
|
||||
|
||||
if (!icon_info->nonactivatable)
|
||||
@@ -4318,7 +4379,7 @@ gtk_entry_event (GtkWidget *widget,
|
||||
break;
|
||||
/* Fall through */
|
||||
case GDK_MOTION_NOTIFY:
|
||||
if (icon_info->pressed &&
|
||||
if ((gtk_css_node_get_state (icon_info->css_node) & GTK_STATE_FLAG_ACTIVE) &&
|
||||
icon_info->target_list != NULL &&
|
||||
gtk_drag_check_threshold (widget,
|
||||
priv->start_x,
|
||||
@@ -4344,18 +4405,9 @@ gtk_entry_event (GtkWidget *widget,
|
||||
icon_info->current_sequence = NULL;
|
||||
/* Fall through */
|
||||
case GDK_BUTTON_RELEASE:
|
||||
icon_info->pressed = FALSE;
|
||||
gtk_css_node_remove_state (icon_info->css_node, GTK_STATE_FLAG_ACTIVE);
|
||||
icon_info->device = NULL;
|
||||
|
||||
if (should_prelight (GTK_ENTRY (widget), i) &&
|
||||
x >= 0 && y >= 0 &&
|
||||
x < gdk_window_get_width (icon_info->window) &&
|
||||
y < gdk_window_get_height (icon_info->window))
|
||||
{
|
||||
icon_info->prelight = TRUE;
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
if (!icon_info->nonactivatable)
|
||||
g_signal_emit (widget, signals[ICON_RELEASE], 0, i, event);
|
||||
|
||||
@@ -5075,6 +5127,8 @@ gtk_entry_state_flags_changed (GtkWidget *widget,
|
||||
gtk_editable_select_region (GTK_EDITABLE (entry), priv->current_pos, priv->current_pos);
|
||||
}
|
||||
|
||||
update_state_for_icon_infos (widget);
|
||||
|
||||
gtk_entry_update_cached_style_values (entry);
|
||||
}
|
||||
|
||||
@@ -6499,7 +6553,7 @@ gtk_entry_draw_text (GtkEntry *entry,
|
||||
gtk_style_context_get_color (context, state, &text_color);
|
||||
|
||||
/* Get foreground color for progressbars */
|
||||
gtk_entry_prepare_context_for_progress (entry, context);
|
||||
gtk_style_context_save_to_node (context, priv->progress_node);
|
||||
gtk_style_context_get_color (context, state, &bar_text_color);
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
@@ -7439,6 +7493,8 @@ gtk_entry_clear (GtkEntry *entry,
|
||||
if (GDK_IS_WINDOW (icon_info->window))
|
||||
gdk_window_hide (icon_info->window);
|
||||
|
||||
gtk_css_node_set_visible (icon_info->css_node, FALSE);
|
||||
|
||||
storage_type = _gtk_icon_helper_get_storage_type (icon_info->icon_helper);
|
||||
|
||||
switch (storage_type)
|
||||
@@ -7486,7 +7542,7 @@ gtk_entry_ensure_pixbuf (GtkEntry *entry,
|
||||
GdkPixbuf *pix;
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (entry));
|
||||
gtk_entry_prepare_context_for_icon (entry, context, icon_pos);
|
||||
gtk_style_context_save_to_node (context, priv->icons[icon_pos]->css_node);
|
||||
|
||||
pix = _gtk_icon_helper_ensure_pixbuf (icon_info->icon_helper,
|
||||
context);
|
||||
@@ -8496,6 +8552,8 @@ gtk_entry_set_icon_from_pixbuf (GtkEntry *entry,
|
||||
_gtk_icon_helper_set_icon_size (icon_info->icon_helper,
|
||||
GTK_ICON_SIZE_MENU);
|
||||
|
||||
gtk_css_node_set_visible (icon_info->css_node, TRUE);
|
||||
|
||||
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
|
||||
{
|
||||
g_object_notify (G_OBJECT (entry), "primary-icon-pixbuf");
|
||||
@@ -8562,6 +8620,8 @@ gtk_entry_set_icon_from_stock (GtkEntry *entry,
|
||||
{
|
||||
_gtk_icon_helper_set_stock_id (icon_info->icon_helper, new_id, GTK_ICON_SIZE_MENU);
|
||||
|
||||
gtk_css_node_set_visible (icon_info->css_node, TRUE);
|
||||
|
||||
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
|
||||
{
|
||||
g_object_notify (G_OBJECT (entry), "primary-icon-stock");
|
||||
@@ -8629,6 +8689,8 @@ gtk_entry_set_icon_from_icon_name (GtkEntry *entry,
|
||||
{
|
||||
_gtk_icon_helper_set_icon_name (icon_info->icon_helper, new_name, GTK_ICON_SIZE_MENU);
|
||||
|
||||
gtk_css_node_set_visible (icon_info->css_node, TRUE);
|
||||
|
||||
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
|
||||
{
|
||||
g_object_notify (G_OBJECT (entry), "primary-icon-name");
|
||||
@@ -8695,6 +8757,8 @@ gtk_entry_set_icon_from_gicon (GtkEntry *entry,
|
||||
{
|
||||
_gtk_icon_helper_set_gicon (icon_info->icon_helper, icon, GTK_ICON_SIZE_MENU);
|
||||
|
||||
gtk_css_node_set_visible (icon_info->css_node, TRUE);
|
||||
|
||||
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
|
||||
{
|
||||
g_object_notify (G_OBJECT (entry), "primary-icon-gicon");
|
||||
@@ -8961,14 +9025,15 @@ gtk_entry_set_icon_sensitive (GtkEntry *entry,
|
||||
{
|
||||
icon_info->insensitive = !sensitive;
|
||||
|
||||
icon_info->pressed = FALSE;
|
||||
icon_info->prelight = FALSE;
|
||||
gtk_css_node_remove_state (icon_info->css_node, GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_ACTIVE);
|
||||
if (!gtk_widget_is_sensitive (GTK_WIDGET (entry)) || icon_info->insensitive)
|
||||
gtk_css_node_add_state (icon_info->css_node, GTK_STATE_FLAG_INSENSITIVE);
|
||||
else
|
||||
gtk_css_node_remove_state (icon_info->css_node, GTK_STATE_FLAG_INSENSITIVE);
|
||||
|
||||
if (gtk_widget_get_realized (GTK_WIDGET (entry)))
|
||||
update_cursors (GTK_WIDGET (entry));
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (entry));
|
||||
|
||||
g_object_notify (G_OBJECT (entry),
|
||||
icon_pos == GTK_ENTRY_ICON_PRIMARY ? "primary-icon-sensitive" : "secondary-icon-sensitive");
|
||||
}
|
||||
@@ -9480,7 +9545,7 @@ check_undo_icon_grab (GtkEntry *entry,
|
||||
!gtk_widget_device_is_shadowed (GTK_WIDGET (entry), info->device))
|
||||
return;
|
||||
|
||||
info->pressed = FALSE;
|
||||
gtk_css_node_remove_state (info->css_node, GTK_STATE_FLAG_ACTIVE);
|
||||
info->current_sequence = NULL;
|
||||
info->device = NULL;
|
||||
}
|
||||
@@ -10554,6 +10619,8 @@ gtk_entry_start_pulse_mode (GtkEntry *entry)
|
||||
priv->progress_pulse_mode = TRUE;
|
||||
priv->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (entry), tick_cb, NULL, NULL);
|
||||
|
||||
gtk_css_node_add_class (priv->progress_node, GTK_STYLE_CLASS_PULSE);
|
||||
|
||||
priv->progress_fraction = 0.0;
|
||||
priv->progress_pulse_way_back = FALSE;
|
||||
priv->progress_pulse_current = 0.0;
|
||||
@@ -10574,6 +10641,8 @@ gtk_entry_stop_pulse_mode (GtkEntry *entry)
|
||||
priv->progress_pulse_mode = FALSE;
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (entry), priv->tick_id);
|
||||
priv->tick_id = 0;
|
||||
|
||||
gtk_css_node_remove_class (priv->progress_node, GTK_STYLE_CLASS_PULSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1193,6 +1193,37 @@ gtk_style_context_get_parent (GtkStyleContext *context)
|
||||
return context->priv->parent;
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_style_context_save_to_node:
|
||||
* @context: a #GtkStyleContext
|
||||
* @node: the node to save to
|
||||
*
|
||||
* Saves the @context state, so temporary modifications done through
|
||||
* gtk_style_context_add_class(), gtk_style_context_remove_class(),
|
||||
* gtk_style_context_set_state(), etc. and rendering using
|
||||
* gtk_render_background() or similar functions are done using the
|
||||
* given @node.
|
||||
*
|
||||
* To undo, call gtk_style_context_restore().
|
||||
*
|
||||
* The matching call to gtk_style_context_restore() must be done
|
||||
* before GTK returns to the main loop.
|
||||
**/
|
||||
void
|
||||
gtk_style_context_save_to_node (GtkStyleContext *context,
|
||||
GtkCssNode *node)
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
|
||||
g_return_if_fail (GTK_IS_CSS_NODE (node));
|
||||
|
||||
priv = context->priv;
|
||||
|
||||
priv->saved_nodes = g_slist_prepend (priv->saved_nodes, priv->cssnode);
|
||||
priv->cssnode = g_object_ref (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_style_context_save:
|
||||
* @context: a #GtkStyleContext
|
||||
@@ -1226,8 +1257,9 @@ gtk_style_context_save (GtkStyleContext *context)
|
||||
gtk_css_node_set_parent (cssnode, gtk_style_context_get_root (context));
|
||||
gtk_css_node_set_widget_type (cssnode, gtk_css_node_get_widget_type (priv->cssnode));
|
||||
|
||||
priv->saved_nodes = g_slist_prepend (priv->saved_nodes, priv->cssnode);
|
||||
priv->cssnode = cssnode;
|
||||
gtk_style_context_save_to_node (context, cssnode);
|
||||
|
||||
g_object_unref (cssnode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1283,15 +1315,13 @@ gtk_style_context_add_class (GtkStyleContext *context,
|
||||
const gchar *class_name)
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
GQuark class_quark;
|
||||
|
||||
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
|
||||
g_return_if_fail (class_name != NULL);
|
||||
|
||||
priv = context->priv;
|
||||
class_quark = g_quark_from_string (class_name);
|
||||
|
||||
gtk_css_node_add_class (priv->cssnode, class_quark);
|
||||
gtk_css_node_add_class (priv->cssnode, class_name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1308,19 +1338,13 @@ gtk_style_context_remove_class (GtkStyleContext *context,
|
||||
const gchar *class_name)
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
GQuark class_quark;
|
||||
|
||||
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
|
||||
g_return_if_fail (class_name != NULL);
|
||||
|
||||
class_quark = g_quark_try_string (class_name);
|
||||
|
||||
if (!class_quark)
|
||||
return;
|
||||
|
||||
priv = context->priv;
|
||||
|
||||
gtk_css_node_remove_class (priv->cssnode, class_quark);
|
||||
gtk_css_node_remove_class (priv->cssnode, class_name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1340,19 +1364,13 @@ gtk_style_context_has_class (GtkStyleContext *context,
|
||||
const gchar *class_name)
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
GQuark class_quark;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
|
||||
g_return_val_if_fail (class_name != NULL, FALSE);
|
||||
|
||||
class_quark = g_quark_try_string (class_name);
|
||||
|
||||
if (!class_quark)
|
||||
return FALSE;
|
||||
|
||||
priv = context->priv;
|
||||
|
||||
return gtk_css_node_has_class (priv->cssnode, class_quark);
|
||||
return gtk_css_node_has_class (priv->cssnode, class_name);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1383,16 +1401,12 @@ GList *
|
||||
gtk_style_context_list_classes (GtkStyleContext *context)
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
GList *classes;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
|
||||
|
||||
priv = context->priv;
|
||||
|
||||
classes = gtk_css_node_list_classes (priv->cssnode);
|
||||
quarks_to_strings (classes);
|
||||
|
||||
return classes;
|
||||
return gtk_css_node_list_classes (priv->cssnode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -36,6 +36,9 @@ const char * gtk_style_context_get_id (GtkStyleContext *c
|
||||
GtkStyleProviderPrivate *
|
||||
gtk_style_context_get_style_provider (GtkStyleContext *context);
|
||||
|
||||
void gtk_style_context_save_to_node (GtkStyleContext *context,
|
||||
GtkCssNode *node);
|
||||
|
||||
const GtkBitmask *
|
||||
_gtk_style_context_get_changes (GtkStyleContext *context);
|
||||
|
||||
|
306
gtk/gtkswitch.c
306
gtk/gtkswitch.c
@@ -42,15 +42,18 @@
|
||||
#include "gtkswitch.h"
|
||||
|
||||
#include "deprecated/gtkactivatable.h"
|
||||
#include "deprecated/gtktoggleaction.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "deprecated/gtktoggleaction.h"
|
||||
#include "gtkwidget.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkapplicationprivate.h"
|
||||
#include "gtkactionable.h"
|
||||
#include "a11y/gtkswitchaccessible.h"
|
||||
#include "gtkactionhelper.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkcssnodeutilsprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
#include "fallback-c89.c"
|
||||
@@ -66,6 +69,8 @@ struct _GtkSwitchPrivate
|
||||
GtkGesture *pan_gesture;
|
||||
GtkGesture *multipress_gesture;
|
||||
|
||||
GtkCssNode *slider_node;
|
||||
|
||||
double handle_pos;
|
||||
gint64 start_time;
|
||||
gint64 end_time;
|
||||
@@ -254,9 +259,7 @@ gtk_switch_pan_gesture_pan (GtkGesturePan *gesture,
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
state = gtk_widget_get_state_flags (widget);
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_TROUGH);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER);
|
||||
gtk_style_context_save_to_node (context, priv->slider_node);
|
||||
gtk_style_context_get_padding (context, state, &padding);
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
@@ -344,55 +347,99 @@ gtk_switch_activate (GtkSwitch *sw)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_switch_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gtk_switch_get_slider_size (GtkCssNode *cssnode,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer data)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkStateFlags state;
|
||||
GtkBorder padding;
|
||||
gint width, slider_width;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle logical_rect;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
state = gtk_style_context_get_state (context);
|
||||
|
||||
gtk_style_context_save (context);
|
||||
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_TROUGH);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER);
|
||||
gtk_style_context_get_padding (context, state, &padding);
|
||||
|
||||
width = padding.left + padding.right;
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
GtkWidget *widget = GTK_WIDGET (data);
|
||||
gint slider_width;
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"slider-width", &slider_width,
|
||||
NULL);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
slider_width *= 0.6;
|
||||
|
||||
*minimum = slider_width;
|
||||
*natural = slider_width;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_switch_get_content_size (GtkCssNode *cssnode,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkSwitch *self;
|
||||
GtkSwitchPrivate *priv;
|
||||
gint slider_minimum, slider_natural;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle on_rect, off_rect;
|
||||
|
||||
widget = GTK_WIDGET (data);
|
||||
self = GTK_SWITCH (data);
|
||||
priv = self->priv;
|
||||
|
||||
gtk_css_node_get_preferred_size (priv->slider_node,
|
||||
orientation,
|
||||
-1,
|
||||
&slider_minimum, &slider_natural,
|
||||
NULL, NULL,
|
||||
gtk_switch_get_slider_size,
|
||||
self);
|
||||
|
||||
/* Translators: if the "on" state label requires more than three
|
||||
* glyphs then use MEDIUM VERTICAL BAR (U+2759) as the text for
|
||||
* the state
|
||||
*/
|
||||
layout = gtk_widget_create_pango_layout (widget, C_("switch", "ON"));
|
||||
pango_layout_get_extents (layout, NULL, &logical_rect);
|
||||
pango_extents_to_pixels (&logical_rect, NULL);
|
||||
width += MAX (logical_rect.width, slider_width);
|
||||
pango_layout_get_pixel_extents (layout, NULL, &on_rect);
|
||||
|
||||
/* Translators: if the "off" state label requires more than three
|
||||
* glyphs then use WHITE CIRCLE (U+25CB) as the text for the state
|
||||
*/
|
||||
pango_layout_set_text (layout, C_("switch", "OFF"), -1);
|
||||
pango_layout_get_extents (layout, NULL, &logical_rect);
|
||||
pango_extents_to_pixels (&logical_rect, NULL);
|
||||
width += MAX (logical_rect.width, slider_width);
|
||||
pango_layout_get_pixel_extents (layout, NULL, &off_rect);
|
||||
|
||||
g_object_unref (layout);
|
||||
|
||||
*minimum = width;
|
||||
*natural = width;
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
int text_width = MAX (on_rect.width, off_rect.width);
|
||||
*minimum = 2 * MAX (slider_minimum, text_width);
|
||||
*natural = 2 * MAX (slider_natural, text_width);
|
||||
}
|
||||
else
|
||||
{
|
||||
int text_height = MAX (on_rect.height, off_rect.height);
|
||||
*minimum = MAX (slider_minimum, text_height);
|
||||
*natural = MAX (slider_natural, text_height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_switch_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gtk_css_node_get_preferred_size (gtk_widget_get_css_node (widget),
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
minimum, natural,
|
||||
NULL, NULL,
|
||||
gtk_switch_get_content_size,
|
||||
widget);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -400,47 +447,34 @@ gtk_switch_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkStateFlags state;
|
||||
GtkBorder padding;
|
||||
gint height, slider_width, min_height;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle logical_rect;
|
||||
gchar *str;
|
||||
gtk_css_node_get_preferred_size (gtk_widget_get_css_node (widget),
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
minimum, natural,
|
||||
NULL, NULL,
|
||||
gtk_switch_get_content_size,
|
||||
widget);
|
||||
}
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
state = gtk_style_context_get_state (context);
|
||||
static void
|
||||
gtk_switch_allocate_contents (GtkCssNode *cssnode,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip,
|
||||
gpointer data)
|
||||
{
|
||||
GtkSwitch *self = data;
|
||||
GtkSwitchPrivate *priv = self->priv;
|
||||
|
||||
gtk_style_context_save (context);
|
||||
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_TROUGH);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER);
|
||||
gtk_style_context_get_padding (context, state, &padding);
|
||||
|
||||
height = padding.top + padding.bottom;
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"slider-width", &slider_width,
|
||||
NULL);
|
||||
|
||||
min_height = slider_width * 0.6;
|
||||
|
||||
str = g_strdup_printf ("%s%s",
|
||||
C_("switch", "ON"),
|
||||
C_("switch", "OFF"));
|
||||
|
||||
layout = gtk_widget_create_pango_layout (widget, str);
|
||||
pango_layout_get_extents (layout, NULL, &logical_rect);
|
||||
pango_extents_to_pixels (&logical_rect, NULL);
|
||||
height += MAX (min_height, logical_rect.height);
|
||||
|
||||
g_object_unref (layout);
|
||||
g_free (str);
|
||||
|
||||
*minimum = height;
|
||||
*natural = height;
|
||||
/* We pretend to allocate the full area to the slider. That way both
|
||||
* potential left and right clip overlap gets correctly computed.
|
||||
*/
|
||||
gtk_css_node_allocate (priv->slider_node,
|
||||
allocation,
|
||||
baseline,
|
||||
out_clip,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -448,6 +482,7 @@ gtk_switch_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv;
|
||||
GtkAllocation clip;
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
@@ -458,7 +493,14 @@ gtk_switch_size_allocate (GtkWidget *widget,
|
||||
allocation->width,
|
||||
allocation->height);
|
||||
|
||||
_gtk_widget_set_simple_clip (widget, NULL);
|
||||
gtk_css_node_allocate (gtk_widget_get_css_node (widget),
|
||||
allocation,
|
||||
gtk_widget_get_allocated_baseline (widget),
|
||||
&clip,
|
||||
gtk_switch_allocate_contents,
|
||||
widget);
|
||||
|
||||
gtk_widget_set_clip (widget, &clip);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -543,9 +585,7 @@ gtk_switch_paint_handle (GtkWidget *widget,
|
||||
{
|
||||
GtkStyleContext *context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_TROUGH);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER);
|
||||
gtk_style_context_save_to_node (context, GTK_SWITCH (widget)->priv->slider_node);
|
||||
|
||||
gtk_render_slider (context, cr,
|
||||
box->x, box->y,
|
||||
@@ -556,48 +596,31 @@ gtk_switch_paint_handle (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_switch_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
gtk_switch_render_slider (GtkCssNode *cssnode,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (data);
|
||||
|
||||
return gtk_widget_has_visible_focus (widget);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_switch_render_trough (GtkCssNode *cssnode,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (data);
|
||||
GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv;
|
||||
GtkStyleContext *context;
|
||||
GdkRectangle handle;
|
||||
GtkStyleContext *context = gtk_widget_get_style_context (widget);
|
||||
PangoLayout *layout;
|
||||
PangoRectangle rect;
|
||||
gint label_x, label_y;
|
||||
GtkBorder padding;
|
||||
GtkStateFlags state;
|
||||
gint x, y, width, height;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
state = gtk_widget_get_state_flags (widget);
|
||||
|
||||
gtk_style_context_save (context);
|
||||
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_TROUGH);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER);
|
||||
|
||||
gtk_style_context_get_padding (context, state, &padding);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
width = gtk_widget_get_allocated_width (widget);
|
||||
height = gtk_widget_get_allocated_height (widget);
|
||||
|
||||
gtk_render_background (context, cr, x, y, width, height);
|
||||
gtk_render_frame (context, cr, x, y, width, height);
|
||||
|
||||
width -= padding.left + padding.right;
|
||||
height -= padding.top + padding.bottom;
|
||||
|
||||
x += padding.left;
|
||||
y += padding.top;
|
||||
|
||||
handle.y = y;
|
||||
handle.width = width / 2;
|
||||
handle.height = height;
|
||||
gint slider_offset;
|
||||
|
||||
/* Translators: if the "on" state label requires more than three
|
||||
* glyphs then use MEDIUM VERTICAL BAR (U+2759) as the text for
|
||||
@@ -605,11 +628,10 @@ gtk_switch_draw (GtkWidget *widget,
|
||||
*/
|
||||
layout = gtk_widget_create_pango_layout (widget, C_("switch", "ON"));
|
||||
|
||||
pango_layout_get_extents (layout, NULL, &rect);
|
||||
pango_extents_to_pixels (&rect, NULL);
|
||||
pango_layout_get_pixel_extents (layout, NULL, &rect);
|
||||
|
||||
label_x = x + ((width / 2) - rect.width) / 2;
|
||||
label_y = y + (height - rect.height) / 2;
|
||||
label_x = ((width / 2) - rect.width) / 2;
|
||||
label_y = (height - rect.height) / 2;
|
||||
|
||||
gtk_render_layout (context, cr, label_x, label_y, layout);
|
||||
|
||||
@@ -620,26 +642,40 @@ gtk_switch_draw (GtkWidget *widget,
|
||||
*/
|
||||
layout = gtk_widget_create_pango_layout (widget, C_("switch", "OFF"));
|
||||
|
||||
pango_layout_get_extents (layout, NULL, &rect);
|
||||
pango_extents_to_pixels (&rect, NULL);
|
||||
pango_layout_get_pixel_extents (layout, NULL, &rect);
|
||||
|
||||
label_x = x + (width / 2) + ((width / 2) - rect.width) / 2;
|
||||
label_y = y + (height - rect.height) / 2;
|
||||
label_x = (width / 2) + ((width / 2) - rect.width) / 2;
|
||||
label_y = (height - rect.height) / 2;
|
||||
|
||||
gtk_render_layout (context, cr, label_x, label_y, layout);
|
||||
|
||||
g_object_unref (layout);
|
||||
|
||||
handle.x = x + round (priv->handle_pos * width / 2);
|
||||
slider_offset = round (priv->handle_pos * (width - width / 2));
|
||||
cairo_translate (cr, slider_offset, 0);
|
||||
|
||||
gtk_switch_paint_handle (widget, cr, &handle);
|
||||
gtk_css_node_draw (priv->slider_node,
|
||||
cr,
|
||||
width / 2,
|
||||
height,
|
||||
gtk_switch_render_slider,
|
||||
widget);
|
||||
|
||||
if (gtk_widget_has_visible_focus (widget))
|
||||
{
|
||||
gtk_render_focus (context, cr,
|
||||
handle.x, handle.y,
|
||||
handle.width, handle.height);
|
||||
}
|
||||
cairo_translate (cr, -slider_offset, 0);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_switch_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
gtk_css_node_draw (gtk_widget_get_css_node (widget),
|
||||
cr,
|
||||
gtk_widget_get_allocated_width (widget),
|
||||
gtk_widget_get_allocated_height (widget),
|
||||
gtk_switch_render_trough,
|
||||
widget);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -995,6 +1031,7 @@ gtk_switch_init (GtkSwitch *self)
|
||||
GtkSwitchPrivate *priv;
|
||||
GtkStyleContext *context;
|
||||
GtkGesture *gesture;
|
||||
GtkCssNode *widget_node;
|
||||
|
||||
priv = self->priv = gtk_switch_get_instance_private (self);
|
||||
|
||||
@@ -1002,6 +1039,15 @@ gtk_switch_init (GtkSwitch *self)
|
||||
gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
|
||||
gtk_widget_set_can_focus (GTK_WIDGET (self), TRUE);
|
||||
|
||||
widget_node = gtk_widget_get_css_node (GTK_WIDGET (self));
|
||||
priv->slider_node = gtk_css_node_new ();
|
||||
gtk_css_node_set_widget_type (priv->slider_node, GTK_TYPE_SWITCH);
|
||||
gtk_css_node_add_class (priv->slider_node, GTK_STYLE_CLASS_SLIDER);
|
||||
gtk_css_node_set_parent (priv->slider_node, widget_node);
|
||||
gtk_css_node_set_state (priv->slider_node, gtk_css_node_get_state (widget_node));
|
||||
g_signal_connect_object (priv->slider_node, "style-changed", G_CALLBACK (gtk_css_node_style_changed_for_widget), self, 0);
|
||||
g_object_unref (priv->slider_node);
|
||||
|
||||
gesture = gtk_gesture_multi_press_new (GTK_WIDGET (self));
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture), FALSE);
|
||||
gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (gesture), TRUE);
|
||||
|
@@ -16339,7 +16339,7 @@ gtk_widget_path_append_for_widget (GtkWidgetPath *path,
|
||||
classes = gtk_css_node_list_classes (widget->priv->cssnode);
|
||||
|
||||
for (l = classes; l; l = l->next)
|
||||
gtk_widget_path_iter_add_class (path, pos, g_quark_to_string (GPOINTER_TO_UINT (l->data)));
|
||||
gtk_widget_path_iter_add_class (path, pos, l->data);
|
||||
|
||||
g_list_free (classes);
|
||||
}
|
||||
|
Reference in New Issue
Block a user