[gtk+] colorswatch: Convert to gadgets
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] colorswatch: Convert to gadgets
- Date: Tue, 15 Dec 2015 13:43:55 +0000 (UTC)
commit c376e82702170ce188271b6b518ebb46495f56ad
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Dec 14 16:10:28 2015 -0500
colorswatch: Convert to gadgets
Use gadgets for the widget and the overlay.
gtk/gtkcolorswatch.c | 302 +++++++++++++++++++++++++++++++++-----------------
1 files changed, 198 insertions(+), 104 deletions(-)
---
diff --git a/gtk/gtkcolorswatch.c b/gtk/gtkcolorswatch.c
index 5e36d08..72526bf 100644
--- a/gtk/gtkcolorswatch.c
+++ b/gtk/gtkcolorswatch.c
@@ -30,6 +30,7 @@
#include "gtkintl.h"
#include "gtkrenderprivate.h"
#include "gtkcssnodeprivate.h"
+#include "gtkcsscustomgadgetprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkstylecontextprivate.h"
#include "a11y/gtkcolorswatchaccessibleprivate.h"
@@ -59,7 +60,8 @@ struct _GtkColorSwatchPrivate
GtkGesture *long_press_gesture;
GtkGesture *multipress_gesture;
- GtkCssNode *overlay_node;
+ GtkCssGadget *gadget;
+ GtkCssGadget *overlay_gadget;
GtkWidget *popover;
};
@@ -81,85 +83,44 @@ enum
static guint signals[LAST_SIGNAL];
-static void hold_action (GtkGestureLongPress *gesture,
- gdouble x,
- gdouble y,
- GtkColorSwatch *swatch);
-static void tap_action (GtkGestureMultiPress *gesture,
- gint n_press,
- gdouble x,
- gdouble y,
- GtkColorSwatch *swatch);
G_DEFINE_TYPE_WITH_PRIVATE (GtkColorSwatch, gtk_color_swatch, GTK_TYPE_WIDGET)
-static void
-gtk_color_swatch_init (GtkColorSwatch *swatch)
+static gboolean
+swatch_draw (GtkWidget *widget,
+ cairo_t *cr)
{
- GtkCssNode *widget_node;
- GtkStyleContext *context;
-
- swatch->priv = gtk_color_swatch_get_instance_private (swatch);
- swatch->priv->use_alpha = TRUE;
- swatch->priv->selectable = TRUE;
- swatch->priv->has_menu = TRUE;
-
- gtk_widget_set_can_focus (GTK_WIDGET (swatch), TRUE);
- gtk_widget_set_has_window (GTK_WIDGET (swatch), FALSE);
+ gtk_css_gadget_draw (GTK_COLOR_SWATCH (widget)->priv->gadget, cr);
- swatch->priv->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (swatch));
- gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (swatch->priv->long_press_gesture),
- TRUE);
- g_signal_connect (swatch->priv->long_press_gesture, "pressed",
- G_CALLBACK (hold_action), swatch);
-
- swatch->priv->multipress_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (swatch));
- gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (swatch->priv->multipress_gesture), 0);
- g_signal_connect (swatch->priv->multipress_gesture, "pressed",
- G_CALLBACK (tap_action), swatch);
-
- widget_node = gtk_widget_get_css_node (GTK_WIDGET (swatch));
- swatch->priv->overlay_node = gtk_css_node_new ();
- gtk_css_node_set_name (swatch->priv->overlay_node, I_("overlay"));
- gtk_css_node_set_parent (swatch->priv->overlay_node, widget_node);
- gtk_css_node_set_state (swatch->priv->overlay_node, gtk_css_node_get_state (widget_node));
- g_object_unref (swatch->priv->overlay_node);
-
- context = gtk_widget_get_style_context (GTK_WIDGET (swatch));
- gtk_style_context_add_class (context, "activatable");
+ return FALSE;
}
#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
#define PIXBUF_SIZE 16
static gboolean
-swatch_draw (GtkWidget *widget,
- cairo_t *cr)
-{
- GtkColorSwatch *swatch = (GtkColorSwatch*)widget;
- gdouble width, height;
+gtk_color_swatch_render (GtkCssGadget *gadget,
+ cairo_t *cr,
+ int x,
+ int y,
+ int width,
+ int height,
+ gpointer data)
+{
+ GtkWidget *widget;
+ GtkColorSwatch *swatch;
GtkStyleContext *context;
- GtkStateFlags state;
- GtkIconTheme *theme;
- GtkBorder border, padding;
- GdkRectangle rect;
- GtkIconInfo *icon_info = NULL;
- gint scale;
- theme = gtk_icon_theme_get_default ();
+ widget = gtk_css_gadget_get_owner (gadget);
+ swatch = GTK_COLOR_SWATCH (widget);
context = gtk_widget_get_style_context (widget);
- state = gtk_style_context_get_state (context);
- width = gtk_widget_get_allocated_width (widget);
- height = gtk_widget_get_allocated_height (widget);
-
- gtk_render_background (context, cr, 0, 0, width, height);
if (swatch->priv->has_color)
{
cairo_pattern_t *pattern;
cairo_matrix_t matrix;
- gtk_render_content_path (context, cr, 0, 0, width, height);
+ gtk_render_content_path (context, cr, x, y, width, height);
if (swatch->priv->use_alpha)
{
@@ -193,7 +154,36 @@ swatch_draw (GtkWidget *widget,
cairo_fill (cr);
}
- gtk_render_frame (context, cr, 0, 0, width, height);
+ gtk_render_frame (context, cr, x, y, width, height);
+
+ gtk_css_gadget_draw (swatch->priv->overlay_gadget, cr);
+
+ return gtk_widget_has_visible_focus (widget);
+}
+
+static gboolean
+gtk_color_swatch_render_overlay (GtkCssGadget *gadget,
+ cairo_t *cr,
+ int x,
+ int y,
+ int width,
+ int height,
+ gpointer data)
+{
+ GtkWidget *widget;
+ GtkColorSwatch *swatch;
+ GtkStyleContext *context;
+ GtkStateFlags state;
+ GtkIconTheme *theme;
+ GtkIconInfo *icon_info = NULL;
+ gint scale;
+
+ widget = gtk_css_gadget_get_owner (gadget);
+ swatch = GTK_COLOR_SWATCH (widget);
+
+ theme = gtk_icon_theme_get_default ();
+ context = gtk_widget_get_style_context (widget);
+ state = gtk_style_context_get_state (context);
scale = gtk_widget_get_scale_factor (widget);
if (swatch->priv->icon)
@@ -218,18 +208,6 @@ swatch_draw (GtkWidget *widget,
}
/* now draw the overlay image */
- gtk_style_context_get_border (context, state, &border);
- gtk_style_context_get_padding (context, state, &padding);
- rect.width = width - (border.left + border.right + padding.left + padding.right);
- rect.height = height - (border.top + border.bottom + padding.top + padding.bottom);
- rect.x = border.left + padding.left;
- rect.y = border.top + padding.top;
-
- gtk_style_context_save_to_node (context, swatch->priv->overlay_node);
-
- gtk_render_background (context, cr, rect.x, rect.y, rect.width, rect.height);
- gtk_render_frame (context, cr, rect.x, rect.y, rect.width, rect.height);
-
if (icon_info != NULL)
{
GdkPixbuf *pixbuf;
@@ -240,9 +218,7 @@ swatch_draw (GtkWidget *widget,
cairo_surface_t *surface;
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, gtk_widget_get_window (widget));
- gtk_render_icon_surface (context, cr, surface,
- rect.x + (rect.width - (gdk_pixbuf_get_width (pixbuf) / scale)) / 2,
- rect.y + (rect.height - (gdk_pixbuf_get_height (pixbuf) / scale)) / 2);
+ gtk_render_icon_surface (context, cr, surface, x, y);
cairo_surface_destroy (surface);
g_object_unref (pixbuf);
}
@@ -250,11 +226,6 @@ swatch_draw (GtkWidget *widget,
g_object_unref (icon_info);
}
- if (gtk_widget_has_visible_focus (widget))
- gtk_render_focus (context, cr, 0, 0, width, height);
-
- gtk_style_context_restore (context);
-
return FALSE;
}
@@ -349,33 +320,49 @@ swatch_drag_data_received (GtkWidget *widget,
}
static void
-swatch_get_preferred_width (GtkWidget *widget,
- gint *min,
- gint *nat)
-{
- gint w, h;
+gtk_color_swatch_measure (GtkCssGadget *gadget,
+ GtkOrientation orientation,
+ int for_size,
+ int *minimum,
+ int *natural,
+ int *minimum_baseline,
+ int *natural_baseline,
+ gpointer unused)
+{
+ GtkWidget *widget;
+ GtkColorSwatch *swatch;
+ gint w, h, min;
+
+ widget = gtk_css_gadget_get_owner (gadget);
+ swatch = GTK_COLOR_SWATCH (widget);
+
+ gtk_css_gadget_get_preferred_size (swatch->priv->overlay_gadget,
+ orientation,
+ -1,
+ minimum, natural,
+ NULL, NULL);
gtk_widget_get_size_request (widget, &w, &h);
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ min = w < 0 ? 48 : w;
+ else
+ min = h < 0 ? 32 : h;
- if (w < 0)
- w = 48;
-
- *min = *nat = w;
+ *minimum = MAX (*minimum, min);
+ *natural = MAX (*natural, min);
}
static void
-swatch_get_preferred_height (GtkWidget *widget,
- gint *min,
- gint *nat)
+gtk_color_swatch_measure_overlay (GtkCssGadget *gadget,
+ GtkOrientation orientation,
+ int for_size,
+ int *minimum,
+ int *natural,
+ int *minimum_baseline,
+ int *natural_baseline,
+ gpointer unused)
{
- gint w, h;
-
- gtk_widget_get_size_request (widget, &w, &h);
-
- if (h < 0)
- h = 32;
-
- *min = *nat = h;
+ *minimum = *natural = 16;
}
static gboolean
@@ -563,9 +550,7 @@ swatch_realize (GtkWidget *widget)
gtk_widget_set_window (widget, window);
g_object_ref (window);
- swatch->priv->event_window =
- gdk_window_new (window,
- &attributes, attributes_mask);
+ swatch->priv->event_window = gdk_window_new (window, &attributes, attributes_mask);
gtk_widget_register_window (widget, swatch->priv->event_window);
}
@@ -589,6 +574,7 @@ swatch_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget);
+ GtkAllocation clip;
gtk_widget_set_allocation (widget, allocation);
@@ -599,7 +585,68 @@ swatch_size_allocate (GtkWidget *widget,
allocation->width,
allocation->height);
- _gtk_widget_set_simple_clip (widget, NULL);
+ gtk_css_gadget_allocate (swatch->priv->gadget,
+ allocation,
+ gtk_widget_get_allocated_baseline (widget),
+ &clip);
+
+ gtk_widget_set_clip (widget, &clip);
+}
+
+static void
+gtk_color_swatch_allocate (GtkCssGadget *gadget,
+ const GtkAllocation *allocation,
+ int baseline,
+ GtkAllocation *out_clip,
+ gpointer unused)
+{
+ GtkColorSwatch *swatch;
+ GtkAllocation overlay_alloc;
+ gint overlay_width, overlay_height;
+
+ swatch = GTK_COLOR_SWATCH (gtk_css_gadget_get_owner (gadget));
+
+ gtk_css_gadget_get_preferred_size (swatch->priv->overlay_gadget,
+ GTK_ORIENTATION_HORIZONTAL,
+ -1,
+ &overlay_width, NULL,
+ NULL, NULL);
+ gtk_css_gadget_get_preferred_size (swatch->priv->overlay_gadget,
+ GTK_ORIENTATION_VERTICAL,
+ -1,
+ &overlay_height, NULL,
+ NULL, NULL);
+
+ overlay_alloc.x = allocation->x + (allocation->width - overlay_width) / 2;
+ overlay_alloc.y = allocation->y + (allocation->height - overlay_height) / 2;
+ overlay_alloc.width = overlay_width;
+ overlay_alloc.height = overlay_height;
+
+ gtk_css_gadget_allocate (swatch->priv->overlay_gadget, &overlay_alloc, baseline, out_clip);
+}
+
+static void
+swatch_get_preferred_width (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ gtk_css_gadget_get_preferred_size (GTK_COLOR_SWATCH (widget)->priv->gadget,
+ GTK_ORIENTATION_HORIZONTAL,
+ -1,
+ minimum, natural,
+ NULL, NULL);
+}
+
+static void
+swatch_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ gtk_css_gadget_get_preferred_size (GTK_COLOR_SWATCH (widget)->priv->gadget,
+ GTK_ORIENTATION_VERTICAL,
+ -1,
+ minimum, natural,
+ NULL, NULL);
}
static gboolean
@@ -615,7 +662,8 @@ swatch_state_flags_changed (GtkWidget *widget,
{
GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget);
- gtk_css_node_set_state (swatch->priv->overlay_node, gtk_widget_get_state_flags (widget));
+ gtk_css_node_set_state (gtk_css_gadget_get_node (swatch->priv->gadget), gtk_widget_get_state_flags
(widget));
+ gtk_css_node_set_state (gtk_css_gadget_get_node (swatch->priv->overlay_gadget), gtk_widget_get_state_flags
(widget));
GTK_WIDGET_CLASS (gtk_color_swatch_parent_class)->state_flags_changed (widget, previous_state);
}
@@ -680,6 +728,8 @@ swatch_finalize (GObject *object)
GtkColorSwatch *swatch = GTK_COLOR_SWATCH (object);
g_free (swatch->priv->icon);
+ g_clear_object (&swatch->priv->gadget);
+ g_clear_object (&swatch->priv->overlay_gadget);
G_OBJECT_CLASS (gtk_color_swatch_parent_class)->finalize (object);
}
@@ -757,6 +807,50 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
gtk_widget_class_set_css_name (widget_class, "colorswatch");
}
+static void
+gtk_color_swatch_init (GtkColorSwatch *swatch)
+{
+ GtkCssNode *widget_node;
+
+ swatch->priv = gtk_color_swatch_get_instance_private (swatch);
+ swatch->priv->use_alpha = TRUE;
+ swatch->priv->selectable = TRUE;
+ swatch->priv->has_menu = TRUE;
+
+ gtk_widget_set_can_focus (GTK_WIDGET (swatch), TRUE);
+ gtk_widget_set_has_window (GTK_WIDGET (swatch), FALSE);
+
+ swatch->priv->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (swatch));
+ gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (swatch->priv->long_press_gesture),
+ TRUE);
+ g_signal_connect (swatch->priv->long_press_gesture, "pressed",
+ G_CALLBACK (hold_action), swatch);
+
+ swatch->priv->multipress_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (swatch));
+ gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (swatch->priv->multipress_gesture), 0);
+ g_signal_connect (swatch->priv->multipress_gesture, "pressed",
+ G_CALLBACK (tap_action), swatch);
+
+ widget_node = gtk_widget_get_css_node (GTK_WIDGET (swatch));
+ swatch->priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
+ GTK_WIDGET (swatch),
+ gtk_color_swatch_measure,
+ gtk_color_swatch_allocate,
+ gtk_color_swatch_render,
+ NULL,
+ NULL);
+
+ swatch->priv->overlay_gadget = gtk_css_custom_gadget_new ("overlay",
+ GTK_WIDGET (swatch),
+ swatch->priv->gadget,
+ NULL,
+ gtk_color_swatch_measure_overlay,
+ NULL,
+ gtk_color_swatch_render_overlay,
+ NULL,
+ NULL);
+ gtk_css_gadget_add_class (swatch->priv->gadget, "activatable");
+}
/* Public API {{{1 */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]