Remove hard limitation that AI wonder cities never build settlers
[freeciv.git] / client / gui-sdl2 / chatline.c
blob3b6f546d3526d8cdb6ffeabd217c3985ca6d25e0
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 /***********************************************************************
15 chatline.c - description
16 -------------------
17 begin : Sun Jun 30 2002
18 copyright : (C) 2002 by Rafał Bursig
19 email : Rafał Bursig <bursig@poczta.fm>
20 ***********************************************************************/
22 #ifdef HAVE_CONFIG_H
23 #include <fc_config.h>
24 #endif
26 /* SDL2 */
27 #ifdef SDL2_PLAIN_INCLUDE
28 #include <SDL.h>
29 #else /* SDL2_PLAIN_INCLUDE */
30 #include <SDL2/SDL.h>
31 #endif /* SDL2_PLAIN_INCLUDE */
33 /* utility */
34 #include "fcintl.h"
35 #include "log.h"
37 /* common */
38 #include "game.h"
39 #include "packets.h"
41 /* client */
42 #include "client_main.h"
43 #include "clinet.h"
44 #include "connectdlg_common.h"
46 /* gui-sdl2 */
47 #include "colors.h"
48 #include "dialogs.h"
49 #include "graphics.h"
50 #include "gui_iconv.h"
51 #include "gui_id.h"
52 #include "gui_main.h"
53 #include "gui_tilespec.h"
54 #include "mapview.h"
55 #include "messagewin.h"
56 #include "pages.h"
57 #include "themespec.h"
58 #include "unistring.h"
59 #include "utf8string.h"
60 #include "widget.h"
62 #include "chatline.h"
64 #define PTSIZE_LOG_FONT adj_font(10)
66 struct CONNLIST {
67 struct ADVANCED_DLG *pUsers_Dlg;
68 struct ADVANCED_DLG *pChat_Dlg;
69 struct widget *pBeginWidgetList;
70 struct widget *pEndWidgetList;
71 struct widget *pStartButton;
72 struct widget *pSelectNationButton;
73 struct widget *pLoadGameButton;
74 struct widget *pConfigure;
75 struct widget *pBackButton;
76 struct widget *pEdit;
77 int text_width;
78 int active;
79 } *pConnDlg = NULL;
81 static void popup_conn_list_dialog(void);
82 static void add_to_chat_list(char *msg, size_t n_alloc);
84 /**************************************************************************
85 LOAD GAME
86 **************************************************************************/
88 struct ADVANCED_DLG *pLoadDialog;
90 /**************************************************************************
91 User event to load game dialog window.
92 **************************************************************************/
93 static int move_load_game_dlg_callback(struct widget *pWindow)
95 if (Main.event.button.button == SDL_BUTTON_LEFT) {
96 move_window_group(pLoadDialog->pBeginWidgetList, pWindow);
99 return -1;
102 /**************************************************************************
103 Close load game dialog
104 **************************************************************************/
105 void popdown_load_game_dialog(void)
107 if (pLoadDialog) {
108 popdown_window_group_dialog(pLoadDialog->pBeginWidgetList, pLoadDialog->pEndWidgetList);
109 FC_FREE(pLoadDialog->pScroll);
110 FC_FREE(pLoadDialog);
112 /* enable buttons */
113 set_wstate(pConnDlg->pBackButton, FC_WS_NORMAL);
114 widget_redraw(pConnDlg->pBackButton);
115 widget_mark_dirty(pConnDlg->pBackButton);
116 set_wstate(pConnDlg->pLoadGameButton, FC_WS_NORMAL);
117 widget_redraw(pConnDlg->pLoadGameButton);
118 widget_mark_dirty(pConnDlg->pLoadGameButton);
119 set_wstate(pConnDlg->pStartButton, FC_WS_NORMAL);
120 widget_redraw(pConnDlg->pStartButton);
121 widget_mark_dirty(pConnDlg->pStartButton);
123 flush_dirty();
127 /**************************************************************************
128 User clicked load game dialog close-button.
129 **************************************************************************/
130 static int exit_load_dlg_callback(struct widget *pWidget)
132 if (Main.event.button.button == SDL_BUTTON_LEFT) {
133 if (get_client_page() == PAGE_LOAD) {
134 set_client_page(PAGE_START);
135 } else {
136 popdown_load_game_dialog();
140 return -1;
143 /**************************************************************************
144 User selected file to load.
145 **************************************************************************/
146 static int load_selected_game_callback(struct widget *pWidget)
148 if (Main.event.button.button == SDL_BUTTON_LEFT) {
149 char *filename = (char*)pWidget->data.ptr;
151 if (is_server_running()) {
152 send_chat_printf("/load %s", filename);
154 if (get_client_page() == PAGE_LOAD) {
155 set_client_page(PAGE_START);
156 } else if (get_client_page() == PAGE_START) {
157 popdown_load_game_dialog();
159 } else {
160 set_client_page(PAGE_MAIN);
164 return -1;
167 /**************************************************************************
168 Open load game dialog
169 **************************************************************************/
170 static void popup_load_game_dialog(void)
172 struct widget *pWindow;
173 struct widget *pCloseButton;
174 struct widget *pFilenameLabel = NULL;
175 struct widget *pFirstLabel = NULL;
176 struct widget *pLastLabel = NULL;
177 struct widget *pNextLabel = NULL;
178 utf8_str *title, *filename;
179 SDL_Rect area;
180 struct fileinfo_list *files;
181 int count = 0;
182 int scrollbar_width = 0;
183 int max_label_width = 0;
185 if (pLoadDialog) {
186 return;
189 /* disable buttons */
190 set_wstate(pConnDlg->pBackButton, FC_WS_DISABLED);
191 widget_redraw(pConnDlg->pBackButton);
192 widget_mark_dirty(pConnDlg->pBackButton);
193 set_wstate(pConnDlg->pLoadGameButton, FC_WS_DISABLED);
194 widget_redraw(pConnDlg->pLoadGameButton);
195 widget_mark_dirty(pConnDlg->pLoadGameButton);
196 set_wstate(pConnDlg->pSelectNationButton, FC_WS_DISABLED);
197 widget_redraw(pConnDlg->pSelectNationButton);
198 widget_mark_dirty(pConnDlg->pSelectNationButton);
199 set_wstate(pConnDlg->pStartButton, FC_WS_DISABLED);
200 widget_redraw(pConnDlg->pStartButton);
201 widget_mark_dirty(pConnDlg->pStartButton);
203 /* create dialog */
204 pLoadDialog = fc_calloc(1, sizeof(struct ADVANCED_DLG));
206 title = create_utf8_from_char(_("Choose Saved Game to Load"), adj_font(12));
207 title->style |= TTF_STYLE_BOLD;
209 pWindow = create_window_skeleton(NULL, title, 0);
210 pWindow->action = move_load_game_dlg_callback;
211 set_wstate(pWindow, FC_WS_NORMAL);
213 add_to_gui_list(ID_WINDOW, pWindow);
215 pLoadDialog->pEndWidgetList = pWindow;
217 area = pWindow->area;
219 /* close button */
220 pCloseButton = create_themeicon(current_theme->Small_CANCEL_Icon, pWindow->dst,
221 WF_WIDGET_HAS_INFO_LABEL
222 | WF_RESTORE_BACKGROUND);
223 pCloseButton->info_label = create_utf8_from_char(_("Close Dialog (Esc)"),
224 adj_font(12));
225 pCloseButton->action = exit_load_dlg_callback;
226 set_wstate(pCloseButton, FC_WS_NORMAL);
227 pCloseButton->key = SDLK_ESCAPE;
229 add_to_gui_list(ID_BUTTON, pCloseButton);
231 area.w += pCloseButton->size.w;
233 pLoadDialog->pBeginWidgetList = pCloseButton;
235 /* create scrollbar */
236 scrollbar_width = create_vertical_scrollbar(pLoadDialog, 1, 20, TRUE, TRUE);
237 hide_scrollbar(pLoadDialog->pScroll);
239 /* search for user saved games. */
240 files = fileinfolist_infix(get_save_dirs(), ".sav", FALSE);
241 fileinfo_list_iterate(files, pfile) {
242 count++;
244 filename = create_utf8_from_char(pfile->name, adj_font(13));
245 filename->style |= SF_CENTER;
246 pFilenameLabel = create_iconlabel(NULL, pWindow->dst, filename,
247 (WF_FREE_DATA | WF_SELECT_WITHOUT_BAR | WF_RESTORE_BACKGROUND));
249 /* store filename */
250 pFilenameLabel->data.ptr = fc_calloc(1, strlen(pfile->fullname) + 1);
251 fc_strlcpy((char*)pFilenameLabel->data.ptr, pfile->fullname, strlen(pfile->fullname) + 1);
253 pFilenameLabel->action = load_selected_game_callback;
255 set_wstate(pFilenameLabel, FC_WS_NORMAL);
257 /* FIXME: this was supposed to be add_widget_to_vertical_scroll_widget_list(), but
258 * add_widget_to_vertical_scroll_widget_list() needs the scrollbar area to be defined
259 * for updating the scrollbar position, but the area is not known yet (depends on
260 * maximum label width) */
261 add_to_gui_list(ID_LABEL, pFilenameLabel);
263 if (count == 1) {
264 pFirstLabel = pFilenameLabel;
267 max_label_width = MAX(max_label_width, pFilenameLabel->size.w);
268 } fileinfo_list_iterate_end;
269 fileinfo_list_destroy(files);
271 pLastLabel = pFilenameLabel;
273 area.w = MAX(area.w, max_label_width + scrollbar_width + 1);
275 if (count > 0) {
276 area.h = (pLoadDialog->pScroll->active * pFilenameLabel->size.h) + adj_size(5);
279 resize_window(pWindow, theme_get_background(theme, BACKGROUND_LOADGAMEDLG),
280 NULL,
281 (pWindow->size.w - pWindow->area.w) + area.w,
282 (pWindow->size.h - pWindow->area.h) + area.h);
284 area = pWindow->area;
286 setup_vertical_scrollbar_area(pLoadDialog->pScroll,
287 area.x + area.w - 1,
288 area.y + 1,
289 area.h - adj_size(2), TRUE);
291 /* add filename labels to list */
292 pFilenameLabel = pFirstLabel;
293 while (pFilenameLabel) {
294 pFilenameLabel->size.w = area.w - scrollbar_width - 3;
296 pNextLabel = pFilenameLabel->prev;
298 del_widget_pointer_from_gui_list(pFilenameLabel);
299 if (pFilenameLabel == pFirstLabel) {
300 add_widget_to_vertical_scroll_widget_list(pLoadDialog,
301 pFilenameLabel, pCloseButton,
302 FALSE,
303 area.x + 1,
304 area.y + adj_size(2));
305 } else {
306 add_widget_to_vertical_scroll_widget_list(pLoadDialog,
307 pFilenameLabel,
308 pLoadDialog->pBeginActiveWidgetList,
309 FALSE,
310 area.x + 1,
311 area.y + adj_size(2));
314 if (pFilenameLabel == pLastLabel) {
315 break;
318 pFilenameLabel = pNextLabel;
321 widget_set_position(pWindow,
322 (main_window_width() - pWindow->size.w) / 2,
323 (main_window_height() - pWindow->size.h) / 2);
325 widget_set_position(pCloseButton,
326 area.x + area.w - pCloseButton->size.w - 1,
327 pWindow->size.y + adj_size(2));
329 /* FIXME: the scrollbar already got a background saved in
330 * add_widget_to_vertical_scroll_widget_list(), but the window
331 * is not drawn yet, so this saved background is wrong.
332 * Deleting it here as a workaround. */
333 FREESURFACE(pLoadDialog->pScroll->pScrollBar->gfx);
335 redraw_group(pLoadDialog->pBeginWidgetList, pWindow, 1);
336 flush_dirty();
339 /**************************************************************************
340 Sent msg/command from input dlg to server
341 **************************************************************************/
342 static int inputline_return_callback(struct widget *pWidget)
344 if (Main.event.type == SDL_KEYDOWN
345 && (Main.event.key.keysym.sym == SDLK_RETURN
346 || Main.event.key.keysym.sym == SDLK_KP_ENTER)) {
348 if (pWidget->string_utf8->text == NULL) {
349 return -1;
352 if (pWidget->string_utf8->text[0] != '\0') {
353 send_chat(pWidget->string_utf8->text);
355 output_window_append(ftc_any, pWidget->string_utf8->text);
359 return -1;
362 /**************************************************************************
363 This function is main chat/command client input.
364 **************************************************************************/
365 void popup_input_line(void)
367 struct widget *pInput_Edit;
369 pInput_Edit = create_edit_from_chars(NULL, Main.gui, "", adj_font(12),
370 adj_size(400), 0);
372 pInput_Edit->size.x = (main_window_width() - pInput_Edit->size.w) / 2;
373 pInput_Edit->size.y = (main_window_height() - pInput_Edit->size.h) / 2;
375 if (edit(pInput_Edit) != ED_ESC) {
376 inputline_return_callback(pInput_Edit);
379 widget_undraw(pInput_Edit);
380 widget_mark_dirty(pInput_Edit);
381 FREEWIDGET(pInput_Edit);
383 flush_dirty();
386 /**************************************************************************
387 Appends the string to the chat output window. The string should be
388 inserted on its own line, although it will have no newline.
389 **************************************************************************/
390 void real_output_window_append(const char *astring,
391 const struct text_tag_list *tags,
392 int conn_id)
394 /* Currently this is a wrapper to the message subsystem. */
395 if (pConnDlg) {
396 size_t n = strlen(astring);
397 char *buffer = fc_strdup(astring);
399 add_to_chat_list(buffer, n);
400 } else {
401 meswin_add(astring, tags, NULL, E_CHAT_MSG);
405 /**************************************************************************
406 Get the text of the output window, and call write_chatline_content() to
407 log it.
408 **************************************************************************/
409 void log_output_window(void)
411 /* TODO */
414 /**************************************************************************
415 Clear all text from the output window.
416 **************************************************************************/
417 void clear_output_window(void)
419 /* TODO */
422 /* ====================================================================== */
424 /**************************************************************************
425 User did something to connection list dialog.
426 **************************************************************************/
427 static int conn_dlg_callback(struct widget *pWindow)
429 return -1;
432 /**************************************************************************
433 User selected to get back from connection list dialog.
434 **************************************************************************/
435 static int disconnect_conn_callback(struct widget *pWidget)
437 if (Main.event.button.button == SDL_BUTTON_LEFT) {
438 popdown_conn_list_dialog();
439 flush_dirty();
440 disconnect_from_server();
443 return -1;
446 /**************************************************************************
447 Handle chat messages when connection dialog open.
448 **************************************************************************/
449 static void add_to_chat_list(char *msg, size_t n_alloc)
451 utf8_str *pstr;
452 struct widget *pBuf, *pWindow = pConnDlg->pEndWidgetList;
454 fc_assert_ret(msg != NULL);
455 fc_assert_ret(n_alloc != 0);
457 pstr = create_utf8_str(msg, n_alloc, adj_font(12));
459 if (convert_utf8_str_to_const_surface_width(pstr, pConnDlg->text_width - adj_size(5))) {
460 utf8_str *pstr2;
461 int count = 0;
462 char **utf8_texts = create_new_line_utf8strs(pstr->text);
464 while (utf8_texts[count] != NULL) {
465 pstr2 = create_utf8_str(utf8_texts[count],
466 strlen(utf8_texts[count]) + 1, adj_font(12));
467 pstr2->bgcol = (SDL_Color) {0, 0, 0, 0};
468 pBuf = create_themelabel2(NULL, pWindow->dst,
469 pstr2, pConnDlg->text_width, 0,
470 (WF_RESTORE_BACKGROUND|WF_DRAW_TEXT_LABEL_WITH_SPACE));
472 pBuf->size.w = pConnDlg->text_width;
473 add_widget_to_vertical_scroll_widget_list(pConnDlg->pChat_Dlg, pBuf,
474 pConnDlg->pChat_Dlg->pBeginActiveWidgetList, FALSE,
475 pWindow->size.x + adj_size(10 + 60 + 10),
476 pWindow->size.y + adj_size(14));
477 count++;
479 redraw_group(pConnDlg->pChat_Dlg->pBeginWidgetList,
480 pConnDlg->pChat_Dlg->pEndWidgetList, TRUE);
481 FREEUTF8STR(pstr);
482 } else {
483 pstr->bgcol = (SDL_Color) {0, 0, 0, 0};
484 pBuf = create_themelabel2(NULL, pWindow->dst,
485 pstr, pConnDlg->text_width, 0,
486 (WF_RESTORE_BACKGROUND|WF_DRAW_TEXT_LABEL_WITH_SPACE));
488 pBuf->size.w = pConnDlg->text_width;
490 if (add_widget_to_vertical_scroll_widget_list(pConnDlg->pChat_Dlg, pBuf,
491 pConnDlg->pChat_Dlg->pBeginActiveWidgetList, FALSE,
492 pWindow->size.x + adj_size(10 + 60 + 10),
493 pWindow->size.y + adj_size(14))) {
494 redraw_group(pConnDlg->pChat_Dlg->pBeginWidgetList,
495 pConnDlg->pChat_Dlg->pEndWidgetList, TRUE);
496 } else {
497 widget_redraw(pBuf);
498 widget_mark_dirty(pBuf);
502 flush_dirty();
505 /**************************************************************************
506 User interacted with connection dialog input field.
507 **************************************************************************/
508 static int input_edit_conn_callback(struct widget *pWidget)
510 if (Main.event.type == SDL_KEYDOWN
511 && (Main.event.key.keysym.sym == SDLK_RETURN
512 || Main.event.key.keysym.sym == SDLK_KP_ENTER)) {
513 if (pWidget->string_utf8->text != NULL) {
514 if (pWidget->string_utf8->text[0] != '\0') {
515 send_chat(pWidget->string_utf8->text);
518 free(pWidget->string_utf8->text);
519 pWidget->string_utf8->text = fc_malloc(1);
520 pWidget->string_utf8->n_alloc = 0;
524 return -1;
527 /**************************************************************************
528 User interacted with Start Game button.
529 **************************************************************************/
530 static int start_game_callback(struct widget *pWidget)
532 if (Main.event.button.button == SDL_BUTTON_LEFT) {
533 send_chat("/start");
536 return -1;
539 /**************************************************************************
540 User interacted with Select Nation button.
541 **************************************************************************/
542 static int select_nation_callback(struct widget *pWidget)
544 if (Main.event.button.button == SDL_BUTTON_LEFT) {
545 popup_races_dialog(client.conn.playing);
548 return -1;
551 /* not implemented yet */
552 #if 0
553 /**************************************************************************
554 User interacted with Server Settings button.
555 **************************************************************************/
556 static int server_config_callback(struct widget *pWidget)
558 return -1;
560 #endif
562 /**************************************************************************
563 User interacted with Load Game button.
564 **************************************************************************/
565 static int load_game_callback(struct widget *pWidget)
567 if (Main.event.button.button == SDL_BUTTON_LEFT) {
568 /* set_wstate(pConnDlg->pLoadGameButton, FC_WS_NORMAL);
569 * widget_redraw(pConnDlg->pLoadGameButton);
570 * flush_dirty(); */
571 popup_load_game_dialog();
574 return -1;
577 /**************************************************************************
578 Update the connected users list at pregame state.
579 **************************************************************************/
580 void real_conn_list_dialog_update(void)
582 if (C_S_PREPARING == client_state()) {
583 if (pConnDlg) {
584 struct widget *pBuf = NULL, *pWindow = pConnDlg->pEndWidgetList;
585 utf8_str *pstr = create_utf8_str(NULL, 0, adj_font(12));
586 bool create;
588 pstr->bgcol = (SDL_Color) {0, 0, 0, 0};
590 if (pConnDlg->pUsers_Dlg) {
591 del_group(pConnDlg->pUsers_Dlg->pBeginActiveWidgetList,
592 pConnDlg->pUsers_Dlg->pEndActiveWidgetList);
593 pConnDlg->pUsers_Dlg->pActiveWidgetList = NULL;
594 pConnDlg->pUsers_Dlg->pBeginWidgetList =
595 pConnDlg->pUsers_Dlg->pScroll->pScrollBar;
596 pConnDlg->pUsers_Dlg->pScroll->count = 0;
597 } else {
598 pConnDlg->pUsers_Dlg = fc_calloc(1, sizeof(struct ADVANCED_DLG));
599 pConnDlg->pUsers_Dlg->pEndWidgetList = pConnDlg->pBeginWidgetList;
600 pConnDlg->pUsers_Dlg->pBeginWidgetList = pConnDlg->pBeginWidgetList;
602 create_vertical_scrollbar(pConnDlg->pUsers_Dlg, 1,
603 pConnDlg->active, TRUE, TRUE);
604 pConnDlg->pUsers_Dlg->pEndWidgetList =
605 pConnDlg->pUsers_Dlg->pEndWidgetList->prev;
606 setup_vertical_scrollbar_area(pConnDlg->pUsers_Dlg->pScroll,
607 pWindow->size.x + pWindow->size.w - adj_size(30),
608 pWindow->size.y + adj_size(14), pWindow->size.h - adj_size(44) - adj_size(40), FALSE);
611 hide_scrollbar(pConnDlg->pUsers_Dlg->pScroll);
612 create = TRUE;
613 conn_list_iterate(game.est_connections, pconn) {
614 copy_chars_to_utf8_str(pstr, pconn->username);
616 pBuf = create_themelabel2(NULL, pWindow->dst, pstr, adj_size(100), 0,
617 (WF_RESTORE_BACKGROUND|WF_DRAW_TEXT_LABEL_WITH_SPACE));
618 clear_wflag(pBuf, WF_FREE_STRING);
620 pBuf->ID = ID_LABEL;
622 /* add to widget list */
623 if (create) {
624 add_widget_to_vertical_scroll_widget_list(pConnDlg->pUsers_Dlg,
625 pBuf, pConnDlg->pUsers_Dlg->pBeginWidgetList, FALSE,
626 pWindow->area.x + pWindow->area.w - adj_size(130),
627 pWindow->size.y + adj_size(14));
628 create = FALSE;
629 } else {
630 add_widget_to_vertical_scroll_widget_list(pConnDlg->pUsers_Dlg,
631 pBuf, pConnDlg->pUsers_Dlg->pBeginActiveWidgetList, FALSE,
632 pWindow->area.x + pWindow->area.w - adj_size(130),
633 pWindow->size.y + adj_size(14));
635 } conn_list_iterate_end;
637 pConnDlg->pBeginWidgetList = pConnDlg->pUsers_Dlg->pBeginWidgetList;
638 FREEUTF8STR(pstr);
640 /* FIXME: implement the server settings dialog and then reactivate this part */
641 #if 0
642 if (ALLOW_CTRL == client.conn.access_level
643 || ALLOW_HACK == client.conn.access_level) {
644 set_wstate(pConnDlg->pConfigure, FC_WS_NORMAL);
645 } else {
646 set_wstate(pConnDlg->pConfigure, FC_WS_DISABLED);
648 #endif
650 /* redraw */
651 redraw_group(pConnDlg->pBeginWidgetList, pConnDlg->pEndWidgetList, 0);
653 widget_flush(pConnDlg->pEndWidgetList);
654 } else {
655 popup_conn_list_dialog();
658 /* PAGE_LOAD -> the server was started from the main page to load a game */
659 if (get_client_page() == PAGE_LOAD) {
660 popup_load_game_dialog();
662 } else {
663 if (popdown_conn_list_dialog()) {
664 flush_dirty();
669 /**************************************************************************
670 Open connection list dialog
671 **************************************************************************/
672 static void popup_conn_list_dialog(void)
674 SDL_Color window_bg_color = {255, 255, 255, 96};
676 struct widget *pWindow = NULL, *pBuf = NULL, *pLabel = NULL;
677 struct widget* pBackButton = NULL;
678 struct widget *pStartGameButton = NULL;
679 struct widget *pSelectNationButton = NULL;
680 /* struct widget *pServerSettingsButton = NULL;*/
681 utf8_str *pstr = NULL;
682 int n;
683 SDL_Rect area;
684 SDL_Surface *pSurf;
686 if (pConnDlg || !client.conn.established) {
687 return;
690 meswin_dialog_popdown();
692 pConnDlg = fc_calloc(1, sizeof(struct CONNLIST));
694 pWindow = create_window_skeleton(NULL, NULL, 0);
695 pWindow->action = conn_dlg_callback;
696 set_wstate(pWindow, FC_WS_NORMAL);
697 clear_wflag(pWindow, WF_DRAW_FRAME_AROUND_WIDGET);
699 pConnDlg->pEndWidgetList = pWindow;
700 add_to_gui_list(ID_WINDOW, pWindow);
702 widget_set_position(pWindow, 0, 0);
704 /* create window background */
705 pSurf = theme_get_background(theme, BACKGROUND_CONNLISTDLG);
706 if (resize_window(pWindow, pSurf, NULL, main_window_width(), main_window_height())) {
707 FREESURFACE(pSurf);
710 pConnDlg->text_width = pWindow->size.w - adj_size(130) - adj_size(20) - adj_size(20);
712 /* chat area background */
713 area.x = adj_size(10);
714 area.y = adj_size(14);
715 area.w = pConnDlg->text_width + adj_size(20);
716 area.h = pWindow->size.h - adj_size(44) - adj_size(40);
717 fill_rect_alpha(pWindow->theme, &area, &window_bg_color);
719 create_frame(pWindow->theme,
720 area.x - 1, area.y - 1, area.w + 1, area.h + 1,
721 get_theme_color(COLOR_THEME_CONNLISTDLG_FRAME));
723 /* user list background */
724 area.x = pWindow->size.w - adj_size(130);
725 area.y = adj_size(14);
726 area.w = adj_size(120);
727 area.h = pWindow->size.h - adj_size(44) - adj_size(40);
728 fill_rect_alpha(pWindow->theme, &area, &window_bg_color);
730 create_frame(pWindow->theme,
731 area.x - 1, area.y - 1, area.w + 1, area.h + 1,
732 get_theme_color(COLOR_THEME_CONNLISTDLG_FRAME));
734 draw_frame(pWindow->theme, 0, 0, pWindow->theme->w, pWindow->theme->h);
736 /* -------------------------------- */
738 /* chat area */
740 pConnDlg->pChat_Dlg = fc_calloc(1, sizeof(struct ADVANCED_DLG));
742 n = conn_list_size(game.est_connections);
745 char cbuf[256];
747 fc_snprintf(cbuf, sizeof(cbuf), _("Total users logged in : %d"), n);
748 pstr = create_utf8_from_char(cbuf, adj_font(12));
751 pstr->bgcol = (SDL_Color) {0, 0, 0, 0};
753 pLabel = create_themelabel2(NULL, pWindow->dst,
754 pstr, pConnDlg->text_width, 0,
755 (WF_RESTORE_BACKGROUND|WF_DRAW_TEXT_LABEL_WITH_SPACE));
757 widget_set_position(pLabel, adj_size(10), adj_size(14));
759 add_to_gui_list(ID_LABEL, pLabel);
761 pConnDlg->pChat_Dlg->pBeginWidgetList = pLabel;
762 pConnDlg->pChat_Dlg->pEndWidgetList = pLabel;
763 pConnDlg->pChat_Dlg->pBeginActiveWidgetList = pConnDlg->pChat_Dlg->pBeginWidgetList;
764 pConnDlg->pChat_Dlg->pEndActiveWidgetList = pConnDlg->pChat_Dlg->pEndWidgetList;
766 n = (pWindow->size.h - adj_size(44) - adj_size(40)) / pLabel->size.h;
767 pConnDlg->active = n;
769 create_vertical_scrollbar(pConnDlg->pChat_Dlg, 1,
770 pConnDlg->active, TRUE, TRUE);
772 setup_vertical_scrollbar_area(pConnDlg->pChat_Dlg->pScroll,
773 adj_size(10) + pConnDlg->text_width + 1,
774 adj_size(14), pWindow->size.h - adj_size(44) - adj_size(40), FALSE);
775 hide_scrollbar(pConnDlg->pChat_Dlg->pScroll);
777 /* -------------------------------- */
779 /* input field */
781 pBuf = create_edit_from_chars(NULL, pWindow->dst, "",
782 adj_font(12), pWindow->size.w - adj_size(10) - adj_size(10),
783 (WF_RESTORE_BACKGROUND|WF_EDIT_LOOP));
785 pBuf->size.x = adj_size(10);
786 pBuf->size.y = pWindow->size.h - adj_size(40) - adj_size(5) - pBuf->size.h;
787 pBuf->action = input_edit_conn_callback;
788 set_wstate(pBuf, FC_WS_NORMAL);
789 pConnDlg->pEdit = pBuf;
790 add_to_gui_list(ID_EDIT, pBuf);
792 /* buttons */
794 pBuf = create_themeicon_button_from_chars(current_theme->BACK_Icon, pWindow->dst,
795 _("Back"), adj_font(12), 0);
796 pBuf->size.x = adj_size(10);
797 pBuf->size.y = pWindow->size.h - adj_size(10) - pBuf->size.h;
798 pConnDlg->pBackButton = pBuf;
799 pBuf->action = disconnect_conn_callback;
800 set_wstate(pBuf, FC_WS_NORMAL);
801 pBuf->key = SDLK_ESCAPE;
802 add_to_gui_list(ID_BUTTON, pBuf);
803 pBackButton = pBuf;
805 pBuf = create_themeicon_button_from_chars(current_theme->OK_Icon, pWindow->dst,
806 _("Start"), adj_font(12), 0);
807 pBuf->size.x = pWindow->size.w - adj_size(10) - pBuf->size.w;
808 pBuf->size.y = pBackButton->size.y;
809 pConnDlg->pStartButton = pBuf;
810 pBuf->action = start_game_callback;
811 set_wstate(pBuf, FC_WS_NORMAL);
812 add_to_gui_list(ID_BUTTON, pBuf);
813 pStartGameButton = pBuf;
815 pBuf = create_themeicon_button_from_chars(NULL, pWindow->dst,
816 _("Pick Nation"), adj_font(12), 0);
817 pBuf->size.h = pStartGameButton->size.h;
818 pBuf->size.x = pStartGameButton->size.x - adj_size(10) - pBuf->size.w;
819 pBuf->size.y = pStartGameButton->size.y;
820 pConnDlg->pSelectNationButton = pBuf;
821 pBuf->action = select_nation_callback;
822 set_wstate(pBuf, FC_WS_NORMAL);
823 add_to_gui_list(ID_BUTTON, pBuf);
824 pSelectNationButton = pBuf;
826 pBuf = create_themeicon_button_from_chars(NULL, pWindow->dst,
827 _("Load Game"), adj_font(12), 0);
828 pBuf->size.h = pSelectNationButton->size.h;
829 pBuf->size.x = pSelectNationButton->size.x - adj_size(10) - pBuf->size.w;
830 pBuf->size.y = pSelectNationButton->size.y;
831 pConnDlg->pLoadGameButton = pBuf;
832 pBuf->action = load_game_callback;
833 set_wstate(pBuf, FC_WS_NORMAL);
834 add_to_gui_list(ID_BUTTON, pBuf);
836 /* not implemented yet */
837 #if 0
838 pBuf = create_themeicon_button_from_chars(NULL, pWindow->dst,
839 _("Server Settings"),
840 adj_font(12), 0);
841 pBuf->size.h = pSelectNationButton->size.h;
842 pBuf->size.x = pSelectNationButton->size.x - adj_size(10) - pBuf->size.w;
843 pBuf->size.y = pSelectNationButton->size.y;
844 pConnDlg->pConfigure = pBuf;
845 pBuf->action = server_config_callback;
846 set_wstate(pBuf, FC_WS_DISABLED);
847 add_to_gui_list(ID_BUTTON, pBuf);
848 pServerSettingsButton = pBuf;
849 #endif
851 /* not implemented yet */
852 #if 0
853 pBuf = create_themeicon_button_from_chars(NULL, pWindow->dst->surface,
854 "?", adj_font(12), 0);
855 pBuf->size.y = pWindow->size.y + pWindow->size.h - (pBuf->size.h + 7);
856 pBuf->size.x = pWindow->size.x + pWindow->size.w - (pBuf->size.w + 10) - 5;
858 pBuf->action = client_config_callback;
859 set_wstate(pBuf, FC_WS_NORMAL);
860 add_to_gui_list(ID_BUTTON, pBuf);
861 #endif
863 pConnDlg->pBeginWidgetList = pBuf;
864 /* ------------------------------------------------------------ */
866 conn_list_dialog_update();
869 /**************************************************************************
870 Close connection list dialog.
871 **************************************************************************/
872 bool popdown_conn_list_dialog(void)
874 if (pConnDlg) {
875 if (get_wstate(pConnDlg->pEdit) == FC_WS_PRESSED) {
876 force_exit_from_event_loop();
879 popdown_window_group_dialog(pConnDlg->pBeginWidgetList,
880 pConnDlg->pEndWidgetList);
881 if (pConnDlg->pUsers_Dlg) {
882 FC_FREE(pConnDlg->pUsers_Dlg->pScroll);
883 FC_FREE(pConnDlg->pUsers_Dlg);
886 if (pConnDlg->pChat_Dlg) {
887 FC_FREE(pConnDlg->pChat_Dlg->pScroll);
888 FC_FREE(pConnDlg->pChat_Dlg);
891 FC_FREE(pConnDlg);
893 return TRUE;
896 return FALSE;
899 /**************************************************************************
900 Got version message from metaserver thread.
901 **************************************************************************/
902 void version_message(const char *vertext)
904 output_window_append(ftc_client, vertext);