loading ui from files
This commit is contained in:
parent
150afa86f3
commit
792d661dad
|
@ -55,6 +55,7 @@ SET(SOURCES
|
||||||
# game sources
|
# game sources
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/menustate.cpp
|
src/menustate.cpp
|
||||||
|
src/mainmenu.cpp
|
||||||
src/teststate.cpp
|
src/teststate.cpp
|
||||||
|
|
||||||
# game net
|
# game net
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
|
|
||||||
#include <GL/gl.h>
|
|
||||||
|
|
||||||
BorderedImage::BorderedImage(TexturePtr texture,
|
BorderedImage::BorderedImage(TexturePtr texture,
|
||||||
const Rect& left,
|
const Rect& left,
|
||||||
const Rect& right,
|
const Rect& right,
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "anchorlayout.h"
|
#include "anchorlayout.h"
|
||||||
|
#include "uielement.h"
|
||||||
|
|
||||||
int AnchorLine::getPos() const
|
int AnchorLine::getPos() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -97,6 +97,11 @@ public:
|
||||||
void setMargin(int horizontal, int vertical) { m_marginLeft = m_marginRight = horizontal; m_marginTop = m_marginBottom = vertical; recalculateAnchors(); }
|
void setMargin(int horizontal, int vertical) { m_marginLeft = m_marginRight = horizontal; m_marginTop = m_marginBottom = vertical; recalculateAnchors(); }
|
||||||
void setMargin(int margin) { m_marginLeft = m_marginRight = m_marginTop = m_marginBottom = margin; recalculateAnchors(); }
|
void setMargin(int margin) { m_marginLeft = m_marginRight = m_marginTop = m_marginBottom = margin; recalculateAnchors(); }
|
||||||
|
|
||||||
|
void setMarginLeft(int margin) { m_marginLeft = margin; recalculateAnchors(); }
|
||||||
|
void setMarginRight(int margin) { m_marginRight = margin; recalculateAnchors(); }
|
||||||
|
void setMarginTop(int margin) { m_marginTop = margin; recalculateAnchors(); }
|
||||||
|
void setMarginBottom(int margin) { m_marginBottom = margin; recalculateAnchors(); }
|
||||||
|
|
||||||
AnchorLayoutPtr asAnchorLayout() { return shared_from_this(); }
|
AnchorLayoutPtr asAnchorLayout() { return shared_from_this(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -26,6 +26,12 @@
|
||||||
#include "../fonts.h"
|
#include "../fonts.h"
|
||||||
#include "../font.h"
|
#include "../font.h"
|
||||||
|
|
||||||
|
void UIButton::load(const YAML::Node& node)
|
||||||
|
{
|
||||||
|
UIElement::load(node);
|
||||||
|
node["text"] >> m_text;
|
||||||
|
}
|
||||||
|
|
||||||
void UIButton::render()
|
void UIButton::render()
|
||||||
{
|
{
|
||||||
UIElement::render();
|
UIElement::render();
|
||||||
|
|
|
@ -34,12 +34,14 @@ typedef std::function<void()> Callback;
|
||||||
class UIButton : public UIElement
|
class UIButton : public UIElement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UIButton(const std::string& text) : UIElement(UI::Button),
|
UIButton(const std::string& text = std::string()) : UIElement(UI::Button),
|
||||||
m_text(text),
|
m_text(text),
|
||||||
m_state(UI::ButtonUp) {
|
m_state(UI::ButtonUp) {
|
||||||
UIElement();
|
UIElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void load(const YAML::Node& node);
|
||||||
|
|
||||||
virtual void render();
|
virtual void render();
|
||||||
bool onInputEvent(const InputEvent& event);
|
bool onInputEvent(const InputEvent& event);
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,99 @@
|
||||||
|
|
||||||
|
|
||||||
#include "uicontainer.h"
|
#include "uicontainer.h"
|
||||||
|
#include "../resources.h"
|
||||||
|
#include "uibutton.h"
|
||||||
|
#include "uipanel.h"
|
||||||
|
#include "uilabel.h"
|
||||||
|
#include "uitextedit.h"
|
||||||
|
#include "uiwindow.h"
|
||||||
|
|
||||||
UIContainerPtr g_ui(new UIContainer);
|
UIContainerPtr g_ui(new UIContainer);
|
||||||
|
|
||||||
|
UIElementPtr createElementFromDescription(std::string elementId)
|
||||||
|
{
|
||||||
|
UIElementPtr element;
|
||||||
|
|
||||||
|
std::vector<std::string> split;
|
||||||
|
boost::split(split, elementId, boost::is_any_of("-"));
|
||||||
|
if(split.size() != 2) {
|
||||||
|
logError("incorrect element id format: %s", elementId.c_str());
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string elementType = split[1];
|
||||||
|
if(elementType == "panel") {
|
||||||
|
element = UIElementPtr(new UIPanel);
|
||||||
|
} else if(elementType == "button") {
|
||||||
|
element = UIElementPtr(new UIButton);
|
||||||
|
} else if(elementType == "label") {
|
||||||
|
element = UIElementPtr(new UILabel);
|
||||||
|
} else if(elementType == "window") {
|
||||||
|
element = UIElementPtr(new UIWindow);
|
||||||
|
} else if(elementType == "textEdit") {
|
||||||
|
element = UIElementPtr(new UITextEdit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(element)
|
||||||
|
element->setId(elementId);
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIContainer::load(const YAML::Node& node)
|
||||||
|
{
|
||||||
|
UIElement::load(node);
|
||||||
|
|
||||||
|
for(auto it = node.begin(); it != node.end(); ++it) {
|
||||||
|
std::string elementDesc;
|
||||||
|
it.first() >> elementDesc;
|
||||||
|
|
||||||
|
if(elementDesc.find("-") != std::string::npos) {
|
||||||
|
UIElementPtr element = createElementFromDescription(elementDesc);
|
||||||
|
if(element) {
|
||||||
|
addChild(element);
|
||||||
|
element->load(it.second());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UIContainerPtr UIContainer::load(const std::string& file)
|
||||||
|
{
|
||||||
|
//TODO: handle errors
|
||||||
|
//TODO: display errors in which file and line
|
||||||
|
UIContainerPtr container;
|
||||||
|
|
||||||
|
std::string fileContents = g_resources.loadTextFile(file);
|
||||||
|
if(!fileContents.size()) {
|
||||||
|
logFatal("could not load ui file \"%s", file.c_str());
|
||||||
|
return UIContainerPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istringstream fin(fileContents);
|
||||||
|
|
||||||
|
try {
|
||||||
|
YAML::Parser parser(fin);
|
||||||
|
|
||||||
|
YAML::Node doc;
|
||||||
|
parser.GetNextDocument(doc);
|
||||||
|
|
||||||
|
std::string elementDesc;
|
||||||
|
doc.begin().first() >> elementDesc;
|
||||||
|
UIElementPtr element = createElementFromDescription(elementDesc);
|
||||||
|
if(element) {
|
||||||
|
g_ui->addChild(element);
|
||||||
|
element->load(doc.begin().second());
|
||||||
|
return element->asUIContainer();
|
||||||
|
}
|
||||||
|
} catch (YAML::ParserException& e) {
|
||||||
|
logError("Malformed ui file \"%s\": %s", file.c_str(), e.what());
|
||||||
|
return UIContainerPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
void UIContainer::addChild(UIElementPtr child)
|
void UIContainer::addChild(UIElementPtr child)
|
||||||
{
|
{
|
||||||
m_children.push_back(child);
|
m_children.push_back(child);
|
||||||
|
@ -41,12 +131,35 @@ void UIContainer::removeChild(UIElementPtr child)
|
||||||
child->setParent(UIContainerPtr());
|
child->setParent(UIContainerPtr());
|
||||||
}
|
}
|
||||||
|
|
||||||
UIElementPtr UIContainer::getChildById(const std::string& id) const
|
UIElementPtr UIContainer::getChildById(const std::string& id)
|
||||||
{
|
{
|
||||||
|
if(getId() == id)
|
||||||
|
return asUIElement();
|
||||||
for(auto it = m_children.begin(); it != m_children.end(); ++it) {
|
for(auto it = m_children.begin(); it != m_children.end(); ++it) {
|
||||||
if((*it)->getId() == id) {
|
if((*it)->getId() == id) {
|
||||||
return (*it);
|
return (*it);
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
|
return UIElementPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
UIElementPtr UIContainer::recursiveGetChildById(const std::string& id)
|
||||||
|
{
|
||||||
|
if(getId() == id)
|
||||||
|
return asUIElement();
|
||||||
|
|
||||||
|
UIElementPtr element;
|
||||||
|
for(auto it = m_children.begin(); it != m_children.end(); ++it) {
|
||||||
|
element = (*it);
|
||||||
|
if(element->getId() == id) {
|
||||||
|
return element;
|
||||||
|
} else {
|
||||||
|
UIContainerPtr container = element->asUIContainer();
|
||||||
|
if(container) {
|
||||||
|
element = container->recursiveGetChildById(id);
|
||||||
|
if(element)
|
||||||
|
return element;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return UIElementPtr();
|
return UIElementPtr();
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#ifndef UICONTAINER_H
|
#ifndef UICONTAINER_H
|
||||||
#define UICONTAINER_H
|
#define UICONTAINER_H
|
||||||
|
|
||||||
|
//TODO: make includes paths, so this will be cleaner
|
||||||
#include "../prerequisites.h"
|
#include "../prerequisites.h"
|
||||||
#include "uielement.h"
|
#include "uielement.h"
|
||||||
#include "../point.h"
|
#include "../point.h"
|
||||||
|
@ -36,9 +37,17 @@ public:
|
||||||
UIContainer(UI::EElementType type = UI::Container) : UIElement(type) { }
|
UIContainer(UI::EElementType type = UI::Container) : UIElement(type) { }
|
||||||
virtual ~UIContainer() { }
|
virtual ~UIContainer() { }
|
||||||
|
|
||||||
|
virtual void load(const YAML::Node& node);
|
||||||
|
|
||||||
|
//TODO: move this shit
|
||||||
|
static UIContainerPtr load(const std::string& file);
|
||||||
|
|
||||||
void addChild(UIElementPtr child);
|
void addChild(UIElementPtr child);
|
||||||
void removeChild(UIElementPtr child);
|
void removeChild(UIElementPtr child);
|
||||||
UIElementPtr getChildById(const std::string& id) const;
|
UIElementPtr getChildById(const std::string& id);
|
||||||
|
|
||||||
|
//TODO: make this backwards
|
||||||
|
UIElementPtr recursiveGetChildById(const std::string& id);
|
||||||
|
|
||||||
virtual void render();
|
virtual void render();
|
||||||
virtual bool onInputEvent(const InputEvent& event);
|
virtual bool onInputEvent(const InputEvent& event);
|
||||||
|
@ -53,9 +62,6 @@ public:
|
||||||
protected:
|
protected:
|
||||||
std::list<UIElementPtr> m_children;
|
std::list<UIElementPtr> m_children;
|
||||||
UIElementPtr m_activeElement;
|
UIElementPtr m_activeElement;
|
||||||
|
|
||||||
private:
|
|
||||||
void onMove(const Point& pos);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern UIContainerPtr g_ui;
|
extern UIContainerPtr g_ui;
|
||||||
|
|
|
@ -38,6 +38,106 @@ UIElement::UIElement(UI::EElementType type) :
|
||||||
setSkin(g_uiSkins.getElementSkin(type));
|
setSkin(g_uiSkins.getElementSkin(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UIElement::load(const YAML::Node& node)
|
||||||
|
{
|
||||||
|
if(node.FindValue("skin"))
|
||||||
|
setSkin(g_uiSkins.getElementSkin(m_type, node["skin"]));
|
||||||
|
|
||||||
|
if(node.FindValue("size")) {
|
||||||
|
Size size;
|
||||||
|
node["size"] >> size;
|
||||||
|
setSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int margin;
|
||||||
|
if(node.FindValue("margin.left")) {
|
||||||
|
node["margin.left"] >> margin;
|
||||||
|
setMarginLeft(margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node.FindValue("margin.right")) {
|
||||||
|
node["margin.right"] >> margin;
|
||||||
|
setMarginRight(margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node.FindValue("margin.top")) {
|
||||||
|
node["margin.top"] >> margin;
|
||||||
|
setMarginTop(margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node.FindValue("margin.bottom")) {
|
||||||
|
node["margin.bottom"] >> margin;
|
||||||
|
setMarginBottom(margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node.FindValue("anchors.left"))
|
||||||
|
loadAnchor(ANCHOR_LEFT, node["anchors.left"]);
|
||||||
|
|
||||||
|
if(node.FindValue("anchors.right"))
|
||||||
|
loadAnchor(ANCHOR_RIGHT, node["anchors.right"]);
|
||||||
|
|
||||||
|
if(node.FindValue("anchors.top"))
|
||||||
|
loadAnchor(ANCHOR_TOP, node["anchors.top"]);
|
||||||
|
|
||||||
|
if(node.FindValue("anchors.bottom"))
|
||||||
|
loadAnchor(ANCHOR_BOTTOM, node["anchors.bottom"]);
|
||||||
|
|
||||||
|
if(node.FindValue("anchors.horizontalCenter"))
|
||||||
|
loadAnchor(ANCHOR_HORIZONTAL_CENTER, node["anchors.horizontalCenter"]);
|
||||||
|
|
||||||
|
if(node.FindValue("anchors.verticalCenter"))
|
||||||
|
loadAnchor(ANCHOR_VERTICAL_CENTER, node["anchors.verticalCenter"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIElement::loadAnchor(EAnchorType type, const YAML::Node& node)
|
||||||
|
{
|
||||||
|
std::string anchorDescription;
|
||||||
|
node >> anchorDescription;
|
||||||
|
|
||||||
|
std::vector<std::string> split;
|
||||||
|
boost::split(split, anchorDescription, boost::is_any_of("."));
|
||||||
|
if(split.size() != 2) {
|
||||||
|
logError("wrong anchors description: %s", anchorDescription.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string relativeElementId = split[0];
|
||||||
|
std::string relativeAnchorTypeId = split[1];
|
||||||
|
EAnchorType relativeAnchorType;
|
||||||
|
|
||||||
|
if(relativeAnchorTypeId == "left")
|
||||||
|
relativeAnchorType = ANCHOR_LEFT;
|
||||||
|
else if(relativeAnchorTypeId == "right")
|
||||||
|
relativeAnchorType = ANCHOR_RIGHT;
|
||||||
|
else if(relativeAnchorTypeId == "top")
|
||||||
|
relativeAnchorType = ANCHOR_TOP;
|
||||||
|
else if(relativeAnchorTypeId == "bottom")
|
||||||
|
relativeAnchorType = ANCHOR_BOTTOM;
|
||||||
|
else if(relativeAnchorTypeId == "horizontalCenter")
|
||||||
|
relativeAnchorType = ANCHOR_HORIZONTAL_CENTER;
|
||||||
|
else if(relativeAnchorTypeId == "verticalCenter")
|
||||||
|
relativeAnchorType = ANCHOR_VERTICAL_CENTER;
|
||||||
|
else {
|
||||||
|
logError("wrong anchors description: %s", anchorDescription.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnchorLayoutPtr relativeElement;
|
||||||
|
if(relativeElementId == "parent" && getParent()) {
|
||||||
|
relativeElement = getParent()->asAnchorLayout();
|
||||||
|
} else {
|
||||||
|
UIElementPtr element = g_ui->recursiveGetChildById(relativeElementId);
|
||||||
|
if(element)
|
||||||
|
relativeElement = element->asAnchorLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(relativeElement) {
|
||||||
|
addAnchor(type, AnchorLine(relativeElement, relativeAnchorType));
|
||||||
|
} else {
|
||||||
|
logError("anchoring has failed: %s", anchorDescription.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool UIElement::setSkin(const std::string& skinName)
|
bool UIElement::setSkin(const std::string& skinName)
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,6 +50,9 @@ public:
|
||||||
virtual void render();
|
virtual void render();
|
||||||
virtual bool onInputEvent(const InputEvent& event) { return false; }
|
virtual bool onInputEvent(const InputEvent& event) { return false; }
|
||||||
|
|
||||||
|
virtual void load(const YAML::Node& node);
|
||||||
|
void loadAnchor(EAnchorType type, const YAML::Node& node);
|
||||||
|
|
||||||
bool setSkin(const std::string& skinName);
|
bool setSkin(const std::string& skinName);
|
||||||
void setSkin(UIElementSkin *skin);
|
void setSkin(UIElementSkin *skin);
|
||||||
UIElementSkin *getSkin() { return m_skin; }
|
UIElementSkin *getSkin() { return m_skin; }
|
||||||
|
@ -69,6 +72,7 @@ public:
|
||||||
UI::EElementType getElementType() const { return m_type; }
|
UI::EElementType getElementType() const { return m_type; }
|
||||||
|
|
||||||
UIElementPtr asUIElement() { return std::static_pointer_cast<UIElement>(shared_from_this()); }
|
UIElementPtr asUIElement() { return std::static_pointer_cast<UIElement>(shared_from_this()); }
|
||||||
|
virtual UIContainerPtr asUIContainer() { return UIContainerPtr(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UI::EElementType m_type;
|
UI::EElementType m_type;
|
||||||
|
|
|
@ -35,6 +35,15 @@ UILabel::UILabel(const std::string& text, Font* font) :
|
||||||
setSize(m_font->calculateTextRectSize(text));
|
setSize(m_font->calculateTextRectSize(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UILabel::load(const YAML::Node& node)
|
||||||
|
{
|
||||||
|
UIElement::load(node);
|
||||||
|
|
||||||
|
std::string text;
|
||||||
|
node["text"] >> text;
|
||||||
|
setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
void UILabel::render()
|
void UILabel::render()
|
||||||
{
|
{
|
||||||
m_font->renderText(m_text, getRect(), ALIGN_LEFT, Color(0xFFBFBFBF));
|
m_font->renderText(m_text, getRect(), ALIGN_LEFT, Color(0xFFBFBFBF));
|
||||||
|
|
|
@ -33,7 +33,9 @@ class Font;
|
||||||
class UILabel : public UIElement
|
class UILabel : public UIElement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UILabel(const std::string& text, Font *font = NULL);
|
UILabel(const std::string& text = std::string(), Font *font = NULL);
|
||||||
|
|
||||||
|
void load(const YAML::Node& node);
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
|
|
|
@ -24,3 +24,8 @@
|
||||||
|
|
||||||
#include "uiwindow.h"
|
#include "uiwindow.h"
|
||||||
|
|
||||||
|
void UIWindow::load(const YAML::Node& node)
|
||||||
|
{
|
||||||
|
UIContainer::load(node);
|
||||||
|
node["title"] >> m_title;
|
||||||
|
}
|
||||||
|
|
|
@ -31,10 +31,12 @@
|
||||||
class UIWindow : public UIContainer
|
class UIWindow : public UIContainer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UIWindow(const std::string& title) :
|
UIWindow(const std::string& title = std::string()) :
|
||||||
UIContainer(UI::Window),
|
UIContainer(UI::Window),
|
||||||
m_title(title) { }
|
m_title(title) { }
|
||||||
|
|
||||||
|
void load(const YAML::Node& node);
|
||||||
|
|
||||||
const std::string& getTitle() const { return m_title; }
|
const std::string& getTitle() const { return m_title; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -42,7 +42,15 @@ void MenuState::onEnter()
|
||||||
m_background = g_textures.get("background.png");
|
m_background = g_textures.get("background.png");
|
||||||
m_background->enableBilinearFilter();
|
m_background->enableBilinearFilter();
|
||||||
|
|
||||||
createMainMenu();
|
UIContainerPtr mainMenuPanel = UIContainer::load("ui/mainMenu-panel.yml");
|
||||||
|
|
||||||
|
UIButtonPtr button = std::static_pointer_cast<UIButton>(mainMenuPanel->getChildById("exitGame-button"));
|
||||||
|
button->onClick([]{ g_engine.stop(); });
|
||||||
|
|
||||||
|
button = std::static_pointer_cast<UIButton>(mainMenuPanel->getChildById("enterGame-button"));
|
||||||
|
button->onClick([]{
|
||||||
|
UIContainer::load("ui/enterGame-window.yml");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuState::onLeave()
|
void MenuState::onLeave()
|
||||||
|
@ -82,6 +90,7 @@ void MenuState::render()
|
||||||
|
|
||||||
void MenuState::createMainMenu()
|
void MenuState::createMainMenu()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
|
||||||
m_menuPanel = UIPanelPtr(new UIPanel);
|
m_menuPanel = UIPanelPtr(new UIPanel);
|
||||||
|
@ -199,4 +208,5 @@ void MenuState::createMainMenu()
|
||||||
if(window)
|
if(window)
|
||||||
window->setVisible(true);
|
window->setVisible(true);
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue