mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 21:51:08 +00:00
Merge branch 'fix-texture-scale-rotation' into 'main'
gtk4-demo: Polish the image scaling demo See merge request GNOME/gtk!5649
This commit is contained in:
commit
7b1644b2d0
@ -28,6 +28,80 @@ struct _Demo3WidgetClass
|
||||
|
||||
G_DEFINE_TYPE (Demo3Widget, demo3_widget, GTK_TYPE_WIDGET)
|
||||
|
||||
static gboolean
|
||||
query_tooltip (GtkWidget *widget,
|
||||
int x,
|
||||
int y,
|
||||
gboolean keyboard_mode,
|
||||
GtkTooltip *tooltip,
|
||||
gpointer data)
|
||||
{
|
||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||
GtkWidget *grid;
|
||||
GtkWidget *label;
|
||||
char *s, *s2;
|
||||
const char *filter[] = { "Linear", "Nearest", "Trilinear" };
|
||||
int precision, l;
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
|
||||
label = gtk_label_new ("Texture");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
|
||||
s = g_strdup_printf ("%d\342\200\206\303\227\342\200\206%d",
|
||||
gdk_texture_get_width (self->texture),
|
||||
gdk_texture_get_height (self->texture));
|
||||
label = gtk_label_new (s);
|
||||
g_free (s);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
|
||||
|
||||
label = gtk_label_new ("Rotation");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
|
||||
s = g_strdup_printf ("%.1f", self->angle);
|
||||
if (g_str_has_suffix (s, ".0"))
|
||||
s[strlen (s) - 2] = '\0';
|
||||
s2 = g_strconcat (s, "\302\260", NULL);
|
||||
label = gtk_label_new (s2);
|
||||
g_free (s2);
|
||||
g_free (s);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 1, 1, 1);
|
||||
|
||||
label = gtk_label_new ("Scale");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
|
||||
|
||||
precision = 1;
|
||||
do {
|
||||
s = g_strdup_printf ("%.*f", precision, self->scale);
|
||||
l = strlen (s) - 1;
|
||||
while (s[l] == '0')
|
||||
l--;
|
||||
if (s[l] == '.')
|
||||
s[l] = '\0';
|
||||
precision++;
|
||||
} while (strcmp (s, "0") == 0);
|
||||
|
||||
label = gtk_label_new (s);
|
||||
g_free (s);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 2, 1, 1);
|
||||
|
||||
label = gtk_label_new ("Filter");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
|
||||
label = gtk_label_new (filter[self->filter]);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 3, 1, 1);
|
||||
|
||||
gtk_tooltip_set_custom (tooltip, grid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
demo3_widget_init (Demo3Widget *self)
|
||||
{
|
||||
@ -135,6 +209,8 @@ demo3_widget_size_allocate (GtkWidget *widget,
|
||||
gtk_popover_present (GTK_POPOVER (self->menu));
|
||||
}
|
||||
|
||||
static void update_actions (Demo3Widget *self);
|
||||
|
||||
static void
|
||||
demo3_widget_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -153,6 +229,7 @@ demo3_widget_set_property (GObject *object,
|
||||
|
||||
case PROP_SCALE:
|
||||
self->scale = g_value_get_float (value);
|
||||
update_actions (self);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
@ -219,6 +296,14 @@ pressed_cb (GtkGestureClick *gesture,
|
||||
gtk_popover_popup (GTK_POPOVER (self->menu));
|
||||
}
|
||||
|
||||
static void
|
||||
update_actions (Demo3Widget *self)
|
||||
{
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.in", self->scale < 1024.);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.out", self->scale > 1./1024.);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.reset", self->scale != 1.);
|
||||
}
|
||||
|
||||
static void
|
||||
zoom_cb (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
@ -228,15 +313,13 @@ zoom_cb (GtkWidget *widget,
|
||||
float scale;
|
||||
|
||||
if (g_str_equal (action_name, "zoom.in"))
|
||||
scale = MIN (10, self->scale * M_SQRT2);
|
||||
scale = MIN (1024., self->scale * M_SQRT2);
|
||||
else if (g_str_equal (action_name, "zoom.out"))
|
||||
scale = MAX (0.01, self->scale / M_SQRT2);
|
||||
else
|
||||
scale = MAX (1./1024., self->scale / M_SQRT2);
|
||||
else if (g_str_equal (action_name, "zoom.reset"))
|
||||
scale = 1.0;
|
||||
|
||||
gtk_widget_action_set_enabled (widget, "zoom.in", scale < 10);
|
||||
gtk_widget_action_set_enabled (widget, "zoom.out", scale > 0.01);
|
||||
gtk_widget_action_set_enabled (widget, "zoom.reset", scale != 1);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
g_object_set (widget, "scale", scale, NULL);
|
||||
}
|
||||
@ -275,7 +358,7 @@ demo3_widget_class_init (Demo3WidgetClass *class)
|
||||
|
||||
g_object_class_install_property (object_class, PROP_SCALE,
|
||||
g_param_spec_float ("scale", NULL, NULL,
|
||||
0.0, 1024.0, 1.0,
|
||||
1./1024., 1024., 1.0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ANGLE,
|
||||
@ -307,7 +390,12 @@ demo3_widget_new (const char *resource)
|
||||
|
||||
texture = gdk_texture_new_from_resource (resource);
|
||||
|
||||
self = g_object_new (DEMO3_TYPE_WIDGET, "texture", texture, NULL);
|
||||
self = g_object_new (DEMO3_TYPE_WIDGET,
|
||||
"texture", texture,
|
||||
"has-tooltip", TRUE,
|
||||
NULL);
|
||||
|
||||
g_signal_connect (self, "query-tooltip", G_CALLBACK (query_tooltip), NULL);
|
||||
|
||||
g_object_unref (texture);
|
||||
|
||||
|
@ -84,14 +84,36 @@ rotate (GtkWidget *button,
|
||||
g_object_set (demo, "angle", angle, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
scale_changed (GtkRange *range,
|
||||
GtkWidget *widget)
|
||||
static gboolean
|
||||
transform_to (GBinding *binding,
|
||||
const GValue *src,
|
||||
GValue *dest,
|
||||
gpointer user_data)
|
||||
{
|
||||
float scale;
|
||||
double from;
|
||||
float to;
|
||||
|
||||
scale = (float) pow (2., gtk_range_get_value (range));
|
||||
g_object_set (widget, "scale", scale, NULL);
|
||||
from = g_value_get_double (src);
|
||||
to = (float) pow (2., from);
|
||||
g_value_set_float (dest, to);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
transform_from (GBinding *binding,
|
||||
const GValue *src,
|
||||
GValue *dest,
|
||||
gpointer user_data)
|
||||
{
|
||||
float to;
|
||||
double from;
|
||||
|
||||
to = g_value_get_float (src);
|
||||
from = log2 (to);
|
||||
g_value_set_double (dest, from);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@ -139,9 +161,10 @@ do_menu (GtkWidget *do_widget)
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (rotate), widget);
|
||||
gtk_box_append (GTK_BOX (box2), button);
|
||||
|
||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, -10, 10.0, 0.1);
|
||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, -10., 10., 0.1);
|
||||
gtk_scale_add_mark (GTK_SCALE (scale), 0., GTK_POS_TOP, NULL);
|
||||
gtk_widget_set_tooltip_text (scale, "Zoom");
|
||||
gtk_range_set_value (GTK_RANGE (scale), 1.0);
|
||||
gtk_range_set_value (GTK_RANGE (scale), 0.);
|
||||
gtk_widget_set_hexpand (scale, TRUE);
|
||||
gtk_box_append (GTK_BOX (box2), scale);
|
||||
|
||||
@ -151,7 +174,12 @@ do_menu (GtkWidget *do_widget)
|
||||
|
||||
g_object_bind_property (dropdown, "selected", widget, "filter", G_BINDING_DEFAULT);
|
||||
|
||||
g_signal_connect (scale, "value-changed", G_CALLBACK (scale_changed), widget);
|
||||
g_object_bind_property_full (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
|
||||
widget, "scale",
|
||||
G_BINDING_BIDIRECTIONAL,
|
||||
transform_to,
|
||||
transform_from,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@ -260,6 +260,7 @@ node_supports_2d_transform (const GskRenderNode *node)
|
||||
case GSK_OPACITY_NODE:
|
||||
case GSK_COLOR_MATRIX_NODE:
|
||||
case GSK_TEXTURE_NODE:
|
||||
case GSK_TEXTURE_SCALE_NODE:
|
||||
case GSK_CROSS_FADE_NODE:
|
||||
case GSK_LINEAR_GRADIENT_NODE:
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
@ -3643,6 +3644,7 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
|
||||
GskTextureKey key;
|
||||
|
||||
gsk_gl_render_job_untransform_bounds (job, &job->current_clip->rect.bounds, &clip_rect);
|
||||
|
||||
if (!graphene_rect_intersection (bounds, &clip_rect, &clip_rect))
|
||||
return;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user