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