webperimental: Mountain vision bonus.
[freeciv.git] / client / gui-sdl2 / finddlg.c
blob0a2ff0ec906851ea6e152bcea79831ca442069e2
1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <stdlib.h>
20 /* SDL2 */
21 #ifdef SDL2_PLAIN_INCLUDE
22 #include <SDL.h>
23 #else /* SDL2_PLAIN_INCLUDE */
24 #include <SDL2/SDL.h>
25 #endif /* SDL2_PLAIN_INCLUDE */
27 /* utility */
28 #include "fcintl.h"
29 #include "log.h"
31 /* common */
32 #include "game.h"
34 /* gui-sdl2 */
35 #include "colors.h"
36 #include "graphics.h"
37 #include "gui_id.h"
38 #include "gui_main.h"
39 #include "gui_tilespec.h"
40 #include "mapctrl.h"
41 #include "mapview.h"
42 #include "sprite.h"
43 #include "widget.h"
45 #include "finddlg.h"
47 /* ====================================================================== */
48 /* ============================= FIND CITY MENU ========================= */
49 /* ====================================================================== */
50 static struct ADVANCED_DLG *pFind_City_Dlg = NULL;
52 /**************************************************************************
53 User interacted with find city dialog window.
54 **************************************************************************/
55 static int find_city_window_dlg_callback(struct widget *pWindow)
57 if (Main.event.button.button == SDL_BUTTON_LEFT) {
58 move_window_group(pFind_City_Dlg->pBeginWidgetList, pWindow);
61 return -1;
64 /**************************************************************************
65 Close find city dialog.
66 **************************************************************************/
67 static int exit_find_city_dlg_callback(struct widget *pWidget)
69 if (Main.event.button.button == SDL_BUTTON_LEFT) {
70 int orginal_x = pWidget->data.cont->id0;
71 int orginal_y = pWidget->data.cont->id1;
73 popdown_find_dialog();
75 center_tile_mapcanvas(map_pos_to_tile(orginal_x, orginal_y));
77 flush_dirty();
80 return -1;
83 /**************************************************************************
84 User has selected city to find.
85 **************************************************************************/
86 static int find_city_callback(struct widget *pWidget)
88 if (Main.event.button.button == SDL_BUTTON_LEFT) {
89 struct city *pCity = pWidget->data.city;
91 if (pCity) {
92 center_tile_mapcanvas(pCity->tile);
93 if (Main.event.button.button == SDL_BUTTON_RIGHT) {
94 popdown_find_dialog();
96 flush_dirty();
100 return -1;
103 /**************************************************************************
104 Popdown a dialog to ask for a city to find.
105 **************************************************************************/
106 void popdown_find_dialog(void)
108 if (pFind_City_Dlg) {
109 popdown_window_group_dialog(pFind_City_Dlg->pBeginWidgetList,
110 pFind_City_Dlg->pEndWidgetList);
111 FC_FREE(pFind_City_Dlg->pScroll);
112 FC_FREE(pFind_City_Dlg);
113 enable_and_redraw_find_city_button();
117 /**************************************************************************
118 Popup a dialog to ask for a city to find.
119 **************************************************************************/
120 void popup_find_dialog(void)
122 struct widget *pWindow = NULL, *pBuf = NULL;
123 SDL_Surface *pLogo = NULL;
124 utf8_str *pstr;
125 char cBuf[128];
126 int h = 0, n = 0, w = 0, units_h = 0;
127 struct player *owner = NULL;
128 struct tile *original;
129 int window_x = 0, window_y = 0;
130 bool mouse = (Main.event.type == SDL_MOUSEBUTTONDOWN);
131 SDL_Rect area;
133 /* check that there are any cities to find */
134 players_iterate(pplayer) {
135 h = city_list_size(pplayer->cities);
136 if (h > 0) {
137 break;
139 } players_iterate_end;
141 if (pFind_City_Dlg && !h) {
142 return;
145 original = canvas_pos_to_tile(Main.map->w / 2, Main.map->h / 2);
147 pFind_City_Dlg = fc_calloc(1, sizeof(struct ADVANCED_DLG));
149 pstr = create_utf8_from_char(_("Find City") , adj_font(12));
150 pstr->style |= TTF_STYLE_BOLD;
152 pWindow = create_window_skeleton(NULL, pstr, 0);
154 pWindow->action = find_city_window_dlg_callback;
155 set_wstate(pWindow , FC_WS_NORMAL);
157 add_to_gui_list(ID_TERRAIN_ADV_DLG_WINDOW, pWindow);
158 pFind_City_Dlg->pEndWidgetList = pWindow;
160 area = pWindow->area;
162 /* ---------- */
163 /* exit button */
164 pBuf = create_themeicon(current_theme->Small_CANCEL_Icon, pWindow->dst,
165 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND
166 | WF_FREE_DATA);
167 pBuf->info_label = create_utf8_from_char(_("Close Dialog (Esc)"),
168 adj_font(12));
169 area.w = MAX(area.w, pBuf->size.w + adj_size(10));
170 pBuf->action = exit_find_city_dlg_callback;
171 set_wstate(pBuf, FC_WS_NORMAL);
172 pBuf->key = SDLK_ESCAPE;
173 pBuf->data.cont = fc_calloc(1, sizeof(struct CONTAINER));
174 pBuf->data.cont->id0 = index_to_map_pos_x(tile_index(original));
175 pBuf->data.cont->id1 = index_to_map_pos_y(tile_index(original));
177 add_to_gui_list(ID_TERRAIN_ADV_DLG_EXIT_BUTTON, pBuf);
178 /* ---------- */
180 players_iterate(pPlayer) {
181 city_list_iterate(pPlayer->cities, pCity) {
182 fc_snprintf(cBuf , sizeof(cBuf), "%s (%d)", city_name_get(pCity),
183 city_size_get(pCity));
185 pstr = create_utf8_from_char(cBuf, adj_font(10));
186 pstr->style |= (TTF_STYLE_BOLD|SF_CENTER);
188 if (!player_owns_city(owner, pCity)) {
189 pLogo = get_nation_flag_surface(nation_of_player(city_owner(pCity)));
190 pLogo = crop_visible_part_from_surface(pLogo);
193 pBuf = create_iconlabel(pLogo, pWindow->dst, pstr,
194 (WF_RESTORE_BACKGROUND|WF_DRAW_TEXT_LABEL_WITH_SPACE));
196 if (!player_owns_city(owner, pCity)) {
197 set_wflag(pBuf, WF_FREE_THEME);
198 owner = city_owner(pCity);
201 pBuf->string_utf8->style &= ~SF_CENTER;
202 pBuf->string_utf8->fgcol = *(get_player_color(tileset, city_owner(pCity))->color);
203 pBuf->string_utf8->bgcol = (SDL_Color) {0, 0, 0, 0};
205 pBuf->data.city = pCity;
207 pBuf->action = find_city_callback;
208 set_wstate(pBuf, FC_WS_NORMAL);
210 add_to_gui_list(ID_LABEL , pBuf);
212 area.w = MAX(area.w, pBuf->size.w);
213 area.h += pBuf->size.h;
215 if (n > 19) {
216 set_wflag(pBuf , WF_HIDDEN);
219 n++;
220 } city_list_iterate_end;
221 } players_iterate_end;
223 pFind_City_Dlg->pBeginWidgetList = pBuf;
224 pFind_City_Dlg->pBeginActiveWidgetList = pFind_City_Dlg->pBeginWidgetList;
225 pFind_City_Dlg->pEndActiveWidgetList = pWindow->prev->prev;
226 pFind_City_Dlg->pActiveWidgetList = pFind_City_Dlg->pEndActiveWidgetList;
229 /* ---------- */
230 if (n > 20) {
231 units_h = create_vertical_scrollbar(pFind_City_Dlg, 1, 20, TRUE, TRUE);
232 pFind_City_Dlg->pScroll->count = n;
234 n = units_h;
235 area.w += n;
237 units_h = 20 * pBuf->size.h + adj_size(2);
239 } else {
240 units_h = area.h;
243 /* ---------- */
245 area.h = units_h;
247 resize_window(pWindow , NULL, NULL,
248 (pWindow->size.w - pWindow->area.w) + area.w,
249 (pWindow->size.h - pWindow->area.h) + area.h);
251 area = pWindow->area;
253 if (!mouse) {
254 window_x = adj_size(10);
255 window_y = (main_window_height() - pWindow->size.h) / 2;
256 } else {
257 window_x = (Main.event.motion.x + pWindow->size.w + adj_size(10) < main_window_width()) ?
258 (Main.event.motion.x + adj_size(10)) :
259 (main_window_width() - pWindow->size.w - adj_size(10));
260 window_y = (Main.event.motion.y - adj_size(2) + pWindow->size.h < main_window_height()) ?
261 (Main.event.motion.y - adj_size(2)) :
262 (main_window_height() - pWindow->size.h - adj_size(10));
265 widget_set_position(pWindow, window_x, window_y);
267 w = area.w;
269 if (pFind_City_Dlg->pScroll) {
270 w -= n;
273 /* exit button */
274 pBuf = pWindow->prev;
276 pBuf->size.x = area.x + area.w - pBuf->size.w - 1;
277 pBuf->size.y = pWindow->size.y + adj_size(2);
279 /* cities */
280 pBuf = pBuf->prev;
281 setup_vertical_widgets_position(1, area.x, area.y, w, 0,
282 pFind_City_Dlg->pBeginActiveWidgetList,
283 pBuf);
285 if (pFind_City_Dlg->pScroll) {
286 setup_vertical_scrollbar_area(pFind_City_Dlg->pScroll,
287 area.x + area.w, area.y,
288 area.h, TRUE);
291 /* -------------------- */
292 /* redraw */
293 redraw_group(pFind_City_Dlg->pBeginWidgetList, pWindow, 0);
294 widget_mark_dirty(pWindow);
296 flush_dirty();