template<> pair<string,cLed*> cDialog::parse(Element& who /*LED*/){ pair<string,cLed*> p; Iterator<Attribute> attr; Iterator<Node> node; string name; int width = 0, height = 0; bool foundTop = false, foundLeft = false; // requireds p.second = new cLed(this); p.second->type = BTN_LED; for(attr = attr.begin(&who); attr != attr.end(); attr++){ attr->GetName(&name); if(name == "name") attr->GetValue(&p.first); else if(name == "state"){ std::string val; attr->GetValue(&val); if(val == "red") p.second->state = led_red; else if(val == "green") p.second->state = led_green; else if(val == "off") p.second->state = led_off; else throw xBadVal("led",name,val,attr->Row(),attr->Column()); }else if(name == "fromlist") attr->GetValue(&p.second->fromList); else if(name == "font"){ std::string val; attr->GetValue(&val); if(val == "dungeon") p.second->textFont = DUNGEON; else if(val == "geneva") p.second->textFont = GENEVA; else if(val == "silom") p.second->textFont = SILOM; else if(val == "maidenword") p.second->textFont = MAIDENWORD; else throw xBadVal("text",name,val,attr->Row(),attr->Column()); }else if(name == "size"){ std::string val; attr->GetValue(&val); if(val == "large") p.second->textSize = 12; else if(val == "small") p.second->textSize = 10; else throw xBadVal("text",name,val,attr->Row(),attr->Column()); }else if(name == "color" || name == "colour"){ std::string val; attr->GetValue(&val); RGBColor clr; try{ clr = parseColor(val); }catch(int){ throw xBadVal("text",name,val,attr->Row(),attr->Column()); } p.second->color = clr; }else if(name == "top"){ attr->GetValue(&p.second->frame.top), foundTop = true; }else if(name == "left"){ attr->GetValue(&p.second->frame.left), foundLeft = true; }else if(name == "width"){ attr->GetValue(&width); }else if(name == "height"){ attr->GetValue(&height); }else throw xBadAttr("button",name,attr->Row(),attr->Column()); } if(!foundTop) throw xMissingAttr("led","top",who.Row(),who.Column()); if(!foundLeft) throw xMissingAttr("led","left",who.Row(),who.Column()); if(width > 0 || height > 0) { p.second->frame.right = p.second->frame.left + width; p.second->frame.bottom = p.second->frame.top + height; }else{ p.second->frame.right = p.second->frame.left + 14; p.second->frame.bottom = p.second->frame.top + 10; } string content; for(node = node.begin(&who); node != node.end(); node++){ string val; int type = node->Type(); node->GetValue(&val); if(type == TiXmlNode::TEXT) content += val; else{ val = '<' + val + '>'; throw xBadVal("text","<content>",content + val,node->Row(),node->Column()); } } p.second->lbl = content; if(p.first == ""){ do{ p.first = generateRandomString(); }while(controls.find(p.first) != controls.end()); } return p; }
template<> pair<string,cButton*> cDialog::parse(Element& who /*button*/){ pair<string,cButton*> p; Iterator<Attribute> attr; Iterator<Node> node; string name; int width = 0, height = 0; bool foundType = false, foundTop = false, foundLeft = false; // required attributes p.second = new cButton(this); for(attr = attr.begin(&who); attr != attr.end(); attr++){ attr->GetName(&name); if(name == "name") attr->GetValue(&p.first); else if(name == "wrap"){ std::string val; attr->GetValue(&val); if(val == "true") p.second->wrapLabel = true; }else if(name == "type"){ std::string val; foundType = true; attr->GetValue(&val); if(val == "small") p.second->type = BTN_SM; else if(val == "regular") p.second->type = BTN_REG; else if(val == "large") p.second->type = BTN_LG; else if(val == "help") p.second->type = BTN_HELP; else if(val == "left") p.second->type = BTN_LEFT; else if(val == "right") p.second->type = BTN_RIGHT; else if(val == "up") p.second->type = BTN_UP; else if(val == "down") p.second->type = BTN_DOWN; else if(val == "tiny") p.second->type = BTN_TINY; else if(val == "done") p.second->type = BTN_DONE; else if(val == "tall") p.second->type = BTN_TALL; else if(val == "trait") p.second->type = BTN_TRAIT; else if(val == "push") p.second->type = BTN_PUSH; }else if(name == "def-key"){ std::string val; attr->GetValue(&val); try{ p.second->key = parseKey(val); }catch(int){ throw xBadVal("button",name,val,attr->Row(),attr->Column()); } }else if(name == "fromlist") attr->GetValue(&p.second->fromList); else if(name == "top"){ attr->GetValue(&p.second->frame.top), foundTop = true; }else if(name == "left"){ attr->GetValue(&p.second->frame.left), foundLeft = true; }else if(name == "width"){ attr->GetValue(&width); }else if(name == "height"){ attr->GetValue(&height); }else throw xBadAttr("button",name,attr->Row(),attr->Column()); } if(!foundType) throw xMissingAttr("button","type",who.Row(),who.Column()); if(!foundTop) throw xMissingAttr("button","top",who.Row(),who.Column()); if(!foundLeft) throw xMissingAttr("button","left",who.Row(),who.Column()); if(width > 0 || height > 0) { p.second->frame.right = p.second->frame.left + width; p.second->frame.bottom = p.second->frame.top + height; }else switch(p.second->type){ case BTN_SM: p.second->frame.right = p.second->frame.left + 23; p.second->frame.bottom = p.second->frame.top + 23; break; case BTN_LG: p.second->frame.right = p.second->frame.left + 102; p.second->frame.bottom = p.second->frame.top + 23; break; case BTN_HELP: p.second->frame.right = p.second->frame.left + 16; p.second->frame.bottom = p.second->frame.top + 13; break; case BTN_TINY: case BTN_LED: // this should never happen p.second->frame.right = p.second->frame.left + 14; p.second->frame.bottom = p.second->frame.top + 10; break; case BTN_TALL: case BTN_TRAIT: p.second->frame.right = p.second->frame.left + 63; p.second->frame.bottom = p.second->frame.top + 40; break; case BTN_PUSH: p.second->frame.right = p.second->frame.left + 30; p.second->frame.bottom = p.second->frame.top + 30; break; default: p.second->frame.right = p.second->frame.left + 63; p.second->frame.bottom = p.second->frame.top + 23; } string content; for(node = node.begin(&who); node != node.end(); node++){ string val; int type = node->Type(); node->GetValue(&val); if(type == TiXmlNode::ELEMENT && val == "key"){ if(content.length() > 0) throw xBadVal("button","<content>",content + val,node->Row(),node->Column()); p.second->labelWithKey = true; }else if(type == TiXmlNode::TEXT) content += val; else{ val = '<' + val + '>'; throw xBadVal("text","<content>",val,node->Row(),node->Column()); } } p.second->lbl = content; if(p.first == ""){ do{ p.first = generateRandomString(); }while(controls.find(p.first) != controls.end()); } return p; }
template<> pair<string,cPict*> cDialog::parse(Element& who /*pict*/){ std::pair<std::string,cPict*> p; Iterator<Attribute> attr; std::string name; bool wide = false, tall = false, custom = false; bool foundTop = false, foundLeft = false, foundType = false, foundNum = false; // required attributes int width = 0, height = 0; p.second = new cPict(this); for(attr = attr.begin(&who); attr != attr.end(); attr++){ attr->GetName(&name); if(name == "name") attr->GetValue(&p.first); else if(name == "type"){ std::string val; foundType = true; attr->GetValue(&val); if(val == "blank"){ p.second->picType = PIC_TER; p.second->picNum = -1; }else if(val == "ter") p.second->picType = PIC_TER; else if(val == "teranim") p.second->picType = PIC_TER_ANIM; else if(val == "monst") p.second->picType = PIC_MONST; else if(val == "dlog") p.second->picType = PIC_DLOG; else if(val == "talk") p.second->picType = PIC_TALK; else if(val == "scen") p.second->picType = PIC_SCEN; else if(val == "item") p.second->picType = PIC_ITEM; else if(val == "pc") p.second->picType = PIC_PC; else if(val == "field") p.second->picType = PIC_FIELD; else if(val == "boom") p.second->picType = PIC_BOOM; else if(val == "missile") p.second->picType = PIC_MISSILE; else if(val == "full") p.second->picType = PIC_FULL; else if(val == "map") p.second->picType = PIC_TER_MAP; else if(val == "status") p.second->picType = PIC_STATUS; else throw xBadVal("pict",name,val,attr->Row(),attr->Column()); }else if(name == "custom"){ std::string val; attr->GetValue(&val); if(val == "true") custom = true; }else if(name == "clickable"){ std::string val; attr->GetValue(&val); if(val == "true") p.second->clickable = true; }else if(name == "size"){ std::string val; attr->GetValue(&val); if(val == "wide") wide = true; else if(val == "tall") tall = true; else if(val == "large") wide = tall = true; else throw xBadVal("pict",name,val,attr->Row(),attr->Column()); }else if(name == "def-key"){ std::string val; attr->GetValue(&val); try{ p.second->key = parseKey(val); }catch(int){ throw xBadVal("pict",name,val,attr->Row(),attr->Column()); } }else if(name == "num"){ attr->GetValue(&p.second->picNum), foundNum = true; }else if(name == "top"){ attr->GetValue(&p.second->frame.top), foundTop = true; }else if(name == "left"){ attr->GetValue(&p.second->frame.left), foundLeft = true;; }else if(name == "width"){ attr->GetValue(&width); }else if(name == "height"){ attr->GetValue(&height); }else throw xBadAttr("pict",name,attr->Row(),attr->Column()); } if(!foundType) throw xMissingAttr("pict","type",who.Row(),who.Column()); if(!foundNum) throw xMissingAttr("pict","num",who.Row(),who.Column()); if(!foundTop) throw xMissingAttr("pict","top",who.Row(),who.Column()); if(!foundLeft) throw xMissingAttr("pict","left",who.Row(),who.Column()); if(wide && !tall && p.second->picType == PIC_MONST) p.second->picType = PIC_MONST_WIDE; else if(!wide && tall && p.second->picType == PIC_MONST) p.second->picType = PIC_MONST_TALL; else if(wide && tall){ if(p.second->picType == PIC_MONST) p.second->picType = PIC_MONST_LG; else if(p.second->picType == PIC_SCEN) p.second->picType = PIC_SCEN_LG; else if(p.second->picType == PIC_DLOG) p.second->picType = PIC_DLOG_LG; } p.second->frame.right = p.second->frame.left; p.second->frame.bottom = p.second->frame.top; if(width > 0 || height > 0 || p.second->picType == PIC_FULL){ p.second->frame.right = p.second->frame.left + width; p.second->frame.bottom = p.second->frame.top + height; }else switch(p.second->picType){ case PIC_DLOG: p.second->frame.right = p.second->frame.left + 36; p.second->frame.bottom = p.second->frame.top + 36; break; case PIC_DLOG_LG: p.second->frame.right = p.second->frame.left + 72; p.second->frame.bottom = p.second->frame.top + 72; break; case PIC_SCEN: case PIC_TALK: p.second->frame.right = p.second->frame.left + 32; p.second->frame.bottom = p.second->frame.top + 32; break; case PIC_SCEN_LG: p.second->frame.right = p.second->frame.left + 64; p.second->frame.bottom = p.second->frame.top + 64; break; case PIC_MISSILE: p.second->frame.right = p.second->frame.left + 18; p.second->frame.bottom = p.second->frame.top + 18; break; case PIC_TER_MAP: p.second->frame.right = p.second->frame.left + 24; p.second->frame.bottom = p.second->frame.top + 24; break; case PIC_STATUS: p.second->frame.right = p.second->frame.left + 12; p.second->frame.bottom = p.second->frame.top + 12; break; default: p.second->frame.right = p.second->frame.left + 28; p.second->frame.bottom = p.second->frame.top + 36; break; } if(custom) p.second->picType += PIC_CUSTOM; if(p.first == ""){ do{ p.first = generateRandomString(); }while(controls.find(p.first) != controls.end()); } return p; }
template<> pair<string,cTextMsg*> cDialog::parse(Element& who /*text*/){ pair<string,cTextMsg*> p; Iterator<Attribute> attr; Iterator<Node> node; string name; int width = 0, height = 0; bool foundTop = false, foundLeft = false; // top and left are required attributes p.second = new cTextMsg(this); for(attr = attr.begin(&who); attr != attr.end(); attr++){ attr->GetName(&name); if(name == "name") attr->GetValue(&p.first); else if(name == "framed"){ std::string val; attr->GetValue(&val); if(val == "true") p.second->drawFramed = true; }else if(name == "clickable"){ std::string val; attr->GetValue(&val); if(val == "true") p.second->clickable = true; }else if(name == "font"){ std::string val; attr->GetValue(&val); if(val == "dungeon") p.second->textFont = DUNGEON; else if(val == "geneva") p.second->textFont = GENEVA; else if(val == "silom") p.second->textFont = SILOM; else if(val == "maidenword") p.second->textFont = MAIDENWORD; else throw xBadVal("text",name,val,attr->Row(),attr->Column()); }else if(name == "size"){ std::string val; attr->GetValue(&val); if(val == "large") p.second->textSize = 12; else if(val == "small") p.second->textSize = 10; else throw xBadVal("text",name,val,attr->Row(),attr->Column()); }else if(name == "color" || name == "colour"){ std::string val; attr->GetValue(&val); RGBColor clr; try{ clr = parseColor(val); }catch(int){ throw xBadVal("text",name,val,attr->Row(),attr->Column()); } p.second->color = clr; }else if(name == "def-key"){ std::string val; attr->GetValue(&val); try{ p.second->key = parseKey(val); }catch(int){ throw xBadVal("text",name,val,attr->Row(),attr->Column()); } }else if(name == "top"){ attr->GetValue(&p.second->frame.top), foundTop = true; }else if(name == "left"){ attr->GetValue(&p.second->frame.left), foundLeft = true; }else if(name == "width"){ attr->GetValue(&width); }else if(name == "height"){ attr->GetValue(&height); }else if(name == "fromlist"){ attr->GetValue(&p.second->fromList); }else throw xBadAttr("pict",name,attr->Row(),attr->Column()); } if(!foundTop) throw xMissingAttr("text","top",who.Row(),who.Column()); if(!foundLeft) throw xMissingAttr("text","left",who.Row(),who.Column()); p.second->frame.right = p.second->frame.left + width; p.second->frame.bottom = p.second->frame.top + height; string content; for(node = node.begin(&who); node != node.end(); node++){ string val; int type = node->Type(); node->GetValue(&val); if(type == TiXmlNode::ELEMENT && val == "br") content += '|'; // because vertical bar is replaced by a newline when drawing strings else if(type == TiXmlNode::TEXT) content += val; else{ val = '<' + val + '>'; throw xBadVal("text","<content>",content + val,node->Row(),node->Column()); } } p.second->lbl = content; if(p.first == ""){ do{ p.first = generateRandomString(); }while(controls.find(p.first) != controls.end()); } return p; }