ui loader and some refactoring
This commit is contained in:
parent
1f78f93096
commit
992e0a8a6b
|
@ -68,6 +68,7 @@ SET(SOURCES
|
||||||
src/framework/core/engine.cpp
|
src/framework/core/engine.cpp
|
||||||
|
|
||||||
# framework utilities
|
# framework utilities
|
||||||
|
src/framework/util/color.cpp
|
||||||
src/framework/util/util.cpp
|
src/framework/util/util.cpp
|
||||||
src/framework/util/logger.cpp
|
src/framework/util/logger.cpp
|
||||||
src/framework/util/rsa.cpp
|
src/framework/util/rsa.cpp
|
||||||
|
@ -84,12 +85,13 @@ SET(SOURCES
|
||||||
src/framework/graphics/graphics.cpp
|
src/framework/graphics/graphics.cpp
|
||||||
|
|
||||||
# framework ui
|
# framework ui
|
||||||
src/framework/ui/anchorlayout.cpp
|
src/framework/ui/uilayout.cpp
|
||||||
src/framework/ui/uielement.cpp
|
src/framework/ui/uielement.cpp
|
||||||
src/framework/ui/uielementskin.cpp
|
src/framework/ui/uielementskin.cpp
|
||||||
src/framework/ui/uibuttonskin.cpp
|
src/framework/ui/uibuttonskin.cpp
|
||||||
src/framework/ui/uicontainer.cpp
|
src/framework/ui/uicontainer.cpp
|
||||||
src/framework/ui/uiskins.cpp
|
src/framework/ui/uiskins.cpp
|
||||||
|
src/framework/ui/uiloader.cpp
|
||||||
src/framework/ui/uipanel.cpp
|
src/framework/ui/uipanel.cpp
|
||||||
src/framework/ui/uibutton.cpp
|
src/framework/ui/uibutton.cpp
|
||||||
src/framework/ui/uilabel.cpp
|
src/framework/ui/uilabel.cpp
|
||||||
|
|
|
@ -35,7 +35,7 @@ bool Configs::load(const std::string& fileName)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string fileContents = g_resources.loadTextFile(fileName);
|
std::string fileContents = g_resources.loadTextFile(fileName);
|
||||||
if(fileContents.size() == 0)
|
if(fileContents.size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::istringstream fin(fileContents);
|
std::istringstream fin(fileContents);
|
||||||
|
@ -52,8 +52,8 @@ bool Configs::load(const std::string& fileName)
|
||||||
it.second() >> value;
|
it.second() >> value;
|
||||||
m_confsMap[key] = value;
|
m_confsMap[key] = value;
|
||||||
}
|
}
|
||||||
} catch (YAML::ParserException& e) {
|
} catch (YAML::Exception& e) {
|
||||||
logError("Malformed configuration file!");
|
logError("Malformed config file: %s", e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ void Engine::init()
|
||||||
{
|
{
|
||||||
// initialize stuff
|
// initialize stuff
|
||||||
g_graphics.init();
|
g_graphics.init();
|
||||||
g_fonts.init();
|
g_fonts.init("tibia-12px-rounded");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::terminate()
|
void Engine::terminate()
|
||||||
|
@ -52,6 +52,7 @@ void Engine::terminate()
|
||||||
|
|
||||||
void Engine::run()
|
void Engine::run()
|
||||||
{
|
{
|
||||||
|
Font *defaultFont = g_fonts.getDefaultFont();
|
||||||
int ticks = Platform::getTicks();
|
int ticks = Platform::getTicks();
|
||||||
int lastFpsTicks = ticks;
|
int lastFpsTicks = ticks;
|
||||||
int frameCount = 0;
|
int frameCount = 0;
|
||||||
|
@ -87,8 +88,8 @@ void Engine::run()
|
||||||
// render fps
|
// render fps
|
||||||
if(m_calculateFps) {
|
if(m_calculateFps) {
|
||||||
std::string fpsText = format("FPS: %d", fps);
|
std::string fpsText = format("FPS: %d", fps);
|
||||||
Size textSize = g_defaultFont->calculateTextRectSize(fpsText);
|
Size textSize = defaultFont->calculateTextRectSize(fpsText);
|
||||||
g_defaultFont->renderText(fpsText, Point(g_graphics.getScreenSize().width() - textSize.width() - 10, 10));
|
defaultFont->renderText(fpsText, Point(g_graphics.getScreenSize().width() - textSize.width() - 10, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
// swap buffers
|
// swap buffers
|
||||||
|
@ -119,7 +120,7 @@ void Engine::render()
|
||||||
g_graphics.beginRender();
|
g_graphics.beginRender();
|
||||||
if(m_currentState)
|
if(m_currentState)
|
||||||
m_currentState->render();
|
m_currentState->render();
|
||||||
g_ui->render();
|
UIContainer::getRootContainer()->render();
|
||||||
g_graphics.endRender();
|
g_graphics.endRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +133,7 @@ void Engine::onClose()
|
||||||
void Engine::onResize(const Size& size)
|
void Engine::onResize(const Size& size)
|
||||||
{
|
{
|
||||||
g_graphics.resize(size);
|
g_graphics.resize(size);
|
||||||
g_ui->setSize(size);
|
UIContainer::getRootContainer()->setSize(size);
|
||||||
|
|
||||||
if(m_currentState)
|
if(m_currentState)
|
||||||
m_currentState->onResize(size);
|
m_currentState->onResize(size);
|
||||||
|
@ -141,7 +142,7 @@ void Engine::onResize(const Size& size)
|
||||||
void Engine::onInputEvent(const InputEvent& event)
|
void Engine::onInputEvent(const InputEvent& event)
|
||||||
{
|
{
|
||||||
// inputs goest to gui first
|
// inputs goest to gui first
|
||||||
if(!g_ui->onInputEvent(event)) {
|
if(!UIContainer::getRootContainer()->onInputEvent(event)) {
|
||||||
// if gui didnt capture the input then goes to the state
|
// if gui didnt capture the input then goes to the state
|
||||||
if(m_currentState)
|
if(m_currentState)
|
||||||
m_currentState->onInputEvent(event);
|
m_currentState->onInputEvent(event);
|
||||||
|
|
|
@ -43,7 +43,7 @@ bool Resources::setWriteDir(const std::string& path)
|
||||||
bool ret = (bool)PHYSFS_setWriteDir(path.c_str());
|
bool ret = (bool)PHYSFS_setWriteDir(path.c_str());
|
||||||
|
|
||||||
if(!ret)
|
if(!ret)
|
||||||
logError("Could not set the path \"%s\" as write directory, file write will not work.", path.c_str());
|
logError("Could not set the path \"%s\" as write directory, file write will not work correctly.", path.c_str());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,70 +84,64 @@ void BorderedImage::draw(const Rect& screenCoords)
|
||||||
if(screenCoords.size() <= m_cornersSize)
|
if(screenCoords.size() <= m_cornersSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Size& textureSize = m_texture->getSize();
|
|
||||||
Rect rectCoords;
|
Rect rectCoords;
|
||||||
Size centerSize = screenCoords.size() - m_cornersSize;
|
Size centerSize = screenCoords.size() - m_cornersSize;
|
||||||
|
|
||||||
g_graphics._beginTextureRender(m_texture.get());
|
|
||||||
|
|
||||||
// first the center
|
// first the center
|
||||||
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width(),
|
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width(),
|
||||||
screenCoords.top() + m_topBorderTexCoords.height(),
|
screenCoords.top() + m_topBorderTexCoords.height(),
|
||||||
centerSize);
|
centerSize);
|
||||||
g_graphics._drawRepeatedTexturedRect(rectCoords, m_centerTexCoords, textureSize);
|
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_centerTexCoords);
|
||||||
|
|
||||||
// top left corner
|
// top left corner
|
||||||
rectCoords = Rect(screenCoords.topLeft(),
|
rectCoords = Rect(screenCoords.topLeft(),
|
||||||
m_topLeftCornerTexCoords.size());
|
m_topLeftCornerTexCoords.size());
|
||||||
g_graphics._drawTexturedRect(rectCoords, m_topLeftCornerTexCoords, textureSize);
|
g_graphics.drawTexturedRect(rectCoords, m_texture, m_topLeftCornerTexCoords);
|
||||||
|
|
||||||
// top
|
// top
|
||||||
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width(),
|
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width(),
|
||||||
screenCoords.topLeft().y,
|
screenCoords.topLeft().y,
|
||||||
centerSize.width(),
|
centerSize.width(),
|
||||||
m_topBorderTexCoords.height());
|
m_topBorderTexCoords.height());
|
||||||
g_graphics._drawRepeatedTexturedRect(rectCoords, m_topBorderTexCoords, textureSize);
|
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_topBorderTexCoords);
|
||||||
|
|
||||||
|
|
||||||
// top right corner
|
// top right corner
|
||||||
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width() + centerSize.width(),
|
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width() + centerSize.width(),
|
||||||
screenCoords.top(),
|
screenCoords.top(),
|
||||||
m_topRightCornerTexCoords.size());
|
m_topRightCornerTexCoords.size());
|
||||||
g_graphics._drawTexturedRect(rectCoords, m_topRightCornerTexCoords, textureSize);
|
g_graphics.drawTexturedRect(rectCoords, m_texture, m_topRightCornerTexCoords);
|
||||||
|
|
||||||
// left
|
// left
|
||||||
rectCoords = Rect(screenCoords.left(),
|
rectCoords = Rect(screenCoords.left(),
|
||||||
screenCoords.top() + m_topLeftCornerTexCoords.height(),
|
screenCoords.top() + m_topLeftCornerTexCoords.height(),
|
||||||
m_leftBorderTexCoords.width(),
|
m_leftBorderTexCoords.width(),
|
||||||
centerSize.height());
|
centerSize.height());
|
||||||
g_graphics._drawRepeatedTexturedRect(rectCoords, m_leftBorderTexCoords, textureSize);
|
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_leftBorderTexCoords);
|
||||||
|
|
||||||
// right
|
// right
|
||||||
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width() + centerSize.width(),
|
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width() + centerSize.width(),
|
||||||
screenCoords.top() + m_topRightCornerTexCoords.height(),
|
screenCoords.top() + m_topRightCornerTexCoords.height(),
|
||||||
m_rightBorderTexCoords.width(),
|
m_rightBorderTexCoords.width(),
|
||||||
centerSize.height());
|
centerSize.height());
|
||||||
g_graphics._drawRepeatedTexturedRect(rectCoords, m_rightBorderTexCoords, textureSize);
|
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_rightBorderTexCoords);
|
||||||
|
|
||||||
// bottom left corner
|
// bottom left corner
|
||||||
rectCoords = Rect(screenCoords.left(),
|
rectCoords = Rect(screenCoords.left(),
|
||||||
screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(),
|
screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(),
|
||||||
m_bottomLeftCornerTexCoords.size());
|
m_bottomLeftCornerTexCoords.size());
|
||||||
g_graphics._drawTexturedRect(rectCoords, m_bottomLeftCornerTexCoords, textureSize);
|
g_graphics.drawTexturedRect(rectCoords, m_texture, m_bottomLeftCornerTexCoords);
|
||||||
|
|
||||||
// bottom
|
// bottom
|
||||||
rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width(),
|
rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width(),
|
||||||
screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(),
|
screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(),
|
||||||
centerSize.width(),
|
centerSize.width(),
|
||||||
m_bottomBorderTexCoords.height());
|
m_bottomBorderTexCoords.height());
|
||||||
g_graphics._drawRepeatedTexturedRect(rectCoords, m_bottomBorderTexCoords, textureSize);
|
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_bottomBorderTexCoords);
|
||||||
|
|
||||||
// bottom right corner
|
// bottom right corner
|
||||||
rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width() + centerSize.width(),
|
rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width() + centerSize.width(),
|
||||||
screenCoords.top() + m_topRightCornerTexCoords.height() + centerSize.height(),
|
screenCoords.top() + m_topRightCornerTexCoords.height() + centerSize.height(),
|
||||||
m_bottomRightCornerTexCoords.size());
|
m_bottomRightCornerTexCoords.size());
|
||||||
g_graphics._drawTexturedRect(rectCoords, m_bottomRightCornerTexCoords, textureSize);
|
g_graphics.drawTexturedRect(rectCoords, m_texture, m_bottomRightCornerTexCoords);
|
||||||
|
|
||||||
//g_graphics._drawBoundingRect(screenCoords, Color(0xFF00FF00), 1);
|
|
||||||
g_graphics._endTextureRender();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,11 +27,7 @@
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
|
|
||||||
Font::Font() :
|
|
||||||
m_glyphHeight(10),
|
|
||||||
m_topMargin(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
|
void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
|
||||||
{
|
{
|
||||||
|
@ -73,12 +69,11 @@ bool Font::load(const std::string& file)
|
||||||
{
|
{
|
||||||
std::string fileContents = g_resources.loadTextFile(file);
|
std::string fileContents = g_resources.loadTextFile(file);
|
||||||
if(!fileContents.size()) {
|
if(!fileContents.size()) {
|
||||||
logError("Empty font file \"%s", file.c_str());
|
logError("Coult not load font file \"%s", file.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istringstream fin(fileContents);
|
std::istringstream fin(fileContents);
|
||||||
|
|
||||||
std::string textureName;
|
std::string textureName;
|
||||||
Size glyphSize;
|
Size glyphSize;
|
||||||
|
|
||||||
|
@ -88,22 +83,25 @@ bool Font::load(const std::string& file)
|
||||||
YAML::Node doc;
|
YAML::Node doc;
|
||||||
parser.GetNextDocument(doc);
|
parser.GetNextDocument(doc);
|
||||||
|
|
||||||
|
// required values
|
||||||
doc["glyph height"] >> m_glyphHeight;
|
doc["glyph height"] >> m_glyphHeight;
|
||||||
doc["glyph spacing"] >> m_glyphSpacing;
|
|
||||||
doc["top margin"] >> m_topMargin;
|
|
||||||
doc["image glyph size"] >> glyphSize;
|
doc["image glyph size"] >> glyphSize;
|
||||||
doc["image"] >> textureName;
|
doc["image"] >> textureName;
|
||||||
|
|
||||||
|
// optional values
|
||||||
|
if(doc.FindValue("glyph spacing"))
|
||||||
|
doc["glyph spacing"] >> m_glyphSpacing;
|
||||||
|
if(doc.FindValue("top margin"))
|
||||||
|
doc["top margin"] >> m_topMargin;
|
||||||
|
|
||||||
|
// load texture
|
||||||
m_texture = g_textures.get("fonts/" + textureName);
|
m_texture = g_textures.get("fonts/" + textureName);
|
||||||
if(!m_texture) {
|
if(!m_texture) {
|
||||||
logError("Failed to load image for font \"%s\"", file.c_str());
|
logError("Failed to load image for font file \"%s\"", file.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set glyphs height
|
// auto calculate widths
|
||||||
for(int glyph = 32; glyph < 256; ++glyph) {
|
|
||||||
}
|
|
||||||
|
|
||||||
calculateGlyphsWidthsAutomatically(glyphSize);
|
calculateGlyphsWidthsAutomatically(glyphSize);
|
||||||
|
|
||||||
// read custom widths
|
// read custom widths
|
||||||
|
@ -125,9 +123,8 @@ bool Font::load(const std::string& file)
|
||||||
m_glyphsSize[glyph].width(),
|
m_glyphsSize[glyph].width(),
|
||||||
m_glyphHeight);
|
m_glyphHeight);
|
||||||
}
|
}
|
||||||
|
} catch (YAML::Exception& e) {
|
||||||
} catch (YAML::ParserException& e) {
|
logError("Malformed font file \"%s\":\n %s", file.c_str(), e.what());
|
||||||
logError("Malformed font file \"%s\"", file.c_str());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,18 +143,12 @@ void Font::renderText(const std::string& text,
|
||||||
const Rect& screenCoords,
|
const Rect& screenCoords,
|
||||||
int align,
|
int align,
|
||||||
const Color& color,
|
const Color& color,
|
||||||
const Point& startInternalPos,
|
const Point& startInternalPos)
|
||||||
bool debug)
|
|
||||||
{
|
{
|
||||||
// prevent glitches from invalid rects
|
// prevent glitches from invalid rects
|
||||||
if(!screenCoords.isValid())
|
if(!screenCoords.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// begin texture rendering
|
|
||||||
g_graphics.setColor(color);
|
|
||||||
g_graphics._beginTextureRender(m_texture.get());
|
|
||||||
|
|
||||||
const Size& textureSize = m_texture->getSize();
|
|
||||||
int textLenght = text.length();
|
int textLenght = text.length();
|
||||||
|
|
||||||
// map glyphs positions
|
// map glyphs positions
|
||||||
|
@ -227,17 +218,8 @@ void Font::renderText(const std::string& text,
|
||||||
}
|
}
|
||||||
|
|
||||||
// render glyph
|
// render glyph
|
||||||
g_graphics._drawTexturedRect(glyphScreenCoords, glyphTextureCoords, textureSize);
|
g_graphics.drawTexturedRect(glyphScreenCoords, m_texture, glyphTextureCoords, color);
|
||||||
|
|
||||||
//g_graphics._drawBoundingRect(glyphScreenCoords, Color(0xFF0000FF));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// end texture redering
|
|
||||||
g_graphics._endTextureRender();
|
|
||||||
g_graphics.resetColor();
|
|
||||||
|
|
||||||
if(debug)
|
|
||||||
g_graphics.drawBoundingRect(screenCoords.expanded(1), Color(0xFF00FF00));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Point* Font::calculateGlyphsPositions(const std::string& text, int align, Size *textBoxSize)
|
Point* Font::calculateGlyphsPositions(const std::string& text, int align, Size *textBoxSize)
|
||||||
|
|
|
@ -45,8 +45,10 @@ enum EAlign {
|
||||||
class Font
|
class Font
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Font();
|
Font(const std::string& name) :
|
||||||
virtual ~Font() { }
|
m_name(name),
|
||||||
|
m_glyphHeight(10),
|
||||||
|
m_topMargin(0) { }
|
||||||
|
|
||||||
/// Load font from file
|
/// Load font from file
|
||||||
bool load(const std::string &file);
|
bool load(const std::string &file);
|
||||||
|
@ -62,9 +64,8 @@ public:
|
||||||
void renderText(const std::string& text,
|
void renderText(const std::string& text,
|
||||||
const Rect& screenCoords,
|
const Rect& screenCoords,
|
||||||
int align = ALIGN_TOP_LEFT,
|
int align = ALIGN_TOP_LEFT,
|
||||||
const Color& color = Color(0xFFFFFFFF),
|
const Color& color = Color::white,
|
||||||
const Point& startInternalPos = Point(),
|
const Point& startInternalPos = Point());
|
||||||
bool debug = false);
|
|
||||||
|
|
||||||
/// Calculate glyphs positions to use on render, also calculates textBoxSize if wanted
|
/// Calculate glyphs positions to use on render, also calculates textBoxSize if wanted
|
||||||
Point *calculateGlyphsPositions(const std::string& text, int align = ALIGN_TOP_LEFT, Size *textBoxSize = NULL);
|
Point *calculateGlyphsPositions(const std::string& text, int align = ALIGN_TOP_LEFT, Size *textBoxSize = NULL);
|
||||||
|
@ -72,9 +73,12 @@ public:
|
||||||
/// Simulate render and calculate text size
|
/// Simulate render and calculate text size
|
||||||
Size calculateTextRectSize(const std::string& text);
|
Size calculateTextRectSize(const std::string& text);
|
||||||
|
|
||||||
|
const std::string& getName() const { return m_name; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void calculateGlyphsWidthsAutomatically(const Size& glyphSize);
|
void calculateGlyphsWidthsAutomatically(const Size& glyphSize);
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
int m_glyphHeight;
|
int m_glyphHeight;
|
||||||
int m_topMargin;
|
int m_topMargin;
|
||||||
Size m_glyphSpacing;
|
Size m_glyphSpacing;
|
||||||
|
@ -83,4 +87,6 @@ private:
|
||||||
Size m_glyphsSize[256];
|
Size m_glyphsSize[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<Font> FontPtr;
|
||||||
|
|
||||||
#endif // FONT_H
|
#endif // FONT_H
|
||||||
|
|
|
@ -23,13 +23,11 @@
|
||||||
|
|
||||||
|
|
||||||
#include "fonts.h"
|
#include "fonts.h"
|
||||||
#include "font.h"
|
|
||||||
#include "core/resources.h"
|
#include "core/resources.h"
|
||||||
|
|
||||||
Fonts g_fonts;
|
Fonts g_fonts;
|
||||||
Font *g_defaultFont = NULL;
|
|
||||||
|
|
||||||
void Fonts::init()
|
void Fonts::init(const std::string& defaultFontName)
|
||||||
{
|
{
|
||||||
// load all fonts
|
// load all fonts
|
||||||
std::list<std::string> files = g_resources.getDirectoryFiles("fonts");
|
std::list<std::string> files = g_resources.getDirectoryFiles("fonts");
|
||||||
|
@ -37,27 +35,28 @@ void Fonts::init()
|
||||||
if(boost::ends_with(file, ".yml")) {
|
if(boost::ends_with(file, ".yml")) {
|
||||||
std::string name = file;
|
std::string name = file;
|
||||||
boost::erase_first(name, ".yml");
|
boost::erase_first(name, ".yml");
|
||||||
std::shared_ptr<Font> font(new Font);
|
FontPtr font(new Font(name));
|
||||||
font->load("fonts/" + file);
|
if(font->load("fonts/" + file)) {
|
||||||
m_fonts[name] = font;
|
m_fonts.push_back(font);
|
||||||
|
|
||||||
|
if(name == defaultFontName)
|
||||||
|
m_defaultFont = font;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set default font
|
if(!m_defaultFont)
|
||||||
g_defaultFont = get("tibia-12px-rounded");
|
logFatal("Could not load the default font \"%s\"\n", defaultFontName.c_str());
|
||||||
if(!g_defaultFont)
|
|
||||||
logFatal("Default font not found!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Font* Fonts::get(const std::string& fontName)
|
Font* Fonts::get(const std::string& fontName)
|
||||||
{
|
{
|
||||||
// find font by name
|
// find font by name
|
||||||
auto it = m_fonts.find(fontName);
|
for(auto it = m_fonts.begin(); it != m_fonts.end(); ++it) {
|
||||||
if(it != m_fonts.end()) {
|
if((*it)->getName() == fontName)
|
||||||
return it->second.get();
|
return (*it).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
logError("Font \"%s\" not found", fontName.c_str());
|
logError("Font \"%s\" not found, returing the default one", fontName.c_str());
|
||||||
return NULL;
|
return m_defaultFont.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,19 +34,22 @@ public:
|
||||||
Fonts() { }
|
Fonts() { }
|
||||||
|
|
||||||
/// Initialize all fonts
|
/// Initialize all fonts
|
||||||
void init();
|
void init(const std::string& defaultFontName);
|
||||||
|
|
||||||
/// Get a font by name
|
|
||||||
Font *get(const std::string& fontName);
|
|
||||||
|
|
||||||
/// Terminate all fonts
|
/// Terminate all fonts
|
||||||
void terminate() { }
|
void terminate() { }
|
||||||
|
|
||||||
|
/// Get a font by name
|
||||||
|
Font *get(const std::string& fontName);
|
||||||
|
|
||||||
|
/// Get the default font
|
||||||
|
Font *getDefaultFont() { return m_defaultFont.get(); };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, std::shared_ptr<Font> > m_fonts;
|
std::vector<FontPtr> m_fonts;
|
||||||
|
FontPtr m_defaultFont;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Fonts g_fonts;
|
extern Fonts g_fonts;
|
||||||
extern Font *g_defaultFont;
|
|
||||||
|
|
||||||
#endif // FONTS_H
|
#endif // FONTS_H
|
||||||
|
|
|
@ -123,49 +123,19 @@ void Graphics::endRender()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::drawTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color)
|
||||||
void Graphics::setColor(const Color& color)
|
|
||||||
{
|
{
|
||||||
|
if(screenCoords.size().isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
glColor4ubv(color.rgbaPtr());
|
glColor4ubv(color.rgbaPtr());
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::resetColor()
|
|
||||||
{
|
|
||||||
glColor4ub(0xFF, 0xFF, 0xFF, 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::_beginTextureRender(const Texture *texture)
|
|
||||||
{
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::_endTextureRender()
|
|
||||||
{
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::drawTexturedRect(const Rect& screenCoords, const Texture *texture, const Rect& textureCoords)
|
|
||||||
{
|
|
||||||
if(screenCoords.size().isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
_drawTexturedRect(screenCoords, textureCoords, texture->getSize());
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::_drawTexturedRect(const Rect& screenCoords, const Rect& textureCoords, const Size& textureSize)
|
|
||||||
{
|
|
||||||
if(screenCoords.size().isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// rect correction for opengl
|
// rect correction for opengl
|
||||||
int right = screenCoords.right() + 1;
|
int right = screenCoords.right() + 1;
|
||||||
int bottom = screenCoords.bottom() + 1;
|
int bottom = screenCoords.bottom() + 1;
|
||||||
int top = screenCoords.top();
|
int top = screenCoords.top();
|
||||||
int left = screenCoords.left();
|
int left = screenCoords.left();
|
||||||
|
const Size& textureSize = texture->getSize();
|
||||||
|
|
||||||
float textureRight = 0.0f;
|
float textureRight = 0.0f;
|
||||||
float textureBottom = 1.0f;
|
float textureBottom = 1.0f;
|
||||||
|
@ -179,24 +149,18 @@ void Graphics::_drawTexturedRect(const Rect& screenCoords, const Rect& textureCo
|
||||||
textureLeft = (float)textureCoords.left() / textureSize.width();
|
textureLeft = (float)textureCoords.left() / textureSize.width();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
|
||||||
glTexCoord2f(textureLeft, textureTop); glVertex2i(left, top);
|
glTexCoord2f(textureLeft, textureTop); glVertex2i(left, top);
|
||||||
glTexCoord2f(textureLeft, textureBottom); glVertex2i(left, bottom);
|
glTexCoord2f(textureLeft, textureBottom); glVertex2i(left, bottom);
|
||||||
glTexCoord2f(textureRight, textureBottom); glVertex2i(right, bottom);
|
glTexCoord2f(textureRight, textureBottom); glVertex2i(right, bottom);
|
||||||
glTexCoord2f(textureRight, textureTop); glVertex2i(right, top);
|
glTexCoord2f(textureRight, textureTop); glVertex2i(right, top);
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::drawRepeatedTexturedRect(const Rect& screenCoords, const Texture* texture, const Rect& texCoords)
|
|
||||||
{
|
|
||||||
if(screenCoords.size().isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
_drawRepeatedTexturedRect(screenCoords, texCoords, texture->getSize());
|
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::_drawRepeatedTexturedRect(const Rect& screenCoords, const Rect& textureCoords, const Size& textureSize)
|
void Graphics::drawRepeatedTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color)
|
||||||
{
|
{
|
||||||
if(screenCoords.size().isEmpty())
|
if(screenCoords.size().isEmpty())
|
||||||
return;
|
return;
|
||||||
|
@ -219,20 +183,19 @@ void Graphics::_drawRepeatedTexturedRect(const Rect& screenCoords, const Rect& t
|
||||||
}
|
}
|
||||||
|
|
||||||
partialCoords.translate(screenCoords.topLeft());
|
partialCoords.translate(screenCoords.topLeft());
|
||||||
_drawTexturedRect(partialCoords, partialTextureCoords, textureSize);
|
drawTexturedRect(partialCoords, texture, partialTextureCoords, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::drawFilledRect(const Rect& screenCoords, const Color& color)
|
||||||
void Graphics::drawColoredRect(const Rect& screenCoords, const Color& color)
|
|
||||||
{
|
{
|
||||||
if(screenCoords.size().isEmpty())
|
if(screenCoords.size().isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
setColor(color);
|
glColor4ubv(color.rgbaPtr());
|
||||||
|
|
||||||
// rect correction for opengl
|
// rect correction for opengl
|
||||||
int right = screenCoords.right() + 1;
|
int right = screenCoords.right() + 1;
|
||||||
|
@ -248,8 +211,6 @@ void Graphics::drawColoredRect(const Rect& screenCoords, const Color& color)
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
resetColor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -260,7 +221,7 @@ void Graphics::drawBoundingRect(const Rect& screenCoords, const Color& color, in
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
setColor(color);
|
glColor4ubv(color.rgbaPtr());
|
||||||
|
|
||||||
// rect correction for opengl
|
// rect correction for opengl
|
||||||
int right = screenCoords.right()+1;
|
int right = screenCoords.right()+1;
|
||||||
|
@ -295,13 +256,4 @@ void Graphics::drawBoundingRect(const Rect& screenCoords, const Color& color, in
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
resetColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::_drawBoundingRect(const Rect& screenCoords, const Color& color, int innerLineWidth)
|
|
||||||
{
|
|
||||||
glEnd();
|
|
||||||
drawBoundingRect(screenCoords, color, innerLineWidth);
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,15 +26,17 @@
|
||||||
#define GRAPHICS_H
|
#define GRAPHICS_H
|
||||||
|
|
||||||
#include "prerequisites.h"
|
#include "prerequisites.h"
|
||||||
|
#include "texture.h"
|
||||||
class Texture;
|
|
||||||
|
|
||||||
class Graphics
|
class Graphics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Graphics() { }
|
Graphics() { }
|
||||||
|
|
||||||
|
/// Initialize graphics
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
/// Termiante graphics
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
/// Check if a GL extension is supported
|
/// Check if a GL extension is supported
|
||||||
|
@ -54,21 +56,10 @@ public:
|
||||||
|
|
||||||
const Size& getScreenSize() const { return m_screenSize; }
|
const Size& getScreenSize() const { return m_screenSize; }
|
||||||
|
|
||||||
void setColor(const Color& color);
|
void drawTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords = Rect(), const Color& color = Color::white);
|
||||||
void resetColor();
|
void drawRepeatedTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color = Color::white);
|
||||||
|
void drawFilledRect(const Rect& screenCoords, const Color& color);
|
||||||
// high level rendering
|
void drawBoundingRect(const Rect& screenCoords, const Color& color = Color::green, int innerLineWidth = 1);
|
||||||
void drawTexturedRect(const Rect& screenCoords, const Texture *texture, const Rect& texCoords = Rect());
|
|
||||||
void drawRepeatedTexturedRect(const Rect& screenCoords, const Texture *texture, const Rect& texCoords);
|
|
||||||
void drawColoredRect(const Rect& screenCoords, const Color& color);
|
|
||||||
void drawBoundingRect(const Rect& screenCoords, const Color& color, int innerLineWidth = 1);
|
|
||||||
|
|
||||||
// lower level rendering
|
|
||||||
void _beginTextureRender(const Texture *texture);
|
|
||||||
void _drawTexturedRect(const Rect& screenCoords, const Rect& textureCoords, const Size& textureSize);
|
|
||||||
void _drawRepeatedTexturedRect(const Rect& screenCoords, const Rect& textureCoords, const Size& textureSize);
|
|
||||||
void _drawBoundingRect(const Rect& screenCoords, const Color& color, int innerLineWidth = 1);
|
|
||||||
void _endTextureRender();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Size m_screenSize;
|
Size m_screenSize;
|
||||||
|
|
|
@ -37,14 +37,9 @@ Image::Image(const std::string& texture, Rect textureCoords) :
|
||||||
m_texture = g_textures.get(texture);
|
m_texture = g_textures.get(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::enableBilinearFilter()
|
|
||||||
{
|
|
||||||
m_texture->enableBilinearFilter();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::draw(const Rect& screenCoords)
|
void Image::draw(const Rect& screenCoords)
|
||||||
{
|
{
|
||||||
g_graphics.drawTexturedRect(screenCoords, m_texture.get(), m_textureCoords);
|
g_graphics.drawTexturedRect(screenCoords, m_texture, m_textureCoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
Image(const std::string& texture);
|
Image(const std::string& texture);
|
||||||
Image(const std::string& texture, Rect textureCoords);
|
Image(const std::string& texture, Rect textureCoords);
|
||||||
|
|
||||||
void enableBilinearFilter();
|
/// Draw image on screen
|
||||||
virtual void draw(const Rect& screenCoords);
|
virtual void draw(const Rect& screenCoords);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -29,9 +29,9 @@
|
||||||
|
|
||||||
Texture::Texture(int width, int height, int components, uchar *pixels)
|
Texture::Texture(int width, int height, int components, uchar *pixels)
|
||||||
{
|
{
|
||||||
m_size.setWidth(width);
|
m_size.setSize(width, height);
|
||||||
m_size.setHeight(height);
|
|
||||||
|
|
||||||
|
// generate opengl texture
|
||||||
glGenTextures(1, &m_textureId);
|
glGenTextures(1, &m_textureId);
|
||||||
glBindTexture(GL_TEXTURE_2D, m_textureId);
|
glBindTexture(GL_TEXTURE_2D, m_textureId);
|
||||||
|
|
||||||
|
@ -51,11 +51,14 @@ Texture::Texture(int width, int height, int components, uchar *pixels)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load the pixels into opengl memory
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, format, GL_UNSIGNED_BYTE, pixels);
|
glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, format, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
|
// disable texture border
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
// nearest filtering
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
}
|
}
|
||||||
|
@ -75,6 +78,7 @@ void Texture::enableBilinearFilter()
|
||||||
|
|
||||||
uchar *Texture::getPixels()
|
uchar *Texture::getPixels()
|
||||||
{
|
{
|
||||||
|
// copy pixels from opengl memory
|
||||||
uchar *pixels = new uchar[m_size.area()*4];
|
uchar *pixels = new uchar[m_size.area()*4];
|
||||||
glBindTexture(GL_TEXTURE_2D, m_textureId);
|
glBindTexture(GL_TEXTURE_2D, m_textureId);
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
|
@ -41,23 +41,22 @@ TexturePtr Textures::get(const std::string& textureFile)
|
||||||
texture = it->second.lock();
|
texture = it->second.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!texture) { // load texture
|
// texture not found, load it
|
||||||
|
if(!texture) {
|
||||||
// currently only png textures are supported
|
// currently only png textures are supported
|
||||||
if(!boost::ends_with(textureFile, ".png")) {
|
if(!boost::ends_with(textureFile, ".png"))
|
||||||
logFatal("Unable to load texture %s, file format no supported.", textureFile.c_str());
|
logFatal("Unable to load texture %s, file format no supported.", textureFile.c_str());
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// load texture file data
|
||||||
uint fileSize;
|
uint fileSize;
|
||||||
uchar *textureFileData = g_resources.loadFile(textureFile, &fileSize);
|
uchar *textureFileData = g_resources.loadFile(textureFile, &fileSize);
|
||||||
if(!textureFileData) {
|
if(!textureFileData)
|
||||||
logFatal("Unable to load texture %s, file could not be read.", textureFile.c_str());
|
logFatal("Unable to load texture %s, file could not be read.", textureFile.c_str());
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// load the texture
|
||||||
texture = TexturePtr(TextureLoader::loadPNG(textureFileData));
|
texture = TexturePtr(TextureLoader::loadPNG(textureFileData));
|
||||||
if(!texture)
|
if(!texture)
|
||||||
logFatal("Unable to load texture %s, loading error.", textureFile.c_str());
|
logFatal("Unable to load texture %s", textureFile.c_str());
|
||||||
delete[] textureFileData;
|
delete[] textureFileData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,5 +36,6 @@
|
||||||
#include "uiskins.h"
|
#include "uiskins.h"
|
||||||
#include "uiwindow.h"
|
#include "uiwindow.h"
|
||||||
#include "uitextedit.h"
|
#include "uitextedit.h"
|
||||||
|
#include "uiloader.h"
|
||||||
|
|
||||||
#endif // UI_H
|
#endif // UI_H
|
||||||
|
|
|
@ -26,12 +26,6 @@
|
||||||
#include "graphics/fonts.h"
|
#include "graphics/fonts.h"
|
||||||
#include "graphics/font.h"
|
#include "graphics/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();
|
||||||
|
|
|
@ -40,11 +40,12 @@ public:
|
||||||
UIElement();
|
UIElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(const YAML::Node& node);
|
|
||||||
|
|
||||||
virtual void render();
|
virtual void render();
|
||||||
bool onInputEvent(const InputEvent& event);
|
bool onInputEvent(const InputEvent& event);
|
||||||
|
|
||||||
|
void setText(const std::string& text) { m_text = text; }
|
||||||
|
const std::string& getText() const { return m_text; }
|
||||||
|
|
||||||
UI::EButtonState getState() { return m_state; }
|
UI::EButtonState getState() { return m_state; }
|
||||||
|
|
||||||
void onClick(const Callback& callback) { m_buttonClickCallback = callback; }
|
void onClick(const Callback& callback) { m_buttonClickCallback = callback; }
|
||||||
|
|
|
@ -30,90 +30,11 @@
|
||||||
#include "uitextedit.h"
|
#include "uitextedit.h"
|
||||||
#include "uiwindow.h"
|
#include "uiwindow.h"
|
||||||
|
|
||||||
UIContainerPtr g_ui(new UIContainer);
|
UIContainerPtr rootContainer(new UIContainer);
|
||||||
|
|
||||||
UIElementPtr createElementFromDescription(std::string elementId)
|
UIContainerPtr& UIContainer::getRootContainer()
|
||||||
{
|
{
|
||||||
UIElementPtr element;
|
return rootContainer;
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -34,11 +34,6 @@ 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);
|
UIElementPtr getChildById(const std::string& id);
|
||||||
|
@ -56,11 +51,11 @@ public:
|
||||||
|
|
||||||
UIContainerPtr asUIContainer() { return std::static_pointer_cast<UIContainer>(shared_from_this()); }
|
UIContainerPtr asUIContainer() { return std::static_pointer_cast<UIContainer>(shared_from_this()); }
|
||||||
|
|
||||||
|
static UIContainerPtr& getRootContainer();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::list<UIElementPtr> m_children;
|
std::list<UIElementPtr> m_children;
|
||||||
UIElementPtr m_activeElement;
|
UIElementPtr m_activeElement;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern UIContainerPtr g_ui;
|
|
||||||
|
|
||||||
#endif // UICONTAINER_H
|
#endif // UICONTAINER_H
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "uielementskin.h"
|
#include "uielementskin.h"
|
||||||
|
|
||||||
UIElement::UIElement(UI::EElementType type) :
|
UIElement::UIElement(UI::EElementType type) :
|
||||||
AnchorLayout(),
|
UILayout(),
|
||||||
m_type(type),
|
m_type(type),
|
||||||
m_skin(NULL),
|
m_skin(NULL),
|
||||||
m_visible(true),
|
m_visible(true),
|
||||||
|
@ -38,107 +38,6 @@ 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)
|
||||||
{
|
{
|
||||||
setSkin(g_uiSkins.getElementSkin(m_type, skinName));
|
setSkin(g_uiSkins.getElementSkin(m_type, skinName));
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include "prerequisites.h"
|
#include "prerequisites.h"
|
||||||
#include "core/input.h"
|
#include "core/input.h"
|
||||||
#include "uiconstants.h"
|
#include "uiconstants.h"
|
||||||
#include "anchorlayout.h"
|
#include "uilayout.h"
|
||||||
|
|
||||||
class UIElementSkin;
|
class UIElementSkin;
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ class UIElement;
|
||||||
typedef std::shared_ptr<UIElement> UIElementPtr;
|
typedef std::shared_ptr<UIElement> UIElementPtr;
|
||||||
typedef std::weak_ptr<UIElement> UIElementWeakPtr;
|
typedef std::weak_ptr<UIElement> UIElementWeakPtr;
|
||||||
|
|
||||||
class UIElement : public AnchorLayout
|
class UIElement : public UILayout
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UIElement(UI::EElementType type = UI::Element);
|
UIElement(UI::EElementType type = UI::Element);
|
||||||
|
@ -49,9 +49,6 @@ 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; }
|
||||||
|
|
|
@ -35,15 +35,6 @@ 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));
|
||||||
|
|
|
@ -35,8 +35,6 @@ class UILabel : public UIElement
|
||||||
public:
|
public:
|
||||||
UILabel(const std::string& text = std::string(), Font *font = NULL);
|
UILabel(const std::string& text = std::string(), Font *font = NULL);
|
||||||
|
|
||||||
void load(const YAML::Node& node);
|
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
void setText(const std::string& text);
|
void setText(const std::string& text);
|
||||||
|
|
|
@ -22,12 +22,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "anchorlayout.h"
|
#include "uilayout.h"
|
||||||
#include "uielement.h"
|
#include "uielement.h"
|
||||||
|
|
||||||
int AnchorLine::getPos() const
|
int AnchorLine::getPos() const
|
||||||
{
|
{
|
||||||
AnchorLayoutPtr element = m_relativeElement.lock();
|
UILayoutPtr element = m_relativeElement.lock();
|
||||||
if(element) {
|
if(element) {
|
||||||
switch(m_anchorType) {
|
switch(m_anchorType) {
|
||||||
case ANCHOR_LEFT:
|
case ANCHOR_LEFT:
|
||||||
|
@ -50,30 +50,30 @@ int AnchorLine::getPos() const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnchorLayout::setSize(const Size& size)
|
void UILayout::setSize(const Size& size)
|
||||||
{
|
{
|
||||||
m_rect.setSize(size);
|
m_rect.setSize(size);
|
||||||
recalculateAnchors();
|
recalculateAnchors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnchorLayout::setRect(const Rect& rect)
|
void UILayout::setRect(const Rect& rect)
|
||||||
{
|
{
|
||||||
m_rect = rect;
|
m_rect = rect;
|
||||||
recalculateAnchors();
|
recalculateAnchors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnchorLayout::addAnchor(EAnchorType type, const AnchorLine& anchorLine)
|
void UILayout::addAnchor(EAnchorType type, const AnchorLine& anchorLine)
|
||||||
{
|
{
|
||||||
if(!anchorLine.isValid()) {
|
if(!anchorLine.isValid()) {
|
||||||
logError("anchoring for an element has failed, got an invalid anchor line");
|
logError("anchoring for an element has failed, got an invalid anchor line");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_anchors[type] = anchorLine;
|
m_anchors[type] = anchorLine;
|
||||||
anchorLine.getRelativeElement()->addAnchoredElement(asAnchorLayout());
|
anchorLine.getRelativeElement()->addAnchoredElement(asUILayout());
|
||||||
recalculateAnchors();
|
recalculateAnchors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnchorLayout::addAnchoredElement(AnchorLayoutPtr anchoredElement)
|
void UILayout::addAnchoredElement(UILayoutPtr anchoredElement)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for(auto it = m_anchoredElements.begin(); it != m_anchoredElements.end(); ++it) {
|
for(auto it = m_anchoredElements.begin(); it != m_anchoredElements.end(); ++it) {
|
||||||
|
@ -86,7 +86,7 @@ void AnchorLayout::addAnchoredElement(AnchorLayoutPtr anchoredElement)
|
||||||
m_anchoredElements.push_back(anchoredElement);
|
m_anchoredElements.push_back(anchoredElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnchorLayout::recalculateAnchors()
|
void UILayout::recalculateAnchors()
|
||||||
{
|
{
|
||||||
// horizontal
|
// horizontal
|
||||||
if(m_anchors[ANCHOR_HORIZONTAL_CENTER].isValid()) {
|
if(m_anchors[ANCHOR_HORIZONTAL_CENTER].isValid()) {
|
||||||
|
@ -117,7 +117,7 @@ void AnchorLayout::recalculateAnchors()
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto it = m_anchoredElements.begin(); it != m_anchoredElements.end(); ++it) {
|
for(auto it = m_anchoredElements.begin(); it != m_anchoredElements.end(); ++it) {
|
||||||
AnchorLayoutPtr element = (*it).lock();
|
UILayoutPtr element = (*it).lock();
|
||||||
if(element)
|
if(element)
|
||||||
element->recalculateAnchors();
|
element->recalculateAnchors();
|
||||||
}
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
/* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UILAYOUT_H
|
||||||
|
#define UILAYOUT_H
|
||||||
|
|
||||||
|
#include "prerequisites.h"
|
||||||
|
#include "uiconstants.h"
|
||||||
|
|
||||||
|
enum EAnchorType {
|
||||||
|
ANCHOR_LEFT = 0,
|
||||||
|
ANCHOR_RIGHT,
|
||||||
|
ANCHOR_TOP,
|
||||||
|
ANCHOR_BOTTOM,
|
||||||
|
ANCHOR_HORIZONTAL_CENTER,
|
||||||
|
ANCHOR_VERTICAL_CENTER,
|
||||||
|
ANCHOR_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
class UILayout;
|
||||||
|
typedef std::shared_ptr<UILayout> UILayoutPtr;
|
||||||
|
typedef std::weak_ptr<UILayout> UILayoutWeakPtr;
|
||||||
|
|
||||||
|
class AnchorLine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AnchorLine() : m_anchorType(ANCHOR_NONE) { }
|
||||||
|
AnchorLine(const AnchorLine& other) :
|
||||||
|
m_relativeElement(other.m_relativeElement), m_anchorType(other.m_anchorType) { }
|
||||||
|
AnchorLine(UILayoutPtr relativeElement, EAnchorType anchorType) :
|
||||||
|
m_relativeElement(relativeElement), m_anchorType(anchorType) { }
|
||||||
|
bool isValid() const { return (m_anchorType != ANCHOR_NONE && !m_relativeElement.expired()); }
|
||||||
|
|
||||||
|
int getPos() const;
|
||||||
|
EAnchorType getAnchorType() const { return m_anchorType; }
|
||||||
|
UILayoutPtr getRelativeElement() const { return m_relativeElement.lock(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
UILayoutWeakPtr m_relativeElement;
|
||||||
|
EAnchorType m_anchorType;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UILayout : public std::enable_shared_from_this<UILayout>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UILayout() :
|
||||||
|
m_marginLeft(0),
|
||||||
|
m_marginRight(0),
|
||||||
|
m_marginTop(0),
|
||||||
|
m_marginBottom(0) { }
|
||||||
|
virtual ~UILayout() { }
|
||||||
|
|
||||||
|
void setSize(const Size& size);
|
||||||
|
Size getSize() { return m_rect.size(); }
|
||||||
|
|
||||||
|
void setRect(const Rect& rect);
|
||||||
|
const Rect& getRect() const{ return m_rect; }
|
||||||
|
|
||||||
|
void addAnchor(EAnchorType type, const AnchorLine& anchorLine);
|
||||||
|
void anchorLeft(const AnchorLine& anchorLine) { addAnchor(ANCHOR_LEFT, anchorLine); }
|
||||||
|
void anchorRight(const AnchorLine& anchorLine) { addAnchor(ANCHOR_RIGHT, anchorLine); }
|
||||||
|
void anchorTop(const AnchorLine& anchorLine) { addAnchor(ANCHOR_TOP, anchorLine); }
|
||||||
|
void anchorBottom(const AnchorLine& anchorLine) { addAnchor(ANCHOR_BOTTOM, anchorLine); }
|
||||||
|
void anchorHorizontalCenter(const AnchorLine& anchorLine) { addAnchor(ANCHOR_HORIZONTAL_CENTER, anchorLine); }
|
||||||
|
void anchorVerticalCenter(const AnchorLine& anchorLine) { addAnchor(ANCHOR_VERTICAL_CENTER, anchorLine); }
|
||||||
|
|
||||||
|
AnchorLine left() { return AnchorLine(asUILayout(), ANCHOR_LEFT); }
|
||||||
|
AnchorLine right() { return AnchorLine(asUILayout(), ANCHOR_RIGHT); }
|
||||||
|
AnchorLine top() { return AnchorLine(asUILayout(), ANCHOR_TOP); }
|
||||||
|
AnchorLine bottom() { return AnchorLine(asUILayout(), ANCHOR_BOTTOM); }
|
||||||
|
AnchorLine horizontalCenter() { return AnchorLine(asUILayout(), ANCHOR_HORIZONTAL_CENTER); }
|
||||||
|
AnchorLine verticalCenter() { return AnchorLine(asUILayout(), ANCHOR_VERTICAL_CENTER); }
|
||||||
|
|
||||||
|
void setMargin(int top, int left, int bottom, int right) { m_marginLeft = left; m_marginRight = right; m_marginTop = top; m_marginBottom = bottom; 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 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(); }
|
||||||
|
|
||||||
|
UILayoutPtr asUILayout() { return shared_from_this(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void recalculateAnchors();
|
||||||
|
void addAnchoredElement(UILayoutPtr anchoredElement);
|
||||||
|
|
||||||
|
AnchorLine m_anchors[6];
|
||||||
|
|
||||||
|
Rect m_rect;
|
||||||
|
int m_marginLeft;
|
||||||
|
int m_marginRight;
|
||||||
|
int m_marginTop;
|
||||||
|
int m_marginBottom;
|
||||||
|
std::list<UILayoutWeakPtr> m_anchoredElements;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UILAYOUT_H
|
|
@ -0,0 +1,254 @@
|
||||||
|
/* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "uiloader.h"
|
||||||
|
#include "core/resources.h"
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
|
UIElementPtr UILoader::createElementFromId(const std::string& id)
|
||||||
|
{
|
||||||
|
UIElementPtr element;
|
||||||
|
|
||||||
|
std::vector<std::string> split;
|
||||||
|
boost::split(split, id, boost::is_any_of("#"));
|
||||||
|
if(split.size() != 2)
|
||||||
|
return element;
|
||||||
|
|
||||||
|
std::string elementType = split[0];
|
||||||
|
std::string elementId = 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& parent)
|
||||||
|
{
|
||||||
|
std::string fileContents = g_resources.loadTextFile(file);
|
||||||
|
if(!fileContents.size()) {
|
||||||
|
logFatal("Could not load ui file \"%s", file.c_str());
|
||||||
|
return UIElementPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istringstream fin(fileContents);
|
||||||
|
|
||||||
|
try {
|
||||||
|
YAML::Parser parser(fin);
|
||||||
|
|
||||||
|
YAML::Node doc;
|
||||||
|
parser.GetNextDocument(doc);
|
||||||
|
|
||||||
|
// get element id
|
||||||
|
std::string elementId;
|
||||||
|
doc.begin().first() >> elementId;
|
||||||
|
|
||||||
|
// first we should populate all elements
|
||||||
|
// only after that we can load anchors
|
||||||
|
|
||||||
|
// create element interpreting it's id
|
||||||
|
UIElementPtr element = createElementFromId(elementId);
|
||||||
|
if(!element)
|
||||||
|
throw YAML::Exception(doc.begin().first().GetMark(), "invalid element type");
|
||||||
|
parent->addChild(element);
|
||||||
|
|
||||||
|
// populete it
|
||||||
|
if(element->asUIContainer())
|
||||||
|
populateContainer(element->asUIContainer(), doc.begin().second());
|
||||||
|
|
||||||
|
// now do the real load
|
||||||
|
loadElements(element, doc.begin().second());
|
||||||
|
} catch (YAML::Exception& e) {
|
||||||
|
logFatal("Failed to load ui file \"%s\":\n %s", file.c_str(), e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
return UIElementPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UILoader::populateContainer(const UIContainerPtr& parent, const YAML::Node& node)
|
||||||
|
{
|
||||||
|
for(auto it = node.begin(); it != node.end(); ++it) {
|
||||||
|
std::string id;
|
||||||
|
it.first() >> id;
|
||||||
|
|
||||||
|
// check if it's and element id
|
||||||
|
if(id.find("#") != std::string::npos) {
|
||||||
|
UIElementPtr element = createElementFromId(id);
|
||||||
|
if(!element)
|
||||||
|
throw YAML::Exception(it.first().GetMark(), "invalid element type");
|
||||||
|
parent->addChild(element);
|
||||||
|
|
||||||
|
// also populate this element if it's a parent
|
||||||
|
if(element->asUIContainer())
|
||||||
|
populateContainer(element->asUIContainer(), it.second());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UILoader::loadElements(const UIElementPtr& parent, const YAML::Node& node)
|
||||||
|
{
|
||||||
|
loadElement(parent, node);
|
||||||
|
|
||||||
|
if(parent->asUIContainer()) {
|
||||||
|
UIContainerPtr container = parent->asUIContainer();
|
||||||
|
for(auto it = node.begin(); it != node.end(); ++it) {
|
||||||
|
std::string id;
|
||||||
|
it.first() >> id;
|
||||||
|
|
||||||
|
// check if it's and element id
|
||||||
|
if(id.find("#") != std::string::npos) {
|
||||||
|
std::vector<std::string> split;
|
||||||
|
boost::split(split, id, boost::is_any_of("#"));
|
||||||
|
loadElements(container->getChildById(split[1]), it.second());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UILoader::loadElement(const UIElementPtr& element, const YAML::Node& node)
|
||||||
|
{
|
||||||
|
std::string tmp;
|
||||||
|
|
||||||
|
if(node.FindValue("skin"))
|
||||||
|
element->setSkin(g_uiSkins.getElementSkin(element->getElementType(), node["skin"]));
|
||||||
|
|
||||||
|
if(node.FindValue("size")) {
|
||||||
|
Size size;
|
||||||
|
node["size"] >> size;
|
||||||
|
element->setSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int margin;
|
||||||
|
if(node.FindValue("margin.left")) {
|
||||||
|
node["margin.left"] >> margin;
|
||||||
|
element->setMarginLeft(margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node.FindValue("margin.right")) {
|
||||||
|
node["margin.right"] >> margin;
|
||||||
|
element->setMarginRight(margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node.FindValue("margin.top")) {
|
||||||
|
node["margin.top"] >> margin;
|
||||||
|
element->setMarginTop(margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node.FindValue("margin.bottom")) {
|
||||||
|
node["margin.bottom"] >> margin;
|
||||||
|
element->setMarginBottom(margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node.FindValue("anchors.left"))
|
||||||
|
loadElementAnchor(element, ANCHOR_LEFT, node["anchors.left"]);
|
||||||
|
|
||||||
|
if(node.FindValue("anchors.right"))
|
||||||
|
loadElementAnchor(element, ANCHOR_RIGHT, node["anchors.right"]);
|
||||||
|
|
||||||
|
if(node.FindValue("anchors.top"))
|
||||||
|
loadElementAnchor(element, ANCHOR_TOP, node["anchors.top"]);
|
||||||
|
|
||||||
|
if(node.FindValue("anchors.bottom"))
|
||||||
|
loadElementAnchor(element, ANCHOR_BOTTOM, node["anchors.bottom"]);
|
||||||
|
|
||||||
|
if(node.FindValue("anchors.horizontalCenter"))
|
||||||
|
loadElementAnchor(element, ANCHOR_HORIZONTAL_CENTER, node["anchors.horizontalCenter"]);
|
||||||
|
|
||||||
|
if(node.FindValue("anchors.verticalCenter"))
|
||||||
|
loadElementAnchor(element, ANCHOR_VERTICAL_CENTER, node["anchors.verticalCenter"]);
|
||||||
|
|
||||||
|
// load specific element type
|
||||||
|
if(element->getElementType() == UI::Button) {
|
||||||
|
UIButtonPtr button = std::static_pointer_cast<UIButton>(element);
|
||||||
|
node["text"] >> tmp;
|
||||||
|
button->setText(tmp);
|
||||||
|
}
|
||||||
|
else if(element->getElementType() == UI::Window) {
|
||||||
|
UIWindowPtr window = std::static_pointer_cast<UIWindow>(element);
|
||||||
|
node["title"] >> tmp;
|
||||||
|
window->setTitle(tmp);
|
||||||
|
}
|
||||||
|
else if(element->getElementType() == UI::Label) {
|
||||||
|
UILabelPtr label = std::static_pointer_cast<UILabel>(element);
|
||||||
|
node["text"] >> tmp;
|
||||||
|
label->setText(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UILoader::loadElementAnchor(const UIElementPtr& element, 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)
|
||||||
|
throw YAML::Exception(node.GetMark(), "invalid anchors description");
|
||||||
|
|
||||||
|
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
|
||||||
|
throw YAML::Exception(node.GetMark(), "invalid anchors description");
|
||||||
|
|
||||||
|
UILayoutPtr relativeElement;
|
||||||
|
if(relativeElementId == "parent" && element->getParent()) {
|
||||||
|
relativeElement = element->getParent()->asUILayout();
|
||||||
|
} else {
|
||||||
|
UIElementPtr tmp = UIContainer::getRootContainer()->recursiveGetChildById(relativeElementId);
|
||||||
|
if(tmp)
|
||||||
|
relativeElement = tmp->asUILayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(relativeElement) {
|
||||||
|
element->addAnchor(type, AnchorLine(relativeElement, relativeAnchorType));
|
||||||
|
} else {
|
||||||
|
throw YAML::Exception(node.GetMark(), "anchoring failed, does the relative element really exists?");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UILOADER_H
|
||||||
|
#define UILOADER_H
|
||||||
|
|
||||||
|
#include "prerequisites.h"
|
||||||
|
#include "uiconstants.h"
|
||||||
|
#include "uicontainer.h"
|
||||||
|
|
||||||
|
namespace UILoader
|
||||||
|
{
|
||||||
|
/// Detect element type and create it
|
||||||
|
UIElementPtr createElementFromId(const std::string& id);
|
||||||
|
|
||||||
|
/// Loads an UIElement and it's children from a YAML file
|
||||||
|
UIElementPtr loadFile(const std::string& file, const UIContainerPtr& parent);
|
||||||
|
|
||||||
|
/// Populate container children from a YAML node
|
||||||
|
void populateContainer(const UIContainerPtr& parent, const YAML::Node& node);
|
||||||
|
|
||||||
|
/// Load element and its children from a YAML node
|
||||||
|
void loadElements(const UIElementPtr& parent, const YAML::Node& node);
|
||||||
|
|
||||||
|
/// Load element proprieties from a YAML node
|
||||||
|
void loadElement(const UIElementPtr& element, const YAML::Node& node);
|
||||||
|
|
||||||
|
/// Load anchor from a YAML node
|
||||||
|
void loadElementAnchor(const UIElementPtr& element, EAnchorType type, const YAML::Node& node);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UILOADER_H
|
|
@ -23,9 +23,3 @@
|
||||||
|
|
||||||
|
|
||||||
#include "uiwindow.h"
|
#include "uiwindow.h"
|
||||||
|
|
||||||
void UIWindow::load(const YAML::Node& node)
|
|
||||||
{
|
|
||||||
UIContainer::load(node);
|
|
||||||
node["title"] >> m_title;
|
|
||||||
}
|
|
||||||
|
|
|
@ -35,8 +35,7 @@ public:
|
||||||
UIContainer(UI::Window),
|
UIContainer(UI::Window),
|
||||||
m_title(title) { }
|
m_title(title) { }
|
||||||
|
|
||||||
void load(const YAML::Node& node);
|
void setTitle(const std::string& title) { m_title = title; }
|
||||||
|
|
||||||
const std::string& getTitle() const { return m_title; }
|
const std::string& getTitle() const { return m_title; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "color.h"
|
||||||
|
|
||||||
|
Color Color::white(0xFF, 0xFF, 0xFF, 0xFF);
|
||||||
|
Color Color::black(0x00, 0x00, 0x00, 0xFF);
|
||||||
|
Color Color::alpha(0x00, 0x00, 0x00, 0x00);
|
||||||
|
Color Color::red (0xFF, 0x00, 0x00, 0xFF);
|
||||||
|
Color Color::green(0x00, 0xFF, 0x00, 0xFF);
|
||||||
|
Color Color::blue (0x00, 0x00, 0xFF, 0xFF);
|
||||||
|
Color Color::pink (0xFF, 0x00, 0xFF, 0xFF);
|
|
@ -37,10 +37,10 @@ public:
|
||||||
inline Color(const Color& other) : color(other.color) { }
|
inline Color(const Color& other) : color(other.color) { }
|
||||||
inline Color(RGBA rgba) : color(rgba) { }
|
inline Color(RGBA rgba) : color(rgba) { }
|
||||||
|
|
||||||
inline uint8 red() const { return (color >> 24) & 0xFF; }
|
inline uint8 r() const { return (color >> 24) & 0xFF; }
|
||||||
inline uint8 green() const { return (color >> 16) & 0xFF; }
|
inline uint8 g() const { return (color >> 16) & 0xFF; }
|
||||||
inline uint8 blue() const { return (color >> 8) & 0xFF; }
|
inline uint8 b() const { return (color >> 8) & 0xFF; }
|
||||||
inline uint8 alpha() const { return color & 0xFF; }
|
inline uint8 a() const { return color & 0xFF; }
|
||||||
inline RGBA rgba() const { return color; }
|
inline RGBA rgba() const { return color; }
|
||||||
inline const uint8* rgbaPtr() const { return (const uint8*)&color; }
|
inline const uint8* rgbaPtr() const { return (const uint8*)&color; }
|
||||||
|
|
||||||
|
@ -55,6 +55,14 @@ public:
|
||||||
inline bool operator==(const Color& other) const { return other.color == color; }
|
inline bool operator==(const Color& other) const { return other.color == color; }
|
||||||
inline bool operator!=(const Color& other) const { return other.color != color; }
|
inline bool operator!=(const Color& other) const { return other.color != color; }
|
||||||
|
|
||||||
|
static Color white;
|
||||||
|
static Color black;
|
||||||
|
static Color alpha;
|
||||||
|
static Color red;
|
||||||
|
static Color green;
|
||||||
|
static Color blue;
|
||||||
|
static Color pink;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RGBA color;
|
RGBA color;
|
||||||
};
|
};
|
||||||
|
@ -69,4 +77,13 @@ inline void operator>>(const YAML::Node& node, Color& color)
|
||||||
color.setRGBA(r,g,b,a);
|
color.setRGBA(r,g,b,a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, const Color& color)
|
||||||
|
{
|
||||||
|
out << "Color(" << (int)color.r() << ","
|
||||||
|
<< (int)color.g() << ","
|
||||||
|
<< (int)color.b() << ","
|
||||||
|
<< (int)color.a() << ")";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // COLOR_H
|
#endif // COLOR_H
|
||||||
|
|
|
@ -85,4 +85,12 @@ inline void operator>>(const YAML::Node& node, TPoint<T>& point)
|
||||||
node[1] >> point.y;
|
node[1] >> point.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, const TPoint<T>& point)
|
||||||
|
{
|
||||||
|
out << "Point(" << point.x << ","
|
||||||
|
<< point.y << ")";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -304,4 +304,14 @@ inline void operator>>(const YAML::Node& node, TRect<T>& rect)
|
||||||
rect.setRect(x, y, width, height);
|
rect.setRect(x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, const TRect<T>& rect)
|
||||||
|
{
|
||||||
|
out << "Rect(" << rect.left() << ","
|
||||||
|
<< rect.top() << ","
|
||||||
|
<< rect.width() << ","
|
||||||
|
<< rect.height() << ")";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // RECT_H
|
#endif // RECT_H
|
||||||
|
|
|
@ -120,4 +120,12 @@ inline void operator>>(const YAML::Node& node, TSize<T>& size)
|
||||||
size.setSize(w, h);
|
size.setSize(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, const TSize<T>& size)
|
||||||
|
{
|
||||||
|
out << "Size(" << size.width() << ","
|
||||||
|
<< size.height() << ")";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,15 +39,15 @@ void MenuState::onEnter()
|
||||||
m_background = g_textures.get("background.png");
|
m_background = g_textures.get("background.png");
|
||||||
m_background->enableBilinearFilter();
|
m_background->enableBilinearFilter();
|
||||||
|
|
||||||
UIContainerPtr mainMenuPanel = UIContainer::load("ui/mainMenu-panel.yml");
|
UIElementPtr mainMenuPanel = UILoader::loadFile("ui/mainMenu.yml", UIContainer::getRootContainer());
|
||||||
|
/*
|
||||||
UIButtonPtr button = std::static_pointer_cast<UIButton>(mainMenuPanel->getChildById("exitGame-button"));
|
UIButtonPtr button = std::static_pointer_cast<UIButton>(mainMenuPanel->getChildById("exitGame-button"));
|
||||||
button->onClick([]{ g_engine.stop(); });
|
button->onClick([]{ g_engine.stop(); });
|
||||||
|
|
||||||
button = std::static_pointer_cast<UIButton>(mainMenuPanel->getChildById("enterGame-button"));
|
button = std::static_pointer_cast<UIButton>(mainMenuPanel->getChildById("enterGame-button"));
|
||||||
button->onClick([]{
|
button->onClick([]{
|
||||||
UIContainer::load("ui/enterGame-window.yml");
|
UIContainer::load("ui/enterGame-window.yml");
|
||||||
});
|
});*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuState::onLeave()
|
void MenuState::onLeave()
|
||||||
|
@ -82,7 +82,7 @@ void MenuState::render()
|
||||||
texCoordsSize = texCoordsSize.boundedTo(texSize);
|
texCoordsSize = texCoordsSize.boundedTo(texSize);
|
||||||
Rect texCoords(0, 0, texCoordsSize);
|
Rect texCoords(0, 0, texCoordsSize);
|
||||||
texCoords.moveBottomRight(texSize.toPoint());
|
texCoords.moveBottomRight(texSize.toPoint());
|
||||||
g_graphics.drawTexturedRect(Rect(0, 0, screenSize), m_background.get(), texCoords);
|
g_graphics.drawTexturedRect(Rect(0, 0, screenSize), m_background, texCoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuState::createMainMenu()
|
void MenuState::createMainMenu()
|
||||||
|
|
Loading…
Reference in New Issue