a bunch of stuff
After Width: | Height: | Size: 7.5 KiB |
|
@ -0,0 +1,9 @@
|
|||
glyph height: 14
|
||||
glyph spacing: [0, 1]
|
||||
top margin: 0
|
||||
image: sans-11px.png
|
||||
image glyph size: [16, 16]
|
||||
first glyph: 0
|
||||
|
||||
glyph widths:
|
||||
32: 4
|
|
@ -3,6 +3,7 @@ glyph spacing: [1, 4]
|
|||
top margin: 3
|
||||
image: tibia-10px-antialised.png
|
||||
image glyph size: [8, 16]
|
||||
first glyph: 32
|
||||
|
||||
glyph widths:
|
||||
32: 2
|
||||
|
|
|
@ -3,6 +3,7 @@ glyph spacing: [1, 1]
|
|||
top margin: 3
|
||||
image: tibia-10px-monochrome.png
|
||||
image glyph size: [8, 16]
|
||||
first glyph: 32
|
||||
|
||||
glyph widths:
|
||||
32: 2
|
||||
|
|
|
@ -3,6 +3,7 @@ glyph spacing: [0, 1]
|
|||
top margin: 3
|
||||
image: tibia-12px-rounded.png
|
||||
image glyph size: [16, 16]
|
||||
first glyph: 32
|
||||
|
||||
glyph widths:
|
||||
32: 4
|
||||
|
|
|
@ -3,6 +3,7 @@ glyph spacing: [0, 1]
|
|||
top margin: 1
|
||||
image: tibia-8px-antialised.png
|
||||
image glyph size: [8, 8]
|
||||
first glyph: 32
|
||||
|
||||
glyph widths:
|
||||
32: 2
|
||||
32: 2
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
panel#background:
|
||||
skin:
|
||||
image: background.png
|
||||
antialised: true
|
||||
size: [500, 500]
|
||||
skin: mainMenuBackground
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
window#optionsWindow:
|
||||
title: Info
|
||||
title: Options
|
||||
size: [286, 262]
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
window#messageBoxWindow:
|
||||
size: [236, 78]
|
||||
size: [192, 78]
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
default font: sans-11px
|
||||
default font color: [0, 115, 234, 255]
|
||||
|
||||
buttons:
|
||||
default:
|
||||
default size: [96, 22]
|
||||
font color: [0, 115, 234, 255]
|
||||
|
||||
bordered image:
|
||||
source: lightness/button-up.png
|
||||
left border: [0,2,2,6]
|
||||
right border: [22,2,2,6]
|
||||
top border: [2,0,20,2]
|
||||
bottom border: [2,8,20,2]
|
||||
top left corner: [0,0,2,2]
|
||||
top right corner: [22,0,2,2]
|
||||
bottom left corner: [0,8,2,2]
|
||||
bottom right corner: [22,8,2,2]
|
||||
center: [2,2,20,6]
|
||||
|
||||
hover state:
|
||||
font color: [255, 255, 255, 255]
|
||||
bordered image:
|
||||
source: lightness/button-hover.png
|
||||
left border: [0,2,2,6]
|
||||
right border: [22,2,2,6]
|
||||
top border: [2,0,20,2]
|
||||
bottom border: [2,8,20,2]
|
||||
top left corner: [0,0,2,2]
|
||||
top right corner: [22,0,2,2]
|
||||
bottom left corner: [0,8,2,2]
|
||||
bottom right corner: [22,8,2,2]
|
||||
center: [2,2,20,6]
|
||||
|
||||
down state:
|
||||
font color: [255, 0, 132, 255]
|
||||
bordered image:
|
||||
source: lightness/button-down.png
|
||||
left border: [0,2,2,6]
|
||||
right border: [22,2,2,6]
|
||||
top border: [2,0,20,2]
|
||||
bottom border: [2,8,20,2]
|
||||
top left corner: [0,0,2,2]
|
||||
top right corner: [22,0,2,2]
|
||||
bottom left corner: [0,8,2,2]
|
||||
bottom right corner: [22,8,2,2]
|
||||
center: [2,2,20,6]
|
||||
panels:
|
||||
default:
|
||||
# the default panel is empty
|
||||
|
||||
mainMenuBackground:
|
||||
image: lightness/background.png
|
||||
antialised: true
|
||||
|
||||
roundedGridPanel:
|
||||
bordered image:
|
||||
source: lightness/menupanel.png
|
||||
left border: [0,2,2,6]
|
||||
right border: [22,2,2,6]
|
||||
top border: [2,0,20,2]
|
||||
bottom border: [2,8,20,2]
|
||||
top left corner: [0,0,2,2]
|
||||
top right corner: [22,0,2,2]
|
||||
bottom left corner: [0,8,2,2]
|
||||
bottom right corner: [22,8,2,2]
|
||||
center: [2,2,20,6]
|
||||
|
||||
flatPanel:
|
||||
bordered image:
|
||||
source: lightness/panel.png
|
||||
left border: [0,2,2,6]
|
||||
right border: [22,2,2,6]
|
||||
top border: [2,0,20,2]
|
||||
bottom border: [2,8,20,2]
|
||||
top left corner: [0,0,2,2]
|
||||
top right corner: [22,0,2,2]
|
||||
bottom left corner: [0,8,2,2]
|
||||
bottom right corner: [22,8,2,2]
|
||||
center: [2,2,20,6]
|
||||
|
||||
labels:
|
||||
default:
|
||||
font color: [0, 115, 234, 255]
|
||||
|
||||
windows:
|
||||
default:
|
||||
font color: [80, 80, 80, 255]
|
||||
head:
|
||||
text align: left
|
||||
margin: 8
|
||||
height: 26
|
||||
bordered image:
|
||||
source: lightness/window.png
|
||||
left border: [0,5,5,22]
|
||||
right border: [251,5,5,22]
|
||||
top border: [5,0,246,5]
|
||||
bottom border: [5,27,246,5]
|
||||
top left corner: [0,0,5,5]
|
||||
top right corner: [251,0,5,5]
|
||||
bottom left corner: [0,27,5,5]
|
||||
bottom right corner: [251,27,5,5]
|
||||
center: [5,5,246,22]
|
||||
body:
|
||||
bordered image:
|
||||
source: lightness/window.png
|
||||
left border: [0,32,2,222]
|
||||
right border: [254,32,2,222]
|
||||
bottom border: [2,254,252,2]
|
||||
bottom left corner: [0,254,2,2]
|
||||
bottom right corner: [254,254,2,2]
|
||||
center: [2, 32, 92, 92]
|
||||
|
||||
text edits:
|
||||
default:
|
||||
default size: [86, 20]
|
||||
font color: [80, 80, 80, 255]
|
||||
text margin: 3
|
||||
bordered image:
|
||||
source: lightness/button-down.png
|
||||
left border: [0,2,2,6]
|
||||
right border: [22,2,2,6]
|
||||
top border: [2,0,20,2]
|
||||
bottom border: [2,8,20,2]
|
||||
top left corner: [0,0,2,2]
|
||||
top right corner: [22,0,2,2]
|
||||
bottom left corner: [0,8,2,2]
|
||||
bottom right corner: [22,8,2,2]
|
||||
center: [2,2,20,6]
|
||||
|
||||
line decorations:
|
||||
default:
|
||||
bordered image:
|
||||
source: lightness/window.png
|
||||
top border: [2,254,252,2]
|
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 235 B |
After Width: | Height: | Size: 283 B |
After Width: | Height: | Size: 234 B |
After Width: | Height: | Size: 232 B |
After Width: | Height: | Size: 252 B |
After Width: | Height: | Size: 880 B |
|
@ -1,9 +1,11 @@
|
|||
default skin image: tibiaskin.png
|
||||
default font: tibia-10px-antialised
|
||||
default font color: [191, 191, 191, 255]
|
||||
default texture: tibiaskin/skin.png
|
||||
|
||||
buttons:
|
||||
default:
|
||||
font: tibia-8px-antialised
|
||||
text color: [238, 238, 238, 255]
|
||||
font color: [238, 238, 238, 255]
|
||||
default size: [86, 20]
|
||||
|
||||
bordered image:
|
||||
|
@ -33,6 +35,10 @@ panels:
|
|||
default:
|
||||
# the default panel is empty
|
||||
|
||||
mainMenuBackground:
|
||||
image: tibiaskin/background.png
|
||||
antialised: true
|
||||
|
||||
roundedGridPanel:
|
||||
bordered image:
|
||||
left border: [0,214,5,32]
|
||||
|
@ -59,15 +65,12 @@ panels:
|
|||
|
||||
labels:
|
||||
default:
|
||||
font: tibia-10px-antialised
|
||||
text color: [191, 191, 191, 255]
|
||||
|
||||
windows:
|
||||
default:
|
||||
font color: [143, 143, 143, 255]
|
||||
head:
|
||||
text color: [143, 143, 143, 255]
|
||||
height: 17
|
||||
font: tibia-10px-antialised
|
||||
bordered image:
|
||||
left border: [106,187,4,9]
|
||||
right border: [110,187,4,9]
|
||||
|
@ -90,7 +93,6 @@ windows:
|
|||
text edits:
|
||||
default:
|
||||
default size: [86, 16]
|
||||
font: tibia-10px-antialised
|
||||
text margin: 3
|
||||
bordered image:
|
||||
left border: [308,97,1,1]
|
||||
|
|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 1.9 MiB |
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
@ -0,0 +1,46 @@
|
|||
/* 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 CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
|
||||
enum AlignmentFlag {
|
||||
AlignLeft = 1,
|
||||
AlignRight = 2,
|
||||
AlignTop = 4,
|
||||
AlignBottom = 8,
|
||||
AlignHorizontalCenter = 16,
|
||||
AlignVerticalCenter = 32,
|
||||
AlignTopLeft = AlignTop | AlignLeft,
|
||||
AlignTopRight = AlignTop | AlignRight,
|
||||
AlignBottomLeft = AlignBottom | AlignLeft,
|
||||
AlignBottomRight = AlignBottom | AlignRight,
|
||||
AlignLeftCenter = AlignLeft | AlignVerticalCenter,
|
||||
AlignRightCenter = AlignRight | AlignVerticalCenter,
|
||||
AlignTopCenter = AlignTop | AlignHorizontalCenter,
|
||||
AlignBottomCenter = AlignBottom | AlignHorizontalCenter,
|
||||
AlignCenter = AlignVerticalCenter | AlignHorizontalCenter
|
||||
};
|
||||
|
||||
#endif // CONSTANTS_H
|
|
@ -82,12 +82,12 @@ void Configs::setValue(const std::string &key, const char *value)
|
|||
|
||||
void Configs::setValue(const std::string &key, int value)
|
||||
{
|
||||
setValue(key, convertType<std::string, int>(value));
|
||||
setValue(key, convert_cast<std::string>(value));
|
||||
}
|
||||
|
||||
void Configs::setValue(const std::string &key, float value)
|
||||
{
|
||||
setValue(key, convertType<std::string, float>(value));
|
||||
setValue(key, convert_cast<std::string>(value));
|
||||
}
|
||||
|
||||
void Configs::setValue(const std::string &key, bool value)
|
||||
|
@ -116,7 +116,7 @@ float Configs::getFloat(const std::string &key) const
|
|||
flogWarning("WARNING: Config value %s not found", key.c_str());
|
||||
return 0;
|
||||
}
|
||||
return convertType<float, std::string>(it->second);
|
||||
return convert_cast<float>(it->second);
|
||||
}
|
||||
|
||||
bool Configs::getBoolean(const std::string &key) const
|
||||
|
@ -136,5 +136,5 @@ int Configs::getInteger(const std::string &key) const
|
|||
flogWarning("WARNING: Config value %s not found", key.c_str());
|
||||
return 0;
|
||||
}
|
||||
return convertType<int, std::string>(it->second);
|
||||
return convert_cast<int>(it->second);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <ui/uicontainer.h>
|
||||
#include <net/connection.h>
|
||||
#include <script/luascript.h>
|
||||
#include <ui/uiskins.h>
|
||||
|
||||
Engine g_engine;
|
||||
|
||||
|
@ -38,23 +39,24 @@ void Engine::init()
|
|||
{
|
||||
// initialize stuff
|
||||
g_graphics.init();
|
||||
g_fonts.init("tibia-12px-rounded");
|
||||
g_fonts.init();
|
||||
g_lua.init();
|
||||
}
|
||||
|
||||
void Engine::terminate()
|
||||
{
|
||||
// terminate stuff
|
||||
g_fonts.terminate();
|
||||
g_graphics.terminate();
|
||||
|
||||
// destroy root ui
|
||||
UIContainer::getRoot()->destroy();
|
||||
|
||||
// cleanup script stuff
|
||||
g_lua.terminate();
|
||||
|
||||
// poll remaning events
|
||||
g_engine.poll();
|
||||
|
||||
// terminate stuff
|
||||
g_fonts.terminate();
|
||||
g_graphics.terminate();
|
||||
}
|
||||
|
||||
void Engine::poll()
|
||||
|
@ -78,7 +80,7 @@ void Engine::run()
|
|||
|
||||
std::string fpsText;
|
||||
Size fpsTextSize;
|
||||
Font *defaultFont = g_fonts.getDefaultFont();
|
||||
FontPtr defaultFont = g_uiSkins.getDefaultFont();
|
||||
|
||||
m_lastFrameTicks = Platform::getTicks();
|
||||
int lastFpsTicks = m_lastFrameTicks;
|
||||
|
@ -93,7 +95,7 @@ void Engine::run()
|
|||
|
||||
// render only when visible
|
||||
if(Platform::isWindowVisible()) {
|
||||
// calculate and fps
|
||||
// calculate fps
|
||||
if(m_calculateFps) {
|
||||
frameCount++;
|
||||
if(m_lastFrameTicks - lastFpsTicks >= 1000) {
|
||||
|
@ -102,7 +104,7 @@ void Engine::run()
|
|||
frameCount = 0;
|
||||
|
||||
// update fps text
|
||||
fpsText = f("FPS: %d", fps);
|
||||
fpsText = fmt("FPS: %d", fps);
|
||||
fpsTextSize = defaultFont->calculateTextRectSize(fpsText);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,14 +75,21 @@ void BorderedImage::setTexCoords(const Rect& left,
|
|||
m_bottomRightCornerTexCoords = bottomRight;
|
||||
m_centerTexCoords = center;
|
||||
|
||||
m_cornersSize = Size(left.width() + right.width(),
|
||||
m_bordersSize = Size(left.width() + right.width(),
|
||||
top.height() + bottom.height());
|
||||
|
||||
m_defaultSize = Size(std::max(std::max(topLeft.width(), bottomLeft.width()), left.width()) +
|
||||
std::max(std::max(topRight.width(), bottomRight.width()), right.width()) +
|
||||
center.width(),
|
||||
std::max(std::max(topLeft.height(), topRight.height()), top.height()) +
|
||||
std::max(std::max(bottomLeft.height(), bottomRight.height()), bottom.height()) +
|
||||
center.height());
|
||||
}
|
||||
|
||||
void BorderedImage::draw(const Rect& screenCoords)
|
||||
{
|
||||
Rect rectCoords;
|
||||
Size centerSize = screenCoords.size() - m_cornersSize;
|
||||
Size centerSize = screenCoords.size() - m_bordersSize;
|
||||
|
||||
// first the center
|
||||
if(centerSize.area() > 0) {
|
||||
|
@ -144,3 +151,4 @@ void BorderedImage::draw(const Rect& screenCoords)
|
|||
m_bottomRightCornerTexCoords.size());
|
||||
g_graphics.drawTexturedRect(rectCoords, m_texture, m_bottomRightCornerTexCoords);
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ public:
|
|||
|
||||
void draw(const Rect& screenCoords);
|
||||
|
||||
Size getDefaultSize() const { return m_defaultSize; }
|
||||
|
||||
private:
|
||||
Rect m_leftBorderTexCoords;
|
||||
Rect m_rightBorderTexCoords;
|
||||
|
@ -79,7 +81,8 @@ private:
|
|||
|
||||
Rect m_centerTexCoords;
|
||||
|
||||
Size m_cornersSize;
|
||||
Size m_bordersSize;
|
||||
Size m_defaultSize;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<BorderedImage> BorderedImagePtr;
|
||||
|
|
|
@ -34,9 +34,9 @@ void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
|
|||
uchar *texturePixels = m_texture->getPixels();
|
||||
|
||||
// small AI to auto calculate pixels widths
|
||||
for(int glyph = 32; glyph< 256; ++glyph) {
|
||||
Rect glyphCoords(((glyph - 32) % numHorizontalGlyphs) * glyphSize.width(),
|
||||
((glyph - 32) / numHorizontalGlyphs) * glyphSize.height(),
|
||||
for(int glyph = m_firstGlyph; glyph< 256; ++glyph) {
|
||||
Rect glyphCoords(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.width(),
|
||||
((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.height(),
|
||||
glyphSize.width(),
|
||||
m_glyphHeight);
|
||||
int width = glyphSize.width();
|
||||
|
@ -85,13 +85,11 @@ bool Font::load(const std::string& file)
|
|||
// required values
|
||||
doc["glyph height"] >> m_glyphHeight;
|
||||
doc["image glyph size"] >> glyphSize;
|
||||
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;
|
||||
textureName = yamlRead<std::string>(doc, "image");
|
||||
m_glyphHeight = yamlRead<int>(doc, "glyph height");
|
||||
m_firstGlyph = yamlRead<int>(doc, "first glyph", 32);
|
||||
m_topMargin = yamlRead<int>(doc, "top margin", 0);
|
||||
m_glyphSpacing = yamlRead(doc, "glyph spacing", Size(0,0));
|
||||
|
||||
// load texture
|
||||
m_texture = g_textures.get("fonts/" + textureName);
|
||||
|
@ -104,21 +102,15 @@ bool Font::load(const std::string& file)
|
|||
calculateGlyphsWidthsAutomatically(glyphSize);
|
||||
|
||||
// read custom widths
|
||||
if(doc.FindValue("glyph widths")) {
|
||||
const YAML::Node& widthsNode = doc["glyph widths"];
|
||||
for(auto it = widthsNode.begin(); it != widthsNode.end(); ++it) {
|
||||
int glyph, glyphWidth;
|
||||
it.first() >> glyph;
|
||||
it.second() >> glyphWidth;
|
||||
m_glyphsSize[glyph].setWidth(glyphWidth);
|
||||
}
|
||||
}
|
||||
std::map<int, int> glyphWidths = yamlReadMap<int, int>(doc, "glyph widths");
|
||||
foreach(const auto& pair, glyphWidths)
|
||||
m_glyphsSize[pair.first].setWidth(pair.second);
|
||||
|
||||
// calculate glyphs texture coords
|
||||
int numHorizontalGlyphs = m_texture->getSize().width() / glyphSize.width();
|
||||
for(int glyph = 32; glyph< 256; ++glyph) {
|
||||
m_glyphsTextureCoords[glyph].setRect(((glyph - 32) % numHorizontalGlyphs) * glyphSize.width(),
|
||||
((glyph - 32) / numHorizontalGlyphs) * glyphSize.height(),
|
||||
for(int glyph = m_firstGlyph; glyph< 256; ++glyph) {
|
||||
m_glyphsTextureCoords[glyph].setRect(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.width(),
|
||||
((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.height(),
|
||||
m_glyphsSize[glyph].width(),
|
||||
m_glyphHeight);
|
||||
}
|
||||
|
@ -136,13 +128,13 @@ void Font::renderText(const std::string& text,
|
|||
{
|
||||
Size boxSize = g_graphics.getScreenSize() - startPos.toSize();
|
||||
Rect screenCoords(startPos, boxSize);
|
||||
renderText(text, screenCoords, ALIGN_TOP_LEFT, color);
|
||||
renderText(text, screenCoords, AlignTopLeft, color);
|
||||
}
|
||||
|
||||
|
||||
void Font::renderText(const std::string& text,
|
||||
const Rect& screenCoords,
|
||||
int align,
|
||||
AlignmentFlag align,
|
||||
const Color& color)
|
||||
{
|
||||
// prevent glitches from invalid rects
|
||||
|
@ -167,19 +159,19 @@ void Font::renderText(const std::string& text,
|
|||
Rect glyphTextureCoords = m_glyphsTextureCoords[glyph];
|
||||
|
||||
// first translate to align position
|
||||
if(align & ALIGN_BOTTOM) {
|
||||
if(align & AlignBottom) {
|
||||
glyphScreenCoords.translate(0, screenCoords.height() - textBoxSize.height());
|
||||
} else if(align & ALIGN_VERTICAL_CENTER) {
|
||||
} else if(align & AlignVerticalCenter) {
|
||||
glyphScreenCoords.translate(0, (screenCoords.height() - textBoxSize.height()) / 2);
|
||||
} else { // ALIGN_TOP
|
||||
} else { // AlignTop
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
if(align & ALIGN_RIGHT) {
|
||||
if(align & AlignRight) {
|
||||
glyphScreenCoords.translate(screenCoords.width() - textBoxSize.width(), 0);
|
||||
} else if(align & ALIGN_HORIZONTAL_CENTER) {
|
||||
} else if(align & AlignHorizontalCenter) {
|
||||
glyphScreenCoords.translate((screenCoords.width() - textBoxSize.width()) / 2, 0);
|
||||
} else { // ALIGN_TOP
|
||||
} else { // AlignLeft
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
|
@ -205,7 +197,7 @@ void Font::renderText(const std::string& text,
|
|||
}
|
||||
}
|
||||
|
||||
const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text, int align, Size *textBoxSize) const
|
||||
const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text, AlignmentFlag align, Size *textBoxSize) const
|
||||
{
|
||||
// for performance reasons we use statics vectors that are allocated on demand
|
||||
static std::vector<Point> glyphsPositions(1);
|
||||
|
@ -229,7 +221,7 @@ const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text
|
|||
glyphsPositions.resize(textLength);
|
||||
|
||||
// calculate lines width
|
||||
if((align & ALIGN_RIGHT || align & ALIGN_HORIZONTAL_CENTER) || textBoxSize) {
|
||||
if((align & AlignRight || align & AlignHorizontalCenter) || textBoxSize) {
|
||||
lineWidths[0] = 0;
|
||||
for(i = 0; i< textLength; ++i) {
|
||||
glyph = (uchar)text[i];
|
||||
|
@ -259,11 +251,11 @@ const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text
|
|||
}
|
||||
|
||||
// calculate start x pos
|
||||
if(align & ALIGN_RIGHT) {
|
||||
if(align & AlignRight) {
|
||||
virtualPos.x = (maxLineWidth - lineWidths[lines]);
|
||||
} else if(align & ALIGN_HORIZONTAL_CENTER) {
|
||||
} else if(align & AlignHorizontalCenter) {
|
||||
virtualPos.x = (maxLineWidth - lineWidths[lines]) / 2;
|
||||
} else { // ALIGN_LEFT
|
||||
} else { // AlignLeft
|
||||
virtualPos.x = 0;
|
||||
}
|
||||
}
|
||||
|
@ -288,7 +280,7 @@ const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text
|
|||
Size Font::calculateTextRectSize(const std::string& text)
|
||||
{
|
||||
Size size;
|
||||
calculateGlyphsPositions(text, ALIGN_TOP_LEFT, &size);
|
||||
calculateGlyphsPositions(text, AlignTopLeft, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,27 +28,11 @@
|
|||
#include <prerequisites.h>
|
||||
#include <graphics/texture.h>
|
||||
|
||||
enum EAlign {
|
||||
ALIGN_TOP = 1 << 0,
|
||||
ALIGN_BOTTOM = 1 << 1,
|
||||
ALIGN_LEFT = 1 << 2,
|
||||
ALIGN_RIGHT = 1 << 3,
|
||||
ALIGN_HORIZONTAL_CENTER = 1 << 4,
|
||||
ALIGN_VERTICAL_CENTER = 1 << 5,
|
||||
ALIGN_CENTER = ALIGN_HORIZONTAL_CENTER | ALIGN_VERTICAL_CENTER,
|
||||
ALIGN_TOP_RIGHT = ALIGN_TOP | ALIGN_RIGHT,
|
||||
ALIGN_TOP_LEFT = ALIGN_TOP | ALIGN_LEFT,
|
||||
ALIGN_BOTTOM_RIGHT = ALIGN_BOTTOM | ALIGN_RIGHT,
|
||||
ALIGN_BOTTOM_LEFT = ALIGN_BOTTOM | ALIGN_LEFT
|
||||
};
|
||||
|
||||
class Font
|
||||
{
|
||||
public:
|
||||
Font(const std::string& name) :
|
||||
m_name(name),
|
||||
m_glyphHeight(10),
|
||||
m_topMargin(0) { }
|
||||
m_name(name) { }
|
||||
|
||||
/// Load font from file
|
||||
bool load(const std::string &file);
|
||||
|
@ -61,28 +45,29 @@ public:
|
|||
/// Advanced text render
|
||||
void renderText(const std::string& text,
|
||||
const Rect& screenCoords,
|
||||
int align = ALIGN_TOP_LEFT,
|
||||
AlignmentFlag align = AlignTopLeft,
|
||||
const Color& color = Color::white);
|
||||
|
||||
/// Calculate glyphs positions to use on render, also calculates textBoxSize if wanted
|
||||
const std::vector<Point>& calculateGlyphsPositions(const std::string& text, int align = ALIGN_TOP_LEFT, Size *textBoxSize = NULL) const;
|
||||
const std::vector<Point>& calculateGlyphsPositions(const std::string& text, AlignmentFlag align = AlignTopLeft, Size *textBoxSize = NULL) const;
|
||||
|
||||
/// Simulate render and calculate text size
|
||||
Size calculateTextRectSize(const std::string& text);
|
||||
|
||||
const std::string& getName() const { return m_name; }
|
||||
std::string getName() const { return m_name; }
|
||||
int getGlyphHeight() const { return m_glyphHeight; }
|
||||
const Rect *getGlyphsTextureCoords() const { return m_glyphsTextureCoords; }
|
||||
const Size *getGlyphsSize() const { return m_glyphsSize; }
|
||||
const TexturePtr& getTexture() const { return m_texture; }
|
||||
int getTopMargin() const { return m_topMargin; }
|
||||
const Size& getGlyphSpacing() const { return m_glyphSpacing; }
|
||||
Size getGlyphSpacing() const { return m_glyphSpacing; }
|
||||
|
||||
private:
|
||||
void calculateGlyphsWidthsAutomatically(const Size& glyphSize);
|
||||
|
||||
std::string m_name;
|
||||
int m_glyphHeight;
|
||||
int m_firstGlyph;
|
||||
int m_topMargin;
|
||||
Size m_glyphSpacing;
|
||||
TexturePtr m_texture;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
Fonts g_fonts;
|
||||
|
||||
void Fonts::init(const std::string& defaultFontName)
|
||||
void Fonts::init()
|
||||
{
|
||||
// load all fonts
|
||||
std::list<std::string> files = g_resources.getDirectoryFiles("fonts");
|
||||
|
@ -37,27 +37,21 @@ void Fonts::init(const std::string& defaultFontName)
|
|||
std::string name = file;
|
||||
boost::erase_first(name, ".yml");
|
||||
FontPtr font(new Font(name));
|
||||
if(font->load("fonts/" + file)) {
|
||||
if(font->load("fonts/" + file))
|
||||
m_fonts.push_back(font);
|
||||
|
||||
if(name == defaultFontName)
|
||||
m_defaultFont = font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_defaultFont)
|
||||
flogFatal("FATAL ERROR: Could not load the default font \"%s\"\n", defaultFontName.c_str());
|
||||
}
|
||||
|
||||
Font* Fonts::get(const std::string& fontName)
|
||||
FontPtr Fonts::get(const std::string& fontName)
|
||||
{
|
||||
// find font by name
|
||||
for(auto it = m_fonts.begin(); it != m_fonts.end(); ++it) {
|
||||
if((*it)->getName() == fontName)
|
||||
return (*it).get();
|
||||
foreach(const FontPtr& font, m_fonts) {
|
||||
if(font->getName() == fontName)
|
||||
return font;
|
||||
}
|
||||
|
||||
flogError("ERROR: Font \"%s\" not found, returing the default one", fontName.c_str());
|
||||
return m_defaultFont.get();
|
||||
flogFatal("ERROR: Font \"%s\" not found", fontName.c_str());
|
||||
return FontPtr();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,20 +34,16 @@ public:
|
|||
Fonts() { }
|
||||
|
||||
/// Initialize all fonts
|
||||
void init(const std::string& defaultFontName);
|
||||
void init();
|
||||
|
||||
/// Terminate all fonts
|
||||
void terminate() { }
|
||||
|
||||
/// Get a font by name
|
||||
Font *get(const std::string& fontName);
|
||||
|
||||
/// Get the default font
|
||||
Font *getDefaultFont() { return m_defaultFont.get(); };
|
||||
FontPtr get(const std::string& fontName);
|
||||
|
||||
private:
|
||||
std::vector<FontPtr> m_fonts;
|
||||
FontPtr m_defaultFont;
|
||||
};
|
||||
|
||||
extern Fonts g_fonts;
|
||||
|
|
|
@ -40,6 +40,7 @@ void Graphics::init()
|
|||
glEnable(GL_TEXTURE_2D); // enable textures by default
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
|
@ -266,7 +267,7 @@ void Graphics::bindColor(const Color& color)
|
|||
void Graphics::bindTexture(const TexturePtr& texture, const Color& color)
|
||||
{
|
||||
// switch drawing to textured quads
|
||||
if(m_drawMode != DRAW_TEXTURE_QUADS || m_bindedTexture != texture) {
|
||||
if(m_drawMode != DRAW_TEXTURE_QUADS || m_bindedTexture != texture || m_bindedColor != color) {
|
||||
if(m_drawMode != DRAW_NONE)
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
class Graphics
|
||||
{
|
||||
enum EDrawMode {
|
||||
enum DrawMode {
|
||||
DRAW_NONE = 0,
|
||||
DRAW_QUADS = 1,
|
||||
DRAW_TEXTURE = 2,
|
||||
|
@ -80,8 +80,7 @@ private:
|
|||
TexturePtr m_bindedTexture;
|
||||
Color m_bindedColor;
|
||||
Size m_screenSize;
|
||||
EDrawMode m_drawMode;
|
||||
EDrawMode m_lastDrawMode;
|
||||
DrawMode m_drawMode;
|
||||
};
|
||||
|
||||
extern Graphics g_graphics;
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
#include <graphics/graphics.h>
|
||||
|
||||
TextArea::TextArea() :
|
||||
m_font(0),
|
||||
m_align(ALIGN_TOP_LEFT),
|
||||
m_align(AlignLeftCenter),
|
||||
m_color(Color::white),
|
||||
m_cursorPos(-1),
|
||||
m_startRenderPos(0),
|
||||
|
@ -37,10 +36,10 @@ TextArea::TextArea() :
|
|||
{
|
||||
}
|
||||
|
||||
TextArea::TextArea(Font* font,
|
||||
TextArea::TextArea(FontPtr font,
|
||||
const std::string& text,
|
||||
const Rect& screenCoords,
|
||||
int align,
|
||||
AlignmentFlag align,
|
||||
const Color& color) :
|
||||
m_font(font),
|
||||
m_text(text),
|
||||
|
@ -165,19 +164,19 @@ void TextArea::recalculate()
|
|||
Rect glyphTextureCoords = glyphsTextureCoords[glyph];
|
||||
|
||||
// first translate to align position
|
||||
if(m_align & ALIGN_BOTTOM) {
|
||||
if(m_align & AlignBottom) {
|
||||
glyphScreenCoords.translate(0, m_screenCoords.height() - textBoxSize.height());
|
||||
} else if(m_align & ALIGN_VERTICAL_CENTER) {
|
||||
} else if(m_align & AlignVerticalCenter) {
|
||||
glyphScreenCoords.translate(0, (m_screenCoords.height() - textBoxSize.height()) / 2);
|
||||
} else { // ALIGN_TOP
|
||||
} else { // AlignTop
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
if(m_align & ALIGN_RIGHT) {
|
||||
if(m_align & AlignRight) {
|
||||
glyphScreenCoords.translate(m_screenCoords.width() - textBoxSize.width(), 0);
|
||||
} else if(m_align & ALIGN_HORIZONTAL_CENTER) {
|
||||
} else if(m_align & AlignHorizontalCenter) {
|
||||
glyphScreenCoords.translate((m_screenCoords.width() - textBoxSize.width()) / 2, 0);
|
||||
} else { // ALIGN_TOP
|
||||
} else { // AlignLeft
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
|
@ -221,7 +220,7 @@ void TextArea::recalculate()
|
|||
}
|
||||
}
|
||||
|
||||
void TextArea::setFont(Font* font)
|
||||
void TextArea::setFont(FontPtr font)
|
||||
{
|
||||
if(m_font != font) {
|
||||
m_font = font;
|
||||
|
@ -249,7 +248,7 @@ void TextArea::setScreenCoords(const Rect& screenCoords)
|
|||
}
|
||||
}
|
||||
|
||||
void TextArea::setAlign(int align)
|
||||
void TextArea::setAlign(AlignmentFlag align)
|
||||
{
|
||||
if(m_align != align) {
|
||||
m_align = align;
|
||||
|
|
|
@ -32,18 +32,18 @@ class TextArea
|
|||
{
|
||||
public:
|
||||
TextArea();
|
||||
TextArea(Font *font,
|
||||
TextArea(FontPtr font,
|
||||
const std::string& text,
|
||||
const Rect& screenCoords,
|
||||
int align = ALIGN_TOP_LEFT,
|
||||
AlignmentFlag align = AlignTopLeft,
|
||||
const Color& color = Color::white);
|
||||
|
||||
void draw();
|
||||
|
||||
void setFont(Font *font);
|
||||
void setFont(FontPtr font);
|
||||
void setText(const std::string& text);
|
||||
void setScreenCoords(const Rect& screenCoords);
|
||||
void setAlign(int align);
|
||||
void setAlign(AlignmentFlag align);
|
||||
void setColor(const Color& color) { m_color = color; }
|
||||
void setCursorPos(int pos);
|
||||
void enableCursor(bool enable = true);
|
||||
|
@ -55,17 +55,17 @@ public:
|
|||
|
||||
std::string getText() const { return m_text; }
|
||||
|
||||
Font *getFont() const { return m_font; }
|
||||
FontPtr getFont() const { return m_font; }
|
||||
int getTextPos(Point pos);
|
||||
|
||||
private:
|
||||
void recalculate();
|
||||
|
||||
Font *m_font;
|
||||
FontPtr m_font;
|
||||
std::string m_text;
|
||||
Rect m_screenCoords;
|
||||
Rect m_drawArea;
|
||||
int m_align;
|
||||
AlignmentFlag m_align;
|
||||
Color m_color;
|
||||
int m_cursorPos;
|
||||
Point m_startInternalPos;
|
||||
|
|
|
@ -45,7 +45,7 @@ void Connection::connect(const std::string& host, uint16 port, const SimpleCallb
|
|||
m_connectCallback = callback;
|
||||
m_connectionState = CONNECTION_STATE_RESOLVING;
|
||||
|
||||
boost::asio::ip::tcp::resolver::query query(host, convertType<std::string, uint16>(port));
|
||||
boost::asio::ip::tcp::resolver::query query(host, convert_cast<std::string>(port));
|
||||
m_resolver.async_resolve(query, boost::bind(&Connection::onResolve, this, boost::asio::placeholders::error, boost::asio::placeholders::iterator));
|
||||
|
||||
m_timer.expires_from_now(boost::posix_time::seconds(2));
|
||||
|
|
|
@ -74,8 +74,8 @@ typedef int8_t int8;
|
|||
|
||||
typedef boost::function<void()> SimpleCallback;
|
||||
|
||||
// yaml
|
||||
#include <yaml-cpp/yaml.h>
|
||||
// constants
|
||||
#include <constants.h>
|
||||
|
||||
// common utilities
|
||||
#include <util/util.h>
|
||||
|
@ -84,5 +84,6 @@ typedef boost::function<void()> SimpleCallback;
|
|||
#include <util/point.h>
|
||||
#include <util/size.h>
|
||||
#include <util/rect.h>
|
||||
#include <util/yaml.h>
|
||||
|
||||
#endif // PREREQUISITES_H
|
||||
|
|
|
@ -187,7 +187,7 @@ void LuaScript::setMetatable(const std::string& name, int index)
|
|||
{
|
||||
luaL_getmetatable(L, name.c_str());
|
||||
if(isNil())
|
||||
reportError(f("could not retrive metatable %d", name));
|
||||
reportError(fmt("could not retrive metatable %d", name));
|
||||
else
|
||||
lua_setmetatable(L, index < 0 ? index-1 : index);
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ void Scriptable::callLuaTableField(const std::string& field)
|
|||
g_lua.pop();
|
||||
}
|
||||
} else if(!g_lua.isNil()) {
|
||||
g_lua.reportError(f("field '%s' for '%s' is not a valid function or array of functions", field % getScriptableName()));
|
||||
g_lua.reportError(fmt("field '%s' for '%s' is not a valid function or array of functions", field % getScriptableName()));
|
||||
}
|
||||
|
||||
// release self
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <prerequisites.h>
|
||||
#include <core/dispatcher.h>
|
||||
#include <ui/uibutton.h>
|
||||
#include "uicontainer.h"
|
||||
|
||||
void UIButton::onInputEvent(const InputEvent& event)
|
||||
{
|
||||
|
@ -35,5 +36,10 @@ void UIButton::onInputEvent(const InputEvent& event)
|
|||
if(getRect().contains(event.mousePos)) {
|
||||
g_dispatcher.addTask(boost::bind(&Scriptable::callLuaTableField, shared_from_this(), "onClick"));
|
||||
}
|
||||
} else if(event.type == EV_MOUSE_MOVE && m_state != ButtonDown) {
|
||||
if(getRect().contains(event.mousePos) && UIContainer::getRoot()->recursiveGetChildByPos(event.mousePos) == asUIElement())
|
||||
m_state = ButtonMouseOver;
|
||||
else
|
||||
m_state = ButtonUp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,17 +31,21 @@ void UIButtonSkin::load(const YAML::Node& node)
|
|||
{
|
||||
UIElementSkin::load(node);
|
||||
|
||||
m_buttonDownImage = loadImage(node["down state"]);
|
||||
m_buttonDownTextColor = getFontColor();
|
||||
m_buttonHoverTextColor = getFontColor();
|
||||
|
||||
if(node["down state"].FindValue("text translate"))
|
||||
node["down state"]["text translate"] >> m_buttonDownTranslate;
|
||||
if(yamlHasValue(node, "down state")) {
|
||||
const YAML::Node& cnode = node["down state"];
|
||||
m_buttonDownImage = loadImage(cnode);
|
||||
m_buttonDownTranslate = yamlRead(cnode, "text translate", Point());
|
||||
m_buttonDownTextColor = yamlRead(cnode, "font color", getFontColor());
|
||||
}
|
||||
|
||||
if(node.FindValue("mouse over state"))
|
||||
m_buttonHoverImage = loadImage(node["mouse over state"]);
|
||||
|
||||
m_font = g_fonts.get(node["font"].Read<std::string>());
|
||||
|
||||
node["text color"] >> m_textColor;
|
||||
if(yamlHasValue(node, "hover state")) {
|
||||
const YAML::Node& cnode = node["hover state"];
|
||||
m_buttonHoverImage = loadImage(cnode);
|
||||
m_buttonHoverTextColor = yamlRead(cnode, "font color", getFontColor());
|
||||
}
|
||||
}
|
||||
|
||||
void UIButtonSkin::draw(UIElement *element)
|
||||
|
@ -59,5 +63,10 @@ void UIButtonSkin::draw(UIElement *element)
|
|||
UIElementSkin::draw(element);
|
||||
}
|
||||
|
||||
m_font->renderText(button->getText(), textRect, ALIGN_CENTER, m_textColor);
|
||||
Color textColor = getFontColor();
|
||||
if(button->getState() == UIButton::ButtonDown)
|
||||
textColor = m_buttonDownTextColor;
|
||||
else if(button->getState() == UIButton::ButtonMouseOver)
|
||||
textColor = m_buttonHoverTextColor;
|
||||
getFont()->renderText(button->getText(), textRect, AlignCenter, textColor);
|
||||
}
|
||||
|
|
|
@ -44,8 +44,8 @@ private:
|
|||
ImagePtr m_buttonDownImage;
|
||||
ImagePtr m_buttonHoverImage;
|
||||
Point m_buttonDownTranslate;
|
||||
Font *m_font;
|
||||
Color m_textColor;
|
||||
Color m_buttonDownTextColor;
|
||||
Color m_buttonHoverTextColor;
|
||||
};
|
||||
|
||||
#endif // UIBUTTONSKIN_H
|
||||
|
|
|
@ -106,17 +106,6 @@ UIElementPtr UIContainer::getChildById(const std::string& id)
|
|||
return UIElementPtr();
|
||||
}
|
||||
|
||||
UIElementPtr UIContainer::getChildByPos(const Point& pos)
|
||||
{
|
||||
for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) {
|
||||
const UIElementPtr& element = (*it);
|
||||
if(element->getRect().contains(pos))
|
||||
return element;
|
||||
}
|
||||
|
||||
return UIElementPtr();
|
||||
}
|
||||
|
||||
UIElementPtr UIContainer::recursiveGetChildById(const std::string& id)
|
||||
{
|
||||
if(getId() == id || id == "self")
|
||||
|
@ -144,6 +133,35 @@ UIElementPtr UIContainer::recursiveGetChildById(const std::string& id)
|
|||
return UIElementPtr();
|
||||
}
|
||||
|
||||
UIElementPtr UIContainer::getChildByPos(const Point& pos)
|
||||
{
|
||||
for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) {
|
||||
const UIElementPtr& element = (*it);
|
||||
if(element->getRect().contains(pos))
|
||||
return element;
|
||||
}
|
||||
|
||||
return UIElementPtr();
|
||||
}
|
||||
|
||||
UIElementPtr UIContainer::recursiveGetChildByPos(const Point& pos)
|
||||
{
|
||||
for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) {
|
||||
const UIElementPtr& element = (*it);
|
||||
if(element->getRect().contains(pos)) {
|
||||
if(UIContainerPtr container = element->asUIContainer()) {
|
||||
if(UIElementPtr containerChild = container->recursiveGetChildByPos(pos))
|
||||
return containerChild;
|
||||
else
|
||||
return container;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
return UIElementPtr();
|
||||
}
|
||||
|
||||
void UIContainer::pushChildToTop(const UIElementPtr& child)
|
||||
{
|
||||
auto it = std::find(m_children.begin(), m_children.end(), child);
|
||||
|
@ -227,12 +245,13 @@ void UIContainer::focusNextElement()
|
|||
void UIContainer::setFocusedElement(const UIElementPtr& focusedElement)
|
||||
{
|
||||
if(focusedElement != m_focusedElement) {
|
||||
if(m_focusedElement)
|
||||
m_focusedElement->onFocusChange();
|
||||
|
||||
UIElementPtr oldFocused = m_focusedElement;
|
||||
m_focusedElement = focusedElement;
|
||||
if(m_focusedElement)
|
||||
m_focusedElement->onFocusChange();
|
||||
|
||||
if(oldFocused)
|
||||
oldFocused->onFocusChange();
|
||||
if(focusedElement)
|
||||
focusedElement->onFocusChange();
|
||||
}
|
||||
|
||||
// when containers are focused they go to the top
|
||||
|
|
|
@ -48,10 +48,12 @@ public:
|
|||
bool hasChild(const UIElementPtr& child);
|
||||
/// Find an element in this container by id
|
||||
UIElementPtr getChildById(const std::string& id);
|
||||
/// Find an element by position
|
||||
UIElementPtr getChildByPos(const Point& pos);
|
||||
/// Find an element in this container and in its children by id
|
||||
UIElementPtr recursiveGetChildById(const std::string& id);
|
||||
/// Find an element by position
|
||||
UIElementPtr getChildByPos(const Point& pos);
|
||||
/// Find an element in this container and in its children by position
|
||||
UIElementPtr recursiveGetChildByPos(const Point& pos);
|
||||
/// Get children
|
||||
const std::list<UIElementPtr>& getChildren() const { return m_children; }
|
||||
/// Pushs a child to the top
|
||||
|
|
|
@ -28,12 +28,14 @@
|
|||
#include <ui/uielementskin.h>
|
||||
#include <graphics/borderedimage.h>
|
||||
#include <graphics/textures.h>
|
||||
#include <graphics/fonts.h>
|
||||
|
||||
void UIElementSkin::load(const YAML::Node& node)
|
||||
{
|
||||
if(node.FindValue("default size"))
|
||||
node["default size"] >> m_defaultSize;
|
||||
m_defaultSize = yamlRead(node, "default size", Size());
|
||||
m_defaultImage = loadImage(node);
|
||||
m_font = loadFont(node);
|
||||
m_fontColor = yamlRead(node, "font color", g_uiSkins.getDefaultFontColor());
|
||||
}
|
||||
|
||||
void UIElementSkin::apply(UIElement* element)
|
||||
|
@ -47,40 +49,29 @@ void UIElementSkin::draw(UIElement *element)
|
|||
if(m_defaultImage)
|
||||
m_defaultImage->draw(element->getRect());
|
||||
}
|
||||
|
||||
ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
|
||||
{
|
||||
ImagePtr image;
|
||||
TexturePtr texture;
|
||||
|
||||
if(node.FindValue("bordered image")) {
|
||||
const YAML::Node& child = node["bordered image"];
|
||||
Rect left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight, center;
|
||||
if(child.FindValue("left border"))
|
||||
child["left border"] >> left;
|
||||
if(child.FindValue("right border"))
|
||||
child["right border"] >> right;
|
||||
if(child.FindValue("top border"))
|
||||
child["top border"] >> top;
|
||||
if(child.FindValue("bottom border"))
|
||||
child["bottom border"] >> bottom;
|
||||
if(child.FindValue("top left corner"))
|
||||
child["top left corner"] >> topLeft;
|
||||
if(child.FindValue("top right corner"))
|
||||
child["top right corner"] >> topRight;
|
||||
if(child.FindValue("bottom left corner"))
|
||||
child["bottom left corner"] >> bottomLeft;
|
||||
if(child.FindValue("bottom right corner"))
|
||||
child["bottom right corner"] >> bottomRight;
|
||||
if(child.FindValue("center"))
|
||||
child["center"] >> center;
|
||||
if(yamlHasValue(node, "bordered image")) {
|
||||
const YAML::Node& cnode = node["bordered image"];
|
||||
Rect left = yamlRead(cnode, "left border", Rect());
|
||||
Rect right = yamlRead(cnode, "right border", Rect());
|
||||
Rect top = yamlRead(cnode, "top border", Rect());
|
||||
Rect bottom = yamlRead(cnode, "bottom border", Rect());
|
||||
Rect topLeft = yamlRead(cnode, "top left corner", Rect());
|
||||
Rect topRight = yamlRead(cnode, "top right corner", Rect());
|
||||
Rect bottomLeft = yamlRead(cnode, "bottom left corner", Rect());
|
||||
Rect bottomRight = yamlRead(cnode, "bottom right corner", Rect());
|
||||
Rect center = yamlRead(cnode, "center", Rect());
|
||||
std::string textureName = yamlRead(cnode, "source", std::string());
|
||||
|
||||
if(child.FindValue("image")) {
|
||||
std::string textureName;
|
||||
child["image"] >> textureName;
|
||||
texture = g_textures.get(textureName);
|
||||
} else {
|
||||
if(!textureName.empty())
|
||||
texture = g_textures.get("skins/" + textureName);
|
||||
else
|
||||
texture = g_uiSkins.getDefaultTexture();
|
||||
}
|
||||
|
||||
if(texture) {
|
||||
image = ImagePtr(new BorderedImage(texture,
|
||||
|
@ -94,18 +85,20 @@ ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
|
|||
bottomRight,
|
||||
center));
|
||||
}
|
||||
} else if(node.FindValue("image")) {
|
||||
std::string textureName;
|
||||
node["image"] >> textureName;
|
||||
texture = g_textures.get(textureName);
|
||||
if(texture) {
|
||||
|
||||
if(!image)
|
||||
logError(yamlErrorDesc(cnode, "failed to load bordered image"));
|
||||
} else if(yamlHasValue(node, "image")) {
|
||||
texture = g_textures.get("skins/" + yamlRead<std::string>(node, "image"));
|
||||
if(texture)
|
||||
image = ImagePtr(new Image(texture));
|
||||
}
|
||||
|
||||
if(!image)
|
||||
logError(yamlErrorDesc(node["image"], "failed to load image"));
|
||||
}
|
||||
|
||||
if(texture && node.FindValue("antialised")){
|
||||
bool antialised;
|
||||
node["antialised"] >> antialised;
|
||||
if(texture) {
|
||||
bool antialised = yamlRead(node, "antialised", false);
|
||||
if(antialised)
|
||||
texture->enableBilinearFilter();
|
||||
}
|
||||
|
@ -113,3 +106,14 @@ ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
|
|||
return image;
|
||||
}
|
||||
|
||||
FontPtr UIElementSkin::loadFont(const YAML::Node& node)
|
||||
{
|
||||
FontPtr font;
|
||||
if(yamlHasValue(node, "font"))
|
||||
font = g_fonts.get(yamlRead<std::string>(node, "font"));
|
||||
if(!font)
|
||||
font = g_uiSkins.getDefaultFont();
|
||||
return font;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <prerequisites.h>
|
||||
#include <graphics/image.h>
|
||||
#include <ui/uiconstants.h>
|
||||
#include <graphics/font.h>
|
||||
|
||||
class UIElement;
|
||||
|
||||
|
@ -51,15 +52,20 @@ public:
|
|||
const Size& getDefaultSize() const { return m_defaultSize; }
|
||||
UI::ElementType getElementType() const { return m_elementType; }
|
||||
ImagePtr getDefaultImage() const { return m_defaultImage; }
|
||||
FontPtr getFont() const { return m_font; }
|
||||
Color getFontColor() const { return m_fontColor; }
|
||||
|
||||
protected:
|
||||
ImagePtr loadImage(const YAML::Node& node);
|
||||
FontPtr loadFont(const YAML::Node &node);
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
UI::ElementType m_elementType;
|
||||
Size m_defaultSize;
|
||||
ImagePtr m_defaultImage;
|
||||
FontPtr m_font;
|
||||
Color m_fontColor;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<UIElementSkin> UIElementSkinPtr;
|
||||
|
|
|
@ -34,20 +34,20 @@ class UILabel : public UIElement
|
|||
public:
|
||||
UILabel() :
|
||||
UIElement(UI::Label),
|
||||
m_align(ALIGN_TOP_LEFT),
|
||||
m_align(AlignTopLeft),
|
||||
m_color(Color::white) { }
|
||||
|
||||
void setText(const std::string& text);
|
||||
std::string getText() const { return m_text; }
|
||||
|
||||
void setAlign(int align) { m_align = align; }
|
||||
int getAlign() const { return m_align; }
|
||||
void setAlign(AlignmentFlag align) { m_align = align; }
|
||||
AlignmentFlag getAlign() const { return m_align; }
|
||||
|
||||
virtual const char *getScriptableName() const { return "UILabel"; }
|
||||
|
||||
private:
|
||||
std::string m_text;
|
||||
int m_align;
|
||||
AlignmentFlag m_align;
|
||||
Color m_color;
|
||||
};
|
||||
|
||||
|
|
|
@ -30,28 +30,18 @@
|
|||
void UILabelSkin::load(const YAML::Node& node)
|
||||
{
|
||||
UIElementSkin::load(node);
|
||||
|
||||
if(node.FindValue("font"))
|
||||
m_font = g_fonts.get(node["font"].Read<std::string>());
|
||||
else
|
||||
m_font = g_fonts.getDefaultFont();
|
||||
|
||||
if(node.FindValue("text color"))
|
||||
node["text color"] >> m_textColor;
|
||||
else
|
||||
m_textColor = Color::white;
|
||||
}
|
||||
|
||||
void UILabelSkin::apply(UIElement* element)
|
||||
{
|
||||
UIElementSkin::apply(element);
|
||||
UILabel *label = static_cast<UILabel*>(element);
|
||||
label->setSize(m_font->calculateTextRectSize(label->getText()));
|
||||
label->setSize(getFont()->calculateTextRectSize(label->getText()));
|
||||
}
|
||||
|
||||
void UILabelSkin::draw(UIElement *element)
|
||||
{
|
||||
UIElementSkin::draw(element);
|
||||
UILabel *label = static_cast<UILabel*>(element);
|
||||
m_font->renderText(label->getText(), label->getRect(), label->getAlign(), m_textColor);
|
||||
getFont()->renderText(label->getText(), label->getRect(), label->getAlign(), getFontColor());
|
||||
}
|
||||
|
|
|
@ -33,19 +33,11 @@ class UILabelSkin : public UIElementSkin
|
|||
{
|
||||
public:
|
||||
UILabelSkin(const std::string& name) :
|
||||
UIElementSkin(name, UI::Label),
|
||||
m_align(ALIGN_TOP_LEFT) { }
|
||||
UIElementSkin(name, UI::Label) { }
|
||||
|
||||
void load(const YAML::Node& node);
|
||||
void apply(UIElement *element);
|
||||
void draw(UIElement *element);
|
||||
|
||||
Font *getFont() const { return m_font; }
|
||||
|
||||
private:
|
||||
Font *m_font;
|
||||
int m_align;
|
||||
Color m_textColor;
|
||||
};
|
||||
|
||||
#endif // UILABELSKIN_H
|
||||
|
|
|
@ -96,7 +96,7 @@ UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& p
|
|||
// create element interpreting it's id
|
||||
UIElementPtr element = createElementFromId(elementId);
|
||||
if(!element)
|
||||
throw YAML::Exception(doc.begin().first().GetMark(), "invalid element type");
|
||||
yamlThrowError(doc.begin().first(), "invalid element type");
|
||||
parent->addChild(element);
|
||||
|
||||
// populete it
|
||||
|
@ -136,7 +136,7 @@ void UILoader::populateContainer(const UIContainerPtr& parent, const YAML::Node&
|
|||
|
||||
UIElementPtr element = createElementFromId(id);
|
||||
if(!element) {
|
||||
logError(YAML::Exception(cnode.GetMark(), "invalid element type").what());
|
||||
logError(yamlErrorDesc(cnode, "invalid element type"));
|
||||
continue;
|
||||
}
|
||||
parent->addChild(element);
|
||||
|
@ -167,78 +167,59 @@ void UILoader::loadElements(const UIElementPtr& parent, const YAML::Node& node)
|
|||
void UILoader::loadElement(const UIElementPtr& element, const YAML::Node& node)
|
||||
{
|
||||
// set element skin
|
||||
if(node.FindValue("skin")) {
|
||||
if(node["skin"].GetType() == YAML::CT_SCALAR) {
|
||||
element->setSkin(g_uiSkins.getElementSkin(element->getElementType(), node["skin"]));
|
||||
if(yamlHasValue(node, "skin")) {
|
||||
const YAML::Node& cnode = node["skin"];
|
||||
if(cnode.GetType() == YAML::CT_SCALAR) {
|
||||
element->setSkin(g_uiSkins.getElementSkin(element->getElementType(), cnode));
|
||||
} else {
|
||||
UIElementSkinPtr skin = UIElementSkinPtr(new UIElementSkin());
|
||||
skin->load(node["skin"]);
|
||||
skin->load(cnode);
|
||||
element->setSkin(skin);
|
||||
}
|
||||
} else // apply default skin
|
||||
element->setSkin(g_uiSkins.getElementSkin(element->getElementType(), "default"));
|
||||
|
||||
// load elements common proprieties
|
||||
if(node.FindValue("size")) {
|
||||
Size size;
|
||||
node["size"] >> size;
|
||||
element->setSize(size);
|
||||
}
|
||||
if(yamlHasValue(node, "size"))
|
||||
element->setSize(yamlRead<Size>(node, "size"));
|
||||
element->setMarginLeft(yamlRead(node, "margin.left", 0));
|
||||
element->setMarginRight(yamlRead(node, "margin.right", 0));
|
||||
element->setMarginTop(yamlRead(node, "margin.top", 0));
|
||||
element->setMarginBottom(yamlRead(node, "margin.bottom", 0));
|
||||
|
||||
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"))
|
||||
if(yamlHasValue(node, "anchors.left"))
|
||||
loadElementAnchor(element, UI::AnchorLeft, node["anchors.left"]);
|
||||
|
||||
if(node.FindValue("anchors.right"))
|
||||
if(yamlHasValue(node, "anchors.right"))
|
||||
loadElementAnchor(element, UI::AnchorRight, node["anchors.right"]);
|
||||
|
||||
if(node.FindValue("anchors.top"))
|
||||
if(yamlHasValue(node, "anchors.top"))
|
||||
loadElementAnchor(element, UI::AnchorTop, node["anchors.top"]);
|
||||
|
||||
if(node.FindValue("anchors.bottom"))
|
||||
if(yamlHasValue(node, "anchors.bottom"))
|
||||
loadElementAnchor(element, UI::AnchorBottom, node["anchors.bottom"]);
|
||||
|
||||
if(node.FindValue("anchors.horizontalCenter"))
|
||||
if(yamlHasValue(node, "anchors.horizontalCenter"))
|
||||
loadElementAnchor(element, UI::AnchorHorizontalCenter, node["anchors.horizontalCenter"]);
|
||||
|
||||
if(node.FindValue("anchors.verticalCenter"))
|
||||
if(yamlHasValue(node, "anchors.verticalCenter"))
|
||||
loadElementAnchor(element, UI::AnchorVerticalCenter, node["anchors.verticalCenter"]);
|
||||
|
||||
// load events
|
||||
if(node.FindValue("onLoad")) {
|
||||
if(yamlHasValue(node, "onLoad")) {
|
||||
const YAML::Node& cnode = node["onLoad"];
|
||||
if(g_lua.loadBufferAsFunction(cnode.Read<std::string>(), element->getId() + ":onLoad"))
|
||||
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), element->getId() + ":onLoad"))
|
||||
g_lua.setScriptableField(element, "onLoad");
|
||||
else
|
||||
logError(YAML::Exception(cnode.GetMark(), "failed to parse inline lua script").what());
|
||||
logError(yamlErrorDesc(cnode, "failed to parse inline lua script"));
|
||||
}
|
||||
|
||||
if(node.FindValue("onDestroy")) {
|
||||
if(yamlHasValue(node, "onDestroy")) {
|
||||
const YAML::Node& cnode = node["onDestroy"];
|
||||
if(g_lua.loadBufferAsFunction(cnode.Read<std::string>(), element->getId() + ":onDestroy"))
|
||||
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), element->getId() + ":onDestroy"))
|
||||
g_lua.setScriptableField(element, "onDestroy");
|
||||
else
|
||||
logError(YAML::Exception(cnode.GetMark(), "failed to parse inline lua script").what());
|
||||
logError(yamlErrorDesc(cnode, "failed to parse inline lua script"));
|
||||
}
|
||||
|
||||
// load specific element type
|
||||
|
@ -246,19 +227,12 @@ void UILoader::loadElement(const UIElementPtr& element, const YAML::Node& node)
|
|||
loadButton(boost::static_pointer_cast<UIButton>(element), node);
|
||||
else if(element->getElementType() == UI::Window) {
|
||||
UIWindowPtr window = boost::static_pointer_cast<UIWindow>(element);
|
||||
if(node.FindValue("title"))
|
||||
window->setTitle(node["title"].Read<std::string>());
|
||||
window->setTitle(yamlRead(node, "title", std::string()));
|
||||
}
|
||||
else if(element->getElementType() == UI::Label) {
|
||||
UILabelPtr label = boost::static_pointer_cast<UILabel>(element);
|
||||
if(node.FindValue("text"))
|
||||
label->setText(node["text"].Read<std::string>());
|
||||
if(node.FindValue("align")) {
|
||||
std::string alignDesc;
|
||||
node["align"] >> alignDesc;
|
||||
if(alignDesc == "center")
|
||||
label->setAlign(ALIGN_CENTER);
|
||||
}
|
||||
label->setText(yamlRead(node, "text", std::string()));
|
||||
label->setAlign(parseAlignment(yamlRead(node, "align", std::string())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,7 +240,7 @@ void UILoader::loadElementAnchor(const UIElementPtr& anchoredElement, UI::Anchor
|
|||
{
|
||||
UIAnchorLayoutPtr layout = boost::dynamic_pointer_cast<UIAnchorLayout>(anchoredElement->getLayout());
|
||||
if(!layout) {
|
||||
logError(YAML::Exception(node.GetMark(), "could not add anchor, because this element does not participate of an anchor layout").what());
|
||||
logError(yamlErrorDesc(node, "could not add anchor, because this element does not participate of an anchor layout"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -276,7 +250,7 @@ void UILoader::loadElementAnchor(const UIElementPtr& anchoredElement, UI::Anchor
|
|||
std::vector<std::string> split;
|
||||
boost::split(split, anchorDescription, boost::is_any_of(std::string(".")));
|
||||
if(split.size() != 2) {
|
||||
logError(YAML::Exception(node.GetMark(), "invalid anchor").what());
|
||||
logError(yamlErrorDesc(node, "invalid anchor"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -284,12 +258,12 @@ void UILoader::loadElementAnchor(const UIElementPtr& anchoredElement, UI::Anchor
|
|||
UI::AnchorPoint anchorLineEdge = UIAnchorLayout::parseAnchorPoint(split[1]);
|
||||
|
||||
if(anchorLineEdge == UI::AnchorNone) {
|
||||
logError(YAML::Exception(node.GetMark(), "invalid anchor type").what());
|
||||
logError(yamlErrorDesc(node, "invalid anchor type"));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!layout->addAnchor(anchoredElement, anchoredEdge, AnchorLine(anchorLineElementId, anchorLineEdge)))
|
||||
logError(YAML::Exception(node.GetMark(), "anchoring failed").what());
|
||||
logError(yamlErrorDesc(node, "anchoring failed"));
|
||||
}
|
||||
|
||||
void UILoader::loadButton(const UIButtonPtr& button, const YAML::Node& node)
|
||||
|
@ -297,10 +271,11 @@ void UILoader::loadButton(const UIButtonPtr& button, const YAML::Node& node)
|
|||
button->setText(node["text"].Read<std::string>());
|
||||
|
||||
// set on click event
|
||||
if(node.FindValue("onClick")) {
|
||||
if(g_lua.loadBufferAsFunction(node["onClick"].Read<std::string>(), button->getId() + ":onClick"))
|
||||
if(yamlHasValue(node, "onClick")) {
|
||||
const YAML::Node& cnode = node["onClick"];
|
||||
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), button->getId() + ":onClick"))
|
||||
g_lua.setScriptableField(button, "onClick");
|
||||
else
|
||||
logError(YAML::Exception(node["onClick"].GetMark(), "failed to parse inline lua script").what());
|
||||
logError(yamlErrorDesc(cnode, "failed to parse inline lua script"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <ui/uiwindowskin.h>
|
||||
#include <ui/uitexteditskin.h>
|
||||
#include <ui/uilabelskin.h>
|
||||
#include <graphics/fonts.h>
|
||||
|
||||
UISkins g_uiSkins;
|
||||
|
||||
|
@ -48,9 +49,15 @@ void UISkins::load(const std::string& skinsFile)
|
|||
YAML::Node doc;
|
||||
parser.GetNextDocument(doc);
|
||||
|
||||
std::string defaultTexture;
|
||||
doc["default skin image"] >> defaultTexture;
|
||||
m_defaultTexture = g_textures.get("skins/" + defaultTexture);
|
||||
m_defaultFont = g_fonts.get(yamlRead<std::string>(doc, "default font"));
|
||||
if(!m_defaultFont)
|
||||
logFatal("FATAL ERROR: Could not load skin default font");
|
||||
|
||||
m_defaultFontColor = yamlRead(doc, "default font color", Color::white);
|
||||
|
||||
std::string defaultTextureName = yamlRead(doc, "default texture", std::string());
|
||||
if(!defaultTextureName.empty())
|
||||
m_defaultTexture = g_textures.get("skins/" + defaultTextureName);
|
||||
|
||||
{
|
||||
const YAML::Node& node = doc["buttons"];
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <prerequisites.h>
|
||||
#include <graphics/texture.h>
|
||||
#include <ui/uielementskin.h>
|
||||
#include <graphics/font.h>
|
||||
|
||||
class UISkins
|
||||
{
|
||||
|
@ -39,9 +40,13 @@ public:
|
|||
|
||||
UIElementSkinPtr getElementSkin(UI::ElementType elementType, const std::string& name = "default");
|
||||
TexturePtr getDefaultTexture() { return m_defaultTexture; }
|
||||
FontPtr getDefaultFont() { return m_defaultFont; }
|
||||
Color getDefaultFontColor() { return m_defaultFontColor; }
|
||||
|
||||
private:
|
||||
TexturePtr m_defaultTexture;
|
||||
FontPtr m_defaultFont;
|
||||
Color m_defaultFontColor;
|
||||
|
||||
std::vector<UIElementSkinPtr> m_elementSkins;
|
||||
};
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
|
||||
#include <prerequisites.h>
|
||||
#include <graphics/fonts.h>
|
||||
#include <ui/uitextedit.h>
|
||||
#include <ui/uitexteditskin.h>
|
||||
#include <ui/uicontainer.h>
|
||||
|
|
|
@ -30,28 +30,15 @@
|
|||
void UITextEditSkin::load(const YAML::Node& node)
|
||||
{
|
||||
UIElementSkin::load(node);
|
||||
|
||||
if(node.FindValue("font")) {
|
||||
m_font = g_fonts.get(node["font"].Read<std::string>());
|
||||
} else
|
||||
m_font = g_fonts.getDefaultFont();
|
||||
|
||||
if(node.FindValue("text color"))
|
||||
node["text color"] >> m_textColor;
|
||||
else
|
||||
m_textColor = Color::white;
|
||||
|
||||
if(node.FindValue("text margin"))
|
||||
node["text margin"] >> m_textMargin;
|
||||
else
|
||||
m_textMargin = 2;
|
||||
m_textMargin = yamlRead(node, "text margin", 2);
|
||||
}
|
||||
|
||||
void UITextEditSkin::apply(UIElement* element)
|
||||
{
|
||||
UIElementSkin::apply(element);
|
||||
UITextEdit *textEdit = static_cast<UITextEdit*>(element);
|
||||
textEdit->getTextArea().setFont(m_font);
|
||||
textEdit->getTextArea().setFont(getFont());
|
||||
textEdit->getTextArea().setColor(getFontColor());
|
||||
}
|
||||
|
||||
void UITextEditSkin::draw(UIElement* element)
|
||||
|
|
|
@ -40,13 +40,10 @@ public:
|
|||
void apply(UIElement *element);
|
||||
void draw(UIElement *element);
|
||||
|
||||
Font *getFont() const { return m_font; }
|
||||
int getTextMargin() const { return m_textMargin; }
|
||||
|
||||
private:
|
||||
Font *m_font;
|
||||
int m_textMargin;
|
||||
Color m_textColor;
|
||||
};
|
||||
|
||||
#endif // UITEXTEDITSKIN_H
|
||||
|
|
|
@ -30,34 +30,36 @@ void UIWindowSkin::load(const YAML::Node& node)
|
|||
{
|
||||
UIElementSkin::load(node);
|
||||
|
||||
node["head"]["height"] >> m_headHeight;
|
||||
m_headImage = loadImage(node["head"]);
|
||||
m_bodyImage = loadImage(node["body"]);
|
||||
const YAML::Node& headNode = node["head"];
|
||||
const YAML::Node& bodyNode = node["body"];
|
||||
|
||||
std::string fontName;
|
||||
node["head"]["font"] >> fontName;
|
||||
m_titleFont = g_fonts.get(fontName);
|
||||
|
||||
node["head"]["text color"] >> m_headTextColor;
|
||||
m_headImage = boost::dynamic_pointer_cast<BorderedImage>(loadImage(headNode));
|
||||
m_headHeight = yamlRead(headNode, "height", m_headImage->getDefaultSize().height());
|
||||
m_headMargin = yamlRead(headNode, "margin", 0);
|
||||
m_titleAlign = parseAlignment(yamlRead(headNode, "text align", std::string("center")));
|
||||
m_bodyImage = loadImage(bodyNode);
|
||||
}
|
||||
|
||||
void UIWindowSkin::draw(UIElement* element)
|
||||
{
|
||||
UIElementSkin::draw(element);
|
||||
|
||||
UIWindow *window = static_cast<UIWindow*>(element);
|
||||
|
||||
// draw window head
|
||||
Rect headRect = window->getRect();
|
||||
Rect bodyRect = window->getRect();
|
||||
|
||||
headRect.setHeight(m_headHeight);
|
||||
bodyRect.setTop(headRect.bottom() + 1);
|
||||
|
||||
m_headImage->draw(headRect);
|
||||
m_titleFont->renderText(window->getTitle(),
|
||||
headRect,
|
||||
ALIGN_CENTER,
|
||||
m_headTextColor);
|
||||
|
||||
// draw window head text
|
||||
Rect headTextRect = headRect;
|
||||
if(m_titleAlign & AlignLeft)
|
||||
headTextRect.addLeft(-m_headMargin);
|
||||
else if(m_titleAlign & AlignRight)
|
||||
headTextRect.addRight(-m_headMargin);
|
||||
getFont()->renderText(window->getTitle(), headTextRect, m_titleAlign, getFontColor());
|
||||
|
||||
// draw window body
|
||||
Rect bodyRect = window->getRect();
|
||||
bodyRect.setTop(headRect.bottom() + 1);
|
||||
m_bodyImage->draw(bodyRect);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <prerequisites.h>
|
||||
#include <graphics/font.h>
|
||||
#include <ui/uielementskin.h>
|
||||
#include <graphics/borderedimage.h>
|
||||
|
||||
class UIWindowSkin : public UIElementSkin
|
||||
{
|
||||
|
@ -40,11 +41,12 @@ public:
|
|||
int getHeadHeight() const { return m_headHeight; }
|
||||
|
||||
private:
|
||||
ImagePtr m_headImage;
|
||||
BorderedImagePtr m_headImage;
|
||||
ImagePtr m_bodyImage;
|
||||
Font *m_titleFont;
|
||||
FontPtr m_titleFont;
|
||||
int m_headHeight;
|
||||
Color m_headTextColor;
|
||||
int m_headMargin;
|
||||
AlignmentFlag m_titleAlign;
|
||||
};
|
||||
|
||||
#endif // UIWINDOWSKIN_H
|
||||
|
|
|
@ -67,16 +67,6 @@ private:
|
|||
RGBA color;
|
||||
};
|
||||
|
||||
inline void operator>>(const YAML::Node& node, Color& color)
|
||||
{
|
||||
int r, g, b, a;
|
||||
node[0] >> r;
|
||||
node[1] >> g;
|
||||
node[2] >> b;
|
||||
node[3] >> a;
|
||||
color.setRGBA(r,g,b,a);
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const Color& color)
|
||||
{
|
||||
out << "Color(" << (int)color.r() << ","
|
||||
|
|
|
@ -77,13 +77,6 @@ public:
|
|||
typedef TPoint<int> Point;
|
||||
typedef TPoint<float> PointF;
|
||||
|
||||
template <class T>
|
||||
inline void operator>>(const YAML::Node& node, TPoint<T>& point)
|
||||
{
|
||||
node[0] >> point.x;
|
||||
node[1] >> point.y;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline std::ostream& operator<<(std::ostream& out, const TPoint<T>& point)
|
||||
{
|
||||
|
|
|
@ -299,17 +299,6 @@ private:
|
|||
typedef TRect<int> Rect;
|
||||
typedef TRect<float> RectF;
|
||||
|
||||
template <class T>
|
||||
inline void operator>>(const YAML::Node& node, TRect<T>& rect)
|
||||
{
|
||||
T x, y, width, height;
|
||||
node[0] >> x;
|
||||
node[1] >> y;
|
||||
node[2] >> width;
|
||||
node[3] >> height;
|
||||
rect.setRect(x, y, width, height);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline std::ostream& operator<<(std::ostream& out, const TRect<T>& rect)
|
||||
{
|
||||
|
|
|
@ -111,15 +111,6 @@ private:
|
|||
typedef TSize<int> Size;
|
||||
typedef TSize<float> SizeF;
|
||||
|
||||
template <class T>
|
||||
inline void operator>>(const YAML::Node& node, TSize<T>& size)
|
||||
{
|
||||
T w, h;
|
||||
node[0] >> w;
|
||||
node[1] >> h;
|
||||
size.setSize(w, h);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline std::ostream& operator<<(std::ostream& out, const TSize<T>& size)
|
||||
{
|
||||
|
|
|
@ -22,4 +22,28 @@
|
|||
*/
|
||||
|
||||
#include <util/util.h>
|
||||
#include <cstdio>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
AlignmentFlag parseAlignment(std::string aligment)
|
||||
{
|
||||
boost::to_lower(aligment);
|
||||
boost::erase_all(aligment, " ");
|
||||
if(aligment == "topleft")
|
||||
return AlignTopLeft;
|
||||
else if(aligment == "topright")
|
||||
return AlignTopRight;
|
||||
else if(aligment == "bottomleft")
|
||||
return AlignBottomLeft;
|
||||
else if(aligment == "bottomright")
|
||||
return AlignBottomRight;
|
||||
else if(aligment == "left")
|
||||
return AlignLeftCenter;
|
||||
else if(aligment == "right")
|
||||
return AlignRightCenter;
|
||||
else if(aligment == "top")
|
||||
return AlignTopCenter;
|
||||
else if(aligment == "bottom")
|
||||
return AlignBottomCenter;
|
||||
else
|
||||
return AlignCenter;
|
||||
}
|
|
@ -28,13 +28,14 @@
|
|||
#include <util/logger.h>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <constants.h>
|
||||
|
||||
/// Easy/fast writting formater
|
||||
#define f(a, b) (boost::format(a) % b).str()
|
||||
// Easy/fast writing formater
|
||||
#define fmt(a, b) (boost::format(a) % b).str()
|
||||
|
||||
/// Convert any data type through boost::lexical_cast
|
||||
template<class R, class T>
|
||||
R convertType(T t)
|
||||
template<class R, class T>
|
||||
R convert_cast(T t)
|
||||
{
|
||||
R ret = R();
|
||||
try {
|
||||
|
@ -45,4 +46,7 @@ R convertType(T t)
|
|||
return ret;
|
||||
}
|
||||
|
||||
AlignmentFlag parseAlignment(std::string aligment);
|
||||
|
||||
|
||||
#endif // UTIL_H
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/* 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 YAML_H
|
||||
#define YAML_H
|
||||
|
||||
#include <prerequisites.h>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
inline void operator>>(const YAML::Node& node, Color& color)
|
||||
{
|
||||
int r, g, b, a;
|
||||
node[0] >> r;
|
||||
node[1] >> g;
|
||||
node[2] >> b;
|
||||
node[3] >> a;
|
||||
color.setRGBA(r,g,b,a);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void operator>>(const YAML::Node& node, TPoint<T>& point)
|
||||
{
|
||||
node[0] >> point.x;
|
||||
node[1] >> point.y;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void operator>>(const YAML::Node& node, TRect<T>& rect)
|
||||
{
|
||||
T x, y, width, height;
|
||||
node[0] >> x;
|
||||
node[1] >> y;
|
||||
node[2] >> width;
|
||||
node[3] >> height;
|
||||
rect.setRect(x, y, width, height);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void operator>>(const YAML::Node& node, TSize<T>& size)
|
||||
{
|
||||
T w, h;
|
||||
node[0] >> w;
|
||||
node[1] >> h;
|
||||
size.setSize(w, h);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T yamlRead(const YAML::Node& node)
|
||||
{
|
||||
return node.Read<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T yamlRead(const YAML::Node& node, const char *name)
|
||||
{
|
||||
T value;
|
||||
node[name] >> value;
|
||||
return value;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T yamlRead(const YAML::Node& node, const char *name, const T& defaultValue)
|
||||
{
|
||||
T value = defaultValue;
|
||||
if(node.FindValue(name))
|
||||
node[name] >> value;
|
||||
return value;
|
||||
}
|
||||
|
||||
inline bool yamlHasValue(const YAML::Node& node, const char *name)
|
||||
{
|
||||
return node.FindValue(name) != NULL;
|
||||
}
|
||||
|
||||
inline std::string yamlErrorDesc(const YAML::Node& node, const std::string& error)
|
||||
{
|
||||
return YAML::Exception(node.GetMark(), error.c_str()).what();
|
||||
}
|
||||
|
||||
inline void yamlThrowError(const YAML::Node& node, const std::string& error)
|
||||
{
|
||||
throw YAML::Exception(node.GetMark(), error.c_str());
|
||||
}
|
||||
|
||||
template<class A, class B>
|
||||
inline std::map<A,B> yamlReadMap(const YAML::Node& node, const char *name)
|
||||
{
|
||||
std::map<A,B> map;
|
||||
if(const YAML::Node* mapNode = node.FindValue(name)) {
|
||||
for(auto it = mapNode->begin(); it != mapNode->end(); ++it) {
|
||||
A a;
|
||||
B b;
|
||||
it.first() >> a;
|
||||
it.second() >> b;
|
||||
map[a] = b;
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
#endif // YAML_H
|
|
@ -115,7 +115,7 @@ int main(int argc, const char *argv[])
|
|||
g_engine.enableFpsCounter();
|
||||
|
||||
// load ui skins
|
||||
g_uiSkins.load("skins/tibiaskin.yml");
|
||||
g_uiSkins.load("skins/lightness.yml");
|
||||
|
||||
// load script modules
|
||||
g_lua.loadAllModules();
|
||||
|
|