~ubuntu-branches/debian/sid/freeciv/sid

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Clint Adams, Karl Goetz, Clint Adams
  • Date: 2011-08-28 22:40:00 UTC
  • mfrom: (1.2.19 upstream)
  • Revision ID: package-import@ubuntu.com-20110828224000-j2r1erewlem25dox
Tags: 2.3.0-1
[ Karl Goetz ]
* New upstream version.
* Fix themes_sdl_use_system_fonts.diff to apply cleanly on 2.3.0
* Massage work_around_unity_induced_breakage.diff to get it
  applying to the new codebase (The patch assumes commits made
  after 2.3.0 was tagged upstream).

[ Clint Adams ]
* Fudge build system to think there is no libtool mismatch.

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
#include "string_vector.h"
 
23
 
 
24
/* client/gui-sdl */
 
25
#include "colors.h"
 
26
#include "gui_iconv.h"
 
27
#include "gui_id.h"
 
28
#include "gui_string.h"
 
29
#include "gui_tilespec.h"
 
30
#include "mapview.h"
 
31
 
 
32
#include "widget.h"
 
33
#include "widget_p.h"
 
34
 
 
35
 
 
36
struct combo_menu {
 
37
  struct widget *begin_widget_list;
 
38
  struct widget *end_widget_list;
 
39
};
 
40
 
 
41
static int (*baseclass_redraw) (struct widget *widget) = NULL;
 
42
 
 
43
 
 
44
/****************************************************************************
 
45
  Redraw the combo box widget.
 
46
****************************************************************************/
 
47
static int combo_redraw(struct widget *combo)
 
48
{
 
49
  SDL_Rect dest = { combo->size.x, combo->size.y, 0, 0 };
 
50
  SDL_Surface *text, *surface;
 
51
  struct combo_menu *menu;
 
52
  int ret;
 
53
 
 
54
  ret = baseclass_redraw(combo);
 
55
  if (0 != ret) {
 
56
    return ret;
 
57
  }
 
58
 
 
59
  surface = create_bcgnd_surf(combo->theme, get_wstate(combo),
 
60
                              combo->size.w, combo->size.h);
 
61
 
 
62
  if (NULL == surface) {
 
63
    return -1;
 
64
  }
 
65
 
 
66
  /* Blit theme. */
 
67
  alphablit(surface, NULL, combo->dst->surface, &dest);
 
68
 
 
69
  /* Set position and blit text. */
 
70
  text = create_text_surf_from_str16(combo->string16);
 
71
  if (NULL != text) {
 
72
    dest.y += (surface->h - surface->h) / 2;
 
73
    /* Blit centred text to botton. */
 
74
    if (combo->string16->style & SF_CENTER) {
 
75
      dest.x += (surface->w - text->w) / 2;
 
76
    } else {
 
77
      if (combo->string16->style & SF_CENTER_RIGHT) {
 
78
        dest.x += surface->w - text->w - adj_size(5);
 
79
      } else {
 
80
        dest.x += adj_size(5);          /* center left */
 
81
      }
 
82
    }
 
83
 
 
84
    alphablit(text, NULL, combo->dst->surface, &dest);
 
85
  }
 
86
  /* text. */
 
87
  ret = surface->h;
 
88
 
 
89
  /* Free memory */
 
90
  FREESURFACE(text);
 
91
  FREESURFACE(surface);
 
92
 
 
93
  menu = (struct combo_menu *) combo->private_data.ptr;
 
94
  if (NULL != menu) {
 
95
    ret = redraw_group(menu->begin_widget_list, menu->end_widget_list, 0);
 
96
  }
 
97
 
 
98
  return ret;
 
99
}
 
100
 
 
101
/****************************************************************************
 
102
  ...
 
103
****************************************************************************/
 
104
static int combo_menu_callback(struct widget *window)
 
105
{
 
106
  if (Main.event.button.button == SDL_BUTTON_LEFT) {
 
107
    struct combo_menu *menu =
 
108
        (struct combo_menu *)window->data.widget->private_data.ptr;
 
109
 
 
110
    move_window_group(menu->begin_widget_list, menu->end_widget_list);
 
111
  }
 
112
  return -1;
 
113
}
 
114
 
 
115
/****************************************************************************
 
116
  ...
 
117
****************************************************************************/
 
118
static int combo_menu_item_callback(struct widget *label)
 
119
{
 
120
  struct widget *combo = label->data.widget;
 
121
 
 
122
  if (Main.event.button.button == SDL_BUTTON_LEFT) {
 
123
    char *str;
 
124
 
 
125
    str = convert_to_chars(label->string16->text);
 
126
    copy_chars_to_string16(combo->string16, str);
 
127
    free(str);
 
128
    widget_redraw(combo);
 
129
    widget_mark_dirty(combo);
 
130
  }
 
131
  combo_popdown(combo);
 
132
  return -1;
 
133
}
 
134
 
 
135
/****************************************************************************
 
136
  Popup the combo box widget.
 
137
****************************************************************************/
 
138
void combo_popup(struct widget *combo)
 
