Compare commits
2 Commits
shader-too
...
wip/baeder
Author | SHA1 | Date | |
---|---|---|---|
|
3153b8565d | ||
|
52c866490f |
@@ -412,6 +412,7 @@ gtk_css_token_print (const GtkCssToken *token,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GTK_CSS_TOKEN_EOF:
|
case GTK_CSS_TOKEN_EOF:
|
||||||
|
g_string_append (string, "EOF");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GTK_CSS_TOKEN_WHITESPACE:
|
case GTK_CSS_TOKEN_WHITESPACE:
|
||||||
|
@@ -40,6 +40,18 @@
|
|||||||
#include "gtkintl.h"
|
#include "gtkintl.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef GtkCssBuildableIface GtkCssBuildableInterface;
|
||||||
|
G_DEFINE_INTERFACE (GtkCssBuildable, gtk_css_buildable, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_css_buildable_default_init (GtkCssBuildableInterface *iface)
|
||||||
|
{
|
||||||
|
g_message ("%s!!!!", __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef GtkBuildableIface GtkBuildableInterface;
|
typedef GtkBuildableIface GtkBuildableInterface;
|
||||||
G_DEFINE_INTERFACE (GtkBuildable, gtk_buildable, G_TYPE_OBJECT)
|
G_DEFINE_INTERFACE (GtkBuildable, gtk_buildable, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
@@ -27,6 +27,38 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define GTK_TYPE_CSS_BUILDABLE (gtk_css_buildable_get_type ())
|
||||||
|
#define GTK_CSS_BUILDABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CSS_BUILDABLE, GtkCssBuildable))
|
||||||
|
#define GTK_CSS_BUILDABLE_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GTK_TYPE_CSS_BUILDABLE, GtkCssBuildableIface))
|
||||||
|
#define GTK_IS_CSS_BUILDABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CSS_BUILDABLE))
|
||||||
|
#define GTK_CSS_BUILDABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_CSS_BUILDABLE, GtkCssBuildableIface))
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _GtkCssBuildable GtkCssBuildable; /* Dummy typedef */
|
||||||
|
typedef struct _GtkCssBuildableIface GtkCssBuildableIface;
|
||||||
|
|
||||||
|
|
||||||
|
struct _GtkCssBuildableIface
|
||||||
|
{
|
||||||
|
GTypeInterface g_iface;
|
||||||
|
|
||||||
|
void (* set_name) (GtkCssBuildable *self,
|
||||||
|
const char *name);
|
||||||
|
|
||||||
|
gboolean (* set_property) (GtkCssBuildable *self,
|
||||||
|
const char *prop_name,
|
||||||
|
size_t prop_name_len,
|
||||||
|
GType value_type,
|
||||||
|
gpointer value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
GType gtk_css_buildable_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
|
||||||
#define GTK_TYPE_BUILDABLE (gtk_buildable_get_type ())
|
#define GTK_TYPE_BUILDABLE (gtk_buildable_get_type ())
|
||||||
#define GTK_BUILDABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_BUILDABLE, GtkBuildable))
|
#define GTK_BUILDABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_BUILDABLE, GtkBuildable))
|
||||||
#define GTK_BUILDABLE_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GTK_TYPE_BUILDABLE, GtkBuildableIface))
|
#define GTK_BUILDABLE_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GTK_TYPE_BUILDABLE, GtkBuildableIface))
|
||||||
@@ -101,7 +133,7 @@ struct _GtkBuildableParser
|
|||||||
* content below <child>. To handle an element, the implementation
|
* content below <child>. To handle an element, the implementation
|
||||||
* must fill in the @parser and @user_data and return %TRUE.
|
* must fill in the @parser and @user_data and return %TRUE.
|
||||||
* #GtkWidget implements this to parse keyboard accelerators specified
|
* #GtkWidget implements this to parse keyboard accelerators specified
|
||||||
* in <accelerator> elements.
|
* in <accelerator> elements.
|
||||||
* Note that @user_data must be freed in @custom_tag_end or @custom_finished.
|
* Note that @user_data must be freed in @custom_tag_end or @custom_finished.
|
||||||
* @custom_tag_end: Called for the end tag of each custom element that is
|
* @custom_tag_end: Called for the end tag of each custom element that is
|
||||||
* handled by the buildable (see @custom_tag_start).
|
* handled by the buildable (see @custom_tag_start).
|
||||||
|
561
gtk/gtkbuildercssparser.c
Normal file
561
gtk/gtkbuildercssparser.c
Normal file
@@ -0,0 +1,561 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include "gtkbuildercssparserprivate.h"
|
||||||
|
#include "gtkbuilderscopeprivate.h"
|
||||||
|
#include "gtkbuildable.h"
|
||||||
|
|
||||||
|
static GObject * parse_object (GtkBuilderCssParser *self,
|
||||||
|
GObject *template_object);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
guint signal_id;
|
||||||
|
GQuark signal_detail;
|
||||||
|
char *signal_name; // TODO: Remove?
|
||||||
|
char *handler_name;
|
||||||
|
guint after: 1;
|
||||||
|
guint swapped: 1;
|
||||||
|
} SignalConnectionData;
|
||||||
|
|
||||||
|
GtkBuilderCssParser *
|
||||||
|
gtk_builder_css_parser_new (void)
|
||||||
|
{
|
||||||
|
GtkBuilderCssParser *self = g_new0 (GtkBuilderCssParser, 1);
|
||||||
|
|
||||||
|
self->object_table = g_hash_table_new (g_str_hash,
|
||||||
|
g_str_equal);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
translated_string_parse_func (GtkCssParser *parser,
|
||||||
|
guint arg,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
char **str = data;
|
||||||
|
g_assert (arg == 0);
|
||||||
|
|
||||||
|
*str = g_strdup (gtk_css_parser_get_token (parser)->string.string);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SignalConnectionData *
|
||||||
|
parse_signals (GtkBuilderCssParser *self,
|
||||||
|
GType object_type,
|
||||||
|
guint *out_n_connections)
|
||||||
|
{
|
||||||
|
GtkCssParser *parser = self->css_parser;
|
||||||
|
GArray *connection_data;
|
||||||
|
|
||||||
|
if (!gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COLON))
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected colon after signal keyword");
|
||||||
|
*out_n_connections = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
connection_data = g_array_new (FALSE, TRUE, sizeof (SignalConnectionData));
|
||||||
|
gtk_css_parser_end_block_prelude (parser);
|
||||||
|
while (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||||
|
{
|
||||||
|
const GtkCssToken *token = gtk_css_parser_get_token (parser);
|
||||||
|
SignalConnectionData connection;
|
||||||
|
|
||||||
|
if (token->type == GTK_CSS_TOKEN_IDENT ||
|
||||||
|
token->type == GTK_CSS_TOKEN_STRING)
|
||||||
|
{
|
||||||
|
connection.signal_name = g_strdup (token->string.string);
|
||||||
|
if (!g_signal_parse_name (token->string.string, object_type,
|
||||||
|
&connection.signal_id,
|
||||||
|
&connection.signal_detail,
|
||||||
|
FALSE))
|
||||||
|
{
|
||||||
|
// TODO: Check for proper signal detail
|
||||||
|
gtk_css_parser_error_syntax (parser, "Signal '%s' is invalid for type '%s'",
|
||||||
|
token->string.string,
|
||||||
|
g_type_name (object_type));
|
||||||
|
goto next_signal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected signal name");
|
||||||
|
goto next_signal;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_css_parser_start_semicolon_block (parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||||
|
|
||||||
|
gtk_css_parser_consume_token (parser); /* Skip signal name */
|
||||||
|
if (!gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COLON))
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected colon after signal name, but got %s",
|
||||||
|
gtk_css_token_to_string (gtk_css_parser_get_token (parser)));
|
||||||
|
goto next_signal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now parse the actual signal */
|
||||||
|
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_STRING))
|
||||||
|
{
|
||||||
|
token = gtk_css_parser_get_token (parser);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_css_parser_end_block_prelude (parser);
|
||||||
|
|
||||||
|
// TODO Implement other signal stuff, like swapped.
|
||||||
|
connection.after = FALSE;
|
||||||
|
connection.swapped = FALSE;
|
||||||
|
|
||||||
|
if (!gtk_css_parser_has_ident (parser, "handler"))
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected 'handler'");
|
||||||
|
goto next_signal;
|
||||||
|
}
|
||||||
|
gtk_css_parser_consume_token (parser);
|
||||||
|
if (!gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COLON))
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected colon");
|
||||||
|
goto next_signal;
|
||||||
|
}
|
||||||
|
token = gtk_css_parser_get_token (parser);
|
||||||
|
}
|
||||||
|
connection.handler_name = g_strdup (token->string.string);
|
||||||
|
|
||||||
|
g_array_append_val (connection_data, connection);
|
||||||
|
|
||||||
|
next_signal:
|
||||||
|
gtk_css_parser_end_block (parser); /* Signal block */
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_n_connections = connection_data->len;
|
||||||
|
return (SignalConnectionData *)g_array_free (connection_data, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
parse_property (GtkBuilderCssParser *self,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
GValue *out_value)
|
||||||
|
{
|
||||||
|
GtkCssParser *parser = self->css_parser;
|
||||||
|
|
||||||
|
if (pspec->value_type == G_TYPE_BOOLEAN)
|
||||||
|
{
|
||||||
|
const GtkCssToken *token = gtk_css_parser_get_token (parser);
|
||||||
|
|
||||||
|
if (token->type != GTK_CSS_TOKEN_IDENT)
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Invalid boolean value: '%s'",
|
||||||
|
token->string.string);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp (token->string.string, "true") == 0)
|
||||||
|
{
|
||||||
|
g_value_init (out_value, G_TYPE_BOOLEAN);
|
||||||
|
g_value_set_boolean (out_value, TRUE);
|
||||||
|
}
|
||||||
|
else if (strcmp (token->string.string, "false") == 0)
|
||||||
|
{
|
||||||
|
g_value_init (out_value, G_TYPE_BOOLEAN);
|
||||||
|
g_value_set_boolean (out_value, FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Invalid boolean value: '%s'",
|
||||||
|
token->string.string);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_css_parser_consume_token (parser);
|
||||||
|
}
|
||||||
|
else if (pspec->value_type == G_TYPE_STRING)
|
||||||
|
{
|
||||||
|
const GtkCssToken *token = gtk_css_parser_get_token (parser);
|
||||||
|
|
||||||
|
if (gtk_css_parser_has_function (parser, "_"))
|
||||||
|
{
|
||||||
|
char *string;
|
||||||
|
|
||||||
|
gtk_css_parser_consume_function (parser, 1, 1, translated_string_parse_func, &string);
|
||||||
|
// TODO: Imlpement translation stuff
|
||||||
|
|
||||||
|
g_value_init (out_value, G_TYPE_STRING);
|
||||||
|
g_value_take_string (out_value, string);
|
||||||
|
}
|
||||||
|
else if (token->type == GTK_CSS_TOKEN_STRING)
|
||||||
|
{
|
||||||
|
g_value_init (out_value, G_TYPE_STRING);
|
||||||
|
g_value_set_string (out_value, token->string.string);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected a string value");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pspec->value_type == G_TYPE_FLOAT ||
|
||||||
|
pspec->value_type == G_TYPE_DOUBLE ||
|
||||||
|
pspec->value_type == G_TYPE_INT)
|
||||||
|
{
|
||||||
|
double d;
|
||||||
|
|
||||||
|
if (!gtk_css_parser_consume_number (parser, &d))
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected a number");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
// TODO: We should probably handle int differently, so we show a warning when
|
||||||
|
// finding a float/double?
|
||||||
|
|
||||||
|
g_value_init (out_value, pspec->value_type);
|
||||||
|
if (pspec->value_type == G_TYPE_FLOAT)
|
||||||
|
g_value_set_float (out_value, d);
|
||||||
|
else if (pspec->value_type == G_TYPE_DOUBLE)
|
||||||
|
g_value_set_double (out_value, d);
|
||||||
|
else if (pspec->value_type == G_TYPE_INT)
|
||||||
|
g_value_set_int (out_value, d);
|
||||||
|
else
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
else if (G_TYPE_IS_ENUM (pspec->value_type))
|
||||||
|
{
|
||||||
|
const GtkCssToken *token = gtk_css_parser_get_token (parser);
|
||||||
|
const GEnumValue *enum_value;
|
||||||
|
GEnumClass *enum_class;
|
||||||
|
|
||||||
|
if (token->type != GTK_CSS_TOKEN_IDENT)
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected an enum value name");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum_class = g_type_class_ref (pspec->value_type);
|
||||||
|
enum_value = g_enum_get_value_by_nick (enum_class, token->string.string);
|
||||||
|
|
||||||
|
g_value_init (out_value, pspec->value_type);
|
||||||
|
g_value_set_enum (out_value, enum_value->value);
|
||||||
|
g_type_class_unref (enum_class);
|
||||||
|
}
|
||||||
|
else if (pspec->value_type == G_TYPE_STRV)
|
||||||
|
{
|
||||||
|
const GtkCssToken *token = gtk_css_parser_get_token (parser);
|
||||||
|
GPtrArray *strings = g_ptr_array_sized_new (16);
|
||||||
|
|
||||||
|
while (token->type != GTK_CSS_TOKEN_EOF)
|
||||||
|
{
|
||||||
|
if (token->type != GTK_CSS_TOKEN_STRING)
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected a string");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ptr_array_add (strings, gtk_css_parser_consume_string (parser));
|
||||||
|
|
||||||
|
token = gtk_css_parser_get_token (parser);
|
||||||
|
if (token->type == GTK_CSS_TOKEN_EOF)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (token->type != GTK_CSS_TOKEN_COMMA)
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected comma after string when parsing GStrv typed property");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_css_parser_consume_token (parser);
|
||||||
|
token = gtk_css_parser_get_token (parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ptr_array_add (strings, NULL);
|
||||||
|
|
||||||
|
g_value_init (out_value, pspec->value_type);
|
||||||
|
g_value_set_boxed (out_value, g_ptr_array_free (strings, FALSE));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (g_type_is_a (pspec->value_type, G_TYPE_OBJECT))
|
||||||
|
{
|
||||||
|
GObject *obj = parse_object (self, NULL);
|
||||||
|
|
||||||
|
g_value_init (out_value, pspec->value_type);
|
||||||
|
g_value_set_object (out_value, obj);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Unable to parse properties of type %s",
|
||||||
|
g_type_name (pspec->value_type));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GObject *
|
||||||
|
parse_object (GtkBuilderCssParser *self,
|
||||||
|
GObject *template_object)
|
||||||
|
{
|
||||||
|
#define MAX_PROPERTIES 64
|
||||||
|
GtkCssParser *parser = self->css_parser;
|
||||||
|
GObject *object = NULL;
|
||||||
|
GObjectClass *object_class;
|
||||||
|
const char *type_name;
|
||||||
|
GType type;
|
||||||
|
char *buildable_id = NULL;
|
||||||
|
char *property_names[MAX_PROPERTIES];
|
||||||
|
GValue property_values[MAX_PROPERTIES];
|
||||||
|
int n_properties = 0;
|
||||||
|
char *buildable_prop_names[MAX_PROPERTIES];
|
||||||
|
GValue buildable_prop_values[MAX_PROPERTIES];
|
||||||
|
int n_buildable_properties = 0;
|
||||||
|
guint n_signal_connections = 0;
|
||||||
|
SignalConnectionData *signal_connections;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
gtk_css_parser_start_semicolon_block (parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||||
|
|
||||||
|
/* Get us the ident, which will determine what we parse and how we parse it */
|
||||||
|
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected type name");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
type_name = gtk_css_parser_get_token (parser)->string.string;
|
||||||
|
type = g_type_from_name (type_name);
|
||||||
|
|
||||||
|
if (type == G_TYPE_INVALID)
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Unknown type name '%s'", type_name);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (template_object &&
|
||||||
|
strcmp (type_name, G_OBJECT_TYPE_NAME (template_object)) != 0)
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser,
|
||||||
|
"Expected object type '%s' but found '%s'",
|
||||||
|
G_OBJECT_TYPE_NAME (template_object),
|
||||||
|
type_name);
|
||||||
|
g_object_unref (object);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
gtk_css_parser_consume_token (parser);
|
||||||
|
|
||||||
|
object_class = g_type_class_ref (type);
|
||||||
|
g_assert (object_class);
|
||||||
|
|
||||||
|
memset (property_values, 0, MAX_PROPERTIES * sizeof (GValue));
|
||||||
|
memset (buildable_prop_values, 0, MAX_PROPERTIES * sizeof (GValue));
|
||||||
|
gtk_css_parser_end_block_prelude (parser);
|
||||||
|
while (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||||
|
{
|
||||||
|
const char *token_string;
|
||||||
|
char *prop_name = NULL;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected property name");
|
||||||
|
goto next_prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
token_string = gtk_css_parser_get_token (parser)->string.string;
|
||||||
|
/* Special cases */
|
||||||
|
if (strcmp (token_string, "signals") == 0)
|
||||||
|
{
|
||||||
|
gtk_css_parser_consume_token (parser);
|
||||||
|
gtk_css_parser_start_semicolon_block (parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||||
|
signal_connections = parse_signals (self, type, &n_signal_connections);
|
||||||
|
goto next_prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_name = g_strdup (token_string);
|
||||||
|
pspec = g_object_class_find_property (object_class, prop_name);
|
||||||
|
gtk_css_parser_consume_token (parser);
|
||||||
|
|
||||||
|
gtk_css_parser_start_semicolon_block (parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||||
|
if (pspec)
|
||||||
|
{
|
||||||
|
// TODO: Validate pspec for correct flags, e.g. writable etc.
|
||||||
|
if (!gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COLON))
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected ':' after property name");
|
||||||
|
goto next_prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parse_property (self, pspec, &property_values[n_properties]))
|
||||||
|
goto next_prop;
|
||||||
|
|
||||||
|
property_names[n_properties] = g_steal_pointer (&prop_name);
|
||||||
|
n_properties++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COLON))
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected colon after property name");
|
||||||
|
goto next_prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buildable ID special case */
|
||||||
|
if (strcmp (prop_name, "id") == 0)
|
||||||
|
{
|
||||||
|
buildable_id = gtk_css_parser_consume_string (parser);
|
||||||
|
if (!buildable_id)
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected string ID");
|
||||||
|
|
||||||
|
goto next_prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
|
||||||
|
gtk_css_parser_end_block_prelude (parser);
|
||||||
|
|
||||||
|
// TODO: Parse other things than objects
|
||||||
|
while (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||||
|
{
|
||||||
|
GObject *o = parse_object (self, NULL);
|
||||||
|
|
||||||
|
if (!o)
|
||||||
|
goto next_prop;
|
||||||
|
|
||||||
|
g_value_init (&buildable_prop_values[n_buildable_properties], G_TYPE_OBJECT);
|
||||||
|
g_value_set_object (&buildable_prop_values[n_buildable_properties], o);
|
||||||
|
buildable_prop_names[n_buildable_properties] = g_strdup (prop_name);
|
||||||
|
n_buildable_properties++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next_prop:
|
||||||
|
gtk_css_parser_end_block (parser); /* Property block */
|
||||||
|
g_free (prop_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (template_object)
|
||||||
|
{
|
||||||
|
object = g_object_ref (template_object);
|
||||||
|
g_object_setv (object, n_properties,
|
||||||
|
(const char **)property_names,
|
||||||
|
property_values);
|
||||||
|
}
|
||||||
|
else /* Create a new object */
|
||||||
|
{
|
||||||
|
object = g_object_new_with_properties (type, n_properties,
|
||||||
|
(const char **)property_names,
|
||||||
|
property_values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now set the buildable properties */
|
||||||
|
for (i = 0; i < n_buildable_properties; i++)
|
||||||
|
{
|
||||||
|
// TODO: Fix this to allow non-GObject values
|
||||||
|
if (GTK_IS_CSS_BUILDABLE (object))
|
||||||
|
{
|
||||||
|
GObject *o = g_value_get_object (&buildable_prop_values[i]);
|
||||||
|
GtkCssBuildableIface *iface = GTK_CSS_BUILDABLE_GET_IFACE (object);
|
||||||
|
/* TODO: WALK UP HIERARCHY AND SHIT */
|
||||||
|
iface->set_property (GTK_CSS_BUILDABLE (object),
|
||||||
|
buildable_prop_names[i], strlen (buildable_prop_names[i]),
|
||||||
|
G_OBJECT_TYPE (o), o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buildable_id)
|
||||||
|
{
|
||||||
|
GtkCssBuildableIface *iface = GTK_CSS_BUILDABLE_GET_IFACE (object);
|
||||||
|
if (iface)
|
||||||
|
iface->set_name (GTK_CSS_BUILDABLE (object), buildable_id);
|
||||||
|
|
||||||
|
g_hash_table_insert (self->object_table,
|
||||||
|
g_steal_pointer (&buildable_id),
|
||||||
|
object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect signal handlers */
|
||||||
|
for (i = 0; i < n_signal_connections; i++)
|
||||||
|
{
|
||||||
|
SignalConnectionData *data = &signal_connections[i];
|
||||||
|
GClosure *closure;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
// TODO vvvv
|
||||||
|
GtkBuilder *b = gtk_builder_new ();
|
||||||
|
closure = gtk_builder_scope_create_closure (self->builder_scope,
|
||||||
|
b,
|
||||||
|
data->handler_name,
|
||||||
|
data->swapped,
|
||||||
|
self->template_object ? self->template_object : object,
|
||||||
|
&error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_error ("%s", error->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_signal_connect_closure_by_id (object,
|
||||||
|
data->signal_id,
|
||||||
|
data->signal_detail,
|
||||||
|
closure,
|
||||||
|
data->after);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_css_parser_end_block (parser); /* Object block */
|
||||||
|
return object;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
gtk_css_parser_end_block (parser);
|
||||||
|
|
||||||
|
if (object)
|
||||||
|
g_object_unref (object);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_objects (GtkBuilderCssParser *self,
|
||||||
|
GObject *template_object)
|
||||||
|
{
|
||||||
|
const GtkCssToken *token;
|
||||||
|
GtkCssParser *parser = self->css_parser;
|
||||||
|
|
||||||
|
for (token = gtk_css_parser_get_token (parser);
|
||||||
|
!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF);
|
||||||
|
token = gtk_css_parser_get_token (parser))
|
||||||
|
{
|
||||||
|
parse_object (self, template_object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parser_error_func (GtkCssParser *parser,
|
||||||
|
const GtkCssLocation *start,
|
||||||
|
const GtkCssLocation *end,
|
||||||
|
const GError *error,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkCssSection *section = gtk_css_section_new (gtk_css_parser_get_file (parser), start, end);
|
||||||
|
|
||||||
|
g_warning ("%s: %s", error->message, gtk_css_section_to_string (section));
|
||||||
|
|
||||||
|
gtk_css_section_unref (section);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
gtk_builder_css_parser_extend_with_template (GtkBuilderCssParser *self,
|
||||||
|
GType template_type,
|
||||||
|
GObject *template_object,
|
||||||
|
GBytes *bytes)
|
||||||
|
{
|
||||||
|
self->css_parser = gtk_css_parser_new_for_bytes (bytes, NULL, NULL, parser_error_func,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
self->template_object = template_object;
|
||||||
|
parse_objects (self, template_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
GObject *
|
||||||
|
gtk_builder_css_parser_get_object (GtkBuilderCssParser *self,
|
||||||
|
const char *object_name)
|
||||||
|
{
|
||||||
|
return g_hash_table_lookup (self->object_table, object_name);
|
||||||
|
}
|
29
gtk/gtkbuildercssparserprivate.h
Normal file
29
gtk/gtkbuildercssparserprivate.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef __GTK_BUILDER_CSS_PARSER_PRIVATE_H__
|
||||||
|
#define __GTK_BUILDER_CSS_PARSER_PRIVATE_H__
|
||||||
|
|
||||||
|
#include "gtkwidget.h"
|
||||||
|
#include <gtk/css/gtkcss.h>
|
||||||
|
#include "gtk/css/gtkcssparserprivate.h"
|
||||||
|
|
||||||
|
typedef struct _GtkBuilderCssParser GtkBuilderCssParser;
|
||||||
|
|
||||||
|
struct _GtkBuilderCssParser
|
||||||
|
{
|
||||||
|
GtkCssParser *css_parser;
|
||||||
|
|
||||||
|
GObject *template_object;
|
||||||
|
GtkBuilderScope *builder_scope;
|
||||||
|
GHashTable *object_table; /* Name -> Object */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
GtkBuilderCssParser * gtk_builder_css_parser_new (void);
|
||||||
|
|
||||||
|
void gtk_builder_css_parser_extend_with_template (GtkBuilderCssParser *self,
|
||||||
|
GType template_type,
|
||||||
|
GObject *object,
|
||||||
|
GBytes *buffer);
|
||||||
|
GObject * gtk_builder_css_parser_get_object (GtkBuilderCssParser *self,
|
||||||
|
const char *object_name);
|
||||||
|
|
||||||
|
#endif
|
49
gtk/gtkcombobox.cssui
Normal file
49
gtk/gtkcombobox.cssui
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
GtkComboBox {
|
||||||
|
children: {
|
||||||
|
GtkBox {
|
||||||
|
id: "box";
|
||||||
|
css-classes: "linked";
|
||||||
|
|
||||||
|
children: {
|
||||||
|
GtkToggleButton {
|
||||||
|
id: "button";
|
||||||
|
|
||||||
|
children: GtkBox {
|
||||||
|
children: GtkBuiltinIcon {
|
||||||
|
id: "arrow";
|
||||||
|
css-name: "arrow";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
signals: {
|
||||||
|
toggled: "gtk_combo_box_button_toggled";
|
||||||
|
"clicked": {
|
||||||
|
handler: "gtk_combo_box_button_toggled";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
GtkTreePopover {
|
||||||
|
id: "popup_widget";
|
||||||
|
has_arrow: false;
|
||||||
|
cell-area: GtkCellAreaBox {
|
||||||
|
id: "area";
|
||||||
|
};
|
||||||
|
|
||||||
|
signals: {
|
||||||
|
menu-activate: "gtk_combo_box_menu_activate";
|
||||||
|
show: "gtk_combo_box_menu_show";
|
||||||
|
hide: "gtk_combo_box_menu_hide";
|
||||||
|
}
|
||||||
|
|
||||||
|
children:GtkEventControllerKey {
|
||||||
|
signals: {
|
||||||
|
key-pressed: "gtk_combo_box_menu_key";
|
||||||
|
key-released: "gtk_combo_box_menu_key";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -7169,7 +7169,8 @@ list_selection_changed (GtkTreeSelection *selection,
|
|||||||
if (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->browse_files_tree_view)) == NULL)
|
if (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->browse_files_tree_view)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (priv->location_entry)
|
if (priv->location_entry &&
|
||||||
|
priv->browse_files_model)
|
||||||
update_chooser_entry (impl);
|
update_chooser_entry (impl);
|
||||||
|
|
||||||
location_bar_update (impl);
|
location_bar_update (impl);
|
||||||
|
36
gtk/gtklockbutton.cssui
Normal file
36
gtk/gtklockbutton.cssui
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
GtkLockButton {
|
||||||
|
can-focus: true;
|
||||||
|
receives-default: true;
|
||||||
|
|
||||||
|
children: {
|
||||||
|
GtkBox {
|
||||||
|
id: "box";
|
||||||
|
halign: center;
|
||||||
|
valign: center;
|
||||||
|
spacing: 6;
|
||||||
|
children: {
|
||||||
|
GtkImage {
|
||||||
|
id: "image";
|
||||||
|
icon-name: "missing-image";
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkStack {
|
||||||
|
id: "stack";
|
||||||
|
children: {
|
||||||
|
GtkLabel {
|
||||||
|
id: "label_lock";
|
||||||
|
xalign: 0;
|
||||||
|
label: _("Lock");
|
||||||
|
}
|
||||||
|
GtkLabel {
|
||||||
|
id: "label_unlock";
|
||||||
|
xalign: 0;
|
||||||
|
label: _("Unlock");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
gtk/gtkstatusbar.cssui
Normal file
26
gtk/gtkstatusbar.cssui
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
GtkStatusBar {
|
||||||
|
children: {
|
||||||
|
GtkFrame {
|
||||||
|
id: "frame";
|
||||||
|
shadow-type: none;
|
||||||
|
hexpand: true;
|
||||||
|
|
||||||
|
children: {
|
||||||
|
GtkBox {
|
||||||
|
id: "message_area";
|
||||||
|
spacing: 4;
|
||||||
|
|
||||||
|
children: {
|
||||||
|
GtkLabel {
|
||||||
|
id: "label";
|
||||||
|
halign: start;
|
||||||
|
valign: center;
|
||||||
|
ellipsize: end;
|
||||||
|
single-line-mode: true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
gtk/gtkvolumebutton.cssui
Normal file
14
gtk/gtkvolumebutton.cssui
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
GtkVolumeButton {
|
||||||
|
can-focus: true;
|
||||||
|
receives-default: true;
|
||||||
|
has-tooltip: true;
|
||||||
|
relief: none;
|
||||||
|
focus-on-click: false;
|
||||||
|
orientation: vertical;
|
||||||
|
icons: "audio-volume-high", "audio-volume-low", "audio-volume-medium";
|
||||||
|
adjustment: GtkAdjustment {
|
||||||
|
upper: 1;
|
||||||
|
step-increment: 0.02;
|
||||||
|
page-increment: 0.2;
|
||||||
|
};
|
||||||
|
}
|
129
gtk/gtkwidget.c
129
gtk/gtkwidget.c
@@ -651,6 +651,10 @@ static gboolean gtk_widget_real_can_activate_accel (GtkWidget *widg
|
|||||||
guint signal_id);
|
guint signal_id);
|
||||||
|
|
||||||
static void gtk_widget_buildable_interface_init (GtkBuildableIface *iface);
|
static void gtk_widget_buildable_interface_init (GtkBuildableIface *iface);
|
||||||
|
static void gtk_widget_css_buildable_interface_init (GtkCssBuildableIface *iface);
|
||||||
|
static void gtk_widget_css_buildable_set_name (GtkCssBuildable *self,
|
||||||
|
const char *name);
|
||||||
|
|
||||||
static void gtk_widget_buildable_set_name (GtkBuildable *buildable,
|
static void gtk_widget_buildable_set_name (GtkBuildable *buildable,
|
||||||
const gchar *name);
|
const gchar *name);
|
||||||
static const gchar * gtk_widget_buildable_get_name (GtkBuildable *buildable);
|
static const gchar * gtk_widget_buildable_get_name (GtkBuildable *buildable);
|
||||||
@@ -743,9 +747,16 @@ gtk_widget_get_type (void)
|
|||||||
|
|
||||||
const GInterfaceInfo buildable_info =
|
const GInterfaceInfo buildable_info =
|
||||||
{
|
{
|
||||||
(GInterfaceInitFunc) gtk_widget_buildable_interface_init,
|
(GInterfaceInitFunc) gtk_widget_buildable_interface_init,
|
||||||
(GInterfaceFinalizeFunc) NULL,
|
(GInterfaceFinalizeFunc) NULL,
|
||||||
NULL /* interface data */
|
NULL /* interface data */
|
||||||
|
};
|
||||||
|
|
||||||
|
const GInterfaceInfo css_buildable_info =
|
||||||
|
{
|
||||||
|
(GInterfaceInitFunc) gtk_widget_css_buildable_interface_init,
|
||||||
|
(GInterfaceFinalizeFunc) NULL,
|
||||||
|
NULL /* interface data */
|
||||||
};
|
};
|
||||||
|
|
||||||
const GInterfaceInfo constraint_target_info =
|
const GInterfaceInfo constraint_target_info =
|
||||||
@@ -767,6 +778,9 @@ gtk_widget_get_type (void)
|
|||||||
&accessibility_info) ;
|
&accessibility_info) ;
|
||||||
g_type_add_interface_static (widget_type, GTK_TYPE_BUILDABLE,
|
g_type_add_interface_static (widget_type, GTK_TYPE_BUILDABLE,
|
||||||
&buildable_info) ;
|
&buildable_info) ;
|
||||||
|
g_type_add_interface_static (widget_type, GTK_TYPE_CSS_BUILDABLE,
|
||||||
|
&css_buildable_info) ;
|
||||||
|
|
||||||
g_type_add_interface_static (widget_type, GTK_TYPE_CONSTRAINT_TARGET,
|
g_type_add_interface_static (widget_type, GTK_TYPE_CONSTRAINT_TARGET,
|
||||||
&constraint_target_info) ;
|
&constraint_target_info) ;
|
||||||
}
|
}
|
||||||
@@ -8690,6 +8704,51 @@ gtk_widget_buildable_add_child (GtkBuildable *buildable,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_widget_css_buildable_set_name (GtkCssBuildable *self,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
g_object_set_qdata_full (G_OBJECT (self), quark_builder_set_name,
|
||||||
|
g_strdup (name), g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_widget_css_buildable_set_property (GtkCssBuildable *self,
|
||||||
|
const char *prop_name,
|
||||||
|
size_t prop_name_len,
|
||||||
|
GType value_type,
|
||||||
|
gpointer value)
|
||||||
|
{
|
||||||
|
if (prop_name_len != strlen ("children"))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (strcmp (prop_name, "children") == 0)
|
||||||
|
{
|
||||||
|
if (g_type_is_a (value_type, GTK_TYPE_WIDGET))
|
||||||
|
{
|
||||||
|
if (GTK_IS_CONTAINER (self))
|
||||||
|
gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (value));
|
||||||
|
else
|
||||||
|
gtk_widget_set_parent (GTK_WIDGET (value), GTK_WIDGET (self));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (g_type_is_a (value_type, GTK_TYPE_EVENT_CONTROLLER))
|
||||||
|
{
|
||||||
|
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_widget_css_buildable_interface_init (GtkCssBuildableIface *iface)
|
||||||
|
{
|
||||||
|
iface->set_name = gtk_widget_css_buildable_set_name;
|
||||||
|
iface->set_property = gtk_widget_css_buildable_set_property;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_widget_buildable_interface_init (GtkBuildableIface *iface)
|
gtk_widget_buildable_interface_init (GtkBuildableIface *iface)
|
||||||
{
|
{
|
||||||
@@ -11314,6 +11373,7 @@ setup_template_child (GtkWidgetTemplate *template_data,
|
|||||||
* before the construct properties are set. Properties passed to g_object_new()
|
* before the construct properties are set. Properties passed to g_object_new()
|
||||||
* should take precedence over properties set in the private template XML.
|
* should take precedence over properties set in the private template XML.
|
||||||
*/
|
*/
|
||||||
|
#include "gtkbuildercssparserprivate.h"
|
||||||
void
|
void
|
||||||
gtk_widget_init_template (GtkWidget *widget)
|
gtk_widget_init_template (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
@@ -11324,12 +11384,69 @@ gtk_widget_init_template (GtkWidget *widget)
|
|||||||
GSList *l;
|
GSList *l;
|
||||||
GType class_type;
|
GType class_type;
|
||||||
|
|
||||||
|
template = GTK_WIDGET_GET_CLASS (widget)->priv->template;
|
||||||
|
class_type = G_OBJECT_TYPE (widget);
|
||||||
|
if (strcmp (G_OBJECT_TYPE_NAME (widget), "GtkComboBox") == 0 &&
|
||||||
|
g_type_from_name ("GtkComboBox") != G_TYPE_INVALID) {
|
||||||
|
GBytes *css_data;
|
||||||
|
GtkBuilderCssParser *p = gtk_builder_css_parser_new ();
|
||||||
|
|
||||||
|
char *d;
|
||||||
|
|
||||||
|
g_file_get_contents ("../gtk/gtkcombobox.cssui", &d, NULL, NULL);
|
||||||
|
|
||||||
|
css_data = g_bytes_new_static (d, strlen (d));
|
||||||
|
|
||||||
|
if (template->scope)
|
||||||
|
p->builder_scope = template->scope;
|
||||||
|
else
|
||||||
|
p->builder_scope = gtk_builder_cscope_new ();
|
||||||
|
|
||||||
|
gtk_builder_css_parser_extend_with_template (p,
|
||||||
|
class_type,
|
||||||
|
G_OBJECT (widget),
|
||||||
|
css_data);
|
||||||
|
/* Build the automatic child data
|
||||||
|
*/
|
||||||
|
template = GTK_WIDGET_GET_CLASS (widget)->priv->template;
|
||||||
|
for (l = template->children; l; l = l->next)
|
||||||
|
{
|
||||||
|
GHashTable *auto_child_hash;
|
||||||
|
AutomaticChildClass *child_class = l->data;
|
||||||
|
GObject *o;
|
||||||
|
|
||||||
|
/* This will setup the pointer of an automated child, and cause
|
||||||
|
* it to be available in any GtkBuildable.get_internal_child()
|
||||||
|
* invocations which may follow by reference in child classes.
|
||||||
|
*/
|
||||||
|
o = gtk_builder_css_parser_get_object (p, child_class->name);
|
||||||
|
if (!o)
|
||||||
|
{
|
||||||
|
g_critical ("Unable to retrieve object '%s' from class template for type '%s' while building a '%s'",
|
||||||
|
child_class->name, g_type_name (class_type), G_OBJECT_TYPE_NAME (widget));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto_child_hash = get_auto_child_hash (widget, class_type, TRUE);
|
||||||
|
g_hash_table_insert (auto_child_hash, child_class->name, g_object_ref (o));
|
||||||
|
|
||||||
|
if (child_class->offset != 0)
|
||||||
|
{
|
||||||
|
gpointer field_p;
|
||||||
|
|
||||||
|
/* Assign 'object' to the specified offset in the instance (or private) data */
|
||||||
|
field_p = G_STRUCT_MEMBER_P (widget, child_class->offset);
|
||||||
|
(* (gpointer *) field_p) = o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||||
|
|
||||||
object = G_OBJECT (widget);
|
object = G_OBJECT (widget);
|
||||||
class_type = G_OBJECT_TYPE (widget);
|
|
||||||
|
|
||||||
template = GTK_WIDGET_GET_CLASS (widget)->priv->template;
|
|
||||||
g_return_if_fail (template != NULL);
|
g_return_if_fail (template != NULL);
|
||||||
|
|
||||||
builder = gtk_builder_new ();
|
builder = gtk_builder_new ();
|
||||||
|
@@ -173,6 +173,7 @@ gtk_public_sources = files([
|
|||||||
'gtkbuildable.c',
|
'gtkbuildable.c',
|
||||||
'gtkbuilder.c',
|
'gtkbuilder.c',
|
||||||
'gtkbuilderparser.c',
|
'gtkbuilderparser.c',
|
||||||
|
'gtkbuildercssparser.c',
|
||||||
'gtkbuilderscope.c',
|
'gtkbuilderscope.c',
|
||||||
'gtkbutton.c',
|
'gtkbutton.c',
|
||||||
'gtkcalendar.c',
|
'gtkcalendar.c',
|
||||||
|
Reference in New Issue
Block a user