[clutter-text] Fix x-position of cursor when moving up or down

ClutterText already has code to try to preserve the x position when
moving up or down. A target x-position is stored and the cursor is
positioned at the nearest point to that in the appropriate line when
up or down is pressed. However the target position was never cleared
so it would always target the x-position of the cursor from the first
time you pressed up or down.

To fix this the patch clears the target position in set_position and
then sets it after the call in real_move_up/down. That way pressing
up or down sets the target position and any other movement will clear
it.

To get an index for the pixel position in the line
pango_layout_line_x_to_index is used. However when x is greater than
the length of the line then the index before the last grapheme is
returned which was causing it to jump to the penultimate
character. The patch makes it add on the trailing value so that it
will jump to the last character.
This commit is contained in:
Neil Roberts 2009-01-14 11:12:02 +00:00
parent b57c7e12d4
commit ffc15e0962

View File

@ -1278,7 +1278,7 @@ clutter_text_real_move_up (ClutterText *self,
PangoLayoutLine *layout_line;
PangoLayout *layout;
gint line_no;
gint index_;
gint index_, trailing;
gint x;
layout = clutter_text_get_layout (self);
@ -1298,21 +1298,23 @@ clutter_text_real_move_up (ClutterText *self,
if (priv->x_pos != -1)
x = priv->x_pos;
else
priv->x_pos = x;
layout_line = pango_layout_get_line_readonly (layout, line_no);
if (!layout_line)
return FALSE;
pango_layout_line_x_to_index (layout_line, x, &index_, NULL);
pango_layout_line_x_to_index (layout_line, x, &index_, &trailing);
{
gint pos = bytes_to_offset (priv->text, index_);
clutter_text_set_cursor_position (self, pos);
clutter_text_set_cursor_position (self, pos + trailing);
}
/* Store the target x position to avoid drifting left and right when
moving the cursor up and down */
priv->x_pos = x;
if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK)))
clutter_text_clear_selection (self);
@ -1329,7 +1331,7 @@ clutter_text_real_move_down (ClutterText *self,
PangoLayoutLine *layout_line;
PangoLayout *layout;
gint line_no;
gint index_;
gint index_, trailing;
gint x;
layout = clutter_text_get_layout (self);
@ -1345,21 +1347,23 @@ clutter_text_real_move_down (ClutterText *self,
if (priv->x_pos != -1)
x = priv->x_pos;
else
priv->x_pos = x;
layout_line = pango_layout_get_line_readonly (layout, line_no + 1);
if (!layout_line)
return FALSE;
pango_layout_line_x_to_index (layout_line, x, &index_, NULL);
pango_layout_line_x_to_index (layout_line, x, &index_, &trailing);
{
gint pos = bytes_to_offset (priv->text, index_);
clutter_text_set_cursor_position (self, pos);
clutter_text_set_cursor_position (self, pos + trailing);
}
/* Store the target x position to avoid drifting left and right when
moving the cursor up and down */
priv->x_pos = x;
if (!(priv->selectable && (modifiers & CLUTTER_SHIFT_MASK)))
clutter_text_clear_selection (self);
@ -3301,6 +3305,10 @@ clutter_text_set_cursor_position (ClutterText *self,
else
priv->position = position;
/* Forget the target x position so that it will be recalculated next
time the cursor is moved up or down */
priv->x_pos = -1;
if (CLUTTER_ACTOR_IS_VISIBLE (self))
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
}