Freeciv-3.3: /fast/freeciv/nightly/main/client/gui-sdl2/widget.c Source File

Freeciv-3.3

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 struct widget *pwidget;
226
227 pwidget = start_widget ? start_widget : begin_main_widget_list;
228
229 while (pwidget) {
230 SDL_Rect area = {
231 .x = pwidget->dst->dest_rect.x + pwidget->size.x,
232 .y = pwidget->dst->dest_rect.y + pwidget->size.y,
233 .w = pwidget->size.w,
234 .h = pwidget->size.h};
235
236 if (is_in_rect_area(x, y, &area)
237 && !((get_wflags(pwidget) & WF_HIDDEN) == WF_HIDDEN)) {
238 return (struct widget *) pwidget;
239 }
240 pwidget = pwidget->next;
241 }
242
243 return NULL;
244}
245
246/**********************************************************************/
252 struct widget *find_next_widget_for_key(struct widget *start_widget,
253 SDL_Keysym key)
254{
255 struct widget *pwidget;
256
257 pwidget = start_widget ? start_widget : begin_main_widget_list;
258
259 key.mod &= ~(KMOD_NUM | KMOD_CAPS);
260 while (pwidget) {
261 if ((pwidget->key == key.sym
262 || (pwidget->key == SDLK_RETURN && key.sym == SDLK_KP_ENTER)
263 || (pwidget->key == SDLK_KP_ENTER && key.sym == SDLK_RETURN))
264 && ((pwidget->mod & key.mod) || (pwidget->mod == key.mod))) {
265 if (!((get_wstate(pwidget) == FC_WS_DISABLED)
266 || ((get_wflags(pwidget) & WF_HIDDEN) == WF_HIDDEN))) {
267 return (struct widget *) pwidget;
268 }
269 }
270 pwidget = pwidget->next;
271 }
272
273 return NULL;
274}
275
276/**********************************************************************/
296 Uint16 widget_pressed_action(struct widget *pwidget)
297{
298 Uint16 id;
299
300 if (!pwidget) {
301 return 0;
302 }
303
304 widget_info_counter = 0;
305 if (info_area) {
306 dirty_sdl_rect(info_area);
307 FC_FREE(info_area);
308 FREESURFACE(info_label);
309 }
310
311 switch (get_wtype(pwidget)) {
312 case WT_TI_BUTTON:
313 case WT_I_BUTTON:
314 case WT_ICON:
315 case WT_ICON2:
316 if (PRESSED_EVENT(main_data.event)) {
317 set_wstate(pwidget, FC_WS_PRESSED);
318 widget_redraw(pwidget);
319 widget_mark_dirty(pwidget);
320 flush_dirty();
321 set_wstate(pwidget, FC_WS_SELECTED);
322 SDL_Delay(300);
323 }
324 if (pwidget->action != NULL && pwidget->action(pwidget)) {
325 id = 0;
326 } else {
327 id = pwidget->id;
328 }
329
330 break;
331
332 case WT_EDIT:
333 {
334 if (PRESSED_EVENT(main_data.event)) {
335 bool ret, loop = (get_wflags(pwidget) & WF_EDIT_LOOP);
336 enum edit_return_codes change;
337
338 do {
339 ret = FALSE;
340 change = edit_field(pwidget);
341 if (change != ED_FORCE_EXIT && (!loop || change != ED_RETURN)) {
342 widget_redraw(pwidget);
343 widget_mark_dirty(pwidget);
344 flush_dirty();
345 }
346 if (change != ED_FORCE_EXIT && change != ED_ESC
347 && pwidget->action != NULL) {
348 pwidget->action(pwidget);
349 }
350 if (loop && change == ED_RETURN) {
351 ret = TRUE;
352 }
353 } while (ret);
354 }
355
356 id = 0;
357 break;
358 }
359 case WT_VSCROLLBAR:
360 case WT_HSCROLLBAR:
361 if (PRESSED_EVENT(main_data.event)) {
362 set_wstate(pwidget, FC_WS_PRESSED);
363 widget_redraw(pwidget);
364 widget_mark_dirty(pwidget);
365 flush_dirty();
366 }
367 if (pwidget->action != NULL && pwidget->action(pwidget)) {
368 id = 0;
369 } else {
370 id = pwidget->id;
371 }
372
373 break;
374 case WT_CHECKBOX:
375 case WT_TCHECKBOX:
376 if (PRESSED_EVENT(main_data.event)) {
377 set_wstate(pwidget, FC_WS_PRESSED);
378 widget_redraw(pwidget);
379 widget_mark_dirty(pwidget);
380 flush_dirty();
381 set_wstate(pwidget, FC_WS_SELECTED);
382 toggle_checkbox(pwidget);
383 SDL_Delay(300);
384 }
385 if (pwidget->action != NULL && pwidget->action(pwidget)) {
386 id = 0;
387 } else {
388 id = pwidget->id;
389 }
390
391 break;
392 case WT_COMBO:
393 if (PRESSED_EVENT(main_data.event)) {
394 set_wstate(pwidget, FC_WS_PRESSED);
395 combo_popup(pwidget);
396 } else {
397 combo_popdown(pwidget);
398 }
399
400 id = 0;
401 break;
402 default:
403 if (pwidget->action != NULL && pwidget->action(pwidget)) {
404 id = 0;
405 } else {
406 id = pwidget->id;
407 }
408
409 break;
410 }
411
412 return id;
413}
414
415/**********************************************************************/
418 void unselect_widget_action(void)
419{
420 if (selected_widget && (get_wstate(selected_widget) != FC_WS_DISABLED)) {
421 set_wstate(selected_widget, FC_WS_NORMAL);
422
423 if (!(get_wflags(selected_widget) & WF_HIDDEN)) {
424 selected_widget->unselect(selected_widget);
425
426 /* Turn off quick info timer/counter */
427 widget_info_counter = 0;
428 }
429 }
430
431 if (info_area) {
432 flush_rect(info_area, FALSE);
433 FC_FREE(info_area);
434 FREESURFACE(info_label);
435 }
436
437 selected_widget = NULL;
438}
439
440/**********************************************************************/
443 void widget_selected_action(struct widget *pwidget)
444{
445 if (!pwidget || pwidget == selected_widget) {
446 return;
447 }
448
449 if (selected_widget) {
450 unselect_widget_action();
451 }
452
453 set_wstate(pwidget, FC_WS_SELECTED);
454
455 pwidget->select(pwidget);
456
457 selected_widget = pwidget;
458
459 if (get_wflags(pwidget) & WF_WIDGET_HAS_INFO_LABEL) {
460 widget_info_counter = 1;
461 }
462}
463
464/**********************************************************************/
467 void redraw_widget_info_label(SDL_Rect *rect)
468{
469 SDL_Surface *text;
470 SDL_Rect srcrect, dstrect;
471 SDL_Color color;
472 struct widget *pwidget = selected_widget;
473
474 if (!pwidget || !pwidget->info_label) {
475 return;
476 }
477
478 if (!info_label) {
479 info_area = fc_calloc(1, sizeof(SDL_Rect));
480
481 color = pwidget->info_label->fgcol;
482 pwidget->info_label->style |= TTF_STYLE_BOLD;
483 pwidget->info_label->fgcol = *get_theme_color(COLOR_THEME_QUICK_INFO_TEXT);
484
485 /* create string and bcgd theme */
486 text = create_text_surf_from_utf8(pwidget->info_label);
487
488 pwidget->info_label->fgcol = color;
489
490 info_label = create_filled_surface(text->w + adj_size(10), text->h + adj_size(6),
491 SDL_SWSURFACE,
492 get_theme_color(COLOR_THEME_QUICK_INFO_BG));
493
494 /* calculate start position */
495 if ((pwidget->dst->dest_rect.y + pwidget->size.y) - info_label->h - adj_size(6) < 0) {
496 info_area->y = (pwidget->dst->dest_rect.y + pwidget->size.y) + pwidget->size.h + adj_size(3);
497 } else {
498 info_area->y = (pwidget->dst->dest_rect.y + pwidget->size.y) - info_label->h - adj_size(5);
499 }
500
501 if ((pwidget->dst->dest_rect.x + pwidget->size.x) + info_label->w + adj_size(5) > main_window_width()) {
502 info_area->x = (pwidget->dst->dest_rect.x + pwidget->size.x) - info_label->w - adj_size(5);
503 } else {
504 info_area->x = (pwidget->dst->dest_rect.x + pwidget->size.x) + adj_size(3);
505 }
506
507 info_area->w = info_label->w + adj_size(2);
508 info_area->h = info_label->h + adj_size(3);
509
510 /* draw text */
511 dstrect.x = adj_size(6);
512 dstrect.y = adj_size(3);
513
514 alphablit(text, NULL, info_label, &dstrect, 255);
515
516 FREESURFACE(text);
517
518 /* draw frame */
519 create_frame(info_label,
520 0, 0, info_label->w - 1, info_label->h - 1,
521 get_theme_color(COLOR_THEME_QUICK_INFO_FRAME));
522
523 }
524
525 if (rect) {
526 dstrect.x = MAX(rect->x, info_area->x);
527 dstrect.y = MAX(rect->y, info_area->y);
528
529 srcrect.x = dstrect.x - info_area->x;
530 srcrect.y = dstrect.y - info_area->y;
531 srcrect.w = MIN((info_area->x + info_area->w), (rect->x + rect->w)) - dstrect.x;
532 srcrect.h = MIN((info_area->y + info_area->h), (rect->y + rect->h)) - dstrect.y;
533
534 screen_blit(info_label, &srcrect, &dstrect, 255);
535 } else {
536 screen_blit(info_label, NULL, info_area, 255);
537 }
538
539 if (correct_rect_region(info_area)) {
540 update_main_screen();
541#if 0
542 SDL_UpdateRect(main_data.screen, info_area->x, info_area->y,
543 info_area->w, info_area->h);
544#endif /* 0 */
545 }
546}
547
548/**********************************************************************/
552 struct widget *get_widget_pointer_from_id(const struct widget *gui_list,
553 Uint16 id, enum scan_direction direction)
554{
555 if (direction == SCAN_FORWARD) {
556 while (gui_list) {
557 if (gui_list->id == id) {
558 return (struct widget *) gui_list;
559 }
560 gui_list = gui_list->next;
561 }
562 } else {
563 while (gui_list) {
564 if (gui_list->id == id) {
565 return (struct widget *) gui_list;
566 }
567 gui_list = gui_list->prev;
568 }
569 }
570
571 return NULL;
572}
573
574/**********************************************************************/
578 struct widget *get_widget_pointer_from_main_list(Uint16 id)
579{
580 return get_widget_pointer_from_id(begin_main_widget_list, id, SCAN_FORWARD);
581}
582
583/**********************************************************************/
586 void add_to_gui_list(Uint16 id, struct widget *gui)
587{
588 if (begin_main_widget_list != NULL) {
589 gui->next = begin_main_widget_list;
590 gui->id = id;
591 begin_main_widget_list->prev = gui;
592 begin_main_widget_list = gui;
593 } else {
594 begin_main_widget_list = gui;
595 begin_main_widget_list->id = id;
596 }
597}
598
599/**********************************************************************/
602 void widget_add_as_prev(struct widget *new_widget, struct widget *add_dock)
603{
604 new_widget->next = add_dock;
605 new_widget->prev = add_dock->prev;
606 if (add_dock->prev) {
607 add_dock->prev->next = new_widget;
608 }
609 add_dock->prev = new_widget;
610 if (add_dock == begin_main_widget_list) {
611 begin_main_widget_list = new_widget;
612 }
613}
614
615/**********************************************************************/
622 void del_widget_pointer_from_gui_list(struct widget *gui)
623{
624 if (!gui) {
625 return;
626 }
627
628 if (gui == begin_main_widget_list) {
629 begin_main_widget_list = begin_main_widget_list->next;
630 }
631
632 if (gui->prev && gui->next) {
633 gui->prev->next = gui->next;
634 gui->next->prev = gui->prev;
635 } else {
636 if (gui->prev) {
637 gui->prev->next = NULL;
638 }
639
640 if (gui->next) {
641 gui->next->prev = NULL;
642 }
643
644 }
645
646 if (selected_widget == gui) {
647 selected_widget = NULL;
648 }
649}
650
651/**********************************************************************/
657 bool is_this_widget_first_on_list(struct widget *gui)
658{
659 return (begin_main_widget_list == gui);
660}
661
662/**********************************************************************/
667 void move_widget_to_front_of_gui_list(struct widget *gui)
668{
669 if (!gui || gui == begin_main_widget_list) {
670 return;
671 }
672
673 /* gui->prev always exists because
674 we don't do this to begin_main_widget_list */
675 if (gui->next) {
676 gui->prev->next = gui->next;
677 gui->next->prev = gui->prev;
678 } else {
679 gui->prev->next = NULL;
680 }
681
682 gui->next = begin_main_widget_list;
683 begin_main_widget_list->prev = gui;
684 begin_main_widget_list = gui;
685 gui->prev = NULL;
686}
687
688/**********************************************************************/
691 void del_main_list(void)
692{
693 del_gui_list(begin_main_widget_list);
694}
695
696/**********************************************************************/
699 void del_gui_list(struct widget *gui_list)
700{
701 while (gui_list) {
702 if (gui_list->next) {
703 gui_list = gui_list->next;
704 FREEWIDGET(gui_list->prev);
705 } else {
706 FREEWIDGET(gui_list);
707 }
708 }
709}
710
711/* ===================================================================== */
712/* ================================ Universal ========================== */
713/* ===================================================================== */
714
715/**********************************************************************/
720 Uint16 redraw_group(const struct widget *begin_group_widget_list,
721 const struct widget *end_group_widget_list,
722 int add_to_update)
723{
724 Uint16 count = 0;
725 struct widget *tmp_widget = (struct widget *) end_group_widget_list;
726
727 while (tmp_widget) {
728
729 if (!(get_wflags(tmp_widget) & WF_HIDDEN)) {
730
731 widget_redraw(tmp_widget);
732
733 if (add_to_update) {
734 widget_mark_dirty(tmp_widget);
735 }
736
737 count++;
738 }
739
740 if (tmp_widget == begin_group_widget_list) {
741 break;
742 }
743
744 tmp_widget = tmp_widget->prev;
745
746 }
747
748 return count;
749}
750
751/**********************************************************************/
754 void undraw_group(struct widget *begin_group_widget_list,
755 struct widget *end_group_widget_list)
756{
757 struct widget *tmp_widget = end_group_widget_list;
758
759 while (tmp_widget) {
760 widget_undraw(tmp_widget);
761 widget_mark_dirty(tmp_widget);
762
763 if (tmp_widget == begin_group_widget_list) {
764 break;
765 }
766
767 tmp_widget = tmp_widget->prev;
768 }
769}
770
771/**********************************************************************/
774 void set_new_group_start_pos(const struct widget *begin_group_widget_list,
775 const struct widget *end_group_widget_list,
776 Sint16 Xrel, Sint16 Yrel)
777{
778 struct widget *tmp_widget = (struct widget *) end_group_widget_list;
779
780 while (tmp_widget) {
781
782 widget_set_position(tmp_widget, tmp_widget->size.x + Xrel,
783 tmp_widget->size.y + Yrel);
784
785 if (get_wtype(tmp_widget) == WT_VSCROLLBAR
786 && tmp_widget->private_data.adv_dlg
787 && tmp_widget->private_data.adv_dlg->scroll) {
788 tmp_widget->private_data.adv_dlg->scroll->max += Yrel;
789 tmp_widget->private_data.adv_dlg->scroll->min += Yrel;
790 }
791
792 if (get_wtype(tmp_widget) == WT_HSCROLLBAR
793 && tmp_widget->private_data.adv_dlg
794 && tmp_widget->private_data.adv_dlg->scroll) {
795 tmp_widget->private_data.adv_dlg->scroll->max += Xrel;
796 tmp_widget->private_data.adv_dlg->scroll->min += Xrel;
797 }
798
799 if (tmp_widget == begin_group_widget_list) {
800 break;
801 }
802
803 tmp_widget = tmp_widget->prev;
804 }
805}
806
807/**********************************************************************/
812 void move_group_to_front_of_gui_list(struct widget *begin_group_widget_list,
813 struct widget *end_group_widget_list)
814{
815 struct widget *tmp_widget = end_group_widget_list, *prev = NULL;
816 struct gui_layer *gui_layer = get_gui_layer(end_group_widget_list->dst->surface);
817
818 /* Widget Pointer Management */
819 while (tmp_widget) {
820
821 prev = tmp_widget->prev;
822
823 /* tmp_widget->prev always exists because we
824 don't do this to begin_main_widget_list */
825 if (tmp_widget->next) {
826 tmp_widget->prev->next = tmp_widget->next;
827 tmp_widget->next->prev = tmp_widget->prev;
828 } else {
829 tmp_widget->prev->next = NULL;
830 }
831
832 tmp_widget->next = begin_main_widget_list;
833 begin_main_widget_list->prev = tmp_widget;
834 begin_main_widget_list = tmp_widget;
835 begin_main_widget_list->prev = NULL;
836
837 if (tmp_widget == begin_group_widget_list) {
838 break;
839 }
840
841 tmp_widget = prev;
842 }
843
844 /* Window Buffer Management */
845 if (gui_layer) {
846 int i = 0;
847
848 while ((i < main_data.guis_count - 1) && main_data.guis[i]) {
849 if (main_data.guis[i] && main_data.guis[i + 1]
850 && (main_data.guis[i] == gui_layer)) {
851 main_data.guis[i] = main_data.guis[i + 1];
852 main_data.guis[i + 1] = gui_layer;
853 }
854 i++;
855 }
856 }
857}
858
859/**********************************************************************/
863 void del_group_of_widgets_from_gui_list(struct widget *begin_group_widget_list,
864 struct widget *end_group_widget_list)
865{
866 struct widget *tmp_widget = end_group_widget_list;
867
868 if (!end_group_widget_list) {
869 return;
870 }
871
872 if (begin_group_widget_list == end_group_widget_list) {
873 del_widget_from_gui_list(tmp_widget);
874 return;
875 }
876
877 tmp_widget = tmp_widget->prev;
878
879 while (tmp_widget) {
880 struct widget *buf_widget = NULL;
881
882 buf_widget = tmp_widget->next;
883 del_widget_from_gui_list(buf_widget);
884
885 if (tmp_widget == begin_group_widget_list) {
886 del_widget_from_gui_list(tmp_widget);
887 break;
888 }
889
890 tmp_widget = tmp_widget->prev;
891 }
892
893}
894
895/**********************************************************************/
898 void set_group_state(struct widget *begin_group_widget_list,
899 struct widget *end_group_widget_list, enum widget_state state)
900{
901 struct widget *tmp_widget = end_group_widget_list;
902
903 while (tmp_widget) {
904 set_wstate(tmp_widget, state);
905 if (tmp_widget == begin_group_widget_list) {
906 break;
907 }
908 tmp_widget = tmp_widget->prev;
909 }
910}
911
912/**********************************************************************/
915 void hide_group(struct widget *begin_group_widget_list,
916 struct widget *end_group_widget_list)
917{
918 struct widget *tmp_widget = end_group_widget_list;
919
920 while (tmp_widget) {
921 set_wflag(tmp_widget, WF_HIDDEN);
922
923 if (tmp_widget == begin_group_widget_list) {
924 break;
925 }
926
927 tmp_widget = tmp_widget->prev;
928 }
929}
930
931/**********************************************************************/
934 void show_group(struct widget *begin_group_widget_list,
935 struct widget *end_group_widget_list)
936{
937 struct widget *tmp_widget = end_group_widget_list;
938
939 while (tmp_widget) {
940 clear_wflag(tmp_widget, WF_HIDDEN);
941
942 if (tmp_widget == begin_group_widget_list) {
943 break;
944 }
945
946 tmp_widget = tmp_widget->prev;
947 }
948}
949
950/**********************************************************************/
953 void group_set_area(struct widget *begin_group_widget_list,
954 struct widget *end_group_widget_list,
955 SDL_Rect area)
956{
957 struct widget *pwidget = end_group_widget_list;
958
959 while (pwidget) {
960 widget_set_area(pwidget, area);
961
962 if (pwidget == begin_group_widget_list) {
963 break;
964 }
965
966 pwidget = pwidget->prev;
967 }
968}
969
970/* ===================================================================== *
971 * =========================== Window Group ============================ *
972 * ===================================================================== */
973
974/*
975 * Window Group - group with 'begin' and 'end' where
976 * windowed type widget is last on list ( 'end' ).
977 */
978
979/**********************************************************************/
983 void popdown_window_group_dialog(struct widget *begin_group_widget_list,
984 struct widget *end_group_widget_list)
985{
986 if ((begin_group_widget_list) && (end_group_widget_list)) {
987 widget_mark_dirty(end_group_widget_list);
988 remove_gui_layer(end_group_widget_list->dst);
989
990 del_group(begin_group_widget_list, end_group_widget_list);
991 }
992}
993
994/**********************************************************************/
998 bool select_window_group_dialog(struct widget *begin_widget_list,
999 struct widget *pwindow)
1000{
1001 if (!is_this_widget_first_on_list(begin_widget_list)) {
1002 move_group_to_front_of_gui_list(begin_widget_list, pwindow);
1003
1004 return TRUE;
1005 }
1006
1007 return FALSE;
1008}
1009
1010/**********************************************************************/
1016 bool move_window_group_dialog(struct widget *begin_group_widget_list,
1017 struct widget *end_group_widget_list)
1018{
1019 bool ret = FALSE;
1020 Sint16 old_x = end_group_widget_list->size.x, old_y = end_group_widget_list->size.y;
1021
1022 if (move_window(end_group_widget_list)) {
1023 set_new_group_start_pos(begin_group_widget_list,
1024 end_group_widget_list->prev,
1025 end_group_widget_list->size.x - old_x,
1026 end_group_widget_list->size.y - old_y);
1027 ret = TRUE;
1028 }
1029
1030 return ret;
1031}
1032
1033/**********************************************************************/
1039 void move_window_group(struct widget *begin_widget_list, struct widget *pwindow)
1040{
1041 if (select_window_group_dialog(begin_widget_list, pwindow)) {
1042 widget_flush(pwindow);
1043 }
1044
1045 move_window_group_dialog(begin_widget_list, pwindow);
1046}
1047
1048/**********************************************************************/
1051 int setup_vertical_widgets_position(int step,
1052 Sint16 start_x, Sint16 start_y,
1053 Uint16 w, Uint16 h,
1054 struct widget *begin, struct widget *end)
1055{
1056 struct widget *buf = end;
1057 register int count = 0;
1058 register int real_start_x = start_x;
1059 int ret = 0;
1060
1061 while (buf) {
1062 buf->size.x = real_start_x;
1063 buf->size.y = start_y;
1064
1065 if (w) {
1066 buf->size.w = w;
1067 }
1068
1069 if (h) {
1070 buf->size.h = h;
1071 }
1072
1073 if (((count + 1) % step) == 0) {
1074 real_start_x = start_x;
1075 start_y += buf->size.h;
1076 if (!(get_wflags(buf) & WF_HIDDEN)) {
1077 ret += buf->size.h;
1078 }
1079 } else {
1080 real_start_x += buf->size.w;
1081 }
1082
1083 if (buf == begin) {
1084 break;
1085 }
1086 count++;
1087 buf = buf->prev;
1088 }
1089
1090 return ret;
1091}
1092
1093/* =================================================== */
1094/* ======================= WINDOWs ==================== */
1095/* =================================================== */
1096
1097/**************************************************************************
1098 Window Manager Mechanism.
1099 Idea is simple each window/dialog has own buffer layer which is draw
1100 on screen during flush operations.
1101 This consume lots of memory but is extremly effecive.
1102
1103 Each widget has own "destination" parm == where ( on what buffer )
1104 will be draw.
1105**************************************************************************/
1106
1107/* =================================================== */
1108/* ======================== MISC ===================== */
1109/* =================================================== */
1110
1111/**********************************************************************/
1114 void draw_frame(SDL_Surface *pdest, Sint16 start_x, Sint16 start_y,
1115 Uint16 w, Uint16 h)
1116{
1117 SDL_Surface *tmp_left =
1118 resize_surface(current_theme->fr_left, current_theme->fr_left->w, h, 1);
1119 SDL_Surface *tmp_right =
1120 resize_surface(current_theme->fr_right, current_theme->fr_right->w, h, 1);
1121 SDL_Surface *tmp_top =
1122 resize_surface(current_theme->fr_top, w, current_theme->fr_top->h, 1);
1123 SDL_Surface *tmp_bottom =
1124 resize_surface(current_theme->fr_bottom, w, current_theme->fr_bottom->h, 1);
1125 SDL_Rect tmp,dst = {start_x, start_y, 0, 0};
1126
1127 tmp = dst;
1128 alphablit(tmp_left, NULL, pdest, &tmp, 255);
1129
1130 dst.x += w - tmp_right->w;
1131 tmp = dst;
1132 alphablit(tmp_right, NULL, pdest, &tmp, 255);
1133
1134 dst.x = start_x;
1135 tmp = dst;
1136 alphablit(tmp_top, NULL, pdest, &tmp, 255);
1137
1138 dst.y += h - tmp_bottom->h;
1139 tmp = dst;
1140 alphablit(tmp_bottom, NULL, pdest, &tmp, 255);
1141
1142 FREESURFACE(tmp_left);
1143 FREESURFACE(tmp_right);
1144 FREESURFACE(tmp_top);
1145 FREESURFACE(tmp_bottom);
1146}
1147
1148/**********************************************************************/
1151 void refresh_widget_background(struct widget *pwidget)
1152{
1153 if (pwidget) {
1154 if (pwidget->gfx && pwidget->gfx->w == pwidget->size.w
1155 && pwidget->gfx->h == pwidget->size.h) {
1156 clear_surface(pwidget->gfx, NULL);
1157 alphablit(pwidget->dst->surface, &pwidget->size, pwidget->gfx, NULL, 255);
1158 } else {
1159 FREESURFACE(pwidget->gfx);
1160 pwidget->gfx = crop_rect_from_surface(pwidget->dst->surface, &pwidget->size);
1161 }
1162 }
1163}
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
incite_cost
char * incite_cost
Definition comments.c:74
id
int int id
Definition editgui_g.h:28
current_theme
QString current_theme
Definition fc_client.cpp:64
flush_dirty
void flush_dirty(void)
Definition mapview.c:468
get_theme_color
SDL_Color * get_theme_color(enum theme_color themecolor)
Definition colors.c:47
resize_surface
SDL_Surface * resize_surface(const SDL_Surface *psrc, Uint16 new_width, Uint16 new_height, int smooth)
Definition graphics.c:1237
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
is_in_rect_area
bool is_in_rect_area(int x, int y, const SDL_Rect *rect)
Definition graphics.c:925
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:1350
FREESURFACE
#define FREESURFACE(ptr)
Definition graphics.h:322
adj_size
#define adj_size(size)
Definition gui_main.h:141
PRESSED_EVENT
#define PRESSED_EVENT(event)
Definition gui_main.h:71
create_text_surf_from_utf8
SDL_Surface * create_text_surf_from_utf8(utf8_str *pstr)
Definition gui_string.c:425
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
COLOR_THEME_QUICK_INFO_TEXT
@ COLOR_THEME_QUICK_INFO_TEXT
Definition themecolors.h:36
COLOR_THEME_QUICK_INFO_BG
@ COLOR_THEME_QUICK_INFO_BG
Definition themecolors.h:34
COLOR_THEME_QUICK_INFO_FRAME
@ COLOR_THEME_QUICK_INFO_FRAME
Definition themecolors.h:35
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:252
del_widget_pointer_from_gui_list
void del_widget_pointer_from_gui_list(struct widget *gui)
Definition widget.c:622
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:774
redraw_widget_info_label
void redraw_widget_info_label(SDL_Rect *rect)
Definition widget.c:467
widget_pressed_action
Uint16 widget_pressed_action(struct widget *pwidget)
Definition widget.c:296
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:898
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:812
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:586
widget_selected_action
void widget_selected_action(struct widget *pwidget)
Definition widget.c:443
get_widget_pointer_from_main_list
struct widget * get_widget_pointer_from_main_list(Uint16 id)
Definition widget.c:578
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:863
move_window_group_dialog
bool move_window_group_dialog(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:1016
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:1151
del_gui_list
void del_gui_list(struct widget *gui_list)
Definition widget.c:699
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:1114
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:934
unselect_widget_action
void unselect_widget_action(void)
Definition widget.c:418
hide_group
void hide_group(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:915
is_this_widget_first_on_list
bool is_this_widget_first_on_list(struct widget *gui)
Definition widget.c:657
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:552
widget_add_as_prev
void widget_add_as_prev(struct widget *new_widget, struct widget *add_dock)
Definition widget.c:602
undraw_group
void undraw_group(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:754
del_main_list
void del_main_list(void)
Definition widget.c:691
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:998
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:953
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:1051
move_widget_to_front_of_gui_list
void move_widget_to_front_of_gui_list(struct widget *gui)
Definition widget.c:667
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:720
popdown_window_group_dialog
void popdown_window_group_dialog(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:983
move_window_group
void move_window_group(struct widget *begin_widget_list, struct widget *pwindow)
Definition widget.c:1039
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
move_window
bool move_window(struct widget *pwindow)
Definition widget_window.c:352
gui_id.h
gui_tilespec.h
themespec.h
widget.h
widget_p.h
colors.h
graphics.h
gui_main.h
mapview.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
y
struct sprite int int y
Definition sprite_g.h:31
x
struct sprite int x
Definition sprite_g.h:31
color
Definition colors.h:21
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::unselect
void(* unselect)(struct widget *pwidget)
Definition widget.h:168
widget::key
SDL_Keycode key
Definition widget.h:153
widget::prev
struct widget * prev
Definition widget.h:114
widget::dst
struct gui_layer * dst
Definition widget.h:116
widget::mod
Uint16 mod
Definition widget.h:154
widget::action
int(* action)(struct widget *)
Definition widget.h:157
widget::area
SDL_Rect area
Definition widget.h:149
widget::gfx
SDL_Surface * gfx
Definition widget.h:120
widget::next
struct widget * next
Definition widget.h:113
widget::info_label
utf8_str * info_label
Definition widget.h:122
widget::select
void(* select)(struct widget *pwidget)
Definition widget.h:167
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