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