139
{
 
140
  struct combo_menu *menu;
 
141
  struct widget *window, *label = NULL;
 
142
  int longest = 0, h = 0, x, y;
 
143
 
 
144
  fc_assert_ret(NULL != combo);
 
145
  fc_assert_ret(WT_COMBO == get_wtype(combo));
 
146
 
 
147
  if (NULL != combo->private_data.ptr) {
 
148
    return;
 
149
  }
 
150
 
 
151
  if (0 >= strvec_size(combo->data.vector)) {
 
152
    return;
 
153
  }
 
154
 
 
155
  /* Menu. */
 
156
  window = create_window_skeleton(NULL, NULL, 0);
 
157
  window->action = combo_menu_callback;
 
158
  window->data.widget = combo;
 
159
  set_wstate(window, FC_WS_NORMAL);
 
160
  add_to_gui_list(ID_COMBO_MENU, window);
 
161
 
 
162
  /* Labels. */
 
163
  strvec_iterate(combo->data.vector, string) {
 
164
    label = create_iconlabel_from_chars(NULL, window->dst, string,
 
165
                                       adj_font(10), WF_RESTORE_BACKGROUND);
 
166
    label->action = combo_menu_item_callback;
 
167
    label->data.widget = combo;
 
168
    set_wstate(label, FC_WS_NORMAL);
 
169
    add_to_gui_list(ID_LABEL, label);
 
170
 
 
171
    longest = MAX(longest, label->size.w);
 
172
    widget_set_position(label, adj_size(10), h);
 
173
    h += adj_size(15);
 
174
  } strvec_iterate_end;
 
175
 
 
176
  /* Resize and relocate the window. */
 
177
  resize_window(window, NULL, NULL, longest + 2 * adj_size(10), h);
 
178
 
 
179
  x = combo->size.x + combo->dst->dest_rect.x;
 
180
  if (x + window->size.w > Main.screen->w) {
 
181
    x = Main.screen->w - window->size.w;
 
182
  }
 
183
  if (x < 0) {
 
184
    x = 0;
 
185
  }
 
186
 
 
187
  y = combo->size.y - h + combo->dst->dest_rect.y;
 
188
  if (y + window->size.h > Main.screen->h) {
 
189
    y = Main.screen->h - window->size.h;
 
190
  }
 
191
  if (y < 0) {
 
192
    y = 0;
 
193
  }
 
194
 
 
195
  widget_set_position(window, x, y);
 
196
 
 
197
  /* Make data. */
 
198
  menu = fc_malloc(sizeof(*menu));
 
199
  menu->begin_widget_list = label;
 
200
  menu->end_widget_list = window;
 
201
  combo->private_data.ptr = menu;
 
202
 
 
203
  /* Redraw. */
 
204
  redraw_group(menu->begin_widget_list, menu->end_widget_list, 0);
 
205
  widget_mark_dirty(window);
 
206
  flush_dirty();
 
207
}
 
208
 
 
209
/****************************************************************************
 
210
  Popdown the combo box widget.
 
211
****************************************************************************/
 
212
void combo_popdown(struct widget *combo)
 
213
{
 
214
  struct combo_menu *menu;
 
215
 
 
216
  fc_assert_ret(NULL != combo);
 
217
  fc_assert_ret(WT_COMBO == get_wtype(combo));
 
218
 
 
219
  menu = (struct combo_menu *) combo->private_data.ptr;
 
220
  if (NULL == menu) {
 
221
    return;
 
222
  }
 
223
 
 
224
  widget_mark_dirty(menu->end_widget_list);
 
225
  popdown_window_group_dialog(menu->begin_widget_list,
 
226
                              menu->end_widget_list);
 
227
  free(menu);
 
228
  combo->private_data.ptr = NULL;
 
229
  flush_dirty();
 
230
}
 
231
 
 
232
/****************************************************************************
 
233
  Create a combo box widget.
 
234
****************************************************************************/
 
235
struct widget *combo_new(SDL_Surface *background, struct gui_layer *dest,
 
236
                         SDL_String16 *string16, const struct strvec *vector,
 
237
                         Uint16 length, Uint32 flags)
 
238
{
 
239
  SDL_Rect buf = {0, 0, 0, 0};
 
240
  struct widget *combo = widget_new();
 
241
 
 
242
  combo->theme = pTheme->Edit;
 
243
  combo->theme2 = background;
 
244
  combo->string16 = string16;
 
245
  set_wflag(combo, WF_FREE_STRING | WF_FREE_GFX | flags);
 
246
  set_wstate(combo, FC_WS_DISABLED);
 
247
  set_wtype(combo, WT_COMBO);
 
248
  combo->mod = KMOD_NONE;
 
249
 
 
250
  baseclass_redraw = combo->redraw;
 
251
  combo->redraw = combo_redraw;
 
252
  combo->destroy = combo_popdown;
 
253
 
 
254
  if (NULL != string16) {
 
255
    combo->string16->style |= SF_CENTER;
 
256
    buf = str16size(string16);
 
257
    buf.h += adj_size(4);
 
258
  }
 
259
 
 
260
  length = MAX(length, buf.w + adj_size(10));
 
261
  correct_size_bcgnd_surf(pTheme->Edit, &length, &buf.h);
 
262
  combo->size.w = buf.w + adj_size(10);
 
263
  combo->size.h = buf.h;
 
264
 
 
265
  if (dest) {
 
266
    combo->dst = dest;
 
267
  } else {
 
268
    combo->dst = add_gui_layer(combo->size.w, combo->size.h);
 
269
  }
 
270
  combo->data.vector = vector;
 
271
  combo->private_data.ptr = NULL;
 
272
 
 
273
  return combo;
 
274
}