diff --git a/client/gui/InterfaceObjectConfigurable.cpp b/client/gui/InterfaceObjectConfigurable.cpp index 130cfec71..9714b9663 100644 --- a/client/gui/InterfaceObjectConfigurable.cpp +++ b/client/gui/InterfaceObjectConfigurable.cpp @@ -26,14 +26,14 @@ #include "../../lib/CGeneralTextHandler.h" -InterfaceObjectConfigurable::InterfaceObjectConfigurable(const JsonNode & config): - CIntObject() +InterfaceObjectConfigurable::InterfaceObjectConfigurable(const JsonNode & config, int used, Point offset): + CIntObject(used, offset) { init(config); } -InterfaceObjectConfigurable::InterfaceObjectConfigurable(): - CIntObject() +InterfaceObjectConfigurable::InterfaceObjectConfigurable(int used, Point offset): + CIntObject(used, offset) { } @@ -55,6 +55,12 @@ void InterfaceObjectConfigurable::init(const JsonNode &config) : item["name"].String(); widgets[name] = buildWidget(item); } + variables = config["variables"]; +} + +const JsonNode & InterfaceObjectConfigurable::variable(const std::string & name) const +{ + return variables[name]; } std::string InterfaceObjectConfigurable::readText(const JsonNode & config) const @@ -153,7 +159,10 @@ std::shared_ptr InterfaceObjectConfigurable::buildPicture(const JsonNo { auto image = readText(config["image"]); auto position = readPosition(config["position"]); - return std::make_shared(image, position.x, position.y); + auto pic = std::make_shared(image, position.x, position.y); + if(!config["visible"].isNull()) + pic->visible = config["visible"].Bool(); + return pic; } std::shared_ptr InterfaceObjectConfigurable::buildLabel(const JsonNode & config) const @@ -243,6 +252,18 @@ std::shared_ptr InterfaceObjectConfigurable::buildLabelGroup(const return group; } +std::shared_ptr InterfaceObjectConfigurable::buildSlider(const JsonNode & config) const +{ + auto position = readPosition(config["position"]); + int length = config["size"].Integer(); + auto style = config["style"].String() == "brown" ? CSlider::BROWN : CSlider::BLUE; + auto itemsVisible = config["itemsVisible"].Integer(); + auto itemsTotal = config["itemsTotal"].Integer(); + auto value = config["selected"].Integer(); + bool horizontal = config["orientation"].String() == "horizontal"; + return std::make_shared(position, length, callbacks.at(config["callback"].String()), itemsVisible, itemsTotal, value, horizontal, style); +} + std::shared_ptr InterfaceObjectConfigurable::buildWidget(const JsonNode & config) const { assert(!config.isNull()); @@ -271,14 +292,18 @@ std::shared_ptr InterfaceObjectConfigurable::buildWidget(const JsonN { return buildLabelGroup(config); } + if(type == "slider") + { + return buildSlider(config); + } if(type == "custom") { - return buildCustomWidget(config); + return const_cast(this)->buildCustomWidget(config); } return std::shared_ptr(nullptr); } -std::shared_ptr InterfaceObjectConfigurable::buildCustomWidget(const JsonNode & config) const +std::shared_ptr InterfaceObjectConfigurable::buildCustomWidget(const JsonNode & config) { return nullptr; } diff --git a/client/gui/InterfaceObjectConfigurable.h b/client/gui/InterfaceObjectConfigurable.h index cae184738..980f8b817 100644 --- a/client/gui/InterfaceObjectConfigurable.h +++ b/client/gui/InterfaceObjectConfigurable.h @@ -20,12 +20,13 @@ class CToggleGroup; class CToggleButton; class CButton; class CLabelGroup; +class CSlider; class InterfaceObjectConfigurable: public CIntObject { public: - InterfaceObjectConfigurable(); - InterfaceObjectConfigurable(const JsonNode & config); + InterfaceObjectConfigurable(int used=0, Point offset=Point()); + InterfaceObjectConfigurable(const JsonNode & config, int used=0, Point offset=Point()); protected: //must be called after adding callbacks @@ -42,9 +43,8 @@ protected: return std::dynamic_pointer_cast(iter->second); } - virtual std::shared_ptr buildCustomWidget(const JsonNode & config) const; + const JsonNode & variable(const std::string & name) const; -private: //field deserializers //basic serializers Point readPosition(const JsonNode &) const; ETextAlignment readTextAlignment(const JsonNode &) const; @@ -60,12 +60,15 @@ private: //field deserializers std::shared_ptr buildToggleButton(const JsonNode &) const; std::shared_ptr buildButton(const JsonNode &) const; std::shared_ptr buildLabelGroup(const JsonNode &) const; + std::shared_ptr buildSlider(const JsonNode &) const; - + //composite widgets + virtual std::shared_ptr buildCustomWidget(const JsonNode & config); std::shared_ptr buildWidget(const JsonNode & config) const; private: std::map> widgets; std::map> callbacks; + JsonNode variables; }; diff --git a/client/lobby/RandomMapTab.cpp b/client/lobby/RandomMapTab.cpp index 37f6a8829..a17c66c8d 100644 --- a/client/lobby/RandomMapTab.cpp +++ b/client/lobby/RandomMapTab.cpp @@ -302,48 +302,56 @@ std::vector RandomMapTab::getPossibleMapSizes() return {CMapHeader::MAP_SIZE_SMALL, CMapHeader::MAP_SIZE_MIDDLE, CMapHeader::MAP_SIZE_LARGE, CMapHeader::MAP_SIZE_XLARGE, CMapHeader::MAP_SIZE_HUGE, CMapHeader::MAP_SIZE_XHUGE, CMapHeader::MAP_SIZE_GIANT}; } -TemplatesDropBox::ListItem::ListItem(TemplatesDropBox & _dropBox, Point position) - : CIntObject(LCLICK | HOVER, position), +TemplatesDropBox::ListItem::ListItem(const JsonNode & config, TemplatesDropBox & _dropBox, Point position) + : InterfaceObjectConfigurable(LCLICK | HOVER, position), dropBox(_dropBox) { OBJ_CONSTRUCTION; - labelName = std::make_shared(0, 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE); - labelName->setAutoRedraw(false); - hoverImage = std::make_shared("List10Sl", 0, 0); - hoverImage->visible = false; + init(config); - pos.w = hoverImage->pos.w; - pos.h = hoverImage->pos.h; + if(auto w = widget("hoverImage")) + { + pos.w = w->pos.w; + pos.h = w->pos.h; + } type |= REDRAW_PARENT; } void TemplatesDropBox::ListItem::updateItem(int idx, const CRmgTemplate * _item) { - item = _item; - if(item) + if(auto w = widget("labelName")) { - labelName->setText(item->getName()); - } - else - { - if(idx) - labelName->setText(""); + item = _item; + if(item) + { + w->setText(item->getName()); + } else - labelName->setText("default"); + { + if(idx) + w->setText(""); + else + w->setText("default"); + } } } void TemplatesDropBox::ListItem::hover(bool on) { - if(labelName->getText().empty()) + auto h = widget("hoverImage"); + auto w = widget("labelName"); + if(h && w) { - hovered = false; - hoverImage->visible = false; - } - else - { - hoverImage->visible = on; + if(w->getText().empty()) + { + hovered = false; + h->visible = false; + } + else + { + h->visible = on; + } } redraw(); } @@ -358,32 +366,43 @@ void TemplatesDropBox::ListItem::clickLeft(tribool down, bool previousState) TemplatesDropBox::TemplatesDropBox(RandomMapTab & randomMapTab, int3 size): - CIntObject(LCLICK | HOVER), + InterfaceObjectConfigurable(LCLICK | HOVER), randomMapTab(randomMapTab) { curItems = VLC->tplh->getTemplates(); vstd::erase_if(curItems, [size](const CRmgTemplate * t){return !t->matchesSize(size);}); curItems.insert(curItems.begin(), nullptr); //default template + const JsonNode config(ResourceID("config/windows/randomMapTemplateWidget.json")); + + addCallback("sliderMove", std::bind(&TemplatesDropBox::sliderMove, this, std::placeholders::_1)); + OBJ_CONSTRUCTION; pos = randomMapTab.pos.topLeft(); pos.w = randomMapTab.pos.w; pos.h = randomMapTab.pos.h; - background = std::make_shared("List10Bk", 158, 76); - int positionsToShow = 10; + init(config); - for(int i = 0; i < positionsToShow; i++) - listItems.push_back(std::make_shared(*this, Point(158, 76 + i * 25))); - - slider = std::make_shared(Point(212 + 158, 76), 252, std::bind(&TemplatesDropBox::sliderMove, this, _1), positionsToShow, (int)curItems.size(), 0, false, CSlider::BLUE); + if(auto w = widget("slider")) + { + w->setAmount(curItems.size()); + } updateListItems(); } +std::shared_ptr TemplatesDropBox::buildCustomWidget(const JsonNode & config) +{ + auto position = readPosition(config["position"]); + listItems.push_back(std::make_shared(config, *this, position)); + return listItems.back(); +} + void TemplatesDropBox::sliderMove(int slidPos) { - if(!slider) + auto w = widget("slider"); + if(!w) return; // ignore spurious call when slider is being created updateListItems(); redraw(); @@ -405,17 +424,20 @@ void TemplatesDropBox::clickLeft(tribool down, bool previousState) void TemplatesDropBox::updateListItems() { - int elemIdx = slider->getValue(); - for(auto item : listItems) + if(auto w = widget("slider")) { - if(elemIdx < curItems.size()) + int elemIdx = w->getValue(); + for(auto item : listItems) { - item->updateItem(elemIdx, curItems[elemIdx]); - elemIdx++; - } - else - { - item->updateItem(elemIdx); + if(elemIdx < curItems.size()) + { + item->updateItem(elemIdx, curItems[elemIdx]); + elemIdx++; + } + else + { + item->updateItem(elemIdx); + } } } } diff --git a/client/lobby/RandomMapTab.h b/client/lobby/RandomMapTab.h index aee146e1f..effe2d66f 100644 --- a/client/lobby/RandomMapTab.h +++ b/client/lobby/RandomMapTab.h @@ -49,16 +49,14 @@ private: std::set playerCountAllowed, playerTeamsAllowed, compCountAllowed, compTeamsAllowed; }; -class TemplatesDropBox : public CIntObject +class TemplatesDropBox : public InterfaceObjectConfigurable { - struct ListItem : public CIntObject + struct ListItem : public InterfaceObjectConfigurable { - std::shared_ptr labelName; - std::shared_ptr hoverImage; TemplatesDropBox & dropBox; const CRmgTemplate * item = nullptr; - ListItem(TemplatesDropBox &, Point position); + ListItem(const JsonNode &, TemplatesDropBox &, Point position); void updateItem(int index, const CRmgTemplate * item = nullptr); void hover(bool on) override; @@ -72,15 +70,16 @@ public: void clickLeft(tribool down, bool previousState) override; void setTemplate(const CRmgTemplate *); +protected: + std::shared_ptr buildCustomWidget(const JsonNode & config) override; + private: void sliderMove(int slidPos); void updateListItems(); RandomMapTab & randomMapTab; - std::shared_ptr background; std::vector> listItems; - std::shared_ptr slider; std::vector curItems; diff --git a/client/widgets/Buttons.cpp b/client/widgets/Buttons.cpp index e180181ae..435a89396 100644 --- a/client/widgets/Buttons.cpp +++ b/client/widgets/Buttons.cpp @@ -566,16 +566,21 @@ void CSlider::setScrollStep(int to) scrollStep = to; } -int CSlider::getAmount() +int CSlider::getAmount() const { return amount; } -int CSlider::getValue() +int CSlider::getValue() const { return value; } +int CSlider::getCapacity() const +{ + return capacity; +} + void CSlider::moveLeft() { moveTo(value-1); diff --git a/client/widgets/Buttons.h b/client/widgets/Buttons.h index d370b515e..f967fa953 100644 --- a/client/widgets/Buttons.h +++ b/client/widgets/Buttons.h @@ -256,8 +256,9 @@ public: void setAmount(int to); /// Accessors - int getAmount(); - int getValue(); + int getAmount() const; + int getValue() const; + int getCapacity() const; void addCallback(std::function callback);