~ubuntu-branches/debian/squeeze/freeciv/squeeze

« back to all changes in this revision

Viewing changes to client/gui-sdl/widget_window.c

  • Committer: Bazaar Package Importer
  • Author(s): Jordi Mallach
  • Date: 2008-07-08 18:34:23 UTC
  • mfrom: (5.1.9 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080708183423-c80u1h25xmj6h9s0
Tags: 2.1.5-2
Export datarootdir=/usr/share in debian/rules, so make calls can
have a correct value for LOCALEDIR (closes: #489455). Thanks Loïc Minier
for the help to solve this.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <config.h>
 
16
#endif
 
17
 
 
18
#include "SDL.h"
 
19
 
 
20
/* utility */
 
21
#include "log.h"
 
22
 
 
23
/* gui-sdl */
 
24
#include "colors.h"
 
25
#include "graphics.h"
 
26
#include "gui_id.h"
 
27
#include "gui_tilespec.h"
 
28
#include "mapview.h"
 
29
#include "themespec.h"
 
30
 
 
31
#include "widget.h"
 
32
#include "widget_p.h"
 
33
 
 
34
struct MOVE {
 
35
  bool moved;
 
36
  struct widget *pWindow;
 
37
  int prev_x;
 
38
  int prev_y;
 
39
};
 
40
 
 
41
static int (*baseclass_redraw)(struct widget *pwidget);
 
42
 
 
43
/**************************************************************************
 
44
  Redraw Window Graphic ( without other Widgets )
 
45
**************************************************************************/
 
46
static int redraw_window(struct widget *pWindow)
 
47
{
 
48
  int ret;
 
49
  SDL_Color title_bg_color = {255, 255, 255, 200};
 
50
  
 
51
  SDL_Surface *pTmp = NULL;
 
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);
 
62
 
 
63
  /* window has title string == has title bar */
 
64
  if (pWindow->string16) {
 
65
    
 
66
    /* Draw Window's TitelBar */
 
67
    dst = pWindow->area;
 
68
    dst.y -= (WINDOW_TITLE_HEIGHT + 1);
 
69
    dst.h = WINDOW_TITLE_HEIGHT;
 
70
    SDL_FillRectAlpha(pWindow->dst->surface, &dst, &title_bg_color);
 
71
    
 
72
    /* Draw Text on Window's TitelBar */
 
73
    pTmp = create_text_surf_from_str16(pWindow->string16);
 
74
    dst.x += adj_size(4);
 
75
    if(pTmp) {
 
76
      dst.y += ((WINDOW_TITLE_HEIGHT - pTmp->h) / 2);
 
77
      alphablit(pTmp, NULL, pWindow->dst->surface, &dst);
 
78
      FREESURFACE(pTmp);
 
79
    }
 
80
 
 
81
    dst = pWindow->area;    
 
82
    
 
83
    putline(pWindow->dst->surface,
 
84
            dst.x, dst.y - 1,
 
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)));    
 
88
  }
 
89
  
 
90
  /* draw frame */
 
91
  if (get_wflags(pWindow) & WF_DRAW_FRAME_AROUND_WIDGET) {
 
92
    widget_draw_frame(pWindow);
 
93
  }
 
94
  
 
95
  return 0;
 
96
}
 
97
 
 
98
/**************************************************************************
 
99
        Window mechanism.
 
100
 
 
101
        Active Window schould be first on list (All Widgets on this
 
102
        Widndow that are on List must be above)
 
103
 
 
104
        LIST:
 
105
 
 
106
        *pFirst_Widget_on_Active_Window.
 
107
 
 
108
        *pN__Widget_on_Active_Window.
 
109
        *pActive_Window. <------
 
110
        *pRest_Widgets.
 
111
 
 
112
        This trick give us:
 
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
**************************************************************************/
 
117
 
 
118
/**************************************************************************
 
119
  ...
 
120
**************************************************************************/
 
