Make cContainers handle relative elements within
This commit is contained in:
@@ -16,38 +16,49 @@
|
||||
#include "dialogxml/widgets/scrollbar.hpp"
|
||||
#include "replay.hpp"
|
||||
|
||||
bool cContainer::parseChildControl(ticpp::Element& elem, std::map<std::string,cControl*>& controls, std::string& id) {
|
||||
bool cContainer::parseChildControl(ticpp::Element& elem, std::map<std::string,cControl*>& controls, std::string& id, std::string fname) {
|
||||
ctrlIter inserted;
|
||||
std::string tag = elem.Value();
|
||||
if(tag == "field") {
|
||||
auto field = parent->parse<cTextField>(elem);
|
||||
controls.insert(field);
|
||||
inserted = controls.insert(field).first;
|
||||
parent->tabOrder.push_back(field);
|
||||
id = field.first;
|
||||
} else if(tag == "text") {
|
||||
auto text = parent->parse<cTextMsg>(elem);
|
||||
controls.insert(text);
|
||||
inserted = controls.insert(text).first;
|
||||
id = text.first;
|
||||
} else if(tag == "pict") {
|
||||
auto pict = parent->parse<cPict>(elem);
|
||||
controls.insert(pict);
|
||||
inserted = controls.insert(pict).first;
|
||||
id = pict.first;
|
||||
} else if(tag == "slider") {
|
||||
auto slide = parent->parse<cScrollbar>(elem);
|
||||
controls.insert(slide);
|
||||
inserted = controls.insert(slide).first;
|
||||
id = slide.first;
|
||||
} else if(tag == "button") {
|
||||
auto button = parent->parse<cButton>(elem);
|
||||
controls.insert(button);
|
||||
inserted = controls.insert(button).first;
|
||||
id = button.first;
|
||||
} else if(tag == "led") {
|
||||
auto led = parent->parse<cLed>(elem);
|
||||
controls.insert(led);
|
||||
inserted = controls.insert(led).first;
|
||||
id = led.first;
|
||||
} else if(tag == "group") {
|
||||
auto group = parent->parse<cLedGroup>(elem);
|
||||
controls.insert(group);
|
||||
inserted = controls.insert(group).first;
|
||||
id = group.first;
|
||||
} else return false;
|
||||
if(prevCtrl.second) {
|
||||
if(inserted->second->anchor == "$$prev$$" && prevCtrl.second->anchor == "$$next$$") {
|
||||
throw xBadVal(tag, "anchor", "<circular dependency>", elem.Row(), elem.Column(), fname);
|
||||
} else if(inserted->second->anchor == "$$prev$$") {
|
||||
inserted->second->anchor = prevCtrl.first;
|
||||
} else if(prevCtrl.second->anchor == "$$next$$") {
|
||||
prevCtrl.second->anchor = inserted->first;
|
||||
}
|
||||
}
|
||||
prevCtrl = *inserted;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -11,6 +11,8 @@
|
||||
|
||||
#include "control.hpp"
|
||||
|
||||
typedef std::map<std::string,cControl*>::iterator ctrlIter;
|
||||
|
||||
/// A superclass to represent a control that contains other controls.
|
||||
class cContainer : public cControl {
|
||||
void callHandler(event_fcn<EVT_CLICK>::type onClick, cDialog& me, std::string id, eKeyMod mods) override;
|
||||
@@ -21,7 +23,7 @@ protected:
|
||||
/// @param controls The map into which the control will be inserted.
|
||||
/// @param[out] The ID of the new control.
|
||||
/// @return true if the element was a valid control, false otherwise.
|
||||
bool parseChildControl(ticpp::Element& elem, std::map<std::string,cControl*>& controls, std::string& id);
|
||||
bool parseChildControl(ticpp::Element& elem, std::map<std::string,cControl*>& controls, std::string& id, std::string fname);
|
||||
public:
|
||||
/// Create a new container control attached to an arbitrary window, rather than a dialog.
|
||||
/// @param t The type of the control.
|
||||
@@ -49,6 +51,8 @@ public:
|
||||
const cControl& operator[](std::string id) const {return const_cast<cContainer&>(*this).getChild(id);}
|
||||
bool isContainer() const override {return true;}
|
||||
bool handleClick(location where, cFramerateLimiter& fps_limiter) override;
|
||||
private:
|
||||
std::pair<std::string,cControl*> prevCtrl{"", nullptr};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -459,7 +459,8 @@ protected:
|
||||
/// Plays the proper sound for this control being clicked on
|
||||
void playClickSound();
|
||||
private:
|
||||
friend class cDialog; // TODO: This is only so it can access parseColour... hack!
|
||||
friend class cDialog; // This is so it can access parseColour and anchor
|
||||
friend class cContainer; // This is so it can access anchor
|
||||
/// The control's current text.
|
||||
std::string lbl;
|
||||
eControlType type;
|
||||
|
@@ -173,7 +173,7 @@ bool cScrollPane::parseAttribute(ticpp::Attribute& attr, std::string tagName, st
|
||||
bool cScrollPane::parseContent(ticpp::Node& content, int n, std::string tagName, std::string fname, std::string& text) {
|
||||
if(content.Type() == TiXmlNode::ELEMENT) {
|
||||
std::string id;
|
||||
return parseChildControl(dynamic_cast<ticpp::Element&>(content), contents, id);
|
||||
return parseChildControl(dynamic_cast<ticpp::Element&>(content), contents, id, fname);
|
||||
}
|
||||
return cContainer::parseContent(content, n, tagName, fname, text);
|
||||
}
|
||||
|
@@ -177,7 +177,7 @@ bool cStack::parseContent(ticpp::Node& content, int n, std::string tagName, std:
|
||||
Iterator<Element> iter;
|
||||
for(iter = iter.begin(&elem); iter != iter.end(); iter++) {
|
||||
if(iter->Type() == TiXmlNode::ELEMENT) {
|
||||
if(!parseChildControl(*iter, controls, id)) return false;
|
||||
if(!parseChildControl(*iter, controls, id, fname)) return false;
|
||||
templates.back().push_back(id);
|
||||
}
|
||||
}
|
||||
@@ -206,7 +206,7 @@ bool cStack::parseContent(ticpp::Node& content, int n, std::string tagName, std:
|
||||
} else throw xBadAttr("page", name, attr->Row(), attr->Column(), fname);
|
||||
}
|
||||
return true;
|
||||
} else return parseChildControl(elem, controls, id);
|
||||
} else return parseChildControl(elem, controls, id, fname);
|
||||
}
|
||||
return cContainer::parseContent(content, n, tagName, fname, text);
|
||||
}
|
||||
|
Reference in New Issue
Block a user