Freeciv-3.1: /fast/freeciv/nightly/S3_1/client/gui-sdl2/widget.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
widget.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14/***********************************************************************
15 widget.c - description
16 -------------------
17 begin : June 30 2002
18 copyright : (C) 2002 by Rafał Bursig
19 email : Rafał Bursig <bursig@poczta.fm>
20***********************************************************************/
21
22#ifdef HAVE_CONFIG_H
23#include <fc_config.h>
24#endif
25
26/* SDL2 */
27#ifdef SDL2_PLAIN_INCLUDE
28#include <SDL.h>
29#else /* SDL2_PLAIN_INCLUDE */
30#include <SDL2/SDL.h>
31#endif /* SDL2_PLAIN_INCLUDE */
32
33/* utility */
34#include "log.h"
35
36/* gui-sdl2 */
37#include "colors.h"
38#include "graphics.h"
39#include "gui_id.h"
40#include "gui_main.h"
41#include "gui_tilespec.h"
42#include "mapview.h"
43#include "themespec.h"
44
45#include "widget.h"
46#include "widget_p.h"
47
48 struct widget *selected_widget;
49 SDL_Rect *info_area = NULL;
50
51extern Uint32 widget_info_counter;
52
53/* ================================ Private ============================ */
54
55 static struct widget *begin_main_widget_list;
56
57 static SDL_Surface *info_label = NULL;
58
59/**********************************************************************/
63 void correct_size_bcgnd_surf(SDL_Surface *ptheme,
64 int *width, int *height)
65{
66 *width = MAX(*width, 2 * (ptheme->w / adj_size(16)));
67 *height = MAX(*height, 2 * (ptheme->h / adj_size(16)));
68}
69
70/**********************************************************************/
78 SDL_Surface *create_bcgnd_surf(SDL_Surface *ptheme, enum widget_state state,
79 Uint16 width, Uint16 height)
80{
81 bool zoom;
82 int tile_width_len_end, tile_width_len_mid, tile_count_len_mid;
83 int tile_width_height_end, tile_width_height_mid, tile_count_height_mid;
84 int i, j;
85 SDL_Rect src, des;
86 SDL_Surface *background = NULL;
87 int start_y = (ptheme->h / 4) * state;
88
89 tile_width_len_end = ptheme->w / 16;
90 tile_width_len_mid = ptheme->w - (tile_width_len_end * 2);
91
92 tile_count_len_mid =
93 (width - (tile_width_len_end * 2)) / tile_width_len_mid;
94
95 /* corrections I */
96 if (((tile_count_len_mid *
97 tile_width_len_mid) + (tile_width_len_end * 2)) < width) {
98 tile_count_len_mid++;
99 }
100
101 tile_width_height_end = ptheme->h / 16;
102 tile_width_height_mid = (ptheme->h / 4) - (tile_width_height_end * 2);
103 tile_count_height_mid =
104 (height - (tile_width_height_end * 2)) / tile_width_height_mid;
105
106 /* corrections II */
107 if (((tile_count_height_mid *
108 tile_width_height_mid) + (tile_width_height_end * 2)) < height) {
109 tile_count_height_mid++;
110 }
111
112 i = MAX(tile_width_len_end * 2, width);
113 j = MAX(tile_width_height_end * 2, height);
114 zoom = ((i != width) || (j != height));
115
116 /* now allocate memory */
117 background = create_surf(i, j, SDL_SWSURFACE);
118
119 /* copy left end */
120
121 /* left top */
122 src.x = 0;
123 src.y = start_y;
124 src.w = tile_width_len_end;
125 src.h = tile_width_height_end;
126
127 des.x = 0;
128 des.y = 0;
129 alphablit(ptheme, &src, background, &des, 255);
130
131 /* left middle */
132 src.y = start_y + tile_width_height_end;
133 src.h = tile_width_height_mid;
134 for (i = 0; i < tile_count_height_mid; i++) {
135 des.y = tile_width_height_end + i * tile_width_height_mid;
136 alphablit(ptheme, &src, background, &des, 255);
137 }
138
139 /* left bottom */
140 src.y = start_y + ((ptheme->h / 4) - tile_width_height_end);
141 src.h = tile_width_height_end;
142 des.y = background->h - tile_width_height_end;
143 clear_surface(background, &des);
144 alphablit(ptheme, &src, background, &des, 255);
145
146 /* copy middle parts */
147
148 src.x = tile_width_len_end;
149 src.y = start_y;
150 src.w = tile_width_len_mid;
151
152 for (i = 0; i < tile_count_len_mid; i++) {
153
154 /* middle top */
155 des.x = tile_width_len_end + i * tile_width_len_mid;
156 des.y = 0;
157 src.y = start_y;
158 alphablit(ptheme, &src, background, &des, 255);
159
160 /* middle middle */
161 src.y = start_y + tile_width_height_end;
162 src.h = tile_width_height_mid;
163 for (j = 0; j < tile_count_height_mid; j++) {
164 des.y = tile_width_height_end + j * tile_width_height_mid;
165 alphablit(ptheme, &src, background, &des, 255);
166 }
167
168 /* middle bottom */
169 src.y = start_y + ((ptheme->h / 4) - tile_width_height_end);
170 src.h = tile_width_height_end;
171 des.y = background->h - tile_width_height_end;
172 clear_surface(background, &des);
173 alphablit(ptheme, &src, background, &des, 255);
174 }
175
176 /* copy right end */
177
178 /* right top */
179 src.x = ptheme->w - tile_width_len_end;
180 src.y = start_y;
181 src.w = tile_width_len_end;
182
183 des.x = background->w - tile_width_len_end;
184 des.y = 0;
185
186 alphablit(ptheme, &src, background, &des, 255);
187
188 /* right middle */
189 src.y = start_y + tile_width_height_end;
190 src.h = tile_width_height_mid;
191 for (i = 0; i < tile_count_height_mid; i++) {
192 des.y = tile_width_height_end + i * tile_width_height_mid;
193 alphablit(ptheme, &src, background, &des, 255);
194 }
195
196 /* right bottom */
197 src.y = start_y + ((ptheme->h / 4) - tile_width_height_end);
198 src.h = tile_width_height_end;
199 des.y = background->h - tile_width_height_end;
200 clear_surface(background, &des);
201 alphablit(ptheme, &src, background, &des, 255);
202
203 if (zoom) {
204 SDL_Surface *zoomed = resize_surface(background, width, height, 1);
205
206 FREESURFACE(background);
207 background = zoomed;
208 }
209
210 return background;
211}
212
213/* =================================================== */
214/* ===================== WIDGET LIST ==================== */
215/* =================================================== */
216
217/**********************************************************************/
222 struct widget *find_next_widget_at_pos(struct widget *start_widget,
223 int x, int y)
224{
225 SDL_Rect area = {0, 0, 0, 0};
226 struct widget *pwidget;
227
228 pwidget = start_widget ? start_widget : begin_main_widget_list;
229
230 while (pwidget) {
231 area.x = pwidget->dst->dest_rect.x + pwidget->size.x;
232 area.y = pwidget->dst->dest_rect.y + pwidget->size.y;
233 area.w = pwidget->size.w;
234 area.h = pwidget->size.h;
235 if (is_in_rect_area(x, y, area)
236 && !((get_wflags(pwidget) & WF_HIDDEN) == WF_HIDDEN)) {
237 return (struct widget *) pwidget;
238 }
239 pwidget = pwidget->next;
240 }
241
242 return NULL;
243}
244
245/**********************************************************************/
251 struct widget *find_next_widget_for_key(struct widget *start_widget,
252 SDL_Keysym key)
253{
254 struct widget *pwidget;
255
256 pwidget = start_widget ? start_widget : begin_main_widget_list;
257
258 key.mod &= ~(KMOD_NUM | KMOD_CAPS);
259 while (pwidget) {
260 if ((pwidget->key == key.sym
261 || (pwidget->key == SDLK_RETURN && key.sym == SDLK_KP_ENTER)
262 || (pwidget->key == SDLK_KP_ENTER && key.sym == SDLK_RETURN))
263 && ((pwidget->mod & key.mod) || (pwidget->mod == key.mod))) {
264 if (!((get_wstate(pwidget) == FC_WS_DISABLED)
265 || ((get_wflags(pwidget) & WF_HIDDEN) == WF_HIDDEN))) {
266 return (struct widget *) pwidget;
267 }
268 }
269 pwidget = pwidget->next;
270 }
271
272 return NULL;
273}
274
275/**********************************************************************/
295 Uint16 widget_pressed_action(struct widget *pwidget)
296{
297 Uint16 id;
298
299 if (!pwidget) {
300 return 0;
301 }
302
303 widget_info_counter = 0;
304 if (info_area) {
305 dirty_sdl_rect(info_area);
306 FC_FREE(info_area);
307 FREESURFACE(info_label);
308 }
309
310 switch (get_wtype(pwidget)) {
311 case WT_TI_BUTTON:
312 case WT_I_BUTTON:
313 case WT_ICON:
314 case WT_ICON2:
315 if (PRESSED_EVENT(main_data.event)) {
316 set_wstate(pwidget, FC_WS_PRESSED);
317 widget_redraw(pwidget);
318 widget_mark_dirty(pwidget);
319 flush_dirty();
320 set_wstate(pwidget, FC_WS_SELECTED);
321 SDL_Delay(300);
322 }
323 if (pwidget->action != NULL && pwidget->action(pwidget)) {
324 id = 0;
325 } else {
326 id = pwidget->id;
327 }
328
329 break;
330
331 case WT_EDIT:
332 {
333 if (PRESSED_EVENT(main_data.event)) {
334 bool ret, loop = (get_wflags(pwidget) & WF_EDIT_LOOP);
335 enum edit_return_codes change;
336
337 do {
338 ret = FALSE;
339 change = edit_field(pwidget);
340 if (change != ED_FORCE_EXIT && (!loop || change != ED_RETURN)) {
341 widget_redraw(pwidget);
342 widget_mark_dirty(pwidget);
343 flush_dirty();
344 }
345 if (change != ED_FORCE_EXIT && change != ED_ESC
346 && pwidget->action != NULL) {
347 pwidget->action(pwidget);
348 }
349 if (loop && change == ED_RETURN) {
350 ret = TRUE;
351 }
352 } while (ret);
353 }
354
355 id = 0;
356 break;
357 }
358 case WT_VSCROLLBAR:
359 case WT_HSCROLLBAR:
360 if (PRESSED_EVENT(main_data.event)) {
361 set_wstate(pwidget, FC_WS_PRESSED);
362 widget_redraw(pwidget);
363 widget_mark_dirty(pwidget);
364 flush_dirty();
365 }
366 if (pwidget->action != NULL && pwidget->action(pwidget)) {
367 id = 0;
368 } else {
369 id = pwidget->id;
370 }
371
372 break;
373 case WT_CHECKBOX:
374 case WT_TCHECKBOX:
375 if (PRESSED_EVENT(main_data.event)) {
376 set_wstate(pwidget, FC_WS_PRESSED);
377 widget_redraw(pwidget);
378 widget_mark_dirty(pwidget);
379 flush_dirty();
380 set_wstate(pwidget, FC_WS_SELECTED);
381 toggle_checkbox(pwidget);
382 SDL_Delay(300);
383 }
384 if (pwidget->action != NULL && pwidget->action(pwidget)) {
385 id = 0;
386 } else {
387 id = pwidget->id;
388 }
389
390 break;
391 case WT_COMBO:
392 if (PRESSED_EVENT(main_data.event)) {
393 set_wstate(pwidget, FC_WS_PRESSED);
394 combo_popup(pwidget);
395 } else {
396 combo_popdown(pwidget);
397 }
398
399 id = 0;
400 break;
401 default:
402 if (pwidget->action != NULL && pwidget->action(pwidget)) {
403 id = 0;
404 } else {
405 id = pwidget->id;
406 }
407
408 break;
409 }
410
411 return id;
412}
413
414/**********************************************************************/
417 void unselect_widget_action(void)
418{
419 if (selected_widget && (get_wstate(selected_widget) != FC_WS_DISABLED)) {
420 set_wstate(selected_widget, FC_WS_NORMAL);
421
422 if (!(get_wflags(selected_widget) & WF_HIDDEN)) {
423 selected_widget->unselect(selected_widget);
424
425 /* turn off quick info timer/counter */
426 widget_info_counter = 0;
427 }
428 }
429
430 if (info_area) {
431 flush_rect(info_area, FALSE);
432 FC_FREE(info_area);
433 FREESURFACE(info_label);
434 }
435
436 selected_widget = NULL;
437}
438
439/**********************************************************************/
442 void widget_selected_action(struct widget *pwidget)
443{
444 if (!pwidget || pwidget == selected_widget) {
445 return;
446 }
447
448 if (selected_widget) {
449 unselect_widget_action();
450 }
451
452 set_wstate(pwidget, FC_WS_SELECTED);
453
454 pwidget->select(pwidget);
455
456 selected_widget = pwidget;
457
458 if (get_wflags(pwidget) & WF_WIDGET_HAS_INFO_LABEL) {
459 widget_info_counter = 1;
460 }
461}
462
463/**********************************************************************/
466 void redraw_widget_info_label(SDL_Rect *rect)
467{
468 SDL_Surface *text;
469 SDL_Rect srcrect, dstrect;
470 SDL_Color color;
471 struct widget *pwidget = selected_widget;
472
473 if (!pwidget || !pwidget->info_label) {
474 return;
475 }
476
477 if (!info_label) {
478 info_area = fc_calloc(1, sizeof(SDL_Rect));
479
480 color = pwidget->info_label->fgcol;
481 pwidget->info_label->style |= TTF_STYLE_BOLD;
482 pwidget->info_label->fgcol = *get_theme_color(COLOR_THEME_QUICK_INFO_TEXT);
483
484 /* create string and bcgd theme */
485 text = create_text_surf_from_utf8(pwidget->info_label);
486
487 pwidget->info_label->fgcol = color;
488
489 info_label = create_filled_surface(text->w + adj_size(10), text->h + adj_size(6),
490 SDL_SWSURFACE,
491 get_theme_color(COLOR_THEME_QUICK_INFO_BG));
492
493 /* calculate start position */
494 if ((pwidget->dst->dest_rect.y + pwidget->size.y) - info_label->h - adj_size(6) < 0) {
495 info_area->y = (pwidget->dst->dest_rect.y + pwidget->size.y) + pwidget->size.h + adj_size(3);
496 } else {
497 info_area->y = (pwidget->dst->dest_rect.y + pwidget->size.y) - info_label->h - adj_size(5);
498 }
499
500 if ((pwidget->dst->dest_rect.x + pwidget->size.x) + info_label->w + adj_size(5) > main_window_width()) {
501 info_area->x = (pwidget->dst->dest_rect.x + pwidget->size.x) - info_label->w - adj_size(5);
502 } else {
503 info_area->x = (pwidget->dst->dest_rect.x + pwidget->size.x) + adj_size(3);
504 }
505
506 info_area->w = info_label->w + adj_size(2);
507 info_area->h = info_label->h + adj_size(3);
508
509 /* draw text */
510 dstrect.x = adj_size(6);
511 dstrect.y = adj_size(3);
512
513 alphablit(text, NULL, info_label, &dstrect, 255);
514
515 FREESURFACE(text);
516
517 /* draw frame */
518 create_frame(info_label,
519 0, 0, info_label->w - 1, info_label->h - 1,
520 get_theme_color(COLOR_THEME_QUICK_INFO_FRAME));
521
522 }
523
524 if (rect) {
525 dstrect.x = MAX(rect->x, info_area->x);
526 dstrect.y = MAX(rect->y, info_area->y);
527
528 srcrect.x = dstrect.x - info_area->x;
529 srcrect.y = dstrect.y - info_area->y;
530 srcrect.w = MIN((info_area->x + info_area->w), (rect->x + rect->w)) - dstrect.x;
531 srcrect.h = MIN((info_area->y + info_area->h), (rect->y + rect->h)) - dstrect.y;
532
533 screen_blit(info_label, &srcrect, &dstrect, 255);
534 } else {
535 screen_blit(info_label, NULL, info_area, 255);
536 }
537
538 if (correct_rect_region(info_area)) {
539 update_main_screen();
540#if 0
541 SDL_UpdateRect(main_data.screen, info_area->x, info_area->y,
542 info_area->w, info_area->h);
543#endif /* 0 */
544 }
545}
546
547/**********************************************************************/
551 struct widget *get_widget_pointer_from_id(const struct widget *gui_list,
552 Uint16 id, enum scan_direction direction)
553{
554 if (direction == SCAN_FORWARD) {
555 while (gui_list) {
556 if (gui_list->id == id) {
557 return (struct widget *) gui_list;
558 }
559 gui_list = gui_list->next;
560 }
561 } else {
562 while (gui_list) {
563 if (gui_list->id == id) {
564 return (struct widget *) gui_list;
565 }
566 gui_list = gui_list->prev;
567 }
568 }
569
570 return NULL;
571}
572
573/**********************************************************************/
577 struct widget *get_widget_pointer_from_main_list(Uint16 id)
578{
579 return get_widget_pointer_from_id(begin_main_widget_list, id, SCAN_FORWARD);
580}
581
582/**********************************************************************/
585 void add_to_gui_list(Uint16 id, struct widget *gui)
586{
587 if (begin_main_widget_list != NULL) {
588 gui->next = begin_main_widget_list;
589 gui->id = id;
590 begin_main_widget_list->prev = gui;
591 begin_main_widget_list = gui;
592 } else {
593 begin_main_widget_list = gui;
594 begin_main_widget_list->id = id;
595 }
596}
597
598/**********************************************************************/
601 void widget_add_as_prev(struct widget *new_widget, struct widget *add_dock)
602{
603 new_widget->next = add_dock;
604 new_widget->prev = add_dock->prev;
605 if (add_dock->prev) {
606 add_dock->prev->next = new_widget;
607 }
608 add_dock->prev = new_widget;
609 if (add_dock == begin_main_widget_list) {
610 begin_main_widget_list = new_widget;
611 }
612}
613
614/**********************************************************************/
621 void del_widget_pointer_from_gui_list(struct widget *gui)
622{
623 if (!gui) {
624 return;
625 }
626
627 if (gui == begin_main_widget_list) {
628 begin_main_widget_list = begin_main_widget_list->next;
629 }
630
631 if (gui->prev && gui->next) {
632 gui->prev->next = gui->next;
633 gui->next->prev = gui->prev;
634 } else {
635 if (gui->prev) {
636 gui->prev->next = NULL;
637 }
638
639 if (gui->next) {
640 gui->next->prev = NULL;
641 }
642
643 }
644
645 if (selected_widget == gui) {
646 selected_widget = NULL;
647 }
648}
649
650/**********************************************************************/
656 bool is_this_widget_first_on_list(struct widget *gui)
657{
658 return (begin_main_widget_list == gui);
659}
660
661/**********************************************************************/
666 void move_widget_to_front_of_gui_list(struct widget *gui)
667{
668 if (!gui || gui == begin_main_widget_list) {
669 return;
670 }
671
672 /* gui->prev always exists because
673 we don't do this to begin_main_widget_list */
674 if (gui->next) {
675 gui->prev->next = gui->next;
676 gui->next->prev = gui->prev;
677 } else {
678 gui->prev->next = NULL;
679 }
680
681 gui->next = begin_main_widget_list;
682 begin_main_widget_list->prev = gui;
683 begin_main_widget_list = gui;
684 gui->prev = NULL;
685}
686
687/**********************************************************************/
690 void del_main_list(void)
691{
692 del_gui_list(begin_main_widget_list);
693}
694
695/**********************************************************************/
698 void del_gui_list(struct widget *gui_list)
699{
700 while (gui_list) {
701 if (gui_list->next) {
702 gui_list = gui_list->next;
703 FREEWIDGET(gui_list->prev);
704 } else {
705 FREEWIDGET(gui_list);
706 }
707 }
708}
709
710/* ===================================================================== */
711/* ================================ Universal ========================== */
712/* ===================================================================== */
713
714/**********************************************************************/
719 Uint16 redraw_group(const struct widget *begin_group_widget_list,
720 const struct widget *end_group_widget_list,
721 int add_to_update)
722{
723 Uint16 count = 0;
724 struct widget *tmp_widget = (struct widget *) end_group_widget_list;
725
726 while (tmp_widget) {
727
728 if (!(get_wflags(tmp_widget) & WF_HIDDEN)) {
729
730 widget_redraw(tmp_widget);
731
732 if (add_to_update) {
733 widget_mark_dirty(tmp_widget);
734 }
735
736 count++;
737 }
738
739 if (tmp_widget == begin_group_widget_list) {
740 break;
741 }
742
743 tmp_widget = tmp_widget->prev;
744
745 }
746
747 return count;
748}
749
750/**********************************************************************/
753 void undraw_group(struct widget *begin_group_widget_list,
754 struct widget *end_group_widget_list)
755{
756 struct widget *tmp_widget = end_group_widget_list;
757
758 while (tmp_widget) {
759 widget_undraw(tmp_widget);
760 widget_mark_dirty(tmp_widget);
761
762 if (tmp_widget == begin_group_widget_list) {
763 break;
764 }
765
766 tmp_widget = tmp_widget->prev;
767 }
768}
769
770/**********************************************************************/
773 void set_new_group_start_pos(const struct widget *begin_group_widget_list,
774 const struct widget *end_group_widget_list,
775 Sint16 Xrel, Sint16 Yrel)
776{
777 struct widget *tmp_widget = (struct widget *) end_group_widget_list;
778
779 while (tmp_widget) {
780
781 widget_set_position(tmp_widget, tmp_widget->size.x + Xrel,
782 tmp_widget->size.y + Yrel);
783
784 if (get_wtype(tmp_widget) == WT_VSCROLLBAR
785 && tmp_widget->private_data.adv_dlg
786 && tmp_widget->private_data.adv_dlg->scroll) {
787 tmp_widget->private_data.adv_dlg->scroll->max += Yrel;
788 tmp_widget->private_data.adv_dlg->scroll->min += Yrel;
789 }
790
791 if (get_wtype(tmp_widget) == WT_HSCROLLBAR
792 && tmp_widget->private_data.adv_dlg
793 && tmp_widget->private_data.adv_dlg->scroll) {
794 tmp_widget->private_data.adv_dlg->scroll->max += Xrel;
795 tmp_widget->private_data.adv_dlg->scroll->min += Xrel;
796 }
797
798 if (tmp_widget == begin_group_widget_list) {
799 break;
800 }
801
802 tmp_widget = tmp_widget->prev;
803 }
804}
805
806/**********************************************************************/
811 void move_group_to_front_of_gui_list(struct widget *begin_group_widget_list,
812 struct widget *end_group_widget_list)
813{
814 struct widget *tmp_widget = end_group_widget_list, *prev = NULL;
815 struct gui_layer *gui_layer = get_gui_layer(end_group_widget_list->dst->surface);
816
817 /* Widget Pointer Management */
818 while (tmp_widget) {
819
820 prev = tmp_widget->prev;
821
822 /* tmp_widget->prev always exists because we
823 don't do this to begin_main_widget_list */
824 if (tmp_widget->next) {
825 tmp_widget->prev->next = tmp_widget->next;
826 tmp_widget->next->prev = tmp_widget->prev;
827 } else {
828 tmp_widget->prev->next = NULL;
829 }
830
831 tmp_widget->next = begin_main_widget_list;
832 begin_main_widget_list->prev = tmp_widget;
833 begin_main_widget_list = tmp_widget;
834 begin_main_widget_list->prev = NULL;
835
836 if (tmp_widget == begin_group_widget_list) {
837 break;
838 }
839
840 tmp_widget = prev;
841 }
842
843 /* Window Buffer Management */
844 if (gui_layer) {
845 int i = 0;
846
847 while ((i < main_data.guis_count - 1) && main_data.guis[i]) {
848 if (main_data.guis[i] && main_data.guis[i + 1]
849 && (main_data.guis[i] == gui_layer)) {
850 main_data.guis[i] = main_data.guis[i + 1];
851 main_data.guis[i + 1] = gui_layer;
852 }
853 i++;
854 }
855 }
856}
857
858/**********************************************************************/
862 void del_group_of_widgets_from_gui_list(struct widget *begin_group_widget_list,
863 struct widget *end_group_widget_list)
864{
865 struct widget *tmp_widget = end_group_widget_list;
866
867 if (!end_group_widget_list) {
868 return;
869 }
870
871 if (begin_group_widget_list == end_group_widget_list) {
872 del_widget_from_gui_list(tmp_widget);
873 return;
874 }
875
876 tmp_widget = tmp_widget->prev;
877
878 while (tmp_widget) {
879 struct widget *buf_widget = NULL;
880
881 buf_widget = tmp_widget->next;
882 del_widget_from_gui_list(buf_widget);
883
884 if (tmp_widget == begin_group_widget_list) {
885 del_widget_from_gui_list(tmp_widget);
886 break;
887 }
888
889 tmp_widget = tmp_widget->prev;
890 }
891
892}
893
894/**********************************************************************/
897 void set_group_state(struct widget *begin_group_widget_list,
898 struct widget *end_group_widget_list, enum widget_state state)
899{
900 struct widget *tmp_widget = end_group_widget_list;
901
902 while (tmp_widget) {
903 set_wstate(tmp_widget, state);
904 if (tmp_widget == begin_group_widget_list) {
905 break;
906 }
907 tmp_widget = tmp_widget->prev;
908 }
909}
910
911/**********************************************************************/
914 void hide_group(struct widget *begin_group_widget_list,
915 struct widget *end_group_widget_list)
916{
917 struct widget *tmp_widget = end_group_widget_list;
918
919 while (tmp_widget) {
920 set_wflag(tmp_widget, WF_HIDDEN);
921
922 if (tmp_widget == begin_group_widget_list) {
923 break;
924 }
925
926 tmp_widget = tmp_widget->prev;
927 }
928}
929
930/**********************************************************************/
933 void show_group(struct widget *begin_group_widget_list,
934 struct widget *end_group_widget_list)
935{
936 struct widget *tmp_widget = end_group_widget_list;
937
938 while (tmp_widget) {
939 clear_wflag(tmp_widget, WF_HIDDEN);
940
941 if (tmp_widget == begin_group_widget_list) {
942 break;
943 }
944
945 tmp_widget = tmp_widget->prev;
946 }
947}
948
949/**********************************************************************/
952 void group_set_area(struct widget *begin_group_widget_list,
953 struct widget *end_group_widget_list,
954 SDL_Rect area)
955{
956 struct widget *pwidget = end_group_widget_list;
957
958 while (pwidget) {
959 widget_set_area(pwidget, area);
960
961 if (pwidget == begin_group_widget_list) {
962 break;
963 }
964
965 pwidget = pwidget->prev;
966 }
967}
968
969/* ===================================================================== *
970 * =========================== Window Group ============================ *
971 * ===================================================================== */
972
973/*
974 * Window Group - group with 'begin' and 'end' where
975 * windowed type widget is last on list ( 'end' ).
976 */
977
978/**********************************************************************/
982 void popdown_window_group_dialog(struct widget *begin_group_widget_list,
983 struct widget *end_group_widget_list)
984{
985 if ((begin_group_widget_list) && (end_group_widget_list)) {
986 widget_mark_dirty(end_group_widget_list);
987 remove_gui_layer(end_group_widget_list->dst);
988
989 del_group(begin_group_widget_list, end_group_widget_list);
990 }
991}
992
993/**********************************************************************/
997 bool select_window_group_dialog(struct widget *begin_widget_list,
998 struct widget *pwindow)
999{
1000 if (!is_this_widget_first_on_list(begin_widget_list)) {
1001 move_group_to_front_of_gui_list(begin_widget_list, pwindow);
1002
1003 return TRUE;
1004 }
1005
1006 return FALSE;
1007}
1008
1009/**********************************************************************/
1015 bool move_window_group_dialog(struct widget *begin_group_widget_list,
1016 struct widget *end_group_widget_list)
1017{
1018 bool ret = FALSE;
1019 Sint16 old_x = end_group_widget_list->size.x, old_y = end_group_widget_list->size.y;
1020
1021 if (move_window(end_group_widget_list)) {
1022 set_new_group_start_pos(begin_group_widget_list,
1023 end_group_widget_list->prev,
1024 end_group_widget_list->size.x - old_x,
1025 end_group_widget_list->size.y - old_y);
1026 ret = TRUE;
1027 }
1028
1029 return ret;
1030}
1031
1032/**********************************************************************/
1038 void move_window_group(struct widget *begin_widget_list, struct widget *pwindow)
1039{
1040 if (select_window_group_dialog(begin_widget_list, pwindow)) {
1041 widget_flush(pwindow);
1042 }
1043
1044 move_window_group_dialog(begin_widget_list, pwindow);
1045}
1046
1047/**********************************************************************/
1050 int setup_vertical_widgets_position(int step,
1051 Sint16 start_x, Sint16 start_y,
1052 Uint16 w, Uint16 h,
1053 struct widget *begin, struct widget *end)
1054{
1055 struct widget *buf = end;
1056 register int count = 0;
1057 register int real_start_x = start_x;
1058 int ret = 0;
1059
1060 while (buf) {
1061 buf->size.x = real_start_x;
1062 buf->size.y = start_y;
1063
1064 if (w) {
1065 buf->size.w = w;
1066 }
1067
1068 if (h) {
1069 buf->size.h = h;
1070 }
1071
1072 if (((count + 1) % step) == 0) {
1073 real_start_x = start_x;
1074 start_y += buf->size.h;
1075 if (!(get_wflags(buf) & WF_HIDDEN)) {
1076 ret += buf->size.h;
1077 }
1078 } else {
1079 real_start_x += buf->size.w;
1080 }
1081
1082 if (buf == begin) {
1083 break;
1084 }
1085 count++;
1086 buf = buf->prev;
1087 }
1088
1089 return ret;
1090}
1091
1092/* =================================================== */
1093/* ======================= WINDOWs ==================== */
1094/* =================================================== */
1095
1096/**************************************************************************
1097 Window Manager Mechanism.
1098 Idea is simple each window/dialog has own buffer layer which is draw
1099 on screen during flush operations.
1100 This consume lots of memory but is extremly effecive.
1101
1102 Each widget has own "destination" parm == where ( on what buffer )
1103 will be draw.
1104**************************************************************************/
1105
1106/* =================================================== */
1107/* ======================== MISC ===================== */
1108/* =================================================== */
1109
1110/**********************************************************************/
1113 void draw_frame(SDL_Surface *pdest, Sint16 start_x, Sint16 start_y,
1114 Uint16 w, Uint16 h)
1115{
1116 SDL_Surface *tmp_left =
1117 resize_surface(current_theme->fr_left, current_theme->fr_left->w, h, 1);
1118 SDL_Surface *tmp_right =
1119 resize_surface(current_theme->fr_right, current_theme->fr_right->w, h, 1);
1120 SDL_Surface *tmp_top =
1121 resize_surface(current_theme->fr_top, w, current_theme->fr_top->h, 1);
1122 SDL_Surface *tmp_bottom =
1123 resize_surface(current_theme->fr_bottom, w, current_theme->fr_bottom->h, 1);
1124 SDL_Rect tmp,dst = {start_x, start_y, 0, 0};
1125
1126 tmp = dst;
1127 alphablit(tmp_left, NULL, pdest, &tmp, 255);
1128
1129 dst.x += w - tmp_right->w;
1130 tmp = dst;
1131 alphablit(tmp_right, NULL, pdest, &tmp, 255);
1132
1133 dst.x = start_x;
1134 tmp = dst;
1135 alphablit(tmp_top, NULL, pdest, &tmp, 255);
1136
1137 dst.y += h - tmp_bottom->h;
1138 tmp = dst;
1139 alphablit(tmp_bottom, NULL, pdest, &tmp, 255);
1140
1141 FREESURFACE(tmp_left);
1142 FREESURFACE(tmp_right);
1143 FREESURFACE(tmp_top);
1144 FREESURFACE(tmp_bottom);
1145}
1146
1147/**********************************************************************/
1150 void refresh_widget_background(struct widget *pwidget)
1151{
1152 if (pwidget) {
1153 if (pwidget->gfx && pwidget->gfx->w == pwidget->size.w
1154 && pwidget->gfx->h == pwidget->size.h) {
1155 clear_surface(pwidget->gfx, NULL);
1156 alphablit(pwidget->dst->surface, &pwidget->size, pwidget->gfx, NULL, 255);
1157 } else {
1158 FREESURFACE(pwidget->gfx);
1159 pwidget->gfx = crop_rect_from_surface(pwidget->dst->surface, &pwidget->size);
1160 }
1161 }
1162}
height
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
width
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
id
int int id
Definition editgui_g.h:28
current_theme
QString current_theme
Definition fc_client.cpp:65
flush_dirty
void flush_dirty(void)
Definition mapview.c:450
get_theme_color
SDL_Color * get_theme_color(enum theme_color themecolor)
Definition colors.c:44
resize_surface
SDL_Surface * resize_surface(const SDL_Surface *psrc, Uint16 new_width, Uint16 new_height, int smooth)
Definition graphics.c:1236
is_in_rect_area
bool is_in_rect_area(int x, int y, SDL_Rect rect)
Definition graphics.c:925
main_window_width
int main_window_width(void)
Definition graphics.c:685
update_main_screen
void update_main_screen(void)
Definition graphics.c:669
remove_gui_layer
void remove_gui_layer(struct gui_layer *gui_layer)
Definition graphics.c:148
create_filled_surface
SDL_Surface * create_filled_surface(Uint16 w, Uint16 h, Uint32 flags, SDL_Color *pcolor)
Definition graphics.c:368
crop_rect_from_surface
SDL_Surface * crop_rect_from_surface(SDL_Surface *psource, SDL_Rect *prect)
Definition graphics.c:236
alphablit
int alphablit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:199
get_gui_layer
struct gui_layer * get_gui_layer(SDL_Surface *surface)
Definition graphics.c:90
screen_blit
int screen_blit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:223
main_data
struct sdl2_data main_data
Definition graphics.c:57
create_surf
SDL_Surface * create_surf(int width, int height, Uint32 flags)
Definition graphics.c:351
clear_surface
int clear_surface(SDL_Surface *surf, SDL_Rect *dstrect)
Definition graphics.c:400
correct_rect_region
bool correct_rect_region(SDL_Rect *prect)
Definition graphics.c:888
create_frame
void create_frame(SDL_Surface *dest, Sint16 left, Sint16 top, Sint16 width, Sint16 height, SDL_Color *pcolor)
Definition graphics.c:1347
FREESURFACE
#define FREESURFACE(ptr)
Definition graphics.h:322
adj_size
#define adj_size(size)
Definition gui_main.h:138
PRESSED_EVENT
#define PRESSED_EVENT(event)
Definition gui_main.h:68
flush_rect
void flush_rect(SDL_Rect *rect, bool force_flush)
Definition mapview.c:103
dirty_sdl_rect
void dirty_sdl_rect(SDL_Rect *Rect)
Definition mapview.c:181
colors.h
graphics.h
gui_main.h
mapview.h
gui_id.h
create_text_surf_from_utf8
SDL_Surface * create_text_surf_from_utf8(utf8_str *pstr)
Definition gui_string.c:425
gui_tilespec.h
log.h
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
gui
static mpgui * gui
Definition mpgui_qt.cpp:52
MIN
#define MIN(x, y)
Definition shared.h:55
MAX
#define MAX(x, y)
Definition shared.h:54
step
int step
Definition specpq.h:92
color
Definition colors.h:20
gui_layer
Definition graphics.h:227
gui_layer::surface
SDL_Surface * surface
Definition graphics.h:229
gui_layer::dest_rect
SDL_Rect dest_rect
Definition graphics.h:228
sdl2_data::guis_count
int guis_count
Definition graphics.h:207
sdl2_data::event
SDL_Event event
Definition graphics.h:217
sdl2_data::guis
struct gui_layer ** guis
Definition graphics.h:216
sdl2_data::screen
SDL_Window * screen
Definition graphics.h:209
utf8_str::style
Uint8 style
Definition gui_string.h:53
utf8_str::fgcol
SDL_Color fgcol
Definition gui_string.h:57
widget
Definition widget.h:112
widget::next
struct widget * next
Definition widget.h:113
widget::unselect
void(* unselect)(struct widget *pwidget)
Definition widget.h:168
widget::info_label
utf8_str * info_label
Definition widget.h:122
widget::key
SDL_Keycode key
Definition widget.h:153
widget::select
void(* select)(struct widget *pwidget)
Definition widget.h:167
widget::dst
struct gui_layer * dst
Definition widget.h:116
widget::gfx
SDL_Surface * gfx
Definition widget.h:120
widget::prev
struct widget * prev
Definition widget.h:114
widget::action
int(* action)(struct widget *)
Definition widget.h:157
widget::cont
struct container * cont
Definition widget.h:127
widget::mod
Uint16 mod
Definition widget.h:154
widget::area
SDL_Rect area
Definition widget.h:149
widget::id
Uint16 id
Definition widget.h:155
widget::size
SDL_Rect size
Definition widget.h:145
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
COLOR_THEME_QUICK_INFO_TEXT
@ COLOR_THEME_QUICK_INFO_TEXT
Definition themecolors.h:35
COLOR_THEME_QUICK_INFO_BG
@ COLOR_THEME_QUICK_INFO_BG
Definition themecolors.h:33
COLOR_THEME_QUICK_INFO_FRAME
@ COLOR_THEME_QUICK_INFO_FRAME
Definition themecolors.h:34
themespec.h
begin_main_widget_list
static struct widget * begin_main_widget_list
Definition widget.c:55
find_next_widget_for_key
struct widget * find_next_widget_for_key(struct widget *start_widget, SDL_Keysym key)
Definition widget.c:251
del_widget_pointer_from_gui_list
void del_widget_pointer_from_gui_list(struct widget *gui)
Definition widget.c:621
set_new_group_start_pos
void set_new_group_start_pos(const struct widget *begin_group_widget_list, const struct widget *end_group_widget_list, Sint16 Xrel, Sint16 Yrel)
Definition widget.c:773
redraw_widget_info_label
void redraw_widget_info_label(SDL_Rect *rect)
Definition widget.c:466
widget_pressed_action
Uint16 widget_pressed_action(struct widget *pwidget)
Definition widget.c:295
set_group_state
void set_group_state(struct widget *begin_group_widget_list, struct widget *end_group_widget_list, enum widget_state state)
Definition widget.c:897
move_group_to_front_of_gui_list
void move_group_to_front_of_gui_list(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:811
correct_size_bcgnd_surf
void correct_size_bcgnd_surf(SDL_Surface *ptheme, int *width, int *height)
Definition widget.c:63
info_label
static SDL_Surface * info_label
Definition widget.c:57
add_to_gui_list
void add_to_gui_list(Uint16 id, struct widget *gui)
Definition widget.c:585
widget_selected_action
void widget_selected_action(struct widget *pwidget)
Definition widget.c:442
get_widget_pointer_from_main_list
struct widget * get_widget_pointer_from_main_list(Uint16 id)
Definition widget.c:577
del_group_of_widgets_from_gui_list
void del_group_of_widgets_from_gui_list(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:862
move_window_group_dialog
bool move_window_group_dialog(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:1015
find_next_widget_at_pos
struct widget * find_next_widget_at_pos(struct widget *start_widget, int x, int y)
Definition widget.c:222
selected_widget
struct widget * selected_widget
Definition widget.c:48
refresh_widget_background
void refresh_widget_background(struct widget *pwidget)
Definition widget.c:1150
del_gui_list
void del_gui_list(struct widget *gui_list)
Definition widget.c:698
widget_info_counter
Uint32 widget_info_counter
Definition gui_main.c:99
draw_frame
void draw_frame(SDL_Surface *pdest, Sint16 start_x, Sint16 start_y, Uint16 w, Uint16 h)
Definition widget.c:1113
info_area
SDL_Rect * info_area
Definition widget.c:49
show_group
void show_group(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:933
unselect_widget_action
void unselect_widget_action(void)
Definition widget.c:417
hide_group
void hide_group(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:914
is_this_widget_first_on_list
bool is_this_widget_first_on_list(struct widget *gui)
Definition widget.c:656
get_widget_pointer_from_id
struct widget * get_widget_pointer_from_id(const struct widget *gui_list, Uint16 id, enum scan_direction direction)
Definition widget.c:551
widget_add_as_prev
void widget_add_as_prev(struct widget *new_widget, struct widget *add_dock)
Definition widget.c:601
undraw_group
void undraw_group(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:753
del_main_list
void del_main_list(void)
Definition widget.c:690
create_bcgnd_surf
SDL_Surface * create_bcgnd_surf(SDL_Surface *ptheme, enum widget_state state, Uint16 width, Uint16 height)
Definition widget.c:78
select_window_group_dialog
bool select_window_group_dialog(struct widget *begin_widget_list, struct widget *pwindow)
Definition widget.c:997
group_set_area
void group_set_area(struct widget *begin_group_widget_list, struct widget *end_group_widget_list, SDL_Rect area)
Definition widget.c:952
setup_vertical_widgets_position
int setup_vertical_widgets_position(int step, Sint16 start_x, Sint16 start_y, Uint16 w, Uint16 h, struct widget *begin, struct widget *end)
Definition widget.c:1050
move_widget_to_front_of_gui_list
void move_widget_to_front_of_gui_list(struct widget *gui)
Definition widget.c:666
redraw_group
Uint16 redraw_group(const struct widget *begin_group_widget_list, const struct widget *end_group_widget_list, int add_to_update)
Definition widget.c:719
popdown_window_group_dialog
void popdown_window_group_dialog(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:982
move_window_group
void move_window_group(struct widget *begin_widget_list, struct widget *pwindow)
Definition widget.c:1038
widget.h
widget_set_position
static void widget_set_position(struct widget *pwidget, int x, int y)
Definition widget.h:266
widget_state
widget_state
Definition widget.h:95
FC_WS_DISABLED
@ FC_WS_DISABLED
Definition widget.h:99
FC_WS_NORMAL
@ FC_WS_NORMAL
Definition widget.h:96
FC_WS_PRESSED
@ FC_WS_PRESSED
Definition widget.h:98
FC_WS_SELECTED
@ FC_WS_SELECTED
Definition widget.h:97
clear_wflag
void clear_wflag(struct widget *pwidget, enum widget_flag flag)
Definition widget_core.c:62
scan_direction
scan_direction
Definition widget.h:190
SCAN_FORWARD
@ SCAN_FORWARD
Definition widget.h:191
widget_mark_dirty
static void widget_mark_dirty(struct widget *pwidget)
Definition widget.h:286
widget_flush
static void widget_flush(struct widget *pwidget)
Definition widget.h:291
get_wflags
enum widget_flag get_wflags(const struct widget *pwidget)
Definition widget_core.c:86
FREEWIDGET
#define FREEWIDGET(pwidget)
Definition widget.h:305
set_wstate
void set_wstate(struct widget *pwidget, enum widget_state state)
Definition widget_core.c:36
get_wstate
enum widget_state get_wstate(const struct widget *pwidget)
Definition widget_core.c:70
widget_undraw
static void widget_undraw(struct widget *pwidget)
Definition widget.h:296
WF_EDIT_LOOP
@ WF_EDIT_LOOP
Definition widget.h:91
WF_WIDGET_HAS_INFO_LABEL
@ WF_WIDGET_HAS_INFO_LABEL
Definition widget.h:88
WF_HIDDEN
@ WF_HIDDEN
Definition widget.h:68
widget_redraw
static int widget_redraw(struct widget *pwidget)
Definition widget.h:276
del_widget_from_gui_list
#define del_widget_from_gui_list(__gui)
Definition widget.h:372
widget_set_area
static void widget_set_area(struct widget *pwidget, SDL_Rect area)
Definition widget.h:261
get_wtype
enum widget_type get_wtype(const struct widget *pwidget)
Definition widget_core.c:78
set_wflag
void set_wflag(struct widget *pwidget, enum widget_flag flag)
Definition widget_core.c:54
del_group
#define del_group(begin_group_widget_list, end_group_widget_list)
Definition widget.h:389
WT_TI_BUTTON
@ WT_TI_BUTTON
Definition widget.h:46
WT_VSCROLLBAR
@ WT_VSCROLLBAR
Definition widget.h:50
WT_EDIT
@ WT_EDIT
Definition widget.h:48
WT_HSCROLLBAR
@ WT_HSCROLLBAR
Definition widget.h:51
WT_TCHECKBOX
@ WT_TCHECKBOX
Definition widget.h:59
WT_COMBO
@ WT_COMBO
Definition widget.h:62
WT_CHECKBOX
@ WT_CHECKBOX
Definition widget.h:58
WT_I_BUTTON
@ WT_I_BUTTON
Definition widget.h:44
WT_ICON2
@ WT_ICON2
Definition widget.h:60
WT_ICON
@ WT_ICON
Definition widget.h:49
toggle_checkbox
void toggle_checkbox(struct widget *cbox)
Definition widget_checkbox.c:225
combo_popup
void combo_popup(struct widget *combo)
Definition widget_combo.c:138
combo_popdown
void combo_popdown(struct widget *combo)
Definition widget_combo.c:212
edit_field
enum edit_return_codes edit_field(struct widget *edit_widget)
Definition widget_edit.c:681
edit_return_codes
edit_return_codes
Definition widget_edit.h:17
ED_FORCE_EXIT
@ ED_FORCE_EXIT
Definition widget_edit.h:21
ED_ESC
@ ED_ESC
Definition widget_edit.h:19
ED_RETURN
@ ED_RETURN
Definition widget_edit.h:18
widget_p.h
move_window
bool move_window(struct widget *pwindow)
Definition widget_window.c:352