[gtk+/wip/matthiasc/gadget: 3/16] colorswatch: Convert to gadgets
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/matthiasc/gadget: 3/16] colorswatch: Convert to gadgets
- Date: Mon, 7 Dec 2015 16:07:08 +0000 (UTC)
commit 6253214f59a910581d5f4cf32674e6eab253cc98
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Dec 2 13:47:02 2015 -0500
colorswatch: Convert to gadgets
Use gadgets for the widget and the overlay. The Adwaita
adjustments in this patch are very provisional and need
more work.
gtk/gtkcolorswatch.c | 294 ++++++++++++++++++++----------
gtk/theme/Adwaita/_common.scss | 16 +-
gtk/theme/Adwaita/gtk-contained-dark.css | 25 ++-
gtk/theme/Adwaita/gtk-contained.css | 25 ++-
4 files changed, 229 insertions(+), 131 deletions(-)
---
diff --git a/gtk/gtkcolorswatch.c b/gtk/gtkcolorswatch.c
index edcc60f..f33f9a9 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_contents (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_get_content_size (GtkCssGadget *gadget,
+ GtkOrientation orientation,
+ gint for_size,
+ gint *minimum,
+ gint *natural,
+ gint *minimum_baseline,
+ gint *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_get_overlay_size (GtkCssGadget *gadget,
+ GtkOrientation orientation,
+ gint for_size,
+ gint *minimum,
+ gint *natural,
+ gint *minimum_baseline,
+ gint *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
@@ -589,6 +576,7 @@ swatch_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget);
+ GtkAllocation clip;
gtk_widget_set_allocation (widget, allocation);
@@ -599,7 +587,60 @@ 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_contents (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 +656,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));
}
/* GObject implementation {{{1 */
@@ -678,6 +720,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);
}
@@ -756,6 +800,54 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
}
+static void
+gtk_color_swatch_init (GtkColorSwatch *swatch)
+{
+ 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);
+
+ 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_get_content_size,
+ gtk_color_swatch_allocate_contents,
+ gtk_color_swatch_render_contents,
+ NULL,
+ NULL);
+
+ swatch->priv->overlay_gadget = gtk_css_custom_gadget_new ("overlay",
+ GTK_WIDGET (swatch),
+ swatch->priv->gadget,
+ NULL,
+ gtk_color_swatch_get_overlay_size,
+ NULL,
+ gtk_color_swatch_render_overlay,
+ NULL,
+ NULL);
+
+ context = gtk_widget_get_style_context (GTK_WIDGET (swatch));
+ gtk_style_context_add_class (context, "activatable");
+}
+
/* Public API {{{1 */
GtkWidget *
diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss
index fd9c890..1cfea18 100644
--- a/gtk/theme/Adwaita/_common.scss
+++ b/gtk/theme/Adwaita/_common.scss
@@ -3147,10 +3147,6 @@ colorswatch {
transparentize(white, 1) 50%);
box-shadow: inset 0 1px transparentize(white, 0.6),
inset 0 -1px if($variant == 'light', transparentize(black, 0.9), transparentize(black, 0.6));
- &.dark overlay { // swatches with colors with luminosity lower than 50% get the dark class
- background-image: linear-gradient(135deg, transparentize(white, 0.5),
- transparentize(white, 1) 50%);
- }
}
&:backdrop,
&:backdrop:selected
@@ -3161,22 +3157,26 @@ colorswatch {
}
// indicator and keynav outline colors
- &.dark overlay {
+ &.dark {
color: white;
outline-color: transparentize(white, 0.5);
+ border: 1px solid if($variant == 'light', transparentize(black, 0.7), $borders_color);
+ &:hover { border-color: if($variant == 'light', transparentize(black, 0.5), black); }
&:backdrop { color: transparentize(white, 0.7); }
}
- &.light overlay {
+ &.light {
color: black;
outline-color: transparentize(black, 0.5);
+ border: 1px solid if($variant == 'light', transparentize(black, 0.7), $borders_color);
+ &:hover { border-color: if($variant == 'light', transparentize(black, 0.5), black); }
&:backdrop { color: transparentize(black, 0.7); }
}
// border color
& overlay,
& overlay:selected {
- border: 1px solid if($variant == 'light', transparentize(black, 0.7), $borders_color);
- &:hover { border-color: if($variant == 'light', transparentize(black, 0.5), black); }
+ background: none;
+ border: none;
}
// make the add color button looks like, well, a button
diff --git a/gtk/theme/Adwaita/gtk-contained-dark.css b/gtk/theme/Adwaita/gtk-contained-dark.css
index 271dc25..6373d77 100644
--- a/gtk/theme/Adwaita/gtk-contained-dark.css
+++ b/gtk/theme/Adwaita/gtk-contained-dark.css
@@ -4317,26 +4317,29 @@ colorswatch {
colorswatch.activatable:hover, colorswatch.activatable:hover:selected {
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0) 50%);
box-shadow: inset 0 1px rgba(255, 255, 255, 0.4), inset 0 -1px rgba(0, 0, 0, 0.4); }
- colorswatch.activatable:hover.dark overlay, colorswatch.activatable:hover:selected.dark overlay {
- background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0) 50%); }
colorswatch:backdrop, colorswatch:backdrop:selected
colorswatch.dark:backdrop, colorswatch.dark:backdrop:selected {
background-image: none;
box-shadow: none; }
- colorswatch.dark overlay {
+ colorswatch.dark {
color: white;
- outline-color: rgba(255, 255, 255, 0.5); }
- colorswatch.dark overlay:backdrop {
+ outline-color: rgba(255, 255, 255, 0.5);
+ border: 1px solid #1c1f1f; }
+ colorswatch.dark:hover {
+ border-color: black; }
+ colorswatch.dark:backdrop {
color: rgba(255, 255, 255, 0.3); }
- colorswatch.light overlay {
+ colorswatch.light {
color: black;
- outline-color: rgba(0, 0, 0, 0.5); }
- colorswatch.light overlay:backdrop {
- color: rgba(0, 0, 0, 0.3); }
- colorswatch overlay, colorswatch overlay:selected {
+ outline-color: rgba(0, 0, 0, 0.5);
border: 1px solid #1c1f1f; }
- colorswatch overlay:hover, colorswatch overlay:selected:hover {
+ colorswatch.light:hover {
border-color: black; }
+ colorswatch.light:backdrop {
+ color: rgba(0, 0, 0, 0.3); }
+ colorswatch overlay, colorswatch overlay:selected {
+ background: none;
+ border: none; }
colorswatch#add-color-button {
border-style: solid;
border-width: 1px;
diff --git a/gtk/theme/Adwaita/gtk-contained.css b/gtk/theme/Adwaita/gtk-contained.css
index 8b5fe3d..4a5a2c0 100644
--- a/gtk/theme/Adwaita/gtk-contained.css
+++ b/gtk/theme/Adwaita/gtk-contained.css
@@ -4489,26 +4489,29 @@ colorswatch {
colorswatch.activatable:hover, colorswatch.activatable:hover:selected {
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0) 50%);
box-shadow: inset 0 1px rgba(255, 255, 255, 0.4), inset 0 -1px rgba(0, 0, 0, 0.1); }
- colorswatch.activatable:hover.dark overlay, colorswatch.activatable:hover:selected.dark overlay {
- background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0) 50%); }
colorswatch:backdrop, colorswatch:backdrop:selected
colorswatch.dark:backdrop, colorswatch.dark:backdrop:selected {
background-image: none;
box-shadow: none; }
- colorswatch.dark overlay {
+ colorswatch.dark {
color: white;
- outline-color: rgba(255, 255, 255, 0.5); }
- colorswatch.dark overlay:backdrop {
+ outline-color: rgba(255, 255, 255, 0.5);
+ border: 1px solid rgba(0, 0, 0, 0.3); }
+ colorswatch.dark:hover {
+ border-color: rgba(0, 0, 0, 0.5); }
+ colorswatch.dark:backdrop {
color: rgba(255, 255, 255, 0.3); }
- colorswatch.light overlay {
+ colorswatch.light {
color: black;
- outline-color: rgba(0, 0, 0, 0.5); }
- colorswatch.light overlay:backdrop {
- color: rgba(0, 0, 0, 0.3); }
- colorswatch overlay, colorswatch overlay:selected {
+ outline-color: rgba(0, 0, 0, 0.5);
border: 1px solid rgba(0, 0, 0, 0.3); }
- colorswatch overlay:hover, colorswatch overlay:selected:hover {
+ colorswatch.light:hover {
border-color: rgba(0, 0, 0, 0.5); }
+ colorswatch.light:backdrop {
+ color: rgba(0, 0, 0, 0.3); }
+ colorswatch overlay, colorswatch overlay:selected {
+ background: none;
+ border: none; }
colorswatch#add-color-button {
border-style: solid;
border-width: 1px;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]