GtkStyleContext: Add gtk_render_icon_pixbuf()
This function is similar to gtk_style_render_icon(), which is now implemented on top of this one.
This commit is contained in:
parent
06c8857191
commit
a23863211b
125
gtk/gtkstyle.c
125
gtk/gtkstyle.c
@ -327,6 +327,9 @@ static void hls_to_rgb (gdouble *h,
|
||||
|
||||
static void style_unrealize_cursors (GtkStyle *style);
|
||||
|
||||
static void transform_detail_string (const gchar *detail,
|
||||
GtkStyleContext *context);
|
||||
|
||||
/*
|
||||
* Data for default check and radio buttons
|
||||
*/
|
||||
@ -1607,54 +1610,6 @@ out:
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
scale_or_ref (GdkPixbuf *src,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
if (width == gdk_pixbuf_get_width (src) &&
|
||||
height == gdk_pixbuf_get_height (src))
|
||||
{
|
||||
return g_object_ref (src);
|
||||
}
|
||||
else
|
||||
{
|
||||
return gdk_pixbuf_scale_simple (src,
|
||||
width, height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
lookup_icon_size (GtkStyle *style,
|
||||
GtkWidget *widget,
|
||||
GtkIconSize size,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
GtkSettings *settings;
|
||||
|
||||
if (widget && gtk_widget_has_screen (widget))
|
||||
{
|
||||
screen = gtk_widget_get_screen (widget);
|
||||
settings = gtk_settings_get_for_screen (screen);
|
||||
}
|
||||
else if (style && style->visual)
|
||||
{
|
||||
screen = gdk_visual_get_screen (style->visual);
|
||||
settings = gtk_settings_get_for_screen (screen);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings = gtk_settings_get_default ();
|
||||
GTK_NOTE (MULTIHEAD,
|
||||
g_warning ("Using the default screen for gtk_default_render_icon()"));
|
||||
}
|
||||
|
||||
return gtk_icon_size_lookup_for_settings (settings, size, width, height);
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
gtk_default_render_icon (GtkStyle *style,
|
||||
const GtkIconSource *source,
|
||||
@ -1664,65 +1619,31 @@ gtk_default_render_icon (GtkStyle *style,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail)
|
||||
{
|
||||
gint width = 1;
|
||||
gint height = 1;
|
||||
GdkPixbuf *scaled;
|
||||
GdkPixbuf *stated;
|
||||
GdkPixbuf *base_pixbuf;
|
||||
GtkStyleContext *context;
|
||||
GtkStylePrivate *priv;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
/* Oddly, style can be NULL in this function, because
|
||||
* GtkIconSet can be used without a style and if so
|
||||
* it uses this function.
|
||||
*/
|
||||
|
||||
base_pixbuf = gtk_icon_source_get_pixbuf (source);
|
||||
|
||||
g_return_val_if_fail (base_pixbuf != NULL, NULL);
|
||||
|
||||
if (size != (GtkIconSize) -1 && !lookup_icon_size(style, widget, size, &width, &height))
|
||||
if (widget)
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
else
|
||||
{
|
||||
g_warning (G_STRLOC ": invalid icon size '%d'", size);
|
||||
return NULL;
|
||||
priv = GTK_STYLE_GET_PRIVATE (style);
|
||||
context = priv->context;
|
||||
}
|
||||
|
||||
/* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
|
||||
* leave it alone.
|
||||
*/
|
||||
if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
|
||||
scaled = scale_or_ref (base_pixbuf, width, height);
|
||||
else
|
||||
scaled = g_object_ref (base_pixbuf);
|
||||
if (!context)
|
||||
return NULL;
|
||||
|
||||
/* If the state was wildcarded, then generate a state. */
|
||||
if (gtk_icon_source_get_state_wildcarded (source))
|
||||
{
|
||||
if (state == GTK_STATE_INSENSITIVE)
|
||||
{
|
||||
stated = gdk_pixbuf_copy (scaled);
|
||||
|
||||
gdk_pixbuf_saturate_and_pixelate (scaled, stated,
|
||||
0.8, TRUE);
|
||||
|
||||
g_object_unref (scaled);
|
||||
}
|
||||
else if (state == GTK_STATE_PRELIGHT)
|
||||
{
|
||||
stated = gdk_pixbuf_copy (scaled);
|
||||
|
||||
gdk_pixbuf_saturate_and_pixelate (scaled, stated,
|
||||
1.2, FALSE);
|
||||
|
||||
g_object_unref (scaled);
|
||||
}
|
||||
else
|
||||
{
|
||||
stated = scaled;
|
||||
}
|
||||
}
|
||||
else
|
||||
stated = scaled;
|
||||
|
||||
return stated;
|
||||
gtk_style_context_save (context);
|
||||
|
||||
if (detail)
|
||||
transform_detail_string (detail, context);
|
||||
|
||||
pixbuf = gtk_render_icon_pixbuf (context, source, size);
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3270,3 +3270,36 @@ gtk_render_activity (GtkStyleContext *context,
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
engine_class->render_activity (priv->theming_engine, cr, x, y, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_render_icon_pixbuf:
|
||||
* @context: a #GtkStyleContext
|
||||
* @source: the #GtkIconSource specifying the icon to render
|
||||
* @size: (type int): the size to render the icon at. A size of (GtkIconSize) -1
|
||||
* means render at the size of the source and don't scale.
|
||||
*
|
||||
* Renders the icon specified by @source at the given @size, returning the result
|
||||
* in a pixbuf.
|
||||
*
|
||||
* Returns: (transfer full): a newly-created #GdkPixbuf containing the rendered icon
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
GdkPixbuf *
|
||||
gtk_render_icon_pixbuf (GtkStyleContext *context,
|
||||
const GtkIconSource *source,
|
||||
GtkIconSize size)
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
GtkThemingEngineClass *engine_class;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
|
||||
g_return_val_if_fail (size >= -1, NULL);
|
||||
g_return_val_if_fail (source != NULL, NULL);
|
||||
|
||||
priv = context->priv;
|
||||
engine_class = GTK_THEMING_ENGINE_GET_CLASS (priv->theming_engine);
|
||||
|
||||
_gtk_theming_engine_set_context (priv->theming_engine, context);
|
||||
return engine_class->render_icon_pixbuf (priv->theming_engine, source, size);
|
||||
}
|
||||
|
@ -404,6 +404,10 @@ void gtk_render_activity (GtkStyleContext *context,
|
||||
gdouble width,
|
||||
gdouble height);
|
||||
|
||||
GdkPixbuf * gtk_render_icon_pixbuf (GtkStyleContext *context,
|
||||
const GtkIconSource *source,
|
||||
GtkIconSize size);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_STYLE_CONTEXT_H__ */
|
||||
|
@ -168,6 +168,9 @@ static void gtk_theming_engine_render_activity (GtkThemingEngine *engine,
|
||||
gdouble y,
|
||||
gdouble width,
|
||||
gdouble height);
|
||||
static GdkPixbuf * gtk_theming_engine_render_icon_pixbuf (GtkThemingEngine *engine,
|
||||
const GtkIconSource *source,
|
||||
GtkIconSize size);
|
||||
|
||||
G_DEFINE_TYPE (GtkThemingEngine, gtk_theming_engine, G_TYPE_OBJECT)
|
||||
|
||||
@ -220,6 +223,7 @@ gtk_theming_engine_class_init (GtkThemingEngineClass *klass)
|
||||
klass->render_extension = gtk_theming_engine_render_extension;
|
||||
klass->render_handle = gtk_theming_engine_render_handle;
|
||||
klass->render_activity = gtk_theming_engine_render_activity;
|
||||
klass->render_icon_pixbuf = gtk_theming_engine_render_icon_pixbuf;
|
||||
|
||||
/**
|
||||
* GtkThemingEngine:name:
|
||||
@ -2807,3 +2811,91 @@ gtk_theming_engine_render_activity (GtkThemingEngine *engine,
|
||||
gtk_theming_engine_render_frame (engine, cr, x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
scale_or_ref (GdkPixbuf *src,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
if (width == gdk_pixbuf_get_width (src) &&
|
||||
height == gdk_pixbuf_get_height (src))
|
||||
return g_object_ref (src);
|
||||
else
|
||||
return gdk_pixbuf_scale_simple (src,
|
||||
width, height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
lookup_icon_size (GtkThemingEngine *engine,
|
||||
GtkIconSize size,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
GtkSettings *settings;
|
||||
|
||||
screen = gtk_theming_engine_get_screen (engine);
|
||||
settings = gtk_settings_get_for_screen (screen);
|
||||
|
||||
return gtk_icon_size_lookup_for_settings (settings, size, width, height);
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
gtk_theming_engine_render_icon_pixbuf (GtkThemingEngine *engine,
|
||||
const GtkIconSource *source,
|
||||
GtkIconSize size)
|
||||
{
|
||||
GdkPixbuf *scaled;
|
||||
GdkPixbuf *stated;
|
||||
GdkPixbuf *base_pixbuf;
|
||||
GtkStateFlags state;
|
||||
gint width = 1;
|
||||
gint height = 1;
|
||||
|
||||
base_pixbuf = gtk_icon_source_get_pixbuf (source);
|
||||
state = gtk_theming_engine_get_state (engine);
|
||||
|
||||
g_return_val_if_fail (base_pixbuf != NULL, NULL);
|
||||
|
||||
if (size != (GtkIconSize) -1 &&
|
||||
!lookup_icon_size (engine, size, &width, &height))
|
||||
{
|
||||
g_warning (G_STRLOC ": invalid icon size '%d'", size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
|
||||
* leave it alone.
|
||||
*/
|
||||
if (size != (GtkIconSize) -1 &&
|
||||
gtk_icon_source_get_size_wildcarded (source))
|
||||
scaled = scale_or_ref (base_pixbuf, width, height);
|
||||
else
|
||||
scaled = g_object_ref (base_pixbuf);
|
||||
|
||||
/* If the state was wildcarded, then generate a state. */
|
||||
if (gtk_icon_source_get_state_wildcarded (source))
|
||||
{
|
||||
if (state & GTK_STATE_FLAG_INSENSITIVE)
|
||||
{
|
||||
stated = gdk_pixbuf_copy (scaled);
|
||||
gdk_pixbuf_saturate_and_pixelate (scaled, stated,
|
||||
0.8, TRUE);
|
||||
g_object_unref (scaled);
|
||||
}
|
||||
else if (state & GTK_STATE_FLAG_PRELIGHT)
|
||||
{
|
||||
stated = gdk_pixbuf_copy (scaled);
|
||||
gdk_pixbuf_saturate_and_pixelate (scaled, stated,
|
||||
1.2, FALSE);
|
||||
g_object_unref (scaled);
|
||||
}
|
||||
else
|
||||
stated = scaled;
|
||||
}
|
||||
else
|
||||
stated = scaled;
|
||||
|
||||
return stated;
|
||||
}
|
||||
|
@ -157,6 +157,10 @@ struct _GtkThemingEngineClass
|
||||
gdouble y,
|
||||
gdouble width,
|
||||
gdouble height);
|
||||
|
||||
GdkPixbuf * (* render_icon_pixbuf) (GtkThemingEngine *engine,
|
||||
const GtkIconSource *source,
|
||||
GtkIconSize size);
|
||||
};
|
||||
|
||||
GType gtk_theming_engine_get_type (void) G_GNUC_CONST;
|
||||
|
Loading…
Reference in New Issue
Block a user