summaryrefslogtreecommitdiff
path: root/gtk/gtktexttag.c
diff options
context:
space:
mode:
authorChristian Hergert <christian@hergert.me>2015-02-09 16:41:48 -0800
committerMatthias Clasen <mclasen@redhat.com>2015-03-17 23:24:13 -0400
commit28063ee2e42e7ce47b7bd5326f2d53875a377d57 (patch)
treece7c2ca0667be5fee723de429ff60d1195cbe822 /gtk/gtktexttag.c
parent416c370da1d2eff2458e4a0c5b8e504cd8061559 (diff)
downloadgtk+-28063ee2e42e7ce47b7bd5326f2d53875a377d57.tar.gz
textview: add support for underline and strikethrough colors
This commit adds the GtkTextTag:underline-rgba and :strikethrough-rgba properties and the necessary plumbing to apply these colors in GtkTextLayout. With this change, you can alter the color of underlines including those of type PANGO_UNDERLINE_ERROR. You might want to alter the underline color to differentiate between spelling and grammer mistakes. In code editors, it is convenient to differentiate between errors and warnings. Note that the GtkTextAppearance struct is public ABI and has no spare room for new fields, so we are resorting to some tricky packing to store the colors in the unused pixel field of the fg_color and bg_color structs. This packing is accomplished by the macros in gtktextattributesprivate.h. Signed-off-by: Christian Hergert <christian@hergert.me> https://bugzilla.gnome.org/show_bug.cgi?id=402168
Diffstat (limited to 'gtk/gtktexttag.c')
-rw-r--r--gtk/gtktexttag.c179
1 files changed, 178 insertions, 1 deletions
diff --git a/gtk/gtktexttag.c b/gtk/gtktexttag.c
index e469d46792..f5f34f0c32 100644
--- a/gtk/gtktexttag.c
+++ b/gtk/gtktexttag.c
@@ -74,6 +74,7 @@
#include <stdlib.h>
#include <string.h>
+#include "gtktextattributesprivate.h"
#include "gtktexttag.h"
#include "gtktexttypes.h"
#include "gtktexttagtable.h"
@@ -119,8 +120,10 @@ enum {
PROP_LEFT_MARGIN,
PROP_INDENT,
PROP_STRIKETHROUGH,
+ PROP_STRIKETHROUGH_RGBA,
PROP_RIGHT_MARGIN,
PROP_UNDERLINE,
+ PROP_UNDERLINE_RGBA,
PROP_RISE,
PROP_BACKGROUND_FULL_HEIGHT,
PROP_LANGUAGE,
@@ -154,8 +157,10 @@ enum {
PROP_LEFT_MARGIN_SET,
PROP_INDENT_SET,
PROP_STRIKETHROUGH_SET,
+ PROP_STRIKETHROUGH_RGBA_SET,
PROP_RIGHT_MARGIN_SET,
PROP_UNDERLINE_SET,
+ PROP_UNDERLINE_RGBA_SET,
PROP_RISE_SET,
PROP_BACKGROUND_FULL_HEIGHT_SET,
PROP_LANGUAGE_SET,
@@ -518,7 +523,43 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
PANGO_TYPE_UNDERLINE,
PANGO_UNDERLINE_NONE,
GTK_PARAM_READWRITE));
-
+
+ /**
+ * GtkTextTag:underline-rgba:
+ *
+ * This property modifies the color of underlines. If not set, underlines
+ * will use the forground color.
+ *
+ * If #GtkTextTag:underline is set to %PANGO_UNDERLINE_ERROR, an alternate
+ * color may be applied instead of the foreground. Setting this property
+ * will always override those defaults.
+ *
+ * Since: 3.18
+ */
+ g_object_class_install_property (object_class,
+ PROP_UNDERLINE_RGBA,
+ g_param_spec_boxed ("underline-rgba",
+ P_("Underline RGBA"),
+ P_("Color of underline for this text"),
+ GDK_TYPE_RGBA,
+ GTK_PARAM_READWRITE));
+
+ /**
+ * GtkTextTag:strikethrough-rgba:
+ *
+ * This property modifies the color of strikeouts. If not set, strikeouts
+ * will use the forground color.
+ *
+ * Since: 3.18
+ */
+ g_object_class_install_property (object_class,
+ PROP_STRIKETHROUGH_RGBA,
+ g_param_spec_boxed ("strikethrough-rgba",
+ P_("Strike-through RGBA"),
+ P_("Color of strike-through for this text"),
+ GDK_TYPE_RGBA,
+ GTK_PARAM_READWRITE));
+
g_object_class_install_property (object_class,
PROP_WRAP_MODE,
g_param_spec_enum ("wrap-mode",
@@ -746,6 +787,28 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
P_("Underline set"),
P_("Whether this tag affects underlining"));
+ /**
+ * GtkTextTag:underline-rgba-set:
+ *
+ * If the #GtkTextTag:underline-rgba property has been set.
+ *
+ * Since: 3.18
+ */
+ ADD_SET_PROP ("underline-rgba-set", PROP_UNDERLINE_RGBA_SET,
+ P_("Underline RGBA set"),
+ P_("Whether this tag affects underlining color"));
+
+ /**
+ * GtkTextTag:strikethrough-rgba-set:
+ *
+ * If the #GtkTextTag:strikethrough-rgba property has been set.
+ *
+ * Since: 3.18
+ */
+ ADD_SET_PROP ("strikethrough-rgba-set", PROP_STRIKETHROUGH_RGBA_SET,
+ P_("Strikethrough RGBA set"),
+ P_("Whether this tag affects strikethrough color"));
+
ADD_SET_PROP ("wrap-mode-set", PROP_WRAP_MODE_SET,
P_("Wrap mode set"),
P_("Whether this tag affects line wrap mode"));
@@ -863,6 +926,66 @@ copy_gdk_color_to_rgba (GdkColor *src,
}
static void
+set_underline_rgba (GtkTextTag *tag,
+ const GdkRGBA *rgba)
+{
+ GtkTextTagPrivate *priv = tag->priv;
+
+ if (rgba)
+ {
+ GTK_TEXT_APPEARANCE_SET_UNDERLINE_RGBA (&priv->values->appearance, rgba);
+
+ if (!GTK_TEXT_APPEARANCE_GET_UNDERLINE_RGBA_SET (&priv->values->appearance))
+ {
+ GTK_TEXT_APPEARANCE_SET_UNDERLINE_RGBA_SET (&priv->values->appearance, TRUE);
+ g_object_notify (G_OBJECT (tag), "underline-rgba-set");
+ }
+ }
+ else
+ {
+ GdkRGBA black = { 0 };
+
+ GTK_TEXT_APPEARANCE_SET_UNDERLINE_RGBA (&priv->values->appearance, &black);
+
+ if (GTK_TEXT_APPEARANCE_GET_UNDERLINE_RGBA_SET (&priv->values->appearance))
+ {
+ GTK_TEXT_APPEARANCE_SET_UNDERLINE_RGBA_SET (&priv->values->appearance, FALSE);
+ g_object_notify (G_OBJECT (tag), "underline-rgba-set");
+ }
+ }
+}
+
+static void
+set_strikethrough_rgba (GtkTextTag *tag,
+ const GdkRGBA *rgba)
+{
+ GtkTextTagPrivate *priv = tag->priv;
+
+ if (rgba)
+ {
+ GTK_TEXT_APPEARANCE_SET_STRIKETHROUGH_RGBA (&priv->values->appearance, rgba);
+
+ if (!GTK_TEXT_APPEARANCE_GET_STRIKETHROUGH_RGBA_SET (&priv->values->appearance))
+ {
+ GTK_TEXT_APPEARANCE_SET_STRIKETHROUGH_RGBA_SET (&priv->values->appearance, TRUE);
+ g_object_notify (G_OBJECT (tag), "strikethrough-rgba-set");
+ }
+ }
+ else
+ {
+ GdkRGBA black = { 0 };
+
+ GTK_TEXT_APPEARANCE_SET_STRIKETHROUGH_RGBA (&priv->values->appearance, &black);
+
+ if (GTK_TEXT_APPEARANCE_GET_STRIKETHROUGH_RGBA_SET (&priv->values->appearance))
+ {
+ GTK_TEXT_APPEARANCE_SET_STRIKETHROUGH_RGBA_SET (&priv->values->appearance, FALSE);
+ g_object_notify (G_OBJECT (tag), "strikethrough-rgba-set");
+ }
+ }
+}
+
+static void
set_bg_rgba (GtkTextTag *tag, GdkRGBA *rgba)
{
GtkTextTagPrivate *priv = tag->priv;
@@ -1409,6 +1532,13 @@ gtk_text_tag_set_property (GObject *object,
g_object_notify (object, "strikethrough-set");
break;
+ case PROP_STRIKETHROUGH_RGBA:
+ {
+ GdkRGBA *color = g_value_get_boxed (value);
+ set_strikethrough_rgba (text_tag, color);
+ }
+ break;
+
case PROP_RIGHT_MARGIN:
priv->right_margin_set = TRUE;
priv->values->right_margin = g_value_get_int (value);
@@ -1422,6 +1552,13 @@ gtk_text_tag_set_property (GObject *object,
g_object_notify (object, "underline-set");
break;
+ case PROP_UNDERLINE_RGBA:
+ {
+ GdkRGBA *color = g_value_get_boxed (value);
+ set_underline_rgba (text_tag, color);
+ }
+ break;
+
case PROP_RISE:
priv->rise_set = TRUE;
priv->values->appearance.rise = g_value_get_int (value);
@@ -1593,6 +1730,11 @@ gtk_text_tag_set_property (GObject *object,
priv->strikethrough_set = g_value_get_boolean (value);
break;
+ case PROP_STRIKETHROUGH_RGBA_SET:
+ GTK_TEXT_APPEARANCE_SET_STRIKETHROUGH_RGBA_SET (&priv->values->appearance,
+ g_value_get_boolean (value));
+ break;
+
case PROP_RIGHT_MARGIN_SET:
priv->right_margin_set = g_value_get_boolean (value);
size_changed = TRUE;
@@ -1602,6 +1744,11 @@ gtk_text_tag_set_property (GObject *object,
priv->underline_set = g_value_get_boolean (value);
break;
+ case PROP_UNDERLINE_RGBA_SET:
+ GTK_TEXT_APPEARANCE_SET_UNDERLINE_RGBA_SET (&priv->values->appearance,
+ g_value_get_boolean (value));
+ break;
+
case PROP_RISE_SET:
priv->rise_set = g_value_get_boolean (value);
size_changed = TRUE;
@@ -1790,6 +1937,16 @@ gtk_text_tag_get_property (GObject *object,
g_value_set_boolean (value, priv->values->appearance.strikethrough);
break;
+ case PROP_STRIKETHROUGH_RGBA:
+ if (GTK_TEXT_APPEARANCE_GET_STRIKETHROUGH_RGBA_SET (&priv->values->appearance))
+ {
+ GdkRGBA rgba;
+
+ GTK_TEXT_APPEARANCE_GET_STRIKETHROUGH_RGBA (&priv->values->appearance, &rgba);
+ g_value_set_boxed (value, &rgba);
+ }
+ break;
+
case PROP_RIGHT_MARGIN:
g_value_set_int (value, priv->values->right_margin);
break;
@@ -1798,6 +1955,16 @@ gtk_text_tag_get_property (GObject *object,
g_value_set_enum (value, priv->values->appearance.underline);
break;
+ case PROP_UNDERLINE_RGBA:
+ if (GTK_TEXT_APPEARANCE_GET_UNDERLINE_RGBA_SET (&priv->values->appearance))
+ {
+ GdkRGBA rgba;
+
+ GTK_TEXT_APPEARANCE_GET_UNDERLINE_RGBA (&priv->values->appearance, &rgba);
+ g_value_set_boxed (value, &rgba);
+ }
+ break;
+
case PROP_RISE:
g_value_set_int (value, priv->values->appearance.rise);
break;
@@ -1901,6 +2068,11 @@ gtk_text_tag_get_property (GObject *object,
g_value_set_boolean (value, priv->strikethrough_set);
break;
+ case PROP_STRIKETHROUGH_RGBA_SET:
+ g_value_set_boolean (value,
+ GTK_TEXT_APPEARANCE_GET_STRIKETHROUGH_RGBA_SET (&priv->values->appearance));
+ break;
+
case PROP_RIGHT_MARGIN_SET:
g_value_set_boolean (value, priv->right_margin_set);
break;
@@ -1909,6 +2081,11 @@ gtk_text_tag_get_property (GObject *object,
g_value_set_boolean (value, priv->underline_set);
break;
+ case PROP_UNDERLINE_RGBA_SET:
+ g_value_set_boolean (value,
+ GTK_TEXT_APPEARANCE_GET_UNDERLINE_RGBA_SET (&priv->values->appearance));
+ break;
+
case PROP_RISE_SET:
g_value_set_boolean (value, priv->rise_set);
break;