|
1 /***************************************************************************** |
|
2 * Copyright (C) 2015 |
|
3 * |
|
4 * Michiel Broek <mbroek at mbse dot eu> |
|
5 * |
|
6 * This file is part of the mbsePi-apps emulator |
|
7 * |
|
8 * The gui code is based on the gui from the emulator ARAnyM, |
|
9 * Copyright (c) 2004 Petr Stehlik of ARAnyM dev team |
|
10 * |
|
11 * This progrm is free software; you can redistribute it and/or modify it |
|
12 * under the terms of the GNU General Public License as published by the |
|
13 * Free Software Foundation; either version 2, or (at your option) any |
|
14 * later version. |
|
15 * |
|
16 * mbsePi-apps is distributed in the hope that it will be useful, but |
|
17 * WITHOUT ANY WARRANTY; without even the implied warranty of |
|
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
19 * General Public License for more details. |
|
20 * |
|
21 * You should have received a copy of the GNU General Public License |
|
22 * along with mbsePi-apps; see the file COPYING. If not, write to the Free |
|
23 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
|
24 *****************************************************************************/ |
|
25 |
|
26 #include "brewpanel.h" |
|
27 #include "sdlgui.h" |
|
28 #include "lcdfont10x16.h" |
|
29 |
|
30 |
|
31 static SDL_Surface *pSdlGuiScrn; /* Pointer to the actual main SDL screen surface */ |
|
32 static SDL_Surface *pFontGfx = NULL; /* The LCD font graphics */ |
|
33 static int fontwidth, fontheight; /* Width & height of the actual font */ |
|
34 TTF_Font *pFont = NULL; /* TTF font for buttons etc. */ |
|
35 |
|
36 extern int my_shutdown; |
|
37 |
|
38 |
|
39 /*-----------------------------------------------------------------------*/ |
|
40 /* |
|
41 * Load an 1 plane XBM into a 8 planes SDL_Surface. |
|
42 */ |
|
43 static SDL_Surface *SDLGui_LoadXBM(int w, int h, const char *pXbmBits) |
|
44 { |
|
45 SDL_Surface *bitmap; |
|
46 Uint8 *dstbits; |
|
47 const Uint8 *srcbits; |
|
48 int x, y, srcpitch, mask; |
|
49 |
|
50 srcbits = (Uint8 *)pXbmBits; |
|
51 |
|
52 /* Allocate the bitmap */ |
|
53 if ((bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0)) == NULL) { |
|
54 syslog(LOG_NOTICE, "Failed to allocate bitmap: %s", SDL_GetError()); |
|
55 return NULL; |
|
56 } |
|
57 |
|
58 srcpitch = ((w + 7) / 8); |
|
59 dstbits = (Uint8 *)bitmap->pixels; |
|
60 mask = 1; |
|
61 |
|
62 /* Copy the pixels */ |
|
63 for (y = 0 ; y < h ; y++) { |
|
64 for (x = 0 ; x < w ; x++) { |
|
65 dstbits[x] = (srcbits[x / 8] & mask) ? 1 : 0; |
|
66 mask <<= 1; |
|
67 mask |= (mask >> 8); |
|
68 mask &= 0xFF; |
|
69 } |
|
70 dstbits += bitmap->pitch; |
|
71 srcbits += srcpitch; |
|
72 } |
|
73 |
|
74 return bitmap; |
|
75 } |
|
76 |
|
77 |
|
78 |
|
79 /* |
|
80 * Initialize the GUI. |
|
81 */ |
|
82 int SDLGui_Init(void) |
|
83 { |
|
84 char *Pt = NULL; |
|
85 |
|
86 SDL_Color blackWhiteColors[2] = {{255, 255, 255, 0}, {0, 0, 0, 0}}; |
|
87 |
|
88 /* |
|
89 * Initialize the LCD font graphics: |
|
90 */ |
|
91 pFontGfx = SDLGui_LoadXBM(lcdfont10x16_width, lcdfont10x16_height, lcdfont10x16_bits); |
|
92 if (pFontGfx == NULL) { |
|
93 syslog(LOG_NOTICE, "Error: Can not init font graphics!"); |
|
94 return -1; |
|
95 } |
|
96 |
|
97 /* Set color palette of the LCD font graphics: */ |
|
98 SDL_SetColors(pFontGfx, blackWhiteColors, 0, 2); |
|
99 |
|
100 /* Set font color 0 as transparent: */ |
|
101 SDL_SetColorKey(pFontGfx, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 0); |
|
102 |
|
103 if (TTF_Init() == -1) { |
|
104 syslog(LOG_NOTICE, "Could not init SDL_ttf"); |
|
105 return -1; |
|
106 } |
|
107 |
|
108 /* |
|
109 * Load TTF font for the dialogs |
|
110 */ |
|
111 Pt = calloc(1024, sizeof(char)); |
|
112 sprintf(Pt, "%s", "/usr/share/fonts/TTF/DejaVuSans.ttf"); |
|
113 if ((pFont = TTF_OpenFont(Pt, 14 )) == NULL) { |
|
114 sprintf(Pt, "%s", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"); |
|
115 if ((pFont = TTF_OpenFont(Pt, 14 )) == NULL) { |
|
116 sprintf(Pt, "%s", "/usr/share/fonts/truetype/freefont/DejaVuSans.ttf"); |
|
117 if ((pFont = TTF_OpenFont(Pt, 14 )) == NULL) { |
|
118 syslog(LOG_NOTICE, "Could not load DejaVuSans.ttf"); |
|
119 return -1; |
|
120 } |
|
121 } |
|
122 } |
|
123 syslog(LOG_NOTICE, "Using ttf font: %s\n", Pt); |
|
124 free(Pt); |
|
125 Pt = NULL; |
|
126 |
|
127 return 0; |
|
128 } |
|
129 |
|
130 |
|
131 |
|
132 /* |
|
133 * Uninitialize the GUI. |
|
134 */ |
|
135 int SDLGui_UnInit(void) |
|
136 { |
|
137 if (pFont) |
|
138 TTF_CloseFont(pFont); |
|
139 pFont = NULL; |
|
140 |
|
141 if (pFontGfx) |
|
142 SDL_FreeSurface(pFontGfx); |
|
143 pFontGfx = NULL; |
|
144 |
|
145 return 0; |
|
146 } |
|
147 |
|
148 |
|
149 |
|
150 /* |
|
151 * Inform the SDL-GUI about the actual SDL_Surface screen pointer and |
|
152 * prepare the font to suit the actual resolution. |
|
153 */ |
|
154 int SDLGui_SetScreen(SDL_Surface *pScrn) |
|
155 { |
|
156 pSdlGuiScrn = pScrn; |
|
157 |
|
158 if (pFontGfx == NULL) { |
|
159 syslog(LOG_NOTICE, "Error: A problem with the font occured!"); |
|
160 return -1; |
|
161 } |
|
162 |
|
163 /* Get the font width and height: */ |
|
164 fontwidth = pFontGfx->w/16; |
|
165 fontheight = pFontGfx->h/16; |
|
166 |
|
167 return 0; |
|
168 } |
|
169 |
|
170 |
|
171 |
|
172 /* |
|
173 * Center a dialog so that it appears in the middle of the screen. |
|
174 * Note: We only store the coordinates in the root box of the dialog, |
|
175 * all other objects in the dialog are positioned relatively to this one. |
|
176 */ |
|
177 void SDLGui_CenterDlg(SGOBJ *dlg) |
|
178 { |
|
179 dlg[0].x = (pSdlGuiScrn->w/1-dlg[0].w)/2; |
|
180 dlg[0].y = (pSdlGuiScrn->h/1-dlg[0].h)/2; |
|
181 } |
|
182 |
|
183 |
|
184 |
|
185 /* |
|
186 * Draw a text string using TTF |
|
187 */ |
|
188 static void SDLGui_TTF(int x, int y, const char *txt) |
|
189 { |
|
190 SDL_Rect offset; |
|
191 SDL_Color textColor = { 0, 0, 0 }; |
|
192 SDL_Surface* message = NULL; |
|
193 |
|
194 message = TTF_RenderText_Solid(pFont, txt, textColor); |
|
195 offset.x = x; |
|
196 offset.y = y; |
|
197 SDL_BlitSurface(message, NULL, pSdlGuiScrn, &offset); |
|
198 SDL_FreeSurface(message); |
|
199 message = NULL; |
|
200 } |
|
201 |
|
202 |
|
203 |
|
204 /* |
|
205 * Draw a dialog TTF text object. |
|
206 */ |
|
207 static void SDLGui_DrawTTF(const SGOBJ *tdlg, int objnum) |
|
208 { |
|
209 int x, y; |
|
210 |
|
211 x = (tdlg[0].x + tdlg[objnum].x); |
|
212 y = (tdlg[0].y + tdlg[objnum].y); |
|
213 SDLGui_TTF(x, y, tdlg[objnum].txt); |
|
214 } |
|
215 |
|
216 |
|
217 |
|
218 /* |
|
219 * Draw a text string. |
|
220 */ |
|
221 static void SDLGui_Text(int x, int y, const char *txt) |
|
222 { |
|
223 int i; |
|
224 char c; |
|
225 SDL_Rect sr, dr; |
|
226 |
|
227 for (i=0; txt[i]!=0; i++) { |
|
228 c = txt[i]; |
|
229 sr.x=fontwidth*(c%16); |
|
230 sr.y=fontheight*(c/16); |
|
231 sr.w=fontwidth; |
|
232 sr.h=fontheight; |
|
233 dr.x=x+i*(fontwidth+2); |
|
234 dr.y=y; |
|
235 dr.w=fontwidth; |
|
236 dr.h=fontheight; |
|
237 SDL_BlitSurface(pFontGfx, &sr, pSdlGuiScrn, &dr); |
|
238 } |
|
239 } |
|
240 |
|
241 |
|
242 |
|
243 /* |
|
244 * Draw a dialog text object. |
|
245 */ |
|
246 static void SDLGui_DrawText(const SGOBJ *tdlg, int objnum) |
|
247 { |
|
248 int x, y; |
|
249 |
|
250 x = (tdlg[0].x + tdlg[objnum].x); |
|
251 y = (tdlg[0].y + tdlg[objnum].y); |
|
252 SDLGui_Text(x, y, tdlg[objnum].txt); |
|
253 } |
|
254 |
|
255 |
|
256 |
|
257 /* |
|
258 * Draw a dialog LCD object. |
|
259 */ |
|
260 static void SDLGui_DrawLCD(const SGOBJ *bdlg, int objnum) |
|
261 { |
|
262 SDL_Rect rect; |
|
263 int x, y, w, h, offset, border = 4; |
|
264 Uint32 bg0 = SDL_MapRGB(pSdlGuiScrn->format, 94,147, 69); |
|
265 Uint32 bg1 = SDL_MapRGB(pSdlGuiScrn->format,156,235, 4); |
|
266 Uint32 bc = SDL_MapRGB(pSdlGuiScrn->format, 32, 32, 32); |
|
267 Uint32 bg; |
|
268 |
|
269 /* |
|
270 * Width and height are given in character columns and rows, |
|
271 * so calculate the display size in pixels. |
|
272 */ |
|
273 w = bdlg[objnum].w * (fontwidth + 2) + 10; |
|
274 h = bdlg[objnum].h * (fontheight + 2) + 4; |
|
275 |
|
276 if (bdlg[objnum].x == -1) { |
|
277 /* |
|
278 * Auto center |
|
279 */ |
|
280 x = (bdlg[0].w - w) / 2; |
|
281 } else { |
|
282 x = bdlg[objnum].x; |
|
283 } |
|
284 y = bdlg[objnum].y; |
|
285 if (objnum > 0) { /* Since the root object is a box, too, */ |
|
286 /* we have to look for it now here and only */ |
|
287 x += bdlg[0].x; /* add its absolute coordinates if we need to */ |
|
288 y += bdlg[0].y; |
|
289 } |
|
290 |
|
291 if (bdlg[objnum].state & SG_SELECTED) { |
|
292 bg = bg1; |
|
293 } else { |
|
294 bg = bg0; |
|
295 } |
|
296 |
|
297 /* The root box should be bigger than the screen, so we disable the offset there: */ |
|
298 if (objnum != 0) |
|
299 offset = border; |
|
300 else |
|
301 offset = 0; |
|
302 |
|
303 /* Draw background: */ |
|
304 rect.x = x; |
|
305 rect.y = y; |
|
306 rect.w = w; |
|
307 rect.h = h; |
|
308 SDL_FillRect(pSdlGuiScrn, &rect, bg); |
|
309 |
|
310 /* Draw upper border: */ |
|
311 rect.x = x - offset; |
|
312 rect.y = y - offset; |
|
313 rect.w = w + offset + offset; |
|
314 rect.h = border; |
|
315 SDL_FillRect(pSdlGuiScrn, &rect, bc); |
|
316 |
|
317 /* Draw left border: */ |
|
318 rect.x = x - offset; |
|
319 rect.y = y; |
|
320 rect.w = border; |
|
321 rect.h = h; |
|
322 SDL_FillRect(pSdlGuiScrn, &rect, bc); |
|
323 |
|
324 /* Draw bottom border: */ |
|
325 rect.x = x - offset; |
|
326 rect.y = y + h - border + offset; |
|
327 rect.w = w + offset + offset; |
|
328 rect.h = border; |
|
329 SDL_FillRect(pSdlGuiScrn, &rect, bc); |
|
330 |
|
331 /* Draw right border: */ |
|
332 rect.x = x + w - border + offset; |
|
333 rect.y = y; |
|
334 rect.w = border; |
|
335 rect.h = h; |
|
336 SDL_FillRect(pSdlGuiScrn, &rect, bc); |
|
337 } |
|
338 |
|
339 |
|
340 |
|
341 /* |
|
342 * Draw a dialog box object. |
|
343 */ |
|
344 static void SDLGui_DrawBox(const SGOBJ *bdlg, int objnum) |
|
345 { |
|
346 SDL_Rect rect; |
|
347 int x, y, w, h, offset, shade = 2; |
|
348 Uint32 grey = SDL_MapRGB(pSdlGuiScrn->format,192,192,192); |
|
349 Uint32 upleftc, downrightc; |
|
350 |
|
351 x = bdlg[objnum].x; |
|
352 y = bdlg[objnum].y; |
|
353 if (objnum > 0) { /* Since the root object is a box, too, */ |
|
354 /* we have to look for it now here and only */ |
|
355 x += bdlg[0].x; /* add its absolute coordinates if we need to */ |
|
356 y += bdlg[0].y; |
|
357 } |
|
358 w = bdlg[objnum].w; |
|
359 h = bdlg[objnum].h; |
|
360 |
|
361 if (bdlg[objnum].state & SG_SELECTED) { |
|
362 upleftc = SDL_MapRGB(pSdlGuiScrn->format,128,128,128); |
|
363 downrightc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255); |
|
364 } else { |
|
365 upleftc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255); |
|
366 downrightc = SDL_MapRGB(pSdlGuiScrn->format,128,128,128); |
|
367 } |
|
368 |
|
369 /* The root box should be bigger than the screen, so we disable the offset there: */ |
|
370 if (objnum != 0) |
|
371 offset = shade; |
|
372 else |
|
373 offset = 0; |
|
374 |
|
375 /* Draw background: */ |
|
376 rect.x = x; |
|
377 rect.y = y; |
|
378 rect.w = w; |
|
379 rect.h = h; |
|
380 SDL_FillRect(pSdlGuiScrn, &rect, grey); |
|
381 |
|
382 /* Draw upper border: */ |
|
383 rect.x = x; |
|
384 rect.y = y - offset; |
|
385 rect.w = w; |
|
386 rect.h = shade; |
|
387 SDL_FillRect(pSdlGuiScrn, &rect, upleftc); |
|
388 |
|
389 /* Draw left border: */ |
|
390 rect.x = x - offset; |
|
391 rect.y = y; |
|
392 rect.w = shade; |
|
393 rect.h = h; |
|
394 SDL_FillRect(pSdlGuiScrn, &rect, upleftc); |
|
395 |
|
396 /* Draw bottom border: */ |
|
397 rect.x = x; |
|
398 rect.y = y + h - shade + offset; |
|
399 rect.w = w; |
|
400 rect.h = shade; |
|
401 SDL_FillRect(pSdlGuiScrn, &rect, downrightc); |
|
402 |
|
403 /* Draw right border: */ |
|
404 rect.x = x + w - shade + offset; |
|
405 rect.y = y; |
|
406 rect.w = shade; |
|
407 rect.h = h; |
|
408 SDL_FillRect(pSdlGuiScrn, &rect, downrightc); |
|
409 } |
|
410 |
|
411 |
|
412 |
|
413 /* |
|
414 * Draw a normal button. |
|
415 */ |
|
416 static void SDLGui_DrawButton(const SGOBJ *bdlg, int objnum) |
|
417 { |
|
418 int x, y, w, h; |
|
419 |
|
420 SDLGui_DrawBox(bdlg, objnum); |
|
421 /* |
|
422 * Use bold text and get outer dimensions of the text |
|
423 */ |
|
424 TTF_SetFontStyle(pFont, TTF_STYLE_BOLD); |
|
425 TTF_SizeText(pFont, bdlg[objnum].txt, &w, &h); |
|
426 x = bdlg[0].x + bdlg[objnum].x + (bdlg[objnum].w - w) / 2; |
|
427 y = bdlg[0].y + bdlg[objnum].y + (bdlg[objnum].h - h) / 2; |
|
428 |
|
429 if (bdlg[objnum].state & SG_SELECTED) { |
|
430 x += 1; |
|
431 y += 1; |
|
432 } |
|
433 |
|
434 if ((bdlg[objnum].flags & SG_HIDE) == 0) |
|
435 SDLGui_TTF(x, y, bdlg[objnum].txt); |
|
436 TTF_SetFontStyle(pFont, TTF_STYLE_NORMAL); |
|
437 } |
|
438 |
|
439 |
|
440 |
|
441 /* |
|
442 * Draw a whole dialog. |
|
443 */ |
|
444 void SDLGui_DrawDialog(const SGOBJ *dlg) |
|
445 { |
|
446 int i; |
|
447 |
|
448 for (i = 0; dlg[i].type != -1; i++) { |
|
449 switch (dlg[i].type) { |
|
450 case SGBOX: |
|
451 SDLGui_DrawBox(dlg, i); |
|
452 break; |
|
453 case SGLCD: |
|
454 SDLGui_DrawLCD(dlg, i); |
|
455 break; |
|
456 case SGTEXT: |
|
457 SDLGui_DrawText(dlg, i); |
|
458 break; |
|
459 case SGTTF: |
|
460 SDLGui_DrawTTF(dlg, i); |
|
461 break; |
|
462 case SGBUTTON: |
|
463 SDLGui_DrawButton(dlg, i); |
|
464 break; |
|
465 } |
|
466 } |
|
467 |
|
468 SDL_UpdateRect(pSdlGuiScrn, 0,0,0,0); |
|
469 } |
|
470 |
|
471 |
|
472 |
|
473 /* |
|
474 * Search an object at a certain position. |
|
475 */ |
|
476 static int SDLGui_FindObj(const SGOBJ *dlg, int fx, int fy) |
|
477 { |
|
478 int len, i, ob = -1, xpos, ypos; |
|
479 |
|
480 len = 0; |
|
481 while (dlg[len].type != -1) |
|
482 len++; |
|
483 |
|
484 xpos = fx; |
|
485 ypos = fy; |
|
486 /* Now search for the object: */ |
|
487 for (i = len; i >= 0; i--) { |
|
488 if (xpos >= dlg[0].x + dlg[i].x && ypos >= dlg[0].y + dlg[i].y && |
|
489 xpos < dlg[0].x + dlg[i].x + dlg[i].w && ypos < dlg[0].y + dlg[i].y + dlg[i].h) { |
|
490 ob = i; |
|
491 break; |
|
492 } |
|
493 } |
|
494 |
|
495 return ob; |
|
496 } |
|
497 |
|
498 |
|
499 |
|
500 /* |
|
501 * Search a button with a special flag (e.g. SG_DEFAULT or SG_CANCEL). |
|
502 */ |
|
503 static int SDLGui_SearchFlaggedButton(const SGOBJ *dlg, int flag) |
|
504 { |
|
505 int i = 0; |
|
506 |
|
507 while (dlg[i].type != -1) { |
|
508 if (dlg[i].flags & flag) |
|
509 return i; |
|
510 i++; |
|
511 } |
|
512 |
|
513 return 0; |
|
514 } |
|
515 |
|
516 |
|
517 |
|
518 /* |
|
519 * Show and process a dialog. Returns the button number that has been |
|
520 * pressed or SDLGUI_UNKNOWNEVENT if an unsupported event occured (will be |
|
521 * stored in parameter pEventOut). |
|
522 */ |
|
523 int SDLGui_DoDialog(SGOBJ *dlg, SDL_Event *pEventOut) |
|
524 { |
|
525 int obj = 0, oldbutton = 0, retbutton = 0, i, j, b; |
|
526 SDL_Event sdlEvent; |
|
527 SDL_Surface *pBgSurface; |
|
528 SDL_Rect dlgrect, bgrect; |
|
529 |
|
530 // if (pSdlGuiScrn->h / fontheight < dlg[0].h) |
|
531 // { |
|
532 // syslog(LOG_NOTICE, "Screen size too small for dialog!"); |
|
533 // return SDLGUI_ERROR; |
|
534 // } |
|
535 |
|
536 dlgrect.x = dlg[0].x; |
|
537 dlgrect.y = dlg[0].y; |
|
538 dlgrect.w = dlg[0].w; |
|
539 dlgrect.h = dlg[0].h; |
|
540 |
|
541 bgrect.x = bgrect.y = 0; |
|
542 bgrect.w = dlgrect.w; |
|
543 bgrect.h = dlgrect.h; |
|
544 |
|
545 /* |
|
546 * Save background |
|
547 */ |
|
548 pBgSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, dlgrect.w, dlgrect.h, pSdlGuiScrn->format->BitsPerPixel, |
|
549 pSdlGuiScrn->format->Rmask, pSdlGuiScrn->format->Gmask, pSdlGuiScrn->format->Bmask, pSdlGuiScrn->format->Amask); |
|
550 if (pSdlGuiScrn->format->palette != NULL) { |
|
551 SDL_SetColors(pBgSurface, pSdlGuiScrn->format->palette->colors, 0, pSdlGuiScrn->format->palette->ncolors-1); |
|
552 } |
|
553 |
|
554 if (pBgSurface != NULL) { |
|
555 SDL_BlitSurface(pSdlGuiScrn, &dlgrect, pBgSurface, &bgrect); |
|
556 } else { |
|
557 syslog(LOG_NOTICE, "SDLGUI_DoDialog: CreateRGBSurface failed: %s", SDL_GetError()); |
|
558 } |
|
559 |
|
560 /* (Re-)draw the dialog */ |
|
561 SDLGui_DrawDialog(dlg); |
|
562 |
|
563 /* |
|
564 * Is the left mouse button still pressed? Yes -> Handle TOUCHEXIT objects here |
|
565 */ |
|
566 SDL_PumpEvents(); |
|
567 b = SDL_GetMouseState(&i, &j); |
|
568 obj = SDLGui_FindObj(dlg, i, j); |
|
569 if (obj > 0 && (dlg[obj].flags & SG_TOUCHEXIT) ) { |
|
570 oldbutton = obj; |
|
571 if (b & SDL_BUTTON(1)) { |
|
572 dlg[obj].state |= SG_SELECTED; |
|
573 retbutton = obj; |
|
574 } |
|
575 } |
|
576 |
|
577 /* The main loop */ |
|
578 while (retbutton == 0 && !my_shutdown) { |
|
579 if (SDL_WaitEvent(&sdlEvent) == 1) /* Wait for events */ |
|
580 switch (sdlEvent.type) { |
|
581 case SDL_QUIT: |
|
582 retbutton = SDLGUI_QUIT; |
|
583 break; |
|
584 |
|
585 case SDL_MOUSEBUTTONDOWN: |
|
586 if (sdlEvent.button.button != SDL_BUTTON_LEFT) { |
|
587 /* Not left mouse button -> unsupported event */ |
|
588 if (pEventOut) |
|
589 retbutton = SDLGUI_UNKNOWNEVENT; |
|
590 break; |
|
591 } |
|
592 /* It was the left button: Find the object under the mouse cursor */ |
|
593 obj = SDLGui_FindObj(dlg, sdlEvent.button.x, sdlEvent.button.y); |
|
594 if (obj > 0) { |
|
595 if (dlg[obj].type == SGBUTTON) { |
|
596 dlg[obj].state |= SG_SELECTED; |
|
597 SDLGui_DrawButton(dlg, obj); |
|
598 SDL_UpdateRect(pSdlGuiScrn, dlg[0].x + dlg[obj].x - 2, dlg[0].y + dlg[obj].y - 2, dlg[obj].w + 4, dlg[obj].h + 4); |
|
599 oldbutton=obj; |
|
600 } |
|
601 if ( dlg[obj].flags & SG_TOUCHEXIT ) { |
|
602 dlg[obj].state |= SG_SELECTED; |
|
603 retbutton = obj; |
|
604 } |
|
605 } |
|
606 break; |
|
607 |
|
608 case SDL_MOUSEBUTTONUP: |
|
609 if (sdlEvent.button.button != SDL_BUTTON_LEFT) { |
|
610 /* Not left mouse button -> unsupported event */ |
|
611 if (pEventOut) |
|
612 retbutton = SDLGUI_UNKNOWNEVENT; |
|
613 break; |
|
614 } |
|
615 /* It was the left button: Find the object under the mouse cursor */ |
|
616 obj = SDLGui_FindObj(dlg, sdlEvent.button.x, sdlEvent.button.y); |
|
617 if (obj > 0) { |
|
618 switch (dlg[obj].type) { |
|
619 case SGBUTTON: |
|
620 if (oldbutton==obj) |
|
621 retbutton=obj; |
|
622 break; |
|
623 } |
|
624 } |
|
625 if (oldbutton > 0) { |
|
626 dlg[oldbutton].state &= ~SG_SELECTED; |
|
627 SDLGui_DrawButton(dlg, oldbutton); |
|
628 SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[oldbutton].x)*fontwidth-2, (dlg[0].y+dlg[oldbutton].y)*fontheight-2, |
|
629 dlg[oldbutton].w*fontwidth+4, dlg[oldbutton].h*fontheight+4); |
|
630 oldbutton = 0; |
|
631 } |
|
632 if (obj >= 0 && (dlg[obj].flags & SG_EXIT)) { |
|
633 retbutton = obj; |
|
634 } |
|
635 break; |
|
636 |
|
637 case SDL_MOUSEMOTION: |
|
638 break; |
|
639 |
|
640 case SDL_KEYDOWN: /* Key pressed */ |
|
641 if (sdlEvent.key.keysym.sym == SDLK_RETURN || sdlEvent.key.keysym.sym == SDLK_KP_ENTER) { |
|
642 retbutton = SDLGui_SearchFlaggedButton(dlg, SG_DEFAULT); |
|
643 } else if (sdlEvent.key.keysym.sym == SDLK_ESCAPE) { |
|
644 retbutton = SDLGui_SearchFlaggedButton(dlg, SG_CANCEL); |
|
645 } else if (pEventOut) { |
|
646 retbutton = SDLGUI_UNKNOWNEVENT; |
|
647 } |
|
648 break; |
|
649 |
|
650 default: |
|
651 if (pEventOut) |
|
652 retbutton = SDLGUI_UNKNOWNEVENT; |
|
653 break; |
|
654 } |
|
655 } |
|
656 |
|
657 /* Restore background */ |
|
658 if (pBgSurface) { |
|
659 SDL_BlitSurface(pBgSurface, &bgrect, pSdlGuiScrn, &dlgrect); |
|
660 SDL_FreeSurface(pBgSurface); |
|
661 } |
|
662 |
|
663 /* Copy event data of unsupported events if caller wants to have it */ |
|
664 if (retbutton == SDLGUI_UNKNOWNEVENT && pEventOut) |
|
665 memcpy(pEventOut, &sdlEvent, sizeof(SDL_Event)); |
|
666 |
|
667 if (retbutton == SDLGUI_QUIT) |
|
668 my_shutdown = TRUE; |
|
669 |
|
670 return retbutton; |
|
671 } |
|
672 |
|
673 |
|
674 |
|
675 void SDLGui_LCDwrite(SGOBJ *dlg, int x, int y, Uint8 c, int lcdindex) |
|
676 { |
|
677 int i, index; |
|
678 |
|
679 fprintf(stdout, "SDLGui_LCDwrite( , %d, %d, %c, %d)\n", x, y, c, lcdindex); |
|
680 |
|
681 i = index = 0; |
|
682 for (;;) { |
|
683 if (dlg[i].type == -1) { |
|
684 syslog(LOG_NOTICE, "SDLGui_LCDwrite() lcdindex=%d not found", lcdindex); |
|
685 return; |
|
686 } |
|
687 if (dlg[i].type == SGLCD) { |
|
688 if (index == lcdindex) |
|
689 break; |
|
690 index++; |
|
691 } |
|
692 i++; |
|
693 } |
|
694 fprintf(stdout, "SDLGui_LCDwrite i=%d LCD=%dx%d\n", i, dlg[i].w, dlg[i].h); |
|
695 |
|
696 } |
|
697 |
|
698 |