[StThemeNode] Add support for 'width' and 'height' CSS properties.
The behavior in respect to borders matches CSS - the properties set the size of the content exclusive of the borders (CSS3 box-sizing property - not implemented here - changes this). min-width/min-height correspond very closely to the CSS meanings. width/height are a little different from the CSS meanings - the CSS meaning is "exactly this size unless overridden by min/max-width/height" - but within the realm of our layout algorithm, making them control natural size is pretty close. This way we can force elements to have a fixed natural or minimum size. https://bugzilla.gnome.org/show_bug.cgi?id=598651
This commit is contained in:
parent
5b769138b6
commit
7239eb2f90
@ -27,6 +27,11 @@ struct _StThemeNode {
|
||||
double border_radius[4];
|
||||
guint padding[4];
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int min_width;
|
||||
int min_height;
|
||||
|
||||
char *background_image;
|
||||
StBorderImage *border_image;
|
||||
|
||||
@ -43,7 +48,7 @@ struct _StThemeNode {
|
||||
CRDeclaration *inline_properties;
|
||||
|
||||
guint properties_computed : 1;
|
||||
guint borders_computed : 1;
|
||||
guint geometry_computed : 1;
|
||||
guint background_computed : 1;
|
||||
guint foreground_computed : 1;
|
||||
guint border_image_computed : 1;
|
||||
@ -1070,14 +1075,25 @@ do_padding_property (StThemeNode *node,
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_borders (StThemeNode *node)
|
||||
do_size_property (StThemeNode *node,
|
||||
CRDeclaration *decl,
|
||||
int *node_value)
|
||||
{
|
||||
gdouble value;
|
||||
|
||||
if (get_length_from_term (node, decl->value, FALSE, &value) == VALUE_FOUND)
|
||||
*node_value = (int) (0.5 + value);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_geometry (StThemeNode *node)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (node->borders_computed)
|
||||
if (node->geometry_computed)
|
||||
return;
|
||||
|
||||
node->borders_computed = TRUE;
|
||||
node->geometry_computed = TRUE;
|
||||
|
||||
ensure_properties (node);
|
||||
|
||||
@ -1087,6 +1103,11 @@ ensure_borders (StThemeNode *node)
|
||||
node->border_color[j] = TRANSPARENT_COLOR;
|
||||
}
|
||||
|
||||
node->width = -1;
|
||||
node->height = -1;
|
||||
node->min_width = -1;
|
||||
node->min_height = -1;
|
||||
|
||||
for (i = 0; i < node->n_properties; i++)
|
||||
{
|
||||
CRDeclaration *decl = node->properties[i];
|
||||
@ -1096,7 +1117,35 @@ ensure_borders (StThemeNode *node)
|
||||
do_border_property (node, decl);
|
||||
else if (g_str_has_prefix (property_name, "padding"))
|
||||
do_padding_property (node, decl);
|
||||
else if (strcmp (property_name, "width") == 0)
|
||||
do_size_property (node, decl, &node->width);
|
||||
else if (strcmp (property_name, "height") == 0)
|
||||
do_size_property (node, decl, &node->height);
|
||||
else if (strcmp (property_name, "min-width") == 0)
|
||||
do_size_property (node, decl, &node->min_width);
|
||||
else if (strcmp (property_name, "min-height") == 0)
|
||||
do_size_property (node, decl, &node->min_height);
|
||||
}
|
||||
|
||||
if (node->width != -1)
|
||||
{
|
||||
if (node->min_width == -1)
|
||||
node->min_width = node->width;
|
||||
else if (node->width <= node->min_width)
|
||||
node->width = node->min_width;
|
||||
}
|
||||
else
|
||||
node->width = node->min_width;
|
||||
|
||||
if (node->height != -1)
|
||||
{
|
||||
if (node->min_height == -1)
|
||||
node->min_height = node->height;
|
||||
else if (node->height <= node->min_height)
|
||||
node->height = node->min_height;
|
||||
}
|
||||
else
|
||||
node->height = node->min_height;
|
||||
}
|
||||
|
||||
double
|
||||
@ -1106,7 +1155,7 @@ st_theme_node_get_border_width (StThemeNode *node,
|
||||
g_return_val_if_fail (ST_IS_THEME_NODE (node), 0.);
|
||||
g_return_val_if_fail (side >= ST_SIDE_TOP && side <= ST_SIDE_LEFT, 0.);
|
||||
|
||||
ensure_borders (node);
|
||||
ensure_geometry (node);
|
||||
|
||||
return node->border_width[side];
|
||||
}
|
||||
@ -1118,11 +1167,47 @@ st_theme_node_get_border_radius (StThemeNode *node,
|
||||
g_return_val_if_fail (ST_IS_THEME_NODE (node), 0.);
|
||||
g_return_val_if_fail (corner >= ST_CORNER_TOPLEFT && corner <= ST_CORNER_BOTTOMLEFT, 0.);
|
||||
|
||||
ensure_borders (node);
|
||||
ensure_geometry (node);
|
||||
|
||||
return node->border_radius[corner];
|
||||
}
|
||||
|
||||
int
|
||||
st_theme_node_get_width (StThemeNode *node)
|
||||
{
|
||||
g_return_val_if_fail (ST_IS_THEME_NODE (node), -1);
|
||||
|
||||
ensure_geometry (node);
|
||||
return node->width;
|
||||
}
|
||||
|
||||
int
|
||||
st_theme_node_get_height (StThemeNode *node)
|
||||
{
|
||||
g_return_val_if_fail (ST_IS_THEME_NODE (node), -1);
|
||||
|
||||
ensure_geometry (node);
|
||||
return node->height;
|
||||
}
|
||||
|
||||
int
|
||||
st_theme_node_get_min_width (StThemeNode *node)
|
||||
{
|
||||
g_return_val_if_fail (ST_IS_THEME_NODE (node), -1);
|
||||
|
||||
ensure_geometry (node);
|
||||
return node->min_width;
|
||||
}
|
||||
|
||||
int
|
||||
st_theme_node_get_min_height (StThemeNode *node)
|
||||
{
|
||||
g_return_val_if_fail (ST_IS_THEME_NODE (node), -1);
|
||||
|
||||
ensure_geometry (node);
|
||||
return node->min_height;
|
||||
}
|
||||
|
||||
static GetFromTermResult
|
||||
get_background_color_from_term (StThemeNode *node,
|
||||
CRTerm *term,
|
||||
@ -1316,7 +1401,7 @@ st_theme_node_get_border_color (StThemeNode *node,
|
||||
g_return_if_fail (ST_IS_THEME_NODE (node));
|
||||
g_return_if_fail (side >= ST_SIDE_TOP && side <= ST_SIDE_LEFT);
|
||||
|
||||
ensure_borders (node);
|
||||
ensure_geometry (node);
|
||||
|
||||
*color = node->border_color[side];
|
||||
}
|
||||
@ -1328,7 +1413,7 @@ st_theme_node_get_padding (StThemeNode *node,
|
||||
g_return_val_if_fail (ST_IS_THEME_NODE (node), 0.);
|
||||
g_return_val_if_fail (side >= ST_SIDE_TOP && side <= ST_SIDE_LEFT, 0.);
|
||||
|
||||
ensure_borders (node);
|
||||
ensure_geometry (node);
|
||||
|
||||
return node->padding[side];
|
||||
}
|
||||
@ -2028,14 +2113,23 @@ st_theme_node_adjust_preferred_width (StThemeNode *node,
|
||||
|
||||
g_return_if_fail (ST_IS_THEME_NODE (node));
|
||||
|
||||
ensure_borders (node);
|
||||
ensure_geometry (node);
|
||||
|
||||
width_inc = get_width_inc (node);
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p += width_inc;
|
||||
{
|
||||
if (node->min_width != -1)
|
||||
*min_width_p = node->min_width;
|
||||
*min_width_p += width_inc;
|
||||
}
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p += width_inc;
|
||||
{
|
||||
if (node->width != -1)
|
||||
*natural_width_p = node->width;
|
||||
*natural_width_p += width_inc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2083,14 +2177,22 @@ st_theme_node_adjust_preferred_height (StThemeNode *node,
|
||||
|
||||
g_return_if_fail (ST_IS_THEME_NODE (node));
|
||||
|
||||
ensure_borders (node);
|
||||
ensure_geometry (node);
|
||||
|
||||
height_inc = get_height_inc (node);
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p += height_inc;
|
||||
{
|
||||
if (node->min_height != -1)
|
||||
*min_height_p = node->min_height;
|
||||
*min_height_p += height_inc;
|
||||
}
|
||||
if (natural_height_p)
|
||||
*natural_height_p += height_inc;
|
||||
{
|
||||
if (node->height != -1)
|
||||
*natural_height_p = node->height;
|
||||
*natural_height_p += height_inc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2111,7 +2213,7 @@ st_theme_node_get_content_box (StThemeNode *node,
|
||||
{
|
||||
g_return_if_fail (ST_IS_THEME_NODE (node));
|
||||
|
||||
ensure_borders (node);
|
||||
ensure_geometry (node);
|
||||
|
||||
content_box->x1 = (int)(0.5 + node->border_width[ST_SIDE_LEFT]) + node->padding[ST_SIDE_LEFT];
|
||||
content_box->y1 = (int)(0.5 + node->border_width[ST_SIDE_TOP]) + node->padding[ST_SIDE_TOP];
|
||||
@ -2135,8 +2237,8 @@ st_theme_node_geometry_equal (StThemeNode *node,
|
||||
{
|
||||
StSide side;
|
||||
|
||||
ensure_borders (node);
|
||||
ensure_borders (other);
|
||||
ensure_geometry (node);
|
||||
ensure_geometry (other);
|
||||
|
||||
for (side = ST_SIDE_TOP; side <= ST_SIDE_LEFT; side++)
|
||||
{
|
||||
@ -2146,5 +2248,10 @@ st_theme_node_geometry_equal (StThemeNode *node,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (node->width != other->width || node->height != other->height)
|
||||
return FALSE;
|
||||
if (node->min_width != other->min_width || node->min_height != other->min_height)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -117,6 +117,11 @@ void st_theme_node_get_border_color (StThemeNode *node,
|
||||
double st_theme_node_get_padding (StThemeNode *node,
|
||||
StSide side);
|
||||
|
||||
int st_theme_node_get_width (StThemeNode *node);
|
||||
int st_theme_node_get_height (StThemeNode *node);
|
||||
int st_theme_node_get_min_width (StThemeNode *node);
|
||||
int st_theme_node_get_min_height (StThemeNode *node);
|
||||
|
||||
StTextDecoration st_theme_node_get_text_decoration (StThemeNode *node);
|
||||
|
||||
/* Font rule processing is pretty complicated, so we just hardcode it
|
||||
|
Loading…
Reference in New Issue
Block a user