clutter-text: Add a selected-text-color

http://bugzilla.clutter-project.org/show_bug.cgi?id=2595
This commit is contained in:
Jasper St. Pierre 2011-03-02 12:02:56 -05:00 committed by Emmanuele Bassi
parent 0a8ec7f7d5
commit 94c9c07509
2 changed files with 167 additions and 23 deletions

View File

@ -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 ();
@ -2956,6 +3004,36 @@ clutter_text_class_init (ClutterTextClass *klass)
obj_props[PROP_SINGLE_LINE_MODE] = pspec;
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;
@ -3802,6 +3882,65 @@ clutter_text_get_selection_color (ClutterText *self,
*color = priv->selection_color;
}
/**
* 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

View File

@ -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,