121
static void window_set_position(struct widget *pWindow, int x, int y)
 
122
{
 
123
  struct gui_layer *gui_layer;
 
124
 
 
125
  pWindow->size.x = 0;
 
126
  pWindow->size.y = 0;
 
127
  
 
128
  gui_layer = get_gui_layer(pWindow->dst->surface);
 
129
  gui_layer->dest_rect.x = x;
 
130
  gui_layer->dest_rect.y = y;
 
131
}
 
132
 
 
133
/**************************************************************************
 
134
  ...
 
135
**************************************************************************/
 
136
static void window_select(struct widget *pWindow)
 
137
{
 
138
  /* nothing */
 
139
}
 
140
 
 
141
/**************************************************************************
 
142
  ...
 
143
**************************************************************************/
 
144
static void window_unselect(struct widget *pWindow)
 
145
{
 
146
  /* nothing */
 
147
}
 
148
 
 
149
/**************************************************************************
 
150
  ...
 
151
**************************************************************************/
 
152
static void set_client_area(struct widget *pWindow)
 
153
{
 
154
  SDL_Rect area;
 
155
  
 
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;
 
161
  } else {
 
162
    area = pWindow->size;
 
163
  }
 
164
    
 
165
  if (pWindow->string16) {
 
166
    area.y += (WINDOW_TITLE_HEIGHT + 1);
 
167
    area.h -= (WINDOW_TITLE_HEIGHT + 1);
 
168
  }
 
169
  
 
170
  widget_set_area(pWindow, area);
 
171
}
 
172
 
 
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)
 
179
{
 
180
  int w = 0, h = 0;
 
181
  struct widget *pWindow = widget_new();
 
182
 
 
183
  pWindow->set_position = window_set_position;
 
184
  
 
185
  baseclass_redraw = pWindow->redraw;
 
186
  pWindow->redraw = redraw_window;
 
187
  pWindow->select = window_select;
 
188
  pWindow->unselect = window_unselect;
 
189
  
 
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;
 
196
 
 
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;
 
200
  }
 
201
  
 
202
  if (pTitle) {
 
203
    SDL_Rect size = str16size(pTitle);
 
204
    w += size.w + adj_size(10);
 
205
    h += MAX(size.h, WINDOW_TITLE_HEIGHT + 1);
 
206
  }
 
207
  
 
208
  pWindow->size.w = w;
 
209
  pWindow->size.h = h;
 
210
 
 
211
  set_client_area(pWindow);
 
212
  
 
213
  if(pDest) {
 
214
    pWindow->dst = pDest;
 
215
  } else {
 
216
    pWindow->dst = add_gui_layer(w, h);
 
217
  }
 
218
 
 
219
  return pWindow;
 
220
}
 
221
 
 
222
struct widget * create_window(struct gui_layer *pDest, SDL_String16 *pTitle, 
 
223
                              Uint16 w, Uint16 h, Uint32 flags)
 
224
{
 
225
  struct widget *pWindow = create_window_skeleton(pDest, pTitle, flags);
 
226
 
 
227
  resize_window(pWindow, NULL, NULL, w, h);
 
228
  
 
229
  return pWindow;
 
230
}
 
231
 
 
232
/**************************************************************************
 
233
  Resize Window 'pWindow' to 'new_w' and 'new_h'.
 
234
  and refresh window background ( save screen under window ).
 
235
 
 
236
  If pBcgd == NULL then theme is set to
 
237
  white transparent ( ALPHA = 128 ).
 
238
 
 
239
  Return 1 if allocate new surface and 0 if used 'pBcgd' surface.
 
240
 
 
241
  Exp.
 
242
  if ( resize_window( pWindow , pBcgd , new_w , new_h ) ) {
 
243
    FREESURFACE( pBcgd );
 
244
  }
 
245
**************************************************************************/
 
