Freeciv-3.3
Loading...
Searching...
No Matches
widget_window.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
24/* gui-sdl3 */
25#include "colors.h"
26#include "graphics.h"
27#include "gui_id.h"
28#include "gui_tilespec.h"
29#include "mapview.h"
30#include "themespec.h"
31
32#include "widget.h"
33#include "widget_p.h"
34
35struct move {
36 bool moved;
37 struct widget *pwindow;
38 float prev_x;
39 float prev_y;
40};
41
42static int (*baseclass_redraw)(struct widget *pwidget);
43
44/**********************************************************************/
47static int redraw_window(struct widget *pwindow)
48{
49 int ret;
50 SDL_Color title_bg_color = {255, 255, 255, 200};
52 SDL_Rect dst = pwindow->size;
53
54 ret = (*baseclass_redraw)(pwindow);
55 if (ret != 0) {
56 return ret;
57 }
58
59 /* Draw theme */
60 clear_surface(pwindow->dst->surface, &dst);
61 alphablit(pwindow->theme, NULL, pwindow->dst->surface, &dst, 255);
62
63 /* window has title string == has title bar */
64 if (pwindow->string_utf8 != NULL) {
65
66 /* Draw Window's TitleBar */
67 dst = pwindow->area;
68 dst.y -= (WINDOW_TITLE_HEIGHT + 1);
71
72 /* Draw Text on Window's TitleBar */
74 dst.x += adj_size(4);
75 if (tmp) {
76 dst.y += ((WINDOW_TITLE_HEIGHT - tmp->h) / 2);
77 alphablit(tmp, NULL, pwindow->dst->surface, &dst, 255);
79 }
80
81 dst = pwindow->area;
82
83 create_line(pwindow->dst->surface,
84 dst.x, dst.y - 1,
85 dst.x + dst.w - 1, dst.y - 1,
87 }
88
89 /* Draw frame */
91 widget_draw_frame(pwindow);
92 }
93
94 return 0;
95}
96
97/**************************************************************************
98 Window mechanism.
99
100 Active Window schould be first on list (All Widgets on this
101 Window that are on List must be above)
102
103 LIST:
104
105 *pFirst_Widget_on_Active_Window.
106
107 *pN__Widget_on_Active_Window.
108 *pActive_Window. <------
109 *pRest_Widgets.
110
111 This trick give us:
112 - if any Widget is under ( area of ) this Window and Mouse
113 cursor is above them, 'WidgetListScaner(...)' return
114 pointer to Active Window not to this Widget.
115**************************************************************************/
116
117/**********************************************************************/
120static void window_set_position(struct widget *pwindow, int x, int y)
121{
122 struct gui_layer *gui_layer;
123
124 pwindow->size.x = 0;
125 pwindow->size.y = 0;
126
127 gui_layer = get_gui_layer(pwindow->dst->surface);
128 gui_layer->dest_rect.x = x;
129 gui_layer->dest_rect.y = y;
130}
131
132/**********************************************************************/
135static void window_select(struct widget *pwindow)
136{
137 /* Nothing */
138}
139
140/**********************************************************************/
143static void window_unselect(struct widget *pwindow)
144{
145 /* Nothing */
146}
147
148/**********************************************************************/
151static void set_client_area(struct widget *pwindow)
152{
153 SDL_Rect area;
154
156 area.x = current_theme->fr_left->w;
157 area.y = current_theme->fr_top->h;
158 area.w = pwindow->size.w - current_theme->fr_left->w - current_theme->fr_right->w;
159 area.h = pwindow->size.h - current_theme->fr_top->h - current_theme->fr_bottom->h;
160 } else {
161 area = pwindow->size;
162 }
163
164 if (pwindow->string_utf8 != NULL) {
165 area.y += (WINDOW_TITLE_HEIGHT + 1);
166 area.h -= (WINDOW_TITLE_HEIGHT + 1);
167 }
168
169 widget_set_area(pwindow, area);
170}
171
172/**********************************************************************/
177 utf8_str *title, Uint32 flags)
178{
179 int w = 0, h = 0;
180 struct widget *pwindow = widget_new();
181
183
184 baseclass_redraw = pwindow->redraw;
185 pwindow->redraw = redraw_window;
186 pwindow->select = window_select;
187 pwindow->unselect = window_unselect;
188
189 pwindow->string_utf8 = title;
192 set_wstate(pwindow, FC_WS_DISABLED);
193 set_wtype(pwindow, WT_WINDOW);
194 pwindow->mod = SDL_KMOD_NONE;
195
197 w += current_theme->fr_left->w + current_theme->fr_right->w;
198 h += current_theme->fr_top->h + current_theme->fr_bottom->h;
199 }
200
201 if (title != NULL) {
203
205
206 w += size.w + adj_size(10);
207 h += MAX(size.h, WINDOW_TITLE_HEIGHT + 1);
208 }
209
210 pwindow->size.w = w;
211 pwindow->size.h = h;
212
213 set_client_area(pwindow);
214
215 if (pdest != NULL) {
216 pwindow->dst = pdest;
217 } else {
218 pwindow->dst = add_gui_layer(w, h);
219 }
220
221 return pwindow;
222}
223
224/**********************************************************************/
228 Uint16 w, Uint16 h, Uint32 flags)
229{
230 struct widget *pwindow = create_window_skeleton(pdest, title, flags);
231
232 resize_window(pwindow, NULL, NULL, w, h);
233
234 return pwindow;
235}
236
237/**********************************************************************/
251bool resize_window(struct widget *pwindow, SDL_Surface *bcgd,
253{
255
256 /* Window */
257 if ((new_w != pwindow->size.w) || (new_h != pwindow->size.h)) {
258 pwindow->size.w = new_w;
259 pwindow->size.h = new_h;
260
261 set_client_area(pwindow);
262
263 if (get_wflags(pwindow) & WF_RESTORE_BACKGROUND) {
265 }
266
267 FREESURFACE(pwindow->dst->surface);
268 pwindow->dst->surface = create_surf(pwindow->size.w,
269 pwindow->size.h);
270 }
271
272 if (bcgd != pwindow->theme) {
273 FREESURFACE(pwindow->theme);
274 }
275
276 if (bcgd) {
277 if (bcgd->w != new_w || bcgd->h != new_h) {
278 pwindow->theme = resize_surface(bcgd, new_w, new_h, 2);
279 return 1;
280 } else {
281 pwindow->theme = bcgd;
282 return FALSE;
283 }
284 } else {
285 pwindow->theme = create_surf(new_w, new_h);
286
287 if (pcolor == NULL) {
289
290 pcolor = &color;
291 }
292
294 map_rgba(pwindow->theme->format, *pcolor));
295
296 return TRUE;
297 }
298}
299
300/**********************************************************************/
304 void *data)
305{
306 struct move *pmove = (struct move *)data;
307 int xrel, yrel;
308
309 if (!pmove->moved) {
310 pmove->moved = TRUE;
311 }
312
313 widget_mark_dirty(pmove->pwindow);
314
315 xrel = motion_event->x - pmove->prev_x;
316 yrel = motion_event->y - pmove->prev_y;
317 pmove->prev_x = motion_event->x;
318 pmove->prev_y = motion_event->y;
319
320 widget_set_position(pmove->pwindow,
321 (pmove->pwindow->dst->dest_rect.x + pmove->pwindow->size.x) + xrel,
322 (pmove->pwindow->dst->dest_rect.y + pmove->pwindow->size.y) + yrel);
323
324 widget_mark_dirty(pmove->pwindow);
325 flush_dirty();
326
327 return ID_ERROR;
328}
329
330/**********************************************************************/
334 void *data)
335{
336 struct move *pmove = (struct move *)data;
337
338 if (pmove && pmove->moved) {
339 return (Uint16)ID_MOVED_WINDOW;
340 }
341
342 return (Uint16)ID_WINDOW;
343}
344
345/**********************************************************************/
349{
350 bool ret;
351 struct move pmove;
352
354 pmove.moved = FALSE;
355 SDL_GetMouseState(&pmove.prev_x, &pmove.prev_y);
356 /* Filter mouse motion events */
358 ret = (gui_event_loop((void *)&pmove, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
360 /* Turn off Filter mouse motion events */
362
363 return ret;
364}
struct canvas int int int int struct sprite *sprite struct canvas struct color * pcolor
Definition canvas_g.h:56
char * incite_cost
Definition comments.c:76
QString current_theme
Definition fc_client.cpp:64
void flush_dirty(void)
Definition mapview.c:468
const char * title
Definition repodlgs.c:1314
SDL_Color * get_theme_color(enum theme_color themecolor)
Definition colors.c:47
SDL_Surface * resize_surface(const SDL_Surface *psrc, Uint16 new_width, Uint16 new_height, int smooth)
Definition graphics.c:1237
int fill_rect_alpha(SDL_Surface *surf, SDL_Rect *prect, SDL_Color *pcolor)
Definition graphics.c:865
void create_line(SDL_Surface *dest, Sint16 x0, Sint16 y0, Sint16 x1, Sint16 y1, SDL_Color *pcolor)
Definition graphics.c:1381
int alphablit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:199
struct gui_layer * get_gui_layer(SDL_Surface *surface)
Definition graphics.c:90
SDL_Surface * create_surf(int width, int height, Uint32 flags)
Definition graphics.c:351
struct gui_layer * add_gui_layer(int width, int height)
Definition graphics.c:112
int clear_surface(SDL_Surface *surf, SDL_Rect *dstrect)
Definition graphics.c:400
#define FREESURFACE(ptr)
Definition graphics.h:322
#define map_rgba(format, color)
Definition graphics.h:315
@ ID_MOVED_WINDOW
Definition gui_id.h:31
@ ID_ERROR
Definition gui_id.h:26
@ ID_WINDOW
Definition gui_id.h:30
int FilterMouseMotionEvents(void *data, SDL_Event *event)
Definition gui_main.c:582
Uint16 gui_event_loop(void *data, void(*loop_action)(void *data), Uint16(*key_down_handler)(SDL_Keysym key, void *data), Uint16(*key_up_handler)(SDL_Keysym key, void *data), Uint16(*textinput_handler)(const char *text, void *data), Uint16(*finger_down_handler)(SDL_TouchFingerEvent *touch_event, void *data), Uint16(*finger_up_handler)(SDL_TouchFingerEvent *touch_event, void *data), Uint16(*finger_motion_handler)(SDL_TouchFingerEvent *touch_event, void *data), Uint16(*mouse_button_down_handler)(SDL_MouseButtonEvent *button_event, void *data), Uint16(*mouse_button_up_handler)(SDL_MouseButtonEvent *button_event, void *data), Uint16(*mouse_motion_handler)(SDL_MouseMotionEvent *motion_event, void *data))
Definition gui_main.c:603
#define adj_size(size)
Definition gui_main.h:141
void utf8_str_size(utf8_str *pstr, SDL_Rect *fill)
Definition gui_string.c:106
SDL_Surface * create_text_surf_from_utf8(utf8_str *pstr)
Definition gui_string.c:425
@ COLOR_THEME_BACKGROUND
Definition themecolors.h:24
@ COLOR_THEME_WINDOW_TITLEBAR_SEPARATOR
Definition themecolors.h:44
void refresh_widget_background(struct widget *pwidget)
Definition widget.c:1151
static void widget_set_position(struct widget *pwidget, int x, int y)
Definition widget.h:266
#define WINDOW_TITLE_HEIGHT
Definition widget.h:35
@ FC_WS_DISABLED
Definition widget.h:99
static void widget_draw_frame(struct widget *pwidget)
Definition widget.h:281
static void widget_mark_dirty(struct widget *pwidget)
Definition widget.h:286
enum widget_flag get_wflags(const struct widget *pwidget)
Definition widget_core.c:86
void set_wstate(struct widget *pwidget, enum widget_state state)
Definition widget_core.c:36
@ WF_FREE_GFX
Definition widget.h:70
@ WF_DRAW_FRAME_AROUND_WIDGET
Definition widget.h:86
@ WF_FREE_STRING
Definition widget.h:76
@ WF_RESTORE_BACKGROUND
Definition widget.h:85
@ WF_FREE_THEME
Definition widget.h:72
void set_wtype(struct widget *pwidget, enum widget_type type)
Definition widget_core.c:45
static void widget_set_area(struct widget *pwidget, SDL_Rect area)
Definition widget.h:261
void set_wflag(struct widget *pwidget, enum widget_flag flag)
Definition widget_core.c:54
@ WT_WINDOW
Definition widget.h:52
struct widget * widget_new(void)
bool resize_window(struct widget *pwindow, SDL_Surface *bcgd, SDL_Color *pcolor, Uint16 new_w, Uint16 new_h)
static Uint16 move_window_motion(SDL_MouseMotionEvent *motion_event, void *data)
static void window_select(struct widget *pwindow)
static int(* baseclass_redraw)(struct widget *pwidget)
struct widget * create_window_skeleton(struct gui_layer *pdest, utf8_str *title, Uint32 flags)
static void window_set_position(struct widget *pwindow, int x, int y)
static int redraw_window(struct widget *pwindow)
static void window_unselect(struct widget *pwindow)
static void set_client_area(struct widget *pwindow)
static Uint16 move_window_button_up(SDL_MouseButtonEvent *button_event, void *data)
bool move_window(struct widget *pwindow)
struct widget * create_window(struct gui_layer *pdest, utf8_str *title, Uint16 w, Uint16 h, Uint32 flags)
#define MAX(x, y)
Definition shared.h:54
size_t size
Definition specvec.h:72
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
Definition colors.h:21
SDL_Surface * surface
Definition graphics.h:229
SDL_Rect dest_rect
Definition graphics.h:228
struct widget * pwindow
bool moved
float prev_x
float prev_y
void(* unselect)(struct widget *pwidget)
Definition widget.h:168
void(* set_position)(struct widget *pwidget, int x, int y)
Definition widget.h:160
SDL_Surface * theme
Definition widget.h:118
union widget::@223 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
SDL_Rect area
Definition widget.h:149
void(* select)(struct widget *pwidget)
Definition widget.h:167
SDL_Rect size
Definition widget.h:145
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47