Merge lp:~widelands-dev/widelands/economy-target-profiles into lp:widelands

Proposed by Benedikt Straub
Status: Superseded
Proposed branch: lp:~widelands-dev/widelands/economy-target-profiles
Merge into: lp:widelands
Diff against target: 1603 lines (+937/-169)
17 files modified
data/tribes/economy_profiles/atlanteans (+89/-0)
data/tribes/economy_profiles/barbarians (+81/-0)
data/tribes/economy_profiles/empire (+89/-0)
data/tribes/economy_profiles/frisians (+93/-0)
src/logic/filesystem_constants.h (+2/-0)
src/logic/map_objects/tribes/tribe_descr.cc (+0/-40)
src/logic/map_objects/tribes/tribe_descr.h (+0/-11)
src/logic/map_objects/tribes/tribes.cc (+1/-6)
src/logic/map_objects/tribes/ware_descr.h (+2/-4)
src/logic/playercommand.h (+2/-0)
src/wui/CMakeLists.txt (+2/-0)
src/wui/economy_options_window.cc (+382/-52)
src/wui/economy_options_window.h (+38/-1)
src/wui/inputqueuedisplay.cc (+6/-6)
src/wui/inputqueuedisplay.h (+1/-1)
src/wui/waresdisplay.cc (+121/-46)
src/wui/waresdisplay.h (+28/-2)
To merge this branch: bzr merge lp:~widelands-dev/widelands/economy-target-profiles
Reviewer Review Type Date Requested Status
Widelands Developers Pending
Review via email: mp+366952@code.launchpad.net

This proposal has been superseded by a proposal from 2019-05-06.

Commit message

Users can define and save their own profiles of economy target quantities. Redesigned the economy options menu.

Description of the change

For each tribe, I added two profiles: "Efficiency" is equal to the changes proposed previously, and "Stockpile" is for people who, well, like to stockpile stuff. Additionally there is an unchangeable "Default" profile that resets stuff to the default settings.
To apply a profile, select the profile and the wares you wish to change and click Apply (replaces Reset). Use "Save" to save your current settings as a profile. The save window also allows you to delete profiles.

To post a comment you must log in.
Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4886. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/528245915.
Appveyor build 4667. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_economy_target_profiles-4667.

Revision history for this message
GunChleoc (gunchleoc) wrote :

2 Comments. Will do some testing.

Revision history for this message
Benedikt Straub (nordfriese) wrote :

Addressed the reviews: The panels now set hgaps to fill the entire available space, and the profiles are stored in tribes/economy_profiles. I added translation markup to the predefined profiles.

Revision history for this message
GunChleoc (gunchleoc) wrote :

New code LGTM.

I am wondering whether we want to save this as Lua tables? I already have the code finished in the spritesheets branch and could pull it out into a separate branch, since spritesheets aren't ready yet.

Revision history for this message
Benedikt Straub (nordfriese) wrote :

Is there a reason why you prefer LuaTables over profile? Personally I find Profile much easier to use for configs that the user has no reason to manually edit.

Regarding the suggestion in the bug report – A spinbox would make sense, but what value should it display when several wares with different settings are selected?

Revision history for this message
GunChleoc (gunchleoc) wrote :

All the tribe's configuration is in LuaTables, so I guess mainly for consistency - I don't feel strongly about this though.

