Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e8e3ed1644 | |||
| 80f7a2a0f2 | |||
| 01d3435bfd | |||
| 958da41891 | |||
| d21be3ed52 | |||
| a00dd599d8 | |||
| c649f1016e | |||
| 3af381d90a | |||
| 81c16a2c26 | |||
| aad718560e | |||
| 159ba3b734 | |||
| dae4d4416e | |||
| 7454d0c669 | |||
| 0ada9a6c53 | |||
| 864b4ddf0e | |||
| 267841b77b | |||
| 60943737ce | |||
| 67d52c6add |
+5
-1
@@ -386,10 +386,12 @@ gtk_private_h_sources = \
|
||||
gtkcssbordervalueprivate.h \
|
||||
gtkcsscolorvalueprivate.h \
|
||||
gtkcsscornervalueprivate.h \
|
||||
gtkcsscustompropertyprivate.h \
|
||||
gtkcsscustomgadgetprivate.h \
|
||||
gtkcsscustompropertyprivate.h \
|
||||
gtkcsseasevalueprivate.h \
|
||||
gtkcssenginevalueprivate.h \
|
||||
gtkcssenumvalueprivate.h \
|
||||
gtkcssgadgetprivate.h \
|
||||
gtkcssiconthemevalueprivate.h \
|
||||
gtkcssimagebuiltinprivate.h \
|
||||
gtkcssimagecrossfadeprivate.h \
|
||||
@@ -639,10 +641,12 @@ gtk_base_c_sources = \
|
||||
gtkcssbordervalue.c \
|
||||
gtkcsscolorvalue.c \
|
||||
gtkcsscornervalue.c \
|
||||
gtkcsscustomgadget.c \
|
||||
gtkcsscustomproperty.c \
|
||||
gtkcsseasevalue.c \
|
||||
gtkcssenumvalue.c \
|
||||
gtkcssenginevalue.c \
|
||||
gtkcssgadget.c \
|
||||
gtkcssiconthemevalue.c \
|
||||
gtkcssimage.c \
|
||||
gtkcssimagebuiltin.c \
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "gtktooltip.h"
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtklabel.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
@@ -1392,7 +1393,7 @@ gtk_status_icon_update_image (GtkStatusIcon *status_icon)
|
||||
|
||||
round_size = round_pixel_size (widget, priv->size);
|
||||
|
||||
icon_helper = _gtk_icon_helper_new (widget);
|
||||
icon_helper = gtk_icon_helper_new (gtk_style_context_get_node (gtk_widget_get_style_context (widget)), widget);
|
||||
_gtk_icon_helper_set_force_scale_pixbuf (icon_helper, TRUE);
|
||||
_gtk_icon_helper_set_definition (icon_helper, priv->image_def);
|
||||
_gtk_icon_helper_set_icon_size (icon_helper, GTK_ICON_SIZE_SMALL_TOOLBAR);
|
||||
|
||||
+138
-64
@@ -81,6 +81,8 @@
|
||||
|
||||
#include "gtkbox.h"
|
||||
#include "gtkboxprivate.h"
|
||||
#include "gtkcontainerprivate.h"
|
||||
#include "gtkcsscustomgadgetprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkorientable.h"
|
||||
@@ -120,6 +122,7 @@ struct _GtkBoxPrivate
|
||||
{
|
||||
GList *children;
|
||||
GtkBoxChild *center;
|
||||
GtkCssGadget *gadget;
|
||||
|
||||
GtkOrientation orientation;
|
||||
gint16 spacing;
|
||||
@@ -226,6 +229,17 @@ G_DEFINE_TYPE_WITH_CODE (GtkBox, gtk_box, GTK_TYPE_CONTAINER,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, gtk_box_buildable_init))
|
||||
|
||||
static void
|
||||
gtk_box_dispose (GObject *object)
|
||||
{
|
||||
GtkBox *box = GTK_BOX (object);
|
||||
GtkBoxPrivate *priv = box->priv;
|
||||
|
||||
g_clear_object (&priv->gadget);
|
||||
|
||||
G_OBJECT_CLASS (gtk_box_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_class_init (GtkBoxClass *class)
|
||||
{
|
||||
@@ -235,6 +249,7 @@ gtk_box_class_init (GtkBoxClass *class)
|
||||
|
||||
object_class->set_property = gtk_box_set_property;
|
||||
object_class->get_property = gtk_box_get_property;
|
||||
object_class->dispose = gtk_box_dispose;
|
||||
|
||||
widget_class->draw = gtk_box_draw;
|
||||
widget_class->size_allocate = gtk_box_size_allocate;
|
||||
@@ -350,29 +365,6 @@ gtk_box_class_init (GtkBoxClass *class)
|
||||
gtk_widget_class_set_css_name (widget_class, "box");
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_init (GtkBox *box)
|
||||
{
|
||||
GtkBoxPrivate *private;
|
||||
|
||||
box->priv = gtk_box_get_instance_private (box);
|
||||
private = box->priv;
|
||||
|
||||
gtk_widget_set_has_window (GTK_WIDGET (box), FALSE);
|
||||
gtk_widget_set_redraw_on_allocate (GTK_WIDGET (box), FALSE);
|
||||
|
||||
private->orientation = GTK_ORIENTATION_HORIZONTAL;
|
||||
private->children = NULL;
|
||||
|
||||
private->default_expand = FALSE;
|
||||
private->homogeneous = FALSE;
|
||||
private->spacing = 0;
|
||||
private->spacing_set = FALSE;
|
||||
private->baseline_pos = GTK_BASELINE_POSITION_CENTER;
|
||||
|
||||
_gtk_orientable_set_style_classes (GTK_ORIENTABLE (box));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -440,22 +432,30 @@ gtk_box_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_box_draw_contents (GtkCssGadget *gadget,
|
||||
cairo_t *cr,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
gpointer unused)
|
||||
{
|
||||
GTK_WIDGET_CLASS (gtk_box_parent_class)->draw (gtk_css_gadget_get_owner (gadget), cr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_box_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkAllocation alloc;
|
||||
gtk_css_gadget_draw (GTK_BOX (widget)->priv->gadget, cr);
|
||||
|
||||
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);
|
||||
|
||||
return GTK_WIDGET_CLASS (gtk_box_parent_class)->draw (widget, cr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
count_expand_children (GtkBox *box,
|
||||
gint *visible_children,
|
||||
@@ -481,8 +481,8 @@ count_expand_children (GtkBox *box,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
const GtkAllocation *allocation)
|
||||
{
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
GtkBoxPrivate *private = box->priv;
|
||||
@@ -509,8 +509,6 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
gint child_size;
|
||||
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
count_expand_children (box, &nvis_children, &nexpand_children);
|
||||
|
||||
/* If there is no visible child, simply return. */
|
||||
@@ -816,8 +814,8 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
const GtkAllocation *allocation)
|
||||
{
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
GtkBoxPrivate *priv = box->priv;
|
||||
@@ -847,8 +845,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)
|
||||
@@ -1185,9 +1181,13 @@ gtk_box_size_allocate_with_center (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
gtk_box_allocate_contents (GtkCssGadget *gadget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
|
||||
GtkBox *box = GTK_BOX (widget);
|
||||
|
||||
if (box->priv->center &&
|
||||
@@ -1195,6 +1195,25 @@ gtk_box_size_allocate (GtkWidget *widget,
|
||||
gtk_box_size_allocate_with_center (widget, allocation);
|
||||
else
|
||||
gtk_box_size_allocate_no_center (widget, allocation);
|
||||
|
||||
gtk_container_get_children_clip (GTK_CONTAINER (box), out_clip);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
GtkBoxPrivate *priv = GTK_BOX (widget)->priv;
|
||||
GtkAllocation clip;
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
gtk_css_gadget_allocate (priv->gadget,
|
||||
allocation,
|
||||
gtk_widget_get_allocated_baseline (widget),
|
||||
&clip);
|
||||
|
||||
gtk_widget_set_clip (widget, &clip);
|
||||
}
|
||||
|
||||
static GType
|
||||
@@ -1679,18 +1698,26 @@ gtk_box_get_size (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size, NULL, NULL);
|
||||
gtk_css_gadget_get_preferred_size (GTK_BOX (widget)->priv->gadget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum_size,
|
||||
gint *natural_size)
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gtk_box_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size, NULL, NULL);
|
||||
gtk_css_gadget_get_preferred_size (GTK_BOX (widget)->priv->gadget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1979,42 +2006,58 @@ gtk_box_compute_size_for_orientation (GtkBox *box,
|
||||
static void
|
||||
gtk_box_get_preferred_width_for_height (GtkWidget *widget,
|
||||
gint height,
|
||||
gint *minimum_width,
|
||||
gint *natural_width)
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
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_gadget_get_preferred_size (GTK_BOX (widget)->priv->gadget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
height,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint width,
|
||||
gint *minimum_height,
|
||||
gint *natural_height,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
gtk_css_gadget_get_preferred_size (GTK_BOX (widget)->priv->gadget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
width,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_get_content_size (GtkCssGadget *gadget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
|
||||
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);
|
||||
if (for_size < 0)
|
||||
gtk_box_get_size (widget, orientation, minimum, natural, 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);
|
||||
if (private->orientation != orientation)
|
||||
gtk_box_compute_size_for_opposing_orientation (box, for_size, minimum, natural, 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_box_compute_size_for_orientation (box, for_size, minimum, natural);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2028,6 +2071,37 @@ gtk_box_get_preferred_height_for_width (GtkWidget *widget,
|
||||
gtk_box_get_preferred_height_and_baseline_for_width (widget, width, minimum_height, natural_height, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_box_init (GtkBox *box)
|
||||
{
|
||||
GtkBoxPrivate *private;
|
||||
|
||||
box->priv = gtk_box_get_instance_private (box);
|
||||
private = box->priv;
|
||||
|
||||
gtk_widget_set_has_window (GTK_WIDGET (box), FALSE);
|
||||
gtk_widget_set_redraw_on_allocate (GTK_WIDGET (box), FALSE);
|
||||
|
||||
private->orientation = GTK_ORIENTATION_HORIZONTAL;
|
||||
private->children = NULL;
|
||||
|
||||
private->default_expand = FALSE;
|
||||
private->homogeneous = FALSE;
|
||||
private->spacing = 0;
|
||||
private->spacing_set = FALSE;
|
||||
private->baseline_pos = GTK_BASELINE_POSITION_CENTER;
|
||||
|
||||
private->gadget = gtk_css_custom_gadget_new_for_node (gtk_widget_get_css_node (GTK_WIDGET (box)),
|
||||
GTK_WIDGET (box),
|
||||
gtk_box_get_content_size,
|
||||
gtk_box_allocate_contents,
|
||||
gtk_box_draw_contents,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
_gtk_orientable_set_style_classes (GTK_ORIENTABLE (box));
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_box_new:
|
||||
* @orientation: the box’s orientation.
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "a11y/gtkimagecellaccessible.h"
|
||||
|
||||
|
||||
@@ -446,7 +447,7 @@ create_icon_helper (GtkCellRendererPixbuf *cellpixbuf,
|
||||
GtkCellRendererPixbufPrivate *priv = cellpixbuf->priv;
|
||||
GtkIconHelper *helper;
|
||||
|
||||
helper = _gtk_icon_helper_new (widget);
|
||||
helper = gtk_icon_helper_new (gtk_style_context_get_node (gtk_widget_get_style_context (widget)), widget);
|
||||
_gtk_icon_helper_set_force_scale_pixbuf (helper, TRUE);
|
||||
_gtk_icon_helper_set_definition (helper, priv->image_def);
|
||||
if (gtk_image_definition_get_storage_type (priv->image_def) != GTK_IMAGE_PIXBUF)
|
||||
@@ -580,12 +581,12 @@ gtk_cell_renderer_pixbuf_render (GtkCellRenderer *cell,
|
||||
|
||||
if (is_expanded && priv->pixbuf_expander_open != NULL)
|
||||
{
|
||||
icon_helper = _gtk_icon_helper_new (widget);
|
||||
icon_helper = gtk_icon_helper_new (gtk_style_context_get_node (context), widget);
|
||||
_gtk_icon_helper_set_pixbuf (icon_helper, priv->pixbuf_expander_open);
|
||||
}
|
||||
else if (!is_expanded && priv->pixbuf_expander_closed != NULL)
|
||||
{
|
||||
icon_helper = _gtk_icon_helper_new (widget);
|
||||
icon_helper = gtk_icon_helper_new (gtk_style_context_get_node (context), widget);
|
||||
_gtk_icon_helper_set_pixbuf (icon_helper, priv->pixbuf_expander_closed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3751,6 +3751,30 @@ gtk_container_propagate_draw_internal (GtkContainer *container,
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
union_with_clip (GtkWidget *widget,
|
||||
gpointer clip)
|
||||
{
|
||||
GtkAllocation widget_clip;
|
||||
|
||||
if (!gtk_widget_is_visible (widget) ||
|
||||
!_gtk_widget_get_child_visible (widget))
|
||||
return;
|
||||
|
||||
gtk_widget_get_clip (widget, &widget_clip);
|
||||
|
||||
gdk_rectangle_union (&widget_clip, clip, clip);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_container_get_children_clip (GtkContainer *container,
|
||||
GtkAllocation *out_clip)
|
||||
{
|
||||
memset (out_clip, 0, sizeof (GtkAllocation));
|
||||
|
||||
gtk_container_forall (container, union_with_clip, out_clip);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_container_propagate_draw:
|
||||
* @container: a #GtkContainer
|
||||
|
||||
@@ -42,6 +42,8 @@ void _gtk_container_maybe_start_idle_sizer (GtkContainer *container);
|
||||
gboolean _gtk_container_get_border_width_set (GtkContainer *container);
|
||||
void _gtk_container_set_border_width_set (GtkContainer *container,
|
||||
gboolean border_width_set);
|
||||
void gtk_container_get_children_clip (GtkContainer *container,
|
||||
GtkAllocation *out_clip);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright © 2015 Red Hat Inc.
|
||||
*
|
||||
* 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.1 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/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcsscustomgadgetprivate.h"
|
||||
|
||||
#include "gtkcssnodeprivate.h"
|
||||
|
||||
typedef struct _GtkCssCustomGadgetPrivate GtkCssCustomGadgetPrivate;
|
||||
struct _GtkCssCustomGadgetPrivate {
|
||||
GtkCssPreferredSizeFunc preferred_size_func;
|
||||
GtkCssAllocateFunc allocate_func;
|
||||
GtkCssDrawFunc draw_func;
|
||||
gpointer data;
|
||||
GDestroyNotify destroy_func;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkCssCustomGadget, gtk_css_custom_gadget, GTK_TYPE_CSS_GADGET,
|
||||
G_ADD_PRIVATE (GtkCssCustomGadget))
|
||||
|
||||
static void
|
||||
gtk_css_custom_gadget_get_preferred_size (GtkCssGadget *gadget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkCssCustomGadgetPrivate *priv = gtk_css_custom_gadget_get_instance_private (GTK_CSS_CUSTOM_GADGET (gadget));
|
||||
|
||||
if (priv->preferred_size_func)
|
||||
return priv->preferred_size_func (gadget, orientation, for_size,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline,
|
||||
priv->data);
|
||||
else
|
||||
return GTK_CSS_GADGET_CLASS (gtk_css_custom_gadget_parent_class)->get_preferred_size (gadget, orientation, for_size,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_custom_gadget_allocate (GtkCssGadget *gadget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip)
|
||||
{
|
||||
GtkCssCustomGadgetPrivate *priv = gtk_css_custom_gadget_get_instance_private (GTK_CSS_CUSTOM_GADGET (gadget));
|
||||
|
||||
if (priv->allocate_func)
|
||||
return priv->allocate_func (gadget, allocation, baseline, out_clip, priv->data);
|
||||
else
|
||||
return GTK_CSS_GADGET_CLASS (gtk_css_custom_gadget_parent_class)->allocate (gadget, allocation, baseline, out_clip);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_custom_gadget_draw (GtkCssGadget *gadget,
|
||||
cairo_t *cr,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GtkCssCustomGadgetPrivate *priv = gtk_css_custom_gadget_get_instance_private (GTK_CSS_CUSTOM_GADGET (gadget));
|
||||
|
||||
if (priv->draw_func)
|
||||
return priv->draw_func (gadget, cr, x, y, width, height, priv->data);
|
||||
else
|
||||
return GTK_CSS_GADGET_CLASS (gtk_css_custom_gadget_parent_class)->draw (gadget, cr, x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_custom_gadget_finalize (GObject *object)
|
||||
{
|
||||
GtkCssCustomGadgetPrivate *priv = gtk_css_custom_gadget_get_instance_private (GTK_CSS_CUSTOM_GADGET (object));
|
||||
|
||||
if (priv->destroy_func)
|
||||
priv->destroy_func (priv->data);
|
||||
|
||||
G_OBJECT_CLASS (gtk_css_custom_gadget_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_custom_gadget_class_init (GtkCssCustomGadgetClass *klass)
|
||||
{
|
||||
GtkCssGadgetClass *gadget_class = GTK_CSS_GADGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gtk_css_custom_gadget_finalize;
|
||||
|
||||
gadget_class->get_preferred_size = gtk_css_custom_gadget_get_preferred_size;
|
||||
gadget_class->allocate = gtk_css_custom_gadget_allocate;
|
||||
gadget_class->draw = gtk_css_custom_gadget_draw;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_custom_gadget_init (GtkCssCustomGadget *custom_gadget)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GtkCssGadget *
|
||||
gtk_css_custom_gadget_new_for_node (GtkCssNode *node,
|
||||
GtkWidget *owner,
|
||||
GtkCssPreferredSizeFunc preferred_size_func,
|
||||
GtkCssAllocateFunc allocate_func,
|
||||
GtkCssDrawFunc draw_func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy_func)
|
||||
{
|
||||
GtkCssCustomGadgetPrivate *priv;
|
||||
GtkCssGadget *result;
|
||||
|
||||
result = g_object_new (GTK_TYPE_CSS_CUSTOM_GADGET,
|
||||
"node", node,
|
||||
"owner", owner,
|
||||
NULL);
|
||||
|
||||
priv = gtk_css_custom_gadget_get_instance_private (GTK_CSS_CUSTOM_GADGET (result));
|
||||
|
||||
priv->preferred_size_func = preferred_size_func;
|
||||
priv->allocate_func = allocate_func;
|
||||
priv->draw_func = draw_func;
|
||||
priv->data = data;
|
||||
priv->destroy_func = destroy_func;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GtkCssGadget *
|
||||
gtk_css_custom_gadget_new (const char *name,
|
||||
GtkWidget *owner,
|
||||
GtkCssGadget *parent,
|
||||
GtkCssGadget *next_sibling,
|
||||
GtkCssPreferredSizeFunc preferred_size_func,
|
||||
GtkCssAllocateFunc allocate_func,
|
||||
GtkCssDrawFunc draw_func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy_func)
|
||||
{
|
||||
GtkCssNode *node;
|
||||
GtkCssGadget *result;
|
||||
|
||||
node = gtk_css_node_new ();
|
||||
gtk_css_node_set_name (node, g_intern_string (name));
|
||||
if (parent)
|
||||
gtk_css_node_insert_before (gtk_css_gadget_get_node (parent),
|
||||
node,
|
||||
next_sibling ? gtk_css_gadget_get_node (next_sibling) : NULL);
|
||||
|
||||
result = gtk_css_custom_gadget_new_for_node (node,
|
||||
owner,
|
||||
preferred_size_func,
|
||||
allocate_func,
|
||||
draw_func,
|
||||
data,
|
||||
destroy_func);
|
||||
|
||||
g_object_unref (node);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright © 2015 Red Hat Inc.
|
||||
*
|
||||
* 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.1 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/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_CUSTOM_GADGET_PRIVATE_H__
|
||||
#define __GTK_CSS_CUSTOM_GADGET_PRIVATE_H__
|
||||
|
||||
#include "gtk/gtkcssgadgetprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CSS_CUSTOM_GADGET (gtk_css_custom_gadget_get_type ())
|
||||
#define GTK_CSS_CUSTOM_GADGET(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_CUSTOM_GADGET, GtkCssCustomGadget))
|
||||
#define GTK_CSS_CUSTOM_GADGET_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_CUSTOM_GADGET, GtkCssCustomGadgetClass))
|
||||
#define GTK_IS_CSS_CUSTOM_GADGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_CUSTOM_GADGET))
|
||||
#define GTK_IS_CSS_CUSTOM_GADGET_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_CUSTOM_GADGET))
|
||||
#define GTK_CSS_CUSTOM_GADGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_CUSTOM_GADGET, GtkCssCustomGadgetClass))
|
||||
|
||||
typedef struct _GtkCssCustomGadget GtkCssCustomGadget;
|
||||
typedef struct _GtkCssCustomGadgetClass GtkCssCustomGadgetClass;
|
||||
|
||||
typedef void (* GtkCssPreferredSizeFunc) (GtkCssGadget *gadget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer data);
|
||||
typedef void (* GtkCssAllocateFunc) (GtkCssGadget *gadget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip,
|
||||
gpointer data);
|
||||
typedef gboolean (* GtkCssDrawFunc) (GtkCssGadget *gadget,
|
||||
cairo_t *cr,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data);
|
||||
struct _GtkCssCustomGadget
|
||||
{
|
||||
GtkCssGadget parent;
|
||||
};
|
||||
|
||||
struct _GtkCssCustomGadgetClass
|
||||
{
|
||||
GtkCssGadgetClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_css_custom_gadget_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkCssGadget * gtk_css_custom_gadget_new (const char *name,
|
||||
GtkWidget *owner,
|
||||
GtkCssGadget *parent,
|
||||
GtkCssGadget *next_sibling,
|
||||
GtkCssPreferredSizeFunc get_preferred_size_func,
|
||||
GtkCssAllocateFunc allocate_func,
|
||||
GtkCssDrawFunc draw_func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy_func);
|
||||
GtkCssGadget * gtk_css_custom_gadget_new_for_node (GtkCssNode *node,
|
||||
GtkWidget *owner,
|
||||
GtkCssPreferredSizeFunc preferred_size_func,
|
||||
GtkCssAllocateFunc allocate_func,
|
||||
GtkCssDrawFunc draw_func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy_func);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_CUSTOM_GADGET_PRIVATE_H__ */
|
||||
@@ -0,0 +1,565 @@
|
||||
/*
|
||||
* Copyright © 2015 Red Hat Inc.
|
||||
*
|
||||
* 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.1 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/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcssgadgetprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssstyleprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkcsswidgetnodeprivate.h"
|
||||
#include "gtkrenderbackgroundprivate.h"
|
||||
#include "gtkrenderborderprivate.h"
|
||||
|
||||
typedef struct _GtkCssGadgetPrivate GtkCssGadgetPrivate;
|
||||
struct _GtkCssGadgetPrivate {
|
||||
GtkCssNode *node;
|
||||
GtkWidget *owner;
|
||||
GtkAllocation allocated_size;
|
||||
gint allocated_baseline;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_NODE,
|
||||
PROP_OWNER,
|
||||
/* add more */
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES];
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkCssGadget, gtk_css_gadget, G_TYPE_OBJECT,
|
||||
G_ADD_PRIVATE (GtkCssGadget))
|
||||
|
||||
static void
|
||||
gtk_css_gadget_real_get_preferred_size (GtkCssGadget *gadget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
*minimum = 0;
|
||||
*natural = 0;
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = 0;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_gadget_real_allocate (GtkCssGadget *gadget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip)
|
||||
{
|
||||
*out_clip = *allocation;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_gadget_real_draw (GtkCssGadget *gadget,
|
||||
cairo_t *cr,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_gadget_real_style_changed (GtkCssGadget *gadget,
|
||||
GtkCssStyleChange *change)
|
||||
{
|
||||
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
|
||||
|
||||
if (priv->owner)
|
||||
{
|
||||
if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SIZE))
|
||||
gtk_widget_queue_resize (priv->owner);
|
||||
else if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_CLIP))
|
||||
gtk_widget_queue_allocate (priv->owner);
|
||||
else if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_REDRAW))
|
||||
gtk_widget_queue_draw (priv->owner);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_gadget_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (GTK_CSS_GADGET (object));
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_NODE:
|
||||
g_value_set_object (value, priv->node);
|
||||
break;
|
||||
|
||||
case PROP_OWNER:
|
||||
g_value_set_object (value, priv->owner);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_gadget_node_style_changed_cb (GtkCssNode *node,
|
||||
GtkCssStyleChange *change,
|
||||
GtkCssGadget *gadget)
|
||||
{
|
||||
GtkCssGadgetClass *klass = GTK_CSS_GADGET_GET_CLASS (gadget);
|
||||
|
||||
klass->style_changed (gadget, change);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_gadget_should_connect_style_changed (GtkCssNode *node)
|
||||
{
|
||||
/* Delegate to WidgetClass->style_changed */
|
||||
if (GTK_IS_CSS_WIDGET_NODE (node))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_gadget_unset_node (GtkCssGadget *gadget)
|
||||
{
|
||||
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
|
||||
|
||||
if (priv->node)
|
||||
{
|
||||
if (gtk_css_gadget_should_connect_style_changed (priv->node))
|
||||
{
|
||||
if (g_signal_handlers_disconnect_by_func (priv->node, gtk_css_gadget_node_style_changed_cb, gadget) != 1)
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
g_object_unref (priv->node);
|
||||
priv->node = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_gadget_set_node (GtkCssGadget *gadget,
|
||||
GtkCssNode *node)
|
||||
{
|
||||
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
|
||||
|
||||
if (node != NULL)
|
||||
priv->node = g_object_ref (node);
|
||||
else
|
||||
priv->node = gtk_css_node_new ();
|
||||
|
||||
if (gtk_css_gadget_should_connect_style_changed (priv->node))
|
||||
{
|
||||
g_signal_connect_after (priv->node,
|
||||
"style-changed",
|
||||
G_CALLBACK (gtk_css_gadget_node_style_changed_cb),
|
||||
gadget);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_gadget_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkCssGadget *gadget = GTK_CSS_GADGET (object);
|
||||
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_NODE:
|
||||
gtk_css_gadget_set_node (gadget, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_OWNER:
|
||||
priv->owner = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_css_gadget_finalize (GObject *object)
|
||||
{
|
||||
GtkCssGadget *gadget = GTK_CSS_GADGET (object);
|
||||
|
||||
gtk_css_gadget_unset_node (gadget);
|
||||
|
||||
G_OBJECT_CLASS (gtk_css_gadget_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_gadget_class_init (GtkCssGadgetClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = gtk_css_gadget_get_property;
|
||||
object_class->set_property = gtk_css_gadget_set_property;
|
||||
object_class->finalize = gtk_css_gadget_finalize;
|
||||
|
||||
klass->get_preferred_size = gtk_css_gadget_real_get_preferred_size;
|
||||
klass->allocate = gtk_css_gadget_real_allocate;
|
||||
klass->draw = gtk_css_gadget_real_draw;
|
||||
klass->style_changed = gtk_css_gadget_real_style_changed;
|
||||
|
||||
properties[PROP_NODE] = g_param_spec_object ("node", "Node",
|
||||
"CSS node",
|
||||
GTK_TYPE_CSS_NODE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
properties[PROP_OWNER] = g_param_spec_object ("owner", "Owner",
|
||||
"Widget that created and owns this gadget",
|
||||
GTK_TYPE_WIDGET,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
|
||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_gadget_init (GtkCssGadget *gadget)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GtkCssNode *
|
||||
gtk_css_gadget_get_node (GtkCssGadget *gadget)
|
||||
{
|
||||
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
|
||||
|
||||
return priv->node;
|
||||
}
|
||||
|
||||
GtkCssStyle *
|
||||
gtk_css_gadget_get_style (GtkCssGadget *gadget)
|
||||
{
|
||||
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
|
||||
|
||||
return gtk_css_node_get_style (priv->node);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_css_gadget_get_owner (GtkCssGadget *gadget)
|
||||
{
|
||||
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
|
||||
|
||||
return priv->owner;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_gadget_add_class (GtkCssGadget *gadget,
|
||||
const char *name)
|
||||
{
|
||||
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
|
||||
GQuark quark;
|
||||
|
||||
quark = g_quark_from_string (name);
|
||||
|
||||
gtk_css_node_add_class (priv->node, quark);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_gadget_remove_class (GtkCssGadget *gadget,
|
||||
const char *name)
|
||||
{
|
||||
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
|
||||
GQuark quark;
|
||||
|
||||
quark = g_quark_try_string (name);
|
||||
if (quark == 0)
|
||||
return;
|
||||
|
||||
gtk_css_node_remove_class (priv->node, quark);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_gadget_get_preferred_size (GtkCssGadget *gadget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
GtkCssStyle *style;
|
||||
GtkBorder margin, border, padding;
|
||||
int min_size, extra_size, extra_opposite, extra_baseline;
|
||||
int unused_minimum, unused_natural;
|
||||
|
||||
if (minimum == NULL)
|
||||
minimum = &unused_minimum;
|
||||
if (natural == NULL)
|
||||
natural = &unused_natural;
|
||||
|
||||
style = gtk_css_gadget_get_style (gadget);
|
||||
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;
|
||||
|
||||
GTK_CSS_GADGET_GET_CLASS (gadget)->get_preferred_size (gadget,
|
||||
orientation,
|
||||
for_size,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_gadget_allocate (GtkCssGadget *gadget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip)
|
||||
{
|
||||
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
|
||||
GtkAllocation content_allocation, content_clip;
|
||||
GtkBorder margin, border, padding, shadow, extents;
|
||||
GtkCssStyle *style;
|
||||
|
||||
g_return_if_fail (out_clip != NULL);
|
||||
|
||||
priv->allocated_size = *allocation;
|
||||
priv->allocated_baseline = baseline;
|
||||
|
||||
style = gtk_css_gadget_get_style (gadget);
|
||||
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);
|
||||
|
||||
GTK_CSS_GADGET_GET_CLASS (gadget)->allocate (gadget, &content_allocation, baseline, &content_clip);
|
||||
|
||||
_gtk_css_shadows_value_get_extents (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BOX_SHADOW), &shadow);
|
||||
out_clip->x = allocation->x + margin.left - shadow.left;
|
||||
out_clip->y = allocation->y + margin.top - shadow.top;
|
||||
out_clip->width = allocation->width - margin.left - margin.right + shadow.left + shadow.right;
|
||||
out_clip->height = allocation->height - margin.top - margin.bottom + shadow.top + shadow.bottom;
|
||||
gdk_rectangle_union (&content_clip, out_clip, out_clip);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_css_gadget_draw:
|
||||
* @gadget: The gadget to draw
|
||||
* @cr: The cairo context to draw to
|
||||
*
|
||||
* Will draw the gadget at the position allocated via
|
||||
* gtk_css_gadget_allocate(). It is your responsibility to make
|
||||
* sure that those 2 coordinate systems match.
|
||||
*
|
||||
* The drawing virtual function will be passed an untransformed @cr.
|
||||
* This is important because functions like
|
||||
* gtk_container_propagate_draw() depend on that.
|
||||
*/
|
||||
void
|
||||
gtk_css_gadget_draw (GtkCssGadget *gadget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
|
||||
GtkBorder margin, border, padding;
|
||||
gboolean draw_focus;
|
||||
GtkCssStyle *style;
|
||||
int x, y, width, height;
|
||||
int contents_x, contents_y, contents_width, contents_height;
|
||||
|
||||
x = priv->allocated_size.x;
|
||||
y = priv->allocated_size.y;
|
||||
if (priv->owner && !gtk_widget_get_has_window (priv->owner))
|
||||
{
|
||||
GtkAllocation widget_alloc;
|
||||
gtk_widget_get_allocation (priv->owner, &widget_alloc);
|
||||
x -= widget_alloc.x;
|
||||
y -= widget_alloc.y;
|
||||
}
|
||||
width = priv->allocated_size.width;
|
||||
height = priv->allocated_size.height;
|
||||
|
||||
style = gtk_css_gadget_get_style (gadget);
|
||||
get_box_margin (style, &margin);
|
||||
get_box_border (style, &border);
|
||||
get_box_padding (style, &padding);
|
||||
|
||||
gtk_css_style_render_background (style,
|
||||
cr,
|
||||
x + margin.left,
|
||||
y + margin.top,
|
||||
width - margin.left - margin.right,
|
||||
height - margin.top - margin.bottom,
|
||||
gtk_css_node_get_junction_sides (priv->node));
|
||||
gtk_css_style_render_border (style,
|
||||
cr,
|
||||
x + margin.left,
|
||||
y + margin.top,
|
||||
width - margin.left - margin.right,
|
||||
height - margin.top - margin.bottom,
|
||||
0,
|
||||
gtk_css_node_get_junction_sides (priv->node));
|
||||
|
||||
contents_x = x + margin.left + border.left + padding.left;
|
||||
contents_y = y + 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 = GTK_CSS_GADGET_GET_CLASS (gadget)->draw (gadget,
|
||||
cr,
|
||||
contents_x, contents_y,
|
||||
contents_width, contents_height);
|
||||
|
||||
if (draw_focus)
|
||||
gtk_css_style_render_outline (style,
|
||||
cr,
|
||||
x + margin.left,
|
||||
y + margin.top,
|
||||
width - margin.left - margin.right,
|
||||
height - margin.top - margin.bottom);
|
||||
}
|
||||
|
||||
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_bitmask_new ();
|
||||
changes = gtk_css_style_add_difference (changes, 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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright © 2015 Red Hat Inc.
|
||||
*
|
||||
* 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.1 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/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_GADGET_PRIVATE_H__
|
||||
#define __GTK_CSS_GADGET_PRIVATE_H__
|
||||
|
||||
#include <cairo.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "gtk/gtkwidget.h"
|
||||
#include "gtk/gtkcssstylechangeprivate.h"
|
||||
#include "gtk/gtkcsstypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CSS_GADGET (gtk_css_gadget_get_type ())
|
||||
#define GTK_CSS_GADGET(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_GADGET, GtkCssGadget))
|
||||
#define GTK_CSS_GADGET_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_GADGET, GtkCssGadgetClass))
|
||||
#define GTK_IS_CSS_GADGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_GADGET))
|
||||
#define GTK_IS_CSS_GADGET_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_GADGET))
|
||||
#define GTK_CSS_GADGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_GADGET, GtkCssGadgetClass))
|
||||
|
||||
typedef struct _GtkCssGadget GtkCssGadget;
|
||||
typedef struct _GtkCssGadgetClass GtkCssGadgetClass;
|
||||
|
||||
struct _GtkCssGadget
|
||||
{
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
struct _GtkCssGadgetClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* get_preferred_size) (GtkCssGadget *gadget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
void (* allocate) (GtkCssGadget *gadget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip);
|
||||
|
||||
gboolean (* draw) (GtkCssGadget *gadget,
|
||||
cairo_t *cr,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
void (* style_changed) (GtkCssGadget *gadget,
|
||||
GtkCssStyleChange *change);
|
||||
};
|
||||
|
||||
GType gtk_css_gadget_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkCssNode * gtk_css_gadget_get_node (GtkCssGadget *gadget);
|
||||
GtkCssStyle * gtk_css_gadget_get_style (GtkCssGadget *gadget);
|
||||
GtkWidget * gtk_css_gadget_get_owner (GtkCssGadget *gadget);
|
||||
|
||||
void gtk_css_gadget_add_class (GtkCssGadget *gadget,
|
||||
const char *name);
|
||||
void gtk_css_gadget_remove_class (GtkCssGadget *gadget,
|
||||
const char *name);
|
||||
|
||||
void gtk_css_gadget_get_preferred_size (GtkCssGadget *gadget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
void gtk_css_gadget_allocate (GtkCssGadget *gadget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip);
|
||||
void gtk_css_gadget_draw (GtkCssGadget *gadget,
|
||||
cairo_t *cr);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_GADGET_PRIVATE_H__ */
|
||||
@@ -843,6 +843,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)
|
||||
{
|
||||
@@ -1605,6 +1614,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,
|
||||
|
||||
@@ -203,6 +203,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,
|
||||
|
||||
+83
-129
@@ -275,7 +275,7 @@ struct _EntryIconInfo
|
||||
|
||||
GdkDragAction actions;
|
||||
GtkTargetList *target_list;
|
||||
GtkIconHelper *icon_helper;
|
||||
GtkCssGadget *gadget;
|
||||
GdkEventSequence *current_sequence;
|
||||
GdkDevice *device;
|
||||
GtkCssNode *css_node;
|
||||
@@ -2772,25 +2772,16 @@ get_icon_width (GtkEntry *entry,
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
EntryIconInfo *icon_info = priv->icons[icon_pos];
|
||||
GtkStyleContext *context;
|
||||
GtkBorder padding;
|
||||
gint width;
|
||||
GtkStateFlags state;
|
||||
|
||||
if (!icon_info)
|
||||
return 0;
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (entry));
|
||||
gtk_style_context_save_to_node (context, icon_info->css_node);
|
||||
state = gtk_style_context_get_state (context);
|
||||
gtk_style_context_get_padding (context, state, &padding);
|
||||
|
||||
_gtk_icon_helper_get_size (icon_info->icon_helper,
|
||||
&width, NULL);
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
if (width > 0)
|
||||
width += padding.left + padding.right;
|
||||
gtk_css_gadget_get_preferred_size (icon_info->gadget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
&width, NULL,
|
||||
NULL, NULL);
|
||||
|
||||
return width;
|
||||
}
|
||||
@@ -2939,7 +2930,7 @@ gtk_entry_finalize (GObject *object)
|
||||
icon_info->target_list = NULL;
|
||||
}
|
||||
|
||||
g_clear_object (&icon_info->icon_helper);
|
||||
g_clear_object (&icon_info->gadget);
|
||||
|
||||
g_slice_free (EntryIconInfo, icon_info);
|
||||
priv->icons[i] = NULL;
|
||||
@@ -3074,7 +3065,7 @@ update_cursors (GtkWidget *widget)
|
||||
{
|
||||
if ((icon_info = priv->icons[i]) != NULL)
|
||||
{
|
||||
if (!_gtk_icon_helper_get_is_empty (icon_info->icon_helper) &&
|
||||
if (!_gtk_icon_helper_get_is_empty (GTK_ICON_HELPER (icon_info->gadget)) &&
|
||||
icon_info->window != NULL)
|
||||
gdk_window_show_unraised (icon_info->window);
|
||||
|
||||
@@ -3151,8 +3142,8 @@ update_icon_style (GtkWidget *widget,
|
||||
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
|
||||
icon_pos = 1 - icon_pos;
|
||||
|
||||
gtk_css_node_add_class (icon_info->css_node, g_quark_from_static_string (sides[icon_pos]));
|
||||
gtk_css_node_remove_class (icon_info->css_node, g_quark_from_static_string (sides[1 - icon_pos]));
|
||||
gtk_css_gadget_add_class (icon_info->gadget, sides[icon_pos]);
|
||||
gtk_css_gadget_remove_class (icon_info->gadget, sides[1 - icon_pos]);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3175,7 +3166,7 @@ update_icon_state (GtkWidget *widget,
|
||||
else if (icon_info->prelight)
|
||||
state |= GTK_STATE_FLAG_PRELIGHT;
|
||||
|
||||
gtk_css_node_set_state (icon_info->css_node, state);
|
||||
gtk_css_node_set_state (gtk_css_gadget_get_node (icon_info->gadget), state);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3233,12 +3224,13 @@ update_node_ordering (GtkEntry *entry)
|
||||
icon_pos = GTK_ENTRY_ICON_PRIMARY;
|
||||
|
||||
icon_info = priv->icons[icon_pos];
|
||||
if (icon_info && icon_info->css_node)
|
||||
if (icon_info)
|
||||
{
|
||||
parent = gtk_css_node_get_parent (icon_info->css_node);
|
||||
GtkCssNode *node = gtk_css_gadget_get_node (icon_info->gadget);
|
||||
parent = gtk_css_node_get_parent (node);
|
||||
sibling = gtk_css_node_get_first_child (parent);
|
||||
if (icon_info->css_node != sibling)
|
||||
gtk_css_node_insert_before (parent, icon_info->css_node, sibling);
|
||||
if (node != sibling)
|
||||
gtk_css_node_insert_before (parent, node, sibling);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3256,17 +3248,14 @@ construct_icon_info (GtkWidget *widget,
|
||||
icon_info = g_slice_new0 (EntryIconInfo);
|
||||
priv->icons[icon_pos] = icon_info;
|
||||
|
||||
icon_info->icon_helper = _gtk_icon_helper_new (widget);
|
||||
_gtk_icon_helper_set_force_scale_pixbuf (icon_info->icon_helper, TRUE);
|
||||
|
||||
widget_node = get_entry_node (widget);
|
||||
icon_info->css_node = gtk_css_node_new ();
|
||||
gtk_css_node_set_name (icon_info->css_node, I_("image"));
|
||||
gtk_css_node_set_parent (icon_info->css_node, widget_node);
|
||||
|
||||
icon_info->gadget = gtk_icon_helper_new_named ("image", widget);
|
||||
_gtk_icon_helper_set_force_scale_pixbuf (GTK_ICON_HELPER (icon_info->gadget), TRUE);
|
||||
gtk_css_node_set_parent (gtk_css_gadget_get_node (icon_info->gadget), widget_node);
|
||||
|
||||
update_icon_state (widget, icon_pos);
|
||||
update_icon_style (widget, icon_pos);
|
||||
g_object_unref (icon_info->css_node);
|
||||
|
||||
update_node_ordering (entry);
|
||||
|
||||
if (gtk_widget_get_realized (widget))
|
||||
@@ -3291,7 +3280,7 @@ gtk_entry_map (GtkWidget *widget)
|
||||
{
|
||||
if ((icon_info = priv->icons[i]) != NULL)
|
||||
{
|
||||
if (!_gtk_icon_helper_get_is_empty (icon_info->icon_helper) &&
|
||||
if (!_gtk_icon_helper_get_is_empty (GTK_ICON_HELPER (icon_info->gadget)) &&
|
||||
icon_info->window != NULL)
|
||||
gdk_window_show (icon_info->window);
|
||||
}
|
||||
@@ -3316,7 +3305,7 @@ gtk_entry_unmap (GtkWidget *widget)
|
||||
{
|
||||
if ((icon_info = priv->icons[i]) != NULL)
|
||||
{
|
||||
if (!_gtk_icon_helper_get_is_empty (icon_info->icon_helper) &&
|
||||
if (!_gtk_icon_helper_get_is_empty (GTK_ICON_HELPER (icon_info->gadget)) &&
|
||||
icon_info->window != NULL)
|
||||
gdk_window_hide (icon_info->window);
|
||||
}
|
||||
@@ -3530,6 +3519,7 @@ gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
PangoContext *context;
|
||||
gint height, baseline;
|
||||
PangoLayout *layout;
|
||||
int icon_min, icon_nat;
|
||||
|
||||
layout = gtk_entry_ensure_layout (entry, TRUE);
|
||||
context = gtk_widget_get_pango_context (widget);
|
||||
@@ -3557,6 +3547,27 @@ gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
*minimum_baseline = baseline;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = baseline;
|
||||
|
||||
if (priv->icons[GTK_ENTRY_ICON_PRIMARY])
|
||||
{
|
||||
gtk_css_gadget_get_preferred_size (priv->icons[GTK_ENTRY_ICON_PRIMARY]->gadget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
&icon_min, &icon_nat,
|
||||
NULL, NULL);
|
||||
*minimum = MAX (*minimum, icon_min);
|
||||
*natural = MAX (*natural, icon_nat);
|
||||
}
|
||||
if (priv->icons[GTK_ENTRY_ICON_SECONDARY])
|
||||
{
|
||||
gtk_css_gadget_get_preferred_size (priv->icons[GTK_ENTRY_ICON_SECONDARY]->gadget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
&icon_min, &icon_nat,
|
||||
NULL, NULL);
|
||||
*minimum = MAX (*minimum, icon_min);
|
||||
*natural = MAX (*natural, icon_nat);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3581,6 +3592,7 @@ place_windows (GtkEntry *entry)
|
||||
GtkAllocation primary;
|
||||
GtkAllocation secondary;
|
||||
EntryIconInfo *icon_info = NULL;
|
||||
GdkRectangle clip = { 0, 0, 0, 0 };
|
||||
|
||||
get_frame_size (entry, TRUE, &frame_x, &frame_y, NULL, NULL);
|
||||
get_text_area_size (entry, &x, &y, &width, &height);
|
||||
@@ -3599,15 +3611,25 @@ place_windows (GtkEntry *entry)
|
||||
secondary.x += frame_x;
|
||||
secondary.y += frame_y;
|
||||
|
||||
if ((icon_info = priv->icons[GTK_ENTRY_ICON_PRIMARY]) != NULL)
|
||||
gdk_window_move_resize (icon_info->window,
|
||||
primary.x, primary.y,
|
||||
primary.width, primary.height);
|
||||
icon_info = priv->icons[GTK_ENTRY_ICON_PRIMARY];
|
||||
if (icon_info)
|
||||
{
|
||||
gdk_window_move_resize (icon_info->window,
|
||||
primary.x, primary.y,
|
||||
primary.width, primary.height);
|
||||
gtk_css_gadget_allocate (icon_info->gadget, &primary, -1, &clip);
|
||||
}
|
||||
|
||||
if ((icon_info = priv->icons[GTK_ENTRY_ICON_SECONDARY]) != NULL)
|
||||
gdk_window_move_resize (icon_info->window,
|
||||
secondary.x, secondary.y,
|
||||
secondary.width, secondary.height);
|
||||
icon_info = priv->icons[GTK_ENTRY_ICON_SECONDARY];
|
||||
if (icon_info)
|
||||
{
|
||||
GdkRectangle tmp_clip;
|
||||
gdk_window_move_resize (icon_info->window,
|
||||
secondary.x, secondary.y,
|
||||
secondary.width, secondary.height);
|
||||
gtk_css_gadget_allocate (icon_info->gadget, &secondary, -1, &tmp_clip);
|
||||
gdk_rectangle_union (&clip, &tmp_clip, &clip);
|
||||
}
|
||||
|
||||
gdk_window_move_resize (priv->text_area, x, y, width, height);
|
||||
}
|
||||
@@ -3766,52 +3788,6 @@ should_prelight (GtkEntry *entry,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
draw_icon (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
GtkEntryIconPosition icon_pos)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
EntryIconInfo *icon_info = priv->icons[icon_pos];
|
||||
gint x, y, width, height, pix_width, pix_height;
|
||||
GtkStyleContext *context;
|
||||
GtkBorder padding;
|
||||
GtkStateFlags state;
|
||||
|
||||
if (!icon_info)
|
||||
return;
|
||||
|
||||
width = gdk_window_get_width (icon_info->window);
|
||||
height = gdk_window_get_height (icon_info->window);
|
||||
|
||||
/* size_allocate hasn't been called yet. These are the default values.
|
||||
*/
|
||||
if (width == 1 || height == 1)
|
||||
return;
|
||||
|
||||
cairo_save (cr);
|
||||
gtk_cairo_transform_to_window (cr, widget, icon_info->window);
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
gtk_style_context_save_to_node (context, icon_info->css_node);
|
||||
_gtk_icon_helper_get_size (icon_info->icon_helper,
|
||||
&pix_width, &pix_height);
|
||||
state = gtk_style_context_get_state (context);
|
||||
gtk_style_context_get_padding (context, state, &padding);
|
||||
|
||||
x = MAX (0, padding.left);
|
||||
y = MAX (0, (height - pix_height) / 2);
|
||||
|
||||
_gtk_icon_helper_draw (icon_info->icon_helper,
|
||||
cr,
|
||||
x, y);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_entry_draw_frame (GtkWidget *widget,
|
||||
GtkStyleContext *context,
|
||||
@@ -4003,7 +3979,7 @@ gtk_entry_draw (GtkWidget *widget,
|
||||
EntryIconInfo *icon_info = priv->icons[i];
|
||||
|
||||
if (icon_info != NULL)
|
||||
draw_icon (widget, cr, i);
|
||||
gtk_css_gadget_draw (icon_info->gadget, cr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5231,22 +5207,6 @@ gtk_entry_get_selection_bounds (GtkEditable *editable,
|
||||
return (priv->selection_bound != priv->current_pos);
|
||||
}
|
||||
|
||||
static void
|
||||
icon_theme_changed (GtkEntry *entry)
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < MAX_ICONS; i++)
|
||||
{
|
||||
EntryIconInfo *icon_info = priv->icons[i];
|
||||
if (icon_info != NULL)
|
||||
_gtk_icon_helper_invalidate (icon_info->icon_helper);
|
||||
}
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (entry));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_update_cached_style_values (GtkEntry *entry)
|
||||
{
|
||||
@@ -5272,8 +5232,6 @@ gtk_entry_style_updated (GtkWidget *widget)
|
||||
GTK_WIDGET_CLASS (gtk_entry_parent_class)->style_updated (widget);
|
||||
|
||||
gtk_entry_update_cached_style_values (entry);
|
||||
|
||||
icon_theme_changed (entry);
|
||||
}
|
||||
|
||||
/* GtkCellEditable method implementations
|
||||
@@ -7476,12 +7434,14 @@ gtk_entry_clear (GtkEntry *entry,
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
EntryIconInfo *icon_info = priv->icons[icon_pos];
|
||||
GtkIconHelper *icon_helper;
|
||||
GtkImageType storage_type;
|
||||
|
||||
if (icon_info == NULL)
|
||||
return;
|
||||
|
||||
if (_gtk_icon_helper_get_is_empty (icon_info->icon_helper))
|
||||
icon_helper = GTK_ICON_HELPER (icon_info->gadget);
|
||||
if (_gtk_icon_helper_get_is_empty (icon_helper))
|
||||
return;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (entry));
|
||||
@@ -7492,7 +7452,7 @@ gtk_entry_clear (GtkEntry *entry,
|
||||
if (GDK_IS_WINDOW (icon_info->window))
|
||||
gdk_window_hide (icon_info->window);
|
||||
|
||||
storage_type = _gtk_icon_helper_get_storage_type (icon_info->icon_helper);
|
||||
storage_type = _gtk_icon_helper_get_storage_type (icon_helper);
|
||||
|
||||
switch (storage_type)
|
||||
{
|
||||
@@ -7529,7 +7489,7 @@ gtk_entry_clear (GtkEntry *entry,
|
||||
break;
|
||||
}
|
||||
|
||||
_gtk_icon_helper_clear (icon_info->icon_helper);
|
||||
_gtk_icon_helper_clear (icon_helper);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (entry),
|
||||
entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY
|
||||
@@ -8533,8 +8493,8 @@ gtk_entry_set_icon_from_pixbuf (GtkEntry *entry,
|
||||
|
||||
if (pixbuf)
|
||||
{
|
||||
_gtk_icon_helper_set_pixbuf (icon_info->icon_helper, pixbuf);
|
||||
_gtk_icon_helper_set_icon_size (icon_info->icon_helper,
|
||||
_gtk_icon_helper_set_pixbuf (GTK_ICON_HELPER (icon_info->gadget), pixbuf);
|
||||
_gtk_icon_helper_set_icon_size (GTK_ICON_HELPER (icon_info->gadget),
|
||||
GTK_ICON_SIZE_MENU);
|
||||
|
||||
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
|
||||
@@ -8601,7 +8561,7 @@ gtk_entry_set_icon_from_stock (GtkEntry *entry,
|
||||
|
||||
if (new_id != NULL)
|
||||
{
|
||||
_gtk_icon_helper_set_stock_id (icon_info->icon_helper, new_id, GTK_ICON_SIZE_MENU);
|
||||
_gtk_icon_helper_set_stock_id (GTK_ICON_HELPER (icon_info->gadget), new_id, GTK_ICON_SIZE_MENU);
|
||||
|
||||
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
|
||||
{
|
||||
@@ -8668,7 +8628,7 @@ gtk_entry_set_icon_from_icon_name (GtkEntry *entry,
|
||||
|
||||
if (new_name != NULL)
|
||||
{
|
||||
_gtk_icon_helper_set_icon_name (icon_info->icon_helper, new_name, GTK_ICON_SIZE_MENU);
|
||||
_gtk_icon_helper_set_icon_name (GTK_ICON_HELPER (icon_info->gadget), new_name, GTK_ICON_SIZE_MENU);
|
||||
|
||||
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
|
||||
{
|
||||
@@ -8734,7 +8694,7 @@ gtk_entry_set_icon_from_gicon (GtkEntry *entry,
|
||||
|
||||
if (icon)
|
||||
{
|
||||
_gtk_icon_helper_set_gicon (icon_info->icon_helper, icon, GTK_ICON_SIZE_MENU);
|
||||
_gtk_icon_helper_set_gicon (GTK_ICON_HELPER (icon_info->gadget), icon, GTK_ICON_SIZE_MENU);
|
||||
|
||||
if (icon_pos == GTK_ENTRY_ICON_PRIMARY)
|
||||
{
|
||||
@@ -8850,7 +8810,6 @@ gtk_entry_get_icon_pixbuf (GtkEntry *entry,
|
||||
{
|
||||
GtkEntryPrivate *priv;
|
||||
EntryIconInfo *icon_info;
|
||||
GtkStyleContext *context;
|
||||
cairo_surface_t *surface;
|
||||
GdkPixbuf *pixbuf;
|
||||
int width, height;
|
||||
@@ -8865,23 +8824,19 @@ gtk_entry_get_icon_pixbuf (GtkEntry *entry,
|
||||
if (!icon_info)
|
||||
return NULL;
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (entry));
|
||||
gtk_style_context_save_to_node (context, icon_info->css_node);
|
||||
|
||||
_gtk_icon_helper_get_size (icon_info->icon_helper, &width, &height);
|
||||
surface = gtk_icon_helper_load_surface (icon_info->icon_helper, 1);
|
||||
_gtk_icon_helper_get_size (GTK_ICON_HELPER (icon_info->gadget), &width, &height);
|
||||
surface = gtk_icon_helper_load_surface (GTK_ICON_HELPER (icon_info->gadget), 1);
|
||||
|
||||
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
/* HACK: unfortunately this is transfer none, so we attach it somehwere
|
||||
* convenient.
|
||||
*/
|
||||
if (pixbuf)
|
||||
{
|
||||
g_object_set_data_full (G_OBJECT (icon_info->icon_helper),
|
||||
g_object_set_data_full (G_OBJECT (icon_info->gadget),
|
||||
"gtk-entry-pixbuf",
|
||||
pixbuf,
|
||||
g_object_unref);
|
||||
@@ -8920,7 +8875,7 @@ gtk_entry_get_icon_gicon (GtkEntry *entry,
|
||||
if (!icon_info)
|
||||
return NULL;
|
||||
|
||||
return _gtk_icon_helper_peek_gicon (icon_info->icon_helper);
|
||||
return _gtk_icon_helper_peek_gicon (GTK_ICON_HELPER (icon_info->gadget));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8955,7 +8910,7 @@ gtk_entry_get_icon_stock (GtkEntry *entry,
|
||||
if (!icon_info)
|
||||
return NULL;
|
||||
|
||||
return _gtk_icon_helper_get_stock_id (icon_info->icon_helper);
|
||||
return _gtk_icon_helper_get_stock_id (GTK_ICON_HELPER (icon_info->gadget));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -8988,7 +8943,7 @@ gtk_entry_get_icon_name (GtkEntry *entry,
|
||||
if (!icon_info)
|
||||
return NULL;
|
||||
|
||||
return _gtk_icon_helper_get_icon_name (icon_info->icon_helper);
|
||||
return _gtk_icon_helper_get_icon_name (GTK_ICON_HELPER (icon_info->gadget));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -9029,7 +8984,6 @@ gtk_entry_set_icon_sensitive (GtkEntry *entry,
|
||||
update_cursors (GTK_WIDGET (entry));
|
||||
|
||||
update_icon_state (GTK_WIDGET (entry), icon_pos);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (entry));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (entry),
|
||||
entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY
|
||||
@@ -9097,7 +9051,7 @@ gtk_entry_get_icon_storage_type (GtkEntry *entry,
|
||||
if (!icon_info)
|
||||
return GTK_IMAGE_EMPTY;
|
||||
|
||||
return _gtk_icon_helper_get_storage_type (icon_info->icon_helper);
|
||||
return _gtk_icon_helper_get_storage_type (GTK_ICON_HELPER (icon_info->gadget));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -10006,7 +9960,7 @@ gtk_entry_drag_begin (GtkWidget *widget,
|
||||
if (icon_info->in_drag)
|
||||
{
|
||||
gtk_drag_set_icon_definition (context,
|
||||
gtk_icon_helper_get_definition (icon_info->icon_helper),
|
||||
gtk_icon_helper_get_definition (GTK_ICON_HELPER (icon_info->gadget)),
|
||||
-2, -2);
|
||||
return;
|
||||
}
|
||||
|
||||
+163
-86
@@ -25,18 +25,18 @@
|
||||
|
||||
#include "gtkcssenumvalueprivate.h"
|
||||
#include "gtkcssiconthemevalueprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkcssstyleprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkcsstransientnodeprivate.h"
|
||||
#include "gtkiconthemeprivate.h"
|
||||
#include "gtkrender.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtkrendericonprivate.h"
|
||||
#include "deprecated/gtkiconfactoryprivate.h"
|
||||
#include "deprecated/gtkstock.h"
|
||||
|
||||
struct _GtkIconHelperPrivate {
|
||||
GtkImageDefinition *def;
|
||||
|
||||
GtkWidget *owner;
|
||||
GdkWindow *window;
|
||||
|
||||
GtkIconSize icon_size;
|
||||
gint pixel_size;
|
||||
|
||||
@@ -44,10 +44,22 @@ struct _GtkIconHelperPrivate {
|
||||
guint force_scale_pixbuf : 1;
|
||||
|
||||
cairo_surface_t *rendered_surface;
|
||||
gint last_surface_scale;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkIconHelper, _gtk_icon_helper, G_TYPE_OBJECT)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkIconHelper, gtk_icon_helper, GTK_TYPE_CSS_GADGET)
|
||||
|
||||
static void
|
||||
gtk_icon_helper_invalidate (GtkIconHelper *self)
|
||||
{
|
||||
if (self->priv->rendered_surface != NULL)
|
||||
{
|
||||
cairo_surface_destroy (self->priv->rendered_surface);
|
||||
self->priv->rendered_surface = NULL;
|
||||
}
|
||||
|
||||
if (!GTK_IS_CSS_TRANSIENT_NODE (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))))
|
||||
gtk_widget_queue_resize (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self)));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_helper_take_definition (GtkIconHelper *self,
|
||||
@@ -61,7 +73,7 @@ gtk_icon_helper_take_definition (GtkIconHelper *self,
|
||||
gtk_image_definition_unref (self->priv->def);
|
||||
self->priv->def = def;
|
||||
|
||||
_gtk_icon_helper_invalidate (self);
|
||||
gtk_icon_helper_invalidate (self);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -73,43 +85,120 @@ _gtk_icon_helper_clear (GtkIconHelper *self)
|
||||
self->priv->def = gtk_image_definition_new_empty ();
|
||||
|
||||
self->priv->icon_size = GTK_ICON_SIZE_INVALID;
|
||||
self->priv->last_surface_scale = 0;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_icon_helper_invalidate (GtkIconHelper *self)
|
||||
static void
|
||||
gtk_icon_helper_get_preferred_size (GtkCssGadget *gadget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
if (self->priv->rendered_surface != NULL)
|
||||
{
|
||||
cairo_surface_destroy (self->priv->rendered_surface);
|
||||
self->priv->rendered_surface = NULL;
|
||||
}
|
||||
GtkIconHelper *self = GTK_ICON_HELPER (gadget);
|
||||
int icon_width, icon_height;
|
||||
|
||||
_gtk_icon_helper_get_size (self, &icon_width, &icon_height);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
*minimum = *natural = icon_width;
|
||||
else
|
||||
*minimum = *natural = icon_height;
|
||||
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = 0;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_helper_allocate (GtkCssGadget *gadget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip)
|
||||
{
|
||||
GTK_CSS_GADGET_CLASS (gtk_icon_helper_parent_class)->allocate (gadget, allocation, baseline, out_clip);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_icon_helper_draw (GtkCssGadget *gadget,
|
||||
cairo_t *cr,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GtkIconHelper *self = GTK_ICON_HELPER (gadget);
|
||||
int icon_width, icon_height;
|
||||
|
||||
_gtk_icon_helper_get_size (self, &icon_width, &icon_height);
|
||||
_gtk_icon_helper_draw (self,
|
||||
cr,
|
||||
x + (width - icon_width) / 2,
|
||||
y + (height - icon_height) / 2);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_helper_style_changed (GtkCssGadget *gadget,
|
||||
GtkCssStyleChange *change)
|
||||
{
|
||||
if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON))
|
||||
gtk_icon_helper_invalidate (GTK_ICON_HELPER (gadget));
|
||||
|
||||
GTK_CSS_GADGET_CLASS (gtk_icon_helper_parent_class)->style_changed (gadget, change);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_helper_constructed (GObject *object)
|
||||
{
|
||||
GtkIconHelper *self = GTK_ICON_HELPER (object);
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_css_gadget_get_owner (GTK_CSS_GADGET (self));
|
||||
|
||||
g_signal_connect_swapped (widget, "direction-changed", G_CALLBACK (gtk_icon_helper_invalidate), self);
|
||||
g_signal_connect_swapped (widget, "notify::scale-factor", G_CALLBACK (gtk_icon_helper_invalidate), self);
|
||||
|
||||
G_OBJECT_CLASS (gtk_icon_helper_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_helper_finalize (GObject *object)
|
||||
{
|
||||
GtkIconHelper *self = GTK_ICON_HELPER (object);
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_css_gadget_get_owner (GTK_CSS_GADGET (self));
|
||||
g_signal_handlers_disconnect_by_func (widget, G_CALLBACK (gtk_icon_helper_invalidate), self);
|
||||
|
||||
_gtk_icon_helper_clear (self);
|
||||
gtk_image_definition_unref (self->priv->def);
|
||||
|
||||
G_OBJECT_CLASS (_gtk_icon_helper_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (gtk_icon_helper_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_icon_helper_class_init (GtkIconHelperClass *klass)
|
||||
gtk_icon_helper_class_init (GtkIconHelperClass *klass)
|
||||
{
|
||||
GObjectClass *oclass;
|
||||
GtkCssGadgetClass *gadget_class = GTK_CSS_GADGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gadget_class->get_preferred_size = gtk_icon_helper_get_preferred_size;
|
||||
gadget_class->allocate = gtk_icon_helper_allocate;
|
||||
gadget_class->draw = gtk_icon_helper_draw;
|
||||
gadget_class->style_changed = gtk_icon_helper_style_changed;
|
||||
|
||||
oclass = G_OBJECT_CLASS (klass);
|
||||
oclass->finalize = gtk_icon_helper_finalize;
|
||||
object_class->constructed = gtk_icon_helper_constructed;
|
||||
object_class->finalize = gtk_icon_helper_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_icon_helper_init (GtkIconHelper *self)
|
||||
gtk_icon_helper_init (GtkIconHelper *self)
|
||||
{
|
||||
self->priv = _gtk_icon_helper_get_instance_private (self);
|
||||
self->priv = gtk_icon_helper_get_instance_private (self);
|
||||
|
||||
self->priv->def = gtk_image_definition_new_empty ();
|
||||
|
||||
@@ -211,27 +300,6 @@ get_surface_size (GtkIconHelper *self,
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_invalidate_surface (GtkIconHelper *self,
|
||||
GtkStyleContext *context)
|
||||
{
|
||||
int scale;
|
||||
|
||||
scale = gtk_widget_get_scale_factor (self->priv->owner);
|
||||
|
||||
if ((self->priv->rendered_surface != NULL) &&
|
||||
(self->priv->last_surface_scale == scale))
|
||||
return FALSE;
|
||||
|
||||
self->priv->last_surface_scale = scale;
|
||||
|
||||
if (self->priv->rendered_surface)
|
||||
cairo_surface_destroy (self->priv->rendered_surface);
|
||||
self->priv->rendered_surface = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
ensure_surface_from_surface (GtkIconHelper *self,
|
||||
cairo_surface_t *orig_surface)
|
||||
@@ -312,7 +380,7 @@ ensure_surface_from_pixbuf (GtkIconHelper *self,
|
||||
else
|
||||
pixbuf = g_object_ref (orig_pixbuf);
|
||||
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, gtk_widget_get_window (self->priv->owner));
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, gtk_widget_get_window (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))));
|
||||
icon_effect = _gtk_css_icon_effect_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_EFFECT));
|
||||
gtk_css_icon_effect_apply (icon_effect, surface);
|
||||
g_object_unref (pixbuf);
|
||||
@@ -337,7 +405,7 @@ ensure_surface_for_icon_set (GtkIconHelper *self,
|
||||
scale);
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf,
|
||||
scale,
|
||||
gtk_widget_get_window (self->priv->owner));
|
||||
gtk_widget_get_window (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))));
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
return surface;
|
||||
@@ -413,13 +481,13 @@ ensure_surface_for_gicon (GtkIconHelper *self,
|
||||
{
|
||||
GtkCssIconEffect icon_effect;
|
||||
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (destination, scale, gtk_widget_get_window (self->priv->owner));
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (destination, scale, gtk_widget_get_window (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))));
|
||||
icon_effect = _gtk_css_icon_effect_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_EFFECT));
|
||||
gtk_css_icon_effect_apply (icon_effect, surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (destination, scale, gtk_widget_get_window (self->priv->owner));
|
||||
surface = gdk_cairo_surface_create_from_pixbuf (destination, scale, gtk_widget_get_window (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))));
|
||||
}
|
||||
g_object_unref (destination);
|
||||
|
||||
@@ -431,12 +499,9 @@ gtk_icon_helper_load_surface (GtkIconHelper *self,
|
||||
int scale)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
GtkStyleContext *context;
|
||||
GtkIconSet *icon_set;
|
||||
GIcon *gicon;
|
||||
|
||||
context = gtk_widget_get_style_context (self->priv->owner);
|
||||
|
||||
switch (gtk_image_definition_get_storage_type (self->priv->def))
|
||||
{
|
||||
case GTK_IMAGE_SURFACE:
|
||||
@@ -445,7 +510,7 @@ gtk_icon_helper_load_surface (GtkIconHelper *self,
|
||||
|
||||
case GTK_IMAGE_PIXBUF:
|
||||
surface = ensure_surface_from_pixbuf (self,
|
||||
gtk_style_context_lookup_style (context),
|
||||
gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))),
|
||||
scale,
|
||||
gtk_image_definition_get_pixbuf (self->priv->def),
|
||||
gtk_image_definition_get_scale (self->priv->def));
|
||||
@@ -457,8 +522,8 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
if (icon_set != NULL)
|
||||
surface = ensure_surface_for_icon_set (self,
|
||||
gtk_style_context_lookup_style (context),
|
||||
gtk_widget_get_direction (self->priv->owner),
|
||||
gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))),
|
||||
gtk_widget_get_direction (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))),
|
||||
scale, icon_set);
|
||||
else
|
||||
surface = NULL;
|
||||
@@ -467,8 +532,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
case GTK_IMAGE_ICON_SET:
|
||||
icon_set = gtk_image_definition_get_icon_set (self->priv->def);
|
||||
surface = ensure_surface_for_icon_set (self,
|
||||
gtk_style_context_lookup_style (context),
|
||||
gtk_widget_get_direction (self->priv->owner),
|
||||
gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))),
|
||||
gtk_widget_get_direction (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))),
|
||||
scale, icon_set);
|
||||
break;
|
||||
|
||||
@@ -478,8 +543,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
else
|
||||
gicon = g_themed_icon_new (gtk_image_definition_get_icon_name (self->priv->def));
|
||||
surface = ensure_surface_for_gicon (self,
|
||||
gtk_style_context_lookup_style (context),
|
||||
gtk_widget_get_direction (self->priv->owner),
|
||||
gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))),
|
||||
gtk_widget_get_direction (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))),
|
||||
scale,
|
||||
gicon);
|
||||
g_object_unref (gicon);
|
||||
@@ -487,8 +552,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
case GTK_IMAGE_GICON:
|
||||
surface = ensure_surface_for_gicon (self,
|
||||
gtk_style_context_lookup_style (context),
|
||||
gtk_widget_get_direction (self->priv->owner),
|
||||
gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))),
|
||||
gtk_widget_get_direction (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))),
|
||||
scale,
|
||||
gtk_image_definition_get_gicon (self->priv->def));
|
||||
break;
|
||||
@@ -505,15 +570,11 @@ G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_helper_ensure_surface (GtkIconHelper *self,
|
||||
GtkStyleContext *context)
|
||||
gtk_icon_helper_ensure_surface (GtkIconHelper *self)
|
||||
{
|
||||
int scale;
|
||||
|
||||
if (!check_invalidate_surface (self, context))
|
||||
return;
|
||||
|
||||
scale = gtk_widget_get_scale_factor (self->priv->owner);
|
||||
scale = gtk_widget_get_scale_factor (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self)));
|
||||
|
||||
self->priv->rendered_surface = gtk_icon_helper_load_surface (self, scale);
|
||||
}
|
||||
@@ -523,10 +584,8 @@ _gtk_icon_helper_get_size (GtkIconHelper *self,
|
||||
gint *width_out,
|
||||
gint *height_out)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
gint width, height, scale;
|
||||
|
||||
context = gtk_widget_get_style_context (self->priv->owner);
|
||||
width = height = 0;
|
||||
|
||||
/* Certain kinds of images are easy to calculate the size for, these
|
||||
@@ -543,7 +602,7 @@ _gtk_icon_helper_get_size (GtkIconHelper *self,
|
||||
|
||||
case GTK_IMAGE_PIXBUF:
|
||||
get_pixbuf_size (self,
|
||||
gtk_widget_get_scale_factor (self->priv->owner),
|
||||
gtk_widget_get_scale_factor (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))),
|
||||
gtk_image_definition_get_pixbuf (self->priv->def),
|
||||
gtk_image_definition_get_scale (self->priv->def),
|
||||
&width, &height, &scale);
|
||||
@@ -576,7 +635,7 @@ _gtk_icon_helper_get_size (GtkIconHelper *self,
|
||||
/* Otherwise we load the surface to guarantee we get a size */
|
||||
if (width == 0)
|
||||
{
|
||||
gtk_icon_helper_ensure_surface (self, context);
|
||||
gtk_icon_helper_ensure_surface (self);
|
||||
|
||||
if (self->priv->rendered_surface != NULL)
|
||||
{
|
||||
@@ -668,7 +727,7 @@ _gtk_icon_helper_set_icon_size (GtkIconHelper *self,
|
||||
if (self->priv->icon_size != icon_size)
|
||||
{
|
||||
self->priv->icon_size = icon_size;
|
||||
_gtk_icon_helper_invalidate (self);
|
||||
gtk_icon_helper_invalidate (self);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -681,7 +740,7 @@ _gtk_icon_helper_set_pixel_size (GtkIconHelper *self,
|
||||
if (self->priv->pixel_size != pixel_size)
|
||||
{
|
||||
self->priv->pixel_size = pixel_size;
|
||||
_gtk_icon_helper_invalidate (self);
|
||||
gtk_icon_helper_invalidate (self);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -694,7 +753,7 @@ _gtk_icon_helper_set_use_fallback (GtkIconHelper *self,
|
||||
if (self->priv->use_fallback != use_fallback)
|
||||
{
|
||||
self->priv->use_fallback = use_fallback;
|
||||
_gtk_icon_helper_invalidate (self);
|
||||
gtk_icon_helper_invalidate (self);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -773,17 +832,36 @@ _gtk_icon_helper_get_icon_name (GtkIconHelper *self)
|
||||
}
|
||||
|
||||
GtkIconHelper *
|
||||
_gtk_icon_helper_new (GtkWidget *owner)
|
||||
gtk_icon_helper_new (GtkCssNode *node,
|
||||
GtkWidget *owner)
|
||||
{
|
||||
GtkIconHelper *helper;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_NODE (node), NULL);
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (owner), NULL);
|
||||
|
||||
helper = g_object_new (GTK_TYPE_ICON_HELPER, NULL);
|
||||
return g_object_new (GTK_TYPE_ICON_HELPER,
|
||||
"node", node,
|
||||
"owner", owner,
|
||||
NULL);
|
||||
}
|
||||
|
||||
helper->priv->owner = owner;
|
||||
GtkCssGadget *
|
||||
gtk_icon_helper_new_named (const char *name,
|
||||
GtkWidget *owner)
|
||||
{
|
||||
GtkIconHelper *result;
|
||||
GtkCssNode *node;
|
||||
|
||||
return helper;
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (owner), NULL);
|
||||
|
||||
node = gtk_css_node_new ();
|
||||
gtk_css_node_set_name (node, g_intern_string (name));
|
||||
|
||||
result = gtk_icon_helper_new (node, owner);
|
||||
|
||||
g_object_unref (node);
|
||||
|
||||
return GTK_CSS_GADGET (result);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -792,15 +870,14 @@ _gtk_icon_helper_draw (GtkIconHelper *self,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
GtkStyleContext *context = gtk_widget_get_style_context (self->priv->owner);
|
||||
|
||||
gtk_icon_helper_ensure_surface (self, context);
|
||||
gtk_icon_helper_ensure_surface (self);
|
||||
|
||||
if (self->priv->rendered_surface != NULL)
|
||||
{
|
||||
gtk_render_icon_surface (context, cr,
|
||||
self->priv->rendered_surface,
|
||||
x, y);
|
||||
gtk_css_style_render_icon_surface (gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))),
|
||||
cr,
|
||||
self->priv->rendered_surface,
|
||||
x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,7 +900,7 @@ _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self,
|
||||
if (self->priv->force_scale_pixbuf != force_scale)
|
||||
{
|
||||
self->priv->force_scale_pixbuf = force_scale;
|
||||
_gtk_icon_helper_invalidate (self);
|
||||
gtk_icon_helper_invalidate (self);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,11 +23,12 @@
|
||||
#include "gtk/gtkimage.h"
|
||||
#include "gtk/gtktypes.h"
|
||||
|
||||
#include "gtkcssgadgetprivate.h"
|
||||
#include "gtkimagedefinitionprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_ICON_HELPER _gtk_icon_helper_get_type()
|
||||
#define GTK_TYPE_ICON_HELPER gtk_icon_helper_get_type()
|
||||
|
||||
#define GTK_ICON_HELPER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
@@ -55,22 +56,24 @@ typedef struct _GtkIconHelperPrivate GtkIconHelperPrivate;
|
||||
|
||||
struct _GtkIconHelper
|
||||
{
|
||||
GObject parent;
|
||||
GtkCssGadget parent;
|
||||
|
||||
GtkIconHelperPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkIconHelperClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
GtkCssGadgetClass parent_class;
|
||||
};
|
||||
|
||||
GType _gtk_icon_helper_get_type (void) G_GNUC_CONST;
|
||||
GType gtk_icon_helper_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkIconHelper *_gtk_icon_helper_new (GtkWidget *owner);
|
||||
GtkIconHelper *gtk_icon_helper_new (GtkCssNode *node,
|
||||
GtkWidget *owner);
|
||||
GtkCssGadget *gtk_icon_helper_new_named (const char *name,
|
||||
GtkWidget *owner);
|
||||
|
||||
void _gtk_icon_helper_clear (GtkIconHelper *self);
|
||||
void _gtk_icon_helper_invalidate (GtkIconHelper *self);
|
||||
|
||||
gboolean _gtk_icon_helper_get_is_empty (GtkIconHelper *self);
|
||||
|
||||
|
||||
+126
-117
@@ -42,6 +42,7 @@
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkcsscustomgadgetprivate.h"
|
||||
|
||||
#include "a11y/gtkimageaccessible.h"
|
||||
|
||||
@@ -144,6 +145,8 @@ struct _GtkImagePrivate
|
||||
GdkPixbufAnimationIter *animation_iter;
|
||||
gint animation_timeout;
|
||||
|
||||
GtkCssGadget *gadget;
|
||||
|
||||
float baseline_align;
|
||||
|
||||
gchar *filename; /* Only used with GTK_IMAGE_ANIMATION, GTK_IMAGE_PIXBUF */
|
||||
@@ -171,9 +174,23 @@ static void gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *wi
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline);
|
||||
|
||||
static void gtk_image_get_content_size (GtkCssGadget *gadget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer unused);
|
||||
static gboolean gtk_image_render_contents (GtkCssGadget *gadget,
|
||||
cairo_t *cr,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data);
|
||||
|
||||
static void gtk_image_style_updated (GtkWidget *widget);
|
||||
static void gtk_image_screen_changed (GtkWidget *widget,
|
||||
GdkScreen *prev_screen);
|
||||
static void gtk_image_finalize (GObject *object);
|
||||
static void gtk_image_reset (GtkImage *image);
|
||||
|
||||
@@ -186,8 +203,6 @@ static void gtk_image_get_property (GObject *object,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void icon_theme_changed (GtkImage *image);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
@@ -234,7 +249,6 @@ gtk_image_class_init (GtkImageClass *class)
|
||||
widget_class->unmap = gtk_image_unmap;
|
||||
widget_class->unrealize = gtk_image_unrealize;
|
||||
widget_class->style_updated = gtk_image_style_updated;
|
||||
widget_class->screen_changed = gtk_image_screen_changed;
|
||||
|
||||
image_props[PROP_PIXBUF] =
|
||||
g_param_spec_object ("pixbuf",
|
||||
@@ -395,13 +409,24 @@ static void
|
||||
gtk_image_init (GtkImage *image)
|
||||
{
|
||||
GtkImagePrivate *priv;
|
||||
GtkCssNode *widget_node;
|
||||
|
||||
image->priv = gtk_image_get_instance_private (image);
|
||||
priv = image->priv;
|
||||
|
||||
widget_node = gtk_widget_get_css_node (GTK_WIDGET (image));
|
||||
gtk_widget_set_has_window (GTK_WIDGET (image), FALSE);
|
||||
priv->icon_helper = _gtk_icon_helper_new (GTK_WIDGET (image));
|
||||
|
||||
priv->icon_helper = gtk_icon_helper_new (widget_node, GTK_WIDGET (image));
|
||||
_gtk_icon_helper_set_icon_size (priv->icon_helper, DEFAULT_ICON_SIZE);
|
||||
|
||||
priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
|
||||
GTK_WIDGET (image),
|
||||
gtk_image_get_content_size,
|
||||
NULL,
|
||||
gtk_image_render_contents,
|
||||
NULL, NULL);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -410,14 +435,15 @@ gtk_image_finalize (GObject *object)
|
||||
GtkImage *image = GTK_IMAGE (object);
|
||||
|
||||
g_clear_object (&image->priv->icon_helper);
|
||||
|
||||
g_clear_object (&image->priv->gadget);
|
||||
|
||||
g_free (image->priv->filename);
|
||||
g_free (image->priv->resource_path);
|
||||
|
||||
G_OBJECT_CLASS (gtk_image_parent_class)->finalize (object);
|
||||
};
|
||||
|
||||
static void
|
||||
static void
|
||||
gtk_image_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
@@ -1531,20 +1557,24 @@ gtk_image_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
GtkAllocation clip;
|
||||
GdkRectangle extents;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_image_parent_class)->size_allocate (widget, allocation);
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
gtk_css_gadget_allocate (GTK_IMAGE (widget)->priv->gadget,
|
||||
allocation,
|
||||
gtk_widget_get_allocated_baseline (widget),
|
||||
&clip);
|
||||
|
||||
/* XXX: This is not strictly correct, we could compute the area
|
||||
* actually occupied by the image, but I'm lazy...
|
||||
*/
|
||||
_gtk_style_context_get_icon_extents (gtk_widget_get_style_context (widget),
|
||||
&clip,
|
||||
&extents,
|
||||
allocation->x,
|
||||
allocation->y,
|
||||
allocation->width,
|
||||
allocation->height);
|
||||
|
||||
_gtk_widget_set_simple_clip (widget, &clip);
|
||||
gdk_rectangle_union (&clip, &extents, &clip);
|
||||
|
||||
gtk_widget_set_clip (widget, &clip);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1615,29 +1645,6 @@ get_animation_frame (GtkImage *image)
|
||||
return g_object_ref (gdk_pixbuf_animation_iter_get_pixbuf (priv->animation_iter));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_image_get_preferred_size (GtkImage *image,
|
||||
gint *width_out,
|
||||
gint *height_out)
|
||||
{
|
||||
GtkImagePrivate *priv = image->priv;
|
||||
gint width, height;
|
||||
GtkBorder border;
|
||||
|
||||
_gtk_icon_helper_get_size (priv->icon_helper, &width, &height);
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
_gtk_misc_get_padding_and_border (GTK_MISC (image), &border);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
width += border.left + border.right;
|
||||
height += border.top + border.bottom;
|
||||
|
||||
if (width_out)
|
||||
*width_out = width;
|
||||
if (height_out)
|
||||
*height_out = height;
|
||||
}
|
||||
|
||||
static float
|
||||
gtk_image_get_baseline_align (GtkImage *image)
|
||||
{
|
||||
@@ -1660,62 +1667,96 @@ gtk_image_get_baseline_align (GtkImage *image)
|
||||
return image->priv->baseline_align;
|
||||
}
|
||||
|
||||
static gint
|
||||
static void
|
||||
gtk_image_get_content_size (GtkCssGadget *gadget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
gint width, height;
|
||||
float baseline_align;
|
||||
|
||||
widget = gtk_css_gadget_get_owner (gadget);
|
||||
|
||||
_gtk_icon_helper_get_size (GTK_IMAGE (widget)->priv->icon_helper,
|
||||
&width, &height);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
*minimum = *natural = width;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseline_align = gtk_image_get_baseline_align (GTK_IMAGE (widget));
|
||||
*minimum = *natural = height;
|
||||
*minimum_baseline = *natural_baseline = height * baseline_align;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_image_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
gtk_css_gadget_draw (GTK_IMAGE (widget)->priv->gadget,
|
||||
cr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_image_render_contents (GtkCssGadget *gadget,
|
||||
cairo_t *cr,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkImage *image;
|
||||
GtkImagePrivate *priv;
|
||||
GtkStyleContext *context;
|
||||
gint x, y, width, height, baseline;
|
||||
gint w, h, baseline;
|
||||
gfloat xalign, yalign;
|
||||
GtkBorder border;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_IMAGE (widget), FALSE);
|
||||
|
||||
widget = gtk_css_gadget_get_owner (gadget);
|
||||
image = GTK_IMAGE (widget);
|
||||
priv = image->priv;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_render_background (context, cr,
|
||||
0, 0,
|
||||
gtk_widget_get_allocated_width (widget), gtk_widget_get_allocated_height (widget));
|
||||
gtk_render_frame (context, cr,
|
||||
0, 0,
|
||||
gtk_widget_get_allocated_width (widget), gtk_widget_get_allocated_height (widget));
|
||||
_gtk_icon_helper_get_size (priv->icon_helper, &w, &h);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
gtk_misc_get_alignment (GTK_MISC (image), &xalign, &yalign);
|
||||
_gtk_misc_get_padding_and_border (GTK_MISC (image), &border);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
gtk_image_get_preferred_size (image, &width, &height);
|
||||
|
||||
if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
|
||||
xalign = 1.0 - xalign;
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
|
||||
x = floor ((gtk_widget_get_allocated_width (widget) - width) * xalign) + border.left;
|
||||
x += floor ((width - w) * xalign);
|
||||
if (baseline == -1)
|
||||
y = floor ((gtk_widget_get_allocated_height (widget) - height) * yalign) + border.top;
|
||||
y += floor ((height - h) * yalign);
|
||||
else
|
||||
y = CLAMP (baseline - height * gtk_image_get_baseline_align (image),
|
||||
border.top, gtk_widget_get_allocated_height (widget) - height);
|
||||
y += CLAMP (baseline - h * gtk_image_get_baseline_align (image),
|
||||
0, height - h);
|
||||
|
||||
if (gtk_image_get_storage_type (image) == GTK_IMAGE_ANIMATION)
|
||||
{
|
||||
GtkStyleContext *context = gtk_widget_get_style_context (widget);
|
||||
GdkPixbuf *pixbuf = get_animation_frame (image);
|
||||
gtk_render_icon (context, cr,
|
||||
pixbuf,
|
||||
x, y);
|
||||
|
||||
gtk_render_icon (context, cr, pixbuf, x, y);
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_icon_helper_draw (priv->icon_helper,
|
||||
cr,
|
||||
x, y);
|
||||
_gtk_icon_helper_draw (priv->icon_helper, cr, x, y);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@@ -1837,11 +1878,24 @@ gtk_image_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gint width;
|
||||
gtk_css_gadget_get_preferred_size (GTK_IMAGE (widget)->priv->gadget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
gtk_image_get_preferred_size (GTK_IMAGE (widget), &width, NULL);
|
||||
*minimum = *natural = width;
|
||||
}
|
||||
static void
|
||||
gtk_image_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gtk_css_gadget_get_preferred_size (GTK_IMAGE (widget)->priv->gadget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
@@ -1851,38 +1905,11 @@ gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline)
|
||||
{
|
||||
gint height;
|
||||
float baseline_align;
|
||||
|
||||
gtk_image_get_preferred_size (GTK_IMAGE (widget), NULL, &height);
|
||||
*minimum = *natural = height;
|
||||
|
||||
if (minimum_baseline || natural_baseline)
|
||||
{
|
||||
baseline_align = gtk_image_get_baseline_align (GTK_IMAGE (widget));
|
||||
if (minimum_baseline)
|
||||
*minimum_baseline = height * baseline_align;
|
||||
if (natural_baseline)
|
||||
*natural_baseline = height * baseline_align;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_image_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gtk_image_get_preferred_height_and_baseline_for_width (widget, -1, minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
icon_theme_changed (GtkImage *image)
|
||||
{
|
||||
GtkImagePrivate *priv = image->priv;
|
||||
|
||||
_gtk_icon_helper_invalidate (priv->icon_helper);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (image));
|
||||
gtk_css_gadget_get_preferred_size (GTK_IMAGE (widget)->priv->gadget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
width,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1890,30 +1917,12 @@ gtk_image_style_updated (GtkWidget *widget)
|
||||
{
|
||||
GtkImage *image = GTK_IMAGE (widget);
|
||||
GtkImagePrivate *priv = image->priv;
|
||||
GtkCssStyleChange *change;
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_image_parent_class)->style_updated (widget);
|
||||
|
||||
change = gtk_style_context_get_change (gtk_widget_get_style_context (widget));
|
||||
if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON))
|
||||
icon_theme_changed (image);
|
||||
priv->baseline_align = 0.0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_image_screen_changed (GtkWidget *widget,
|
||||
GdkScreen *prev_screen)
|
||||
{
|
||||
GtkImage *image;
|
||||
|
||||
image = GTK_IMAGE (widget);
|
||||
|
||||
if (GTK_WIDGET_CLASS (gtk_image_parent_class)->screen_changed)
|
||||
GTK_WIDGET_CLASS (gtk_image_parent_class)->screen_changed (widget, prev_screen);
|
||||
|
||||
icon_theme_changed (image);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_image_set_pixel_size:
|
||||
* @image: a #GtkImage
|
||||
|
||||
+4
-1
@@ -96,7 +96,7 @@ gtk_css_style_render_icon_surface (GtkCssStyle *style,
|
||||
double y)
|
||||
{
|
||||
const GtkCssValue *shadows;
|
||||
cairo_matrix_t matrix, transform_matrix;
|
||||
cairo_matrix_t matrix, transform_matrix, saved_matrix;
|
||||
GdkRectangle extents;
|
||||
|
||||
g_return_if_fail (GTK_IS_CSS_STYLE (style));
|
||||
@@ -114,6 +114,7 @@ gtk_css_style_render_icon_surface (GtkCssStyle *style,
|
||||
return;
|
||||
}
|
||||
|
||||
cairo_get_matrix (cr, &saved_matrix);
|
||||
cairo_translate (cr, x + extents.x, y + extents.y);
|
||||
|
||||
if (_gtk_css_transform_value_get_matrix (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM), &transform_matrix))
|
||||
@@ -138,5 +139,7 @@ gtk_css_style_render_icon_surface (GtkCssStyle *style,
|
||||
_gtk_css_shadows_value_paint_icon (shadows, cr);
|
||||
cairo_paint (cr);
|
||||
}
|
||||
|
||||
cairo_set_matrix (cr, &saved_matrix);
|
||||
}
|
||||
|
||||
|
||||
+47
-120
@@ -37,6 +37,8 @@
|
||||
|
||||
#include "gtkadjustment.h"
|
||||
#include "gtkbindings.h"
|
||||
#include "gtkcssgadgetprivate.h"
|
||||
#include "gtkcsscustomgadgetprivate.h"
|
||||
#include "gtkentryprivate.h"
|
||||
#include "gtkiconhelperprivate.h"
|
||||
#include "gtkicontheme.h"
|
||||
@@ -183,8 +185,8 @@ struct _GtkSpinButtonPrivate
|
||||
GdkWindow *up_panel;
|
||||
|
||||
GtkCssNode *entry_node;
|
||||
GtkCssNode *down_node;
|
||||
GtkCssNode *up_node;
|
||||
GtkCssGadget *down_button;
|
||||
GtkCssGadget *up_button;
|
||||
|
||||
GdkWindow *click_child;
|
||||
GdkWindow *in_child;
|
||||
@@ -750,21 +752,21 @@ update_node_ordering (GtkSpinButton *spin_button)
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (spin_button)) == GTK_TEXT_DIR_LTR)
|
||||
{
|
||||
first = priv->entry_node;
|
||||
middle = priv->down_node;
|
||||
last = priv->up_node;
|
||||
middle = gtk_css_gadget_get_node (priv->down_button);
|
||||
last = gtk_css_gadget_get_node (priv->up_button);
|
||||
}
|
||||
else
|
||||
{
|
||||
first = priv->up_node;
|
||||
middle = priv->down_node;
|
||||
first = gtk_css_gadget_get_node (priv->up_button);
|
||||
middle = gtk_css_gadget_get_node (priv->down_button);
|
||||
last = priv->entry_node;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
first = priv->up_node;
|
||||
first = gtk_css_gadget_get_node (priv->up_button);
|
||||
middle = priv->entry_node;
|
||||
last = priv->down_node;
|
||||
last = gtk_css_gadget_get_node (priv->down_button);
|
||||
}
|
||||
|
||||
gtk_css_node_insert_before (widget_node, first, middle);
|
||||
@@ -810,21 +812,21 @@ gtk_spin_button_init (GtkSpinButton *spin_button)
|
||||
g_signal_connect_object (priv->entry_node, "style-changed", G_CALLBACK (node_style_changed_cb), spin_button, 0);
|
||||
g_object_unref (priv->entry_node);
|
||||
|
||||
priv->down_node = gtk_css_node_new ();
|
||||
gtk_css_node_set_name (priv->down_node, I_("button"));
|
||||
gtk_css_node_set_parent (priv->down_node, widget_node);
|
||||
gtk_css_node_add_class (priv->down_node, g_quark_from_static_string ("down"));
|
||||
gtk_css_node_set_state (priv->down_node, gtk_css_node_get_state (widget_node));
|
||||
g_signal_connect_object (priv->down_node, "style-changed", G_CALLBACK (node_style_changed_cb), spin_button, 0);
|
||||
g_object_unref (priv->down_node);
|
||||
priv->down_button = gtk_icon_helper_new_named ("button",
|
||||
GTK_WIDGET (spin_button));
|
||||
_gtk_icon_helper_set_use_fallback (GTK_ICON_HELPER (priv->down_button), TRUE);
|
||||
_gtk_icon_helper_set_icon_name (GTK_ICON_HELPER (priv->down_button), "list-remove-symbolic", GTK_ICON_SIZE_MENU);
|
||||
gtk_css_gadget_add_class (priv->down_button, "down");
|
||||
gtk_css_node_set_parent (gtk_css_gadget_get_node (priv->down_button), widget_node);
|
||||
gtk_css_node_set_state (gtk_css_gadget_get_node (priv->down_button), gtk_css_node_get_state (widget_node));
|
||||
|
||||
priv->up_node = gtk_css_node_new ();
|
||||
gtk_css_node_set_name (priv->up_node, I_("button"));
|
||||
gtk_css_node_set_parent (priv->up_node, widget_node);
|
||||
gtk_css_node_add_class (priv->up_node, g_quark_from_static_string ("up"));
|
||||
gtk_css_node_set_state (priv->up_node, gtk_css_node_get_state (widget_node));
|
||||
g_signal_connect_object (priv->up_node, "style-changed", G_CALLBACK (node_style_changed_cb), spin_button, 0);
|
||||
g_object_unref (priv->up_node);
|
||||
priv->up_button = gtk_icon_helper_new_named ("button",
|
||||
GTK_WIDGET (spin_button));
|
||||
_gtk_icon_helper_set_use_fallback (GTK_ICON_HELPER (priv->up_button), TRUE);
|
||||
_gtk_icon_helper_set_icon_name (GTK_ICON_HELPER (priv->up_button), "list-add-symbolic", GTK_ICON_SIZE_MENU);
|
||||
gtk_css_gadget_add_class (priv->up_button, "up");
|
||||
gtk_css_node_set_parent (gtk_css_gadget_get_node (priv->down_button), widget_node);
|
||||
gtk_css_node_set_state (gtk_css_gadget_get_node (priv->down_button), gtk_css_node_get_state (widget_node));
|
||||
|
||||
gtk_spin_button_set_adjustment (spin_button, NULL);
|
||||
|
||||
@@ -954,46 +956,12 @@ update_node_state (GtkSpinButton *spin_button)
|
||||
{
|
||||
GtkSpinButtonPrivate *priv = spin_button->priv;
|
||||
|
||||
gtk_css_node_set_state (priv->up_node,
|
||||
gtk_css_node_set_state (gtk_css_gadget_get_node (priv->up_button),
|
||||
gtk_spin_button_panel_get_state (spin_button, UP_PANEL));
|
||||
gtk_css_node_set_state (priv->down_node,
|
||||
gtk_css_node_set_state (gtk_css_gadget_get_node (priv->down_button),
|
||||
gtk_spin_button_panel_get_state (spin_button, DOWN_PANEL));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_spin_button_panel_get_size (GtkSpinButton *spin_button,
|
||||
GdkWindow *panel,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
GtkSpinButtonPrivate *priv = spin_button->priv;
|
||||
GtkBorder button_padding, button_border;
|
||||
GtkStyleContext *context;
|
||||
gint icon_size, w, h;
|
||||
|
||||
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
|
||||
icon_size = MAX (w, h);
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (spin_button));
|
||||
if (panel == priv->up_panel)
|
||||
gtk_style_context_save_to_node (context, priv->up_node);
|
||||
else
|
||||
gtk_style_context_save_to_node (context, priv->down_node);
|
||||
|
||||
gtk_style_context_get_padding (context, gtk_style_context_get_state (context), &button_padding);
|
||||
gtk_style_context_get_border (context, gtk_style_context_get_state (context), &button_border);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
if (width)
|
||||
*width = icon_size + button_padding.left + button_padding.right +
|
||||
button_border.left + button_border.right;
|
||||
|
||||
if (height)
|
||||
*height = icon_size + button_padding.top + button_padding.bottom +
|
||||
button_border.top + button_border.bottom;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_spin_button_panel_get_allocations (GtkSpinButton *spin_button,
|
||||
GtkAllocation *down_allocation_out,
|
||||
@@ -1017,8 +985,10 @@ gtk_spin_button_panel_get_allocations (GtkSpinButton *spin_button,
|
||||
state = gtk_style_context_get_state (context);
|
||||
gtk_style_context_get_border (context, state, &border);
|
||||
|
||||
gtk_spin_button_panel_get_size (spin_button, priv->down_panel, &down_panel_width, &down_panel_height);
|
||||
gtk_spin_button_panel_get_size (spin_button, priv->up_panel, &up_panel_width, &up_panel_height);
|
||||
gtk_css_gadget_get_preferred_size (priv->down_button, GTK_ORIENTATION_HORIZONTAL, -1, &down_panel_width, NULL, NULL, NULL);
|
||||
gtk_css_gadget_get_preferred_size (priv->down_button, GTK_ORIENTATION_VERTICAL, -1, &down_panel_height, NULL, NULL, NULL);
|
||||
gtk_css_gadget_get_preferred_size (priv->up_button, GTK_ORIENTATION_HORIZONTAL, -1, &up_panel_width, NULL, NULL, NULL);
|
||||
gtk_css_gadget_get_preferred_size (priv->up_button, GTK_ORIENTATION_VERTICAL, -1, &up_panel_height, NULL, NULL, NULL);
|
||||
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
@@ -1066,57 +1036,6 @@ gtk_spin_button_panel_get_allocations (GtkSpinButton *spin_button,
|
||||
*up_allocation_out = up_allocation;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_spin_button_panel_draw (GtkSpinButton *spin_button,
|
||||
cairo_t *cr,
|
||||
GdkWindow *panel)
|
||||
{
|
||||
GtkSpinButtonPrivate *priv = spin_button->priv;
|
||||
GtkStyleContext *context;
|
||||
GtkWidget *widget;
|
||||
gdouble width, height, x, y;
|
||||
gint icon_width, icon_height;
|
||||
GtkIconHelper *icon_helper;
|
||||
|
||||
widget = GTK_WIDGET (spin_button);
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
cairo_save (cr);
|
||||
gtk_cairo_transform_to_window (cr, widget, panel);
|
||||
|
||||
height = gdk_window_get_height (panel);
|
||||
width = gdk_window_get_width (panel);
|
||||
|
||||
icon_helper = _gtk_icon_helper_new (widget);
|
||||
_gtk_icon_helper_set_use_fallback (icon_helper, TRUE);
|
||||
|
||||
if (panel == priv->down_panel)
|
||||
{
|
||||
gtk_style_context_save_to_node (context, priv->down_node);
|
||||
_gtk_icon_helper_set_icon_name (icon_helper, "list-remove-symbolic", GTK_ICON_SIZE_MENU);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_style_context_save_to_node (context, priv->up_node);
|
||||
_gtk_icon_helper_set_icon_name (icon_helper, "list-add-symbolic", GTK_ICON_SIZE_MENU);
|
||||
}
|
||||
|
||||
_gtk_icon_helper_get_size (icon_helper, &icon_width, &icon_height);
|
||||
|
||||
gtk_render_background (context, cr, 0, 0, width, height);
|
||||
gtk_render_frame (context, cr, 0, 0, width, height);
|
||||
|
||||
x = floor ((width - icon_width) / 2.0);
|
||||
y = floor ((height - icon_height) / 2.0);
|
||||
|
||||
_gtk_icon_helper_draw (icon_helper, cr, x, y);
|
||||
cairo_restore (cr);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
g_object_unref (icon_helper);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_spin_button_realize (GtkWidget *widget)
|
||||
{
|
||||
@@ -1329,8 +1248,8 @@ gtk_spin_button_get_preferred_width (GtkWidget *widget,
|
||||
gint down_panel_width;
|
||||
gint up_panel_width;
|
||||
|
||||
gtk_spin_button_panel_get_size (spin_button, priv->down_panel, &down_panel_width, NULL);
|
||||
gtk_spin_button_panel_get_size (spin_button, priv->up_panel, &up_panel_width, NULL);
|
||||
gtk_css_gadget_get_preferred_size (priv->down_button, GTK_ORIENTATION_HORIZONTAL, -1, &down_panel_width, NULL, NULL, NULL);
|
||||
gtk_css_gadget_get_preferred_size (priv->up_button, GTK_ORIENTATION_HORIZONTAL, -1, &up_panel_width, NULL, NULL, NULL);
|
||||
|
||||
*minimum += up_panel_width + down_panel_width;
|
||||
*natural += up_panel_width + down_panel_width;
|
||||
@@ -1358,8 +1277,8 @@ gtk_spin_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
|
||||
gint down_panel_height;
|
||||
gint up_panel_height;
|
||||
|
||||
gtk_spin_button_panel_get_size (spin_button, priv->down_panel, NULL, &down_panel_height);
|
||||
gtk_spin_button_panel_get_size (spin_button, priv->up_panel, NULL, &up_panel_height);
|
||||
gtk_css_gadget_get_preferred_size (priv->down_button, GTK_ORIENTATION_VERTICAL, -1, &down_panel_height, NULL, NULL, NULL);
|
||||
gtk_css_gadget_get_preferred_size (priv->up_button, GTK_ORIENTATION_VERTICAL, -1, &up_panel_height, NULL, NULL, NULL);
|
||||
|
||||
*minimum += up_panel_height + down_panel_height;
|
||||
*natural += up_panel_height + down_panel_height;
|
||||
@@ -1386,6 +1305,7 @@ gtk_spin_button_size_allocate (GtkWidget *widget,
|
||||
GtkSpinButton *spin = GTK_SPIN_BUTTON (widget);
|
||||
GtkSpinButtonPrivate *priv = spin->priv;
|
||||
GtkAllocation down_panel_allocation, up_panel_allocation;
|
||||
GtkAllocation down_clip, up_clip, clip;
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
@@ -1393,6 +1313,9 @@ gtk_spin_button_size_allocate (GtkWidget *widget,
|
||||
|
||||
gtk_spin_button_panel_get_allocations (spin, &down_panel_allocation, &up_panel_allocation);
|
||||
|
||||
gtk_css_gadget_allocate (priv->down_button, &down_panel_allocation, -1, &down_clip);
|
||||
gtk_css_gadget_allocate (priv->up_button, &up_panel_allocation, -1, &up_clip);
|
||||
|
||||
if (gtk_widget_get_realized (widget))
|
||||
{
|
||||
gdk_window_move_resize (priv->down_panel,
|
||||
@@ -1408,7 +1331,9 @@ gtk_spin_button_size_allocate (GtkWidget *widget,
|
||||
up_panel_allocation.height);
|
||||
}
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (spin));
|
||||
gdk_rectangle_union (&down_clip, &up_clip, &clip);
|
||||
|
||||
_gtk_widget_set_simple_clip (widget, &clip);
|
||||
}
|
||||
|
||||
static gint
|
||||
@@ -1421,8 +1346,8 @@ gtk_spin_button_draw (GtkWidget *widget,
|
||||
GTK_WIDGET_CLASS (gtk_spin_button_parent_class)->draw (widget, cr);
|
||||
|
||||
/* Draw the buttons */
|
||||
gtk_spin_button_panel_draw (spin, cr, priv->down_panel);
|
||||
gtk_spin_button_panel_draw (spin, cr, priv->up_panel);
|
||||
gtk_css_gadget_draw (priv->down_button, cr);
|
||||
gtk_css_gadget_draw (priv->up_button, cr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1906,8 +1831,10 @@ gtk_spin_button_get_text_area_size (GtkEntry *entry,
|
||||
|
||||
GTK_ENTRY_CLASS (gtk_spin_button_parent_class)->get_text_area_size (entry, x, y, width, height);
|
||||
|
||||
gtk_spin_button_panel_get_size (GTK_SPIN_BUTTON (entry), priv->up_panel, &up_panel_width, &up_panel_height);
|
||||
gtk_spin_button_panel_get_size (GTK_SPIN_BUTTON (entry), priv->down_panel, &down_panel_width, &down_panel_height);
|
||||
gtk_css_gadget_get_preferred_size (priv->down_button, GTK_ORIENTATION_HORIZONTAL, -1, &down_panel_width, NULL, NULL, NULL);
|
||||
gtk_css_gadget_get_preferred_size (priv->down_button, GTK_ORIENTATION_VERTICAL, -1, &down_panel_height, NULL, NULL, NULL);
|
||||
gtk_css_gadget_get_preferred_size (priv->up_button, GTK_ORIENTATION_HORIZONTAL, -1, &up_panel_width, NULL, NULL, NULL);
|
||||
gtk_css_gadget_get_preferred_size (priv->up_button, GTK_ORIENTATION_VERTICAL, -1, &up_panel_height, NULL, NULL, NULL);
|
||||
|
||||
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
|
||||
@@ -484,6 +484,12 @@ gtk_style_context_lookup_style (GtkStyleContext *context)
|
||||
return gtk_css_node_get_style (context->priv->cssnode);
|
||||
}
|
||||
|
||||
GtkCssNode*
|
||||
gtk_style_context_get_node (GtkStyleContext *context)
|
||||
{
|
||||
return context->priv->cssnode;
|
||||
}
|
||||
|
||||
static GtkStateFlags
|
||||
gtk_style_context_push_state (GtkStyleContext *context,
|
||||
GtkStateFlags state)
|
||||
|
||||
@@ -30,6 +30,7 @@ G_BEGIN_DECLS
|
||||
|
||||
GtkStyleContext *gtk_style_context_new_for_node (GtkCssNode *node);
|
||||
|
||||
GtkCssNode *gtk_style_context_get_node (GtkStyleContext *context);
|
||||
void gtk_style_context_set_id (GtkStyleContext *context,
|
||||
const char *id);
|
||||
const char * gtk_style_context_get_id (GtkStyleContext *context);
|
||||
|
||||
+166
-176
@@ -61,8 +61,8 @@
|
||||
#include "gtkactionable.h"
|
||||
#include "a11y/gtkswitchaccessible.h"
|
||||
#include "gtkactionhelper.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkcsscustomgadgetprivate.h"
|
||||
#include "gtkcssgadgetprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
@@ -81,7 +81,8 @@ struct _GtkSwitchPrivate
|
||||
GtkGesture *pan_gesture;
|
||||
GtkGesture *multipress_gesture;
|
||||
|
||||
GtkCssNode *slider_node;
|
||||
GtkCssGadget *gadget;
|
||||
GtkCssGadget *slider_gadget;
|
||||
|
||||
double handle_pos;
|
||||
gint64 start_time;
|
||||
@@ -179,7 +180,7 @@ gtk_switch_on_frame_clock_update (GtkWidget *widget,
|
||||
gtk_switch_set_active (sw, !priv->is_active);
|
||||
}
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (sw));
|
||||
gtk_widget_queue_allocate (GTK_WIDGET (sw));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
@@ -258,8 +259,6 @@ gtk_switch_pan_gesture_pan (GtkGesturePan *gesture,
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (sw);
|
||||
GtkSwitchPrivate *priv = sw->priv;
|
||||
GtkStyleContext *context;
|
||||
GtkBorder padding;
|
||||
gint width;
|
||||
|
||||
if (direction == GTK_PAN_DIRECTION_LEFT)
|
||||
@@ -267,12 +266,6 @@ gtk_switch_pan_gesture_pan (GtkGesturePan *gesture,
|
||||
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_style_context_save_to_node (context, priv->slider_node);
|
||||
gtk_style_context_get_padding (context, gtk_style_context_get_state (context), &padding);
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
width = gtk_widget_get_allocated_width (widget);
|
||||
|
||||
if (priv->is_active)
|
||||
@@ -283,7 +276,7 @@ gtk_switch_pan_gesture_pan (GtkGesturePan *gesture,
|
||||
priv->handle_pos = CLAMP (offset, 0, 1.0);
|
||||
|
||||
/* we need to redraw the handle */
|
||||
gtk_widget_queue_draw (widget);
|
||||
gtk_widget_queue_allocate (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -315,7 +308,7 @@ gtk_switch_pan_gesture_drag_end (GtkGestureDrag *gesture,
|
||||
|
||||
priv->handle_pos = active ? 1.0 : 0.0;
|
||||
gtk_switch_set_active (sw, active);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (sw));
|
||||
gtk_widget_queue_allocate (GTK_WIDGET (sw));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -357,54 +350,102 @@ gtk_switch_activate (GtkSwitch *sw)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_switch_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
gtk_switch_get_slider_size (GtkCssGadget *gadget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
|
||||
gint slider_size;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
{
|
||||
gtk_widget_style_get (widget,
|
||||
"slider-width", &slider_size,
|
||||
NULL);
|
||||
slider_size *= 0.6;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_style_get (widget,
|
||||
"slider-height", &slider_size,
|
||||
NULL);
|
||||
}
|
||||
|
||||
*minimum = slider_size;
|
||||
*natural = slider_size;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_switch_get_content_size (GtkCssGadget *gadget,
|
||||
GtkOrientation orientation,
|
||||
gint for_size,
|
||||
gint *minimum,
|
||||
gint *natural,
|
||||
gint *minimum_baseline,
|
||||
gint *natural_baseline,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkSwitch *self;
|
||||
GtkSwitchPrivate *priv;
|
||||
GtkStyleContext *context;
|
||||
GtkBorder padding;
|
||||
gint width, slider_width;
|
||||
gint slider_minimum, slider_natural;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle logical_rect;
|
||||
PangoRectangle on_rect, off_rect;
|
||||
|
||||
widget = gtk_css_gadget_get_owner (gadget);
|
||||
self = GTK_SWITCH (widget);
|
||||
priv = self->priv;
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_style_context_save_to_node (context, priv->slider_node);
|
||||
gtk_style_context_get_padding (context, gtk_style_context_get_state (context), &padding);
|
||||
|
||||
width = padding.left + padding.right;
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"slider-width", &slider_width,
|
||||
NULL);
|
||||
gtk_css_gadget_get_preferred_size (priv->slider_gadget,
|
||||
orientation,
|
||||
-1,
|
||||
&slider_minimum, &slider_natural,
|
||||
NULL, NULL);
|
||||
|
||||
/* 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_gadget_get_preferred_size (GTK_SWITCH (widget)->priv->gadget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
-1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -412,45 +453,33 @@ gtk_switch_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GtkSwitch *self;
|
||||
GtkSwitchPrivate *priv;
|
||||
GtkStyleContext *context;
|
||||
GtkBorder padding;
|
||||
gint height, slider_height;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle logical_rect;
|
||||
gchar *str;
|
||||
gtk_css_gadget_get_preferred_size (GTK_SWITCH (widget)->priv->gadget,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
-1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
self = GTK_SWITCH (widget);
|
||||
priv = self->priv;
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
static void
|
||||
gtk_switch_allocate_contents (GtkCssGadget *gadget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkSwitch *self = GTK_SWITCH (gtk_css_gadget_get_owner (gadget));
|
||||
GtkSwitchPrivate *priv = self->priv;
|
||||
GtkAllocation slider_alloc;
|
||||
|
||||
slider_alloc.x = allocation->x + round (priv->handle_pos * (allocation->width - allocation->width / 2));
|
||||
slider_alloc.y = allocation->y;
|
||||
slider_alloc.width = allocation->width / 2;
|
||||
slider_alloc.height = allocation->height;
|
||||
|
||||
gtk_style_context_save_to_node (context, priv->slider_node);
|
||||
|
||||
gtk_style_context_get_padding (context, gtk_style_context_get_state (context), &padding);
|
||||
|
||||
height = padding.top + padding.bottom;
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"slider-height", &slider_height,
|
||||
NULL);
|
||||
|
||||
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 (slider_height, logical_rect.height);
|
||||
|
||||
g_object_unref (layout);
|
||||
g_free (str);
|
||||
|
||||
*minimum = height;
|
||||
*natural = height;
|
||||
gtk_css_gadget_allocate (priv->slider_gadget,
|
||||
&slider_alloc,
|
||||
baseline,
|
||||
out_clip);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -458,8 +487,6 @@ gtk_switch_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv;
|
||||
GtkStyleContext *context;
|
||||
GtkBorder extents;
|
||||
GtkAllocation clip;
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
@@ -471,23 +498,12 @@ gtk_switch_size_allocate (GtkWidget *widget,
|
||||
allocation->width,
|
||||
allocation->height);
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_style_context_save_to_node (context, priv->slider_node);
|
||||
|
||||
_gtk_css_shadows_value_get_extents (_gtk_style_context_peek_property (context,
|
||||
GTK_CSS_PROPERTY_BOX_SHADOW),
|
||||
&extents);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
clip = *allocation;
|
||||
clip.x -= extents.left;
|
||||
clip.y -= extents.top;
|
||||
clip.width += extents.left + extents.right;
|
||||
clip.height += extents.top + extents.bottom;
|
||||
|
||||
_gtk_widget_set_simple_clip (widget, &clip);
|
||||
gtk_css_gadget_allocate (priv->gadget,
|
||||
allocation,
|
||||
gtk_widget_get_allocated_baseline (widget),
|
||||
&clip);
|
||||
|
||||
gtk_widget_set_clip (widget, &clip);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -564,61 +580,33 @@ gtk_switch_unmap (GtkWidget *widget)
|
||||
GTK_WIDGET_CLASS (gtk_switch_parent_class)->unmap (widget);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gtk_switch_paint_handle (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
GdkRectangle *box)
|
||||
static gboolean
|
||||
gtk_switch_render_slider (GtkCssGadget *gadget,
|
||||
cairo_t *cr,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data)
|
||||
{
|
||||
GtkStyleContext *context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_style_context_save_to_node (context, GTK_SWITCH (widget)->priv->slider_node);
|
||||
|
||||
gtk_render_slider (context, cr,
|
||||
box->x, box->y,
|
||||
box->width, box->height,
|
||||
GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
return gtk_widget_has_visible_focus (gtk_css_gadget_get_owner (gadget));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_switch_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
gtk_switch_render_trough (GtkCssGadget *gadget,
|
||||
cairo_t *cr,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
|
||||
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;
|
||||
gint x, y, width, height;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_style_context_save_to_node (context, priv->slider_node);
|
||||
|
||||
gtk_style_context_get_padding (context, gtk_style_context_get_state (context), &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;
|
||||
|
||||
/* Translators: if the "on" state label requires more than three
|
||||
* glyphs then use MEDIUM VERTICAL BAR (U+2759) as the text for
|
||||
@@ -626,11 +614,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);
|
||||
|
||||
@@ -641,26 +628,25 @@ 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);
|
||||
gtk_css_gadget_draw (priv->slider_gadget, cr);
|
||||
|
||||
gtk_switch_paint_handle (widget, cr, &handle);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gtk_widget_has_visible_focus (widget))
|
||||
{
|
||||
gtk_render_focus (context, cr,
|
||||
handle.x, handle.y,
|
||||
handle.width, handle.height);
|
||||
}
|
||||
static gboolean
|
||||
gtk_switch_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
gtk_css_gadget_draw (GTK_SWITCH (widget)->priv->gadget, cr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -839,6 +825,9 @@ gtk_switch_dispose (GObject *object)
|
||||
priv->action = NULL;
|
||||
}
|
||||
|
||||
g_clear_object (&priv->gadget);
|
||||
g_clear_object (&priv->slider_gadget);
|
||||
|
||||
g_clear_object (&priv->pan_gesture);
|
||||
g_clear_object (&priv->multipress_gesture);
|
||||
|
||||
@@ -869,17 +858,6 @@ state_set (GtkSwitch *sw, gboolean state)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
node_style_changed_cb (GtkCssNode *node,
|
||||
GtkCssStyleChange *change,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_CLIP))
|
||||
gtk_widget_queue_resize (widget);
|
||||
else
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_switch_class_init (GtkSwitchClass *klass)
|
||||
{
|
||||
@@ -1052,12 +1030,24 @@ gtk_switch_init (GtkSwitch *self)
|
||||
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_name (priv->slider_node, I_("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 (node_style_changed_cb), self, 0);
|
||||
g_object_unref (priv->slider_node);
|
||||
priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
|
||||
GTK_WIDGET (self),
|
||||
gtk_switch_get_content_size,
|
||||
gtk_switch_allocate_contents,
|
||||
gtk_switch_render_trough,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
priv->slider_gadget = gtk_css_custom_gadget_new ("slider",
|
||||
GTK_WIDGET (self),
|
||||
priv->gadget,
|
||||
NULL,
|
||||
gtk_switch_get_slider_size,
|
||||
NULL,
|
||||
gtk_switch_render_slider,
|
||||
NULL,
|
||||
NULL);
|
||||
gtk_css_gadget_add_class (priv->slider_gadget, GTK_STYLE_CLASS_SLIDER);
|
||||
|
||||
gesture = gtk_gesture_multi_press_new (GTK_WIDGET (self));
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture), FALSE);
|
||||
@@ -1140,7 +1130,7 @@ gtk_switch_set_active (GtkSwitch *sw,
|
||||
accessible = gtk_widget_get_accessible (GTK_WIDGET (sw));
|
||||
atk_object_notify_state_change (accessible, ATK_STATE_CHECKED, priv->is_active);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (sw));
|
||||
gtk_widget_queue_allocate (GTK_WIDGET (sw));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-16
@@ -3482,6 +3482,22 @@ gtk_tree_view_column_drag_gesture_begin (GtkGestureDrag *gesture,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_update_button_position (GtkTreeView *tree_view,
|
||||
GtkTreeViewColumn *column)
|
||||
{
|
||||
GtkTreeViewPrivate *priv = tree_view->priv;
|
||||
GList *column_el;
|
||||
|
||||
column_el = g_list_find (priv->columns, column);
|
||||
g_return_if_fail (column_el != NULL);
|
||||
|
||||
gtk_css_node_insert_after (priv->header_node,
|
||||
gtk_widget_get_css_node (gtk_tree_view_column_get_button (column)),
|
||||
column_el->prev ? gtk_widget_get_css_node (
|
||||
gtk_tree_view_column_get_button (column_el->prev->data)) : NULL);
|
||||
}
|
||||
|
||||
/* column drag gesture helper */
|
||||
static gboolean
|
||||
gtk_tree_view_button_release_drag_column (GtkTreeView *tree_view)
|
||||
@@ -3502,6 +3518,7 @@ gtk_tree_view_button_release_drag_column (GtkTreeView *tree_view)
|
||||
g_object_ref (button);
|
||||
gtk_container_remove (GTK_CONTAINER (tree_view), button);
|
||||
gtk_widget_set_parent_window (button, tree_view->priv->header_window);
|
||||
gtk_tree_view_update_button_position (tree_view, tree_view->priv->drag_column);
|
||||
gtk_widget_set_parent (button, GTK_WIDGET (tree_view));
|
||||
g_object_unref (button);
|
||||
gtk_widget_queue_resize (widget);
|
||||
@@ -12025,22 +12042,6 @@ gtk_tree_view_remove_column (GtkTreeView *tree_view,
|
||||
return tree_view->priv->n_columns;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_update_button_position (GtkTreeView *tree_view,
|
||||
GtkTreeViewColumn *column)
|
||||
{
|
||||
GtkTreeViewPrivate *priv = tree_view->priv;
|
||||
GList *column_el;
|
||||
|
||||
column_el = g_list_find (priv->columns, column);
|
||||
g_return_if_fail (column_el != NULL);
|
||||
|
||||
gtk_css_node_insert_after (priv->header_node,
|
||||
gtk_widget_get_css_node (gtk_tree_view_column_get_button (column)),
|
||||
column_el->prev ? gtk_widget_get_css_node (
|
||||
gtk_tree_view_column_get_button (column_el->prev->data)) : NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_tree_view_insert_column:
|
||||
* @tree_view: A #GtkTreeView.
|
||||
|
||||
+6
-23
@@ -15629,21 +15629,6 @@ gtk_widget_set_clip (GtkWidget *widget,
|
||||
priv->clip = *clip;
|
||||
}
|
||||
|
||||
static void
|
||||
union_with_clip (GtkWidget *widget,
|
||||
gpointer clip)
|
||||
{
|
||||
GtkAllocation widget_clip;
|
||||
|
||||
if (!gtk_widget_is_visible (widget) ||
|
||||
!_gtk_widget_get_child_visible (widget))
|
||||
return;
|
||||
|
||||
gtk_widget_get_clip (widget, &widget_clip);
|
||||
|
||||
gdk_rectangle_union (&widget_clip, clip, clip);
|
||||
}
|
||||
|
||||
/*
|
||||
* _gtk_widget_set_simple_clip:
|
||||
* @widget: a #GtkWidget
|
||||
@@ -15690,19 +15675,17 @@ _gtk_widget_set_simple_clip (GtkWidget *widget,
|
||||
|
||||
if (GTK_IS_CONTAINER (widget))
|
||||
{
|
||||
if (_gtk_widget_get_has_window (widget))
|
||||
{
|
||||
clip.x -= allocation.x;
|
||||
clip.y -= allocation.y;
|
||||
}
|
||||
GdkRectangle children_clip;
|
||||
|
||||
gtk_container_forall (GTK_CONTAINER (widget), union_with_clip, &clip);
|
||||
gtk_container_get_children_clip (GTK_CONTAINER (widget), &children_clip);
|
||||
|
||||
if (_gtk_widget_get_has_window (widget))
|
||||
{
|
||||
clip.x += allocation.x;
|
||||
clip.y += allocation.y;
|
||||
children_clip.x += allocation.x;
|
||||
children_clip.y += allocation.y;
|
||||
}
|
||||
|
||||
gdk_rectangle_union (&children_clip, &clip, &clip);
|
||||
}
|
||||
|
||||
gtk_widget_set_clip (widget, &clip);
|
||||
|
||||
Reference in New Issue
Block a user