summaryrefslogtreecommitdiff
path: root/gtk/gtkiconhelper.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2018-03-15 09:40:52 +0100
committerBenjamin Otte <otte@redhat.com>2018-03-16 06:04:45 +0100
commit0a08c0388587500930a684d3bcf7d26d7dc7bd52 (patch)
tree89493374767f5ecd6201e2493da6b7fdabfa1a19 /gtk/gtkiconhelper.c
parentaf18796312711dd6943e25e31016da9511eaa327 (diff)
downloadgtk+-0a08c0388587500930a684d3bcf7d26d7dc7bd52.tar.gz
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.
Diffstat (limited to 'gtk/gtkiconhelper.c')
-rw-r--r--gtk/gtkiconhelper.c376
1 files changed, 245 insertions, 131 deletions
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)
{