Good point about the value in the spinbox - I still think we should have the possibility of having steps of 10 though. Maybe fake it with 4 buttons and make them look like the spinbox buttons?

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4901. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/528550026.
Appveyor build 4682. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_economy_target_profiles-4682.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'data/images/ui_basic/scrollbar_down_fast.png'
0Binary files data/images/ui_basic/scrollbar_down_fast.png 1970-01-01 00:00:00 +0000 and data/images/ui_basic/scrollbar_down_fast.png 2019-05-06 13:51:46 +0000 differ0Binary files data/images/ui_basic/scrollbar_down_fast.png 1970-01-01 00:00:00 +0000 and data/images/ui_basic/scrollbar_down_fast.png 2019-05-06 13:51:46 +0000 differ
=== added file 'data/images/ui_basic/scrollbar_up_fast.png'
1Binary files data/images/ui_basic/scrollbar_up_fast.png 1970-01-01 00:00:00 +0000 and data/images/ui_basic/scrollbar_up_fast.png 2019-05-06 13:51:46 +0000 differ1Binary files data/images/ui_basic/scrollbar_up_fast.png 1970-01-01 00:00:00 +0000 and data/images/ui_basic/scrollbar_up_fast.png 2019-05-06 13:51:46 +0000 differ
=== added directory 'data/tribes/economy_profiles'
=== added file 'data/tribes/economy_profiles/atlanteans'
--- data/tribes/economy_profiles/atlanteans 1970-01-01 00:00:00 +0000
+++ data/tribes/economy_profiles/atlanteans 2019-05-06 13:51:46 +0000
@@ -0,0 +1,89 @@
1# Automatically created by Widelands bzr9094[economy-target-profiles] (Debug)
2
3[Default]
40=_"Efficiency"
51=_"Stockpile"
6
7[0]
8blackroot_flour="1"
9atlanteans_bread="20"
10bread_paddle="0"
11buckets="0"
12coal="5"
13cornmeal="3"
14diamond="3"
15fire_tongs="1"
16fishing_net="2"
17gold="1"
18gold_ore="1"
19gold_thread="0"
20granite="10"
21hammer="0"
22hook_pole="0"
23hunting_bow="1"
24iron="5"
25iron_ore="1"
26milking_tongs="0"
27pick="1"
28planks="1"
29quartz="3"
30saw="0"
31scythe="0"
32shield_advanced="0"
33shield_steel="0"
34shovel="0"
35smoked_fish="5"
36smoked_meat="3"
37spidercloth="5"
38spider_silk="5"
39tabard="1"
40tabard_golden="0"
41trident_double="0"
42trident_heavy_double="0"
43trident_light="1"
44trident_long="0"
45trident_steel="0"
46atlanteans_horse="1"
47atlanteans_soldier="10"
48
49[1]
50blackroot_flour="20"
51atlanteans_bread="30"
52bread_paddle="1"
53buckets="2"
54coal="25"
55cornmeal="20"
56diamond="10"
57fire_tongs="1"
58fishing_net="2"
59gold="20"
60gold_ore="15"
61gold_thread="5"
62granite="30"
63hammer="2"
64hook_pole="1"
65hunting_bow="1"
66iron="25"
67iron_ore="20"
68milking_tongs="1"
69pick="3"
70planks="40"
71quartz="10"
72saw="2"
73scythe="1"
74shield_advanced="1"
75shield_steel="1"
76shovel="2"
77smoked_fish="40"
78smoked_meat="25"
79spidercloth="20"
80spider_silk="15"
81tabard="30"
82tabard_golden="1"
83trident_double="1"
84trident_heavy_double="1"
85trident_light="30"
86trident_long="1"
87trident_steel="1"
88atlanteans_horse="20"
89atlanteans_soldier="20"
090
=== added file 'data/tribes/economy_profiles/barbarians'
--- data/tribes/economy_profiles/barbarians 1970-01-01 00:00:00 +0000
+++ data/tribes/economy_profiles/barbarians 2019-05-06 13:51:46 +0000
@@ -0,0 +1,81 @@
1# Automatically created by Widelands bzr9094[economy-target-profiles] (Debug)
2
3[Default]
40=_"Efficiency"
51=_"Stockpile"
6
7[0]
8ax="1"
9ax_battle="0"
10ax_broad="0"
11ax_bronze="0"
12ax_sharp="0"
13ax_warriors="0"
14beer="0"
15beer_strong="1"
16blackwood="40"
17barbarians_bread="5"
18bread_paddle="0"
19cloth="10"
20coal="20"
21felling_ax="0"
22fire_tongs="1"
23fishing_rod="0"
24gold="1"
25gold_ore="1"
26granite="10"
27grout="1"
28hammer="1"
29helmet="0"
30helmet_mask="0"
31helmet_warhelm="0"
32hunting_spear="0"
33iron="5"
34iron_ore="5"
35kitchen_tools="0"
36meal="5"
37pick="1"
38ration="20"
39scythe="0"
40shovel="0"
41snack="0"
42barbarians_ox="1"
43barbarians_soldier="10"
44
45[1]
46ax="30"
47ax_battle="1"
48ax_broad="1"
49ax_bronze="1"
50ax_sharp="1"
51ax_warriors="1"
52beer="15"
53beer_strong="20"
54blackwood="45"
55barbarians_bread="25"
56bread_paddle="1"
57cloth="10"
58coal="25"
59felling_ax="5"
60fire_tongs="1"
61fishing_rod="1"
62gold="20"
63gold_ore="15"
64granite="30"
65grout="20"
66hammer="2"
67helmet="1"
68helmet_mask="1"
69helmet_warhelm="1"
70hunting_spear="1"
71iron="25"
72iron_ore="20"
73kitchen_tools="1"
74meal="15"
75pick="2"
76ration="30"
77scythe="1"
78shovel="1"
79snack="20"
80barbarians_ox="20"
81barbarians_soldier="20"
082
=== added file 'data/tribes/economy_profiles/empire'
--- data/tribes/economy_profiles/empire 1970-01-01 00:00:00 +0000
+++ data/tribes/economy_profiles/empire 2019-05-06 13:51:46 +0000
@@ -0,0 +1,89 @@
1# Automatically created by Widelands bzr9094[economy-target-profiles] (Debug)
2
3[Default]
40=_"Efficiency"
51=_"Stockpile"
6
7[0]
8armor="1"
9armor_chain="1"
10armor_gilded="1"
11armor_helmet="30"
12basket="1"
13beer="1"
14empire_bread="20"
15bread_paddle="0"
16cloth="15"
17coal="5"
18felling_ax="0"
19fire_tongs="1"
20fishing_rod="0"
21flour="20"
22gold="1"
23gold_ore="1"
24granite="10"
25hammer="0"
26hunting_spear="0"
27iron="5"
28iron_ore="3"
29kitchen_tools="0"
30marble="30"
31marble_column="10"
32meal="5"
33meat="20"
34pick="1"
35planks="1"
36ration="20"
37saw="0"
38scythe="0"
39shovel="0"
40spear="1"
41spear_advanced="1"
42spear_heavy="1"
43spear_war="1"
44spear_wooden="30"
45wool="10"
46empire_donkey="1"
47empire_soldier="10"
48
49[1]
50armor="1"
51armor_chain="1"
52armor_gilded="1"
53armor_helmet="30"
54basket="1"
55beer="20"
56empire_bread="30"
57bread_paddle="1"
58cloth="15"
59coal="25"
60felling_ax="3"
61fire_tongs="1"
62fishing_rod="1"
63flour="25"
64gold="20"
65gold_ore="15"
66granite="30"
67hammer="2"
68hunting_spear="1"
69iron="25"
70iron_ore="20"
71kitchen_tools="1"
72marble="35"
73marble_column="15"
74meal="20"
75meat="30"
76pick="2"
77planks="40"
78ration="25"
79saw="1"
80scythe="1"
81shovel="1"
82spear="1"
83spear_advanced="1"
84spear_heavy="1"
85spear_war="1"
86spear_wooden="30"
87wool="15"
88empire_donkey="20"
89empire_soldier="20"
090
=== added file 'data/tribes/economy_profiles/frisians'
--- data/tribes/economy_profiles/frisians 1970-01-01 00:00:00 +0000
+++ data/tribes/economy_profiles/frisians 2019-05-06 13:51:46 +0000
@@ -0,0 +1,93 @@
1# Automatically created by Widelands bzr9093[economy-target-profiles] (Debug)
2
3[Default]
40=_"Efficiency"
51=_"Stockpile"
6
7[0]
8clay="30"
9brick="40"
10bread_frisians="20"
11honey_bread="20"
12mead="15"
13fur="10"
14fur_garment="30"
15fur_garment_studded="2"
16fur_garment_golden="2"
17helmet_golden="2"
18sword_short="30"
19sword_long="2"
20sword_broad="2"
21sword_double="2"
22needles="1"
23basket="1"
24beer="1"
25bread_paddle="1"
26cloth="10"
27coal="20"
28felling_ax="0"
29fire_tongs="1"
30fish="20"
31fishing_net="2"
32gold="1"
33gold_ore="1"
34granite="10"
35hammer="1"
36helmet="0"
37hunting_spear="0"
38iron="5"
39iron_ore="3"
40kitchen_tools="0"
41meal="1"
42pick="1"
43ration="20"
44scythe="0"
45shovel="0"
46smoked_fish="20"
47smoked_meat="10"
48frisians_reindeer="1"
49frisians_soldier="10"
50
51[1]
52clay="35"
53brick="50"
54bread_frisians="30"
55honey_bread="30"
56mead="30"
57fur="20"
58fur_garment="30"
59fur_garment_studded="2"
60fur_garment_golden="2"
61helmet_golden="2"
62sword_short="30"
63sword_long="2"
64sword_broad="2"
65sword_double="2"
66needles="1"
67basket="1"
68beer="30"
69bread_paddle="1"
70cloth="10"
71coal="35"
72felling_ax="3"
73fire_tongs="2"
74fish="40"
75fishing_net="2"
76gold="20"
77gold_ore="15"
78granite="35"
79hammer="3"
80helmet="2"
81hunting_spear="1"
82iron="25"
83iron_ore="20"
84kitchen_tools="2"
85meal="10"
86pick="3"
87ration="30"
88scythe="2"
89shovel="5"
90smoked_fish="30"
91smoked_meat="20"
92frisians_reindeer="20"
93frisians_soldier="20"
094
=== modified file 'src/logic/filesystem_constants.h'
--- src/logic/filesystem_constants.h 2019-04-18 16:50:35 +0000
+++ src/logic/filesystem_constants.h 2019-05-06 13:51:46 +0000
@@ -78,4 +78,6 @@
78/// Filesystem names for config78/// Filesystem names for config
79const std::string kConfigFile = "config";79const std::string kConfigFile = "config";
8080
81const std::string kEconomyProfilesDir = "tribes/economy_profiles";
82
81#endif // end of include guard: WL_LOGIC_FILESYSTEM_CONSTANTS_H83#endif // end of include guard: WL_LOGIC_FILESYSTEM_CONSTANTS_H
8284
=== modified file 'src/logic/map_objects/tribes/tribe_descr.cc'
--- src/logic/map_objects/tribes/tribe_descr.cc 2019-05-04 10:47:44 +0000
+++ src/logic/map_objects/tribes/tribe_descr.cc 2019-05-06 13:51:46 +0000
@@ -89,8 +89,6 @@
89 load_roads("busy", &busy_road_paths_);89 load_roads("busy", &busy_road_paths_);
9090
91 items_table = table.get_table("wares_order");91 items_table = table.get_table("wares_order");
92 wares_order_coords_.resize(tribes_.nrwares());
93 int columnindex = 0;
94 for (const int key : items_table->keys<int>()) {92 for (const int key : items_table->keys<int>()) {
95 std::vector<DescriptionIndex> column;93 std::vector<DescriptionIndex> column;
96 std::vector<std::string> warenames =94 std::vector<std::string> warenames =
@@ -104,7 +102,6 @@
104 }102 }
105 wares_.insert(wareindex);103 wares_.insert(wareindex);
106 column.push_back(wareindex);104 column.push_back(wareindex);
107 wares_order_coords_[wareindex] = std::make_pair(columnindex, rowindex);
108 } catch (const WException& e) {105 } catch (const WException& e) {
109 throw GameDataError(106 throw GameDataError(
110 "Failed adding ware '%s: %s", warenames[rowindex].c_str(), e.what());107 "Failed adding ware '%s: %s", warenames[rowindex].c_str(), e.what());
@@ -112,13 +109,10 @@
112 }109 }
113 if (!column.empty()) {110 if (!column.empty()) {
114 wares_order_.push_back(column);111 wares_order_.push_back(column);
115 ++columnindex;
116 }112 }
117 }113 }
118114
119 items_table = table.get_table("workers_order");115 items_table = table.get_table("workers_order");
120 workers_order_coords_.resize(tribes_.nrworkers());
121 columnindex = 0;
122 for (const int key : items_table->keys<int>()) {116 for (const int key : items_table->keys<int>()) {
123 std::vector<DescriptionIndex> column;117 std::vector<DescriptionIndex> column;
124 std::vector<std::string> workernames =118 std::vector<std::string> workernames =
@@ -132,7 +126,6 @@
132 }126 }
133 workers_.insert(workerindex);127 workers_.insert(workerindex);
134 column.push_back(workerindex);128 column.push_back(workerindex);
135 workers_order_coords_[workerindex] = std::make_pair(columnindex, rowindex);
136129
137 const WorkerDescr& worker_descr = *tribes_.get_worker_descr(workerindex);130 const WorkerDescr& worker_descr = *tribes_.get_worker_descr(workerindex);
138 if (worker_descr.is_buildable() && worker_descr.buildcost().empty()) {131 if (worker_descr.is_buildable() && worker_descr.buildcost().empty()) {
@@ -145,7 +138,6 @@
145 }138 }
146 if (!column.empty()) {139 if (!column.empty()) {
147 workers_order_.push_back(column);140 workers_order_.push_back(column);
148 ++columnindex;
149 }141 }
150 }142 }
151143
@@ -423,38 +415,6 @@
423 return list->second.find(lowest)->second;415 return list->second.find(lowest)->second;
424}416}
425417
426void TribeDescr::resize_ware_orders(size_t maxLength) {
427 bool need_resize = false;
428
429 // Check if we actually need to resize.
430 for (WaresOrder::iterator it = wares_order_.begin(); it != wares_order_.end(); ++it) {
431 if (it->size() > maxLength) {
432 need_resize = true;
433 }
434 }
435
436 // Build new smaller wares_order.
437 if (need_resize) {
438 WaresOrder new_wares_order;
439 for (WaresOrder::iterator it = wares_order_.begin(); it != wares_order_.end(); ++it) {
440 new_wares_order.push_back(std::vector<Widelands::DescriptionIndex>());
441 for (std::vector<Widelands::DescriptionIndex>::iterator it2 = it->begin();
442 it2 != it->end(); ++it2) {
443 if (new_wares_order.rbegin()->size() >= maxLength) {
444 new_wares_order.push_back(std::vector<Widelands::DescriptionIndex>());
445 }
446 new_wares_order.rbegin()->push_back(*it2);
447 wares_order_coords_[*it2].first = new_wares_order.size() - 1;
448 wares_order_coords_[*it2].second = new_wares_order.rbegin()->size() - 1;
449 }
450 }
451
452 // Remove old array.
453 wares_order_.clear();
454 wares_order_ = new_wares_order;
455 }
456}
457
458void TribeDescr::add_building(const std::string& buildingname) {418void TribeDescr::add_building(const std::string& buildingname) {
459 try {419 try {
460 DescriptionIndex index = tribes_.safe_building_index(buildingname);420 DescriptionIndex index = tribes_.safe_building_index(buildingname);
461421
=== modified file 'src/logic/map_objects/tribes/tribe_descr.h'
--- src/logic/map_objects/tribes/tribe_descr.h 2019-03-01 04:19:53 +0000
+++ src/logic/map_objects/tribes/tribe_descr.h 2019-05-06 13:51:46 +0000
@@ -149,22 +149,13 @@
149 }149 }
150150
151 using WaresOrder = std::vector<std::vector<Widelands::DescriptionIndex>>;151 using WaresOrder = std::vector<std::vector<Widelands::DescriptionIndex>>;
152 using WaresOrderCoords = std::vector<std::pair<uint32_t, uint32_t>>;
153 const WaresOrder& wares_order() const {152 const WaresOrder& wares_order() const {
154 return wares_order_;153 return wares_order_;
155 }154 }
156 const WaresOrderCoords& wares_order_coords() const {
157 return wares_order_coords_;
158 }
159155
160 const WaresOrder& workers_order() const {156 const WaresOrder& workers_order() const {
161 return workers_order_;157 return workers_order_;
162 }158 }
163 const WaresOrderCoords& workers_order_coords() const {
164 return workers_order_coords_;
165 }
166
167 void resize_ware_orders(size_t maxLength);
168159
169 const std::vector<std::string>& get_ship_names() const {160 const std::vector<std::string>& get_ship_names() const {
170 return ship_names_;161 return ship_names_;
@@ -215,9 +206,7 @@
215 std::vector<DescriptionIndex> trainingsites_;206 std::vector<DescriptionIndex> trainingsites_;
216 // Order and positioning of wares in the warehouse display207 // Order and positioning of wares in the warehouse display
217 WaresOrder wares_order_;208 WaresOrder wares_order_;
218 WaresOrderCoords wares_order_coords_;
219 WaresOrder workers_order_;209 WaresOrder workers_order_;
220 WaresOrderCoords workers_order_coords_;
221210
222 std::vector<Widelands::TribeBasicInfo::Initialization> initializations_;211 std::vector<Widelands::TribeBasicInfo::Initialization> initializations_;
223212
224213
=== modified file 'src/logic/map_objects/tribes/tribes.cc'
--- src/logic/map_objects/tribes/tribes.cc 2019-03-01 04:19:53 +0000
+++ src/logic/map_objects/tribes/tribes.cc 2019-05-06 13:51:46 +0000
@@ -340,14 +340,9 @@
340 // Calculate the trainingsites proportions.340 // Calculate the trainingsites proportions.
341 postload_calculate_trainingsites_proportions();341 postload_calculate_trainingsites_proportions();
342342
343 // Resize the configuration of our wares if they won't fit in the current window (12 = info label343 // Some final checks on the gamedata
344 // size).
345 // Also, do some final checks on the gamedata
346 int number = (g_gr->get_yres() - 290) / (WARE_MENU_PIC_HEIGHT + WARE_MENU_PIC_PAD_Y + 12);
347 for (DescriptionIndex i = 0; i < tribes_->size(); ++i) {344 for (DescriptionIndex i = 0; i < tribes_->size(); ++i) {
348 TribeDescr* tribe_descr = tribes_->get_mutable(i);345 TribeDescr* tribe_descr = tribes_->get_mutable(i);
349 tribe_descr->resize_ware_orders(number);
350
351 // Verify that the preciousness has been set for all of the tribe's wares346 // Verify that the preciousness has been set for all of the tribe's wares
352 for (const DescriptionIndex wi : tribe_descr->wares()) {347 for (const DescriptionIndex wi : tribe_descr->wares()) {
353 if (tribe_descr->get_ware_descr(wi)->preciousness(tribe_descr->name()) == kInvalidWare) {348 if (tribe_descr->get_ware_descr(wi)->preciousness(tribe_descr->name()) == kInvalidWare) {
354349
=== modified file 'src/logic/map_objects/tribes/ware_descr.h'
--- src/logic/map_objects/tribes/ware_descr.h 2019-02-27 19:00:36 +0000
+++ src/logic/map_objects/tribes/ware_descr.h 2019-05-06 13:51:46 +0000
@@ -33,10 +33,8 @@
33class Image;33class Image;
34class LuaTable;34class LuaTable;
3535
36#define WARE_MENU_PIC_WIDTH 24 //!< Default width for ware's menu icons36constexpr int kWareMenuPicWidth = 24; //!< Default width for ware's menu icons
37#define WARE_MENU_PIC_HEIGHT 24 //!< Default height for ware's menu icons37constexpr int kWareMenuPicHeight = 24; //!< Default height for ware's menu icons
38#define WARE_MENU_PIC_PAD_X 3 //!< Default padding between menu icons
39#define WARE_MENU_PIC_PAD_Y 4 //!< Default padding between menu icons
4038
41namespace Widelands {39namespace Widelands {
4240
4341
=== modified file 'src/logic/playercommand.h'
--- src/logic/playercommand.h 2019-02-23 11:00:49 +0000
+++ src/logic/playercommand.h 2019-05-06 13:51:46 +0000
@@ -581,6 +581,7 @@
581 uint32_t permanent_;581 uint32_t permanent_;
582};582};
583583
584// TODO(Nordfriese): CmdResetWareTargetQuantity can be removed when we next break savegame compatibility
584struct CmdResetWareTargetQuantity : public CmdChangeTargetQuantity {585struct CmdResetWareTargetQuantity : public CmdChangeTargetQuantity {
585 CmdResetWareTargetQuantity() : CmdChangeTargetQuantity() {586 CmdResetWareTargetQuantity() : CmdChangeTargetQuantity() {
586 }587 }
@@ -629,6 +630,7 @@
629 uint32_t permanent_;630 uint32_t permanent_;
630};631};
631632
633// TODO(Nordfriese): CmdResetWorkerTargetQuantity can be removed when we next break savegame compatibility
632struct CmdResetWorkerTargetQuantity : public CmdChangeTargetQuantity {634struct CmdResetWorkerTargetQuantity : public CmdChangeTargetQuantity {
633 CmdResetWorkerTargetQuantity() : CmdChangeTargetQuantity() {635 CmdResetWorkerTargetQuantity() : CmdChangeTargetQuantity() {
634 }636 }
635637
=== modified file 'src/wui/CMakeLists.txt'
--- src/wui/CMakeLists.txt 2019-05-04 15:37:33 +0000
+++ src/wui/CMakeLists.txt 2019-05-06 13:51:46 +0000
@@ -44,8 +44,10 @@
44 graphic44 graphic
45 logic45 logic
46 logic_commands46 logic_commands
47 logic_filesystem_constants
47 logic_map_objects48 logic_map_objects
48 notifications49 notifications
50 profile
49 ui_basic51 ui_basic
50 wui_waresdisplay52 wui_waresdisplay
51)53)
5254
=== modified file 'src/wui/economy_options_window.cc'
--- src/wui/economy_options_window.cc 2019-02-23 11:00:49 +0000
+++ src/wui/economy_options_window.cc 2019-05-06 13:51:46 +0000
@@ -19,36 +19,98 @@
1919
20#include "wui/economy_options_window.h"20#include "wui/economy_options_window.h"
2121
22#include <memory>
23
22#include <boost/lexical_cast.hpp>24#include <boost/lexical_cast.hpp>
2325
24#include "graphic/graphic.h"26#include "graphic/graphic.h"
25#include "logic/editor_game_base.h"27#include "logic/editor_game_base.h"
28#include "logic/filesystem_constants.h"
26#include "logic/map_objects/tribes/ware_descr.h"29#include "logic/map_objects/tribes/ware_descr.h"
27#include "logic/map_objects/tribes/worker_descr.h"30#include "logic/map_objects/tribes/worker_descr.h"
28#include "logic/player.h"31#include "logic/player.h"
29#include "logic/playercommand.h"32#include "logic/playercommand.h"
33#include "profile/profile.h"
30#include "ui_basic/button.h"34#include "ui_basic/button.h"
35#include "ui_basic/editbox.h"
36#include "ui_basic/messagebox.h"
37#include "ui_basic/table.h"
3138
32static const char pic_tab_wares[] = "images/wui/buildings/menu_tab_wares.png";39static const char pic_tab_wares[] = "images/wui/buildings/menu_tab_wares.png";
33static const char pic_tab_workers[] = "images/wui/buildings/menu_tab_workers.png";40static const char pic_tab_workers[] = "images/wui/buildings/menu_tab_workers.png";
3441
42constexpr int kDesiredWidth = 216;
43
44static inline int32_t calc_hgap(int32_t columns, int32_t total_w) {
45 return (total_w - columns * kWareMenuPicWidth) / (columns - 1);
46}
47
35EconomyOptionsWindow::EconomyOptionsWindow(UI::Panel* parent,48EconomyOptionsWindow::EconomyOptionsWindow(UI::Panel* parent,
36 Widelands::Economy* economy,49 Widelands::Economy* economy,
37 bool can_act)50 bool can_act)
38 : UI::Window(parent, "economy_options", 0, 0, 0, 0, _("Economy options")),51 : UI::Window(parent, "economy_options", 0, 0, 0, 0, _("Economy options")),
52 main_box_(this, 0, 0, UI::Box::Vertical),
39 serial_(economy->serial()),53 serial_(economy->serial()),
40 player_(&economy->owner()),54 player_(&economy->owner()),
41 tabpanel_(this, UI::TabPanelStyle::kWuiDark),55 tabpanel_(this, UI::TabPanelStyle::kWuiDark),
42 ware_panel_(new EconomyOptionsPanel(&tabpanel_, serial_, player_, can_act, Widelands::wwWARE)),56 ware_panel_(new EconomyOptionsPanel(&tabpanel_, this, serial_, player_, can_act, Widelands::wwWARE, kDesiredWidth)),
43 worker_panel_(57 worker_panel_(
44 new EconomyOptionsPanel(&tabpanel_, serial_, player_, can_act, Widelands::wwWORKER)) {58 new EconomyOptionsPanel(&tabpanel_, this, serial_, player_, can_act, Widelands::wwWORKER, kDesiredWidth)),
45 set_center_panel(&tabpanel_);59 dropdown_box_(this, 0, 0, UI::Box::Horizontal),
60 dropdown_(&dropdown_box_, 0, 0, 174, 200, 34, "", UI::DropdownType::kTextual, UI::PanelStyle::kWui) {
61 set_center_panel(&main_box_);
4662
47 tabpanel_.add("wares", g_gr->images().get(pic_tab_wares), ware_panel_, _("Wares"));63 tabpanel_.add("wares", g_gr->images().get(pic_tab_wares), ware_panel_, _("Wares"));
48 tabpanel_.add("workers", g_gr->images().get(pic_tab_workers), worker_panel_, _("Workers"));64 tabpanel_.add("workers", g_gr->images().get(pic_tab_workers), worker_panel_, _("Workers"));
65
66 UI::Box* buttons = new UI::Box(this, 0, 0, UI::Box::Horizontal);
67 UI::Button* b = new UI::Button(buttons, "decrease_target_fast", 0, 0, 44, 28, UI::ButtonStyle::kWuiSecondary,
68 g_gr->images().get("images/ui_basic/scrollbar_down_fast.png"), _("Decrease target by 10"));
69 b->sigclicked.connect([this] { change_target(-10); });
70 buttons->add(b);
71 b->set_repeating(true);
72 buttons->add_space(8);
73 b = new UI::Button(buttons, "decrease_target", 0, 0, 44, 28, UI::ButtonStyle::kWuiSecondary,
74 g_gr->images().get("images/ui_basic/scrollbar_down.png"), _("Decrease target"));
75 b->sigclicked.connect([this] { change_target(-1); });
76 buttons->add(b);
77 b->set_repeating(true);
78 buttons->add_space(24);
79
80 b = new UI::Button(buttons, "increase_target", 0, 0, 44, 28, UI::ButtonStyle::kWuiSecondary,
81 g_gr->images().get("images/ui_basic/scrollbar_up.png"), _("Increase target"));
82 b->sigclicked.connect([this] { change_target(1); });
83 buttons->add(b);
84 b->set_repeating(true);
85 buttons->add_space(8);
86 b = new UI::Button(buttons, "increase_target_fast", 0, 0, 44, 28, UI::ButtonStyle::kWuiSecondary,
87 g_gr->images().get("images/ui_basic/scrollbar_up_fast.png"), _("Increase target by 10"));
88 b->sigclicked.connect([this] { change_target(10); });
89 buttons->add(b);
90 b->set_repeating(true);
91
92 dropdown_.set_tooltip(_("Profile to apply to the selected items"));
93 dropdown_box_.set_size(40, 20); // Prevent assert failures
94 dropdown_box_.add(&dropdown_, UI::Box::Resizing::kFullSize);
95 dropdown_.selected.connect([this] { reset_target(); });
96
97 b = new UI::Button(&dropdown_box_, "save_targets", 0, 0, 34, 34, UI::ButtonStyle::kWuiMenu,
98 g_gr->images().get("images/wui/menus/menu_save_game.png"), _("Save target settings"));
99 b->sigclicked.connect([this] { create_target(); });
100 dropdown_box_.add_space(8);
101 dropdown_box_.add(b);
102
103 main_box_.add(&tabpanel_, UI::Box::Resizing::kAlign, UI::Align::kCenter);
104 main_box_.add_space(8);
105 main_box_.add(buttons, UI::Box::Resizing::kAlign, UI::Align::kCenter);
106 main_box_.add_space(8);
107 main_box_.add(&dropdown_box_, UI::Box::Resizing::kAlign, UI::Align::kCenter);
108
49 economy->set_has_window(true);109 economy->set_has_window(true);
50 economynotes_subscriber_ = Notifications::subscribe<Widelands::NoteEconomy>(110 economynotes_subscriber_ = Notifications::subscribe<Widelands::NoteEconomy>(
51 [this](const Widelands::NoteEconomy& note) { on_economy_note(note); });111 [this](const Widelands::NoteEconomy& note) { on_economy_note(note); });
112
113 read_targets();
52}114}
53115
54EconomyOptionsWindow::~EconomyOptionsWindow() {116EconomyOptionsWindow::~EconomyOptionsWindow() {
@@ -81,6 +143,20 @@
81 }143 }
82}144}
83145
146void EconomyOptionsWindow::layout() {
147 int w, h;
148 tabpanel_.get_desired_size(&w, &h);
149 main_box_.set_desired_size(w, h + 78);
150 update_desired_size();
151 UI::Window::layout();
152}
153
154void EconomyOptionsWindow::EconomyOptionsPanel::update_desired_size() {
155 display_.set_hgap(std::max(3, calc_hgap(display_.get_extent().w, kDesiredWidth)));
156 Box::update_desired_size();
157 get_parent()->layout();
158}
159
84EconomyOptionsWindow::TargetWaresDisplay::TargetWaresDisplay(UI::Panel* const parent,160EconomyOptionsWindow::TargetWaresDisplay::TargetWaresDisplay(UI::Panel* const parent,
85 int32_t const x,161 int32_t const x,
86 int32_t const y,162 int32_t const y,
@@ -129,42 +205,26 @@
129 * Wraps the wares/workers display together with some buttons205 * Wraps the wares/workers display together with some buttons
130 */206 */
131EconomyOptionsWindow::EconomyOptionsPanel::EconomyOptionsPanel(UI::Panel* parent,207EconomyOptionsWindow::EconomyOptionsPanel::EconomyOptionsPanel(UI::Panel* parent,
208 EconomyOptionsWindow* eco_window,
132 Widelands::Serial serial,209 Widelands::Serial serial,
133 Widelands::Player* player,210 Widelands::Player* player,
134 bool can_act,211 bool can_act,
135 Widelands::WareWorker type)212 Widelands::WareWorker type,
213 int32_t min_w)
136 : UI::Box(parent, 0, 0, UI::Box::Vertical),214 : UI::Box(parent, 0, 0, UI::Box::Vertical),
137 serial_(serial),215 serial_(serial),
138 player_(player),216 player_(player),
139 type_(type),217 type_(type),
140 can_act_(can_act),218 can_act_(can_act),
141 display_(this, 0, 0, serial_, player_, type_, can_act_) {219 display_(this, 0, 0, serial_, player_, type_, can_act_),
220 economy_options_window_(eco_window) {
142 add(&display_, UI::Box::Resizing::kFullSize);221 add(&display_, UI::Box::Resizing::kFullSize);
143222
223 display_.set_hgap(std::max(3, calc_hgap(display_.get_extent().w, min_w)));
224
144 if (!can_act_) {225 if (!can_act_) {
145 return;226 return;
146 }227 }
147 UI::Box* buttons = new UI::Box(this, 0, 0, UI::Box::Horizontal);
148 add(buttons);
149
150 UI::Button* b = new UI::Button(buttons, "decrease_target", 0, 0, 34, 34,
151 UI::ButtonStyle::kWuiMenu, "-", _("Decrease target"));
152 b->sigclicked.connect(boost::bind(&EconomyOptionsPanel::change_target, this, -1));
153 buttons->add(b);
154 b->set_repeating(true);
155 buttons->add_space(8);
156
157 b = new UI::Button(buttons, "increase_target", 0, 0, 34, 34, UI::ButtonStyle::kWuiMenu, "+",
158 _("Increase target"));
159 b->sigclicked.connect(boost::bind(&EconomyOptionsPanel::change_target, this, 1));
160 buttons->add(b);
161 b->set_repeating(true);
162 buttons->add_space(8);
163
164 b = new UI::Button(
165 buttons, "reset_target", 0, 0, 34, 34, UI::ButtonStyle::kWuiMenu, "R", _("Reset to default"));
166 b->sigclicked.connect(boost::bind(&EconomyOptionsPanel::reset_target, this));
167 buttons->add(b);
168}228}
169229
170void EconomyOptionsWindow::EconomyOptionsPanel::set_economy(Widelands::Serial serial) {230void EconomyOptionsWindow::EconomyOptionsPanel::set_economy(Widelands::Serial serial) {
@@ -172,7 +232,26 @@
172 display_.set_economy(serial);232 display_.set_economy(serial);
173}233}
174234
175void EconomyOptionsWindow::EconomyOptionsPanel::change_target(int amount) {235void EconomyOptionsWindow::change_target(int amount) {
236 if (tabpanel_.active() == 0) {
237 ware_panel_->change_target(amount);
238 } else {
239 worker_panel_->change_target(amount);
240 }
241}
242
243void EconomyOptionsWindow::reset_target() {
244 if (tabpanel_.active() == 0) {
245 ware_panel_->reset_target();
246 } else {
247 worker_panel_->reset_target();
248 }
249}
250
251void EconomyOptionsWindow::EconomyOptionsPanel::change_target(int delta) {
252 if (delta == 0) {
253 return;
254 }
176 Widelands::Economy* economy = player_->get_economy(serial_);255 Widelands::Economy* economy = player_->get_economy(serial_);
177 if (economy == nullptr) {256 if (economy == nullptr) {
178 die();257 die();
@@ -186,35 +265,286 @@
186 const Widelands::Economy::TargetQuantity& tq = is_wares ?265 const Widelands::Economy::TargetQuantity& tq = is_wares ?
187 economy->ware_target_quantity(index) :266 economy->ware_target_quantity(index) :
188 economy->worker_target_quantity(index);267 economy->worker_target_quantity(index);
189 // Don't allow negative new amount.268 // Don't allow negative new amount
190 if (amount >= 0 || -amount <= static_cast<int>(tq.permanent)) {269 const int old_amount = static_cast<int>(tq.permanent);
191 if (is_wares) {270 const int new_amount = std::max(0, old_amount + delta);
192 game.send_player_command(*new Widelands::CmdSetWareTargetQuantity(271 if (new_amount == old_amount) {
193 game.get_gametime(), player_->player_number(), serial_, index,272 continue;
194 tq.permanent + amount));273 }
274 if (is_wares) {
275 game.send_player_command(*new Widelands::CmdSetWareTargetQuantity(
276 game.get_gametime(), player_->player_number(), serial_, index, new_amount));
277 } else {
278 game.send_player_command(*new Widelands::CmdSetWorkerTargetQuantity(
279 game.get_gametime(), player_->player_number(), serial_, index, new_amount));
280 }
281 }
282 }
283}
284
285void EconomyOptionsWindow::EconomyOptionsPanel::reset_target() {
286 Widelands::Game& game = dynamic_cast<Widelands::Game&>(player_->egbase());
287 const bool is_wares = type_ == Widelands::wwWARE;
288 const auto& items = is_wares ? player_->tribe().wares() : player_->tribe().workers();
289 const PredefinedTargets settings = economy_options_window_->get_selected_target();
290 for (const Widelands::DescriptionIndex& index : items) {
291 if (display_.ware_selected(index)) {
292 if (is_wares) {
293 game.send_player_command(*new Widelands::CmdSetWareTargetQuantity(
294 game.get_gametime(), player_->player_number(), serial_, index, settings.wares.at(index)));
295 } else {
296 game.send_player_command(*new Widelands::CmdSetWorkerTargetQuantity(
297 game.get_gametime(), player_->player_number(), serial_, index, settings.workers.at(index)));
298 }
299 }
300 }
301}
302
303void EconomyOptionsWindow::update_profiles(const std::string& select) {
304 dropdown_.clear();
305 for (const auto& pair : predefined_targets_) {
306 dropdown_.add(_(pair.first), pair.first, nullptr, pair.first == select);
307 }
308}
309
310struct SaveProfileWindow : public UI::Window {
311 void update_save_enabled() {
312 const std::string& text = profile_name_.text();
313 if (text.empty() || text == kDefaultEconomyProfile) {
314 save_.set_enabled(false);
315 save_.set_tooltip(text.empty() ? _("The profile name cannot be empty") :
316 _("The default profile cannot be overwritten"));
317 } else {
318 save_.set_enabled(true);
319 save_.set_tooltip(_("Save the profile under this name"));
320 }
321 }
322
323 void table_selection_changed() {
324 if (!table_.has_selection()) {
325 delete_.set_enabled(false);
326 delete_.set_tooltip("");
327 return;
328 }
329 const std::string& sel = table_[table_.selection_index()];
330 if (sel == kDefaultEconomyProfile) {
331 delete_.set_tooltip(_("The default profile cannot be deleted"));
332 delete_.set_enabled(false);
333 } else {
334 delete_.set_tooltip(_("Delete the selected profiles"));
335 delete_.set_enabled(true);
336 }
337 profile_name_.set_text(sel);
338 update_save_enabled();
339 }
340
341 void close(bool ok) {
342 end_modal(ok ? UI::Panel::Returncodes::kOk : UI::Panel::Returncodes::kBack);
343 die();
344 }
345
346 void update_table() {
347 table_.clear();
348 for (const auto& pair : economy_options_->get_predefined_targets()) {
349 table_.add(pair.first).set_string(0, _(pair.first));
350 }
351 layout();
352 }
353
354 void save() {
355 const std::string name = profile_name_.text();
356 assert(!name.empty());
357 assert(name != kDefaultEconomyProfile);
358 for (const auto& pair : economy_options_->get_predefined_targets()) {
359 if (pair.first == name) {
360 UI::WLMessageBox m(this, _("Overwrite?"),
361 _("A profile with this name already exists.\nDo you wish to replace it?"),
362 UI::WLMessageBox::MBoxType::kOkCancel);
363 if (m.run<UI::Panel::Returncodes>() != UI::Panel::Returncodes::kOk) {
364 return;
365 }
366 break;
367 }
368 }
369 economy_options_->do_create_target(name);
370 close(true);
371 }
372
373 void delete_selected() {
374 assert(table_.has_selection());
375 auto& map = economy_options_->get_predefined_targets();
376 const std::string& name = table_[table_.selection_index()];
377 assert(name != kDefaultEconomyProfile);
378 for (auto it = map.begin(); it != map.end(); ++it) {
379 if (it->first == name) {
380 map.erase(it);
381 break;
382 }
383 }
384 economy_options_->save_targets();
385 update_table();
386 }
387
388 explicit SaveProfileWindow(UI::Panel* parent, EconomyOptionsWindow* eco)
389 : UI::Window(parent, "save_economy_options_profile", 0, 0, 0, 0, _("Save Profile")),
390 economy_options_(eco),
391 main_box_(this, 0, 0, UI::Box::Vertical),
392 table_box_(&main_box_, 0, 0, UI::Box::Vertical),
393 table_(&table_box_, 0, 0, 460, 120, UI::PanelStyle::kWui),
394 buttons_box_(&main_box_, 0, 0, UI::Box::Horizontal),
395 profile_name_(&buttons_box_, 0, 0, 240, 0, 0, UI::PanelStyle::kWui),
396 save_(&buttons_box_, "save", 0, 0, 80, 34, UI::ButtonStyle::kWuiPrimary, _("Save")),
397 cancel_(&buttons_box_, "cancel", 0, 0, 80, 34, UI::ButtonStyle::kWuiSecondary, _("Cancel")),
398 delete_(&buttons_box_, "delete", 0, 0, 80, 34, UI::ButtonStyle::kWuiSecondary, _("Delete")) {
399 table_.add_column(200, _("Existing Profiles"));
400 update_table();
401
402 table_.selected.connect([this](uint32_t) { table_selection_changed(); });
403 profile_name_.changed.connect([this] { update_save_enabled(); });
404 profile_name_.ok.connect([this] { save(); });
405 profile_name_.cancel.connect([this] { close(false); });
406 save_.sigclicked.connect([this] { save(); });
407 cancel_.sigclicked.connect([this] { close(false); });
408 delete_.sigclicked.connect([this] { delete_selected(); });
409
410 table_box_.add(&table_, UI::Box::Resizing::kFullSize);
411 buttons_box_.add(&profile_name_, UI::Box::Resizing::kFullSize);
412 buttons_box_.add(&save_);
413 buttons_box_.add(&cancel_);
414 buttons_box_.add(&delete_);
415 main_box_.add(&table_box_, UI::Box::Resizing::kFullSize);
416 main_box_.add(&buttons_box_, UI::Box::Resizing::kFullSize);
417 set_center_panel(&main_box_);
418
419 table_selection_changed();
420 update_save_enabled();
421 }
422 ~SaveProfileWindow() {
423 }
424
425private:
426 EconomyOptionsWindow* economy_options_;
427 UI::Box main_box_;
428 UI::Box table_box_;
429 UI::Table<const std::string&> table_;
430 UI::Box buttons_box_;
431 UI::EditBox profile_name_;
432 UI::Button save_;
433 UI::Button cancel_;
434 UI::Button delete_;
435};
436
437void EconomyOptionsWindow::create_target() {
438 std::unique_ptr<SaveProfileWindow> s (new SaveProfileWindow(get_parent(), this));
439 s->run<UI::Panel::Returncodes>();
440}
441
442void EconomyOptionsWindow::do_create_target(const std::string& name) {
443 assert(!name.empty());
444 assert(name != kDefaultEconomyProfile);
445 const Widelands::Tribes& tribes = player_->egbase().tribes();
446 const Widelands::TribeDescr& tribe = player_->tribe();
447 Widelands::Economy* economy = player_->get_economy(serial_);
448 PredefinedTargets t;
449 for (Widelands::DescriptionIndex di : tribe.wares()) {
450 if (tribes.get_ware_descr(di)->has_demand_check(tribe.name())) {
451 t.wares[di] = economy->ware_target_quantity(di).permanent;
452 }
453 }
454 for (Widelands::DescriptionIndex di : tribe.workers()) {
455 if (tribes.get_worker_descr(di)->has_demand_check()) {
456 t.workers[di] = economy->worker_target_quantity(di).permanent;
457 }
458 }
459 predefined_targets_[name] = t;
460
461 save_targets();
462 update_profiles(name);
463}
464
465void EconomyOptionsWindow::save_targets() {
466 const Widelands::Tribes& tribes = player_->egbase().tribes();
467 Profile profile;
468
469 std::map<std::string, uint32_t> serials;
470 for (const auto& pair : predefined_targets_) {
471 if (pair.first != kDefaultEconomyProfile) {
472 serials.emplace(pair.first, serials.size());
473 }
474 }
475 Section& global_section = profile.create_section(kDefaultEconomyProfile.c_str());
476 for (const auto& pair : serials) {
477 global_section.set_string(std::to_string(pair.second).c_str(), pair.first);
478 }
479
480 for (const auto& pair : predefined_targets_) {
481 if (pair.first == kDefaultEconomyProfile) {
482 continue;
483 }
484 Section& section = profile.create_section(std::to_string(serials.at(pair.first)).c_str());
485 for (const auto& setting : pair.second.wares) {
486 section.set_natural(tribes.get_ware_descr(setting.first)->name().c_str(), setting.second);
487 }
488 for (const auto& setting : pair.second.workers) {
489 section.set_natural(tribes.get_worker_descr(setting.first)->name().c_str(), setting.second);
490 }
491 }
492
493 g_fs->ensure_directory_exists(kEconomyProfilesDir);
494 std::string complete_filename = kEconomyProfilesDir + g_fs->file_separator() + player_->tribe().name();
495 profile.write(complete_filename.c_str(), false);
496}
497
498void EconomyOptionsWindow::read_targets(const std::string& select) {
499 predefined_targets_.clear();
500 const Widelands::Tribes& tribes = player_->egbase().tribes();
501 const Widelands::TribeDescr& tribe = player_->tribe();
502
503 {
504 PredefinedTargets t;
505 for (Widelands::DescriptionIndex di : tribe.wares()) {
506 const Widelands::WareDescr* descr = tribes.get_ware_descr(di);
507 if (descr->has_demand_check(tribe.name())) {
508 t.wares.emplace(di, descr->default_target_quantity(tribe.name()));
509 }
510 }
511 for (Widelands::DescriptionIndex di : tribe.workers()) {
512 const Widelands::WorkerDescr* descr = tribes.get_worker_descr(di);
513 if (descr->has_demand_check()) {
514 t.workers.emplace(di, descr->default_target_quantity());
515 }
516 }
517 predefined_targets_.emplace(kDefaultEconomyProfile, t);
518 }
519
520 std::string complete_filename = kEconomyProfilesDir + g_fs->file_separator() + player_->tribe().name();
521 Profile profile;
522 profile.read(complete_filename.c_str());
523
524 Section* global_section = profile.get_section(kDefaultEconomyProfile);
525 if (global_section) {
526 std::map<std::string, std::string> serials;
527 while (Section::Value* v = global_section->get_next_val()) {
528 serials.emplace(std::string(v->get_name()), v->get_string());
529 }
530
531 for (const auto& pair : serials) {
532 Section* section = profile.get_section(pair.first);
533 PredefinedTargets t;
534 while (Section::Value* v = section->get_next_val()) {
535 const std::string name = std::string(v->get_name());
536 Widelands::DescriptionIndex di = tribes.ware_index(name);
537 if (di == Widelands::INVALID_INDEX) {
538 di = tribes.worker_index(name);
539 assert(di != Widelands::INVALID_INDEX);
540 t.workers.emplace(di, v->get_natural());
195 } else {541 } else {
196 game.send_player_command(*new Widelands::CmdSetWorkerTargetQuantity(542 t.wares.emplace(di, v->get_natural());
197 game.get_gametime(), player_->player_number(), serial_, index,
198 tq.permanent + amount));
199 }543 }
200 }544 }
545 predefined_targets_.emplace(pair.second, t);
201 }546 }
202 }547 }
203}
204548
205void EconomyOptionsWindow::EconomyOptionsPanel::reset_target() {549 update_profiles(select);
206 Widelands::Game& game = dynamic_cast<Widelands::Game&>(player_->egbase());
207 const bool is_wares = type_ == Widelands::wwWARE;
208 const auto& items = is_wares ? player_->tribe().wares() : player_->tribe().workers();
209 for (const Widelands::DescriptionIndex& index : items) {
210 if (display_.ware_selected(index)) {
211 if (is_wares) {
212 game.send_player_command(*new Widelands::CmdResetWareTargetQuantity(
213 game.get_gametime(), player_->player_number(), serial_, index));
214 } else {
215 game.send_player_command(*new Widelands::CmdResetWorkerTargetQuantity(
216 game.get_gametime(), player_->player_number(), serial_, index));
217 }
218 }
219 }
220}550}
221551
=== modified file 'src/wui/economy_options_window.h'
--- src/wui/economy_options_window.h 2019-02-23 11:00:49 +0000
+++ src/wui/economy_options_window.h 2019-05-06 13:51:46 +0000
@@ -20,20 +20,48 @@
20#ifndef WL_WUI_ECONOMY_OPTIONS_WINDOW_H20#ifndef WL_WUI_ECONOMY_OPTIONS_WINDOW_H
21#define WL_WUI_ECONOMY_OPTIONS_WINDOW_H21#define WL_WUI_ECONOMY_OPTIONS_WINDOW_H
2222
23#include <map>
23#include <memory>24#include <memory>
25#include <string>
2426
25#include "economy/economy.h"27#include "economy/economy.h"
26#include "logic/map_objects/tribes/tribe_descr.h"28#include "logic/map_objects/tribes/tribe_descr.h"
27#include "notifications/notifications.h"29#include "notifications/notifications.h"
28#include "ui_basic/box.h"30#include "ui_basic/box.h"
31#include "ui_basic/dropdown.h"
29#include "ui_basic/tabpanel.h"32#include "ui_basic/tabpanel.h"
30#include "ui_basic/window.h"33#include "ui_basic/window.h"
31#include "wui/waresdisplay.h"34#include "wui/waresdisplay.h"
3235
36const std::string kDefaultEconomyProfile = "Default";
37
33struct EconomyOptionsWindow : public UI::Window {38struct EconomyOptionsWindow : public UI::Window {
34 EconomyOptionsWindow(UI::Panel* parent, Widelands::Economy* economy, bool can_act);39 EconomyOptionsWindow(UI::Panel* parent, Widelands::Economy* economy, bool can_act);
35 ~EconomyOptionsWindow();40 ~EconomyOptionsWindow();
3641
42 struct PredefinedTargets {
43 using Targets = std::map<Widelands::DescriptionIndex, uint32_t>;
44 Targets wares;
45 Targets workers;
46 };
47
48 void create_target();
49 void do_create_target(const std::string&);
50 void save_targets();
51 void read_targets(const std::string& = kDefaultEconomyProfile);
52 void update_profiles(const std::string&);
53 std::map<std::string, PredefinedTargets>& get_predefined_targets() {
54 return predefined_targets_;
55 }
56 const PredefinedTargets& get_selected_target() const {
57 return predefined_targets_.at(dropdown_.get_selected());
58 }
59
60 void change_target(int amount);
61 void reset_target();
62
63 void layout() override;
64
37private:65private:
38 struct TargetWaresDisplay : public AbstractWaresDisplay {66 struct TargetWaresDisplay : public AbstractWaresDisplay {
39 TargetWaresDisplay(UI::Panel* const parent,67 TargetWaresDisplay(UI::Panel* const parent,
@@ -59,14 +87,17 @@
59 */87 */
60 struct EconomyOptionsPanel : UI::Box {88 struct EconomyOptionsPanel : UI::Box {
61 EconomyOptionsPanel(UI::Panel* parent,89 EconomyOptionsPanel(UI::Panel* parent,
90 EconomyOptionsWindow* eco_window,
62 Widelands::Serial serial,91 Widelands::Serial serial,
63 Widelands::Player* player,92 Widelands::Player* player,
64 bool can_act,93 bool can_act,
65 Widelands::WareWorker type);94 Widelands::WareWorker type,
95 int32_t min_w);
6696
67 void set_economy(Widelands::Serial serial);97 void set_economy(Widelands::Serial serial);
68 void change_target(int amount);98 void change_target(int amount);
69 void reset_target();99 void reset_target();
100 void update_desired_size() override;
70101
71 private:102 private:
72 Widelands::Serial serial_;103 Widelands::Serial serial_;
@@ -74,17 +105,23 @@
74 Widelands::WareWorker type_;105 Widelands::WareWorker type_;
75 bool can_act_;106 bool can_act_;
76 TargetWaresDisplay display_;107 TargetWaresDisplay display_;
108 EconomyOptionsWindow* economy_options_window_;
77 };109 };
78110
79 /// Actions performed when a NoteEconomyWindow is received.111 /// Actions performed when a NoteEconomyWindow is received.
80 void on_economy_note(const Widelands::NoteEconomy& note);112 void on_economy_note(const Widelands::NoteEconomy& note);
81113
114 UI::Box main_box_;
82 Widelands::Serial serial_;115 Widelands::Serial serial_;
83 Widelands::Player* player_;116 Widelands::Player* player_;
84 UI::TabPanel tabpanel_;117 UI::TabPanel tabpanel_;
85 EconomyOptionsPanel* ware_panel_;118 EconomyOptionsPanel* ware_panel_;
86 EconomyOptionsPanel* worker_panel_;119 EconomyOptionsPanel* worker_panel_;
87 std::unique_ptr<Notifications::Subscriber<Widelands::NoteEconomy>> economynotes_subscriber_;120 std::unique_ptr<Notifications::Subscriber<Widelands::NoteEconomy>> economynotes_subscriber_;
121
122 std::map<std::string, PredefinedTargets> predefined_targets_;
123 UI::Box dropdown_box_;
124 UI::Dropdown<std::string> dropdown_;
88};125};
89126
90#endif // end of include guard: WL_WUI_ECONOMY_OPTIONS_WINDOW_H127#endif // end of include guard: WL_WUI_ECONOMY_OPTIONS_WINDOW_H
91128
=== modified file 'src/wui/inputqueuedisplay.cc'
--- src/wui/inputqueuedisplay.cc 2019-04-25 06:40:24 +0000
+++ src/wui/inputqueuedisplay.cc 2019-05-06 13:51:46 +0000
@@ -71,7 +71,7 @@
7171
72 uint32_t priority_button_height = show_only ? 0 : 3 * PriorityButtonSize;72 uint32_t priority_button_height = show_only ? 0 : 3 * PriorityButtonSize;
73 uint32_t image_height =73 uint32_t image_height =
74 show_only ? WARE_MENU_PIC_HEIGHT : std::max<int32_t>(WARE_MENU_PIC_HEIGHT, ph);74 show_only ? kWareMenuPicHeight : std::max<int32_t>(kWareMenuPicHeight, ph);
7575
76 total_height_ = std::max(priority_button_height, image_height) + 2 * Border;76 total_height_ = std::max(priority_button_height, image_height) + 2 * Border;
7777
@@ -91,7 +91,7 @@
91 */91 */
92void InputQueueDisplay::max_size_changed() {92void InputQueueDisplay::max_size_changed() {
93 uint32_t pbs = show_only_ ? 0 : PriorityButtonSize;93 uint32_t pbs = show_only_ ? 0 : PriorityButtonSize;
94 uint32_t ctrl_b_size = show_only_ ? 0 : 2 * WARE_MENU_PIC_WIDTH;94 uint32_t ctrl_b_size = show_only_ ? 0 : 2 * kWareMenuPicWidth;
9595
96 cache_size_ = queue_.get_max_size();96 cache_size_ = queue_.get_max_size();
9797
@@ -140,7 +140,7 @@
140140
141 Vector2i point = Vector2i::zero();141 Vector2i point = Vector2i::zero();
142 point.x = Border + (show_only_ ? 0 : CellWidth + CellSpacing);142 point.x = Border + (show_only_ ? 0 : CellWidth + CellSpacing);
143 point.y = Border + (total_height_ - 2 * Border - WARE_MENU_PIC_HEIGHT) / 2;143 point.y = Border + (total_height_ - 2 * Border - kWareMenuPicHeight) / 2;
144144
145 for (; nr_inputs_to_draw; --nr_inputs_to_draw, point.x += CellWidth + CellSpacing) {145 for (; nr_inputs_to_draw; --nr_inputs_to_draw, point.x += CellWidth + CellSpacing) {
146 dst.blitrect(Vector2i(point.x, point.y), icon_, Recti(0, 0, icon_->width(), icon_->height()),146 dst.blitrect(Vector2i(point.x, point.y), icon_, Recti(0, 0, icon_->width(), icon_->height()),
@@ -240,12 +240,12 @@
240 return;240 return;
241241
242 uint32_t x = Border;242 uint32_t x = Border;
243 uint32_t y = Border + (total_height_ - 2 * Border - WARE_MENU_PIC_WIDTH) / 2;243 uint32_t y = Border + (total_height_ - 2 * Border - kWareMenuPicWidth) / 2;
244244
245 boost::format tooltip_format("%s<br><p><font size=%d bold=0>%s<br>%s</font></p>");245 boost::format tooltip_format("%s<br><p><font size=%d bold=0>%s<br>%s</font></p>");
246246
247 decrease_max_fill_ = new UI::Button(247 decrease_max_fill_ = new UI::Button(
248 this, "decrease_max_fill", x, y, WARE_MENU_PIC_WIDTH, WARE_MENU_PIC_HEIGHT,248 this, "decrease_max_fill", x, y, kWareMenuPicWidth, kWareMenuPicHeight,
249 UI::ButtonStyle::kWuiMenu, g_gr->images().get("images/ui_basic/scrollbar_left.png"),249 UI::ButtonStyle::kWuiMenu, g_gr->images().get("images/ui_basic/scrollbar_left.png"),
250 (tooltip_format250 (tooltip_format
251 /** TRANSLATORS: Button tooltip in in a building's wares input queue */251 /** TRANSLATORS: Button tooltip in in a building's wares input queue */
@@ -262,7 +262,7 @@
262 x = Border + (cache_size_ + 1) * (CellWidth + CellSpacing);262 x = Border + (cache_size_ + 1) * (CellWidth + CellSpacing);
263263
264 increase_max_fill_ = new UI::Button(264 increase_max_fill_ = new UI::Button(
265 this, "increase_max_fill", x, y, WARE_MENU_PIC_WIDTH, WARE_MENU_PIC_HEIGHT,265 this, "increase_max_fill", x, y, kWareMenuPicWidth, kWareMenuPicHeight,
266 UI::ButtonStyle::kWuiMenu, g_gr->images().get("images/ui_basic/scrollbar_right.png"),266 UI::ButtonStyle::kWuiMenu, g_gr->images().get("images/ui_basic/scrollbar_right.png"),
267 (tooltip_format267 (tooltip_format
268 /** TRANSLATORS: Button tooltip in a building's wares input queue */268 /** TRANSLATORS: Button tooltip in a building's wares input queue */
269269
=== modified file 'src/wui/inputqueuedisplay.h'
--- src/wui/inputqueuedisplay.h 2019-04-23 14:53:35 +0000
+++ src/wui/inputqueuedisplay.h 2019-05-06 13:51:46 +0000
@@ -49,7 +49,7 @@
49 */49 */
50class InputQueueDisplay : public UI::Panel {50class InputQueueDisplay : public UI::Panel {
51public:51public:
52 enum { CellWidth = WARE_MENU_PIC_WIDTH, CellSpacing = 2, Border = 4, PriorityButtonSize = 10 };52 enum { CellWidth = kWareMenuPicWidth, CellSpacing = 2, Border = 4, PriorityButtonSize = 10 };
5353
54 InputQueueDisplay(UI::Panel* parent,54 InputQueueDisplay(UI::Panel* parent,
55 int32_t x,55 int32_t x,
5656
=== modified file 'src/wui/waresdisplay.cc'
--- src/wui/waresdisplay.cc 2019-02-23 11:00:49 +0000
+++ src/wui/waresdisplay.cc 2019-05-06 13:51:46 +0000
@@ -35,8 +35,9 @@
35#include "logic/map_objects/tribes/ware_descr.h"35#include "logic/map_objects/tribes/ware_descr.h"
36#include "logic/map_objects/tribes/worker.h"36#include "logic/map_objects/tribes/worker.h"
37#include "logic/player.h"37#include "logic/player.h"
38#include "ui_basic/window.h"
3839
39const int WARE_MENU_INFO_SIZE = 12;40constexpr int kWareMenuInfoSize = 12;
4041
41AbstractWaresDisplay::AbstractWaresDisplay(42AbstractWaresDisplay::AbstractWaresDisplay(
42 UI::Panel* const parent,43 UI::Panel* const parent,
@@ -46,7 +47,9 @@
46 Widelands::WareWorker type,47 Widelands::WareWorker type,
47 bool selectable,48 bool selectable,
48 boost::function<void(Widelands::DescriptionIndex, bool)> callback_function,49 boost::function<void(Widelands::DescriptionIndex, bool)> callback_function,
49 bool horizontal)50 bool horizontal,
51 int32_t hgap,
52 int32_t vgap)
50 : // Size is set when add_warelist is called, as it depends on the type_.53 : // Size is set when add_warelist is called, as it depends on the type_.
51 UI::Panel(parent, x, y, 0, 0),54 UI::Panel(parent, x, y, 0, 0),
52 tribe_(tribe),55 tribe_(tribe),
@@ -57,6 +60,8 @@
5760
58 selectable_(selectable),61 selectable_(selectable),
59 horizontal_(horizontal),62 horizontal_(horizontal),
63 hgap_(hgap),
64 vgap_(vgap),
60 selection_anchor_(Widelands::INVALID_INDEX),65 selection_anchor_(Widelands::INVALID_INDEX),
61 callback_function_(callback_function) {66 callback_function_(callback_function) {
62 for (const Widelands::DescriptionIndex& index : indices_) {67 for (const Widelands::DescriptionIndex& index : indices_) {
@@ -67,22 +72,65 @@
6772
68 curware_.set_text(_("Stock"));73 curware_.set_text(_("Stock"));
6974
70 // Find out geometry from icons_order75 graphic_resolution_changed_subscriber_ = Notifications::subscribe<GraphicResolutionChanged>(
71 unsigned int columns = icons_order().size();76 [this](const GraphicResolutionChanged&) {
72 unsigned int rows = 0;77 recalc_desired_size(true);
73 for (unsigned int i = 0; i < icons_order().size(); i++)78 });
74 if (icons_order()[i].size() > rows)79
75 rows = icons_order()[i].size();80 recalc_desired_size(false);
81}
82
83Widelands::Extent AbstractWaresDisplay::get_extent() const {
84 int16_t columns = 0;
85 int16_t rows = 0;
86 for (const auto& pair : icons_order_coords()) {
87 columns = std::max(columns, pair.second.x);
88 rows = std::max(rows, pair.second.y);
89 }
90 // We cound from 0 up
91 ++columns;
92 ++rows;
93
76 if (horizontal_) {94 if (horizontal_) {
77 unsigned int s = columns;95 const int16_t s = columns;
78 columns = rows;96 columns = rows;
79 rows = s;97 rows = s;
80 }98 }
99 return Widelands::Extent(columns, rows);
100}
101
102void AbstractWaresDisplay::set_hgap(int32_t gap) {
103 hgap_ = gap;
104 recalc_desired_size(true);
105}
106
107void AbstractWaresDisplay::set_vgap(int32_t gap) {
108 vgap_ = gap;
109 recalc_desired_size(true);
110}
111
112void AbstractWaresDisplay::recalc_desired_size(bool relayout) {
113 relayout_icons_order_coords();
114
115 // Find out geometry from icons_order
116 const Widelands::Extent size = get_extent();
81117
82 // 25 is height of curware_ text118 // 25 is height of curware_ text
83 set_desired_size(119 set_desired_size(
84 columns * (WARE_MENU_PIC_WIDTH + WARE_MENU_PIC_PAD_X) + 1,120 size.w * (kWareMenuPicWidth + hgap_) + 1,
85 rows * (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + WARE_MENU_PIC_PAD_Y) + 1 + 25);121 size.h * (kWareMenuPicHeight + kWareMenuInfoSize + vgap_) + 1 + 25);
122
123 if (relayout) {
124 // Since we are usually stacked deep within other panels, we need to tell our highest parent window to relayout
125 UI::Panel* p = this;
126 while (p->get_parent()) {
127 p = p->get_parent();
128 if (dynamic_cast<UI::Window*>(p)) {
129 p->layout();
130 return;
131 }
132 }
133 }
86}134}
87135
88bool AbstractWaresDisplay::handle_mousemove(uint8_t state, int32_t x, int32_t y, int32_t, int32_t) {136bool AbstractWaresDisplay::handle_mousemove(uint8_t state, int32_t x, int32_t y, int32_t, int32_t) {
@@ -162,21 +210,33 @@
162 * DescriptionIndex::null() if the given point is outside the range.210 * DescriptionIndex::null() if the given point is outside the range.
163 */211 */
164Widelands::DescriptionIndex AbstractWaresDisplay::ware_at_point(int32_t x, int32_t y) const {212Widelands::DescriptionIndex AbstractWaresDisplay::ware_at_point(int32_t x, int32_t y) const {
165 if (x < 0 || y < 0)213 // Graphical offset
166 return Widelands::INVALID_INDEX;214 x -= 2;
167215 y -= 2;
168 unsigned int i = x / (WARE_MENU_PIC_WIDTH + WARE_MENU_PIC_PAD_X);216
169 unsigned int j = y / (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + WARE_MENU_PIC_PAD_Y);217 if (x < 0 || y < 0) {
218 return Widelands::INVALID_INDEX;
219 }
220
221 int i = x / (kWareMenuPicWidth + hgap_);
222 int j = y / (kWareMenuPicHeight + kWareMenuInfoSize + vgap_);
223 if (kWareMenuPicWidth * (i + 1) + hgap_ * i < x ||
224 (kWareMenuPicHeight + kWareMenuInfoSize) * (j + 1) + vgap_ * j < y) {
225 // Not on the ware, but on the space between
226 return Widelands::INVALID_INDEX;
227 }
170 if (horizontal_) {228 if (horizontal_) {
171 unsigned int s = i;229 int s = i;
172 i = j;230 i = j;
173 j = s;231 j = s;
174 }232 }
175 if (i < icons_order().size() && j < icons_order()[i].size()) {233 for (const auto& pair : icons_order_coords()) {
176 const Widelands::DescriptionIndex& ware = icons_order()[i][j];234 if (pair.second.x == i && pair.second.y == j) {
177 assert(hidden_.count(ware) == 1);235 assert(hidden_.count(pair.first) == 1);
178 if (!(hidden_.find(ware)->second)) {236 if (!(hidden_.find(pair.first)->second)) {
179 return ware;237 return pair.first;
238 }
239 break;
180 }240 }
181 }241 }
182242
@@ -199,15 +259,13 @@
199 Vector2i anchor_pos = ware_position(selection_anchor_);259 Vector2i anchor_pos = ware_position(selection_anchor_);
200 // Add an offset to make sure the anchor line and column will be260 // Add an offset to make sure the anchor line and column will be
201 // selected when selecting in topleft direction261 // selected when selecting in topleft direction
202 int32_t anchor_x = anchor_pos.x + WARE_MENU_PIC_WIDTH / 2;262 int32_t anchor_x = anchor_pos.x + kWareMenuPicWidth / 2;
203 int32_t anchor_y = anchor_pos.y + WARE_MENU_PIC_HEIGHT / 2;263 int32_t anchor_y = anchor_pos.y + kWareMenuPicHeight / 2;
204264
205 unsigned int left_ware_idx = anchor_x / (WARE_MENU_PIC_WIDTH + WARE_MENU_PIC_PAD_X);265 unsigned int left_ware_idx = anchor_x / (kWareMenuPicWidth + hgap_);
206 unsigned int top_ware_idx =266 unsigned int top_ware_idx = anchor_y / (kWareMenuPicHeight + kWareMenuInfoSize + vgap_);
207 anchor_y / (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + WARE_MENU_PIC_PAD_Y);267 unsigned int right_ware_idx = x / (kWareMenuPicWidth + hgap_);
208 unsigned int right_ware_idx = x / (WARE_MENU_PIC_WIDTH + WARE_MENU_PIC_PAD_X);268 unsigned int bottoware_idx_ = y / (kWareMenuPicHeight + kWareMenuInfoSize + vgap_);
209 unsigned int bottoware_idx_ =
210 y / (WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + WARE_MENU_PIC_PAD_Y);
211 unsigned int tmp;269 unsigned int tmp;
212270
213 // Reverse col/row and anchor/endpoint if needed271 // Reverse col/row and anchor/endpoint if needed
@@ -271,26 +329,43 @@
271 NEVER_HERE();329 NEVER_HERE();
272}330}
273331
274const Widelands::TribeDescr::WaresOrderCoords& AbstractWaresDisplay::icons_order_coords() const {332const WaresOrderCoords& AbstractWaresDisplay::icons_order_coords() const {
275 switch (type_) {333 assert(!order_coords_.empty());
276 case Widelands::wwWARE:334 return order_coords_;
277 return tribe_.wares_order_coords();335}
278 case Widelands::wwWORKER:336
279 return tribe_.workers_order_coords();337void AbstractWaresDisplay::relayout_icons_order_coords() {
338 order_coords_.clear();
339 const int column_number = icons_order().size();
340 const int column_max_size = (g_gr->get_yres() - 290) / (kWareMenuPicHeight + vgap_ + kWareMenuInfoSize);
341
342 int16_t column_index_to_apply = 0;
343 for (int16_t column_index = 0; column_index < column_number; ++column_index) {
344 const std::vector<Widelands::DescriptionIndex>& column = icons_order().at(column_index);
345 const int row_number = column.size();
346 int16_t row_index_to_apply = 0;
347 for (int16_t row_index = 0; row_index < row_number; ++row_index) {
348 order_coords_.emplace(column.at(row_index), Widelands::Coords(column_index_to_apply, row_index_to_apply));
349 ++row_index_to_apply;
350 if (row_index_to_apply > column_max_size) {
351 row_index_to_apply = 0;
352 ++column_index_to_apply;
353 }
354 }
355 if (row_index_to_apply > 0) {
356 ++column_index_to_apply;
357 }
280 }358 }
281 NEVER_HERE();
282}359}
283360
284Vector2i AbstractWaresDisplay::ware_position(Widelands::DescriptionIndex id) const {361Vector2i AbstractWaresDisplay::ware_position(Widelands::DescriptionIndex id) const {
285 Vector2i p(2, 2);362 Vector2i p(2, 2);
286 if (horizontal_) {363 if (horizontal_) {
287 p.x += icons_order_coords()[id].second * (WARE_MENU_PIC_WIDTH + WARE_MENU_PIC_PAD_X);364 p.x += icons_order_coords().at(id).y * (kWareMenuPicWidth + hgap_);
288 p.y += icons_order_coords()[id].first *365 p.y += icons_order_coords().at(id).x * (kWareMenuPicHeight + vgap_ + kWareMenuInfoSize);
289 (WARE_MENU_PIC_HEIGHT + WARE_MENU_PIC_PAD_Y + WARE_MENU_INFO_SIZE);
290 } else {366 } else {
291 p.x += icons_order_coords()[id].first * (WARE_MENU_PIC_WIDTH + WARE_MENU_PIC_PAD_X);367 p.x += icons_order_coords().at(id).x * (kWareMenuPicWidth + hgap_);
292 p.y += icons_order_coords()[id].second *368 p.y += icons_order_coords().at(id).y * (kWareMenuPicHeight + vgap_ + kWareMenuInfoSize);
293 (WARE_MENU_PIC_HEIGHT + WARE_MENU_PIC_PAD_Y + WARE_MENU_INFO_SIZE);
294 }369 }
295 return p;370 return p;
296}371}
@@ -326,15 +401,15 @@
326 const Image* icon = type_ == Widelands::wwWORKER ? tribe_.get_worker_descr(id)->icon() :401 const Image* icon = type_ == Widelands::wwWORKER ? tribe_.get_worker_descr(id)->icon() :
327 tribe_.get_ware_descr(id)->icon();402 tribe_.get_ware_descr(id)->icon();
328403
329 dst.blit(p + Vector2i((w - WARE_MENU_PIC_WIDTH) / 2, 1), icon);404 dst.blit(p + Vector2i((w - kWareMenuPicWidth) / 2, 1), icon);
330405
331 dst.fill_rect(Recti(p + Vector2i(0, WARE_MENU_PIC_HEIGHT), w, WARE_MENU_INFO_SIZE),406 dst.fill_rect(Recti(p + Vector2i(0, kWareMenuPicHeight), w, kWareMenuInfoSize),
332 info_color_for_ware(id));407 info_color_for_ware(id));
333408
334 std::shared_ptr<const UI::RenderedText> rendered_text =409 std::shared_ptr<const UI::RenderedText> rendered_text =
335 UI::g_fh->render(as_waresinfo(info_for_ware(id)));410 UI::g_fh->render(as_waresinfo(info_for_ware(id)));
336 rendered_text->draw(dst, Vector2i(p.x + w - rendered_text->width() - 1,411 rendered_text->draw(dst, Vector2i(p.x + w - rendered_text->width() - 1,
337 p.y + WARE_MENU_PIC_HEIGHT + WARE_MENU_INFO_SIZE + 1 -412 p.y + kWareMenuPicHeight + kWareMenuInfoSize + 1 -
338 rendered_text->height()));413 rendered_text->height()));
339}414}
340415
341416
=== modified file 'src/wui/waresdisplay.h'
--- src/wui/waresdisplay.h 2019-02-23 11:00:49 +0000
+++ src/wui/waresdisplay.h 2019-05-06 13:51:46 +0000
@@ -20,6 +20,7 @@
20#ifndef WL_WUI_WARESDISPLAY_H20#ifndef WL_WUI_WARESDISPLAY_H
21#define WL_WUI_WARESDISPLAY_H21#define WL_WUI_WARESDISPLAY_H
2222
23#include <memory>
23#include <vector>24#include <vector>
2425
25#include "logic/map_objects/tribes/tribe_descr.h"26#include "logic/map_objects/tribes/tribe_descr.h"
@@ -36,6 +37,8 @@
36struct WareList;37struct WareList;
37} // namespace Widelands38} // namespace Widelands
3839
40using WaresOrderCoords = std::map<Widelands::DescriptionIndex, Widelands::Coords>;
41
39/**42/**
40 * Display wares or workers together with some string (typically a number)43 * Display wares or workers together with some string (typically a number)
41 * in the style of the @ref WarehouseWindow.44 * in the style of the @ref WarehouseWindow.
@@ -54,7 +57,9 @@
54 CLANG_DIAG_OFF("-Wunknown-pragmas") CLANG_DIAG_OFF("-Wzero-as-null-pointer-constant")57 CLANG_DIAG_OFF("-Wunknown-pragmas") CLANG_DIAG_OFF("-Wzero-as-null-pointer-constant")
55 boost::function<void(Widelands::DescriptionIndex, bool)> callback_function = 0,58 boost::function<void(Widelands::DescriptionIndex, bool)> callback_function = 0,
56 CLANG_DIAG_ON("-Wzero-as-null-pointer-constant")59 CLANG_DIAG_ON("-Wzero-as-null-pointer-constant")
57 CLANG_DIAG_ON("-Wunknown-pragmas") bool horizontal = false);60 CLANG_DIAG_ON("-Wunknown-pragmas") bool horizontal = false,
61 int32_t hgap = 3,
62 int32_t vgap = 4);
5863
59 bool64 bool
60 handle_mousemove(uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff) override;65 handle_mousemove(uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff) override;
@@ -74,6 +79,19 @@
74 return type_;79 return type_;
75 }80 }
7681
82 int32_t get_hgap() {
83 return hgap_;
84 }
85 int32_t get_vgap() {
86 return vgap_;
87 }
88 void set_hgap(int32_t);
89 void set_vgap(int32_t);
90
91 Widelands::Extent get_extent() const;
92
93 const WaresOrderCoords& icons_order_coords() const;
94
77protected:95protected:
78 void layout() override;96 void layout() override;
7997
@@ -82,7 +100,6 @@
82 virtual RGBColor info_color_for_ware(Widelands::DescriptionIndex);100 virtual RGBColor info_color_for_ware(Widelands::DescriptionIndex);
83101
84 const Widelands::TribeDescr::WaresOrder& icons_order() const;102 const Widelands::TribeDescr::WaresOrder& icons_order() const;
85 const Widelands::TribeDescr::WaresOrderCoords& icons_order_coords() const;
86 virtual Vector2i ware_position(Widelands::DescriptionIndex) const;103 virtual Vector2i ware_position(Widelands::DescriptionIndex) const;
87 void draw(RenderTarget&) override;104 void draw(RenderTarget&) override;
88 virtual void draw_ware(RenderTarget&, Widelands::DescriptionIndex);105 virtual void draw_ware(RenderTarget&, Widelands::DescriptionIndex);
@@ -110,6 +127,13 @@
110 WareListSelectionType in_selection_; // Wares in temporary anchored selection127 WareListSelectionType in_selection_; // Wares in temporary anchored selection
111 bool selectable_;128 bool selectable_;
112 bool horizontal_;129 bool horizontal_;
130 int32_t hgap_;
131 int32_t vgap_;
132
133 WaresOrderCoords order_coords_;
134
135 void relayout_icons_order_coords();
136 void recalc_desired_size(bool);
113137
114 /**138 /**
115 * The ware on which the mouse press has been performed.139 * The ware on which the mouse press has been performed.
@@ -117,6 +141,8 @@
117 */141 */
118 Widelands::DescriptionIndex selection_anchor_;142 Widelands::DescriptionIndex selection_anchor_;
119 boost::function<void(Widelands::DescriptionIndex, bool)> callback_function_;143 boost::function<void(Widelands::DescriptionIndex, bool)> callback_function_;
144
145 std::unique_ptr<Notifications::Subscriber<GraphicResolutionChanged>> graphic_resolution_changed_subscriber_;
120};146};
121147
122/*148/*

Subscribers

People subscribed via source and target branches

to status/vote changes: