Freeciv-3.3
Loading...
Searching...
No Matches
widget_combo.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2006 - The Freeciv Project
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#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* SDL3 */
19#include <SDL3/SDL.h>
20
21/* utility */
22#include "log.h"
23#include "string_vector.h"
24
25/* client/gui-sdl3 */
26#include "colors.h"
27#include "gui_id.h"
28#include "gui_string.h"
29#include "gui_tilespec.h"
30#include "mapview.h"
31#include "widget.h"
32#include "widget_p.h"
33
34struct combo_menu {
36 struct widget *end_widget_list;
37};
38
39static int (*baseclass_redraw) (struct widget *widget) = NULL;
40
41
42/************************************************************************/
45static int combo_redraw(struct widget *combo)
46{
47 SDL_Rect dest = { combo->size.x, combo->size.y, 0, 0 };
48 SDL_Surface *text, *surface;
49 struct combo_menu *menu;
50 int ret;
51
52 ret = baseclass_redraw(combo);
53 if (0 != ret) {
54 return ret;
55 }
56
57 surface = create_bcgnd_surf(combo->theme, get_wstate(combo),
58 combo->size.w, combo->size.h);
59
60 if (NULL == surface) {
61 return -1;
62 }
63
64 /* Blit theme. */
65 alphablit(surface, NULL, combo->dst->surface, &dest, 255);
66
67 /* Set position and blit text. */
69 if (NULL != text) {
70 dest.y += (surface->h - surface->h) / 2;
71 /* Blit centred text to botton. */
72 if (combo->string_utf8->style & SF_CENTER) {
73 dest.x += (surface->w - text->w) / 2;
74 } else {
75 if (combo->string_utf8->style & SF_CENTER_RIGHT) {
76 dest.x += surface->w - text->w - adj_size(5);
77 } else {
78 dest.x += adj_size(5); /* center left */
79 }
80 }
81
82 alphablit(text, NULL, combo->dst->surface, &dest, 255);
83 }
84 /* text. */
85 ret = surface->h;
86
87 /* Free memory */
88 FREESURFACE(text);
89 FREESURFACE(surface);
90
91 menu = (struct combo_menu *) combo->private_data.ptr;
92 if (NULL != menu) {
94 }
95
96 return ret;
97}
98
99/************************************************************************/
102static int combo_menu_callback(struct widget *window)
103{
105 struct combo_menu *menu =
106 (struct combo_menu *)window->data.widget->private_data.ptr;
107
109 }
110
111 return -1;
112}
113
114/************************************************************************/
117static int combo_menu_item_callback(struct widget *label)
118{
119 struct widget *combo = label->data.widget;
120
123 widget_redraw(combo);
124 widget_mark_dirty(combo);
125 }
126 combo_popdown(combo);
127
128 return -1;
129}
130
131/************************************************************************/
134void combo_popup(struct widget *combo)
135{
136 struct combo_menu *menu;
137 struct widget *window, *label = NULL;
138 int longest = 0, h = 0, x, y;
139
140 fc_assert_ret(NULL != combo);
142
143 if (NULL != combo->private_data.ptr) {
144 return;
145 }
146
147 if (0 >= strvec_size(combo->data.vector)) {
148 return;
149 }
150
151 /* Menu. */
152 window = create_window_skeleton(NULL, NULL, 0);
153 window->action = combo_menu_callback;
154 window->data.widget = combo;
155 set_wstate(window, FC_WS_NORMAL);
157
158 /* Labels. */
159 strvec_iterate(combo->data.vector, string) {
160 label = create_iconlabel_from_chars(NULL, window->dst, string, 0,
163 label->data.widget = combo;
164 set_wstate(label, FC_WS_NORMAL);
166
167 longest = MAX(longest, label->size.w);
168 widget_set_position(label, adj_size(10), h);
169 h += adj_size(15);
171
172 /* Resize and relocate the window. */
173 resize_window(window, NULL, NULL, longest + 2 * adj_size(10), h);
174
175 x = combo->size.x + combo->dst->dest_rect.x;
176 if (x + window->size.w > main_window_width()) {
177 x = main_window_width() - window->size.w;
178 }
179 if (x < 0) {
180 x = 0;
181 }
182
183 y = combo->size.y - h + combo->dst->dest_rect.y;
184 if (y + window->size.h > main_window_height()) {
185 y = main_window_height() - window->size.h;
186 }
187 if (y < 0) {
188 y = 0;
189 }
190
191 widget_set_position(window, x, y);
192
193 /* Make data. */
194 menu = fc_malloc(sizeof(*menu));
195 menu->begin_widget_list = label;
196 menu->end_widget_list = window;
197 combo->private_data.ptr = menu;
198
199 /* Redraw. */
201 widget_mark_dirty(window);
202 flush_dirty();
203}
204
205/************************************************************************/
208void combo_popdown(struct widget *combo)
209{
210 struct combo_menu *menu;
211
212 fc_assert_ret(NULL != combo);
214
215 menu = (struct combo_menu *) combo->private_data.ptr;
216 if (NULL == menu) {
217 return;
218 }
219
222 menu->end_widget_list);
223 free(menu);
224 combo->private_data.ptr = NULL;
225 flush_dirty();
226}
227
228/************************************************************************/
231struct widget *combo_new(SDL_Surface *background, struct gui_layer *dest,
232 utf8_str *pstr, const struct strvec *vector,
233 int length, Uint32 flags)
234{
235 SDL_Rect buf = {0, 0, 0, 0};
236 struct widget *combo = widget_new();
237
238 combo->theme = current_theme->edit;
239 combo->theme2 = background;
240 combo->string_utf8 = pstr;
241 set_wflag(combo, WF_FREE_STRING | WF_FREE_GFX | flags);
243 set_wtype(combo, WT_COMBO);
244 combo->mod = SDL_KMOD_NONE;
245
246 baseclass_redraw = combo->redraw;
247 combo->redraw = combo_redraw;
248 combo->destroy = combo_popdown;
249
250 if (pstr != NULL) {
251 combo->string_utf8->style |= SF_CENTER;
253 buf.h += adj_size(4);
254 }
255
256 length = MAX(length, buf.w + adj_size(10));
257 correct_size_bcgnd_surf(current_theme->edit, &length, &buf.h);
258 combo->size.w = buf.w + adj_size(10);
259 combo->size.h = buf.h;
260
261 if (dest != NULL) {
262 combo->dst = dest;
263 } else {
264 combo->dst = add_gui_layer(combo->size.w, combo->size.h);
265 }
266 combo->data.vector = vector;
267 combo->private_data.ptr = NULL;
268
269 return combo;
270}
char * incite_cost
Definition comments.c:76
QString current_theme
Definition fc_client.cpp:64
void flush_dirty(void)
Definition mapview.c:468
int main_window_width(void)
Definition graphics.c:685
int alphablit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:199
struct sdl2_data main_data
Definition graphics.c:57
struct gui_layer * add_gui_layer(int width, int height)
Definition graphics.c:112
int main_window_height(void)
Definition graphics.c:693
#define FREESURFACE(ptr)
Definition graphics.h:322
@ ID_LABEL
Definition gui_id.h:27
@ ID_COMBO_MENU
Definition gui_id.h:37
#define adj_size(size)
Definition gui_main.h:141
#define PRESSED_EVENT(event)
Definition gui_main.h:71
void utf8_str_size(utf8_str *pstr, SDL_Rect *fill)
Definition gui_string.c:106
utf8_str * copy_chars_to_utf8_str(utf8_str *pstr, const char *pchars)
Definition gui_string.c:251
SDL_Surface * create_text_surf_from_utf8(utf8_str *pstr)
Definition gui_string.c:425
#define SF_CENTER
Definition gui_string.h:40
#define SF_CENTER_RIGHT
Definition gui_string.h:41
void correct_size_bcgnd_surf(SDL_Surface *ptheme, int *width, int *height)
Definition widget.c:63
void add_to_gui_list(Uint16 id, struct widget *gui)
Definition widget.c:586
SDL_Surface * create_bcgnd_surf(SDL_Surface *ptheme, enum widget_state state, Uint16 width, Uint16 height)
Definition widget.c:78
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
void popdown_window_group_dialog(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:983
void move_window_group(struct widget *begin_widget_list, struct widget *pwindow)
Definition widget.c:1039
static void widget_set_position(struct widget *pwidget, int x, int y)
Definition widget.h:266
@ FC_WS_DISABLED
Definition widget.h:99
@ FC_WS_NORMAL
Definition widget.h:96
static void widget_mark_dirty(struct widget *pwidget)
Definition widget.h:286
void set_wstate(struct widget *pwidget, enum widget_state state)
Definition widget_core.c:36
enum widget_state get_wstate(const struct widget *pwidget)
Definition widget_core.c:70
@ WF_FREE_GFX
Definition widget.h:70
@ WF_FREE_STRING
Definition widget.h:76
@ WF_RESTORE_BACKGROUND
Definition widget.h:85
static int widget_redraw(struct widget *pwidget)
Definition widget.h:276
void set_wtype(struct widget *pwidget, enum widget_type type)
Definition widget_core.c:45
enum widget_type get_wtype(const struct widget *pwidget)
Definition widget_core.c:78
void set_wflag(struct widget *pwidget, enum widget_flag flag)
Definition widget_core.c:54
@ WT_COMBO
Definition widget.h:62
static int combo_menu_item_callback(struct widget *label)
void combo_popup(struct widget *combo)
static int(* baseclass_redraw)(struct widget *widget)
struct widget * combo_new(SDL_Surface *background, struct gui_layer *dest, utf8_str *pstr, const struct strvec *vector, int length, Uint32 flags)
void combo_popdown(struct widget *combo)
static int combo_menu_callback(struct widget *window)
static int combo_redraw(struct widget *combo)
struct widget * widget_new(void)
#define create_iconlabel_from_chars(picon, pdest, chars, ptsize, flags)
bool resize_window(struct widget *pwindow, SDL_Surface *bcgd, SDL_Color *pcolor, Uint16 new_w, Uint16 new_h)
struct widget * create_window_skeleton(struct gui_layer *pdest, utf8_str *title, Uint32 flags)
#define fc_assert_ret(condition)
Definition log.h:192
#define fc_malloc(sz)
Definition mem.h:34
#define MAX(x, y)
Definition shared.h:54
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
size_t strvec_size(const struct strvec *psv)
#define strvec_iterate(psv, str)
#define strvec_iterate_end
struct widget * end_widget_list
struct widget * begin_widget_list
SDL_Surface * surface
Definition graphics.h:229
SDL_Rect dest_rect
Definition graphics.h:228
SDL_Event event
Definition graphics.h:217
Uint8 style
Definition gui_string.h:53
char * text
Definition gui_string.h:60
void * ptr
Definition widget.h:133
SDL_Surface * theme
Definition widget.h:118
struct widget * widget
Definition widget.h:132
union widget::@223 data
SDL_Surface * theme2
Definition widget.h:119
union widget::@224 private_data
int(* redraw)(struct widget *pwidget)
Definition widget.h:163
struct gui_layer * dst
Definition widget.h:116
Uint16 mod
Definition widget.h:154
utf8_str * string_utf8
Definition widget.h:121
const struct strvec * vector
Definition widget.h:126
int(* action)(struct widget *)
Definition widget.h:157
void(* destroy)(struct widget *pwidget)
Definition widget.h:170
SDL_Rect size
Definition widget.h:145