src/tron/cockpit/cWidgetBase.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 
00008 **************************************************************************
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
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     // TODO:
00127     /*
00128     return tValue::Set(
00129                value.release(),
00130                minimum.release(),
00131                maximum.release());
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     //is it an integer?
00282     int val_int;
00283     if(data.Convert(val_int)) return new tValue::Int(val_int);
00284     //is it a float
00285     float val_float;
00286     if(data.Convert(val_float)) return new tValue::Float(val_float);
00287 
00288     //is it one of the dynamic callbacks?
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     //growing desperate... is this a configuration value maybe?
00296     tValue::ConfItem *item = new tValue::ConfItem(data);
00297     if(item->Good())
00298         return item;
00299     delete item;
00300 
00301     //Ok, giving up... this has to be a string then.
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             //            m_table.back().back().push_back((tValue::Set(tValue::BasePtr(new tValue::String(cur.GetProp("value"))))));
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

Generated on Sat Mar 15 22:56:05 2008 for Armagetron Advanced by  doxygen 1.5.4