1 /***************************************************************************
2 menuitem.cpp - description
3 -------------------
4 begin : Tue Feb 29 2000
5 copyright : (C) 2000 by Michael Speck
6 email :
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "menuitem.h"
19 #include <string.h>
20 #include <stdlib.h>
21
22 extern Sdl sdl;
23 extern DrawRgn dr_src, dr_dst;
24
MenuItem()25 MenuItem::MenuItem() //separator
26 {
27 type = ET_SEPARATOR;
28 strcpy(name, " ");
29 Enlight(0);
30 alpha = 255;
31 used = 0;
32 }
33
MenuItem(char * n)34 MenuItem::MenuItem(char *n) //separator
35 {
36 type = ET_SEPARATOR;
37 strcpy(name, n);
38 Enlight(0);
39 alpha = 255;
40 used = 0;
41 }
42
MenuItem(char * n,int * p,char * cap1,char * cap2)43 MenuItem::MenuItem(char *n, int *p, char *cap1, char *cap2) //switch group
44 {
45 type = ET_SWITCHGRP;
46 strcpy(name, n);
47
48 sw_cap = new char*[2];
49 sw_cap[0] = cap1;
50 sw_cap[1] = cap2;
51 sw_cap_num = 2;
52
53 Enlight(0);
54 pos = p;
55 alpha = 255;
56 min = 0;
57 max = 1;
58 step = 1;
59 used = 0;
60 }
61
MenuItem(char * n,int * p,char ** caps,int num)62 MenuItem::MenuItem(char *n, int *p, char **caps, int num) //switch group
63 {
64 type = ET_SWITCHGRP;
65 strcpy(name, n);
66
67 sw_cap = new char*[num];
68 for (int i = 0; i < num; i++)
69 sw_cap[i] = caps[i];
70 sw_cap_num = num;
71
72 Enlight(0);
73 pos = p;
74 alpha = 255;
75 min = 0;
76 max = num-1;
77 step = 1;
78 used = 0;
79 }
80
MenuItem(char * n,int * p,int min,int max,int s)81 MenuItem::MenuItem(char *n, int *p, int min, int max, int s) //range
82 {
83 type = ET_RANGE;
84 strcpy(name, n);
85 Enlight(0);
86 pos = p;
87 alpha = 255;
88 step = s;
89 MenuItem::min = min;
90 MenuItem::max = max;
91 used = 0;
92 }
93
MenuItem(char * n,int * p,char * k)94 MenuItem::MenuItem(char *n, int *p, char *k) //restr_keys
95 {
96 type = ET_KEY;
97 strcpy(name, n);
98 Enlight(0);
99 pos = p;
100 alpha = 255;
101 used = 0;
102 }
103
MenuItem(char * n,int a_id)104 MenuItem::MenuItem(char *n, int a_id) //action
105 {
106 type = ET_ACTION;
107 strcpy(name, n);
108 Enlight(0);
109 alpha = 255;
110 action = a_id;
111 used = 0;
112 }
113
MenuItem(char * n,Menu * m)114 MenuItem::MenuItem(char *n, Menu* m) //submenu
115 {
116 type = ET_SUBMENU;
117 strcpy(name, n);
118 submenu = m;
119 Enlight(0);
120 alpha = 255;
121 used = 0;
122 }
123
MenuItem(char * n,char * p,int m)124 MenuItem::MenuItem(char *n, char *p, int m) //string
125 {
126 type = ET_STRING;
127 strcpy(name, n);
128 Enlight(0);
129 alpha = 255;
130 max = m;
131 pos = (int*)p;
132 min = strlen((char*)p);
133 used = 0;
134 }
135
~MenuItem()136 MenuItem::~MenuItem()
137 {
138 if (type == ET_SWITCHGRP)
139 delete sw_cap;
140 }
141
SetXY(int x,int y)142 void MenuItem::SetXY(int x, int y)
143 {
144 MenuItem::x = x;
145 MenuItem::y = y;
146 }
147
SetBackgnd(SDL_Surface * backgnd)148 void MenuItem::SetBackgnd(SDL_Surface *backgnd)
149 {
150 MenuItem::backgnd = backgnd;
151 }
152
SetSubmenu(Menu * m)153 void MenuItem::SetSubmenu(Menu* m)
154 {
155 }
156
SetFont(SFnt * fnt,SFnt * enlgt_fnt)157 void MenuItem::SetFont(SFnt *fnt, SFnt *enlgt_fnt)
158 {
159 font = fnt;
160 enlgt_font = enlgt_fnt;
161 }
162
ComputeStr()163 void MenuItem::ComputeStr()
164 {
165 switch (type) {
166 case ET_STRING:
167 sprintf(string, "%s: %s", name, (char*)pos);
168 break;
169 case ET_SWITCHGRP:
170 sprintf(string, "%s %s", name, sw_cap[*pos]);
171 break;
172 case ET_RANGE:
173 sprintf(string, "%s %i", name, *pos);
174 break;
175 case ET_KEY:
176 if (*pos > 32 && *pos < 127)
177 sprintf(string, "%s: '%c'", name, (char)*pos);
178 else
179 if (*pos == 0)
180 sprintf(string, "%s: ???", name);
181 else
182 switch (*pos){
183 case SDLK_UP:
184 sprintf(string, "%s: Up", name);
185 break;
186 case SDLK_DOWN:
187 sprintf(string, "%s: Down", name);
188 break;
189 case SDLK_LEFT:
190 sprintf(string, "%s: Left", name);
191 break;
192 case SDLK_RIGHT:
193 sprintf(string, "%s: Right", name);
194 break;
195 case SDLK_SPACE:
196 sprintf(string, "%s: Space", name);
197 break;
198 default:
199 sprintf(string, "%s: %i", name, *pos);
200 }
201 break;
202 default:
203 strcpy(string, name);
204 break;
205 }
206 ComputeSize();
207 }
208
Enlight(int t)209 void MenuItem::Enlight(int t)
210 {
211 if (t) {
212 if (!enlighted)
213 changed = 1;
214 else
215 changed = 0;
216 enlighted = 1;
217 alpha = 0;
218 }
219 else {
220 if (enlighted)
221 changed = 1;
222 else
223 changed = 0;
224 enlighted = 0;
225 }
226 }
227
Type()228 int MenuItem::Type()
229 {
230 return type;
231 }
232
KeyEvent(int code)233 int MenuItem::KeyEvent(int code)
234 {
235 if (type == ET_SWITCHGRP || type == ET_RANGE) {
236 int val = *pos;
237 switch (code) {
238 case SDLK_LEFT:
239 val -= step;
240 if (val < min)
241 val = max - ((max - min) % step);
242 used = 1;
243 break;
244 case SDLK_RIGHT:
245 val += step;
246 if (val > max) val = min;
247 used = 1;
248 break;
249 }
250 if (val != *pos) {
251 *pos = val;
252 StrUpdate();
253 }
254 return MR_CONTINUE;
255 }
256 else
257 if (type == ET_KEY && code == SDLK_RETURN){
258 *pos = 0;
259 StrUpdate();
260 }
261 return MR_CONTINUE;
262 }
263
SetKey(int code)264 void MenuItem::SetKey(int code)
265 {
266 if (*pos == 0) {
267 *pos = code;
268 StrUpdate();
269 }
270 }
271
Update()272 void MenuItem::Update()
273 {
274 if (!changed) return;
275 //redraw in buffer
276 if (enlighted) {
277 if (alpha > 0) {
278 SFnt_Write(font, sdl.scr, x, y, string, 0);
279 SFnt_Write(enlgt_font, sdl.scr, x, y, string, alpha);
280 }
281 else
282 SFnt_Write(enlgt_font, sdl.scr, x, y, string, 0);
283 }
284 else {
285 SFnt_Write(font, sdl.scr, x, y, string, 0);
286 if (alpha < 255)
287 SFnt_Write(enlgt_font, sdl.scr, x, y, string, alpha);
288 }
289 changed = 0;
290 }
291
SetChanged(int c)292 void MenuItem::SetChanged(int c)
293 {
294 changed = c;
295 }
296
Hide()297 void MenuItem::Hide()
298 {
299 if (dw != -1) {
300 DR_SETDST(sdl.scr, dx, dy, dw, dh);
301 DR_SETSRC(backgnd, dx, dy);
302 SSur_Blit();
303 }
304 }
305
Refresh()306 void MenuItem::Refresh()
307 {
308 SDL_UpdateRect(sdl.scr, dx, dy, dw, dh);
309 }
310
ComputeSize()311 void MenuItem::ComputeSize()
312 {
313 dw = SFnt_TextWidth(font, string);
314 dh = font->lh;
315 dx = x - (dw >> 1);
316 dy = y - (dh >> 1);
317 }
318
Compute()319 void MenuItem::Compute()
320 {
321 if (alpha < 255 && !enlighted) {
322 alpha += 3;
323 changed = 1;
324 }
325 else
326 if (alpha >= 5 && enlighted) {
327 alpha -= 3;
328 changed = 1;
329 }
330 }
331
Submenu()332 Menu* MenuItem::Submenu()
333 {
334 return submenu;
335 }
336
ActionId()337 int MenuItem::ActionId()
338 {
339 return action;
340 }
341
ClearAlpha()342 void MenuItem::ClearAlpha()
343 {
344 alpha = 255;
345 }
346
Pos()347 int MenuItem::Pos()
348 {
349 return *pos;
350 }
351
StrUpdate()352 void MenuItem::StrUpdate()
353 {
354 int x_old = dx;
355 int y_old = dy;
356 int w_old = dw;
357 int h_old = dh;
358 Hide();
359 ComputeStr();
360 changed = 1;
361 Update();
362 x_old = (dx < x_old) ? dx : x_old;
363 y_old = (dy < y_old) ? dy : y_old;
364 w_old = (dw > w_old) ? dw : w_old;
365 h_old = (dh > h_old) ? dh : h_old;
366 SDL_UpdateRect(sdl.scr, x_old, y_old, w_old, h_old);
367 }
368
EditStr(int code,int unicode)369 void MenuItem::EditStr(int code, int unicode)
370 {
371 if (code == SDLK_BACKSPACE && min > 0) {
372 //clear last char
373 ((char*)pos)[--min] = 0;
374 StrUpdate();
375 }
376 else
377 if (code >= 32 && code < 128 && min < max) {
378 //letter
379 ((char*)pos)[min++] = unicode;
380 StrUpdate();
381 }
382 }
383
SetRestrKeys(char * rk)384 void MenuItem::SetRestrKeys(char *rk)
385 {
386 restr_keys = rk;
387 }
388
NoBackgnd()389 void MenuItem::NoBackgnd()
390 {
391 dw = -1;
392 }
393
OnItem(int mx,int my)394 int MenuItem::OnItem(int mx, int my)
395 {
396 return (mx >= dx && mx < dx + dw && my >= dy && my <dy + dh);
397 }
398
ButtonEvent(SDL_MouseButtonEvent button)399 int MenuItem::ButtonEvent(SDL_MouseButtonEvent button)
400 {
401 if (type == ET_KEY) {
402 *pos = 0;
403 StrUpdate();
404 return MR_CONTINUE;
405 }
406 int val = *pos;
407 if (button.button == 3) {
408 val -= step;
409 if (val < min)
410 val = max - ((max - min) % step);
411 used = 1;
412 }
413 else
414 if (button.button == 1) {
415 val += step;
416 if (val > max) val = min;
417 used = 1;
418 }
419 if (val != *pos) {
420 *pos = val;
421 StrUpdate();
422 }
423 return MR_CONTINUE;
424 }
425
SetString(char * s,int rep)426 void MenuItem::SetString(char *s, int rep)
427 {
428 strcpy(name, s);
429 changed = 1;
430 if (rep)
431 StrUpdate();
432 else
433 ComputeStr();
434 }
435
SetRange(int ll,int ul,int st,int rep)436 void MenuItem::SetRange(int ll, int ul, int st, int rep)
437 {
438 min = ll;
439 max = ul;
440 step = st;
441 if (*pos > ul)
442 *pos = ll;
443 changed = 1;
444 if (rep)
445 StrUpdate();
446 }
447
Used()448 int MenuItem::Used()
449 {
450 int ret = used;
451 used = 0;
452 return ret;
453 }
454
SetUsed(int u)455 void MenuItem::SetUsed(int u)
456 {
457 used = u;
458 }
459