Compare commits
2 Commits
flatten-li
...
attribute-
Author | SHA1 | Date | |
---|---|---|---|
|
efe16cf4be | ||
|
dc2f65dd2b |
@@ -293,13 +293,86 @@ static void gtk_entry_measure (GtkWidget *widget,
|
|||||||
int *minimum_baseline,
|
int *minimum_baseline,
|
||||||
int *natural_baseline);
|
int *natural_baseline);
|
||||||
|
|
||||||
|
static GtkBuildableIface *buildable_parent_iface = NULL;
|
||||||
|
|
||||||
|
static void gtk_entry_buildable_interface_init (GtkBuildableIface *iface);
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GtkEntry, gtk_entry, GTK_TYPE_WIDGET,
|
G_DEFINE_TYPE_WITH_CODE (GtkEntry, gtk_entry, GTK_TYPE_WIDGET,
|
||||||
G_ADD_PRIVATE (GtkEntry)
|
G_ADD_PRIVATE (GtkEntry)
|
||||||
|
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
|
||||||
|
gtk_entry_buildable_interface_init)
|
||||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
|
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
|
||||||
gtk_entry_editable_init)
|
gtk_entry_editable_init)
|
||||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_EDITABLE,
|
G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_EDITABLE,
|
||||||
gtk_entry_cell_editable_init))
|
gtk_entry_cell_editable_init))
|
||||||
|
|
||||||
|
|
||||||
|
static const GtkBuildableParser pango_parser =
|
||||||
|
{
|
||||||
|
gtk_pango_attribute_start_element,
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_entry_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||||
|
GtkBuilder *builder,
|
||||||
|
GObject *child,
|
||||||
|
const gchar *tagname,
|
||||||
|
GtkBuildableParser *parser,
|
||||||
|
gpointer *data)
|
||||||
|
{
|
||||||
|
if (buildable_parent_iface->custom_tag_start (buildable, builder, child,
|
||||||
|
tagname, parser, data))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (strcmp (tagname, "attributes") == 0)
|
||||||
|
{
|
||||||
|
GtkPangoAttributeParserData *parser_data;
|
||||||
|
|
||||||
|
parser_data = g_slice_new0 (GtkPangoAttributeParserData);
|
||||||
|
parser_data->builder = g_object_ref (builder);
|
||||||
|
parser_data->object = (GObject *) g_object_ref (buildable);
|
||||||
|
*parser = pango_parser;
|
||||||
|
*data = parser_data;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_entry_buildable_custom_finished (GtkBuildable *buildable,
|
||||||
|
GtkBuilder *builder,
|
||||||
|
GObject *child,
|
||||||
|
const gchar *tagname,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkPangoAttributeParserData *data = user_data;
|
||||||
|
|
||||||
|
buildable_parent_iface->custom_finished (buildable, builder, child,
|
||||||
|
tagname, user_data);
|
||||||
|
|
||||||
|
if (strcmp (tagname, "attributes") == 0)
|
||||||
|
{
|
||||||
|
if (data->attrs)
|
||||||
|
{
|
||||||
|
gtk_entry_set_attributes (GTK_ENTRY (buildable), data->attrs);
|
||||||
|
pango_attr_list_unref (data->attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (data->object);
|
||||||
|
g_object_unref (data->builder);
|
||||||
|
g_slice_free (GtkPangoAttributeParserData, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_entry_buildable_interface_init (GtkBuildableIface *iface)
|
||||||
|
{
|
||||||
|
buildable_parent_iface = g_type_interface_peek_parent (iface);
|
||||||
|
|
||||||
|
iface->custom_tag_start = gtk_entry_buildable_custom_tag_start;
|
||||||
|
iface->custom_finished = gtk_entry_buildable_custom_finished;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_entry_grab_focus (GtkWidget *widget)
|
gtk_entry_grab_focus (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
|
316
gtk/gtklabel.c
316
gtk/gtklabel.c
@@ -1360,310 +1360,10 @@ gtk_label_buildable_interface_init (GtkBuildableIface *iface)
|
|||||||
iface->custom_finished = gtk_label_buildable_custom_finished;
|
iface->custom_finished = gtk_label_buildable_custom_finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
GtkBuilder *builder;
|
|
||||||
GObject *object;
|
|
||||||
PangoAttrList *attrs;
|
|
||||||
} PangoParserData;
|
|
||||||
|
|
||||||
static PangoAttribute *
|
|
||||||
attribute_from_text (GtkBuilder *builder,
|
|
||||||
const gchar *name,
|
|
||||||
const gchar *value,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
PangoAttribute *attribute = NULL;
|
|
||||||
PangoAttrType type;
|
|
||||||
PangoLanguage *language;
|
|
||||||
PangoFontDescription *font_desc;
|
|
||||||
GdkRGBA *color;
|
|
||||||
GValue val = G_VALUE_INIT;
|
|
||||||
|
|
||||||
if (!gtk_builder_value_from_string_type (builder, PANGO_TYPE_ATTR_TYPE, name, &val, error))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
type = g_value_get_enum (&val);
|
|
||||||
g_value_unset (&val);
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
/* PangoAttrLanguage */
|
|
||||||
case PANGO_ATTR_LANGUAGE:
|
|
||||||
if ((language = pango_language_from_string (value)))
|
|
||||||
{
|
|
||||||
attribute = pango_attr_language_new (language);
|
|
||||||
g_value_init (&val, G_TYPE_INT);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
/* PangoAttrInt */
|
|
||||||
case PANGO_ATTR_STYLE:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_STYLE, value, &val, error))
|
|
||||||
attribute = pango_attr_style_new (g_value_get_enum (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_WEIGHT:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_WEIGHT, value, &val, error))
|
|
||||||
attribute = pango_attr_weight_new (g_value_get_enum (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_VARIANT:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_VARIANT, value, &val, error))
|
|
||||||
attribute = pango_attr_variant_new (g_value_get_enum (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_STRETCH:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_STRETCH, value, &val, error))
|
|
||||||
attribute = pango_attr_stretch_new (g_value_get_enum (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_UNDERLINE:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_UNDERLINE, value, &val, NULL))
|
|
||||||
attribute = pango_attr_underline_new (g_value_get_enum (&val));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* XXX: allow boolean for backwards compat, so ignore error */
|
|
||||||
/* Deprecate this somehow */
|
|
||||||
g_value_unset (&val);
|
|
||||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
|
|
||||||
attribute = pango_attr_underline_new (g_value_get_boolean (&val));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_STRIKETHROUGH:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
|
|
||||||
attribute = pango_attr_strikethrough_new (g_value_get_boolean (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_GRAVITY:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_GRAVITY, value, &val, error))
|
|
||||||
attribute = pango_attr_gravity_new (g_value_get_enum (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_GRAVITY_HINT:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_GRAVITY_HINT, value, &val, error))
|
|
||||||
attribute = pango_attr_gravity_hint_new (g_value_get_enum (&val));
|
|
||||||
break;
|
|
||||||
/* PangoAttrString */
|
|
||||||
case PANGO_ATTR_FAMILY:
|
|
||||||
attribute = pango_attr_family_new (value);
|
|
||||||
g_value_init (&val, G_TYPE_INT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* PangoAttrSize */
|
|
||||||
case PANGO_ATTR_SIZE:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
|
||||||
attribute = pango_attr_size_new (g_value_get_int (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_ABSOLUTE_SIZE:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
|
||||||
attribute = pango_attr_size_new_absolute (g_value_get_int (&val));
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* PangoAttrFontDesc */
|
|
||||||
case PANGO_ATTR_FONT_DESC:
|
|
||||||
if ((font_desc = pango_font_description_from_string (value)))
|
|
||||||
{
|
|
||||||
attribute = pango_attr_font_desc_new (font_desc);
|
|
||||||
pango_font_description_free (font_desc);
|
|
||||||
g_value_init (&val, G_TYPE_INT);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
/* PangoAttrColor */
|
|
||||||
case PANGO_ATTR_FOREGROUND:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, GDK_TYPE_RGBA, value, &val, error))
|
|
||||||
{
|
|
||||||
color = g_value_get_boxed (&val);
|
|
||||||
attribute = pango_attr_foreground_new (color->red * 65535,
|
|
||||||
color->green * 65535,
|
|
||||||
color->blue * 65535);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_BACKGROUND:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, GDK_TYPE_RGBA, value, &val, error))
|
|
||||||
{
|
|
||||||
color = g_value_get_boxed (&val);
|
|
||||||
attribute = pango_attr_background_new (color->red * 65535,
|
|
||||||
color->green * 65535,
|
|
||||||
color->blue * 65535);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_UNDERLINE_COLOR:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, GDK_TYPE_RGBA, value, &val, error))
|
|
||||||
{
|
|
||||||
color = g_value_get_boxed (&val);
|
|
||||||
attribute = pango_attr_underline_color_new (color->red * 65535,
|
|
||||||
color->green * 65535,
|
|
||||||
color->blue * 65535);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_STRIKETHROUGH_COLOR:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, GDK_TYPE_RGBA, value, &val, error))
|
|
||||||
{
|
|
||||||
color = g_value_get_boxed (&val);
|
|
||||||
attribute = pango_attr_strikethrough_color_new (color->red * 65535,
|
|
||||||
color->green * 65535,
|
|
||||||
color->blue * 65535);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
/* PangoAttrShape */
|
|
||||||
case PANGO_ATTR_SHAPE:
|
|
||||||
/* Unsupported for now */
|
|
||||||
break;
|
|
||||||
/* PangoAttrFloat */
|
|
||||||
case PANGO_ATTR_SCALE:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_DOUBLE, value, &val, error))
|
|
||||||
attribute = pango_attr_scale_new (g_value_get_double (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_LETTER_SPACING:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
|
||||||
attribute = pango_attr_letter_spacing_new (g_value_get_int (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_RISE:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
|
||||||
attribute = pango_attr_rise_new (g_value_get_int (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_FALLBACK:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
|
|
||||||
attribute = pango_attr_fallback_new (g_value_get_boolean (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_FONT_FEATURES:
|
|
||||||
attribute = pango_attr_font_features_new (value);
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_FOREGROUND_ALPHA:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
|
||||||
attribute = pango_attr_foreground_alpha_new ((guint16)g_value_get_int (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_BACKGROUND_ALPHA:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
|
||||||
attribute = pango_attr_background_alpha_new ((guint16)g_value_get_int (&val));
|
|
||||||
break;
|
|
||||||
#if PANGO_VERSION_CHECK(1,44,0)
|
|
||||||
case PANGO_ATTR_ALLOW_BREAKS:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
|
|
||||||
attribute = pango_attr_allow_breaks_new (g_value_get_boolean (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_SHOW:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_SHOW_FLAGS, value, &val, error))
|
|
||||||
attribute = pango_attr_show_new (g_value_get_flags (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_INSERT_HYPHENS:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
|
|
||||||
attribute = pango_attr_insert_hyphens_new (g_value_get_boolean (&val));
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#if PANGO_VERSION_CHECK(1,45,0)
|
|
||||||
case PANGO_ATTR_OVERLINE:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_OVERLINE, value, &val, NULL))
|
|
||||||
attribute = pango_attr_overline_new (g_value_get_enum (&val));
|
|
||||||
break;
|
|
||||||
case PANGO_ATTR_OVERLINE_COLOR:
|
|
||||||
if (gtk_builder_value_from_string_type (builder, GDK_TYPE_RGBA, value, &val, error))
|
|
||||||
{
|
|
||||||
color = g_value_get_boxed (&val);
|
|
||||||
attribute = pango_attr_overline_color_new (color->red * 65535,
|
|
||||||
color->green * 65535,
|
|
||||||
color->blue * 65535);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case PANGO_ATTR_INVALID:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_value_unset (&val);
|
|
||||||
|
|
||||||
return attribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
pango_start_element (GtkBuildableParseContext *context,
|
|
||||||
const gchar *element_name,
|
|
||||||
const gchar **names,
|
|
||||||
const gchar **values,
|
|
||||||
gpointer user_data,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
PangoParserData *data = (PangoParserData*)user_data;
|
|
||||||
|
|
||||||
if (strcmp (element_name, "attribute") == 0)
|
|
||||||
{
|
|
||||||
PangoAttribute *attr = NULL;
|
|
||||||
const gchar *name = NULL;
|
|
||||||
const gchar *value = NULL;
|
|
||||||
const gchar *start = NULL;
|
|
||||||
const gchar *end = NULL;
|
|
||||||
guint start_val = 0;
|
|
||||||
guint end_val = G_MAXUINT;
|
|
||||||
GValue val = G_VALUE_INIT;
|
|
||||||
|
|
||||||
if (!_gtk_builder_check_parent (data->builder, context, "attributes", error))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!g_markup_collect_attributes (element_name, names, values, error,
|
|
||||||
G_MARKUP_COLLECT_STRING, "name", &name,
|
|
||||||
G_MARKUP_COLLECT_STRING, "value", &value,
|
|
||||||
G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "start", &start,
|
|
||||||
G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "end", &end,
|
|
||||||
G_MARKUP_COLLECT_INVALID))
|
|
||||||
{
|
|
||||||
_gtk_builder_prefix_error (data->builder, context, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start)
|
|
||||||
{
|
|
||||||
if (!gtk_builder_value_from_string_type (data->builder, G_TYPE_UINT, start, &val, error))
|
|
||||||
{
|
|
||||||
_gtk_builder_prefix_error (data->builder, context, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
start_val = g_value_get_uint (&val);
|
|
||||||
g_value_unset (&val);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end)
|
|
||||||
{
|
|
||||||
if (!gtk_builder_value_from_string_type (data->builder, G_TYPE_UINT, end, &val, error))
|
|
||||||
{
|
|
||||||
_gtk_builder_prefix_error (data->builder, context, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
end_val = g_value_get_uint (&val);
|
|
||||||
g_value_unset (&val);
|
|
||||||
}
|
|
||||||
|
|
||||||
attr = attribute_from_text (data->builder, name, value, error);
|
|
||||||
if (!attr)
|
|
||||||
{
|
|
||||||
_gtk_builder_prefix_error (data->builder, context, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
attr->start_index = start_val;
|
|
||||||
attr->end_index = end_val;
|
|
||||||
|
|
||||||
if (!data->attrs)
|
|
||||||
data->attrs = pango_attr_list_new ();
|
|
||||||
|
|
||||||
pango_attr_list_insert (data->attrs, attr);
|
|
||||||
}
|
|
||||||
else if (strcmp (element_name, "attributes") == 0)
|
|
||||||
{
|
|
||||||
if (!_gtk_builder_check_parent (data->builder, context, "object", error))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!g_markup_collect_attributes (element_name, names, values, error,
|
|
||||||
G_MARKUP_COLLECT_INVALID, NULL, NULL,
|
|
||||||
G_MARKUP_COLLECT_INVALID))
|
|
||||||
_gtk_builder_prefix_error (data->builder, context, error);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_gtk_builder_error_unhandled_tag (data->builder, context,
|
|
||||||
"GtkContainer", element_name,
|
|
||||||
error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const GtkBuildableParser pango_parser =
|
static const GtkBuildableParser pango_parser =
|
||||||
{
|
{
|
||||||
pango_start_element,
|
gtk_pango_attribute_start_element,
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_label_buildable_custom_tag_start (GtkBuildable *buildable,
|
gtk_label_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||||
@@ -1679,9 +1379,9 @@ gtk_label_buildable_custom_tag_start (GtkBuildable *buildable,
|
|||||||
|
|
||||||
if (strcmp (tagname, "attributes") == 0)
|
if (strcmp (tagname, "attributes") == 0)
|
||||||
{
|
{
|
||||||
PangoParserData *parser_data;
|
GtkPangoAttributeParserData *parser_data;
|
||||||
|
|
||||||
parser_data = g_slice_new0 (PangoParserData);
|
parser_data = g_slice_new0 (GtkPangoAttributeParserData);
|
||||||
parser_data->builder = g_object_ref (builder);
|
parser_data->builder = g_object_ref (builder);
|
||||||
parser_data->object = (GObject *) g_object_ref (buildable);
|
parser_data->object = (GObject *) g_object_ref (buildable);
|
||||||
*parser = pango_parser;
|
*parser = pango_parser;
|
||||||
@@ -1698,15 +1398,13 @@ gtk_label_buildable_custom_finished (GtkBuildable *buildable,
|
|||||||
const gchar *tagname,
|
const gchar *tagname,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
PangoParserData *data;
|
GtkPangoAttributeParserData *data = user_data;
|
||||||
|
|
||||||
buildable_parent_iface->custom_finished (buildable, builder, child,
|
buildable_parent_iface->custom_finished (buildable, builder, child,
|
||||||
tagname, user_data);
|
tagname, user_data);
|
||||||
|
|
||||||
if (strcmp (tagname, "attributes") == 0)
|
if (strcmp (tagname, "attributes") == 0)
|
||||||
{
|
{
|
||||||
data = (PangoParserData*)user_data;
|
|
||||||
|
|
||||||
if (data->attrs)
|
if (data->attrs)
|
||||||
{
|
{
|
||||||
gtk_label_set_attributes (GTK_LABEL (buildable), data->attrs);
|
gtk_label_set_attributes (GTK_LABEL (buildable), data->attrs);
|
||||||
@@ -1715,7 +1413,7 @@ gtk_label_buildable_custom_finished (GtkBuildable *buildable,
|
|||||||
|
|
||||||
g_object_unref (data->object);
|
g_object_unref (data->object);
|
||||||
g_object_unref (data->builder);
|
g_object_unref (data->builder);
|
||||||
g_slice_free (PangoParserData, data);
|
g_slice_free (GtkPangoAttributeParserData, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
293
gtk/gtkpango.c
293
gtk/gtkpango.c
@@ -1075,3 +1075,296 @@ _gtk_pango_attr_list_merge (PangoAttrList *into,
|
|||||||
|
|
||||||
return into;
|
return into;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PangoAttribute *
|
||||||
|
attribute_from_text (GtkBuilder *builder,
|
||||||
|
const char *name,
|
||||||
|
const char *value,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
PangoAttribute *attribute = NULL;
|
||||||
|
PangoAttrType type;
|
||||||
|
PangoLanguage *language;
|
||||||
|
PangoFontDescription *font_desc;
|
||||||
|
GdkRGBA *color;
|
||||||
|
GValue val = G_VALUE_INIT;
|
||||||
|
|
||||||
|
if (!gtk_builder_value_from_string_type (builder, PANGO_TYPE_ATTR_TYPE, name, &val, error))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
type = g_value_get_enum (&val);
|
||||||
|
g_value_unset (&val);
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
/* PangoAttrLanguage */
|
||||||
|
case PANGO_ATTR_LANGUAGE:
|
||||||
|
if ((language = pango_language_from_string (value)))
|
||||||
|
{
|
||||||
|
attribute = pango_attr_language_new (language);
|
||||||
|
g_value_init (&val, G_TYPE_INT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/* PangoAttrInt */
|
||||||
|
case PANGO_ATTR_STYLE:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_STYLE, value, &val, error))
|
||||||
|
attribute = pango_attr_style_new (g_value_get_enum (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_WEIGHT:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_WEIGHT, value, &val, error))
|
||||||
|
attribute = pango_attr_weight_new (g_value_get_enum (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_VARIANT:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_VARIANT, value, &val, error))
|
||||||
|
attribute = pango_attr_variant_new (g_value_get_enum (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_STRETCH:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_STRETCH, value, &val, error))
|
||||||
|
attribute = pango_attr_stretch_new (g_value_get_enum (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_UNDERLINE:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_UNDERLINE, value, &val, NULL))
|
||||||
|
attribute = pango_attr_underline_new (g_value_get_enum (&val));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* XXX: allow boolean for backwards compat, so ignore error */
|
||||||
|
/* Deprecate this somehow */
|
||||||
|
g_value_unset (&val);
|
||||||
|
if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
|
||||||
|
attribute = pango_attr_underline_new (g_value_get_boolean (&val));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_STRIKETHROUGH:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
|
||||||
|
attribute = pango_attr_strikethrough_new (g_value_get_boolean (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_GRAVITY:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_GRAVITY, value, &val, error))
|
||||||
|
attribute = pango_attr_gravity_new (g_value_get_enum (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_GRAVITY_HINT:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_GRAVITY_HINT, value, &val, error))
|
||||||
|
attribute = pango_attr_gravity_hint_new (g_value_get_enum (&val));
|
||||||
|
break;
|
||||||
|
/* PangoAttrString */
|
||||||
|
case PANGO_ATTR_FAMILY:
|
||||||
|
attribute = pango_attr_family_new (value);
|
||||||
|
g_value_init (&val, G_TYPE_INT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* PangoAttrSize */
|
||||||
|
case PANGO_ATTR_SIZE:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
||||||
|
attribute = pango_attr_size_new (g_value_get_int (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_ABSOLUTE_SIZE:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
||||||
|
attribute = pango_attr_size_new_absolute (g_value_get_int (&val));
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* PangoAttrFontDesc */
|
||||||
|
case PANGO_ATTR_FONT_DESC:
|
||||||
|
if ((font_desc = pango_font_description_from_string (value)))
|
||||||
|
{
|
||||||
|
attribute = pango_attr_font_desc_new (font_desc);
|
||||||
|
pango_font_description_free (font_desc);
|
||||||
|
g_value_init (&val, G_TYPE_INT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/* PangoAttrColor */
|
||||||
|
case PANGO_ATTR_FOREGROUND:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, GDK_TYPE_RGBA, value, &val, error))
|
||||||
|
{
|
||||||
|
color = g_value_get_boxed (&val);
|
||||||
|
attribute = pango_attr_foreground_new (color->red * 65535,
|
||||||
|
color->green * 65535,
|
||||||
|
color->blue * 65535);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_BACKGROUND:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, GDK_TYPE_RGBA, value, &val, error))
|
||||||
|
{
|
||||||
|
color = g_value_get_boxed (&val);
|
||||||
|
attribute = pango_attr_background_new (color->red * 65535,
|
||||||
|
color->green * 65535,
|
||||||
|
color->blue * 65535);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_UNDERLINE_COLOR:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, GDK_TYPE_RGBA, value, &val, error))
|
||||||
|
{
|
||||||
|
color = g_value_get_boxed (&val);
|
||||||
|
attribute = pango_attr_underline_color_new (color->red * 65535,
|
||||||
|
color->green * 65535,
|
||||||
|
color->blue * 65535);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_STRIKETHROUGH_COLOR:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, GDK_TYPE_RGBA, value, &val, error))
|
||||||
|
{
|
||||||
|
color = g_value_get_boxed (&val);
|
||||||
|
attribute = pango_attr_strikethrough_color_new (color->red * 65535,
|
||||||
|
color->green * 65535,
|
||||||
|
color->blue * 65535);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/* PangoAttrShape */
|
||||||
|
case PANGO_ATTR_SHAPE:
|
||||||
|
/* Unsupported for now */
|
||||||
|
break;
|
||||||
|
/* PangoAttrFloat */
|
||||||
|
case PANGO_ATTR_SCALE:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, G_TYPE_DOUBLE, value, &val, error))
|
||||||
|
attribute = pango_attr_scale_new (g_value_get_double (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_LETTER_SPACING:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
||||||
|
attribute = pango_attr_letter_spacing_new (g_value_get_int (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_RISE:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
||||||
|
attribute = pango_attr_rise_new (g_value_get_int (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_FALLBACK:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
|
||||||
|
attribute = pango_attr_fallback_new (g_value_get_boolean (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_FONT_FEATURES:
|
||||||
|
attribute = pango_attr_font_features_new (value);
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_FOREGROUND_ALPHA:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
||||||
|
attribute = pango_attr_foreground_alpha_new ((guint16)g_value_get_int (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_BACKGROUND_ALPHA:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, G_TYPE_INT, value, &val, error))
|
||||||
|
attribute = pango_attr_background_alpha_new ((guint16)g_value_get_int (&val));
|
||||||
|
break;
|
||||||
|
#if PANGO_VERSION_CHECK(1,44,0)
|
||||||
|
case PANGO_ATTR_ALLOW_BREAKS:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
|
||||||
|
attribute = pango_attr_allow_breaks_new (g_value_get_boolean (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_SHOW:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_SHOW_FLAGS, value, &val, error))
|
||||||
|
attribute = pango_attr_show_new (g_value_get_flags (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_INSERT_HYPHENS:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, value, &val, error))
|
||||||
|
attribute = pango_attr_insert_hyphens_new (g_value_get_boolean (&val));
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if PANGO_VERSION_CHECK(1,45,0)
|
||||||
|
case PANGO_ATTR_OVERLINE:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, PANGO_TYPE_OVERLINE, value, &val, NULL))
|
||||||
|
attribute = pango_attr_overline_new (g_value_get_enum (&val));
|
||||||
|
break;
|
||||||
|
case PANGO_ATTR_OVERLINE_COLOR:
|
||||||
|
if (gtk_builder_value_from_string_type (builder, GDK_TYPE_RGBA, value, &val, error))
|
||||||
|
{
|
||||||
|
color = g_value_get_boxed (&val);
|
||||||
|
attribute = pango_attr_overline_color_new (color->red * 65535,
|
||||||
|
color->green * 65535,
|
||||||
|
color->blue * 65535);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case PANGO_ATTR_INVALID:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_unset (&val);
|
||||||
|
|
||||||
|
return attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gtk_pango_attribute_start_element (GtkBuildableParseContext *context,
|
||||||
|
const char *element_name,
|
||||||
|
const char **names,
|
||||||
|
const char **values,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GtkPangoAttributeParserData *data = user_data;
|
||||||
|
|
||||||
|
if (strcmp (element_name, "attribute") == 0)
|
||||||
|
{
|
||||||
|
PangoAttribute *attr = NULL;
|
||||||
|
const char *name = NULL;
|
||||||
|
const char *value = NULL;
|
||||||
|
const char *start = NULL;
|
||||||
|
const char *end = NULL;
|
||||||
|
guint start_val = 0;
|
||||||
|
guint end_val = G_MAXUINT;
|
||||||
|
GValue val = G_VALUE_INIT;
|
||||||
|
|
||||||
|
if (!_gtk_builder_check_parent (data->builder, context, "attributes", error))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!g_markup_collect_attributes (element_name, names, values, error,
|
||||||
|
G_MARKUP_COLLECT_STRING, "name", &name,
|
||||||
|
G_MARKUP_COLLECT_STRING, "value", &value,
|
||||||
|
G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "start", &start,
|
||||||
|
G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "end", &end,
|
||||||
|
G_MARKUP_COLLECT_INVALID))
|
||||||
|
{
|
||||||
|
_gtk_builder_prefix_error (data->builder, context, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start)
|
||||||
|
{
|
||||||
|
if (!gtk_builder_value_from_string_type (data->builder, G_TYPE_UINT, start, &val, error))
|
||||||
|
{
|
||||||
|
_gtk_builder_prefix_error (data->builder, context, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
start_val = g_value_get_uint (&val);
|
||||||
|
g_value_unset (&val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end)
|
||||||
|
{
|
||||||
|
if (!gtk_builder_value_from_string_type (data->builder, G_TYPE_UINT, end, &val, error))
|
||||||
|
{
|
||||||
|
_gtk_builder_prefix_error (data->builder, context, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
end_val = g_value_get_uint (&val);
|
||||||
|
g_value_unset (&val);
|
||||||
|
}
|
||||||
|
|
||||||
|
attr = attribute_from_text (data->builder, name, value, error);
|
||||||
|
if (!attr)
|
||||||
|
{
|
||||||
|
_gtk_builder_prefix_error (data->builder, context, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
attr->start_index = start_val;
|
||||||
|
attr->end_index = end_val;
|
||||||
|
|
||||||
|
if (!data->attrs)
|
||||||
|
data->attrs = pango_attr_list_new ();
|
||||||
|
|
||||||
|
pango_attr_list_insert (data->attrs, attr);
|
||||||
|
}
|
||||||
|
else if (strcmp (element_name, "attributes") == 0)
|
||||||
|
{
|
||||||
|
if (!_gtk_builder_check_parent (data->builder, context, "object", error))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!g_markup_collect_attributes (element_name, names, values, error,
|
||||||
|
G_MARKUP_COLLECT_INVALID, NULL, NULL,
|
||||||
|
G_MARKUP_COLLECT_INVALID))
|
||||||
|
_gtk_builder_prefix_error (data->builder, context, error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_gtk_builder_error_unhandled_tag (data->builder, context,
|
||||||
|
"GtkContainer", element_name,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include <pango/pangocairo.h>
|
#include <pango/pangocairo.h>
|
||||||
#include <atk/atk.h>
|
#include <atk/atk.h>
|
||||||
|
#include "gtkbuildable.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@@ -59,6 +60,27 @@ gchar *_gtk_pango_get_text_after (PangoLayout *layout,
|
|||||||
PangoAttrList *_gtk_pango_attr_list_merge (PangoAttrList *into,
|
PangoAttrList *_gtk_pango_attr_list_merge (PangoAttrList *into,
|
||||||
PangoAttrList *from);
|
PangoAttrList *from);
|
||||||
|
|
||||||
|
gboolean gtk_buildable_attribute_tag_start (GtkBuildable *buildable,
|
||||||
|
GtkBuilder *builder,
|
||||||
|
GObject *child,
|
||||||
|
const gchar *tagname,
|
||||||
|
GtkBuildableParser *parser,
|
||||||
|
gpointer *data);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GtkBuilder *builder;
|
||||||
|
GObject *object;
|
||||||
|
PangoAttrList *attrs;
|
||||||
|
} GtkPangoAttributeParserData;
|
||||||
|
|
||||||
|
void
|
||||||
|
gtk_pango_attribute_start_element (GtkBuildableParseContext *context,
|
||||||
|
const char *element_name,
|
||||||
|
const char **names,
|
||||||
|
const char **values,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GTK_PANGO_H__ */
|
#endif /* __GTK_PANGO_H__ */
|
||||||
|
Reference in New Issue
Block a user