1 /*
2 Copyright (C) 2005 David Kamphausen <david.kamphausen@web.de>
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 Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 #include <config.h>
19
20 #include "PBar.hpp"
21 #include "Util.hpp"
22 #include "gui/ComponentFactory.hpp"
23 #include "gui/ComponentLoader.hpp"
24 #include "gui/XmlReader.hpp"
25 #include "gui/Paragraph.hpp"
26 #include "gui/Painter.hpp"
27
28 LCPBar* LCPBarInstance = 0;
29
LCPBar()30 LCPBar::LCPBar()
31 {
32 LCPBarInstance = this;
33 }
34
~LCPBar()35 LCPBar::~LCPBar()
36 {
37 if(LCPBarInstance == this)
38 LCPBarInstance = 0;
39 }
40
41 void
parse(XmlReader & reader)42 LCPBar::parse(XmlReader& reader)
43 {
44 XmlReader::AttributeIterator iter(reader);
45 while(iter.next()) {
46 const char* name = (const char*) iter.getName();
47 const char* value = (const char*) iter.getValue();
48
49 if(parseAttribute(name, value)) {
50 continue;
51 } else {
52 std::cerr << "Unknown attribute '" << name
53 << "' skipped in PBar.\n";
54 }
55 }
56
57 Component* component = parseEmbeddedComponent(reader);
58 addChild(component);
59
60 width = component->getWidth();
61 height = component->getHeight();
62 }
63
64 // copied from old-gui
65 #define pbar_adjust_pop(diff) 2 * diff
66 #define pbar_adjust_tech(diff) diff > 0 ? diff / 4 + 1 : -((-diff+1)/ 2)
67 #define pbar_adjust_food(diff) diff > 0 ? diff / 2 + 1 : diff
68 #define pbar_adjust_jobs(diff) diff > 0 ? diff / 2 + 1 : diff
69 #define pbar_adjust_coal(diff) diff > 0 ? diff / 2 + 1 : diff
70 #define pbar_adjust_goods(diff) diff > 0 ? diff / 2 + 1 : diff
71 #define pbar_adjust_ore(diff) diff > 0 ? diff / 2 + 1 : diff
72 #define pbar_adjust_steel(diff) diff > 0 ? diff / 2 + 1 : diff
73 #define pbar_adjust_money(diff) diff > 0 ? diff / 800 + 1 : diff / 400
74
75 void
setValue(int num,int value,int diff)76 LCPBar::setValue(int num, int value, int diff)
77 {
78 std::ostringstream compname;
79 compname << "pbar_text" << (num+1);
80 Paragraph* p = getParagraph(*this, compname.str());
81
82 std::ostringstream os;
83 os<<std::fixed;
84 os<<std::setprecision(1);
85 if(num==PTECH)
86 {
87 os<<value/10000.0;
88 }
89 else if(num==PMONEY)
90 {
91 if(abs(value)>=1000000000)
92 os<<value/1000000<<"M";
93 else if(abs(value)>1000000)
94 os<<value/1000000.0<<"M";
95 else if(abs(value)>1000)
96 os<<value/1000.0<<"K";
97 else
98 os<<value;
99 }
100 else
101 os<<value;
102
103 if( diff != 0 ){
104 p->setText(os.str());
105 }
106 os.str("");
107 os<<"pbar_barview"<<(num+1);
108
109 float sv=0;
110 switch(num)
111 {
112 case PPOP:
113 sv=pbar_adjust_pop(diff);
114 break;
115 case PTECH:
116 sv=pbar_adjust_tech(diff);
117 break;
118 case PFOOD:
119 sv=pbar_adjust_food(diff);break;
120 case PJOBS:
121 sv=pbar_adjust_jobs(diff);break;
122 case PCOAL:
123 sv=pbar_adjust_coal(diff);break;
124 case PGOODS:
125 sv=pbar_adjust_goods(diff);break;
126 case PORE:
127 sv=pbar_adjust_ore(diff);break;
128 case PSTEEL:
129 sv=pbar_adjust_steel(diff);break;
130 case PMONEY:
131 sv=pbar_adjust_money(diff);break;
132 };
133
134 sv/=10.0;
135
136
137 if(sv>1.0)
138 sv=1.0;
139 if(sv<-1.0)
140 sv=-1.0;
141
142 Component *c=findComponent(os.str()+"a");
143 if(c)
144 {
145 BarView *bv=dynamic_cast<BarView*>(c);
146 if(bv)
147 {
148 bv->setValue(sv);
149 }
150 }
151 c=findComponent(os.str()+"b");
152 if(c)
153 {
154 BarView *bv=dynamic_cast<BarView*>(c);
155 if(bv)
156 {
157 bv->setValue(sv);
158 }
159 }
160
161 }
162
163 ///////////////////////////////////////////////////////////////////////////////////////
164 // BarView
165 ///////////////////////////////////////////////////////////////////////////////////////
166
BarView()167 BarView::BarView()
168 {
169 }
170
~BarView()171 BarView::~BarView()
172 {
173 }
174
175 void
parse(XmlReader & reader)176 BarView::parse(XmlReader& reader)
177 {
178 dir=true;
179 // parse attributes...
180 XmlReader::AttributeIterator iter(reader);
181 while(iter.next()) {
182 const char* name = (const char*) iter.getName();
183 const char* value = (const char*) iter.getValue();
184
185 if(parseAttribute(name, value)) {
186 continue;
187 } else if(strcmp(name, "width") == 0) {
188 if(sscanf(value, "%f", &width) != 1) {
189 std::stringstream msg;
190 msg << "Couldn't parse width attribute (" << value << ").";
191 throw std::runtime_error(msg.str());
192 }
193 } else if(strcmp(name, "height") == 0) {
194 if(sscanf(value, "%f", &height) != 1) {
195 std::stringstream msg;
196 msg << "Couldn't parse height attribute (" << value << ").";
197 throw std::runtime_error(msg.str());
198 }
199 } else if(strcmp(name, "dir") == 0) {
200 if(strcmp(value,"1") == 0) {
201 dir=true;
202 } else {
203 dir=false;
204 }
205 } else {
206 std::cerr << "Unknown attribute '" << name
207 << "' skipped in BarView.\n";
208 }
209 }
210 if(width <= 0 || height <= 0)
211 throw std::runtime_error("Width or Height invalid");
212 value=0.7;
213 }
214
setValue(float v)215 void BarView::setValue(float v)
216 {
217 if(v>=-1.0 && v<=1.0)
218 value=v;
219 }
220
draw(Painter & painter)221 void BarView::draw(Painter &painter)
222 {
223 painter.setFillColor(Color(0,0xAA,0,255));
224
225 if((int)(width*value)>0 && dir) {
226 painter.fillRectangle(Rect2D(0,0,width*value,height));
227 } else if((int)(width*value)<0 && !dir) {
228 painter.setFillColor(Color(0xFF,0,0,255));
229 painter.fillRectangle(Rect2D(width-1+width*value,0,width-1,height));
230 }
231 }
232
233 IMPLEMENT_COMPONENT_FACTORY(LCPBar);
234 IMPLEMENT_COMPONENT_FACTORY(BarView);
235