css: Support background-position property
This commit is contained in:
committed by
Benjamin Otte
parent
b874e6c3cf
commit
e65a2709a3
@ -682,6 +682,181 @@ background_size_compute (GtkCssStyleProperty *property,
|
||||
return _gtk_css_value_ref (specified);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
background_position_parse (GtkCssStyleProperty *property,
|
||||
GValue *value,
|
||||
GtkCssParser *parser,
|
||||
GFile *base)
|
||||
{
|
||||
static const struct {
|
||||
const char *name;
|
||||
guint percentage;
|
||||
gboolean horizontal;
|
||||
gboolean vertical;
|
||||
} names[] = {
|
||||
{ "left", 0, TRUE, FALSE },
|
||||
{ "right", 100, TRUE, FALSE },
|
||||
{ "center", 50, TRUE, TRUE },
|
||||
{ "top", 0, FALSE, TRUE },
|
||||
{ "bottom", 100, FALSE, TRUE },
|
||||
{ NULL , 0, TRUE, FALSE }, /* used for numbers */
|
||||
{ NULL , 50, TRUE, TRUE } /* used for no value */
|
||||
};
|
||||
GtkCssBackgroundPosition pos;
|
||||
GtkCssNumber *missing;
|
||||
guint first, second;
|
||||
|
||||
for (first = 0; names[first].name != NULL; first++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, names[first].name, TRUE))
|
||||
{
|
||||
if (names[first].horizontal)
|
||||
{
|
||||
_gtk_css_number_init (&pos.x, names[first].percentage, GTK_CSS_PERCENT);
|
||||
missing = &pos.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_css_number_init (&pos.y, names[first].percentage, GTK_CSS_PERCENT);
|
||||
missing = &pos.x;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (names[first].name == NULL)
|
||||
{
|
||||
missing = &pos.y;
|
||||
if (!_gtk_css_parser_read_number (parser,
|
||||
&pos.x,
|
||||
GTK_CSS_PARSE_PERCENT
|
||||
| GTK_CSS_PARSE_LENGTH))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (second = 0; names[second].name != NULL; second++)
|
||||
{
|
||||
if (_gtk_css_parser_try (parser, names[second].name, TRUE))
|
||||
{
|
||||
_gtk_css_number_init (missing, names[second].percentage, GTK_CSS_PERCENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (names[second].name == NULL)
|
||||
{
|
||||
if (_gtk_css_parser_has_number (parser))
|
||||
{
|
||||
if (missing != &pos.y)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Invalid combination of values");
|
||||
return FALSE;
|
||||
}
|
||||
if (!_gtk_css_parser_read_number (parser,
|
||||
missing,
|
||||
GTK_CSS_PARSE_PERCENT
|
||||
| GTK_CSS_PARSE_LENGTH))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
second++;
|
||||
_gtk_css_number_init (missing, 50, GTK_CSS_PERCENT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((names[first].horizontal && !names[second].vertical) ||
|
||||
(!names[first].horizontal && !names[second].horizontal))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Invalid combination of values");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
g_value_set_boxed (value, &pos);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
background_position_print (GtkCssStyleProperty *property,
|
||||
const GValue *value,
|
||||
GString *string)
|
||||
{
|
||||
GtkCssBackgroundPosition *pos = g_value_get_boxed (value);
|
||||
static const GtkCssNumber center = GTK_CSS_NUMBER_INIT (50, GTK_CSS_PERCENT);
|
||||
static const struct {
|
||||
const char *x_name;
|
||||
const char *y_name;
|
||||
GtkCssNumber number;
|
||||
} values[] = {
|
||||
{ "left", "top", GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT) },
|
||||
{ "right", "bottom", GTK_CSS_NUMBER_INIT (100, GTK_CSS_PERCENT) }
|
||||
};
|
||||
guint i;
|
||||
|
||||
if (_gtk_css_number_equal (&pos->x, ¢er))
|
||||
{
|
||||
if (_gtk_css_number_equal (&pos->y, ¢er))
|
||||
{
|
||||
g_string_append (string, "center");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < G_N_ELEMENTS (values); i++)
|
||||
{
|
||||
if (_gtk_css_number_equal (&pos->x, &values[i].number))
|
||||
{
|
||||
g_string_append (string, values[i].x_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == G_N_ELEMENTS (values))
|
||||
_gtk_css_number_print (&pos->x, string);
|
||||
|
||||
if (_gtk_css_number_equal (&pos->y, ¢er))
|
||||
return;
|
||||
|
||||
g_string_append_c (string, ' ');
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (values); i++)
|
||||
{
|
||||
if (_gtk_css_number_equal (&pos->y, &values[i].number))
|
||||
{
|
||||
g_string_append (string, values[i].y_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == G_N_ELEMENTS (values))
|
||||
{
|
||||
if (_gtk_css_number_equal (&pos->x, ¢er))
|
||||
g_string_append (string, "center ");
|
||||
_gtk_css_number_print (&pos->y, string);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
background_position_compute (GtkCssStyleProperty *property,
|
||||
GtkStyleContext *context,
|
||||
GtkCssValue *specified)
|
||||
{
|
||||
GtkCssBackgroundPosition *spos = _gtk_css_value_get_background_position (specified);
|
||||
GtkCssBackgroundPosition cpos;
|
||||
gboolean changed;
|
||||
|
||||
changed = _gtk_css_number_compute (&cpos.x,
|
||||
&spos->x,
|
||||
context);
|
||||
changed |= _gtk_css_number_compute (&cpos.y,
|
||||
&spos->y,
|
||||
context);
|
||||
if (changed)
|
||||
return _gtk_css_value_new_from_background_position (&cpos);
|
||||
return _gtk_css_value_ref (specified);
|
||||
}
|
||||
|
||||
/*** REGISTRATION ***/
|
||||
|
||||
static GtkSymbolicColor *
|
||||
@ -702,6 +877,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
GtkCssNumber number;
|
||||
GtkSymbolicColor *symbolic;
|
||||
GtkCssBackgroundSize default_background_size = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), FALSE, FALSE };
|
||||
GtkCssBackgroundPosition default_background_position = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT)};
|
||||
GtkCssBorderCornerRadius no_corner_radius = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX) };
|
||||
GtkBorder border_of_ones = { 1, 1, 1, 1 };
|
||||
GtkCssBorderImageRepeat border_image_repeat = { GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH };
|
||||
@ -1054,6 +1230,15 @@ _gtk_css_style_property_init_properties (void)
|
||||
background_size_print,
|
||||
background_size_compute,
|
||||
&default_background_size);
|
||||
gtk_css_style_property_register ("background-position",
|
||||
GTK_TYPE_CSS_BACKGROUND_POSITION,
|
||||
GTK_TYPE_CSS_BACKGROUND_POSITION,
|
||||
G_TYPE_NONE,
|
||||
0,
|
||||
background_position_parse,
|
||||
background_position_print,
|
||||
background_position_compute,
|
||||
&default_background_position);
|
||||
|
||||
gtk_css_style_property_register ("border-top-color",
|
||||
GTK_TYPE_SYMBOLIC_COLOR,
|
||||
|
||||
Reference in New Issue
Block a user