1 /***************************************************************************
2  *      Mechanized Assault and Exploration Reloaded Projectfile            *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (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                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18  ***************************************************************************/
19 
20 #include "ui/graphical/menu/windows/windowresourcedistribution/windowresourcedistribution.h"
21 #include "pcx.h"
22 #include "main.h"
23 #include "game/data/base/base.h"
24 #include "ui/graphical/menu/widgets/label.h"
25 #include "ui/graphical/menu/widgets/pushbutton.h"
26 #include "ui/graphical/menu/widgets/special/resourcebar.h"
27 #include "ui/graphical/menu/dialogs/dialogok.h"
28 #include "ui/graphical/application.h"
29 #include "ui/graphical/game/widgets/turntimeclockwidget.h"
30 
31 //------------------------------------------------------------------------------
cWindowResourceDistribution(const sSubBase & subBase_,std::shared_ptr<const cTurnTimeClock> turnTimeClock)32 cWindowResourceDistribution::cWindowResourceDistribution (const sSubBase& subBase_, std::shared_ptr<const cTurnTimeClock> turnTimeClock) :
33 	cWindow (LoadPCX (GFXOD_MINEMANAGER)),
34 	subBase (subBase_)
35 {
36 	addChild (std::make_unique<cLabel> (cBox<cPosition> (getPosition() + cPosition (0, 11), getPosition() + cPosition (getArea().getMaxCorner().x(), 11 + 10)), lngPack.i18n ("Text~Title~Mine"), FONT_LATIN_NORMAL, eAlignmentType::CenterHorizontal));
37 
38 	auto turnTimeClockWidget = addChild (std::make_unique<cTurnTimeClockWidget> (cBox<cPosition> (cPosition (525, 16), cPosition (525 + 60, 16 + 10))));
39 	turnTimeClockWidget->setTurnTimeClock (std::move (turnTimeClock));
40 
41 	for (size_t i = 0; i < 3; ++i)
42 	{
43 		metalBars[i] = addChild (std::make_unique<cResourceBar> (cBox<cPosition> (getPosition() + cPosition (174, 70 + 37 * i), getPosition() + cPosition (174 + 240, 70 + 37 * i + 30)), 0, 100, eResourceBarType::Metal, eOrientationType::Horizontal));
44 		oilBars[i] = addChild (std::make_unique<cResourceBar> (cBox<cPosition> (getPosition() + cPosition (174, 190 + 37 * i), getPosition() + cPosition (174 + 240, 190 + 37 * i + 30)), 0, 100, eResourceBarType::Oil, eOrientationType::Horizontal));
45 		goldBars[i] = addChild (std::make_unique<cResourceBar> (cBox<cPosition> (getPosition() + cPosition (174, 310 + 37 * i), getPosition() + cPosition (174 + 240, 310 + 37 * i + 30)), 0, 100, eResourceBarType::Gold, eOrientationType::Horizontal));
46 
47 		if (i > 0)
48 		{
49 			metalBars[i]->disable();
50 			oilBars[i]->disable();
51 			goldBars[i]->disable();
52 		}
53 		else
54 		{
55 			signalConnectionManager.connect (metalBars[i]->valueChanged, std::bind (&cWindowResourceDistribution::handleMetalChanged, this));
56 			signalConnectionManager.connect (oilBars[i]->valueChanged, std::bind (&cWindowResourceDistribution::handleOilChanged, this));
57 			signalConnectionManager.connect (goldBars[i]->valueChanged, std::bind (&cWindowResourceDistribution::handleGoldChanged, this));
58 		}
59 
60 		noneBars[i] = addChild (std::make_unique<cResourceBar> (cBox<cPosition> (getPosition() + cPosition (174, 70 + 120 * i), getPosition() + cPosition (174 + 240, 70 + 120 * i + 30)), 0, 100, eResourceBarType::Blocked, eOrientationType::Horizontal));
61 		noneBars[i]->disable();
62 		noneBars[i]->setInverted (true);
63 		noneBars[i]->setValue (30);
64 
65 		std::string resourceName;
66 		if (i == 0) resourceName = lngPack.i18n ("Text~Title~Metal");
67 		else if (i == 1) resourceName = lngPack.i18n ("Text~Title~Oil");
68 		else resourceName = lngPack.i18n ("Text~Title~Gold");
69 
70 		addChild (std::make_unique<cLabel> (cBox<cPosition> (getPosition() + cPosition (40, 78 + 121 * i), getPosition() + cPosition (40 + 80, 78 + 121 * i + 10)), resourceName, FONT_LATIN_NORMAL, eAlignmentType::CenterHorizontal));
71 		addChild (std::make_unique<cLabel> (cBox<cPosition> (getPosition() + cPosition (40, 78 + 37 + 121 * i), getPosition() + cPosition (40 + 80, 78 + 37 + 121 * i + 10)), lngPack.i18n ("Text~Others~Usage_7"), FONT_LATIN_NORMAL, eAlignmentType::CenterHorizontal));
72 		addChild (std::make_unique<cLabel> (cBox<cPosition> (getPosition() + cPosition (40, 78 + 37 * 2 + 121 * i), getPosition() + cPosition (40 + 80, 78 + 37 * 2 + 121 * i + 10)), lngPack.i18n ("Text~Comp~Reserve"), FONT_LATIN_NORMAL, eAlignmentType::CenterHorizontal));
73 
74 		auto decreaseButton = addChild (std::make_unique<cPushButton> (getPosition() + cPosition (139, 70 + 120 * i), ePushButtonType::ArrowLeftBig));
75 		signalConnectionManager.connect (decreaseButton->clicked, [&, i]()
76 		{
77 			if (i == 0) metalBars[0]->decrease (1);
78 			else if (i == 1) oilBars[0]->decrease (1);
79 			else if (i == 2) goldBars[0]->decrease (1);
80 		});
81 		auto increaseButton = addChild (std::make_unique<cPushButton> (getPosition() + cPosition (421, 70 + 120 * i), ePushButtonType::ArrowRightBig));
82 		signalConnectionManager.connect (increaseButton->clicked, [&, i]()
83 		{
84 			if (i == 0) metalBars[0]->increase (1);
85 			else if (i == 1) oilBars[0]->increase (1);
86 			else if (i == 2) goldBars[0]->increase (1);
87 		});
88 	}
89 
90 	// add labels after resource bars so that they will be drawn
91 	// above the resource bars.
92 	for (size_t i = 0; i < 3; ++i)
93 	{
94 		metalLabels[i] = addChild (std::make_unique<cLabel> (cBox<cPosition> (getPosition() + cPosition (174, 78 + 37 * i), getPosition() + cPosition (174 + 240, 78 + 37 * i + 15)), "Metal", FONT_LATIN_BIG, eAlignmentType::CenterHorizontal));
95 		oilLabels[i] = addChild (std::make_unique<cLabel> (cBox<cPosition> (getPosition() + cPosition (174, 198 + 37 * i), getPosition() + cPosition (174 + 240, 198 + 37 * i + 15)), "Oil", FONT_LATIN_BIG, eAlignmentType::CenterHorizontal));
96 		goldLabels[i] = addChild (std::make_unique<cLabel> (cBox<cPosition> (getPosition() + cPosition (174, 318 + 37 * i), getPosition() + cPosition (174 + 240, 318 + 37 * i + 15)), "Gold", FONT_LATIN_BIG, eAlignmentType::CenterHorizontal));
97 
98 		// disable the label so that they will not receive any mouse events
99 		metalLabels[i]->disable();
100 		oilLabels[i]->disable();
101 		goldLabels[i]->disable();
102 	}
103 
104 	auto doneButton = addChild (std::make_unique<cPushButton> (getPosition() + cPosition (514, 430), ePushButtonType::Huge, lngPack.i18n ("Text~Others~Done")));
105 	doneButton->addClickShortcut (cKeySequence (cKeyCombination (eKeyModifierType::None, SDLK_RETURN)));
106 	signalConnectionManager.connect (doneButton->clicked, [&]() { done(); });
107 
108 	setBarLabels();
109 	setBarValues();
110 
111 	signalConnectionManager.connect (subBase.destroyed, std::bind (&cWindowResourceDistribution::closeOnSubBaseDestruction, this));
112 }
113 
114 //------------------------------------------------------------------------------
getMetalProduction()115 int cWindowResourceDistribution::getMetalProduction()
116 {
117 	return subBase.getMetalProd();
118 }
119 
120 //------------------------------------------------------------------------------
getOilProduction()121 int cWindowResourceDistribution::getOilProduction()
122 {
123 	return subBase.getOilProd();
124 }
125 
126 //------------------------------------------------------------------------------
getGoldProduction()127 int cWindowResourceDistribution::getGoldProduction()
128 {
129 	return subBase.getGoldProd();
130 }
131 
132 //------------------------------------------------------------------------------
secondBarText(int prod,int need)133 std::string cWindowResourceDistribution::secondBarText (int prod, int need)
134 {
135 	int perTurn = prod - need;
136 	std::string text = iToStr (need) + " (";
137 	if (perTurn > 0) text += "+";
138 	text += iToStr (perTurn) + " / " + lngPack.i18n ("Text~Comp~Turn_5") + ")";
139 	return text;
140 }
141 
142 //------------------------------------------------------------------------------
setBarLabels()143 void cWindowResourceDistribution::setBarLabels()
144 {
145 	metalLabels[0]->setText (iToStr (subBase.getMetalProd()));
146 	metalLabels[1]->setText (secondBarText (subBase.getMetalProd(), subBase.MetalNeed));
147 	metalLabels[2]->setText (iToStr (subBase.getMetal()));
148 
149 	oilLabels[0]->setText (iToStr (subBase.getOilProd()));
150 	oilLabels[1]->setText (secondBarText (subBase.getOilProd(), subBase.OilNeed));
151 	oilLabels[2]->setText (iToStr (subBase.getOil()));
152 
153 	goldLabels[0]->setText (iToStr (subBase.getGoldProd()));
154 	goldLabels[1]->setText (secondBarText (subBase.getGoldProd(), subBase.GoldNeed));
155 	goldLabels[2]->setText (iToStr (subBase.getGold()));
156 }
157 
158 //------------------------------------------------------------------------------
setBarValues()159 void cWindowResourceDistribution::setBarValues()
160 {
161 	metalBars[0]->setMaxValue (subBase.getMaxMetalProd());
162 	metalBars[0]->setValue (subBase.getMetalProd());
163 	metalBars[1]->setMaxValue (subBase.MaxMetalNeed);
164 	metalBars[1]->setValue (subBase.MetalNeed);
165 	metalBars[2]->setMaxValue (subBase.MaxMetal);
166 	metalBars[2]->setValue (subBase.getMetal());
167 
168 	noneBars[0]->setMaxValue (subBase.getMaxMetalProd());
169 	noneBars[0]->setValue (subBase.getMaxMetalProd() - subBase.getMaxAllowedMetalProd());
170 
171 	oilBars[0]->setMaxValue (subBase.getMaxOilProd());
172 	oilBars[0]->setValue (subBase.getOilProd());
173 	oilBars[1]->setMaxValue (subBase.MaxOilNeed);
174 	oilBars[1]->setValue (subBase.OilNeed);
175 	oilBars[2]->setMaxValue (subBase.MaxOil);
176 	oilBars[2]->setValue (subBase.getOil());
177 
178 	noneBars[1]->setMaxValue (subBase.getMaxOilProd());
179 	noneBars[1]->setValue (subBase.getMaxOilProd() - subBase.getMaxAllowedOilProd());
180 
181 	goldBars[0]->setMaxValue (subBase.getMaxGoldProd());
182 	goldBars[0]->setValue (subBase.getGoldProd());
183 	goldBars[1]->setMaxValue (subBase.MaxGoldNeed);
184 	goldBars[1]->setValue (subBase.GoldNeed);
185 	goldBars[2]->setMaxValue (subBase.MaxGold);
186 	goldBars[2]->setValue (subBase.getGold());
187 
188 	noneBars[2]->setMaxValue (subBase.getMaxGoldProd());
189 	noneBars[2]->setValue (subBase.getMaxGoldProd() - subBase.getMaxAllowedGoldProd());
190 }
191 
192 //------------------------------------------------------------------------------
handleMetalChanged()193 void cWindowResourceDistribution::handleMetalChanged()
194 {
195 	subBase.setMetalProd (metalBars[0]->getValue());
196 
197 	setBarValues();
198 	setBarLabels();
199 }
200 
201 //------------------------------------------------------------------------------
handleOilChanged()202 void cWindowResourceDistribution::handleOilChanged()
203 {
204 	subBase.setOilProd (oilBars[0]->getValue());
205 
206 	setBarValues();
207 	setBarLabels();
208 }
209 
210 //------------------------------------------------------------------------------
handleGoldChanged()211 void cWindowResourceDistribution::handleGoldChanged()
212 {
213 	subBase.setGoldProd (goldBars[0]->getValue());
214 
215 	setBarValues();
216 	setBarLabels();
217 }
218 
219 //------------------------------------------------------------------------------
closeOnSubBaseDestruction()220 void cWindowResourceDistribution::closeOnSubBaseDestruction()
221 {
222 	close();
223 	auto application = getActiveApplication();
224 	if (application)
225 	{
226 		application->show (std::make_shared<cDialogOk> (lngPack.i18n ("Text~Others~Unit_destroyed")));
227 	}
228 }
229