diff --git a/src/dialogxml/widgets/container.cpp b/src/dialogxml/widgets/container.cpp index 3fd91d4f..7483ec33 100644 --- a/src/dialogxml/widgets/container.cpp +++ b/src/dialogxml/widgets/container.cpp @@ -16,38 +16,49 @@ #include "dialogxml/widgets/scrollbar.hpp" #include "replay.hpp" -bool cContainer::parseChildControl(ticpp::Element& elem, std::map& controls, std::string& id) { +bool cContainer::parseChildControl(ticpp::Element& elem, std::map& controls, std::string& id, std::string fname) { + ctrlIter inserted; std::string tag = elem.Value(); if(tag == "field") { auto field = parent->parse(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(elem); - controls.insert(text); + inserted = controls.insert(text).first; id = text.first; } else if(tag == "pict") { auto pict = parent->parse(elem); - controls.insert(pict); + inserted = controls.insert(pict).first; id = pict.first; } else if(tag == "slider") { auto slide = parent->parse(elem); - controls.insert(slide); + inserted = controls.insert(slide).first; id = slide.first; } else if(tag == "button") { auto button = parent->parse(elem); - controls.insert(button); + inserted = controls.insert(button).first; id = button.first; } else if(tag == "led") { auto led = parent->parse(elem); - controls.insert(led); + inserted = controls.insert(led).first; id = led.first; } else if(tag == "group") { auto group = parent->parse(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", "", 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; } diff --git a/src/dialogxml/widgets/container.hpp b/src/dialogxml/widgets/container.hpp index 4b5a1f6a..fd1e1718 100644 --- a/src/dialogxml/widgets/container.hpp +++ b/src/dialogxml/widgets/container.hpp @@ -11,6 +11,8 @@ #include "control.hpp" +typedef std::map::iterator ctrlIter; + /// A superclass to represent a control that contains other controls. class cContainer : public cControl { void callHandler(event_fcn::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& controls, std::string& id); + bool parseChildControl(ticpp::Element& elem, std::map& 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(*this).getChild(id);} bool isContainer() const override {return true;} bool handleClick(location where, cFramerateLimiter& fps_limiter) override; +private: + std::pair prevCtrl{"", nullptr}; }; #endif diff --git a/src/dialogxml/widgets/control.hpp b/src/dialogxml/widgets/control.hpp index b8e63e9a..f0a1983b 100644 --- a/src/dialogxml/widgets/control.hpp +++ b/src/dialogxml/widgets/control.hpp @@ -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; diff --git a/src/dialogxml/widgets/scrollpane.cpp b/src/dialogxml/widgets/scrollpane.cpp index 46082084..bffaba68 100644 --- a/src/dialogxml/widgets/scrollpane.cpp +++ b/src/dialogxml/widgets/scrollpane.cpp @@ -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(content), contents, id); + return parseChildControl(dynamic_cast(content), contents, id, fname); } return cContainer::parseContent(content, n, tagName, fname, text); } diff --git a/src/dialogxml/widgets/stack.cpp b/src/dialogxml/widgets/stack.cpp index 6a51c47e..a0f99af5 100644 --- a/src/dialogxml/widgets/stack.cpp +++ b/src/dialogxml/widgets/stack.cpp @@ -177,7 +177,7 @@ bool cStack::parseContent(ticpp::Node& content, int n, std::string tagName, std: Iterator 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); }