1 /*
2  * Copyright (C) 2002-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  *
18  */
19 
20 #include "wui/soldiercapacitycontrol.h"
21 
22 #include "graphic/graphic.h"
23 #include "logic/map_objects/tribes/soldiercontrol.h"
24 #include "logic/player.h"
25 #include "ui_basic/button.h"
26 #include "ui_basic/radiobutton.h"
27 #include "ui_basic/textarea.h"
28 #include "wui/interactive_gamebase.h"
29 
30 using Widelands::SoldierControl;
31 
32 /**
33  * Widget to control the capacity of \ref MilitaryBuilding and \ref TrainingSite
34  * via \ref SoldierControl
35  */
36 struct SoldierCapacityControl : UI::Box {
37 	SoldierCapacityControl(UI::Panel* parent,
38 	                       InteractiveGameBase& igb,
39 	                       Widelands::Building& building);
40 
41 protected:
42 	void think() override;
43 
44 private:
45 	void change_soldier_capacity(int delta);
46 	void click_decrease();
47 	void click_increase();
48 
49 	InteractiveGameBase& igbase_;
50 	Widelands::Building& building_;
51 
52 	UI::Button decrease_;
53 	UI::Button increase_;
54 	UI::Textarea value_;
55 };
56 
SoldierCapacityControl(UI::Panel * parent,InteractiveGameBase & igb,Widelands::Building & building)57 SoldierCapacityControl::SoldierCapacityControl(UI::Panel* parent,
58                                                InteractiveGameBase& igb,
59                                                Widelands::Building& building)
60    : Box(parent, 0, 0, Horizontal),
61      igbase_(igb),
62      building_(building),
63      decrease_(this,
64                "decrease",
65                0,
66                0,
67                32,
68                32,
69                UI::ButtonStyle::kWuiMenu,
70                g_gr->images().get("images/wui/buildings/menu_down_train.png"),
71                _("Decrease capacity. Hold down Ctrl to set the capacity to the lowest value")),
72      increase_(this,
73                "increase",
74                0,
75                0,
76                32,
77                32,
78                UI::ButtonStyle::kWuiMenu,
79                g_gr->images().get("images/wui/buildings/menu_up_train.png"),
80                _("Increase capacity. Hold down Ctrl to set the capacity to the highest value")),
81      value_(this, "199", UI::Align::kCenter) {
82 	decrease_.sigclicked.connect([this]() { click_decrease(); });
83 	increase_.sigclicked.connect([this]() { click_increase(); });
84 
85 	add(new UI::Textarea(this, _("Capacity")), UI::Box::Resizing::kAlign, UI::Align::kCenter);
86 	add(&decrease_, UI::Box::Resizing::kAlign, UI::Align::kCenter);
87 	add(&value_, UI::Box::Resizing::kAlign, UI::Align::kCenter);
88 	add(&increase_, UI::Box::Resizing::kAlign, UI::Align::kCenter);
89 
90 	decrease_.set_repeating(true);
91 	increase_.set_repeating(true);
92 
93 	set_thinks(true);
94 }
95 
think()96 void SoldierCapacityControl::think() {
97 	const SoldierControl* soldiers = building_.soldier_control();
98 	assert(soldiers != nullptr);
99 	uint32_t const capacity = soldiers->soldier_capacity();
100 	value_.set_text(boost::lexical_cast<std::string>(capacity));
101 
102 	bool const can_act = igbase_.can_act(building_.owner().player_number());
103 	decrease_.set_enabled(can_act && soldiers->min_soldier_capacity() < capacity);
104 	increase_.set_enabled(can_act && soldiers->max_soldier_capacity() > capacity);
105 }
106 
change_soldier_capacity(int delta)107 void SoldierCapacityControl::change_soldier_capacity(int delta) {
108 	igbase_.game().send_player_change_soldier_capacity(building_, delta);
109 }
110 
click_decrease()111 void SoldierCapacityControl::click_decrease() {
112 	const SoldierControl* soldiers = building_.soldier_control();
113 	assert(soldiers);
114 	change_soldier_capacity((SDL_GetModState() & KMOD_CTRL) ?
115 	                           soldiers->min_soldier_capacity() - soldiers->soldier_capacity() :
116 	                           -1);
117 }
118 
click_increase()119 void SoldierCapacityControl::click_increase() {
120 	const SoldierControl* soldiers = building_.soldier_control();
121 	assert(soldiers);
122 	change_soldier_capacity((SDL_GetModState() & KMOD_CTRL) ?
123 	                           soldiers->max_soldier_capacity() - soldiers->soldier_capacity() :
124 	                           1);
125 }
126 
create_soldier_capacity_control(UI::Panel & parent,InteractiveGameBase & igb,Widelands::Building & building)127 UI::Panel* create_soldier_capacity_control(UI::Panel& parent,
128                                            InteractiveGameBase& igb,
129                                            Widelands::Building& building) {
130 	return new SoldierCapacityControl(&parent, igb, building);
131 }
132