1 /*
2 * file mi_string.c - string ediotr for menus
3 *
4 * $Id: mi_string.c,v 1.6 2006/02/09 21:21:24 fzago Exp $
5 *
6 * Program XBLAST
7 * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2; or (at your option)
12 * any later version
13 *
14 * This program is distributed in the hope that it will be entertaining,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include "xblast.h"
25
26 /*
27 * local macros
28 */
29 #define BLINK_RATE 8
30
31 #define FF_STRING_TEXT_FOCUS (FF_Medium | FF_Black | FF_Left | FF_Outlined)
32 #define FF_STRING_TEXT_NO_FOCUS (FF_Medium | FF_White | FF_Left)
33 #define FF_STRING_VALUE_SELECT (FF_Medium | FF_Black | FF_Left | FF_Boxed)
34 #define FF_STRING_VALUE_NO_SELECT (FF_Medium | FF_White | FF_Left | FF_Boxed)
35
36 /*
37 * local types
38 */
39 typedef struct
40 {
41 XBMenuItem item;
42 const char *text;
43 char *buffer;
44 size_t len;
45 char *work;
46 size_t pos;
47 Sprite *lSprite;
48 Sprite *eSprite;
49 int pollCount;
50 } XBMenuStringItem;
51
52 /*
53 * a string item receives the focus
54 */
55 static void
MenuStringFocus(XBMenuItem * ptr,XBBool flag)56 MenuStringFocus (XBMenuItem * ptr, XBBool flag)
57 {
58 XBMenuStringItem *string = (XBMenuStringItem *) ptr;
59
60 assert (string != NULL);
61 assert (string->lSprite != NULL);
62 SetSpriteAnime (string->lSprite, flag ? FF_STRING_TEXT_FOCUS : FF_STRING_TEXT_NO_FOCUS);
63 } /* MenuStringFocus */
64
65 /*
66 * Menu String Item
67 */
68 static void
MenuStringPoll(XBMenuItem * ptr)69 MenuStringPoll (XBMenuItem * ptr)
70 {
71 XBMenuStringItem *string = (XBMenuStringItem *) ptr;
72
73 assert (string != NULL);
74 string->pollCount++;
75 if ((string->item.flags & MIF_SELECTED) && (0 == (string->pollCount % BLINK_RATE))) {
76 if (0 == (string->pollCount % (2 * BLINK_RATE))) {
77 SetSpriteAnime (string->eSprite, FF_STRING_VALUE_SELECT | FF_Cursor);
78 }
79 else {
80 SetSpriteAnime (string->eSprite, FF_STRING_VALUE_SELECT);
81 }
82 }
83 } /* MenuStringPoll */
84
85 /*
86 * event handling while string is selected
87 */
88 static void
StringEventLoop(XBMenuItem * ptr)89 StringEventLoop (XBMenuItem * ptr)
90 {
91 XBEventCode event;
92 XBEventData data;
93 XBMenuStringItem *string = (XBMenuStringItem *) ptr;
94
95 assert (string != NULL);
96 assert (string->eSprite != NULL);
97
98 string->item.flags |= MIF_SELECTED;
99 SetSpriteAnime (string->eSprite, FF_STRING_VALUE_SELECT);
100 GUI_SetKeyboardMode (KB_ASCII);
101 /* event loop */
102 while (1) {
103 /* update window contents */
104 MenuUpdateWindow ();
105 /* get event from gui */
106 while (XBE_TIMER != (event = GUI_WaitEvent (&data))) {
107 if (event == XBE_ASCII) {
108 // Dbg_Out(" mi_string %c \n",data.value);
109 /* add a character */
110 if (string->pos < string->len - 1) {
111 string->work[string->pos++] = (char)data.value;
112 string->work[string->pos] = 0;
113 }
114 SetSpriteText (string->eSprite, string->work);
115 }
116 else if (event == XBE_CTRL) {
117 /* control key */
118 switch (data.value) {
119 /* delete last character */
120 case XBCK_BACKSPACE:
121 if (string->pos > 0) {
122 string->work[--string->pos] = 0;
123 SetSpriteText (string->eSprite, string->work);
124 }
125 break;
126 /* accept value */
127 case XBCK_RETURN:
128 memcpy (string->buffer, string->work, string->len);
129 goto Finish;
130 /* reject value */
131 case XBCK_ESCAPE:
132 memcpy (string->work, string->buffer, string->len);
133 string->pos = strlen (string->buffer);
134 goto Finish;
135 default:
136 break;
137 }
138 }
139 else if (event == XBE_MOUSE_1) {
140 /* accept value */
141 memcpy (string->buffer, string->work, string->len);
142 goto Finish;
143 }
144 else if (event == XBE_MOUSE_2) {
145 /* reject value */
146 memcpy (string->work, string->buffer, string->len);
147 string->pos = strlen (string->buffer);
148 goto Finish;
149 }
150 }
151 }
152 Finish:
153 string->item.flags &= ~MIF_SELECTED;
154 SetSpriteText (string->eSprite, string->work);
155 SetSpriteAnime (string->eSprite, FF_STRING_VALUE_NO_SELECT);
156 GUI_SetKeyboardMode (KB_MENU);
157 return;
158 } /* StringEventLoop */
159
160 /*
161 * mouse click
162 */
163 static void
MenuStringMouse(XBMenuItem * ptr,XBEventCode code)164 MenuStringMouse (XBMenuItem * ptr, XBEventCode code)
165 {
166 if (code == XBE_MOUSE_1) {
167 StringEventLoop (ptr);
168 }
169 } /* MenuStringMouse */
170
171 /*
172 *
173 */
174 XBMenuItem *
MenuCreateString(int x,int y,int w,const char * text,int wEdit,char * buffer,size_t len)175 MenuCreateString (int x, int y, int w, const char *text, int wEdit, char *buffer, size_t len)
176 {
177 XBMenuStringItem *string;
178
179 assert (w - wEdit > 0);
180 assert (buffer != NULL);
181 assert (len > 0);
182 /* create item */
183 string = calloc (1, sizeof (*string));
184 assert (NULL != string);
185 MenuSetItem (&string->item, MIT_String, x, y, w, CELL_H, MenuStringFocus, StringEventLoop,
186 MenuStringMouse, MenuStringPoll);
187 /* set label */
188 string->text = text;
189 string->lSprite =
190 CreateTextSprite (text, (x + 1) * BASE_X, (y + 1) * BASE_Y, (w - wEdit - 2) * BASE_X,
191 (CELL_H - 2) * BASE_Y, FF_STRING_TEXT_NO_FOCUS, SPM_MAPPED);
192 /* create work buffer */
193 string->len = len;
194 string->buffer = buffer;
195 string->work = calloc (1, len);
196 assert (NULL != string->work);
197 memcpy (string->work, buffer, len);
198 string->pos = strlen (buffer);
199 assert (string->pos < string->len);
200 /* create editor */
201 string->eSprite =
202 CreateTextSprite (string->work, (x + w - wEdit + 1) * BASE_X, (y + 2) * BASE_Y,
203 (wEdit - 2) * BASE_X, (CELL_H - 4) * BASE_Y, FF_STRING_VALUE_NO_SELECT,
204 SPM_MAPPED);
205 /* graphics */
206 MenuAddLargeFrame ((x - CELL_W / 2) / CELL_W, (x + w + CELL_W / 2 - 1) / CELL_W, y / CELL_H);
207 /* that's all */
208 return &string->item;
209 } /* CreateMenuString */
210
211 /*
212 * delete a string
213 */
214 void
MenuDeleteString(XBMenuItem * item)215 MenuDeleteString (XBMenuItem * item)
216 {
217 XBMenuStringItem *string = (XBMenuStringItem *) item;
218
219 assert (string->lSprite != NULL);
220 assert (string->eSprite != NULL);
221 assert (string->work != NULL);
222 DeleteSprite (string->lSprite);
223 DeleteSprite (string->eSprite);
224 free (string->work);
225 } /* DeleteComboItem */
226
227 /*
228 * end of file mi_string.c
229 */
230