246
int resize_window(struct widget *pWindow,
 
247
                  SDL_Surface * pBcgd,
 
248
                  SDL_Color * pColor, Uint16 new_w, Uint16 new_h)
 
249
{
 
250
  struct gui_layer *gui_layer;  
 
251
  struct widget *pWidget;
 
252
 
 
253
  /* window */
 
254
 
 
255
  if ((new_w != pWindow->size.w) || (new_h != pWindow->size.h)) {
 
256
    pWindow->size.w = new_w;
 
257
    pWindow->size.h = new_h;
 
258
  
 
259
    set_client_area(pWindow);
 
260
    
 
261
    if (get_wflags(pWindow) & WF_RESTORE_BACKGROUND) {
 
262
      refresh_widget_background(pWindow);
 
263
    }
 
264
  
 
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,
 
269
                                                               SDL_SWSURFACE);
 
270
    /* assign new buffer to all widgets on this window */
 
271
    pWidget = pWindow;
 
272
    while(pWidget) {
 
273
      pWidget->dst->surface = gui_layer->surface;
 
274
      pWidget = pWidget->prev;
 
275
    }
 
276
  }
 
277
  
 
278
  if (pBcgd != pWindow->theme) {
 
279
    FREESURFACE(pWindow->theme);
 
280
  }
 
281
 
 
282
  if (pBcgd) {
 
283
    if (pBcgd->w != new_w || pBcgd->h != new_h) {
 
284
      pWindow->theme = ResizeSurface(pBcgd, new_w, new_h, 2);
 
285
      return 1;
 
286
    } else {
 
287
      pWindow->theme = pBcgd;
 
288
      return 0;
 
289
    }
 
290
  } else {
 
291
    pWindow->theme = create_surf_alpha(new_w, new_h, SDL_SWSURFACE);
 
292
    
 
293
    if (!pColor) {
 
294
      SDL_Color color = *get_game_colorRGB(COLOR_THEME_BACKGROUND);
 
295
      pColor = &color;
 
296
    }
 
297
  
 
298
    SDL_FillRect(pWindow->theme, NULL, map_rgba(pWindow->theme->format, *pColor));
 
299
    
 
300
    return 1;
 
301
  }
 
302
}
 
303
 
 
304
/**************************************************************************
 
305
...
 
306
**************************************************************************/
 
307
static Uint16 move_window_motion(SDL_MouseMotionEvent *pMotionEvent, void *pData)
 
308
{
 
309
  struct MOVE *pMove = (struct MOVE *)pData;
 
310
  int xrel, yrel;
 
311
  
 
312
  if (!pMove->moved) {
 
313
    pMove->moved = TRUE;
 
314
  }
 
315
 
 
316
  widget_mark_dirty(pMove->pWindow);
 
317
 
 
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;
 
322
 
 
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);
 
326
  
 
327
  widget_mark_dirty(pMove->pWindow);
 
328
  flush_dirty();
 
329
  
 
330
  return ID_ERROR;
 
331
}
 
332
 
 
333
/**************************************************************************
 
334
...
 
335
**************************************************************************/
 
336
static Uint16 move_window_button_up(SDL_MouseButtonEvent * pButtonEvent, void *pData)
 
337
{
 
338
  struct MOVE *pMove = (struct MOVE *)pData;
 
339
 
 
340
  if (pMove && pMove->moved) {
 
341
    return (Uint16)ID_MOVED_WINDOW;
 
342
  }
 
343
  
 
344
  return (Uint16)ID_WINDOW;
 
345
}
 
346
 
 
347
 
 
348
/**************************************************************************
 
349
  ...
 
350
**************************************************************************/
 
351
bool move_window(struct widget *pWindow)
 
352
{
 
353
  bool ret;
 
354
  struct MOVE pMove;
 
355
  pMove.pWindow = pWindow;
 
356
  pMove.moved = FALSE;
 
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);
 
364
  return ret;
 
365
}