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
This commit is contained in:
Emmanuele Bassi 2015-11-02 12:34:39 +00:00
parent 8c863573fc
commit 78eb07d657

View File

@ -309,6 +309,16 @@ clutter_text_queue_redraw (ClutterActor *self)
clutter_actor_queue_redraw (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 \ #define clutter_actor_queue_redraw \
Please_use_clutter_text_queue_redraw_instead Please_use_clutter_text_queue_redraw_instead
@ -1602,18 +1612,15 @@ selection_paint (ClutterText *self)
ClutterTextPrivate *priv = self->priv; ClutterTextPrivate *priv = self->priv;
ClutterActor *actor = CLUTTER_ACTOR (self); ClutterActor *actor = CLUTTER_ACTOR (self);
guint8 paint_opacity = clutter_actor_get_paint_opacity (actor); guint8 paint_opacity = clutter_actor_get_paint_opacity (actor);
const ClutterColor *color;
if (!priv->has_focus) if (!priv->has_focus)
return; return;
if (priv->editable && priv->cursor_visible) if (!clutter_text_should_draw_cursor (self))
{ return;
const ClutterColor *color;
gint position;
position = priv->position; if (priv->position == priv->selection_bound)
if (position == priv->selection_bound)
{ {
/* No selection, just draw the cursor */ /* No selection, just draw the cursor */
if (priv->cursor_color_set) if (priv->cursor_color_set)
@ -1682,7 +1689,6 @@ selection_paint (ClutterText *self)
cogl_framebuffer_pop_clip (fb); cogl_framebuffer_pop_clip (fb);
} }
} }
}
static gint static gint
clutter_text_move_word_backward (ClutterText *self, clutter_text_move_word_backward (ClutterText *self,
@ -1852,7 +1858,7 @@ clutter_text_press (ClutterActor *actor,
/* if a ClutterText is just used for display purposes, then we /* if a ClutterText is just used for display purposes, then we
* should ignore the events we receive * should ignore the events we receive
*/ */
if (!priv->editable) if (!(priv->editable || priv->selectable))
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
clutter_actor_grab_key_focus (actor); 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 * editable, in which case we want to paint at least the
* cursor * cursor
*/ */
if (n_chars == 0 && (!priv->editable || !priv->cursor_visible)) if (n_chars == 0 &&
!clutter_text_should_draw_cursor (text))
return; return;
if (priv->editable && priv->single_line_mode) 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); clutter_text_ensure_cursor_position (text);
if (priv->editable && priv->single_line_mode) 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 /* If the cursor is visible then that will likely be drawn
outside of the ink rectangle so we should merge that in */ 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; ClutterPaintVolume cursor_paint_volume;
@ -2653,11 +2662,7 @@ clutter_text_allocate (ClutterActor *self,
static gboolean static gboolean
clutter_text_has_overlaps (ClutterActor *self) clutter_text_has_overlaps (ClutterActor *self)
{ {
ClutterTextPrivate *priv = CLUTTER_TEXT (self)->priv; return clutter_text_should_draw_cursor ((ClutterText *) self);
return priv->editable ||
priv->selectable ||
priv->cursor_visible;
} }
static void static void