1 /* 2 3 Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc. 4 and the "Aleph One" developers. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 This license is contained in the file "COPYING", 17 which is included with this source code; it is available online at 18 http://www.gnu.org/licenses/gpl.html 19 20 */ 21 22 /* 23 * sdl_dialogs.h - SDL implementation of user dialogs 24 * 25 * Written in 2000 by Christian Bauer 26 */ 27 28 #ifndef SDL_DIALOGS_H 29 #define SDL_DIALOGS_H 30 31 #include "cstypes.h" 32 #include <vector> 33 #include <memory> 34 #include <boost/function.hpp> 35 #include <SDL.h> 36 37 #ifndef NO_STD_NAMESPACE 38 using std::vector; 39 #endif 40 41 class widget; 42 class font_info; 43 class FileSpecifier; 44 45 46 /* 47 * Definitions 48 */ 49 50 class dialog; 51 52 class placeable { 53 public: 54 enum placement_flags 55 { 56 kDefault = 0x0, 57 kAlignLeft = 0x1, 58 kAlignCenter = 0x2, 59 kAlignRight = 0x4, 60 kFill = 0x8, 61 }; 62 placeable()63 placeable() : m_visible(true) { } ~placeable()64 virtual ~placeable() { } 65 66 virtual void place(const SDL_Rect &r, placement_flags flags = kDefault) = 0; 67 virtual int min_height() = 0; 68 virtual int min_width() = 0; 69 visible()70 virtual bool visible() { return m_visible; } visible(bool visible)71 virtual void visible(bool visible) { m_visible = visible; } 72 73 private: 74 bool m_visible; 75 }; 76 77 class widget_placer : public placeable 78 { 79 public: widget_placer()80 widget_placer() : placeable() { } 81 ~widget_placer(); 82 83 void place(const SDL_Rect &r, placement_flags flags = kDefault) = 0; 84 int min_height() = 0; 85 int min_width() = 0; 86 87 protected: assume_ownership(placeable * p)88 void assume_ownership(placeable *p) { m_owned.push_back(p); } 89 90 private: 91 std::vector<placeable *> m_owned; 92 }; 93 94 class tab_placer : public widget_placer 95 { 96 public: tab_placer()97 tab_placer() : widget_placer(), m_tab(0) { } 98 void add(placeable *p, bool assume_ownership = false); 99 void dual_add(widget *w, dialog& d); 100 int min_height(); 101 int min_width(); tabs()102 int tabs() { return m_tabs.size(); }; 103 void choose_tab(int new_tab); 104 void place(const SDL_Rect &r, placement_flags flags = kDefault); visible()105 bool visible() { return widget_placer::visible(); } 106 void visible(bool visible); 107 private: 108 int m_tab; 109 std::vector<placeable *> m_tabs; 110 }; 111 112 class table_placer : public widget_placer 113 { 114 public: 115 enum { kSpace = 4 }; widget_placer()116 table_placer(int columns, int space = kSpace, bool balance_widths = false) : widget_placer(), m_add(0), m_columns(columns), m_space(space), m_balance_widths(balance_widths) { m_col_flags.resize(m_columns); m_col_min_widths.resize(m_columns);} 117 void add(placeable *p, bool assume_ownership = false); 118 void add_row(placeable *p, bool assume_ownership = false); 119 void col_flags(int col, placement_flags flags = kDefault) { m_col_flags[col] = flags; } col_min_width(int col,int min_width)120 void col_min_width(int col, int min_width) { m_col_min_widths[col] = min_width; } 121 void dual_add(widget *w, dialog& d); 122 void dual_add_row(widget *w, dialog& d); 123 int min_height(); 124 int min_width(); 125 void place(const SDL_Rect &r, placement_flags flags = kDefault); 126 void visible(bool visible); 127 int col_width(int column); 128 private: 129 int row_height(int row); 130 int m_add; // column to add next widget to 131 int m_columns; // number of columns 132 int m_space; 133 bool m_balance_widths; 134 std::vector<std::vector<placeable *> > m_table; 135 std::vector<placement_flags> m_col_flags; 136 std::vector<int> m_col_min_widths; 137 }; 138 139 140 class vertical_placer : public widget_placer 141 { 142 public: 143 enum { kSpace = 0 }; m_space(space)144 vertical_placer(int space = kSpace) : m_space(space), widget_placer(), m_min_width(0), m_add_flags(kDefault) { } 145 146 void add(placeable *p, bool assume_ownership = false); 147 void add_flags(placement_flags flags = kDefault) { m_add_flags = flags; } 148 void dual_add(widget *w, dialog& d); 149 int min_height(); 150 int min_width(); min_width(int w)151 void min_width(int w) { m_min_width = w; } 152 153 void place(const SDL_Rect &r, placement_flags flags = kDefault); 154 void visible(bool visible); 155 156 private: 157 std::vector<placeable *> m_widgets; 158 std::vector<int> m_widget_heights; 159 std::vector<placement_flags> m_placement_flags; 160 int m_min_width; 161 placement_flags m_add_flags; 162 int m_space; 163 }; 164 165 class horizontal_placer : public widget_placer 166 { 167 public: 168 enum { kSpace = 4 }; widget_placer()169 horizontal_placer(int space = kSpace, bool balance_widths = false) : widget_placer(), m_space(space), m_add_flags(kDefault), m_balance_widths(balance_widths) { } 170 171 void add(placeable *p, bool assume_ownership = false); 172 void add_flags(placement_flags flags = kDefault) { m_add_flags = flags; } 173 // adds w to this placer, as well as dialog d 174 void dual_add(widget *w, dialog& d); 175 int min_height(); 176 int min_width(); 177 178 void place(const SDL_Rect &r, placement_flags flags = kDefault); 179 void visible(bool visible); 180 181 private: 182 std::vector<placeable *> m_widgets; 183 std::vector<int> m_widget_widths; 184 std::vector<placement_flags> m_placement_flags; 185 int m_space; 186 placement_flags m_add_flags; 187 bool m_balance_widths; 188 }; 189 190 191 // Dialog structure 192 class dialog { 193 public: 194 typedef boost::function<void (dialog* d)> Callback; 195 196 dialog(); 197 ~dialog(); 198 199 // Add widget to dialog 200 void add(widget *w); 201 202 // Run dialog modally 203 int run(bool intro_exit_sounds = true); 204 205 // Put dialog on screen 206 void start(bool play_sound = true); 207 208 // Process pending events, returns "done" flag 209 bool process_events(); 210 211 // Remove dialog from screen, returns dialog result 212 int finish(bool play_sound = true); 213 214 // Quit dialog, return result 215 void quit(int result); 216 217 // Draw dialog 218 void draw(void); 219 220 // ZZZ: Draw those widgets that are marked as needing redraw 221 // This is used automatically by the dialog code in response to user events -- 222 // other code doesn't need to call this unless it's altering dialog widgets 223 // on its own (e.g. on a timer, or according to network activity, etc.) 224 void draw_dirty_widgets() const; 225 226 // Find the first widget with matching numerical ID 227 widget *get_widget_by_id(short inID) const; 228 229 // Set custom processing function, called while dialog is idle set_processing_function(Callback func)230 void set_processing_function(Callback func) { processing_function = func; } 231 232 // Activate next selectable widget 233 void activate_next_widget(void); 234 235 // exposed to allow toggling fill_the_screen 236 // don't call this unless you know what you're doing 237 void layout(void); 238 239 // takes ownership set_widget_placer(widget_placer * w)240 void set_widget_placer(widget_placer *w) { placer = w; } 241 242 void activate_widget(widget *w); 243 244 private: 245 SDL_Surface *get_surface(void) const; 246 void update(SDL_Rect r) const; 247 void draw_widget(widget *w, bool do_update = true) const; 248 void deactivate_currently_active_widget(); 249 void activate_first_widget(void); 250 void activate_widget(size_t num); 251 void activate_prev_widget(void); 252 int find_widget(int x, int y); 253 void event(SDL_Event &e); 254 255 void new_layout(void); 256 257 SDL_Rect rect; // Position relative to video surface, and dimensions 258 259 vector<widget *> widgets; // List of widgets 260 261 widget *active_widget; // Pointer to active widget 262 widget *mouse_widget; // Pointer to mouse event widget 263 size_t active_widget_num; // Number of active widget 264 265 int result; // Dialog result code 266 bool done; // Flag: dialog done 267 bool cursor_was_visible; // Previous cursor state 268 269 dialog *parent_dialog; // Pointer to parent dialog 270 271 Callback processing_function; // Custom idle procedure 272 273 // Frame images (frame_t, frame_l, frame_r and frame_b must be freed) 274 SDL_Surface *frame_tl, *frame_t, *frame_tr, *frame_l, *frame_r, *frame_bl, *frame_b, *frame_br; 275 276 widget_placer *placer; 277 bool layout_for_fullscreen; // is the current layout for fullscreen? 278 279 Uint32 last_redraw; 280 }; 281 282 // Pointer to top-level dialog, NULL = no dialog active 283 extern dialog *top_dialog; 284 285 // Sounds 286 enum { 287 DIALOG_INTRO_SOUND, 288 DIALOG_OK_SOUND, 289 DIALOG_CANCEL_SOUND, 290 DIALOG_ERROR_SOUND, 291 DIALOG_SELECT_SOUND, 292 DIALOG_CLICK_SOUND, 293 DIALOG_TYPE_SOUND, 294 DIALOG_DELETE_SOUND, 295 DIALOG_ERASE_SOUND, 296 NUMBER_OF_DIALOG_SOUNDS 297 }; 298 299 /* 300 * Functions 301 */ 302 303 extern void initialize_dialogs(); 304 305 extern bool load_dialog_theme(bool force_reload = false); 306 307 extern uint32 get_dialog_player_color(size_t colorIndex); // ZZZ: added 308 extern void play_dialog_sound(int which); 309 310 // new theme stuff 311 312 // States 313 enum { 314 DEFAULT_STATE, 315 DISABLED_STATE, 316 ACTIVE_STATE, 317 CURSOR_STATE, 318 PRESSED_STATE 319 }; 320 321 // Widget types 322 enum { 323 DEFAULT_WIDGET, 324 DIALOG_FRAME, 325 TITLE_WIDGET, 326 LABEL_WIDGET, 327 MESSAGE_WIDGET, 328 ITEM_WIDGET, 329 TEXT_ENTRY_WIDGET, 330 SPACER_WIDGET, 331 BUTTON_WIDGET, 332 SLIDER_WIDGET, 333 SLIDER_THUMB, 334 LIST_WIDGET, 335 LIST_THUMB, 336 CHAT_ENTRY, 337 TINY_BUTTON, 338 CHECKBOX, 339 TAB_WIDGET, 340 METASERVER_WIDGETS, 341 METASERVER_PLAYERS, 342 METASERVER_GAMES, 343 HYPERLINK_WIDGET, 344 }; 345 346 enum { 347 FOREGROUND_COLOR, 348 BACKGROUND_COLOR, 349 FRAME_COLOR 350 }; 351 352 enum { 353 TL_IMAGE, 354 T_IMAGE, 355 TR_IMAGE, 356 L_IMAGE, 357 R_IMAGE, 358 BL_IMAGE, 359 B_IMAGE, 360 BR_IMAGE 361 }; 362 363 enum { 364 BUTTON_L_IMAGE, 365 BUTTON_C_IMAGE, 366 BUTTON_R_IMAGE 367 }; 368 369 enum { 370 SLIDER_L_IMAGE, 371 SLIDER_C_IMAGE, 372 SLIDER_R_IMAGE, 373 }; 374 375 enum { 376 SLIDER_T_SPACE, 377 SLIDER_L_SPACE, 378 SLIDER_R_SPACE 379 }; 380 381 enum { 382 T_SPACE, 383 L_SPACE, 384 R_SPACE, 385 B_SPACE 386 }; 387 388 enum { 389 BUTTON_T_SPACE, 390 BUTTON_L_SPACE, 391 BUTTON_R_SPACE, 392 BUTTON_HEIGHT, 393 }; 394 395 enum { 396 TAB_LC_SPACE = BUTTON_HEIGHT + 1, 397 TAB_RC_SPACE 398 }; 399 400 enum { 401 TAB_L_IMAGE, 402 TAB_LC_IMAGE, 403 TAB_C_IMAGE, 404 TAB_RC_IMAGE, 405 TAB_R_IMAGE 406 }; 407 408 enum { 409 TROUGH_T_SPACE = B_SPACE + 1, 410 TROUGH_R_SPACE, 411 TROUGH_B_SPACE, 412 TROUGH_WIDTH 413 }; 414 415 enum { 416 THUMB_T_IMAGE, 417 THUMB_TC_IMAGE, 418 THUMB_C_IMAGE, 419 THUMB_BC_IMAGE, 420 THUMB_B_IMAGE 421 }; 422 423 extern font_info *get_theme_font(int widget_type, uint16 &style); 424 425 extern uint32 get_theme_color(int widget_type, int state, int which = 0); 426 extern SDL_Surface* get_theme_image(int widget_type, int state, int which, int width = 0, int height = 0); 427 extern bool use_theme_images(int widget_type); 428 extern bool use_theme_color(int widget_type, int which); 429 extern int get_theme_space(int widget_type, int which = 0); 430 431 extern void dialog_ok(void *arg); 432 extern void dialog_cancel(void *arg); 433 434 // ZZZ: some more handy callbacks 435 class w_text_entry; 436 extern void dialog_try_ok(w_text_entry* text_entry); 437 extern void dialog_disable_ok_if_empty(w_text_entry* inTextEntry); 438 439 #endif 440