[clutter/text-selection-color: 2/5] clutter-text: Add a selected-text-color
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/text-selection-color: 2/5] clutter-text: Add a selected-text-color
- Date: Fri, 13 May 2011 13:35:56 +0000 (UTC)
commit a3c109c8b31f2f74a0abbe75f6e91d525f9bd773
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Wed Mar 2 12:02:56 2011 -0500
clutter-text: Add a selected-text-color
http://bugzilla.clutter-project.org/show_bug.cgi?id=2595
clutter/clutter-text.c | 185 ++++++++++++++++++++++++++++++++++++++++++------
clutter/clutter-text.h | 5 ++
2 files changed, 167 insertions(+), 23 deletions(-)
---
diff --git a/clutter/clutter-text.c b/clutter/clutter-text.c
index f65e2f5..ce2139e 100644
--- a/clutter/clutter-text.c
+++ b/clutter/clutter-text.c
@@ -82,6 +82,7 @@ typedef struct _LayoutCache LayoutCache;
static const ClutterColor default_cursor_color = { 0, 0, 0, 255 };
static const ClutterColor default_selection_color = { 0, 0, 0, 255 };
static const ClutterColor default_text_color = { 0, 0, 0, 255 };
+static const ClutterColor default_selected_text_color = { 0, 0, 0, 255 };
G_DEFINE_TYPE (ClutterText, clutter_text, CLUTTER_TYPE_ACTOR);
@@ -147,6 +148,7 @@ struct _ClutterTextPrivate
guint preedit_set : 1;
guint is_default_font : 1;
guint has_focus : 1;
+ guint selected_text_color_set : 1;
/* current cursor position */
gint position;
@@ -181,6 +183,8 @@ struct _ClutterTextPrivate
ClutterColor selection_color;
+ ClutterColor selected_text_color;
+
gint max_length;
gunichar password_char;
@@ -221,6 +225,8 @@ enum
PROP_PASSWORD_CHAR,
PROP_MAX_LENGTH,
PROP_SINGLE_LINE_MODE,
+ PROP_SELECTED_TEXT_COLOR,
+ PROP_SELECTED_TEXT_COLOR_SET,
PROP_LAST
};
@@ -1189,6 +1195,10 @@ clutter_text_set_property (GObject *gobject,
clutter_text_set_single_line_mode (self, g_value_get_boolean (value));
break;
+ case PROP_SELECTED_TEXT_COLOR:
+ clutter_text_set_selected_text_color (self, clutter_value_get_color (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
}
@@ -1304,6 +1314,14 @@ clutter_text_get_property (GObject *gobject,
g_value_set_boxed (value, priv->attrs);
break;
+ case PROP_SELECTED_TEXT_COLOR:
+ clutter_value_set_color (value, &priv->selected_text_color);
+ break;
+
+ case PROP_SELECTED_TEXT_COLOR_SET:
+ g_value_set_boolean (value, priv->selected_text_color_set);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
}
@@ -1358,15 +1376,16 @@ clutter_text_finalize (GObject *gobject)
G_OBJECT_CLASS (clutter_text_parent_class)->finalize (gobject);
}
+/* Draws the selected text, its background, and the cursor */
static void
-cursor_paint (ClutterText *self)
+selection_paint (ClutterText *self)
{
ClutterTextPrivate *priv = self->priv;
ClutterActor *actor = CLUTTER_ACTOR (self);
+ guint8 paint_opacity = clutter_actor_get_paint_opacity (actor);
if (priv->editable && priv->cursor_visible)
{
- guint8 paint_opacity = clutter_actor_get_paint_opacity (actor);
const ClutterColor *color;
gint position;
@@ -1377,6 +1396,7 @@ cursor_paint (ClutterText *self)
if (position == priv->selection_bound)
{
+ /* No selection, just draw the cursor */
if (priv->cursor_color_set)
color = &priv->cursor_color;
else
@@ -1396,6 +1416,9 @@ cursor_paint (ClutterText *self)
}
else
{
+ /* Paint selection background first */
+ CoglPath *selection_path = cogl_path_new ();
+ CoglColor cogl_color = { 0, };
PangoLayout *layout = clutter_text_get_layout (self);
gchar *utf8 = clutter_text_get_display_text (self);
gint lines;
@@ -1403,20 +1426,6 @@ cursor_paint (ClutterText *self)
gint end_index;
gint line_no;
- if (priv->selection_color_set)
- color = &priv->selection_color;
- else if (priv->cursor_color_set)
- color = &priv->cursor_color;
- else
- color = &priv->text_color;
-
- cogl_set_source_color4ub (color->red,
- color->green,
- color->blue,
- paint_opacity
- * color->alpha
- / 255);
-
if (position == 0)
start_index = 0;
else
@@ -1475,15 +1484,54 @@ cursor_paint (ClutterText *self)
range_width = (ranges[i * 2 + 1] - ranges[i * 2])
/ PANGO_SCALE;
- cogl_rectangle (range_x,
- y,
- range_x + range_width,
- y + height);
+ cogl_path_rectangle (selection_path,
+ range_x,
+ y,
+ range_x + range_width,
+ y + height);
}
g_free (ranges);
}
+ /* Paint selection background */
+ if (priv->selection_color_set)
+ color = &priv->selection_color;
+ else if (priv->cursor_color_set)
+ color = &priv->cursor_color;
+ else
+ color = &priv->text_color;
+
+ cogl_set_source_color4ub (color->red,
+ color->green,
+ color->blue,
+ paint_opacity * color->alpha / 255);
+
+ cogl_path_fill (selection_path);
+
+ /* Paint selected text */
+ cogl_clip_push_from_path (selection_path);
+ cogl_object_unref (selection_path);
+
+ if (priv->selected_text_color_set)
+ color = &priv->selected_text_color;
+ else if (priv->selection_color_set)
+ color = &priv->selection_color;
+ else if (priv->cursor_color_set)
+ color = &priv->cursor_color;
+ else
+ color = &priv->text_color;
+
+ cogl_color_init_from_4ub (&cogl_color,
+ color->red,
+ color->green,
+ color->blue,
+ paint_opacity * color->alpha / 255);
+
+ cogl_pango_render_layout (layout, priv->text_x, 0, &cogl_color, 0);
+
+ cogl_clip_pop ();
+
g_free (utf8);
}
}
@@ -1904,9 +1952,6 @@ clutter_text_paint (ClutterActor *self)
priv->text_x = text_x;
- if (priv->has_focus)
- cursor_paint (text);
-
real_opacity = clutter_actor_get_paint_opacity (self)
* priv->text_color.alpha
/ 255;
@@ -1920,6 +1965,9 @@ clutter_text_paint (ClutterActor *self)
real_opacity);
cogl_pango_render_layout (layout, text_x, 0, &color, 0);
+ if (priv->has_focus)
+ selection_paint (text);
+
if (clip_set)
cogl_clip_pop ();
@@ -2957,6 +3005,36 @@ clutter_text_class_init (ClutterTextClass *klass)
g_object_class_install_property (gobject_class, PROP_SINGLE_LINE_MODE, pspec);
/**
+ * ClutterText:selected-text-color:
+ *
+ * The color of selected text.
+ *
+ * Since: 1.8
+ */
+ pspec = clutter_param_spec_color ("selected-text-color",
+ P_("Selected Text Color"),
+ P_("Selected Text Color"),
+ &default_selected_text_color,
+ CLUTTER_PARAM_READWRITE);
+ obj_props[PROP_SELECTED_TEXT_COLOR] = pspec;
+ g_object_class_install_property (gobject_class, PROP_SELECTED_TEXT_COLOR, pspec);
+
+ /**
+ * ClutterText:selected-text-color-set:
+ *
+ * Will be set to %TRUE if #ClutterText:selected-text-color has been set.
+ *
+ * Since: 1.8
+ */
+ pspec = g_param_spec_boolean ("selected-text-color-set",
+ P_("Selected Text Color Set"),
+ P_("Whether the selected text color has been set"),
+ FALSE,
+ CLUTTER_PARAM_READABLE);
+ obj_props[PROP_SELECTED_TEXT_COLOR_SET] = pspec;
+ g_object_class_install_property (gobject_class, PROP_SELECTED_TEXT_COLOR_SET, pspec);
+
+ /**
* ClutterText::text-changed:
* @self: the #ClutterText that emitted the signal
*
@@ -3185,6 +3263,7 @@ clutter_text_init (ClutterText *self)
priv->text_color = default_text_color;
priv->cursor_color = default_cursor_color;
priv->selection_color = default_selection_color;
+ priv->selected_text_color = default_selected_text_color;
/* get the default font name from the context; we don't use
* set_font_description() here because we are initializing
@@ -3207,6 +3286,7 @@ clutter_text_init (ClutterText *self)
priv->selection_color_set = FALSE;
priv->cursor_color_set = FALSE;
+ priv->selected_text_color_set = FALSE;
priv->preedit_set = FALSE;
priv->password_char = 0;
@@ -3803,6 +3883,65 @@ clutter_text_get_selection_color (ClutterText *self,
}
/**
+ * clutter_text_set_selected_text_color:
+ * @self: a #ClutterText
+ * @color: the selected text color, or %NULL to unset it
+ *
+ * Sets the selected text color of a #ClutterText actor.
+ *
+ * If @color is %NULL, the selected text color will be the same as the
+ * selection color, which then falls back to cursor, and then text color.
+ *
+ * Since: 1.8
+ */
+void
+clutter_text_set_selected_text_color (ClutterText *self,
+ const ClutterColor *color)
+{
+ ClutterTextPrivate *priv;
+
+ g_return_if_fail (CLUTTER_IS_TEXT (self));
+
+ priv = self->priv;
+
+ if (color)
+ {
+ priv->selected_text_color = *color;
+ priv->selected_text_color_set = TRUE;
+ }
+ else
+ priv->selected_text_color_set = FALSE;
+
+ clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
+
+ g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SELECTED_TEXT_COLOR]);
+ g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SELECTED_TEXT_COLOR_SET]);
+}
+
+/**
+ * clutter_text_get_selected_text_color:
+ * @self: a #ClutterText
+ * @color: (out caller-allocates): return location for a #ClutterColor
+ *
+ * Retrieves the color of selected text of a #ClutterText actor.
+ *
+ * Since: 1.8
+ */
+void
+clutter_text_get_selected_text_color (ClutterText *self,
+ ClutterColor *color)
+{
+ ClutterTextPrivate *priv;
+
+ g_return_if_fail (CLUTTER_IS_TEXT (self));
+ g_return_if_fail (color != NULL);
+
+ priv = self->priv;
+
+ *color = priv->selected_text_color;
+}
+
+/**
* clutter_text_set_font_description:
* @self: a #ClutterText
* @font_desc: a #PangoFontDescription
diff --git a/clutter/clutter-text.h b/clutter/clutter-text.h
index 9edbbca..315bd46 100644
--- a/clutter/clutter-text.h
+++ b/clutter/clutter-text.h
@@ -200,6 +200,11 @@ void clutter_text_set_single_line_mode (ClutterText *s
gboolean single_line);
gboolean clutter_text_get_single_line_mode (ClutterText *self);
+void clutter_text_set_selected_text_color (ClutterText *self,
+ const ClutterColor *color);
+void clutter_text_get_selected_text_color (ClutterText *self,
+ ClutterColor *color);
+
gboolean clutter_text_activate (ClutterText *self);
gboolean clutter_text_position_to_coords (ClutterText *self,
gint position,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]