forked from AuroraMiddleware/gtk
Add custom parser for guides defined in GtkBuilder UI files
Like we describe constraints, we can also define guides.
This commit is contained in:
parent
6bc156c237
commit
8ab609e4e7
@ -103,6 +103,27 @@
|
||||
* The "source" and "target" attributes can be set to "super" to indicate
|
||||
* that the constraint target is the widget using the GtkConstraintLayout.
|
||||
*
|
||||
* Additionally, the "constraints" element can also contain a description
|
||||
* of the #GtkConstraintGuides used by the layout:
|
||||
*
|
||||
* |[
|
||||
* <constraints>
|
||||
* <guide min-width="100" max-width="500" name="hspace"/>
|
||||
* <guide min-height="64" nat-height="128" name="vspace" strength="strong"/>
|
||||
* </constraints>
|
||||
* ]|
|
||||
*
|
||||
* The "guide" element has the following optional attributes:
|
||||
*
|
||||
* - "min-width", "nat-width", and "max-width", describe the minimum,
|
||||
* natural, and maximum width of the guide, respectively
|
||||
* - "min-height", "nat-height", and "max-height", describe the minimum,
|
||||
* natural, and maximum height of the guide, respectively
|
||||
* - "strength" describes the strength of the constraint on the natural
|
||||
* size of the guide; if not specified, the constraint is assumed to
|
||||
* have a medium strength
|
||||
* - "name" describes a name for the guide, useful when debugging
|
||||
*
|
||||
* # Using the Visual Format Language
|
||||
*
|
||||
* Complex constraints can be described using a compact syntax called VFL,
|
||||
@ -1187,6 +1208,7 @@ typedef struct {
|
||||
GtkConstraintLayout *layout;
|
||||
GtkBuilder *builder;
|
||||
GList *constraints;
|
||||
GList *guides;
|
||||
} ConstraintsParserData;
|
||||
|
||||
typedef struct {
|
||||
@ -1200,6 +1222,14 @@ typedef struct {
|
||||
double multiplier;
|
||||
} ConstraintData;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *strength;
|
||||
struct {
|
||||
int min, nat, max;
|
||||
} sizes[2];
|
||||
} GuideData;
|
||||
|
||||
static void
|
||||
constraint_data_free (gpointer _data)
|
||||
{
|
||||
@ -1215,6 +1245,17 @@ constraint_data_free (gpointer _data)
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
guide_data_free (gpointer _data)
|
||||
{
|
||||
GuideData *data = _data;
|
||||
|
||||
g_free (data->name);
|
||||
g_free (data->strength);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_double (const char *string,
|
||||
double *value_p,
|
||||
@ -1241,6 +1282,32 @@ parse_double (const char *string,
|
||||
errno = saved_errno;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_int (const char *string,
|
||||
int *value_p,
|
||||
int default_value)
|
||||
{
|
||||
gint64 value;
|
||||
char *endptr;
|
||||
int saved_errno;
|
||||
|
||||
if (string == NULL || string[0] == '\0')
|
||||
{
|
||||
*value_p = default_value;
|
||||
return;
|
||||
}
|
||||
|
||||
saved_errno = errno;
|
||||
errno = 0;
|
||||
value = g_ascii_strtoll (string, &endptr, 10);
|
||||
if (errno == 0 && endptr != string)
|
||||
*value_p = (int) value;
|
||||
else
|
||||
*value_p = default_value;
|
||||
|
||||
errno = saved_errno;
|
||||
}
|
||||
|
||||
static GtkConstraint *
|
||||
constraint_data_to_constraint (const ConstraintData *data,
|
||||
GtkBuilder *builder,
|
||||
@ -1322,6 +1389,8 @@ constraint_data_to_constraint (const ConstraintData *data,
|
||||
data->strength,
|
||||
&strength,
|
||||
error);
|
||||
if (!res)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
strength = GTK_CONSTRAINT_STRENGTH_REQUIRED;
|
||||
@ -1340,6 +1409,38 @@ constraint_data_to_constraint (const ConstraintData *data,
|
||||
strength);
|
||||
}
|
||||
|
||||
static GtkConstraintGuide *
|
||||
guide_data_to_guide (const GuideData *data,
|
||||
GtkBuilder *builder,
|
||||
GError **error)
|
||||
{
|
||||
int strength;
|
||||
gboolean res;
|
||||
|
||||
if (data->strength != NULL)
|
||||
{
|
||||
res = _gtk_builder_enum_from_string (GTK_TYPE_CONSTRAINT_STRENGTH,
|
||||
data->strength,
|
||||
&strength,
|
||||
error);
|
||||
if (!res)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
strength = GTK_CONSTRAINT_STRENGTH_MEDIUM;
|
||||
|
||||
return g_object_new (GTK_TYPE_CONSTRAINT_GUIDE,
|
||||
"min-width", data->sizes[GTK_ORIENTATION_HORIZONTAL].min,
|
||||
"nat-width", data->sizes[GTK_ORIENTATION_HORIZONTAL].nat,
|
||||
"max-width", data->sizes[GTK_ORIENTATION_HORIZONTAL].max,
|
||||
"min-height", data->sizes[GTK_ORIENTATION_VERTICAL].min,
|
||||
"nat-height", data->sizes[GTK_ORIENTATION_VERTICAL].nat,
|
||||
"max-height", data->sizes[GTK_ORIENTATION_VERTICAL].max,
|
||||
"strength", strength,
|
||||
"name", data->name,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
constraints_start_element (GMarkupParseContext *context,
|
||||
const char *element_name,
|
||||
@ -1399,6 +1500,44 @@ constraints_start_element (GMarkupParseContext *context,
|
||||
|
||||
data->constraints = g_list_prepend (data->constraints, cdata);
|
||||
}
|
||||
else if (strcmp (element_name, "guide") == 0)
|
||||
{
|
||||
const char *min_width, *nat_width, *max_width;
|
||||
const char *min_height, *nat_height, *max_height;
|
||||
const char *strength_str;
|
||||
const char *name;
|
||||
GuideData *gdata;
|
||||
|
||||
if (!_gtk_builder_check_parent (data->builder, context, "constraints", error))
|
||||
return;
|
||||
|
||||
if (!g_markup_collect_attributes (element_name, attr_names, attr_values, error,
|
||||
G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "min-width", &min_width,
|
||||
G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "nat-width", &nat_width,
|
||||
G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "max-width", &max_width,
|
||||
G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "min-height", &min_height,
|
||||
G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "nat-height", &nat_height,
|
||||
G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "max-height", &max_height,
|
||||
G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "strength", &strength_str,
|
||||
G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "name", &name,
|
||||
G_MARKUP_COLLECT_INVALID))
|
||||
{
|
||||
_gtk_builder_prefix_error (data->builder, context, error);
|
||||
return;
|
||||
}
|
||||
|
||||
gdata = g_new0 (GuideData, 1);
|
||||
parse_int (min_width, &(gdata->sizes[GTK_ORIENTATION_HORIZONTAL].min), 0);
|
||||
parse_int (nat_width, &(gdata->sizes[GTK_ORIENTATION_HORIZONTAL].nat), 0);
|
||||
parse_int (max_width, &(gdata->sizes[GTK_ORIENTATION_HORIZONTAL].max), G_MAXINT);
|
||||
parse_int (min_height, &(gdata->sizes[GTK_ORIENTATION_VERTICAL].min), 0);
|
||||
parse_int (nat_height, &(gdata->sizes[GTK_ORIENTATION_VERTICAL].nat), 0);
|
||||
parse_int (max_height, &(gdata->sizes[GTK_ORIENTATION_VERTICAL].max), G_MAXINT);
|
||||
gdata->name = g_strdup (name);
|
||||
gdata->strength = g_strdup (strength_str);
|
||||
|
||||
data->guides = g_list_prepend (data->guides, gdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_builder_error_unhandled_tag (data->builder, context,
|
||||
@ -1436,6 +1575,7 @@ gtk_constraint_layout_custom_tag_start (GtkBuildable *buildable,
|
||||
data->layout = g_object_ref (GTK_CONSTRAINT_LAYOUT (buildable));
|
||||
data->builder = builder;
|
||||
data->constraints = NULL;
|
||||
data->guides = NULL;
|
||||
|
||||
*parser = constraints_parser;
|
||||
*parser_data = data;
|
||||
@ -1468,6 +1608,25 @@ gtk_constraint_layout_custom_finished (GtkBuildable *buildable,
|
||||
{
|
||||
GList *l;
|
||||
|
||||
data->guides = g_list_reverse (data->guides);
|
||||
for (l = data->guides; l != NULL; l = l->next)
|
||||
{
|
||||
const GuideData *gdata = l->data;
|
||||
GtkConstraintGuide *g;
|
||||
GError *error = NULL;
|
||||
|
||||
g = guide_data_to_guide (gdata, builder, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_critical ("Unable to parse guide definition: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
continue;
|
||||
}
|
||||
|
||||
gtk_constraint_layout_add_guide (data->layout, g);
|
||||
}
|
||||
|
||||
data->constraints = g_list_reverse (data->constraints);
|
||||
for (l = data->constraints; l != NULL; l = l->next)
|
||||
{
|
||||
@ -1493,6 +1652,7 @@ gtk_constraint_layout_custom_finished (GtkBuildable *buildable,
|
||||
}
|
||||
|
||||
g_list_free_full (data->constraints, constraint_data_free);
|
||||
g_list_free_full (data->guides, guide_data_free);
|
||||
g_object_unref (data->layout);
|
||||
g_free (data);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user