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)
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
***********************************************************************/
27
#include "gui_tilespec.h"
29
#include "themespec.h"
36
struct widget *pWindow;
41
static int (*baseclass_redraw)(struct widget *pwidget);
43
/**************************************************************************
44
Redraw Window Graphic ( without other Widgets )
45
**************************************************************************/
46
static int redraw_window(struct widget *pWindow)
49
SDL_Color title_bg_color = {255, 255, 255, 200};
51
SDL_Surface *pTmp = NULL;
52
SDL_Rect dst = pWindow->size;
54
ret = (*baseclass_redraw)(pWindow);
60
clear_surface(pWindow->dst->surface, &dst);
61
alphablit(pWindow->theme, NULL, pWindow->dst->surface, &dst);
63
/* window has title string == has title bar */
64
if (pWindow->string16) {
66
/* Draw Window's TitelBar */
68
dst.y -= (WINDOW_TITLE_HEIGHT + 1);
69
dst.h = WINDOW_TITLE_HEIGHT;
70
SDL_FillRectAlpha(pWindow->dst->surface, &dst, &title_bg_color);
72
/* Draw Text on Window's TitelBar */
73
pTmp = create_text_surf_from_str16(pWindow->string16);
76
dst.y += ((WINDOW_TITLE_HEIGHT - pTmp->h) / 2);
77
alphablit(pTmp, NULL, pWindow->dst->surface, &dst);
83
putline(pWindow->dst->surface,
85
dst.x + dst.w - 1, dst.y - 1,
86
map_rgba(pWindow->dst->surface->format,
87
*get_game_colorRGB(COLOR_THEME_WINDOW_TITLEBAR_SEPARATOR)));
91
if (get_wflags(pWindow) & WF_DRAW_FRAME_AROUND_WIDGET) {
92
widget_draw_frame(pWindow);
98
/**************************************************************************
101
Active Window schould be first on list (All Widgets on this
102
Widndow that are on List must be above)
106
*pFirst_Widget_on_Active_Window.
108
*pN__Widget_on_Active_Window.
109
*pActive_Window. <------
113
- if any Widget is under ( area of ) this Window and Mouse
114
cursor is above them, 'WidgetListScaner(...)' return
115
pointer to Active Window not to this Widget.
116
**************************************************************************/
118
/**************************************************************************
120
**************************************************************************/
121
static void window_set_position(struct widget *pWindow, int x, int y)
123
struct gui_layer *gui_layer;
128
gui_layer = get_gui_layer(pWindow->dst->surface);
129
gui_layer->dest_rect.x = x;
130
gui_layer->dest_rect.y = y;
133
/**************************************************************************
135
**************************************************************************/
136
static void window_select(struct widget *pWindow)
141
/**************************************************************************
143
**************************************************************************/
144
static void window_unselect(struct widget *pWindow)
149
/**************************************************************************
151
**************************************************************************/
152
static void set_client_area(struct widget *pWindow)
156
if (get_wflags(pWindow) & WF_DRAW_FRAME_AROUND_WIDGET) {
157
area.x = pTheme->FR_Left->w;
158
area.y = pTheme->FR_Top->h;
159
area.w = pWindow->size.w - pTheme->FR_Left->w - pTheme->FR_Right->w;
160
area.h = pWindow->size.h - pTheme->FR_Top->h - pTheme->FR_Bottom->h;
162
area = pWindow->size;
165
if (pWindow->string16) {
166
area.y += (WINDOW_TITLE_HEIGHT + 1);
167
area.h -= (WINDOW_TITLE_HEIGHT + 1);
170
widget_set_area(pWindow, area);
173
/**************************************************************************
174
Allocate Widow Widget Structute.
175
Text to titelbar is taken from 'pTitle'.
176
**************************************************************************/
177
struct widget *create_window_skeleton(struct gui_layer *pDest,
178
SDL_String16 *pTitle, Uint32 flags)
181
struct widget *pWindow = widget_new();
183
pWindow->set_position = window_set_position;
185
baseclass_redraw = pWindow->redraw;
186
pWindow->redraw = redraw_window;
187
pWindow->select = window_select;
188
pWindow->unselect = window_unselect;
190
pWindow->string16 = pTitle;
191
set_wflag(pWindow, WF_FREE_STRING | WF_FREE_GFX | WF_FREE_THEME |
192
WF_DRAW_FRAME_AROUND_WIDGET| flags);
193
set_wstate(pWindow, FC_WS_DISABLED);
194
set_wtype(pWindow, WT_WINDOW);
195
pWindow->mod = KMOD_NONE;
197
if (get_wflags(pWindow) & WF_DRAW_FRAME_AROUND_WIDGET) {
198
w += pTheme->FR_Left->w + pTheme->FR_Right->w;
199
h += pTheme->FR_Top->h + pTheme->FR_Bottom->h;
203
SDL_Rect size = str16size(pTitle);
204
w += size.w + adj_size(10);
205
h += MAX(size.h, WINDOW_TITLE_HEIGHT + 1);
211
set_client_area(pWindow);
214
pWindow->dst = pDest;
216
pWindow->dst = add_gui_layer(w, h);
222
struct widget * create_window(struct gui_layer *pDest, SDL_String16 *pTitle,
223
Uint16 w, Uint16 h, Uint32 flags)
225
struct widget *pWindow = create_window_skeleton(pDest, pTitle, flags);
227
resize_window(pWindow, NULL, NULL, w, h);
232
/**************************************************************************
233
Resize Window 'pWindow' to 'new_w' and 'new_h'.
234
and refresh window background ( save screen under window ).
236
If pBcgd == NULL then theme is set to
237
white transparent ( ALPHA = 128 ).
239
Return 1 if allocate new surface and 0 if used 'pBcgd' surface.
242
if ( resize_window( pWindow , pBcgd , new_w , new_h ) ) {
243
FREESURFACE( pBcgd );
245
**************************************************************************/
246
int resize_window(struct widget *pWindow,
248
SDL_Color * pColor, Uint16 new_w, Uint16 new_h)
250
struct gui_layer *gui_layer;
251
struct widget *pWidget;
255
if ((new_w != pWindow->size.w) || (new_h != pWindow->size.h)) {
256
pWindow->size.w = new_w;
257
pWindow->size.h = new_h;
259
set_client_area(pWindow);
261
if (get_wflags(pWindow) & WF_RESTORE_BACKGROUND) {
262
refresh_widget_background(pWindow);
265
gui_layer = get_gui_layer(pWindow->dst->surface);
266
FREESURFACE(gui_layer->surface);
267
gui_layer->surface = create_surf_alpha(/*Main.screen->w*/pWindow->size.w,
268
/*Main.screen->h*/pWindow->size.h,
270
/* assign new buffer to all widgets on this window */
273
pWidget->dst->surface = gui_layer->surface;
274
pWidget = pWidget->prev;
278
if (pBcgd != pWindow->theme) {
279
FREESURFACE(pWindow->theme);
283
if (pBcgd->w != new_w || pBcgd->h != new_h) {
284
pWindow->theme = ResizeSurface(pBcgd, new_w, new_h, 2);
287
pWindow->theme = pBcgd;
291
pWindow->theme = create_surf_alpha(new_w, new_h, SDL_SWSURFACE);
294
SDL_Color color = *get_game_colorRGB(COLOR_THEME_BACKGROUND);
298
SDL_FillRect(pWindow->theme, NULL, map_rgba(pWindow->theme->format, *pColor));
304
/**************************************************************************
306
**************************************************************************/
307
static Uint16 move_window_motion(SDL_MouseMotionEvent *pMotionEvent, void *pData)
309
struct MOVE *pMove = (struct MOVE *)pData;
316
widget_mark_dirty(pMove->pWindow);
318
xrel = pMotionEvent->x - pMove->prev_x;
319
yrel = pMotionEvent->y - pMove->prev_y;
320
pMove->prev_x = pMotionEvent->x;
321
pMove->prev_y = pMotionEvent->y;
323
widget_set_position(pMove->pWindow,
324
(pMove->pWindow->dst->dest_rect.x + pMove->pWindow->size.x) + xrel,
325
(pMove->pWindow->dst->dest_rect.y + pMove->pWindow->size.y) + yrel);
327
widget_mark_dirty(pMove->pWindow);
333
/**************************************************************************
335
**************************************************************************/
336
static Uint16 move_window_button_up(SDL_MouseButtonEvent * pButtonEvent, void *pData)
338
struct MOVE *pMove = (struct MOVE *)pData;
340
if (pMove && pMove->moved) {
341
return (Uint16)ID_MOVED_WINDOW;
344
return (Uint16)ID_WINDOW;
348
/**************************************************************************
350
**************************************************************************/
351
bool move_window(struct widget *pWindow)
355
pMove.pWindow = pWindow;
357
SDL_GetMouseState(&pMove.prev_x, &pMove.prev_y);
358
/* Filter mouse motion events */
359
SDL_SetEventFilter(FilterMouseMotionEvents);
360
ret = (gui_event_loop((void *)&pMove, NULL, NULL, NULL, NULL,
361
move_window_button_up, move_window_motion) == ID_MOVED_WINDOW);
362
/* Turn off Filter mouse motion events */
363
SDL_SetEventFilter(NULL);