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
***********************************************************************/
22
#include "string_vector.h"
26
#include "gui_iconv.h"
28
#include "gui_string.h"
29
#include "gui_tilespec.h"
37
struct widget *begin_widget_list;
38
struct widget *end_widget_list;
41
static int (*baseclass_redraw) (struct widget *widget) = NULL;
44
/****************************************************************************
45
Redraw the combo box widget.
46
****************************************************************************/
47
static int combo_redraw(struct widget *combo)
49
SDL_Rect dest = { combo->size.x, combo->size.y, 0, 0 };
50
SDL_Surface *text, *surface;
51
struct combo_menu *menu;
54
ret = baseclass_redraw(combo);
59
surface = create_bcgnd_surf(combo->theme, get_wstate(combo),
60
combo->size.w, combo->size.h);
62
if (NULL == surface) {
67
alphablit(surface, NULL, combo->dst->surface, &dest);
69
/* Set position and blit text. */
70
text = create_text_surf_from_str16(combo->string16);
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;
77
if (combo->string16->style & SF_CENTER_RIGHT) {
78
dest.x += surface->w - text->w - adj_size(5);
80
dest.x += adj_size(5); /* center left */
84
alphablit(text, NULL, combo->dst->surface, &dest);
93
menu = (struct combo_menu *) combo->private_data.ptr;
95
ret = redraw_group(menu->begin_widget_list, menu->end_widget_list, 0);
101
/****************************************************************************
103
****************************************************************************/
104
static int combo_menu_callback(struct widget *window)
106
if (Main.event.button.button == SDL_BUTTON_LEFT) {
107
struct combo_menu *menu =
108
(struct combo_menu *)window->data.widget->private_data.ptr;
110
move_window_group(menu->begin_widget_list, menu->end_widget_list);
115
/****************************************************************************
117
****************************************************************************/
118
static int combo_menu_item_callback(struct widget *label)
120
struct widget *combo = label->data.widget;
122
if (Main.event.button.button == SDL_BUTTON_LEFT) {
125
str = convert_to_chars(label->string16->text);
126
copy_chars_to_string16(combo->string16, str);
128
widget_redraw(combo);
129
widget_mark_dirty(combo);
131
combo_popdown(combo);
135
/****************************************************************************
136
Popup the combo box widget.
137
****************************************************************************/
138
void combo_popup(struct widget *combo)
140
struct combo_menu *menu;
141
struct widget *window, *label = NULL;
142
int longest = 0, h = 0, x, y;
144
fc_assert_ret(NULL != combo);
145
fc_assert_ret(WT_COMBO == get_wtype(combo));
147
if (NULL != combo->private_data.ptr) {
151
if (0 >= strvec_size(combo->data.vector)) {
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);
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);
171
longest = MAX(longest, label->size.w);
172
widget_set_position(label, adj_size(10), h);
174
} strvec_iterate_end;
176
/* Resize and relocate the window. */
177
resize_window(window, NULL, NULL, longest + 2 * adj_size(10), h);
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;
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;
195
widget_set_position(window, x, y);
198
menu = fc_malloc(sizeof(*menu));
199
menu->begin_widget_list = label;
200
menu->end_widget_list = window;
201
combo->private_data.ptr = menu;
204
redraw_group(menu->begin_widget_list, menu->end_widget_list, 0);
205
widget_mark_dirty(window);
209
/****************************************************************************
210
Popdown the combo box widget.
211
****************************************************************************/
212
void combo_popdown(struct widget *combo)
214
struct combo_menu *menu;
216
fc_assert_ret(NULL != combo);
217
fc_assert_ret(WT_COMBO == get_wtype(combo));
219
menu = (struct combo_menu *) combo->private_data.ptr;
224
widget_mark_dirty(menu->end_widget_list);
225
popdown_window_group_dialog(menu->begin_widget_list,
226
menu->end_widget_list);
228
combo->private_data.ptr = NULL;
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)
239
SDL_Rect buf = {0, 0, 0, 0};
240
struct widget *combo = widget_new();
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;
250
baseclass_redraw = combo->redraw;
251
combo->redraw = combo_redraw;
252
combo->destroy = combo_popdown;
254
if (NULL != string16) {
255
combo->string16->style |= SF_CENTER;
256
buf = str16size(string16);
257
buf.h += adj_size(4);
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;
268
combo->dst = add_gui_layer(combo->size.w, combo->size.h);
270
combo->data.vector = vector;
271
combo->private_data.ptr = NULL;