mirror of
https://github.com/brl/mutter.git
synced 2025-05-06 23:24:56 +00:00
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:
parent
8c863573fc
commit
78eb07d657
@ -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,85 +1612,81 @@ 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;
|
||||||
|
|
||||||
|
if (priv->position == priv->selection_bound)
|
||||||
{
|
{
|
||||||
const ClutterColor *color;
|
/* No selection, just draw the cursor */
|
||||||
gint position;
|
if (priv->cursor_color_set)
|
||||||
|
color = &priv->cursor_color;
|
||||||
position = priv->position;
|
|
||||||
|
|
||||||
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_set_source_color4ub (color->red,
|
|
||||||
color->green,
|
|
||||||
color->blue,
|
|
||||||
paint_opacity * color->alpha / 255);
|
|
||||||
|
|
||||||
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
|
else
|
||||||
{
|
color = &priv->text_color;
|
||||||
/* 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);
|
cogl_set_source_color4ub (color->red,
|
||||||
if (G_UNLIKELY (fb == NULL))
|
color->green,
|
||||||
return;
|
color->blue,
|
||||||
|
paint_opacity * color->alpha / 255);
|
||||||
|
|
||||||
/* Paint selection background */
|
cogl_rectangle (priv->cursor_rect.origin.x,
|
||||||
if (priv->selection_color_set)
|
priv->cursor_rect.origin.y,
|
||||||
color = &priv->selection_color;
|
priv->cursor_rect.origin.x + priv->cursor_rect.size.width,
|
||||||
else if (priv->cursor_color_set)
|
priv->cursor_rect.origin.y + priv->cursor_rect.size.height);
|
||||||
color = &priv->cursor_color;
|
}
|
||||||
else
|
else
|
||||||
color = &priv->text_color;
|
{
|
||||||
|
/* 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,
|
fb = _clutter_actor_get_active_framebuffer (actor);
|
||||||
color->green,
|
if (G_UNLIKELY (fb == NULL))
|
||||||
color->blue,
|
return;
|
||||||
paint_opacity * color->alpha / 255);
|
|
||||||
|
|
||||||
clutter_text_foreach_selection_rectangle (self,
|
/* Paint selection background */
|
||||||
add_selection_rectangle_to_path,
|
if (priv->selection_color_set)
|
||||||
selection_path);
|
color = &priv->selection_color;
|
||||||
|
else if (priv->cursor_color_set)
|
||||||
|
color = &priv->cursor_color;
|
||||||
|
else
|
||||||
|
color = &priv->text_color;
|
||||||
|
|
||||||
cogl_path_fill (selection_path);
|
cogl_set_source_color4ub (color->red,
|
||||||
|
color->green,
|
||||||
|
color->blue,
|
||||||
|
paint_opacity * color->alpha / 255);
|
||||||
|
|
||||||
/* Paint selected text */
|
clutter_text_foreach_selection_rectangle (self,
|
||||||
cogl_framebuffer_push_path_clip (fb, selection_path);
|
add_selection_rectangle_to_path,
|
||||||
cogl_object_unref (selection_path);
|
selection_path);
|
||||||
|
|
||||||
if (priv->selected_text_color_set)
|
cogl_path_fill (selection_path);
|
||||||
color = &priv->selected_text_color;
|
|
||||||
else
|
|
||||||
color = &priv->text_color;
|
|
||||||
|
|
||||||
cogl_color_init_from_4ub (&cogl_color,
|
/* Paint selected text */
|
||||||
color->red,
|
cogl_framebuffer_push_path_clip (fb, selection_path);
|
||||||
color->green,
|
cogl_object_unref (selection_path);
|
||||||
color->blue,
|
|
||||||
paint_opacity * color->alpha / 255);
|
|
||||||
|
|
||||||
cogl_pango_render_layout (layout, priv->text_x, 0, &cogl_color, 0);
|
if (priv->selected_text_color_set)
|
||||||
|
color = &priv->selected_text_color;
|
||||||
|
else
|
||||||
|
color = &priv->text_color;
|
||||||
|
|
||||||
cogl_framebuffer_pop_clip (fb);
|
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_framebuffer_pop_clip (fb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user