From e7c01297ddcdff76cb668a48763c6a00a13acbbf Mon Sep 17 00:00:00 2001 From: avolkov Date: Sat, 20 May 2006 00:37:08 +0000 Subject: [PATCH] Better text entry support for setup menu git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2366 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/src/sc2code/libs/graphics/widgets.c | 102 +++++++++++++++++++++--- sc2/src/sc2code/setupmenu.c | 5 +- 2 files changed, 95 insertions(+), 12 deletions(-) diff --git a/sc2/src/sc2code/libs/graphics/widgets.c b/sc2/src/sc2code/libs/graphics/widgets.c index 511d42c65..eb68afbf1 100644 --- a/sc2/src/sc2code/libs/graphics/widgets.c +++ b/sc2/src/sc2code/libs/graphics/widgets.c @@ -9,6 +9,7 @@ WIDGET *widget_focus = NULL; #define WIDGET_ACTIVE_COLOR BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x00), 0x0E) #define WIDGET_INACTIVE_COLOR BUILD_COLOR (MAKE_RGB15 (0x18, 0x18, 0x1F), 0x09) #define WIDGET_INACTIVE_SELECTED_COLOR BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F) +#define WIDGET_CURSOR_COLOR BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00) void DrawShadowedBox(PRECT r, COLOR bg, COLOR dark, COLOR medium) @@ -354,6 +355,8 @@ Widget_DrawTextEntry (WIDGET *_self, int x, int y) selected = WIDGET_ACTIVE_COLOR; inactive = WIDGET_INACTIVE_COLOR; + BatchGraphics (); + t.baseline.x = x; t.baseline.y = y; t.align = ALIGN_LEFT; @@ -373,22 +376,101 @@ Widget_DrawTextEntry (WIDGET *_self, int x, int y) /* Force string termination */ self->value[WIDGET_TEXTENTRY_WIDTH-1] = 0; - t.baseline.x = 160; t.baseline.y = y; - t.align = ALIGN_CENTER; t.valign = VALIGN_BOTTOM; - t.CharCount = ~0; + t.CharCount = utf8StringCount (self->value); t.pStr = self->value; - if (widget_focus == _self) - { - oldtext = SetContextForeGroundColor (selected); + + if (!(self->state & WTE_EDITING)) + { // normal or selected state + t.baseline.x = 160; + t.align = ALIGN_CENTER; + + if (widget_focus == _self) + { + oldtext = SetContextForeGroundColor (selected); + } + else + { + oldtext = SetContextForeGroundColor (inactive); + } + font_DrawText (&t); } else - { - oldtext = SetContextForeGroundColor (inactive); - } - font_DrawText (&t); + { // editing state + COUNT i; + RECT text_r; + BYTE char_deltas[WIDGET_TEXTENTRY_WIDTH]; + PBYTE pchar_deltas; + RECT r; + SIZE leading; + t.baseline.x = 90; + t.align = ALIGN_LEFT; + + // calc background box dimensions + // XXX: this may need some tuning, especially if a + // different font is used. The font 'leading' values + // are not what they should be. +#define BOX_VERT_OFFSET 2 + GetContextFontLeading (&leading); + r.corner.x = t.baseline.x - 1; + r.corner.y = t.baseline.y - leading + BOX_VERT_OFFSET; + r.extent.width = ScreenWidth - r.corner.x - 10; + r.extent.height = leading + 2; + + TextRect (&t, &text_r, char_deltas); +#if 0 + // XXX: this should potentially be used in ChangeCallback + if ((text_r.extent.width + 2) >= r.extent.width) + { // the text does not fit the input box size and so + // will not fit when displayed later + UnbatchGraphics (); + // disallow the change + return (FALSE); + } +#endif + + oldtext = SetContextForeGroundColor (selected); + DrawFilledRectangle (&r); + + // calculate the cursor position and draw it + pchar_deltas = char_deltas; + for (i = self->cursor_pos; i > 0; --i) + r.corner.x += (SIZE)*pchar_deltas++; + if (self->cursor_pos < t.CharCount) /* cursor mid-line */ + --r.corner.x; + if (self->state & WTE_BLOCKCUR) + { // Use block cursor for keyboardless systems + if (self->cursor_pos == t.CharCount) + { // cursor at end-line -- use insertion point + r.extent.width = 1; + } + else if (self->cursor_pos + 1 == t.CharCount) + { // extra pixel for last char margin + r.extent.width = (SIZE)*pchar_deltas + 2; + } + else + { // normal mid-line char + r.extent.width = (SIZE)*pchar_deltas + 1; + } + } + else + { // Insertion point cursor + r.extent.width = 1; + } + // position cursor within input field rect + ++r.corner.x; + ++r.corner.y; + r.extent.height -= 2; + SetContextForeGroundColor (WIDGET_CURSOR_COLOR); + DrawFilledRectangle (&r); + + SetContextForeGroundColor (inactive); + font_DrawText (&t); + } + + UnbatchGraphics (); SetContextFontEffect (oldFontEffect); SetContextFont (oldfont); SetContextForeGroundColor (oldtext); diff --git a/sc2/src/sc2code/setupmenu.c b/sc2/src/sc2code/setupmenu.c index 26053d779..1263a01f6 100644 --- a/sc2/src/sc2code/setupmenu.c +++ b/sc2/src/sc2code/setupmenu.c @@ -450,7 +450,8 @@ OnTextEntryEvent (WIDGET_TEXTENTRY *widget) TEXTENTRY_STATE tes; UNICODE revert_buf[256]; - widget->cursor_pos = 0; + // position cursor at the end of text + widget->cursor_pos = utf8StringCount (widget->value); widget->state = WTE_EDITING; redraw_menu (); @@ -468,7 +469,7 @@ OnTextEntryEvent (WIDGET_TEXTENTRY *widget) tes.ChangeCallback = OnTextEntryChange; tes.FrameCallback = OnTextEntryFrame; - SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); + SetMenuSounds (0, MENU_SOUND_SELECT); if (!DoTextEntry (&tes)) { // editing failed (canceled) -- revert the changes utf8StringCopy (widget->value, widget->maxlen, revert_buf);