mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 05:50:10 +00:00
rendernodeparser: Add support for reusing nodes
We extend the syntax for nodes from: <node-type> { ... } to <node-type> { ... } <node-type> <string> { ... } <string>; where the first is the same as before, the 2nd defines a named node and the last references a previously defined node. Or to give an example: color "node" { bounds: 0 0 10 10; color: red; } transform { bounds: 20 0 10 10; child: "node"; } This will draw the red box twice, once at (0,0) and once at (20,0). The intended use for this is both shortening generated node files as well as allowing to write tests that reuse nodes, in particular when dealing with caches.
This commit is contained in:
parent
348a68599a
commit
5a0c4de07f
@ -2136,19 +2136,60 @@ parse_node (GtkCssParser *parser,
|
||||
{ "mask", parse_mask_node },
|
||||
};
|
||||
GskRenderNode **node_p = out_node;
|
||||
const GtkCssToken *token;
|
||||
guint i;
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_STRING))
|
||||
if (gtk_css_token_is (token, GTK_CSS_TOKEN_STRING))
|
||||
{
|
||||
GskRenderNode *node;
|
||||
char *node_name;
|
||||
|
||||
node_name = gtk_css_parser_consume_string (parser);
|
||||
|
||||
if (context->named_nodes)
|
||||
node = g_hash_table_lookup (context->named_nodes, node_name);
|
||||
else
|
||||
node = NULL;
|
||||
|
||||
if (node)
|
||||
{
|
||||
*node_p = gsk_render_node_ref (node);
|
||||
g_free (node_name);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "No node named \"%s\"", node_name);
|
||||
g_free (node_name);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (node_parsers); i++)
|
||||
{
|
||||
if (gtk_css_parser_try_ident (parser, node_parsers[i].name))
|
||||
{
|
||||
GskRenderNode *node;
|
||||
GtkCssLocation node_name_start_location, node_name_end_location;
|
||||
char *node_name;
|
||||
|
||||
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_STRING))
|
||||
{
|
||||
node_name_start_location = *gtk_css_parser_get_start_location (parser);
|
||||
node_name_end_location = *gtk_css_parser_get_end_location (parser);
|
||||
node_name = gtk_css_parser_consume_string (parser);
|
||||
}
|
||||
else
|
||||
node_name = NULL;
|
||||
|
||||
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected '{' after node name");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_css_parser_end_block_prelude (parser);
|
||||
node = node_parsers[i].func (parser, context);
|
||||
if (node)
|
||||
@ -2156,9 +2197,31 @@ parse_node (GtkCssParser *parser,
|
||||
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||
gtk_css_parser_error_syntax (parser, "Expected '}' at end of node definition");
|
||||
g_clear_pointer (node_p, gsk_render_node_unref);
|
||||
|
||||
if (node_name)
|
||||
{
|
||||
if (context->named_nodes == NULL)
|
||||
context->named_nodes = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, (GDestroyNotify) gsk_render_node_unref);
|
||||
if (g_hash_table_lookup (context->named_nodes, node_name))
|
||||
{
|
||||
gtk_css_parser_error (parser,
|
||||
GTK_CSS_PARSER_ERROR_FAILED,
|
||||
&node_name_start_location,
|
||||
&node_name_end_location,
|
||||
"A node named \"%s\" already exists.", node_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_hash_table_insert (context->named_nodes, g_strdup (node_name), gsk_render_node_ref (node));
|
||||
}
|
||||
}
|
||||
|
||||
*node_p = node;
|
||||
}
|
||||
|
||||
g_free (node_name);
|
||||
|
||||
return node != NULL;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user