mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-03 17:21:11 +00:00
Add GtkGradient.
This type defines a gradient between 2 symbolic colors, with any number of color stop between these. At the moment it has been put besides GtkSymbolicColor, although should be completely private, it will likely need extending in the future for radial gradients. At some point, it maybe should also be used for images, so painting both a gradient and an image is consistent.
This commit is contained in:
parent
74de1839a4
commit
142a72637d
@ -106,6 +106,9 @@ void gtk_style_set_merge (GtkStyleSet *set,
|
||||
gboolean gtk_symbolic_color_resolve (GtkSymbolicColor *color,
|
||||
GtkStyleSet *style_set,
|
||||
GdkColor *resolved_color);
|
||||
gboolean gtk_gradient_resolve (GtkGradient *gradient,
|
||||
GtkStyleSet *style_set,
|
||||
cairo_pattern_t **resolved_gradient);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include "gtkstyleset.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GtkGradient, gtk_gradient,
|
||||
gtk_gradient_ref, gtk_gradient_unref)
|
||||
|
||||
/* Symbolic colors */
|
||||
typedef enum {
|
||||
COLOR_TYPE_LITERAL,
|
||||
@ -55,6 +58,26 @@ struct GtkSymbolicColor
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct ColorStop ColorStop;
|
||||
|
||||
struct ColorStop
|
||||
{
|
||||
gdouble offset;
|
||||
GtkSymbolicColor *color;
|
||||
};
|
||||
|
||||
struct GtkGradient
|
||||
{
|
||||
gdouble x0;
|
||||
gdouble y0;
|
||||
gdouble x1;
|
||||
gdouble y1;
|
||||
|
||||
GArray *stops;
|
||||
|
||||
guint ref_count;
|
||||
};
|
||||
|
||||
GtkSymbolicColor *
|
||||
gtk_symbolic_color_new_literal (GdkColor *color)
|
||||
{
|
||||
@ -240,3 +263,112 @@ gtk_symbolic_color_get_type (void)
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* GtkGradient */
|
||||
GtkGradient *
|
||||
gtk_gradient_new_linear (gdouble x0,
|
||||
gdouble y0,
|
||||
gdouble x1,
|
||||
gdouble y1)
|
||||
{
|
||||
GtkGradient *gradient;
|
||||
|
||||
gradient = g_slice_new (GtkGradient);
|
||||
gradient->stops = g_array_new (FALSE, FALSE, sizeof (ColorStop));
|
||||
|
||||
gradient->x0 = x0;
|
||||
gradient->y0 = y0;
|
||||
gradient->x1 = x1;
|
||||
gradient->y1 = y1;
|
||||
|
||||
gradient->ref_count = 1;
|
||||
|
||||
return gradient;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_gradient_add_color_stop (GtkGradient *gradient,
|
||||
gdouble offset,
|
||||
GtkSymbolicColor *color)
|
||||
{
|
||||
ColorStop stop;
|
||||
|
||||
g_return_if_fail (gradient != NULL);
|
||||
|
||||
stop.offset = offset;
|
||||
stop.color = gtk_symbolic_color_ref (color);
|
||||
|
||||
g_array_append_val (gradient->stops, stop);
|
||||
}
|
||||
|
||||
GtkGradient *
|
||||
gtk_gradient_ref (GtkGradient *gradient)
|
||||
{
|
||||
g_return_val_if_fail (gradient != NULL, NULL);
|
||||
|
||||
gradient->ref_count++;
|
||||
|
||||
return gradient;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_gradient_unref (GtkGradient *gradient)
|
||||
{
|
||||
g_return_if_fail (gradient != NULL);
|
||||
|
||||
gradient->ref_count--;
|
||||
|
||||
if (gradient->ref_count == 0)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < gradient->stops->len; i++)
|
||||
{
|
||||
ColorStop *stop;
|
||||
|
||||
stop = &g_array_index (gradient->stops, ColorStop, i);
|
||||
gtk_symbolic_color_unref (stop->color);
|
||||
}
|
||||
|
||||
g_array_free (gradient->stops, TRUE);
|
||||
g_slice_free (GtkGradient, gradient);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_gradient_resolve (GtkGradient *gradient,
|
||||
GtkStyleSet *style_set,
|
||||
cairo_pattern_t **resolved_gradient)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (gradient != NULL, FALSE);
|
||||
g_return_val_if_fail (GTK_IS_STYLE_SET (style_set), FALSE);
|
||||
g_return_val_if_fail (resolved_gradient != NULL, FALSE);
|
||||
|
||||
pattern = cairo_pattern_create_linear (gradient->x0, gradient->y0,
|
||||
gradient->x1, gradient->y1);
|
||||
|
||||
for (i = 0; i < gradient->stops->len; i++)
|
||||
{
|
||||
ColorStop *stop;
|
||||
GdkColor color;
|
||||
|
||||
stop = &g_array_index (gradient->stops, ColorStop, i);
|
||||
|
||||
if (!gtk_symbolic_color_resolve (stop->color, style_set, &color))
|
||||
{
|
||||
cairo_pattern_destroy (pattern);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cairo_pattern_add_color_stop_rgb (pattern, stop->offset,
|
||||
color.red / 65535.,
|
||||
color.green / 65535.,
|
||||
color.blue / 65535.);
|
||||
}
|
||||
|
||||
*resolved_gradient = pattern;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -26,11 +26,13 @@ G_BEGIN_DECLS
|
||||
|
||||
/* Dummy typedefs */
|
||||
typedef struct GtkSymbolicColor GtkSymbolicColor;
|
||||
typedef struct GtkSymbolicColorMap GtkSymbolicColorMap;
|
||||
typedef struct GtkGradient GtkGradient;
|
||||
|
||||
#define GTK_TYPE_SYMBOLIC_COLOR (gtk_symbolic_color_get_type ())
|
||||
#define GTK_TYPE_GRADIENT (gtk_gradient_get_type ())
|
||||
|
||||
GType gtk_symbolic_color_get_type (void) G_GNUC_CONST;
|
||||
GType gtk_gradient_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkSymbolicColor * gtk_symbolic_color_new_literal (GdkColor *color);
|
||||
GtkSymbolicColor * gtk_symbolic_color_new_name (const gchar *name);
|
||||
@ -43,6 +45,18 @@ GtkSymbolicColor * gtk_symbolic_color_new_mix (GtkSymbolicColor *color1,
|
||||
GtkSymbolicColor * gtk_symbolic_color_ref (GtkSymbolicColor *color);
|
||||
void gtk_symbolic_color_unref (GtkSymbolicColor *color);
|
||||
|
||||
GtkGradient * gtk_gradient_new_linear (gdouble x0,
|
||||
gdouble y0,
|
||||
gdouble x1,
|
||||
gdouble y1);
|
||||
|
||||
void gtk_gradient_add_color_stop (GtkGradient *gradient,
|
||||
gdouble offset,
|
||||
GtkSymbolicColor *color);
|
||||
|
||||
GtkGradient * gtk_gradient_ref (GtkGradient *gradient);
|
||||
void gtk_gradient_unref (GtkGradient *gradient);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SYMBOLIC_COLOR_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user