Clipping within the entry class to stop it over-slipping its

boundries.
        Text will move within the clip region to keep the cursor always
        visible.
        Added some padding to the left and right to make sure cursor is
        always show.
This commit is contained in:
Neil J. Patel 2007-06-01 16:50:35 +00:00
parent 479fe01b5a
commit d5c38ef466
2 changed files with 79 additions and 9 deletions

View File

@ -1,3 +1,15 @@
2007-06-01 Neil J. Patel <njp@o-hand.com>
* clutter/clutter-entry.c: (clutter_entry_ensure_cursor_position),
(clutter_entry_paint), (clutter_entry_init),
(clutter_entry_handle_key_event):
Clipping within the entry class to stop it over-slipping its
boundries.
Text will move within the clip region to keep the cursor always
visible.
Added some padding to the left and right to make sure cursor is
always show.
2007-06-01 Tomas Frydrych <tf@openedhand.com> 2007-06-01 Tomas Frydrych <tf@openedhand.com>
* clutter/clutter-actor.c: * clutter/clutter-actor.c:

View File

@ -47,6 +47,7 @@
#define DEFAULT_FONT_NAME "Sans 10" #define DEFAULT_FONT_NAME "Sans 10"
#define ENTRY_CURSOR_WIDTH 1 #define ENTRY_CURSOR_WIDTH 1
#define ENTRY_PADDING 5
G_DEFINE_TYPE (ClutterEntry, clutter_entry, CLUTTER_TYPE_ACTOR); G_DEFINE_TYPE (ClutterEntry, clutter_entry, CLUTTER_TYPE_ACTOR);
@ -102,6 +103,7 @@ struct _ClutterEntryPrivate
guint single_line_mode : 1; guint single_line_mode : 1;
guint wrap_mode : 3; guint wrap_mode : 3;
gint position; gint position;
gint text_x;
PangoAttrList *attrs; PangoAttrList *attrs;
PangoAttrList *effective_attrs; PangoAttrList *effective_attrs;
@ -264,7 +266,7 @@ clutter_entry_ensure_cursor_position (ClutterEntry *entry)
else else
index = priv->position; index = priv->position;
if (priv->cursor_pos.width == 0) if (1)
{ {
pango_layout_get_cursor_pos (priv->layout, index, &rect, NULL); pango_layout_get_cursor_pos (priv->layout, index, &rect, NULL);
priv->cursor_pos.x = rect.x / PANGO_SCALE; priv->cursor_pos.x = rect.x / PANGO_SCALE;
@ -308,7 +310,11 @@ clutter_entry_paint (ClutterActor *self)
{ {
ClutterEntry *entry; ClutterEntry *entry;
ClutterEntryPrivate *priv; ClutterEntryPrivate *priv;
PangoRectangle logical;
gint actor_width;
gint text_width;
gint cursor_x;
entry = CLUTTER_ENTRY(self); entry = CLUTTER_ENTRY(self);
priv = entry->priv; priv = entry->priv;
@ -320,17 +326,63 @@ clutter_entry_paint (ClutterActor *self)
priv->text); priv->text);
return; return;
} }
clutter_entry_ensure_layout (entry, clutter_actor_get_width(self)); clutter_actor_set_clip (self, 0, 0,
clutter_actor_get_width (self),
clutter_actor_get_height (self));
actor_width = clutter_actor_get_width(self) - (2*ENTRY_PADDING);
clutter_entry_ensure_layout (entry, actor_width);
clutter_entry_ensure_cursor_position (entry); clutter_entry_ensure_cursor_position (entry);
priv->fgcol.alpha = clutter_actor_get_opacity(self);
pango_clutter_render_layout (priv->layout, 0, 0, &priv->fgcol, 0); pango_layout_get_extents (priv->layout, NULL, &logical);
text_width = logical.width / PANGO_SCALE;
if (actor_width < text_width)
{
/* We need to do some scrolling */
cursor_x = priv->cursor_pos.x;
/* If the cursor is at the begining or the end of the text, the placement
is easy, however, if the cursor is in the middle somewhere, we need to
make sure the text doesn't move until the cursor is either in the
far left or far right
*/
if (priv->position == 0)
priv->text_x = 0;
else if (priv->position == -1)
{
priv->text_x = actor_width - text_width;
priv->cursor_pos.x += priv->text_x + ENTRY_PADDING;
}
else
{
if (priv->text_x < 0)
{
gint diff = -1 * priv->text_x;
if (cursor_x < diff)
priv->text_x += diff - cursor_x;
else if (cursor_x > (diff + actor_width))
priv->text_x -= cursor_x - (diff+actor_width);
}
priv->cursor_pos.x += priv->text_x + ENTRY_PADDING;
}
}
else
{
priv->text_x = 0;
priv->cursor_pos.x += ENTRY_PADDING;
}
priv->fgcol.alpha = clutter_actor_get_opacity(self);
pango_clutter_render_layout (priv->layout,
priv->text_x + ENTRY_PADDING,
0, &priv->fgcol, 0);
if (CLUTTER_ENTRY_GET_CLASS (entry)->paint_cursor != NULL) if (CLUTTER_ENTRY_GET_CLASS (entry)->paint_cursor != NULL)
{ CLUTTER_ENTRY_GET_CLASS (entry)->paint_cursor (entry);
CLUTTER_ENTRY_GET_CLASS (entry)->paint_cursor (entry);
}
} }
static void static void
@ -535,6 +587,8 @@ clutter_entry_init (ClutterEntry *self)
priv->attrs = NULL; priv->attrs = NULL;
priv->position = -1; priv->position = -1;
priv->priv_char = '*'; priv->priv_char = '*';
priv->text_visible = TRUE;
priv->text_x = 0;
priv->fgcol.red = 0; priv->fgcol.red = 0;
priv->fgcol.green = 0; priv->fgcol.green = 0;
@ -975,6 +1029,10 @@ clutter_entry_handle_key_event (ClutterEntry *entry, ClutterKeyEvent *kev)
case CLUTTER_KP_Enter: case CLUTTER_KP_Enter:
case CLUTTER_ISO_Enter: case CLUTTER_ISO_Enter:
case CLUTTER_Escape: case CLUTTER_Escape:
case CLUTTER_Up:
case CLUTTER_KP_Up:
case CLUTTER_Down:
case CLUTTER_KP_Down:
case CLUTTER_Shift_L: case CLUTTER_Shift_L:
case CLUTTER_Shift_R: case CLUTTER_Shift_R:
break; break;