00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "cockpit/cWidgetBase.h"
00029 #include "cockpit/cCockpit.h"
00030 #include "tValueParser.h"
00031 #include "tResourceManager.h"
00032
00033 #ifndef DEDICATED
00034
00035 #include <typeinfo>
00036
00037 namespace cWidget {
00038
00039 void Base::SetCam(int Cam) {
00040 m_Cam = Cam;
00041 }
00042
00047 void Base::DisplayError(tXmlParser::node cur) {
00048 if(!m_ParsingTemplate) {
00049 tERR_WARN("Element of type '" + cur.GetName() + "' not processable in this context: '" + typeid(*this).name() + "'");
00050 }
00051 }
00052
00058 bool Base::Process(tXmlParser::node cur) {
00059 return false;
00060 }
00061
00062 WithCoordinates::WithCoordinates() : m_originalPosition(0,0), m_originalSize(1,1), m_position(0,0), m_size(1,1)
00063 {}
00064
00065 bool WithCoordinates::Process(tXmlParser::node cur) {
00066 if(cur.IsOfType("Position")) {
00067 tCoord shift;
00068 cur.GetProp("x", shift.x);
00069 cur.GetProp("y", shift.y);
00070 m_position += shift;
00071 m_originalPosition = m_position;
00072 return true;
00073 }
00074 if(cur.IsOfType("Size")) {
00075 tCoord factor;
00076 cur.GetProp("width", factor.x);
00077 cur.GetProp("height", factor.y);
00078 m_size *= factor;
00079 m_originalSize = m_size;
00080 return true;
00081 }
00082 return Base::Process(cur);
00083 }
00084
00086 void WithCoordinates::SetFactor(float factor) {
00087 m_position.y = (m_originalPosition.y + 1.) * factor - 1.;
00088 m_size.y = m_originalSize.y * factor;
00089 }
00090
00091 bool WithDataFunctions::Process(tXmlParser::node cur) {
00092 return Base::Process(cur);
00093 }
00094
00097 tValue::Set WithDataFunctions::ProcessDataSet(tXmlParser::node cur) {
00098 tValue::BasePtr
00099 value(new tValue::Base()),
00100 minimum(new tValue::Base()),
00101 maximum(new tValue::Base());
00102 for (cur = cur.GetFirstChild(); cur; ++cur) {
00103 tValue::Base *newvalue = 0;
00104 tString name = cur.GetName();
00105 if(name == "AtomicData") {
00106 newvalue = ProcessAtomicData(cur);
00107 } else if(name == "Conditional") {
00108 newvalue = ProcessConditional(cur);
00109 } else if(name == "Math") {
00110 newvalue = ProcessMath(cur);
00111 }
00112 else
00113 if (name == "Value")
00114 newvalue = ProcessValue(cur);
00115 if(newvalue != 0) {
00116 tString field = cur.GetProp("field");
00117 if(field == "source") {
00118 value = tValue::BasePtr(newvalue);
00119 } else if(field=="minimum") {
00120 minimum = tValue::BasePtr(newvalue);
00121 } else if(field=="maximum") {
00122 maximum = tValue::BasePtr(newvalue);
00123 }
00124 }
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 return tValue::Set(
00134 value,
00135 minimum,
00136 maximum);
00137 }
00138
00139 tValue::Base *WithDataFunctions::ProcessMath(tXmlParser::node cur) {
00140 tValue::BasePtr lvalue(ProcessDataSource(cur.GetProp("lvalue")));
00141 tValue::BasePtr rvalue(ProcessDataSource(cur.GetProp("rvalue")));
00142
00143 for (tXmlParser::node child = cur.GetFirstChild(); child; ++child) {
00144 tString name = child.GetName();
00145 if(name == "RValue") {
00146 rvalue = tValue::BasePtr(ProcessConditionalCore(child));
00147 } else if(name == "LValue") {
00148 lvalue = tValue::BasePtr(ProcessConditionalCore(child));
00149 }
00150 }
00151
00152 tValue::Base *val;
00153 if (cur.GetProp("type") == "sum")
00154 val = new tValue::Add(lvalue, rvalue);
00155 else
00156 if (cur.GetProp("type") == "difference")
00157 val = new tValue::Subtract(lvalue, rvalue);
00158 else
00159 if (cur.GetProp("type") == "product")
00160 val = new tValue::Multiply(lvalue, rvalue);
00161 else
00162 if (cur.GetProp("type") == "quotient")
00163 val = new tValue::Divide(lvalue, rvalue);
00164 else
00165 {
00166 tERR_WARN("Type '" + cur.GetProp("type") + "' unknown!");
00167 val = new tValue::Add(lvalue, rvalue);
00168 }
00169 ProcessDataTags(cur, *val);
00170 return val;
00171 }
00172
00173 tValue::Base *WithDataFunctions::ProcessConditional(tXmlParser::node cur) {
00174 tValue::BasePtr lvalue(ProcessDataSource(cur.GetProp("lvalue")));
00175 tValue::BasePtr rvalue(ProcessDataSource(cur.GetProp("rvalue")));
00176 tValue::BasePtr truevalue(new tValue::Base), falsevalue(new tValue::Base);
00177
00178 tString oper = cur.GetProp("operator");
00179 tValue::Base *condvalue = NULL;
00180 if (oper.size() == 2)
00181 {
00182 switch (oper[1]) {
00183 case 't': case 'T':
00184 switch (oper[0]) {
00185 case 'g': case 'G':
00186 condvalue = new tValue::GreaterThan (lvalue, rvalue);
00187 break;
00188 case 'l': case 'L':
00189 condvalue = new tValue:: LessThan (lvalue, rvalue);
00190 break;
00191 }
00192 break;
00193 case 'e': case 'E':
00194 switch (oper[0]) {
00195 case 'g': case 'G':
00196 condvalue = new tValue::GreaterOrEquals(lvalue, rvalue);
00197 break;
00198 case 'l': case 'L':
00199 condvalue = new tValue:: LessOrEquals(lvalue, rvalue);
00200 break;
00201 case 'n': case 'N':
00202 tValue::BasePtr precond(new tValue::Equals(lvalue, rvalue));
00203 condvalue = new tValue::Not(precond);
00204 break;
00205 }
00206 break;
00207 case 'q': case 'Q':
00208 if (oper[0] == 'e' || oper[0] == 'E')
00209 condvalue = new tValue:: Equals(lvalue, rvalue);
00210 break;
00211 }
00212 }
00213 if (!condvalue)
00214 {
00215 tERR_WARN("Operator '" + oper + "' unknown!");
00216 condvalue = new tValue::Equals(lvalue, rvalue);
00217 }
00218 tValue::BasePtr condvalueP(condvalue);
00219
00220 for (cur = cur.GetFirstChild(); cur; ++cur) {
00221 tString name = cur.GetName();
00222 if(name == "IfTrue") {
00223 truevalue = tValue::BasePtr(ProcessConditionalCore(cur));
00224 } else if(name == "IfFalse") {
00225 falsevalue = tValue::BasePtr(ProcessConditionalCore(cur));
00226 }
00227 }
00228
00229 return new tValue::Condition(condvalueP, truevalue, falsevalue);
00230 }
00231
00232 tValue::Base *WithDataFunctions::ProcessConditionalCore(tXmlParser::node cur) {
00233 for (cur = cur.GetFirstChild(); cur; ++cur) {
00234 tString name = cur.GetName();
00235 if(name == "AtomicData") {
00236 return ProcessAtomicData(cur);
00237 }
00238 if(name == "Conditional") {
00239 return ProcessConditional(cur);
00240 }
00241 if(name == "Math") {
00242 return ProcessMath(cur);
00243 }
00244 else
00245 if (name == "Value")
00246 return ProcessValue(cur);
00247 }
00248 tERR_WARN("IfTrue or IfFalse node doesn't contain an AtomicData or Conditional node")
00249 return new tValue::Base();
00250 }
00251
00252 tValue::Base *WithDataFunctions::ProcessAtomicData(tXmlParser::node cur) {
00253 tValue::Base *ret = ProcessDataSource(cur.GetProp("source"));
00254 ProcessDataTags(cur, *ret);
00255 return ret;
00256 }
00257
00258 tValue::Base *WithDataFunctions::ProcessValue(tXmlParser::node cur) {
00259 #ifndef WIN32
00260 return tValueParser::parse(cur.GetProp("expr"));
00261 #else
00262 return 0;
00263 #endif
00264 }
00265
00266 void WithDataFunctions::ProcessDataTags(tXmlParser::node cur, tValue::Base &data) {
00267 int precision, minwidth;
00268 cur.GetProp("precision", precision);
00269 cur.GetProp("minwidth", minwidth);
00270 tString fill = cur.GetProp("fill");
00271 if(fill.size() != 1) {
00272 tERR_WARN("Attribute 'fill' has to have a length of 1!");
00273 fill = "!";
00274 }
00275 data.SetPrecision(precision);
00276 data.SetMinsize(minwidth);
00277 data.SetFill(fill(0));
00278 }
00279
00280 tValue::Base *WithDataFunctions::ProcessDataSource(tString const &data) {
00281
00282 int val_int;
00283 if(data.Convert(val_int)) return new tValue::Int(val_int);
00284
00285 float val_float;
00286 if(data.Convert(val_float)) return new tValue::Float(val_float);
00287
00288
00289 std::map<tString, tValue::Callback<cCockpit>::cb_ptr>::const_iterator iter;
00290 if((iter = stc_callbacks.find(data.ToLower())) != stc_callbacks.end()) {
00291 if(stc_forbiddenCallbacks.count(data.ToLower())) return new tValue::Base();
00292 return new tValue::Callback<cCockpit>(iter->second, m_Cockpit);
00293 }
00294
00295
00296 tValue::ConfItem *item = new tValue::ConfItem(data);
00297 if(item->Good())
00298 return item;
00299 delete item;
00300
00301
00302 return new tValue::String(data);
00303 }
00304
00305 bool WithSingleData::Process(tXmlParser::node cur) {
00306 if(cur.IsOfType("DataSet")) {
00307 m_data = ProcessDataSet(cur);
00308 return true;
00309 }
00310 return WithDataFunctions::Process(cur);
00311 }
00312
00313 bool WithIdData::Process(tXmlParser::node cur) {
00314 if(cur.IsOfType("DataSet")) {
00315 tString id = cur.GetProp("id");
00316 if(id.empty()) {
00317 tERR_WARN("Empty or no id tag where needed!");
00318 return true;
00319 }
00320 m_data[id] = ProcessDataSet(cur);
00321 return true;
00322 }
00323 return WithDataFunctions::Process(cur);
00324 }
00325
00326 bool WithTable::Process(tXmlParser::node cur) {
00327 if(cur.IsOfType("Face")) {
00328 ProcessCore(cur);
00329 return true;
00330 }
00331 return WithIdData::Process(cur);
00332 }
00333
00334 void WithTable::ProcessCore(tXmlParser::node cur) {
00335 for (cur = cur.GetFirstChild(); cur; ++cur) {
00336 if(cur.IsOfType("Table")) {
00337 ProcessTable(cur);
00338 return;
00339 }
00340 }
00341 }
00342
00343 void WithTable::ProcessTable(tXmlParser::node cur) {
00344 for (cur = cur.GetFirstChild(); cur; ++cur) {
00345 if(cur.IsOfType("Row")) {
00346 m_table.push_back(std::deque<std::deque<tValue::Set> >());
00347 ProcessRow(cur);
00348 }
00349 }
00350 }
00351
00352 void WithTable::ProcessRow(tXmlParser::node cur) {
00353 for (cur = cur.GetFirstChild(); ++cur; ++cur) {
00354 tString name = cur.GetName();
00355 if(name == "Cell") {
00356 m_table.back().push_back(std::deque<tValue::Set>());
00357 ProcessCell(cur);
00358 }
00359 }
00360 }
00361
00362 void WithTable::ProcessCell(tXmlParser::node cur) {
00363 for (cur = cur.GetFirstChild(); cur; ++cur) {
00364 if(cur.IsOfType("Text")) {
00365
00366 tValue::BasePtr a(new tValue::String(cur.GetProp("value")));
00367 tValue::BasePtr b(new tValue::Int(3));
00368 tValue::BasePtr c(new tValue::Int(4));
00369 m_table.back().back().push_back((tValue::Set(a, b, c)));
00370 } else if(cur.IsOfType("GameData")) {
00371 std::map<tString, tValue::Set>::iterator iter;
00372 if((iter = m_data.find(cur.GetProp("data"))) != m_data.end()) {
00373 m_table.back().back().push_back((tValue::Set(iter->second)));
00374 } else {
00375 tERR_WARN("Id '" + cur.GetProp("data") + "' undefined!");
00376 }
00377 }
00378 }
00379 }
00380
00381 bool WithColorFunctions::Process(tXmlParser::node cur) {
00382 return Base::Process(cur);
00383 }
00384
00385 rGradient WithColorFunctions::ProcessGradient(tXmlParser::node cur) {
00386 rGradient ret;
00387 for (cur = cur.GetFirstChild(); cur; ++cur) {
00388 tString name=cur.GetName();
00389 if(name == "Solid") {
00390 ProcessGradientCore(cur, ret);
00391 } else if(name == "Gradient") {
00392 std::map<tString, rGradient::direction> directions;
00393 directions[tString("horizontal")] = rGradient::horizontal;
00394 directions[tString("vertical")] = rGradient::vertical;
00395 directions[tString("value")] = rGradient::value;
00396 std::map<tString, rGradient::direction>::iterator iter;
00397 if((iter = directions.find(cur.GetProp("orientation"))) != directions.end()) {
00398 ret.SetDir(iter->second);
00399 } else {
00400 tERR_WARN("Gradient orientation '" + cur.GetProp("orientation") + "' unknown!");
00401 }
00402 ProcessGradientCore(cur, ret);
00403 } else if(name == "Image") {
00404 int rep = 0;
00405 std::map<tString, int> repeat;
00406 repeat[tString("none")] = 0;
00407 repeat[tString("x")] = 1;
00408 repeat[tString("y")] = 2;
00409 repeat[tString("both")] = 3;
00410 std::map<tString, int>::iterator iter;
00411 if((iter = repeat.find(cur.GetProp("repeat"))) != repeat.end()) {
00412 rep = iter->second;
00413 } else {
00414 tERR_WARN("Repeat setting '" + cur.GetProp("repeat") + "' unknown!");
00415 }
00416 tCoord scale;
00417 cur.GetProp("scale_x", scale.x);
00418 cur.GetProp("scale_y", scale.y);
00419 ret.SetTextureScale(scale);
00420 ProcessImage(cur, ret, rep);
00421 }
00422 }
00423 return ret;
00424 }
00425
00426 void WithColorFunctions::ProcessGradientCore(tXmlParser::node cur, rGradient &gradient) {
00427 for (cur = cur.GetFirstChild(); cur; ++cur) {
00428 if(cur.IsOfType("Color")) {
00429 float r,g,b,a,at;
00430 cur.GetProp("r", r);
00431 cur.GetProp("g", g);
00432 cur.GetProp("b", b);
00433 cur.GetProp("alpha", a);
00434 cur.GetProp("at", at);
00435 gradient[at] = rColor(r ,g ,b ,a);
00436 }
00437 }
00438 }
00439
00440 void WithColorFunctions::ProcessImage(tXmlParser::node cur, rGradient &gradient, int repeat) {
00441 for(cur = cur.GetFirstChild(); cur; ++cur) {
00442 if(cur.IsOfType("Graphic")) {
00443 tResourcePath path(
00444 cur.HasProp("author") ? cur.GetProp("author") : m_Cockpit->Path().Author(),
00445 cur.HasProp("category") ? cur.GetProp("category") : m_Cockpit->Path().Category(),
00446 cur.GetProp("name"),
00447 cur.GetProp("version"),
00448 tString("aatex"),
00449 cur.GetProp("extension"),
00450 cur.GetProp("uri")
00451 );
00452 gradient.SetTexture(rResourceTexture(path, repeat & 1, repeat & 2));
00453 }
00454 }
00455 }
00456
00457 bool WithForeground::Process(tXmlParser::node cur) {
00458 if(cur.IsOfType("Foreground")) {
00459 m_foreground = ProcessGradient(cur);
00460 return true;
00461 }
00462 return WithColorFunctions::Process(cur);
00463 }
00464
00465 bool WithBackground::Process(tXmlParser::node cur) {
00466 if(cur.IsOfType("Background")) {
00467 m_background = ProcessGradient(cur);
00468 return true;
00469 }
00470 return WithColorFunctions::Process(cur);
00471 }
00472
00473 bool WithLineColor::Process(tXmlParser::node cur) {
00474 if(cur.IsOfType("LineColor")) {
00475 m_line_color = ProcessGradient(cur);
00476 return true;
00477 }
00478 return WithColorFunctions::Process(cur);
00479 }
00480
00481 bool WithCaption::Process(tXmlParser::node cur) {
00482 if(cur.IsOfType("Caption")) {
00483 ProcessCaption(cur);
00484 return true;
00485 }
00486 return Base::Process(cur);
00487 }
00488
00489 void WithCaption::ProcessCaption(tXmlParser::node cur) {
00490 ProcessCaptionLocation(cur);
00491 for (cur = cur.GetFirstChild(); cur; ++cur) {
00492 if(cur.IsOfType("Text")) {
00493 m_caption = cur.GetProp("value");
00494 }
00495 }
00496 }
00497
00498 void WithCaption::ProcessCaptionLocation(tXmlParser::node cur) {
00499 std::map<tString, int> locations;
00500 locations[tString("top")] = top;
00501 locations[tString("bottom")] = bottom;
00502 locations[tString("off")] = off;
00503
00504 std::map<tString, int>::iterator iter;
00505 if((iter = locations.find(cur.GetProp("location"))) != locations.end()) {
00506 m_captionloc = iter->second;
00507 } else {
00508 tERR_WARN("Location '" + cur.GetProp("location") + "' unknown!");
00509 m_captionloc = bottom;
00510 }
00511 }
00512
00513 bool WithReverse::Process(tXmlParser::node cur) {
00514 if(cur.IsOfType("Reverse")) {
00515 m_reverse = cur.GetPropBool("value");
00516 return true;
00517 }
00518 return Base::Process(cur);
00519 }
00520
00521 bool WithAngles::Process(tXmlParser::node cur) {
00522 if(cur.IsOfType("Angles")) {
00523 cur.GetProp("min", m_angle_min);
00524 cur.GetProp("max", m_angle_max);
00525 m_angle_min *= M_PI / 180.;
00526 m_angle_max *= M_PI / 180.;
00527 return true;
00528 }
00529 return Base::Process(cur);
00530 }
00531
00532 bool WithShowSettings::Process(tXmlParser::node cur) {
00533 if(cur.IsOfType("ShowMinimum")) {
00534 m_showmin = cur.GetPropBool("value");
00535 return true;
00536 }
00537 if(cur.IsOfType("ShowMaximum")) {
00538 m_showmax = cur.GetPropBool("value");
00539 return true;
00540 }
00541 if(cur.IsOfType("ShowCurrent")) {
00542 m_showvalue = cur.GetPropBool("value");
00543 return true;
00544 }
00545 return Base::Process(cur);
00546 }
00547
00548 }
00549
00550 #endif