summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2015-11-02 12:34:39 +0000
committerEmmanuele Bassi <ebassi@gnome.org>2015-11-28 20:20:00 +0000
commit78eb07d6576b0ef6c9d7e91d34414772d71d7455 (patch)
tree8ce434910ed0fa1eb33b50c4eda4cc5b1809c68d
parent8c863573fcd8bf40c5cf0f2cb29673636ad90d56 (diff)
downloadclutter-78eb07d6576b0ef6c9d7e91d34414772d71d7455.tar.gz
text: Allow selectability without editability
Being able to select text and being able to edit text are two separate capabilities, but ClutterText only allows the former with the latter. The ClutterText:selectable property is set to TRUE by default, given that it depends on the :editable property; this implies that all ClutterText instances now are going to show a cursor as soon as they get key focused. Obviously, this would make labels look a bit off — but if you have a label then you would not give it key focus, either by explicitly calling clutter_actor_grab_focus(), or by setting it as reactive and allowing it to be clicked. If this turns out to be a problem, we have various ways to avoid showing a cursor — for instance, we could change the default value of the selectable property, and ensure that setting the :editable property to TRUE would also set the :selectable property as a side effect. Or we could hide the cursor until the first button/touch press event. Finally, we could always back this commit out if it proves to be too much of a breakage for existing code bases. https://bugzilla.gnome.org/show_bug.cgi?id=757470
-rw-r--r--clutter/clutter-text.c145
1 files changed, 75 insertions, 70 deletions
diff --git a/clutter/clutter-text.c b/clutter/clutter-text.c
index a0d8b2703..6f6491309 100644
--- a/clutter/clutter-text.c
+++ b/clutter/clutter-text.c
@@ -309,6 +309,16 @@ clutter_text_queue_redraw (ClutterActor *self)
clutter_actor_queue_redraw (self);
}
+static gboolean
+clutter_text_should_draw_cursor (ClutterText *self)
+{
+ ClutterTextPrivate *priv = self->priv;
+
+ return priv->editable ||
+ priv->selectable ||
+ priv->cursor_visible;
+}
+
#define clutter_actor_queue_redraw \
Please_use_clutter_text_queue_redraw_instead
@@ -1602,85 +1612,81 @@ selection_paint (ClutterText *self)
ClutterTextPrivate *priv = self->priv;
ClutterActor *actor = CLUTTER_ACTOR (self);
guint8 paint_opacity = clutter_actor_get_paint_opacity (actor);
+ const ClutterColor *color;
if (!priv->has_focus)
return;
- if (priv->editable && priv->cursor_visible)
+ if (!clutter_text_should_draw_cursor (self))
+ return;
+
+ if (priv->position == priv->selection_bound)
{
- const ClutterColor *color;
- gint position;
+ /* No selection, just draw the cursor */
+ if (priv->cursor_color_set)
+ color = &priv->cursor_color;
+ else
+ color = &priv->text_color;
- position = priv->position;
+ cogl_set_source_color4ub (color->red,
+ color->green,
+ color->blue,
+ paint_opacity * color->alpha / 255);
- if (position == priv->selection_bound)
- {
- /* No selection, just draw the cursor */
- if (priv->cursor_color_set)
- color = &priv->cursor_color;
- else
- color = &priv->text_color;
+ cogl_rectangle (priv->cursor_rect.origin.x,
+ priv->cursor_rect.origin.y,
+ priv->cursor_rect.origin.x + priv->cursor_rect.size.width,
+ priv->cursor_rect.origin.y + priv->cursor_rect.size.height);
+ }
+ else
+ {
+ /* Paint selection background first */
+ PangoLayout *layout = clutter_text_get_layout (self);
+ CoglPath *selection_path = cogl_path_new ();
+ CoglColor cogl_color = { 0, };
+ CoglFramebuffer *fb;
- cogl_set_source_color4ub (color->red,
- color->green,
- color->blue,
- paint_opacity * color->alpha / 255);
+ fb = _clutter_actor_get_active_framebuffer (actor);
+ if (G_UNLIKELY (fb == NULL))
+ return;
- cogl_rectangle (priv->cursor_rect.origin.x,
- priv->cursor_rect.origin.y,
- priv->cursor_rect.origin.x + priv->cursor_rect.size.width,
- priv->cursor_rect.origin.y + priv->cursor_rect.size.height);
- }
+ /* Paint selection background */
+ if (priv->selection_color_set)
+ color = &priv->selection_color;
+ else if (priv->cursor_color_set)
+ color = &priv->cursor_color;
else
- {
- /* Paint selection background first */
- PangoLayout *layout = clutter_text_get_layout (self);
- CoglPath *selection_path = cogl_path_new ();
- CoglColor cogl_color = { 0, };
- CoglFramebuffer *fb;
-
- fb = _clutter_actor_get_active_framebuffer (actor);
- if (G_UNLIKELY (fb == NULL))
- return;
-
- /* 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;
+ color = &priv->text_color;
- cogl_set_source_color4ub (color->red,
- color->green,
- color->blue,
- paint_opacity * color->alpha / 255);
+ cogl_set_source_color4ub (color->red,
+ color->green,
+ color->blue,
+ paint_opacity * color->alpha / 255);
- clutter_text_foreach_selection_rectangle (self,
- add_selection_rectangle_to_path,
- selection_path);
+ clutter_text_foreach_selection_rectangle (self,
+ add_selection_rectangle_to_path,
+ selection_path);
- cogl_path_fill (selection_path);
+ cogl_path_fill (selection_path);
- /* Paint selected text */
- cogl_framebuffer_push_path_clip (fb, selection_path);
- cogl_object_unref (selection_path);
+ /* Paint selected text */
+ cogl_framebuffer_push_path_clip (fb, selection_path);
+ cogl_object_unref (selection_path);
- if (priv->selected_text_color_set)
- color = &priv->selected_text_color;
- else
- color = &priv->text_color;
+ if (priv->selected_text_color_set)
+ color = &priv->selected_text_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_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_pango_render_layout (layout, priv->text_x, 0, &cogl_color, 0);
- cogl_framebuffer_pop_clip (fb);
- }
+ cogl_framebuffer_pop_clip (fb);
}
}
@@ -1852,7 +1858,7 @@ clutter_text_press (ClutterActor *actor,
/* if a ClutterText is just used for display purposes, then we
* should ignore the events we receive
*/
- if (!priv->editable)
+ if (!(priv->editable || priv->selectable))
return CLUTTER_EVENT_PROPAGATE;
clutter_actor_grab_key_focus (actor);
@@ -2265,7 +2271,8 @@ clutter_text_paint (ClutterActor *self)
* editable, in which case we want to paint at least the
* cursor
*/
- if (n_chars == 0 && (!priv->editable || !priv->cursor_visible))
+ if (n_chars == 0 &&
+ !clutter_text_should_draw_cursor (text))
return;
if (priv->editable && priv->single_line_mode)
@@ -2299,7 +2306,7 @@ clutter_text_paint (ClutterActor *self)
}
}
- if (priv->editable && priv->cursor_visible)
+ if ((priv->editable || priv->selectable) && priv->cursor_visible)
clutter_text_ensure_cursor_position (text);
if (priv->editable && priv->single_line_mode)
@@ -2492,7 +2499,9 @@ clutter_text_get_paint_volume (ClutterActor *self,
/* If the cursor is visible then that will likely be drawn
outside of the ink rectangle so we should merge that in */
- if (priv->editable && priv->cursor_visible && priv->has_focus)
+ if ((priv->editable || priv->selectable) &&
+ priv->cursor_visible &&
+ priv->has_focus)
{
ClutterPaintVolume cursor_paint_volume;
@@ -2653,11 +2662,7 @@ clutter_text_allocate (ClutterActor *self,
static gboolean
clutter_text_has_overlaps (ClutterActor *self)
{
- ClutterTextPrivate *priv = CLUTTER_TEXT (self)->priv;
-
- return priv->editable ||
- priv->selectable ||
- priv->cursor_visible;
+ return clutter_text_should_draw_cursor ((ClutterText *) self);
}
static void