From: Benjamin Otte Date: Thu, 15 Mar 2018 08:40:52 +0000 (+0100) Subject: iconhelper: Implement GdkPaintable X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~22^2~932 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0a08c0388587500930a684d3bcf7d26d7dc7bd52;p=gtk4.git iconhelper: Implement GdkPaintable This only implements the vfuncs, but does not actually emit signals yet. It's also not useed for anything other than snapshot() so far, this will come in later commits. --- diff --git a/gtk/gtkcellrendererpixbuf.c b/gtk/gtkcellrendererpixbuf.c index 1426fef268..3cca5e5555 100644 --- a/gtk/gtkcellrendererpixbuf.c +++ b/gtk/gtkcellrendererpixbuf.c @@ -551,7 +551,7 @@ gtk_cell_renderer_pixbuf_snapshot (GtkCellRenderer *cell, } gtk_snapshot_offset (snapshot, pix_rect.x, pix_rect.y); - gtk_icon_helper_snapshot (icon_helper, snapshot, pix_rect.width, pix_rect.height); + gdk_paintable_snapshot (GDK_PAINTABLE (icon_helper), snapshot, pix_rect.width, pix_rect.height); gtk_snapshot_offset (snapshot, - pix_rect.x, - pix_rect.y); g_object_unref (icon_helper); diff --git a/gtk/gtkiconhelper.c b/gtk/gtkiconhelper.c index 5904fe3faa..5a38f2aea2 100644 --- a/gtk/gtkiconhelper.c +++ b/gtk/gtkiconhelper.c @@ -53,116 +53,6 @@ struct _GtkIconHelper int texture_scale; }; -G_DEFINE_TYPE (GtkIconHelper, gtk_icon_helper, G_TYPE_OBJECT) - -void -gtk_icon_helper_invalidate (GtkIconHelper *self) -{ - g_clear_object (&self->paintable); - self->texture_scale = 1; - self->texture_is_symbolic = FALSE; - - if (!GTK_IS_CSS_TRANSIENT_NODE (self->node)) - gtk_widget_queue_resize (self->owner); -} - -void -gtk_icon_helper_invalidate_for_change (GtkIconHelper *self, - GtkCssStyleChange *change) -{ - if (change == NULL || - ((gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SYMBOLIC_ICON) && - self->texture_is_symbolic) || - (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON) && - !self->texture_is_symbolic))) - { - /* Avoid the queue_resize in gtk_icon_helper_invalidate */ - g_clear_object (&self->paintable); - self->texture_scale = 1; - self->texture_is_symbolic = FALSE; - - if (change == NULL || - (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_SIZE) && - !GTK_IS_CSS_TRANSIENT_NODE (self->node))) - gtk_widget_queue_resize (self->owner); - } -} - -static void -gtk_icon_helper_take_definition (GtkIconHelper *self, - GtkImageDefinition *def) -{ - _gtk_icon_helper_clear (self); - - if (def == NULL) - return; - - gtk_image_definition_unref (self->def); - self->def = def; - - gtk_icon_helper_invalidate (self); -} - -void -_gtk_icon_helper_clear (GtkIconHelper *self) -{ - g_clear_object (&self->paintable); - self->texture_scale = 1; - self->texture_is_symbolic = FALSE; - - if (gtk_image_definition_get_storage_type (self->def) != GTK_IMAGE_EMPTY) - { - gtk_image_definition_unref (self->def); - self->def = gtk_image_definition_new_empty (); - gtk_icon_helper_invalidate (self); - } -} - -static void -gtk_icon_helper_finalize (GObject *object) -{ - GtkIconHelper *self = GTK_ICON_HELPER (object); - - _gtk_icon_helper_clear (self); - g_signal_handlers_disconnect_by_func (self->owner, G_CALLBACK (gtk_icon_helper_invalidate), self); - gtk_image_definition_unref (self->def); - - G_OBJECT_CLASS (gtk_icon_helper_parent_class)->finalize (object); -} - -void -gtk_icon_helper_class_init (GtkIconHelperClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->finalize = gtk_icon_helper_finalize; -} - -void -gtk_icon_helper_init (GtkIconHelper *self) -{ - self->def = gtk_image_definition_new_empty (); -} - -GtkIconHelper * -gtk_icon_helper_new (GtkCssNode *css_node, - GtkWidget *owner) -{ - GtkIconHelper *self; - - self = g_object_new (GTK_TYPE_ICON_HELPER, NULL); - - self->pixel_size = -1; - self->texture_is_symbolic = FALSE; - - self->node = css_node; - self->owner = owner; - g_signal_connect_swapped (owner, "direction-changed", G_CALLBACK (gtk_icon_helper_invalidate), self); - g_signal_connect_swapped (owner, "notify::scale-factor", G_CALLBACK (gtk_icon_helper_invalidate), self); - - return self; -} - static int get_default_size (GtkIconHelper *self) { @@ -344,6 +234,251 @@ gtk_icon_helper_ensure_paintable (GtkIconHelper *self) self->texture_is_symbolic = symbolic; } +static void +gtk_icon_helper_paintable_snapshot (GdkPaintable *paintable, + GdkSnapshot *snapshot, + double width, + double height) +{ + GtkIconHelper *self = GTK_ICON_HELPER (paintable); + GtkCssStyle *style; + + style = gtk_css_node_get_style (self->node); + + gtk_icon_helper_ensure_paintable (self); + if (self->paintable == NULL) + return; + + gtk_css_style_snapshot_icon_paintable (style, + snapshot, + self->paintable, + width, height, + self->texture_is_symbolic); +} + +static GdkPaintable * +gtk_icon_helper_paintable_get_current_image (GdkPaintable *paintable) +{ + GtkIconHelper *self = GTK_ICON_HELPER (paintable); + + gtk_icon_helper_ensure_paintable (self); + if (self->paintable == NULL) + return NULL; + + return gtk_icon_helper_paintable_get_current_image (self->paintable); +} + +static int +gtk_icon_helper_paintable_get_intrinsic_width (GdkPaintable *paintable) +{ + GtkIconHelper *self = GTK_ICON_HELPER (paintable); + + switch (gtk_image_definition_get_storage_type (self->def)) + { + case GTK_IMAGE_TEXTURE: + return gdk_paintable_get_intrinsic_width (GDK_PAINTABLE (gtk_image_definition_get_texture (self->def))); + + case GTK_IMAGE_PAINTABLE: + return gdk_paintable_get_intrinsic_width (gtk_image_definition_get_paintable (self->def)); + + case GTK_IMAGE_ICON_NAME: + case GTK_IMAGE_GICON: + if (self->pixel_size != -1 || self->force_scale_pixbuf) + return get_default_size (self); + gtk_icon_helper_ensure_paintable (self); + if (self->paintable) + return gdk_paintable_get_intrinsic_width (self->paintable); + else + return 0; + + case GTK_IMAGE_EMPTY: + return 0; + + default: + g_assert_not_reached (); + return 0; + } +} + +static int +gtk_icon_helper_paintable_get_intrinsic_height (GdkPaintable *paintable) +{ + GtkIconHelper *self = GTK_ICON_HELPER (paintable); + + switch (gtk_image_definition_get_storage_type (self->def)) + { + case GTK_IMAGE_TEXTURE: + return gdk_paintable_get_intrinsic_height (GDK_PAINTABLE (gtk_image_definition_get_texture (self->def))); + + case GTK_IMAGE_PAINTABLE: + return gdk_paintable_get_intrinsic_height (gtk_image_definition_get_paintable (self->def)); + + case GTK_IMAGE_ICON_NAME: + case GTK_IMAGE_GICON: + if (self->pixel_size != -1 || self->force_scale_pixbuf) + return get_default_size (self); + gtk_icon_helper_ensure_paintable (self); + if (self->paintable) + return gdk_paintable_get_intrinsic_height (self->paintable); + else + return 0; + + case GTK_IMAGE_EMPTY: + return 0; + + default: + g_assert_not_reached (); + return 0; + } +} + +static double gtk_icon_helper_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable) +{ + GtkIconHelper *self = GTK_ICON_HELPER (paintable); + + switch (gtk_image_definition_get_storage_type (self->def)) + { + case GTK_IMAGE_TEXTURE: + return gdk_paintable_get_intrinsic_aspect_ratio (GDK_PAINTABLE (gtk_image_definition_get_texture (self->def))); + + case GTK_IMAGE_PAINTABLE: + return gdk_paintable_get_intrinsic_aspect_ratio (gtk_image_definition_get_paintable (self->def)); + + case GTK_IMAGE_ICON_NAME: + case GTK_IMAGE_GICON: + return 1.0; + + case GTK_IMAGE_EMPTY: + return 0.0; + + default: + g_assert_not_reached (); + return 0.0; + } +}; + +static void +gtk_icon_helper_paintable_init (GdkPaintableInterface *iface) +{ + iface->snapshot = gtk_icon_helper_paintable_snapshot; + iface->get_current_image = gtk_icon_helper_paintable_get_current_image; + iface->get_intrinsic_width = gtk_icon_helper_paintable_get_intrinsic_width; + iface->get_intrinsic_height = gtk_icon_helper_paintable_get_intrinsic_height; + iface->get_intrinsic_aspect_ratio = gtk_icon_helper_paintable_get_intrinsic_aspect_ratio; +} + +G_DEFINE_TYPE_WITH_CODE (GtkIconHelper, gtk_icon_helper, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE, + gtk_icon_helper_paintable_init)) + +void +gtk_icon_helper_invalidate (GtkIconHelper *self) +{ + g_clear_object (&self->paintable); + self->texture_scale = 1; + self->texture_is_symbolic = FALSE; + + if (!GTK_IS_CSS_TRANSIENT_NODE (self->node)) + gtk_widget_queue_resize (self->owner); +} + +void +gtk_icon_helper_invalidate_for_change (GtkIconHelper *self, + GtkCssStyleChange *change) +{ + if (change == NULL || + ((gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SYMBOLIC_ICON) && + self->texture_is_symbolic) || + (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON) && + !self->texture_is_symbolic))) + { + /* Avoid the queue_resize in gtk_icon_helper_invalidate */ + g_clear_object (&self->paintable); + self->texture_scale = 1; + self->texture_is_symbolic = FALSE; + + if (change == NULL || + (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_SIZE) && + !GTK_IS_CSS_TRANSIENT_NODE (self->node))) + gtk_widget_queue_resize (self->owner); + } +} + +static void +gtk_icon_helper_take_definition (GtkIconHelper *self, + GtkImageDefinition *def) +{ + _gtk_icon_helper_clear (self); + + if (def == NULL) + return; + + gtk_image_definition_unref (self->def); + self->def = def; + + gtk_icon_helper_invalidate (self); +} + +void +_gtk_icon_helper_clear (GtkIconHelper *self) +{ + g_clear_object (&self->paintable); + self->texture_scale = 1; + self->texture_is_symbolic = FALSE; + + if (gtk_image_definition_get_storage_type (self->def) != GTK_IMAGE_EMPTY) + { + gtk_image_definition_unref (self->def); + self->def = gtk_image_definition_new_empty (); + gtk_icon_helper_invalidate (self); + } +} + +static void +gtk_icon_helper_finalize (GObject *object) +{ + GtkIconHelper *self = GTK_ICON_HELPER (object); + + _gtk_icon_helper_clear (self); + g_signal_handlers_disconnect_by_func (self->owner, G_CALLBACK (gtk_icon_helper_invalidate), self); + gtk_image_definition_unref (self->def); + + G_OBJECT_CLASS (gtk_icon_helper_parent_class)->finalize (object); +} + +void +gtk_icon_helper_class_init (GtkIconHelperClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = gtk_icon_helper_finalize; +} + +void +gtk_icon_helper_init (GtkIconHelper *self) +{ + self->def = gtk_image_definition_new_empty (); +} + +GtkIconHelper * +gtk_icon_helper_new (GtkCssNode *css_node, + GtkWidget *owner) +{ + GtkIconHelper *self; + + self = g_object_new (GTK_TYPE_ICON_HELPER, NULL); + + self->pixel_size = -1; + self->texture_is_symbolic = FALSE; + + self->node = css_node; + self->owner = owner; + g_signal_connect_swapped (owner, "direction-changed", G_CALLBACK (gtk_icon_helper_invalidate), self); + g_signal_connect_swapped (owner, "notify::scale-factor", G_CALLBACK (gtk_icon_helper_invalidate), self); + + return self; +} + void gtk_icon_helper_measure (GtkIconHelper *self, GtkOrientation orientation, @@ -615,27 +750,6 @@ _gtk_icon_helper_get_icon_name (GtkIconHelper *self) return gtk_image_definition_get_icon_name (self->def); } -void -gtk_icon_helper_snapshot (GtkIconHelper *self, - GtkSnapshot *snapshot, - double width, - double height) -{ - GtkCssStyle *style; - - style = gtk_css_node_get_style (self->node); - - gtk_icon_helper_ensure_paintable (self); - if (self->paintable == NULL) - return; - - gtk_css_style_snapshot_icon_paintable (style, - snapshot, - self->paintable, - width, height, - self->texture_is_symbolic); -} - gboolean _gtk_icon_helper_get_is_empty (GtkIconHelper *self) { diff --git a/gtk/gtkiconhelperprivate.h b/gtk/gtkiconhelperprivate.h index 2a14a61d65..2e6846c266 100644 --- a/gtk/gtkiconhelperprivate.h +++ b/gtk/gtkiconhelperprivate.h @@ -76,11 +76,6 @@ void _gtk_icon_helper_get_size (GtkIconHelper *self, gint *width_out, gint *height_out); -void gtk_icon_helper_snapshot (GtkIconHelper *self, - GtkSnapshot *snapshot, - double width, - double height); - gboolean _gtk_icon_helper_get_force_scale_pixbuf (GtkIconHelper *self); void _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self, gboolean force_scale); diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c index 5502cba89b..2d4d5a0dbb 100644 --- a/gtk/gtkimage.c +++ b/gtk/gtkimage.c @@ -1211,7 +1211,7 @@ gtk_image_snapshot (GtkWidget *widget, if (_gtk_icon_helper_get_storage_type (priv->icon_helper) == GTK_IMAGE_PAINTABLE) { - gtk_icon_helper_snapshot (priv->icon_helper, snapshot, width, height); + gdk_paintable_snapshot (GDK_PAINTABLE (priv->icon_helper), snapshot, width, height); } else { @@ -1226,7 +1226,7 @@ gtk_image_snapshot (GtkWidget *widget, y = CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h); gtk_snapshot_offset (snapshot, x, y); - gtk_icon_helper_snapshot (priv->icon_helper, snapshot, w, h); + gdk_paintable_snapshot (GDK_PAINTABLE (priv->icon_helper), snapshot, w, h); gtk_snapshot_offset (snapshot, -x, -y); } }