Freeciv-3.1
Loading...
Searching...
No Matches
wldlg.c
Go to the documentation of this file.
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.
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 wldlg.c - description
15 -------------------
16 begin : Wed Sep 18 2002
17 copyright : (C) 2002 by Rafał Bursig
18 email : Rafał Bursig <bursig@poczta.fm>
19***********************************************************************/
20
21#ifdef HAVE_CONFIG_H
22#include <fc_config.h>
23#endif
24
25#include <stdlib.h>
26
27/* SDL2 */
28#ifdef SDL2_PLAIN_INCLUDE
29#include <SDL.h>
30#else /* SDL2_PLAIN_INCLUDE */
31#include <SDL2/SDL.h>
32#endif /* SDL2_PLAIN_INCLUDE */
33
34/* utility */
35#include "fcintl.h"
36#include "log.h"
37
38/* common */
39#include "game.h"
40#include "movement.h"
41#include "unit.h"
42
43/* client */
44#include "client_main.h"
45#include "climisc.h"
46#include "global_worklist.h"
47
48/* gui-sdl2 */
49#include "citydlg.h"
50#include "colors.h"
51#include "graphics.h"
52#include "gui_id.h"
53#include "gui_main.h"
54#include "gui_tilespec.h"
55#include "helpdlg.h"
56#include "mapview.h"
57#include "sprite.h"
58#include "themespec.h"
59#include "widget.h"
60
61#include "wldlg.h"
62
63#define TARGETS_COL 4
64#define TARGETS_ROW 4
65
89
90
91static int worklist_editor_item_callback(struct widget *pwidget);
92static SDL_Surface *get_progress_icon(int stock, int cost, int *progress);
93static const char *get_production_name(struct city *pcity,
94 struct universal prod, int *cost);
95static void refresh_worklist_count_label(void);
96static void refresh_production_label(int stock);
97
98/* =========================================================== */
99
100/**********************************************************************/
103static int window_worklist_editor_callback(struct widget *pwidget)
104{
105 return -1;
106}
107
108/**********************************************************************/
111static int popdown_worklist_editor_callback(struct widget *pwidget)
112{
115 }
116
117 return -1;
118}
119
120/**********************************************************************/
124static int ok_worklist_editor_callback(struct widget *pwidget)
125{
127 int i, j;
128 struct city *pcity = editor->pcity;
129
130 /* remove duplicate entry of impv./wonder target from worklist */
131 for (i = 0; i < worklist_length(&editor->worklist_copy); i++) {
132 if (VUT_IMPROVEMENT == editor->worklist_copy.entries[i].kind) {
133 for (j = i + 1; j < worklist_length(&editor->worklist_copy); j++) {
134 if (VUT_IMPROVEMENT == editor->worklist_copy.entries[j].kind
135 && editor->worklist_copy.entries[i].value.building ==
136 editor->worklist_copy.entries[j].value.building) {
137 worklist_remove(&editor->worklist_copy, j);
138 }
139 }
140 }
141 }
142
143 if (pcity) {
144 /* remove duplicate entry of currently building impv./wonder from worklist */
145 if (VUT_IMPROVEMENT == editor->currently_building.kind) {
146 for (i = 0; i < worklist_length(&editor->worklist_copy); i++) {
147 if (VUT_IMPROVEMENT == editor->worklist_copy.entries[i].kind
148 && editor->worklist_copy.entries[i].value.building ==
149 editor->currently_building.value.building) {
150 worklist_remove(&editor->worklist_copy, i);
151 }
152 }
153 }
154
155 /* change production */
156 if (!are_universals_equal(&pcity->production, &editor->currently_building)) {
157 city_change_production(pcity, &editor->currently_building);
158 }
159
160 /* commit new city worklist */
161 city_set_worklist(pcity, &editor->worklist_copy);
162 } else {
163 /* commit global worklist */
164 struct global_worklist *gwl = global_worklist_by_id(editor->global_worklist_id);
165
166 if (gwl) {
167 global_worklist_set(gwl, &editor->worklist_copy);
168 global_worklist_set_name(gwl, editor->worklist_name);
170 }
171 }
172
173 /* popdown dialog */
175 }
176
177 return -1;
178}
179
180/**********************************************************************/
183static int rename_worklist_editor_callback(struct widget *pwidget)
184{
186 if (pwidget->string_utf8->text != NULL) {
187 fc_snprintf(editor->worklist_name, MAX_LEN_NAME, "%s",
188 pwidget->string_utf8->text);
189 } else {
190 /* empty input -> restore previous content */
191 copy_chars_to_utf8_str(pwidget->string_utf8, editor->worklist_name);
192 widget_redraw(pwidget);
193 widget_mark_dirty(pwidget);
194 flush_dirty();
195 }
196 }
197
198 return -1;
199}
200
201/* ====================================================================== */
202
203/**********************************************************************/
206static void add_target_to_worklist(struct widget *target)
207{
208 struct widget *buf = NULL, *dock = NULL;
209 utf8_str *pstr = NULL;
210 int i;
211 struct universal prod = cid_decode(MAX_ID - target->id);
212
213 set_wstate(target, FC_WS_SELECTED);
214 widget_redraw(target);
215 widget_flush(target);
216
217 /* Deny adding currently building Impr/Wonder Target */
218 if (editor->pcity
219 && VUT_IMPROVEMENT == prod.kind
220 && are_universals_equal(&prod, &editor->currently_building)) {
221 return;
222 }
223
224 if (worklist_length(&editor->worklist_copy) >= MAX_LEN_WORKLIST - 1) {
225 return;
226 }
227
228 for (i = 0; i < worklist_length(&editor->worklist_copy); i++) {
229 if (VUT_IMPROVEMENT == prod.kind
230 && are_universals_equal(&prod, &editor->worklist_copy.entries[i])) {
231 return;
232 }
233 }
234
235 worklist_append(&editor->worklist_copy, &prod);
236
237 /* Create widget entry */
238 if (VUT_UTYPE == prod.kind) {
241 } else {
243 prod.value.building),
245 }
246
247 pstr->style |= SF_CENTER;
248 buf = create_iconlabel(NULL, target->dst, pstr,
250
253
254 buf->data.ptr = fc_calloc(1, sizeof(int));
255 *((int *)buf->data.ptr) = worklist_length(&editor->worklist_copy) - 1;
256
257 buf->id = MAX_ID - cid_encode(prod);
258
259 if (editor->work->begin_active_widget_list) {
260 dock = editor->work->begin_active_widget_list;
261 } else {
262 dock = editor->dock;
263 }
264
265/* FIXME */
266#if 0
267 if (worklist_length(&editor->worklist_copy) > editor->work->scroll->active + 1) {
268
270 editor->end_widget_list->area.x + adj_size(2),
272 editor->work->scroll->up_left_button->size.h + 1,
273 adj_size(126), 0, editor->work->begin_widget_list,
274 editor->work->end_widget_list);
275
277 editor->end_widget_list->area.x + adj_size(2),
279 adj_size(225), FALSE);
280
281 show_scrollbar(editor->work->scroll);
282 }
283#endif /* 0 */
284
286 dock, FALSE,
287 editor->end_widget_list->area.x + adj_size(2),
288 editor->end_widget_list->area.y + adj_size(152));
289
290 buf->size.w = adj_size(126);
291
293 redraw_group(editor->work->begin_widget_list,
294 editor->work->end_widget_list, TRUE);
295 flush_dirty();
296}
297
298/**********************************************************************/
303static bool are_prods_same_class(const struct universal *one,
304 const struct universal *two)
305{
306 if (one->kind != two->kind) {
307 return FALSE;
308 }
309
310 if (VUT_IMPROVEMENT == one->kind) {
311 if (is_wonder(one->value.building)) {
312 return is_wonder(two->value.building);
313 } else {
314 return !is_wonder(two->value.building);
315 }
316 }
317
318 return FALSE;
319}
320
321/**********************************************************************/
325static void change_production(struct universal *prod)
326{
327 if (!are_prods_same_class(&editor->currently_building, prod)) {
328 if (editor->stock != editor->pcity->shield_stock) {
329 if (are_prods_same_class(&editor->pcity->production, prod)) {
330 editor->stock = editor->pcity->shield_stock;
331 }
332 } else {
333 editor->stock =
335 }
336 }
337
338 editor->currently_building = *prod;
340}
341
342/**********************************************************************/
350static void add_target_to_production(struct widget *target)
351{
352 int dummy;
353 struct universal prod;
354
355 fc_assert_ret(target != NULL);
356
357 /* redraw Target Icon */
358 set_wstate(target, FC_WS_SELECTED);
359 widget_redraw(target);
360 widget_flush(target);
361
362 prod = cid_decode(MAX_ID - target->id);
363
364 /* check if we change to the same target */
365 if (are_universals_equal(&prod, &editor->currently_building)) {
366 /* comit changes and exit - double click detection */
368 return;
369 }
370
371 change_production(&prod);
372
373 /* change Production Text Label in Worklist Widget list */
374 copy_chars_to_utf8_str(editor->work->end_active_widget_list->string_utf8,
375 get_production_name(editor->pcity, prod, &dummy));
376
377 editor->work->end_active_widget_list->id = MAX_ID - cid_encode(prod);
378
379 widget_redraw(editor->work->end_active_widget_list);
380 widget_mark_dirty(editor->work->end_active_widget_list);
381
382 flush_dirty();
383}
384
385/**********************************************************************/
388static void get_target_help_data(struct widget *target)
389{
390 struct universal prod;
391
392 fc_assert_ret(target != NULL);
393
394 /* redraw Target Icon */
395 set_wstate(target, FC_WS_SELECTED);
396 widget_redraw(target);
397 /*widget_flush(target);*/
398
399 prod = cid_decode(MAX_ID - target->id);
400
401 if (VUT_UTYPE == prod.kind) {
403 } else {
405 }
406}
407
408/**********************************************************************/
415static int worklist_editor_targets_callback(struct widget *pwidget)
416{
417 if (main_data.event.type == SDL_MOUSEBUTTONDOWN) {
418 switch (main_data.event.button.button) {
419 case SDL_BUTTON_LEFT:
420 if (editor->pcity) {
422 } else {
423 add_target_to_worklist(pwidget);
424 }
425 break;
426 case SDL_BUTTON_MIDDLE:
427 get_target_help_data(pwidget);
428 break;
429 case SDL_BUTTON_RIGHT:
430 add_target_to_worklist(pwidget);
431 break;
432 default:
433 /* do nothing */
434 break;
435 }
436 } else if (PRESSED_EVENT(main_data.event)) {
437 if (editor->pcity) {
439 } else {
440 add_target_to_worklist(pwidget);
441 }
442 }
443
444 return -1;
445}
446
447/* ====================================================================== */
448
449/**********************************************************************/
455{
456 /* only one item (production) is left */
457 if (worklist_is_empty(&editor->worklist_copy)) {
458 return;
459 }
460
461 if (item->data.ptr) {
462 /* correct "data" widget fields */
463 struct widget *buf = item;
464
465 if (buf != editor->work->begin_active_widget_list) {
466 do {
467 buf = buf->prev;
468 *((int *)buf->data.ptr) = *((int *)buf->data.ptr) - 1;
469 } while (buf != editor->work->begin_active_widget_list);
470 }
471
472 /* remove element from worklist */
473 worklist_remove(&editor->worklist_copy, *((int *)item->data.ptr));
474
475 /* remove widget from widget list */
477 } else {
478 /* change productions to first worklist element */
479 struct widget *buf = item->prev;
480
481 change_production(&editor->worklist_copy.entries[0]);
482 worklist_advance(&editor->worklist_copy);
484 FC_FREE(buf->data.ptr);
485 if (buf != editor->work->begin_active_widget_list) {
486 do {
487 buf = buf->prev;
488 *((int *)buf->data.ptr) = *((int *)buf->data.ptr) - 1;
489 } while (buf != editor->work->begin_active_widget_list);
490 }
491 }
492
493/* FIXME: fix scrollbar code */
494#if 0
495 /* worklist_length(&editor->worklist_copy): without production */
496 if (worklist_length(&editor->worklist_copy) <= editor->work->scroll->active + 1) {
497
499 editor->end_widget_list->area.x + adj_size(2),
501 adj_size(126), 0, editor->work->begin_widget_list,
502 editor->work->end_widget_list);
503#if 0
505 editor->end_widget_list->area.x + adj_size(2),
507 adj_size(225), FALSE);*/
508#endif /* 0 */
509 hide_scrollbar(editor->work->scroll);
510 }
511#endif /* 0 */
512
514 redraw_group(editor->work->begin_widget_list,
515 editor->work->end_widget_list, TRUE);
516 flush_dirty();
517}
518
519/**********************************************************************/
531{
532 char *text;
533 Uint16 id;
534 bool changed = FALSE;
535 struct universal tmp;
536
537 if (item == editor->work->begin_active_widget_list) {
539 return;
540 }
541
542 text = item->string_utf8->text;
543 id = item->id;
544
545 /* second item or higher was clicked */
546 if (item->data.ptr) {
547 /* worklist operations -> swap down */
548 int row = *((int *)item->data.ptr);
549
550 tmp = editor->worklist_copy.entries[row];
551 editor->worklist_copy.entries[row] = editor->worklist_copy.entries[row + 1];
552 editor->worklist_copy.entries[row + 1] = tmp;
553
554 changed = TRUE;
555 } else {
556 /* first item was clicked -> change production */
557 change_production(&editor->worklist_copy.entries[0]);
558 editor->worklist_copy.entries[0] = cid_decode(MAX_ID - id);
559 changed = TRUE;
560 }
561
562 if (changed) {
563 item->string_utf8->text = item->prev->string_utf8->text;
564 item->id = item->prev->id;
565
566 item->prev->string_utf8->text = text;
567 item->prev->id = id;
568
569 redraw_group(editor->work->begin_widget_list,
570 editor->work->end_widget_list, TRUE);
571 flush_dirty();
572 }
573}
574
575/**********************************************************************/
588{
589 char *text = item->string_utf8->text;
590 Uint16 id = item->id;
591 bool changed = FALSE;
592 struct universal tmp;
593
594 /* first item was clicked -> remove */
595 if (item == editor->work->end_active_widget_list) {
597
598 return;
599 }
600
601 /* third item or higher was clicked */
602 if (item->data.ptr && *((int *)item->data.ptr) > 0) {
603 /* worklist operations -> swap up */
604 int row = *((int *)item->data.ptr);
605
606 tmp = editor->worklist_copy.entries[row];
607 editor->worklist_copy.entries[row] = editor->worklist_copy.entries[row - 1];
608 editor->worklist_copy.entries[row - 1] = tmp;
609
610 changed = TRUE;
611 } else {
612 /* second item was clicked -> change production ... */
613 tmp = editor->currently_building;
614 change_production(&editor->worklist_copy.entries[0]);
615 editor->worklist_copy.entries[0] = tmp;
616
617 changed = TRUE;
618 }
619
620 if (changed) {
621 item->string_utf8->text = item->next->string_utf8->text;
622 item->id = item->next->id;
623
624 item->next->string_utf8->text = text;
625 item->next->id = id;
626
627 redraw_group(editor->work->begin_widget_list,
628 editor->work->end_widget_list, TRUE);
629 flush_dirty();
630 }
631}
632
633/**********************************************************************/
639static int worklist_editor_item_callback(struct widget *pwidget)
640{
641 if (main_data.event.type == SDL_MOUSEBUTTONDOWN) {
642 switch (main_data.event.button.button) {
643 case SDL_BUTTON_LEFT:
645 break;
646 case SDL_BUTTON_MIDDLE:
648 break;
649 case SDL_BUTTON_RIGHT:
651 break;
652 default:
653 ;/* do nothing */
654 break;
655 }
656 } else if (PRESSED_EVENT(main_data.event)) {
658 }
659
660 return -1;
661}
662/* ======================================================= */
663
664/**********************************************************************/
670static void add_global_worklist(struct widget *pwidget)
671{
672 struct global_worklist *gwl = global_worklist_by_id(MAX_ID - pwidget->id);
673 const struct worklist *pworklist;
674 int count, firstfree;
675
676 if (!gwl
677 || !(pworklist = global_worklist_get(gwl))
678 || worklist_is_empty(pworklist)) {
679 return;
680 }
681
682 if (worklist_length(&editor->worklist_copy) >= MAX_LEN_WORKLIST - 1) {
683 /* Worklist is full */
684 return;
685 }
686
687 firstfree = worklist_length(&editor->worklist_copy);
688 /* Copy global worklist to city worklist */
689 for (count = 0 ; count < worklist_length(pworklist); count++) {
690 struct widget *buf;
691
692 /* Global worklist can have targets unavilable in current state of game
693 then we must remove those targets from new city worklist */
694 if (!can_city_build_later(&(wld.map), editor->pcity, &pworklist->entries[count])) {
695 continue;
696 }
697
698 worklist_append(&editor->worklist_copy, &pworklist->entries[count]);
699
700 /* Create widget */
701 if (VUT_UTYPE == pworklist->entries[count].kind) {
702 buf = create_iconlabel(NULL, pwidget->dst,
704 utype_name_translation(pworklist->entries[count].value.utype),
707 buf->id = MAX_ID - cid_encode_unit(pworklist->entries[count].value.utype);
708 } else {
709 buf = create_iconlabel(NULL, pwidget->dst,
712 pworklist->entries[count].value.building),
715 buf->id = MAX_ID - cid_encode_building(pworklist->entries[count].value.building);
716 }
717
718 buf->string_utf8->style |= SF_CENTER;
721 buf->size.w = adj_size(126);
722 buf->data.ptr = fc_calloc(1, sizeof(int));
723 *((int *)buf->data.ptr) = firstfree;
724
726 buf, editor->work->begin_active_widget_list,
727 FALSE,
728 editor->end_widget_list->area.x + adj_size(2),
729 editor->end_widget_list->area.y + adj_size(152));
730
731 firstfree++;
732 if (firstfree == MAX_LEN_WORKLIST - 1) {
733 break;
734 }
735 }
736
738 redraw_group(editor->work->begin_widget_list,
739 editor->work->end_widget_list, TRUE);
740
741 flush_dirty();
742}
743
744/**********************************************************************/
749static void set_global_worklist(struct widget *pwidget)
750{
751 struct global_worklist *gwl = global_worklist_by_id(MAX_ID - pwidget->id);
752 struct widget *buf = editor->work->end_active_widget_list;
753 const struct worklist *pworklist;
754 struct worklist wl;
755 int count, wl_count;
756 struct universal target;
757
758 if (!gwl
759 || !(pworklist = global_worklist_get(gwl))
760 || worklist_is_empty(pworklist)) {
761 return;
762 }
763
764 /* clear tmp worklist */
765 worklist_init(&wl);
766
767 wl_count = 0;
768 /* copy global worklist to city worklist */
769 for (count = 0; count < worklist_length(pworklist); count++) {
770 /* global worklist can have targets unavilable in current state of game
771 then we must remove those targets from new city worklist */
772 if (!can_city_build_later(&(wld.map), editor->pcity, &pworklist->entries[count])) {
773 continue;
774 }
775
776 wl.entries[wl_count] = pworklist->entries[count];
777 wl_count++;
778 }
779 /* --------------------------------- */
780
781 if (!worklist_is_empty(&wl)) {
782 /* free old widget list */
783 if (buf != editor->work->begin_active_widget_list) {
784 buf = buf->prev;
785 if (buf != editor->work->begin_active_widget_list) {
786 do {
787 buf = buf->prev;
789 } while (buf != editor->work->begin_active_widget_list);
790 }
792 }
793 /* --------------------------------- */
794
795 worklist_copy(&editor->worklist_copy, &wl);
796
797 /* --------------------------------- */
798 /* Create new widget list */
799 for (count = 0; count < MAX_LEN_WORKLIST; count++) {
800 /* End of list */
801 if (!worklist_peek_ith(&editor->worklist_copy, &target, count)) {
802 break;
803 }
804
805 if (VUT_UTYPE == target.kind) {
806 buf = create_iconlabel(NULL, pwidget->dst,
810 buf->id = MAX_ID - B_LAST - utype_number(target.value.utype);
811 } else {
812 buf = create_iconlabel(NULL, pwidget->dst,
814 target.value.building),
817 buf->id = MAX_ID - improvement_number(target.value.building);
818 }
819 buf->string_utf8->style |= SF_CENTER;
822 buf->size.w = adj_size(126);
823 buf->data.ptr = fc_calloc(1, sizeof(int));
824 *((int *)buf->data.ptr) = count;
825
827 buf, editor->work->begin_active_widget_list, FALSE,
828 editor->end_widget_list->area.x + adj_size(2),
829 editor->end_widget_list->area.y + adj_size(152));
830 }
831
833 redraw_group(editor->work->begin_widget_list,
834 editor->work->end_widget_list, TRUE);
835
836 flush_dirty();
837 }
838}
839
840/**********************************************************************/
851static int global_worklist_callback(struct widget *pwidget)
852{
853 if (main_data.event.type == SDL_MOUSEBUTTONDOWN) {
854 switch (main_data.event.button.button) {
855 case SDL_BUTTON_LEFT:
856 add_global_worklist(pwidget);
857 break;
858 case SDL_BUTTON_MIDDLE:
859 /* nothing */
860 break;
861 case SDL_BUTTON_RIGHT:
862 set_global_worklist(pwidget);
863 break;
864 default:
865 /* do nothing */
866 break;
867 }
868 } else if (PRESSED_EVENT(main_data.event)) {
869 add_global_worklist(pwidget);
870 }
871
872 return -1;
873}
874
875/* ======================================================= */
876
877/**********************************************************************/
880static const char *get_production_name(struct city *pcity,
881 struct universal prod, int *cost)
882{
883 fc_assert_ret_val(cost != NULL, NULL);
884
885 *cost = universal_build_shield_cost(pcity, &prod);
886
887 if (VUT_UTYPE == prod.kind) {
889 } else {
891 }
892}
893
894/**********************************************************************/
900static SDL_Surface *get_progress_icon(int stock, int cost, int *progress)
901{
902 SDL_Surface *icon = NULL;
903 int width;
904
905 fc_assert_ret_val(progress != NULL, NULL);
906
907 if (stock < cost) {
908 width = ((float)stock / cost) * adj_size(116.0);
909 *progress = ((float)stock / cost) * 100.0;
910 if (!width && stock) {
911 *progress = 1;
912 width = 1;
913 }
914 } else {
915 width = adj_size(116);
916 *progress = 100;
917 }
918
920
921 if (width) {
922 SDL_Rect dst = {2,1,0,0};
923 SDL_Surface *buf = create_bcgnd_surf(current_theme->button, FC_WS_DISABLED, width,
924 adj_size(28));
925
926 alphablit(buf, NULL, icon, &dst, 255);
927 FREESURFACE(buf);
928 }
929
930 return icon;
931}
932
933/**********************************************************************/
937static void refresh_production_label(int stock)
938{
939 int cost, turns;
940 char cbuf[64];
941 SDL_Rect area;
942 bool gold_prod = improvement_has_flag(editor->currently_building.value.building,
943 IF_GOLD);
944 const char *name = get_production_name(editor->pcity,
945 editor->currently_building, &cost);
946
947 if (VUT_IMPROVEMENT == editor->currently_building.kind && gold_prod) {
948 int gold = MAX(0, editor->pcity->surplus[O_SHIELD]);
949
950 fc_snprintf(cbuf, sizeof(cbuf),
951 PL_("%s\n%d gold per turn",
952 "%s\n%d gold per turn", gold),
953 name, gold);
954 } else {
955 if (stock < cost) {
956 turns = city_turns_to_build(editor->pcity,
957 &editor->currently_building, TRUE);
958 if (turns == 999) {
959 fc_snprintf(cbuf, sizeof(cbuf), _("%s\nblocked!"), name);
960 } else {
961 fc_snprintf(cbuf, sizeof(cbuf), _("%s\n%d %s"),
962 name, turns, PL_("turn", "turns", turns));
963 }
964 } else {
965 fc_snprintf(cbuf, sizeof(cbuf), _("%s\nfinished!"), name);
966 }
967 }
968 copy_chars_to_utf8_str(editor->production_name->string_utf8, cbuf);
969
970 widget_undraw(editor->production_name);
971 remake_label_size(editor->production_name);
972
973 editor->production_name->size.x = editor->end_widget_list->area.x +
974 (adj_size(130) - editor->production_name->size.w)/2;
975
976 /* Can't just widget_mark_dirty(), as it may have reduced in size */
977 area.x = editor->end_widget_list->area.x; /* left edge of client area */
978 area.y = editor->production_name->size.y;
979 area.w = adj_size(130);
980 area.h = editor->production_name->size.h;
981 layer_rect_to_screen_rect(editor->end_widget_list->dst, &area);
982
983 if (get_wflags(editor->production_name) & WF_RESTORE_BACKGROUND) {
984 refresh_widget_background(editor->production_name);
985 }
986
987 widget_redraw(editor->production_name);
988 dirty_sdl_rect(&area);
989
990 FREESURFACE(editor->production_progress->theme);
991 editor->production_progress->theme =
992 get_progress_icon(stock, cost, &cost);
993
994 if (!gold_prod) {
995 fc_snprintf(cbuf, sizeof(cbuf), "%d%%" , cost);
996 } else {
997 fc_snprintf(cbuf, sizeof(cbuf), "-");
998 }
999 copy_chars_to_utf8_str(editor->production_progress->string_utf8, cbuf);
1000 widget_redraw(editor->production_progress);
1001 widget_mark_dirty(editor->production_progress);
1002}
1003
1004/**********************************************************************/
1008{
1009 char cbuf[64];
1010 SDL_Rect area;
1011 int len = worklist_length(&editor->worklist_copy);
1012
1013 if (editor->pcity != NULL) {
1014 len += 1; /* External entry from current production */
1015 }
1016
1017 fc_snprintf(cbuf, sizeof(cbuf),
1018 /* TRANS: length of worklist */
1019 PL_("( %d entry )", "( %d entries )", len), len);
1020 copy_chars_to_utf8_str(editor->worklist_counter->string_utf8, cbuf);
1021
1022 widget_undraw(editor->worklist_counter);
1023 remake_label_size(editor->worklist_counter);
1024
1025 editor->worklist_counter->size.x = editor->end_widget_list->area.x +
1026 (adj_size(130) - editor->worklist_counter->size.w)/2;
1027
1028 if (get_wflags(editor->worklist_counter) & WF_RESTORE_BACKGROUND) {
1029 refresh_widget_background(editor->worklist_counter);
1030 }
1031
1032 widget_redraw(editor->worklist_counter);
1033
1034 /* Can't just widget_mark_dirty(), as it may have reduced in size */
1035 area.x = editor->end_widget_list->area.x; /* left edge of client area */
1036 area.y = editor->worklist_counter->size.y;
1037 area.w = adj_size(130);
1038 area.h = editor->worklist_counter->size.h;
1039 layer_rect_to_screen_rect(editor->end_widget_list->dst, &area);
1040 dirty_sdl_rect(&area);
1041}
1042
1043/* ====================================================================== */
1044
1045/**********************************************************************/
1050void popup_worklist_editor(struct city *pcity, struct global_worklist *gwl)
1051{
1052 SDL_Color bg_color = {255,255,255,128};
1053 SDL_Color bg_color2 = {255,255,255,136};
1054 int count = 0, turns;
1055 int widget_w = 0, widget_h = 0;
1056 utf8_str *pstr = NULL;
1057 struct widget *buf = NULL, *pwindow, *last;
1058 SDL_Surface *text = NULL, *text_name = NULL, *zoomed = NULL;
1060 SDL_Surface *icon;
1061 SDL_Rect dst;
1062 char cbuf[128];
1063 struct unit_type *punittype = NULL;
1064 char *state = NULL;
1065 bool advanced_tech;
1066 bool can_build, can_eventually_build;
1067 SDL_Rect area;
1068 int len;
1069 const struct civ_map *nmap = &(wld.map);
1070
1071 if (editor) {
1072 return;
1073 }
1074
1075 editor = fc_calloc(1, sizeof(struct wl_editor));
1076
1077 if (pcity) {
1078 editor->pcity = pcity;
1079 editor->global_worklist_id = -1;
1080 editor->currently_building = pcity->production;
1081 editor->stock = pcity->shield_stock;
1082 worklist_copy(&editor->worklist_copy, &pcity->worklist);
1083 fc_snprintf(editor->worklist_name, sizeof(editor->worklist_name),
1084 "%s worklist", city_name_get(pcity));
1085 } else if (gwl != NULL) {
1086 editor->pcity = NULL;
1087 editor->global_worklist_id = global_worklist_id(gwl);
1088 worklist_copy(&editor->worklist_copy, global_worklist_get(gwl));
1089 sz_strlcpy(editor->worklist_name, global_worklist_name(gwl));
1090 } else {
1091 /* Not valid variant! */
1092 return;
1093 }
1094
1095 len = worklist_length(&editor->worklist_copy);
1096 advanced_tech = (pcity == NULL);
1097
1098 /* --------------- */
1099 /* create Target Background Icon */
1100 main_surf = create_surf(adj_size(116), adj_size(116), SDL_SWSURFACE);
1101 SDL_FillRect(main_surf, NULL, map_rgba(main_surf->format, bg_color));
1102
1103 create_frame(main_surf,
1104 0, 0, main_surf->w - 1, main_surf->h - 1,
1106
1107 /* ---------------- */
1108 /* Create Main Window */
1109 pwindow = create_window_skeleton(NULL, NULL, 0);
1110 pwindow->action = window_worklist_editor_callback;
1111 set_wstate(pwindow, FC_WS_NORMAL);
1112
1113 add_to_gui_list(ID_WINDOW, pwindow);
1114 editor->end_widget_list = pwindow;
1115
1116 area = pwindow->area;
1117
1118 /* ---------------- */
1119 if (pcity) {
1120 fc_snprintf(cbuf, sizeof(cbuf), _("Worklist of\n%s"), city_name_get(pcity));
1121 len += 1; /* External entry from current production */
1122 } else {
1123 fc_snprintf(cbuf, sizeof(cbuf), "%s", global_worklist_name(gwl));
1124 }
1125
1127 pstr->style |= (TTF_STYLE_BOLD|SF_CENTER);
1128
1129 buf = create_iconlabel(NULL, pwindow->dst, pstr, WF_RESTORE_BACKGROUND);
1130
1132 /* --------------------------- */
1133
1134 fc_snprintf(cbuf, sizeof(cbuf),
1135 /* TRANS: Length of worklist */
1136 PL_("( %d entry )", "( %d entries )", len), len);
1138 pstr->bgcol = (SDL_Color) {0, 0, 0, 0};
1139 buf = create_iconlabel(NULL, pwindow->dst, pstr, WF_RESTORE_BACKGROUND);
1140 editor->worklist_counter = buf;
1142 /* --------------------------- */
1143
1144 /* Create production progress label or rename worklist edit */
1145 if (pcity) {
1146 /* count == cost */
1147 /* turns == progress */
1148 const char *name = city_production_name_translation(pcity);
1149 bool gold_prod = city_production_has_flag(pcity, IF_GOLD);
1150
1151 count = city_production_build_shield_cost(pcity);
1152
1153 if (gold_prod) {
1154 int gold = MAX(0, pcity->surplus[O_SHIELD]);
1155
1156 fc_snprintf(cbuf, sizeof(cbuf),
1157 PL_("%s\n%d gold per turn",
1158 "%s\n%d gold per turn", gold),
1159 name, gold);
1160 } else {
1161 if (pcity->shield_stock < count) {
1162 turns = city_production_turns_to_build(pcity, TRUE);
1163 if (turns == 999) {
1164 fc_snprintf(cbuf, sizeof(cbuf), _("%s\nblocked!"), name);
1165 } else {
1166 fc_snprintf(cbuf, sizeof(cbuf), _("%s\n%d %s"),
1167 name, turns, PL_("turn", "turns", turns));
1168 }
1169 } else {
1170 fc_snprintf(cbuf, sizeof(cbuf), _("%s\nfinished!"), name);
1171 }
1172 }
1174 pstr->style |= SF_CENTER;
1175 buf = create_iconlabel(NULL, pwindow->dst, pstr, WF_RESTORE_BACKGROUND);
1176
1177 editor->production_name = buf;
1179
1180 icon = get_progress_icon(pcity->shield_stock, count, &turns);
1181
1182 if (!gold_prod) {
1183 fc_snprintf(cbuf, sizeof(cbuf), "%d%%" , turns);
1184 } else {
1185 fc_snprintf(cbuf, sizeof(cbuf), "-");
1186 }
1188 pstr->style |= (TTF_STYLE_BOLD|SF_CENTER);
1189
1190 buf = create_iconlabel(icon, pwindow->dst, pstr,
1192
1193 icon = NULL;
1194 turns = 0;
1195 editor->production_progress = buf;
1197 } else {
1198 buf = create_edit_from_chars_fonto(NULL, pwindow->dst,
1203
1205 }
1206
1207 /* --------------------------- */
1208 /* Commit Widget */
1209 buf = create_themeicon(current_theme->ok_icon, pwindow->dst, WF_RESTORE_BACKGROUND);
1210
1213 buf->key = SDLK_RETURN;
1214
1216 /* --------------------------- */
1217 /* Cancel Widget */
1218 buf = create_themeicon(current_theme->cancel_icon, pwindow->dst,
1220
1223 buf->key = SDLK_ESCAPE;
1224
1226 /* --------------------------- */
1227 /* work list */
1228
1229 /*
1230 pwidget->data filed will contains position of target in worklist all
1231 action on worklist (swap/romove/add) must correct this fields
1232
1233 Production Widget Label in worklist Widget list
1234 will have this field NULL
1235 */
1236
1237 editor->work = fc_calloc(1, sizeof(struct advanced_dialog));
1238
1239 editor->work->scroll = fc_calloc(1, sizeof(struct scroll_bar));
1240 editor->work->scroll->count = 0;
1241 editor->work->scroll->active = MAX_LEN_WORKLIST;
1242 editor->work->scroll->step = 1;
1243
1244/* FIXME: this should replace the 4 lines above, but
1245 * editor->work->end_widget_list is not set yet */
1246#if 0
1248#endif /* 0 */
1249
1250 if (pcity) {
1251 /* Production Widget Label */
1254 turns = city_production_build_shield_cost(pcity);
1255 pstr->style |= SF_CENTER;
1256 buf = create_iconlabel(NULL, pwindow->dst, pstr, WF_RESTORE_BACKGROUND);
1257
1260
1262
1263 editor->work->end_widget_list = buf;
1264 editor->work->begin_widget_list = buf;
1265 editor->work->end_active_widget_list = editor->work->end_widget_list;
1266 editor->work->begin_active_widget_list = editor->work->begin_widget_list;
1267 editor->work->scroll->count++;
1268 }
1269
1270 last = buf;
1271 editor->dock = buf;
1272
1273 /* Create Widget Labels of worklist entries */
1274
1275 count = 0;
1276
1277 worklist_iterate(&editor->worklist_copy, prod) {
1278 if (VUT_UTYPE == prod.kind) {
1279 pstr = create_utf8_from_char_fonto(utype_name_translation(prod.value.utype),
1281 } else {
1283 prod.value.building),
1285 }
1286 pstr->style |= SF_CENTER;
1287 buf = create_iconlabel(NULL, pwindow->dst, pstr,
1289
1292
1293 buf->data.ptr = fc_calloc(1, sizeof(int));
1294 *((int *)buf->data.ptr) = count;
1295
1296 add_to_gui_list(MAX_ID - cid_encode(prod), buf);
1297
1298 count++;
1299
1300 if (count > editor->work->scroll->active - 1) {
1301 set_wflag(buf, WF_HIDDEN);
1302 }
1303
1305
1306 if (count) {
1307 if (!pcity) {
1308 editor->work->end_widget_list = last->prev;
1309 editor->work->end_active_widget_list = editor->work->end_widget_list;
1310 }
1311 editor->work->begin_widget_list = buf;
1312 editor->work->begin_active_widget_list = editor->work->begin_widget_list;
1313 } else {
1314 if (!pcity) {
1315 editor->work->end_widget_list = last;
1316 }
1317 editor->work->begin_widget_list = last;
1318 }
1319
1320/* FIXME */
1321#if 0
1322 editor->work->active_widget_list = editor->work->end_active_widget_list;
1324 editor->work->scroll->active, FALSE, TRUE);
1325 editor->work->scroll->up_left_button->size.w = adj_size(122);
1326 editor->work->scroll->down_right_button->size.w = adj_size(122);
1327
1328 /* count: without production */
1329 if (count <= editor->work->scroll->active + 1) {
1330 if (count > 0) {
1331 struct widget *tmp = last;
1332
1333 do {
1334 tmp = tmp->prev;
1336 } while (tmp != buf);
1337 }
1338 hide_scrollbar(editor->work->scroll);
1339 }
1340#endif /* 0 */
1341
1342 editor->work->scroll->count += count;
1343 last = editor->work->begin_widget_list;
1344
1345 /* --------------------------- */
1346 /* Global worklists */
1347 if (pcity) {
1348 count = 0;
1349
1357 buf->string_utf8->style |= SF_CENTER;
1358 buf->action = global_worklist_callback;
1359 buf->string_utf8->fgcol = bg_color;
1360
1361 count++;
1362
1363 if (count > 4) {
1365 }
1367
1368 if (count) {
1369 editor->global = fc_calloc(1, sizeof(struct advanced_dialog));
1370 editor->global->end_widget_list = last->prev;
1371 editor->global->end_active_widget_list = editor->global->end_widget_list;
1372 editor->global->begin_widget_list = buf;
1373 editor->global->begin_active_widget_list = editor->global->begin_widget_list;
1374
1375 if (count > 6) {
1376 editor->global->active_widget_list = editor->global->end_active_widget_list;
1377
1378 create_vertical_scrollbar(editor->global, 1, 4, FALSE, TRUE);
1379 editor->global->scroll->up_left_button->size.w = adj_size(122);
1380 editor->global->scroll->down_right_button->size.w = adj_size(122);
1381 } else {
1382 struct widget *tmp = last;
1383
1384 do {
1385 tmp = tmp->prev;
1387 } while (tmp != buf);
1388 }
1389
1390 last = editor->global->begin_widget_list;
1391 }
1392 }
1393 /* ----------------------------- */
1394 count = 0;
1395 /* Targets units and imprv. to build */
1397 pstr->style |= (SF_CENTER|TTF_STYLE_BOLD);
1398 pstr->bgcol = (SDL_Color) {0, 0, 0, 0};
1399
1400 improvement_iterate(pimprove) {
1404
1405 /* If there's a city, can the city build the improvement? */
1406 if (pcity) {
1409 && can_city_build_improvement_later(pcity, pimprove);
1410 }
1411
1413 || (!advanced_tech && can_build)) {
1414
1416
1417 fc_snprintf(cbuf, sizeof(cbuf), "%s", improvement_name_translation(pimprove));
1419 pstr->style |= TTF_STYLE_BOLD;
1420
1421 if (pcity && is_improvement_redundant(pcity, pimprove)) {
1422 pstr->style |= TTF_STYLE_STRIKETHROUGH;
1423 }
1424
1426
1427 if (is_wonder(pimprove)) {
1428 if (improvement_obsolete(client.conn.playing, pimprove, pcity)) {
1429 state = _("Obsolete");
1430 } else if (is_great_wonder(pimprove)) {
1431 if (great_wonder_is_built(pimprove)) {
1432 state = _("Built");
1433 } else if (great_wonder_is_destroyed(pimprove)) {
1434 state = _("Destroyed");
1435 } else {
1436 state = _("Great Wonder");
1437 }
1438 } else if (is_small_wonder(pimprove)) {
1439 if (small_wonder_is_built(client.conn.playing, pimprove)) {
1440 state = _("Built");
1441 } else {
1442 state = _("Small Wonder");
1443 }
1444 }
1445 } else {
1446 state = NULL;
1447 }
1448
1449 if (pcity) {
1450 if (!improvement_has_flag(pimprove, IF_GOLD)) {
1451 struct universal univ = cid_production(cid_encode_building(pimprove));
1452 int cost = impr_build_shield_cost(pcity, pimprove);
1453
1454 turns = city_turns_to_build(pcity, &univ, TRUE);
1455
1456 if (turns == FC_INFINITY) {
1457 if (state) {
1458 fc_snprintf(cbuf, sizeof(cbuf), _("(%s)\n%d/%d %s\n%s"),
1459 state, pcity->shield_stock, cost,
1460 PL_("shield", "shields", cost),
1461 _("never"));
1462 } else {
1463 fc_snprintf(cbuf, sizeof(cbuf), _("%d/%d %s\n%s"),
1464 pcity->shield_stock, cost,
1465 PL_("shield", "shields", cost), _("never"));
1466 }
1467 } else {
1468 if (state) {
1469 fc_snprintf(cbuf, sizeof(cbuf), _("(%s)\n%d/%d %s\n%d %s"),
1470 state, pcity->shield_stock, cost,
1471 PL_("shield", "shields", cost),
1472 turns, PL_("turn", "turns", turns));
1473 } else {
1474 fc_snprintf(cbuf, sizeof(cbuf), _("%d/%d %s\n%d %s"),
1475 pcity->shield_stock, cost,
1476 PL_("shield", "shields", cost),
1477 turns, PL_("turn", "turns", turns));
1478 }
1479 }
1480 } else {
1481 /* capitalization */
1482 int gold = MAX(0, pcity->surplus[O_SHIELD]);
1483
1484 fc_snprintf(cbuf, sizeof(cbuf), PL_("%d gold per turn",
1485 "%d gold per turn", gold),
1486 gold);
1487 }
1488 } else {
1489 /* non city mode */
1490 if (!improvement_has_flag(pimprove, IF_GOLD)) {
1491 int cost = impr_build_shield_cost(NULL, pimprove);
1492
1493 if (state) {
1494 fc_snprintf(cbuf, sizeof(cbuf), _("(%s)\n%d %s"),
1495 state, cost,
1496 PL_("shield", "shields", cost));
1497 } else {
1498 fc_snprintf(cbuf, sizeof(cbuf), _("%d %s"),
1499 cost,
1500 PL_("shield", "shields", cost));
1501 }
1502 } else {
1503 fc_snprintf(cbuf, sizeof(cbuf), _("shields into gold"));
1504 }
1505 }
1506
1507 copy_chars_to_utf8_str(pstr, cbuf);
1508 pstr->style &= ~TTF_STYLE_BOLD;
1509 pstr->style &= ~TTF_STYLE_STRIKETHROUGH;
1510
1511 text = create_text_surf_from_utf8(pstr);
1512
1513 /*-----------------*/
1514
1515 zoomed = get_building_surface(pimprove);
1516 zoomed = zoomSurface(zoomed, DEFAULT_ZOOM * ((float)54 / zoomed->w),
1517 DEFAULT_ZOOM * ((float)54 / zoomed->w), 1);
1518 dst.x = (icon->w - zoomed->w) / 2;
1519 dst.y = (icon->h/2 - zoomed->h) / 2;
1520 alphablit(zoomed, NULL, icon, &dst, 255);
1521 dst.y += zoomed->h;
1522 FREESURFACE(zoomed);
1523
1524 dst.x = (icon->w - text_name->w) / 2;
1525 dst.y += ((icon->h - dst.y) - (text_name->h + text->h)) / 2;
1526 alphablit(text_name, NULL, icon, &dst, 255);
1527
1528 dst.x = (icon->w - text->w) / 2;
1529 dst.y += text_name->h;
1530 alphablit(text, NULL, icon, &dst, 255);
1531
1532 FREESURFACE(text);
1533 FREESURFACE(text_name);
1534
1535 buf = create_icon2(icon, pwindow->dst,
1538
1539 widget_w = MAX(widget_w, buf->size.w);
1540 widget_h = MAX(widget_h, buf->size.h);
1541
1542 buf->data.city = pcity;
1543 add_to_gui_list(MAX_ID - improvement_number(pimprove), buf);
1545
1546 if (count > (TARGETS_ROW * TARGETS_COL - 1)) {
1547 set_wflag(buf, WF_HIDDEN);
1548 }
1549 count++;
1550 }
1552
1553 /* ------------------------------ */
1554
1555 unit_type_iterate(un) {
1557 can_eventually_build =
1559
1560 /* If there's a city, can the city build the unit? */
1561 if (pcity) {
1562 can_build = can_build && can_city_build_unit_now(nmap, pcity, un);
1563 can_eventually_build = can_eventually_build
1564 && can_city_build_unit_later(nmap, pcity, un);
1565 }
1566
1567 if ((advanced_tech && can_eventually_build)
1568 || (!advanced_tech && can_build)) {
1569
1570 punittype = un;
1571
1572 icon = crop_rect_from_surface(main_surf, NULL);
1573
1574 fc_snprintf(cbuf, sizeof(cbuf), "%s", utype_name_translation(un));
1575
1576 copy_chars_to_utf8_str(pstr, cbuf);
1577 pstr->style |= TTF_STYLE_BOLD;
1578 text_name = create_text_surf_smaller_than_w(pstr, icon->w - 4);
1579
1580 if (pcity) {
1581 struct universal univ = cid_production(cid_encode_unit(un));
1582 int cost = utype_build_shield_cost(pcity, NULL, un);
1583
1584 turns = city_turns_to_build(pcity, &univ, TRUE);
1585
1586 if (turns == FC_INFINITY) {
1587 fc_snprintf(cbuf, sizeof(cbuf),
1588 _("(%d/%d/%s)\n%d/%d %s\nnever"),
1589 punittype->attack_strength,
1590 punittype->defense_strength,
1591 move_points_text(punittype->move_rate, TRUE),
1592 pcity->shield_stock, cost,
1593 PL_("shield", "shields", cost));
1594 } else {
1595 fc_snprintf(cbuf, sizeof(cbuf),
1596 _("(%d/%d/%s)\n%d/%d %s\n%d %s"),
1597 punittype->attack_strength,
1598 punittype->defense_strength,
1599 move_points_text(punittype->move_rate, TRUE),
1600 pcity->shield_stock, cost,
1601 PL_("shield", "shields", cost),
1602 turns, PL_("turn", "turns", turns));
1603 }
1604 } else {
1605 int cost = utype_build_shield_cost(NULL, client_player(), un);
1606
1607 fc_snprintf(cbuf, sizeof(cbuf),
1608 _("(%d/%d/%s)\n%d %s"),
1609 punittype->attack_strength,
1610 punittype->defense_strength,
1611 move_points_text(punittype->move_rate, TRUE),
1612 cost,
1613 PL_("shield", "shields", cost));
1614 }
1615
1616 copy_chars_to_utf8_str(pstr, cbuf);
1617 pstr->style &= ~TTF_STYLE_BOLD;
1618
1619 text = create_text_surf_from_utf8(pstr);
1620
1621 zoomed = adj_surf(get_unittype_surface(un, direction8_invalid()));
1622 dst.x = (icon->w - zoomed->w) / 2;
1623 dst.y = (icon->h / 2 - zoomed->h) / 2;
1624 alphablit(zoomed, NULL, icon, &dst, 255);
1625 FREESURFACE(zoomed);
1626
1627 dst.x = (icon->w - text_name->w) / 2;
1628 dst.y = icon->h / 2 + (icon->h / 2 - (text_name->h + text->h)) / 2;
1629 alphablit(text_name, NULL, icon, &dst, 255);
1630
1631 dst.x = (icon->w - text->w) / 2;
1632 dst.y += text_name->h;
1633 alphablit(text, NULL, icon, &dst, 255);
1634
1635 FREESURFACE(text);
1636 FREESURFACE(text_name);
1637
1638 buf = create_icon2(icon, pwindow->dst,
1641
1642 widget_w = MAX(widget_w, buf->size.w);
1643 widget_h = MAX(widget_h, buf->size.h);
1644
1645 buf->data.city = pcity;
1648
1649 if (count > (TARGETS_ROW * TARGETS_COL - 1)) {
1650 set_wflag(buf, WF_HIDDEN);
1651 }
1652 count++;
1653
1654 }
1656
1657 editor->targets = fc_calloc(1, sizeof(struct advanced_dialog));
1658
1659 editor->targets->end_widget_list = last->prev;
1660 editor->targets->begin_widget_list = buf;
1661 editor->targets->end_active_widget_list = editor->targets->end_widget_list;
1662 editor->targets->begin_active_widget_list = editor->targets->begin_widget_list;
1663 editor->targets->active_widget_list = editor->targets->end_active_widget_list;
1664
1665 /* --------------- */
1666 if (count > (TARGETS_ROW * TARGETS_COL - 1)) {
1667 count = create_vertical_scrollbar(editor->targets,
1669 } else {
1670 count = 0;
1671 }
1672 /* --------------- */
1673
1674 editor->begin_widget_list = editor->targets->begin_widget_list;
1675
1676 /* Window */
1677 area.w = MAX(area.w, widget_w * TARGETS_COL + count + adj_size(130));
1678 area.h = MAX(area.h, widget_h * TARGETS_ROW);
1679
1681 if (resize_window(pwindow, icon, NULL,
1682 (pwindow->size.w - pwindow->area.w) + area.w,
1683 (pwindow->size.h - pwindow->area.h) + area.h)) {
1684 FREESURFACE(icon);
1685 }
1686
1687 area = pwindow->area;
1688
1689 /* Backgrounds */
1690 dst.x = area.x;
1691 dst.y = area.y;
1692 dst.w = adj_size(130);
1693 dst.h = adj_size(145);
1694
1695 SDL_FillRect(pwindow->theme, &dst,
1696 map_rgba(pwindow->theme->format,
1698
1699 create_frame(pwindow->theme,
1700 dst.x, dst.y, dst.w - 1, dst.h - 1,
1702 create_frame(pwindow->theme,
1703 dst.x + 2, dst.y + 2, dst.w - 5, dst.h - 5,
1705
1706 dst.x = area.x;
1707 dst.y += dst.h + adj_size(2);
1708 dst.w = adj_size(130);
1709 dst.h = adj_size(228);
1710 fill_rect_alpha(pwindow->theme, &dst, &bg_color2);
1711
1712 create_frame(pwindow->theme,
1713 dst.x, dst.y, dst.w - 1, dst.h - 1,
1715
1716 if (editor->global) {
1717 dst.x = area.x;
1718 dst.y += dst.h + adj_size(2);
1719 dst.w = adj_size(130);
1720 dst.h = pwindow->size.h - dst.y - adj_size(4);
1721
1722 SDL_FillRect(pwindow->theme, &dst,
1723 map_rgba(pwindow->theme->format,
1725
1726 create_frame(pwindow->theme,
1727 dst.x, dst.y, dst.w - 1, dst.h - 1,
1729 create_frame(pwindow->theme,
1730 dst.x + adj_size(2), dst.y + adj_size(2),
1731 dst.w - adj_size(5), dst.h - adj_size(5),
1733 }
1734
1735 widget_set_position(pwindow,
1736 (main_window_width() - pwindow->size.w) / 2,
1737 (main_window_height() - pwindow->size.h) / 2);
1738
1739 /* name */
1740 buf = pwindow->prev;
1741 buf->size.x = area.x + (adj_size(130) - buf->size.w) / 2;
1742 buf->size.y = area.y + adj_size(4);
1743
1744 /* size of worklist (without production) */
1745 buf = buf->prev;
1746 buf->size.x = area.x + (adj_size(130) - buf->size.w) / 2;
1747 buf->size.y = buf->next->size.y + buf->next->size.h;
1748
1749 if (pcity) {
1750 /* current build and progress bar */
1751 buf = buf->prev;
1752 buf->size.x = area.x + (adj_size(130) - buf->size.w) / 2;
1753 buf->size.y = buf->next->size.y + buf->next->size.h + adj_size(5);
1754
1755 buf = buf->prev;
1756 buf->size.x = area.x + (adj_size(130) - buf->size.w) / 2;
1757 buf->size.y = buf->next->size.y + buf->next->size.h;
1758 } else {
1759 /* rename worklist */
1760 buf = buf->prev;
1761 buf->size.x = area.x + (adj_size(130) - buf->size.w) / 2;
1762 buf->size.y = area.y + 1 + (adj_size(145) - buf->size.h) / 2;
1763 }
1764
1765 /* ok button */
1766 buf = buf->prev;
1767 buf->size.x = area.x + (adj_size(65) - buf->size.w) / 2;
1768 buf->size.y = area.y + adj_size(135) - buf->size.h;
1769
1770 /* exit button */
1771 buf = buf->prev;
1772 buf->size.x = area.x + adj_size(65) + (adj_size(65) - buf->size.w) / 2;
1773 buf->size.y = area.y + adj_size(135) - buf->size.h;
1774
1775 /* worklist */
1776 /* editor->work->scroll->count: including production */
1777 if (len > 0) {
1778 /* FIXME */
1780 area.x + adj_size(2), area.y + adj_size(152)
1781 /* + ((editor->work->scroll->count > editor->work->scroll->active + 2) ?
1782 editor->work->scroll->up_left_button->size.h + 1 : 0)*/,
1783 adj_size(126), 0, editor->work->begin_widget_list,
1784 editor->work->end_widget_list);
1785
1787 area.x + adj_size(2),
1788 area.y + adj_size(152),
1789 adj_size(225), FALSE);
1790 }
1791
1792 /* global worklists */
1793 if (editor->global) {
1795 area.x + adj_size(4),
1796 area.y + adj_size(384) +
1797 (editor->global->scroll ?
1798 editor->global->scroll->up_left_button->size.h + 1 : 0),
1799 adj_size(122), 0, editor->global->begin_widget_list,
1800 editor->global->end_widget_list);
1801
1802 if (editor->global->scroll) {
1803 setup_vertical_scrollbar_area(editor->global->scroll,
1804 area.x + adj_size(4),
1805 area.y + adj_size(384),
1806 adj_size(93), FALSE);
1807 }
1808
1809 }
1810
1811 /* Targets */
1813 area.x + adj_size(130), area.y,
1814 0, 0, editor->targets->begin_widget_list,
1815 editor->targets->end_widget_list);
1816
1817 if (editor->targets->scroll) {
1818 setup_vertical_scrollbar_area(editor->targets->scroll,
1819 area.x + area.w,
1820 area.y + 1,
1821 area.h - 1, TRUE);
1822
1823 }
1824
1825 /* ----------------------------------- */
1826 FREEUTF8STR(pstr);
1827 FREESURFACE(main_surf);
1828
1829 redraw_group(editor->begin_widget_list, pwindow, 0);
1830 widget_flush(pwindow);
1831}
1832
1833/**********************************************************************/
1837{
1838 if (editor) {
1839 popdown_window_group_dialog(editor->begin_widget_list,
1840 editor->end_widget_list);
1841 FC_FREE(editor->targets->scroll);
1842 FC_FREE(editor->targets);
1843
1844 FC_FREE(editor->work->scroll);
1845 FC_FREE(editor->work);
1846
1847 if (editor->global) {
1848 FC_FREE(editor->global->scroll);
1849 FC_FREE(editor->global);
1850 }
1851
1852 if (city_dialog_is_open(editor->pcity)) {
1854 }
1855
1856 FC_FREE(editor);
1857
1858 flush_dirty();
1859 }
1860}
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
int city_turns_to_build(const struct city *pcity, const struct universal *target, bool include_shield_stock)
Definition city.c:1938
const char * city_improvement_name_translation(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:658
int city_production_build_shield_cost(const struct city *pcity)
Definition city.c:722
const char * city_name_get(const struct city *pcity)
Definition city.c:1115
bool can_city_build_later(const struct civ_map *nmap, const struct city *pcity, const struct universal *target)
Definition city.c:1009
bool city_production_has_flag(const struct city *pcity, enum impr_flag_id flag)
Definition city.c:712
bool can_city_build_improvement_now(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:839
int city_production_turns_to_build(const struct city *pcity, bool include_shield_stock)
Definition city.c:805
int city_change_production_penalty(const struct city *pcity, const struct universal *target)
Definition city.c:1859
bool can_city_build_unit_now(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:927
bool can_city_build_improvement_later(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:856
bool can_city_build_unit_later(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:948
const char * city_production_name_translation(const struct city *pcity)
Definition city.c:695
int city_set_worklist(struct city *pcity, const struct worklist *pworklist)
int city_change_production(struct city *pcity, struct universal *target)
struct civclient client
#define client_player()
cid cid_encode_building(const struct impr_type *pimprove)
Definition climisc.c:498
cid cid_encode(struct universal target)
Definition climisc.c:476
struct universal cid_decode(cid id)
Definition climisc.c:519
cid cid_encode_unit(const struct unit_type *punittype)
Definition climisc.c:486
#define cid_production
Definition climisc.h:71
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:73
int int id
Definition editgui_g.h:28
static struct editor_state * editor
Definition editor.c:100
QString current_theme
Definition fc_client.cpp:65
#define MAX_LEN_NAME
Definition fc_types.h:66
@ O_SHIELD
Definition fc_types.h:91
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
struct world wld
Definition game.c:58
struct global_worklist * global_worklist_by_id(int id)
bool global_worklist_set(struct global_worklist *pgwl, const struct worklist *pwl)
const char * global_worklist_name(const struct global_worklist *pgwl)
int global_worklist_id(const struct global_worklist *pgwl)
const struct worklist * global_worklist_get(const struct global_worklist *pgwl)
void global_worklist_set_name(struct global_worklist *pgwl, const char *name)
#define global_worklists_iterate(pgwl)
#define global_worklists_iterate_end
bool city_dialog_is_open(struct city *pcity)
Definition citydlg.c:579
void flush_dirty(void)
Definition mapview.c:450
void update_worklist_report_dialog(void)
Definition wldlg.c:115
void enable_city_dlg_widgets(void)
Definition citydlg.c:1535
SDL_Color * get_theme_color(enum theme_color themecolor)
Definition colors.c:44
int main_window_width(void)
Definition graphics.c:685
void layer_rect_to_screen_rect(struct gui_layer *gui_layer, SDL_Rect *dest_rect)
Definition graphics.c:185
int fill_rect_alpha(SDL_Surface *surf, SDL_Rect *prect, SDL_Color *pcolor)
Definition graphics.c:865
SDL_Surface * crop_rect_from_surface(SDL_Surface *psource, SDL_Rect *prect)
Definition graphics.c:236
int alphablit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:199
struct sdl2_data main_data
Definition graphics.c:57
SDL_Surface * create_surf(int width, int height, Uint32 flags)
Definition graphics.c:351
void create_frame(SDL_Surface *dest, Sint16 left, Sint16 top, Sint16 width, Sint16 height, SDL_Color *pcolor)
Definition graphics.c:1347
int main_window_height(void)
Definition graphics.c:693
#define DEFAULT_ZOOM
Definition graphics.h:198
#define FREESURFACE(ptr)
Definition graphics.h:322
#define adj_surf(surf)
Definition graphics.h:200
#define map_rgba(format, color)
Definition graphics.h:315
#define adj_size(size)
Definition gui_main.h:138
#define PRESSED_EVENT(event)
Definition gui_main.h:68
void popup_impr_info(Impr_type_id impr)
Definition helpdlg.c:202
void popup_unit_info(Unit_type_id type_id)
Definition helpdlg.c:632
void dirty_sdl_rect(SDL_Rect *Rect)
Definition mapview.c:181
static void get_target_help_data(struct widget *target)
Definition wldlg.c:388
static void add_target_to_worklist(struct widget *target)
Definition wldlg.c:206
static void set_global_worklist(struct widget *pwidget)
Definition wldlg.c:749
static bool are_prods_same_class(const struct universal *one, const struct universal *two)
Definition wldlg.c:303
static const char * get_production_name(struct city *pcity, struct universal prod, int *cost)
Definition wldlg.c:880
static int window_worklist_editor_callback(struct widget *pwidget)
Definition wldlg.c:103
static void add_target_to_production(struct widget *target)
Definition wldlg.c:350
static void swap_item_down_from_worklist(struct widget *item)
Definition wldlg.c:530
static int popdown_worklist_editor_callback(struct widget *pwidget)
Definition wldlg.c:111
static int ok_worklist_editor_callback(struct widget *pwidget)
Definition wldlg.c:124
static SDL_Surface * get_progress_icon(int stock, int cost, int *progress)
Definition wldlg.c:900
void popup_worklist_editor(struct city *pcity, struct global_worklist *gwl)
Definition wldlg.c:1050
#define TARGETS_ROW
Definition wldlg.c:64
static void remove_item_from_worklist(struct widget *item)
Definition wldlg.c:454
static void refresh_worklist_count_label(void)
Definition wldlg.c:1007
static int worklist_editor_item_callback(struct widget *pwidget)
Definition wldlg.c:639
static int global_worklist_callback(struct widget *pwidget)
Definition wldlg.c:851
void popdown_worklist_editor(void)
Definition wldlg.c:1836
static int worklist_editor_targets_callback(struct widget *pwidget)
Definition wldlg.c:415
#define TARGETS_COL
Definition wldlg.c:63
static void add_global_worklist(struct widget *pwidget)
Definition wldlg.c:670
static void swap_item_up_from_worklist(struct widget *item)
Definition wldlg.c:587
static int rename_worklist_editor_callback(struct widget *pwidget)
Definition wldlg.c:183
static void change_production(struct universal *prod)
Definition wldlg.c:325
static void refresh_production_label(int stock)
Definition wldlg.c:937
@ ID_BUTTON
Definition gui_id.h:29
@ ID_EDIT
Definition gui_id.h:34
@ ID_LABEL
Definition gui_id.h:27
@ ID_WINDOW
Definition gui_id.h:30
utf8_str * copy_chars_to_utf8_str(utf8_str *pstr, const char *pchars)
Definition gui_string.c:251
SDL_Surface * create_text_surf_from_utf8(utf8_str *pstr)
Definition gui_string.c:425
utf8_str * create_utf8_str_fonto(char *in_text, size_t n_alloc, enum font_origin origin)
Definition gui_string.c:241
SDL_Surface * create_text_surf_smaller_than_w(utf8_str *pstr, int w)
Definition gui_string.c:539
#define FREEUTF8STR(pstr)
Definition gui_string.h:92
#define SF_CENTER
Definition gui_string.h:40
@ FONTO_DEFAULT
Definition gui_string.h:64
@ FONTO_ATTENTION
Definition gui_string.h:66
#define create_utf8_from_char_fonto(string_in, fonto)
Definition gui_string.h:107
static SDL_Surface * get_building_surface(const struct impr_type *pimprove)
static SDL_Surface * get_unittype_surface(const struct unit_type *punittype, enum direction8 facing)
bool great_wonder_is_built(const struct impr_type *pimprove)
bool is_improvement_redundant(const struct city *pcity, const struct impr_type *pimprove)
bool can_player_build_improvement_later(const struct player *p, const struct impr_type *pimprove)
bool great_wonder_is_destroyed(const struct impr_type *pimprove)
bool can_player_build_improvement_now(const struct player *p, struct impr_type *pimprove)
Impr_type_id improvement_number(const struct impr_type *pimprove)
bool small_wonder_is_built(const struct player *pplayer, const struct impr_type *pimprove)
int impr_build_shield_cost(const struct city *pcity, const struct impr_type *pimprove)
bool is_wonder(const struct impr_type *pimprove)
bool is_great_wonder(const struct impr_type *pimprove)
bool improvement_obsolete(const struct player *pplayer, const struct impr_type *pimprove, const struct city *pcity)
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
const char * improvement_name_translation(const struct impr_type *pimprove)
bool is_small_wonder(const struct impr_type *pimprove)
#define improvement_iterate_end
#define improvement_iterate(_p)
#define B_LAST
Definition improvement.h:42
const char * name
Definition inputfile.c:127
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
const char * move_points_text(int mp, bool reduce)
Definition movement.c:973
int len
Definition packhand.c:125
int universal_build_shield_cost(const struct city *pcity, const struct universal *target)
bool are_universals_equal(const struct universal *psource1, const struct universal *psource2)
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
Definition city.h:309
int surplus[O_LAST]
Definition city.h:343
struct worklist worklist
Definition city.h:387
struct universal production
Definition city.h:382
int shield_stock
Definition city.h:355
struct connection conn
Definition client_main.h:96
struct player * playing
Definition connection.h:156
int value
Definition widget.h:105
Definition climisc.h:82
SDL_Event event
Definition graphics.h:217
int defense_strength
Definition unittype.h:496
int move_rate
Definition unittype.h:497
int attack_strength
Definition unittype.h:495
enum universals_n kind
Definition fc_types.h:758
universals_u value
Definition fc_types.h:757
Uint8 style
Definition gui_string.h:53
SDL_Color bgcol
Definition gui_string.h:58
char * text
Definition gui_string.h:60
struct widget * next
Definition widget.h:113
void * ptr
Definition widget.h:133
SDL_Keycode key
Definition widget.h:153
union widget::@214 data
struct gui_layer * dst
Definition widget.h:116
struct widget * prev
Definition widget.h:114
int(* action)(struct widget *)
Definition widget.h:157
struct city * city
Definition widget.h:128
struct container * cont
Definition widget.h:127
utf8_str * string_utf8
Definition widget.h:121
SDL_Rect area
Definition widget.h:149
Uint16 id
Definition widget.h:155
SDL_Rect size
Definition widget.h:145
struct worklist worklist_copy
Definition wldlg.c:76
struct widget * end_widget_list
Definition wldlg.c:68
struct advanced_dialog * work
Definition wldlg.c:71
struct widget * begin_widget_list
Definition wldlg.c:67
struct widget * production_name
Definition wldlg.c:83
struct widget * worklist_counter
Definition wldlg.c:81
struct city * pcity
Definition wldlg.c:74
int global_worklist_id
Definition wldlg.c:75
char worklist_name[MAX_LEN_NAME]
Definition wldlg.c:77
struct advanced_dialog * targets
Definition wldlg.c:70
int stock
Definition wldlg.c:86
struct advanced_dialog * global
Definition wldlg.c:72
struct universal currently_building
Definition wldlg.c:87
struct widget * production_progress
Definition wldlg.c:84
struct widget * dock
Definition wldlg.c:80
struct universal entries[MAX_LEN_WORKLIST]
Definition worklist.h:30
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
#define sz_strlcpy(dest, src)
Definition support.h:167
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
SDL_Surface * theme_get_background(const struct theme *t, enum theme_background background)
@ BACKGROUND_WLDLG
@ COLOR_THEME_BACKGROUND
Definition themecolors.h:23
@ COLOR_THEME_WLDLG_FRAME
struct theme * active_theme
Definition themespec.c:154
const struct unit_type * utype
Definition fc_types.h:604
const struct impr_type * building
Definition fc_types.h:598
Unit_type_id utype_number(const struct unit_type *punittype)
Definition unittype.c:100
bool can_player_build_unit_later(const struct player *p, const struct unit_type *punittype)
Definition unittype.c:2150
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1490
bool can_player_build_unit_now(const struct player *p, const struct unit_type *punittype)
Definition unittype.c:2131
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1612
#define unit_type_iterate(_p)
Definition unittype.h:841
#define unit_type_iterate_end
Definition unittype.h:848
void add_to_gui_list(Uint16 id, struct widget *gui)
Definition widget.c:585
struct widget * get_widget_pointer_from_main_list(Uint16 id)
Definition widget.c:577
void refresh_widget_background(struct widget *pwidget)
Definition widget.c:1150
SDL_Surface * create_bcgnd_surf(SDL_Surface *ptheme, enum widget_state state, Uint16 width, Uint16 height)
Definition widget.c:78
int setup_vertical_widgets_position(int step, Sint16 start_x, Sint16 start_y, Uint16 w, Uint16 h, struct widget *begin, struct widget *end)
Definition widget.c:1050
Uint16 redraw_group(const struct widget *begin_group_widget_list, const struct widget *end_group_widget_list, int add_to_update)
Definition widget.c:719
void popdown_window_group_dialog(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:982
static void widget_set_position(struct widget *pwidget, int x, int y)
Definition widget.h:266
#define MAX_ID
Definition widget.h:38
@ FC_WS_DISABLED
Definition widget.h:99
@ FC_WS_NORMAL
Definition widget.h:96
@ FC_WS_SELECTED
Definition widget.h:97
void clear_wflag(struct widget *pwidget, enum widget_flag flag)
Definition widget_core.c:62
bool add_widget_to_vertical_scroll_widget_list(struct advanced_dialog *dlg, struct widget *new_widget, struct widget *add_dock, bool dir, Sint16 start_x, Sint16 start_y) fc__attribute((nonnull(2)))
bool del_widget_from_vertical_scroll_widget_list(struct advanced_dialog *dlg, struct widget *pwidget) fc__attribute((nonnull(2)))
static void widget_mark_dirty(struct widget *pwidget)
Definition widget.h:286
static void widget_flush(struct widget *pwidget)
Definition widget.h:291
enum widget_flag get_wflags(const struct widget *pwidget)
Definition widget_core.c:86
void set_wstate(struct widget *pwidget, enum widget_state state)
Definition widget_core.c:36
static void widget_undraw(struct widget *pwidget)
Definition widget.h:296
@ WF_ICON_CENTER
Definition widget.h:83
@ WF_FREE_DATA
Definition widget.h:78
@ WF_RESTORE_BACKGROUND
Definition widget.h:85
@ WF_HIDDEN
Definition widget.h:68
@ WF_FREE_THEME
Definition widget.h:72
static int widget_redraw(struct widget *pwidget)
Definition widget.h:276
void set_wflag(struct widget *pwidget, enum widget_flag flag)
Definition widget_core.c:54
#define create_edit_from_chars_fonto(background, pdest, char_string, fonto, length, flags)
Definition widget_edit.h:29
struct widget * create_themeicon(SDL_Surface *icon_theme, struct gui_layer *pdest, Uint32 flags)
struct widget * create_icon2(SDL_Surface *icon, struct gui_layer *pdest, Uint32 flags)
void remake_label_size(struct widget *label)
struct widget * create_iconlabel(SDL_Surface *icon, struct gui_layer *pdest, utf8_str *pstr, Uint32 flags)
#define create_iconlabel_from_chars_fonto(picon, pdest, chars, fonto, flags)
void setup_vertical_scrollbar_area(struct scroll_bar *scroll, Sint16 start_x, Sint16 start_y, Uint16 height, bool swap_start_x)
Uint32 create_vertical_scrollbar(struct advanced_dialog *dlg, Uint8 step, Uint8 active, bool create_scrollbar, bool create_buttons)
#define hide_scrollbar(scrollbar)
#define show_scrollbar(scrollbar)
int resize_window(struct widget *pwindow, SDL_Surface *bcgd, SDL_Color *pcolor, Uint16 new_w, Uint16 new_h)
struct widget * create_window_skeleton(struct gui_layer *pdest, utf8_str *title, Uint32 flags)
void worklist_advance(struct worklist *pwl)
Definition worklist.c:104
void worklist_copy(struct worklist *dst, const struct worklist *src)
Definition worklist.c:112
void worklist_init(struct worklist *pwl)
Definition worklist.c:38
bool worklist_peek_ith(const struct worklist *pwl, struct universal *prod, int idx)
Definition worklist.c:86
bool worklist_is_empty(const struct worklist *pwl)
Definition worklist.c:66
bool worklist_append(struct worklist *pwl, const struct universal *prod)
Definition worklist.c:147
void worklist_remove(struct worklist *pwl, int idx)
Definition worklist.c:122
int worklist_length(const struct worklist *pwl)
Definition worklist.c:57
#define worklist_iterate_end
Definition worklist.h:59
#define worklist_iterate(_list, _p)
Definition worklist.h:51
#define MAX_LEN_WORKLIST
Definition worklist.h:24