text edit (not finished)
This commit is contained in:
parent
bab83308cf
commit
da2993d1f9
|
@ -79,6 +79,7 @@ SET(SOURCES
|
||||||
src/framework/graphics/framebuffer.cpp
|
src/framework/graphics/framebuffer.cpp
|
||||||
src/framework/graphics/font.cpp
|
src/framework/graphics/font.cpp
|
||||||
src/framework/graphics/fonts.cpp
|
src/framework/graphics/fonts.cpp
|
||||||
|
src/framework/graphics/fonttext.cpp
|
||||||
src/framework/graphics/textureloader.cpp
|
src/framework/graphics/textureloader.cpp
|
||||||
src/framework/graphics/texture.cpp
|
src/framework/graphics/texture.cpp
|
||||||
src/framework/graphics/textures.cpp
|
src/framework/graphics/textures.cpp
|
||||||
|
|
|
@ -16,6 +16,7 @@ buttons:
|
||||||
center: [46,139,84,18]
|
center: [46,139,84,18]
|
||||||
|
|
||||||
down state:
|
down state:
|
||||||
|
translate: [1, 1]
|
||||||
bordered image:
|
bordered image:
|
||||||
left border: [45,159,1,18]
|
left border: [45,159,1,18]
|
||||||
right border: [130,159,1,18]
|
right border: [130,159,1,18]
|
||||||
|
@ -74,6 +75,7 @@ windows:
|
||||||
text edits:
|
text edits:
|
||||||
default:
|
default:
|
||||||
default size: [86, 16]
|
default size: [86, 16]
|
||||||
|
text margin: 2
|
||||||
bordered image:
|
bordered image:
|
||||||
left border: [308,97,1,1]
|
left border: [308,97,1,1]
|
||||||
right border: [319,97,1,10]
|
right border: [319,97,1,10]
|
||||||
|
|
|
@ -6,31 +6,31 @@ panel#mainMenu:
|
||||||
margin.left: 60
|
margin.left: 60
|
||||||
margin.bottom: 70
|
margin.bottom: 70
|
||||||
|
|
||||||
button#enterGame:
|
button#enterGameButton:
|
||||||
text: Enter Game
|
text: Enter Game
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
margin.top: 16
|
margin.top: 16
|
||||||
|
|
||||||
button#accessAccount:
|
button#accessAccountButton:
|
||||||
text: Access Account
|
text: Access Account
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
margin.top: 46
|
margin.top: 46
|
||||||
|
|
||||||
button#options:
|
button#optionsButton:
|
||||||
text: Options
|
text: Options
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
margin.top: 76
|
margin.top: 76
|
||||||
|
|
||||||
button#info:
|
button#infoButton:
|
||||||
text: Info
|
text: Info
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
margin.top: 106
|
margin.top: 106
|
||||||
|
|
||||||
button#exitGame:
|
button#exitGameButton:
|
||||||
text: Exit
|
text: Exit
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
|
@ -141,10 +141,13 @@ void Engine::onResize(const Size& size)
|
||||||
|
|
||||||
void Engine::onInputEvent(const InputEvent& event)
|
void Engine::onInputEvent(const InputEvent& event)
|
||||||
{
|
{
|
||||||
// inputs goest to gui first
|
bool eventCaptured = false;
|
||||||
if(!UIContainer::getRootContainer()->onInputEvent(event)) {
|
|
||||||
// if gui didnt capture the input then goes to the state
|
// events goes to the state first
|
||||||
if(m_currentState)
|
if(m_currentState)
|
||||||
m_currentState->onInputEvent(event);
|
eventCaptured = m_currentState->onInputEvent(event);
|
||||||
}
|
|
||||||
|
// if the state didn't capture the input then goes to the gui
|
||||||
|
if(!eventCaptured)
|
||||||
|
UIContainer::getRootContainer()->onInputEvent(event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
virtual void onLeave() = 0;
|
virtual void onLeave() = 0;
|
||||||
|
|
||||||
virtual void onClose() = 0;
|
virtual void onClose() = 0;
|
||||||
virtual void onInputEvent(const InputEvent& event) = 0;
|
virtual bool onInputEvent(const InputEvent& event) = 0;
|
||||||
virtual void onResize(const Size& size) = 0;
|
virtual void onResize(const Size& size) = 0;
|
||||||
|
|
||||||
virtual void render() = 0;
|
virtual void render() = 0;
|
||||||
|
|
|
@ -176,22 +176,31 @@ enum EKeyCode {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EEvent {
|
enum EEvent {
|
||||||
EV_KEY_DOWN = 0,
|
EV_MOUSE = 1,
|
||||||
EV_KEY_UP,
|
EV_KEYBOARD = 2,
|
||||||
EV_TEXT_ENTER,
|
EV_DOWN = 4,
|
||||||
EV_MOUSE_LDOWN,
|
EV_UP = 8,
|
||||||
EV_MOUSE_LUP,
|
EV_MOUSE_MOVE = 32,
|
||||||
EV_MOUSE_MDOWN,
|
EV_MOUSE_WHEEL = 64,
|
||||||
EV_MOUSE_MUP,
|
EV_MOUSE_LEFT = 128,
|
||||||
EV_MOUSE_RDOWN,
|
EV_MOUSE_RIGHT = 256,
|
||||||
EV_MOUSE_RUP,
|
EV_MOUSE_MIDDLE = 512,
|
||||||
EV_MOUSE_WHEEL_UP,
|
|
||||||
EV_MOUSE_WHEEL_DOWN,
|
EV_TEXT_ENTER = EV_KEYBOARD | 1024,
|
||||||
EV_MOUSE_MOVE
|
EV_KEY_DOWN = EV_KEYBOARD | EV_DOWN,
|
||||||
|
EV_KEY_UP = EV_KEYBOARD | EV_UP,
|
||||||
|
EV_MOUSE_LDOWN = EV_MOUSE | EV_DOWN | EV_MOUSE_LEFT,
|
||||||
|
EV_MOUSE_LUP = EV_MOUSE | EV_KEY_UP | EV_MOUSE_LEFT,
|
||||||
|
EV_MOUSE_MDOWN = EV_MOUSE | EV_DOWN | EV_MOUSE_MIDDLE,
|
||||||
|
EV_MOUSE_MUP = EV_MOUSE | EV_KEY_UP | EV_MOUSE_MIDDLE,
|
||||||
|
EV_MOUSE_RDOWN = EV_MOUSE | EV_DOWN | EV_MOUSE_RIGHT,
|
||||||
|
EV_MOUSE_RUP = EV_MOUSE | EV_KEY_UP | EV_MOUSE_RIGHT,
|
||||||
|
EV_MOUSE_WHEEL_UP = EV_MOUSE | EV_MOUSE_WHEEL | EV_UP,
|
||||||
|
EV_MOUSE_WHEEL_DOWN = EV_MOUSE | EV_MOUSE_WHEEL | EV_DOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InputEvent {
|
struct InputEvent {
|
||||||
EEvent type;
|
int type;
|
||||||
Point mousePos;
|
Point mousePos;
|
||||||
char keychar;
|
char keychar;
|
||||||
uchar keycode;
|
uchar keycode;
|
||||||
|
|
|
@ -143,7 +143,9 @@ void Font::renderText(const std::string& text,
|
||||||
const Rect& screenCoords,
|
const Rect& screenCoords,
|
||||||
int align,
|
int align,
|
||||||
const Color& color,
|
const Color& color,
|
||||||
const Point& startInternalPos)
|
const Point& startInternalPos,
|
||||||
|
int cursorPos,
|
||||||
|
const Color& cursorColor)
|
||||||
{
|
{
|
||||||
// prevent glitches from invalid rects
|
// prevent glitches from invalid rects
|
||||||
if(!screenCoords.isValid())
|
if(!screenCoords.isValid())
|
||||||
|
@ -219,6 +221,17 @@ void Font::renderText(const std::string& text,
|
||||||
|
|
||||||
// render glyph
|
// render glyph
|
||||||
g_graphics.drawTexturedRect(glyphScreenCoords, m_texture, glyphTextureCoords, color);
|
g_graphics.drawTexturedRect(glyphScreenCoords, m_texture, glyphTextureCoords, color);
|
||||||
|
|
||||||
|
// render cursor
|
||||||
|
if(i == cursorPos) {
|
||||||
|
Rect cursorRect(glyphScreenCoords.left()-1, glyphScreenCoords.top(), 1, m_glyphHeight);
|
||||||
|
g_graphics.drawFilledRect(cursorRect, cursorColor);
|
||||||
|
}
|
||||||
|
// render cursor after last element
|
||||||
|
else if(cursorPos == textLenght && i == textLenght - 1) {
|
||||||
|
Rect cursorRect(glyphScreenCoords.right()+1, glyphScreenCoords.top(), 1, m_glyphHeight);
|
||||||
|
g_graphics.drawFilledRect(cursorRect, cursorColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,10 @@ public:
|
||||||
const Rect& screenCoords,
|
const Rect& screenCoords,
|
||||||
int align = ALIGN_TOP_LEFT,
|
int align = ALIGN_TOP_LEFT,
|
||||||
const Color& color = Color::white,
|
const Color& color = Color::white,
|
||||||
const Point& startInternalPos = Point());
|
const Point& startInternalPos = Point(),
|
||||||
|
int cursorPos = -1,
|
||||||
|
const Color& cursorColor = 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
|
||||||
Point *calculateGlyphsPositions(const std::string& text, int align = ALIGN_TOP_LEFT, Size *textBoxSize = NULL);
|
Point *calculateGlyphsPositions(const std::string& text, int align = ALIGN_TOP_LEFT, Size *textBoxSize = NULL);
|
||||||
|
@ -74,7 +77,8 @@ public:
|
||||||
Size calculateTextRectSize(const std::string& text);
|
Size calculateTextRectSize(const std::string& text);
|
||||||
|
|
||||||
const std::string& getName() const { return m_name; }
|
const std::string& getName() const { return m_name; }
|
||||||
|
int getGlyphHeight() const { return m_glyphHeight; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void calculateGlyphsWidthsAutomatically(const Size& glyphSize);
|
void calculateGlyphsWidthsAutomatically(const Size& glyphSize);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "fonttext.h"
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FONTTEXT_H
|
||||||
|
#define FONTTEXT_H
|
||||||
|
|
||||||
|
#include "prerequisites.h"
|
||||||
|
#include "font.h"
|
||||||
|
|
||||||
|
class FontText
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FontText() { }
|
||||||
|
|
||||||
|
void appendCharacter(char c);
|
||||||
|
void appendText(const std::string &text);
|
||||||
|
void erase(bool left);
|
||||||
|
|
||||||
|
void setText(const std::string &text);
|
||||||
|
void setCursorPos(int pos);
|
||||||
|
void setSelection(int start, int end);
|
||||||
|
void setColor(const Color& color);
|
||||||
|
void setSize(const Size& size);
|
||||||
|
void setStartPos();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_cursorPos;
|
||||||
|
std::string m_text;
|
||||||
|
Font *m_font;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FONTTEXT_H
|
|
@ -23,27 +23,16 @@
|
||||||
|
|
||||||
|
|
||||||
#include "uibutton.h"
|
#include "uibutton.h"
|
||||||
#include "graphics/fonts.h"
|
|
||||||
#include "graphics/font.h"
|
|
||||||
|
|
||||||
void UIButton::render()
|
void UIButton::onInputEvent(const InputEvent& event)
|
||||||
{
|
{
|
||||||
UIElement::render();
|
if(event.type == EV_MOUSE_LDOWN && getRect().contains(event.mousePos)) {
|
||||||
|
|
||||||
g_fonts.get("tibia-8px-antialised")->renderText(m_text, getRect(), ALIGN_CENTER, Color(0xFFEEEEEE));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UIButton::onInputEvent(const InputEvent& event)
|
|
||||||
{
|
|
||||||
if(event.type == EV_MOUSE_LDOWN &&
|
|
||||||
getRect().contains(event.mousePos)) {
|
|
||||||
m_state = UI::ButtonDown;
|
m_state = UI::ButtonDown;
|
||||||
} else if(m_state == UI::ButtonDown && event.type == EV_MOUSE_LUP) {
|
} else if(event.type == EV_MOUSE_LUP && m_state == UI::ButtonDown) {
|
||||||
m_state = UI::ButtonUp;
|
m_state = UI::ButtonUp;
|
||||||
if(getRect().contains(event.mousePos)) {
|
if(getRect().contains(event.mousePos)) {
|
||||||
if(m_buttonClickCallback)
|
if(m_buttonClickCallback)
|
||||||
m_buttonClickCallback();
|
m_buttonClickCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,7 @@ public:
|
||||||
UIElement();
|
UIElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void render();
|
void onInputEvent(const InputEvent& event);
|
||||||
bool onInputEvent(const InputEvent& event);
|
|
||||||
|
|
||||||
void setText(const std::string& text) { m_text = text; }
|
void setText(const std::string& text) { m_text = text; }
|
||||||
const std::string& getText() const { return m_text; }
|
const std::string& getText() const { return m_text; }
|
||||||
|
|
|
@ -24,27 +24,38 @@
|
||||||
|
|
||||||
#include "uibuttonskin.h"
|
#include "uibuttonskin.h"
|
||||||
#include "uibutton.h"
|
#include "uibutton.h"
|
||||||
|
#include "graphics/fonts.h"
|
||||||
|
|
||||||
void UIButtonSkin::draw(UIElement *element)
|
void UIButtonSkin::draw(UIElement *element)
|
||||||
{
|
{
|
||||||
UIButton *button = static_cast<UIButton*>(element);
|
UIButton *button = static_cast<UIButton*>(element);
|
||||||
|
|
||||||
|
Rect textRect = button->getRect();
|
||||||
|
|
||||||
if(button->getState() == UI::ButtonDown && m_buttonDownImage) {
|
if(button->getState() == UI::ButtonDown && m_buttonDownImage) {
|
||||||
m_buttonDownImage->draw(element->getRect());
|
m_buttonDownImage->draw(element->getRect());
|
||||||
|
textRect.translate(m_buttonDownTranslate);
|
||||||
} else if(button->getState() == UI::ButtonMouseOver && m_buttonHoverImage) {
|
} else if(button->getState() == UI::ButtonMouseOver && m_buttonHoverImage) {
|
||||||
m_buttonHoverImage->draw(element->getRect());
|
m_buttonHoverImage->draw(element->getRect());
|
||||||
} else {
|
} else {
|
||||||
UIElementSkin::draw(element);
|
UIElementSkin::draw(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_fonts.get("tibia-8px-antialised")->renderText(button->getText(), textRect, ALIGN_CENTER, Color(0xFFEEEEEE));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIButtonSkin::load(const YAML::Node& node)
|
void UIButtonSkin::load(const YAML::Node& node)
|
||||||
{
|
{
|
||||||
UIElementSkin::load(node);
|
UIElementSkin::load(node);
|
||||||
|
|
||||||
if(node.FindValue("down state"))
|
if(node.FindValue("down state")) {
|
||||||
m_buttonDownImage = loadImage(node["down state"]);
|
m_buttonDownImage = loadImage(node["down state"]);
|
||||||
|
|
||||||
|
if(node["down state"].FindValue("translate"))
|
||||||
|
node["down state"]["translate"] >> m_buttonDownTranslate;
|
||||||
|
}
|
||||||
|
|
||||||
if(node.FindValue("mouse over state"))
|
if(node.FindValue("mouse over state"))
|
||||||
m_buttonHoverImage = loadImage(node["mouse over state"]);
|
m_buttonHoverImage = loadImage(node["mouse over state"]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
private:
|
private:
|
||||||
ImagePtr m_buttonDownImage;
|
ImagePtr m_buttonDownImage;
|
||||||
ImagePtr m_buttonHoverImage;
|
ImagePtr m_buttonHoverImage;
|
||||||
|
Point m_buttonDownTranslate;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UIBUTTONSKIN_H
|
#endif // UIBUTTONSKIN_H
|
||||||
|
|
|
@ -45,8 +45,8 @@ void UIContainer::addChild(UIElementPtr child)
|
||||||
|
|
||||||
void UIContainer::removeChild(UIElementPtr child)
|
void UIContainer::removeChild(UIElementPtr child)
|
||||||
{
|
{
|
||||||
if(m_activeElement == child)
|
if(m_focusedElement == child)
|
||||||
setActiveElement(UIElementPtr());
|
setFocusedElement(UIElementPtr());
|
||||||
m_children.remove(child);
|
m_children.remove(child);
|
||||||
if(child->getParent() == shared_from_this())
|
if(child->getParent() == shared_from_this())
|
||||||
child->setParent(UIContainerPtr());
|
child->setParent(UIContainerPtr());
|
||||||
|
@ -96,18 +96,45 @@ void UIContainer::render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UIContainer::onInputEvent(const InputEvent& event)
|
void UIContainer::onInputEvent(const InputEvent& event)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
|
||||||
for(auto it = m_children.begin(); it != m_children.end(); ++it) {
|
for(auto it = m_children.begin(); it != m_children.end(); ++it) {
|
||||||
const UIElementPtr& child = (*it);
|
const UIElementPtr& child = (*it);
|
||||||
if(child->isEnabled() && child->isVisible())
|
bool shouldFire = false;
|
||||||
ret = child->onInputEvent(event) || ret;
|
|
||||||
|
// events should pass only when element is visible and enabled
|
||||||
|
if(child->isEnabled() && child->isVisible()) {
|
||||||
|
if(event.type & EV_KEYBOARD) {
|
||||||
|
// keyboard events only go to focused elements
|
||||||
|
if(child == getFocusedElement()) {
|
||||||
|
shouldFire = true;
|
||||||
|
}
|
||||||
|
// mouse events
|
||||||
|
} else if(event.type & EV_MOUSE) {
|
||||||
|
// mouse down and weel events only go to elements that contains the mouse position
|
||||||
|
if(event.type & EV_DOWN || event.type & EV_MOUSE_WHEEL) {
|
||||||
|
if(child->getRect().contains(event.mousePos)) {
|
||||||
|
// focus it
|
||||||
|
if(event.type == EV_MOUSE_LDOWN)
|
||||||
|
setFocusedElement(child);
|
||||||
|
shouldFire = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// mouse move and mouse up events go to all elements
|
||||||
|
else {
|
||||||
|
shouldFire = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(shouldFire)
|
||||||
|
child->onInputEvent(event);
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIContainer::setActiveElement(UIElementPtr activeElement)
|
void UIContainer::setFocusedElement(UIElementPtr focusedElement)
|
||||||
{
|
{
|
||||||
|
if(m_focusedElement)
|
||||||
|
m_focusedElement->setFocused(false);
|
||||||
|
m_focusedElement = focusedElement;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,10 +41,10 @@ public:
|
||||||
UIElementPtr recursiveGetChildById(const std::string& id);
|
UIElementPtr recursiveGetChildById(const std::string& id);
|
||||||
|
|
||||||
virtual void render();
|
virtual void render();
|
||||||
virtual bool onInputEvent(const InputEvent& event);
|
virtual void onInputEvent(const InputEvent& event);
|
||||||
|
|
||||||
void setActiveElement(UIElementPtr activeElement);
|
void setFocusedElement(UIElementPtr focusedElement);
|
||||||
UIElementPtr getActiveElement() const { return m_activeElement; }
|
UIElementPtr getFocusedElement() const { return m_focusedElement; }
|
||||||
|
|
||||||
virtual UI::EElementType getElementType() const { return UI::Container; }
|
virtual UI::EElementType getElementType() const { return UI::Container; }
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::list<UIElementPtr> m_children;
|
std::list<UIElementPtr> m_children;
|
||||||
UIElementPtr m_activeElement;
|
UIElementPtr m_focusedElement;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UICONTAINER_H
|
#endif // UICONTAINER_H
|
||||||
|
|
|
@ -31,7 +31,8 @@ UIElement::UIElement(UI::EElementType type) :
|
||||||
m_type(type),
|
m_type(type),
|
||||||
m_skin(NULL),
|
m_skin(NULL),
|
||||||
m_visible(true),
|
m_visible(true),
|
||||||
m_enabled(true)
|
m_enabled(true),
|
||||||
|
m_focused(false)
|
||||||
{
|
{
|
||||||
// set default skin
|
// set default skin
|
||||||
if(type > UI::Container)
|
if(type > UI::Container)
|
||||||
|
@ -58,7 +59,6 @@ void UIElement::render()
|
||||||
m_skin->draw(this);
|
m_skin->draw(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
UIElementPtr UIElement::backwardsGetElementById(const std::string& id)
|
UIElementPtr UIElement::backwardsGetElementById(const std::string& id)
|
||||||
{
|
{
|
||||||
if(getId() == id)
|
if(getId() == id)
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
virtual ~UIElement() { }
|
virtual ~UIElement() { }
|
||||||
|
|
||||||
virtual void render();
|
virtual void render();
|
||||||
virtual bool onInputEvent(const InputEvent& event) { return false; }
|
virtual void onInputEvent(const InputEvent& event) { }
|
||||||
|
|
||||||
UIElementPtr backwardsGetElementById(const std::string& id);
|
UIElementPtr backwardsGetElementById(const std::string& id);
|
||||||
|
|
||||||
|
@ -64,6 +64,9 @@ public:
|
||||||
void setEnabled(bool enabled) { m_enabled = enabled; }
|
void setEnabled(bool enabled) { m_enabled = enabled; }
|
||||||
bool isEnabled() const { return m_enabled; }
|
bool isEnabled() const { return m_enabled; }
|
||||||
|
|
||||||
|
void setFocused(bool focused) { m_focused = focused; }
|
||||||
|
bool isFocused() const { return m_focused; }
|
||||||
|
|
||||||
void setVisible(bool visible) { m_visible = visible; }
|
void setVisible(bool visible) { m_visible = visible; }
|
||||||
bool isVisible() const { return m_visible; }
|
bool isVisible() const { return m_visible; }
|
||||||
|
|
||||||
|
@ -79,6 +82,7 @@ private:
|
||||||
std::string m_id;
|
std::string m_id;
|
||||||
bool m_visible;
|
bool m_visible;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
|
bool m_focused;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UIELEMENT_H
|
#endif // UIELEMENT_H
|
||||||
|
|
|
@ -52,7 +52,10 @@ int AnchorLine::getPos() const
|
||||||
|
|
||||||
void UILayout::setSize(const Size& size)
|
void UILayout::setSize(const Size& size)
|
||||||
{
|
{
|
||||||
m_rect.setSize(size);
|
if(m_rect.isValid())
|
||||||
|
m_rect.setSize(size);
|
||||||
|
else
|
||||||
|
m_rect = Rect(0, 0, size);
|
||||||
|
|
||||||
// rect updated, recalculate itself and anchored elements positions
|
// rect updated, recalculate itself and anchored elements positions
|
||||||
recalculateAnchors();
|
recalculateAnchors();
|
||||||
|
|
|
@ -91,6 +91,8 @@ UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& p
|
||||||
|
|
||||||
// now do the real load
|
// now do the real load
|
||||||
loadElements(element, doc.begin().second());
|
loadElements(element, doc.begin().second());
|
||||||
|
|
||||||
|
return element;
|
||||||
} catch (YAML::Exception& e) {
|
} catch (YAML::Exception& e) {
|
||||||
logFatal("Failed to load ui file \"%s\":\n %s", file.c_str(), e.what());
|
logFatal("Failed to load ui file \"%s\":\n %s", file.c_str(), e.what());
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace UILoader
|
||||||
UIElementPtr createElementFromId(const std::string& id);
|
UIElementPtr createElementFromId(const std::string& id);
|
||||||
|
|
||||||
/// Loads an UIElement and it's children from a YAML file
|
/// Loads an UIElement and it's children from a YAML file
|
||||||
UIElementPtr loadFile(const std::string& file, const UIContainerPtr& parent);
|
UIElementPtr loadFile(const std::string& file, const UIContainerPtr& parent = UIContainer::getRootContainer());
|
||||||
|
|
||||||
/// Populate container children from a YAML node
|
/// Populate container children from a YAML node
|
||||||
void populateContainer(const UIContainerPtr& parent, const YAML::Node& node);
|
void populateContainer(const UIContainerPtr& parent, const YAML::Node& node);
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
UITextEdit::UITextEdit(Font* font) :
|
UITextEdit::UITextEdit(Font* font) :
|
||||||
UIElement(UI::TextEdit),
|
UIElement(UI::TextEdit),
|
||||||
|
m_cursorPos(0),
|
||||||
|
m_startRenderPos(0),
|
||||||
m_font(font)
|
m_font(font)
|
||||||
{
|
{
|
||||||
if(!font)
|
if(!font)
|
||||||
|
@ -36,10 +38,67 @@ UITextEdit::UITextEdit(Font* font) :
|
||||||
void UITextEdit::render()
|
void UITextEdit::render()
|
||||||
{
|
{
|
||||||
UIElement::render();
|
UIElement::render();
|
||||||
m_font->renderText(m_text, getRect(), ALIGN_LEFT, Color(0xFFBFBFBF));
|
|
||||||
|
Rect textRect = getRect();
|
||||||
|
textRect.setLeft(textRect.left() + 2);
|
||||||
|
textRect.setRight(textRect.right() - 2);
|
||||||
|
|
||||||
|
// render text
|
||||||
|
m_font->renderText(m_text, textRect, ALIGN_LEFT, Color(0xFFBFBFBF), Point(m_startRenderPos, 0), m_cursorPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITextEdit::onInputEvent(const InputEvent& event)
|
||||||
|
{
|
||||||
|
if(event.type == EV_TEXT_ENTER) {
|
||||||
|
appendCharacter(event.keychar);
|
||||||
|
} else if(event.type == EV_KEY_DOWN) {
|
||||||
|
if(event.keycode == KC_DELETE)
|
||||||
|
removeCharacter(true);
|
||||||
|
else if(event.keycode == KC_BACK)
|
||||||
|
removeCharacter(false);
|
||||||
|
else if(event.keycode == KC_RIGHT) {
|
||||||
|
if(m_cursorPos < m_text.length())
|
||||||
|
m_cursorPos++;
|
||||||
|
} else if(event.keycode == KC_LEFT) {
|
||||||
|
if(m_cursorPos > 0)
|
||||||
|
m_cursorPos--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITextEdit::clearText()
|
||||||
|
{
|
||||||
|
m_text = "";
|
||||||
|
m_cursorPos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UITextEdit::setText(const std::string& text)
|
void UITextEdit::setText(const std::string& text)
|
||||||
{
|
{
|
||||||
m_text = text;
|
m_text = text;
|
||||||
|
m_cursorPos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UITextEdit::appendCharacter(char c)
|
||||||
|
{
|
||||||
|
std::string tmp;
|
||||||
|
tmp = c;
|
||||||
|
m_text.insert(m_cursorPos, tmp);
|
||||||
|
m_cursorPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITextEdit::removeCharacter(bool right)
|
||||||
|
{
|
||||||
|
if(right && m_cursorPos < m_text.length())
|
||||||
|
m_text.erase(m_text.begin() + m_cursorPos);
|
||||||
|
else if(m_text.length() >= m_cursorPos && m_cursorPos > 0)
|
||||||
|
m_text.erase(m_text.begin() + (--m_cursorPos));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITextEdit::setCursorPos(uint pos)
|
||||||
|
{
|
||||||
|
if(pos > m_text.length())
|
||||||
|
m_cursorPos = m_text.length();
|
||||||
|
else
|
||||||
|
m_cursorPos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,12 +35,24 @@ class UITextEdit : public UIElement
|
||||||
public:
|
public:
|
||||||
UITextEdit(Font *font = NULL);
|
UITextEdit(Font *font = NULL);
|
||||||
|
|
||||||
|
void onInputEvent(const InputEvent& event);
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
|
void clearText();
|
||||||
void setText(const std::string& text);
|
void setText(const std::string& text);
|
||||||
const std::string& getText() const { return m_text; }
|
const std::string& getText() const { return m_text; }
|
||||||
|
|
||||||
|
void setCursorPos(uint pos);
|
||||||
|
uint getCursorPos() { return m_cursorPos; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void appendCharacter(char c);
|
||||||
|
void removeCharacter(bool right);
|
||||||
|
void recalculate();
|
||||||
|
|
||||||
|
uint m_cursorPos;
|
||||||
|
int m_startRenderPos;
|
||||||
std::string m_text;
|
std::string m_text;
|
||||||
Font *m_font;
|
Font *m_font;
|
||||||
};
|
};
|
||||||
|
|
|
@ -80,7 +80,6 @@ typedef TPoint<float> PointF;
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void operator>>(const YAML::Node& node, TPoint<T>& point)
|
inline void operator>>(const YAML::Node& node, TPoint<T>& point)
|
||||||
{
|
{
|
||||||
T x, y;
|
|
||||||
node[0] >> point.x;
|
node[0] >> point.x;
|
||||||
node[1] >> point.y;
|
node[1] >> point.y;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,15 +39,20 @@ void MenuState::onEnter()
|
||||||
m_background = g_textures.get("background.png");
|
m_background = g_textures.get("background.png");
|
||||||
m_background->enableBilinearFilter();
|
m_background->enableBilinearFilter();
|
||||||
|
|
||||||
UIElementPtr mainMenuPanel = UILoader::loadFile("ui/mainMenu.yml", UIContainer::getRootContainer());
|
UIContainerPtr mainMenuPanel = UILoader::loadFile("ui/mainMenu.yml")->asUIContainer();
|
||||||
/*
|
|
||||||
UIButtonPtr button = std::static_pointer_cast<UIButton>(mainMenuPanel->getChildById("exitGame-button"));
|
UIButtonPtr button = std::static_pointer_cast<UIButton>(mainMenuPanel->getChildById("exitGameButton"));
|
||||||
button->onClick([]{ g_engine.stop(); });
|
button->onClick([this]{
|
||||||
|
this->onClose();
|
||||||
button = std::static_pointer_cast<UIButton>(mainMenuPanel->getChildById("enterGame-button"));
|
});
|
||||||
button->onClick([]{
|
|
||||||
UIContainer::load("ui/enterGame-window.yml");
|
button = std::static_pointer_cast<UIButton>(mainMenuPanel->getChildById("enterGameButton"));
|
||||||
});*/
|
button->onClick([mainMenuPanel]{
|
||||||
|
UIElementPtr window = UIContainer::getRootContainer()->getChildById("enterGameWindow");
|
||||||
|
if(!window)
|
||||||
|
window = UILoader::loadFile("ui/enterGameWindow.yml");
|
||||||
|
mainMenuPanel->setEnabled(false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuState::onLeave()
|
void MenuState::onLeave()
|
||||||
|
@ -60,9 +65,9 @@ void MenuState::onClose()
|
||||||
g_engine.stop();
|
g_engine.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuState::onInputEvent(const InputEvent& event)
|
bool MenuState::onInputEvent(const InputEvent& event)
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuState::onResize(const Size& size)
|
void MenuState::onResize(const Size& size)
|
||||||
|
@ -84,126 +89,3 @@ void MenuState::render()
|
||||||
texCoords.moveBottomRight(texSize.toPoint());
|
texCoords.moveBottomRight(texSize.toPoint());
|
||||||
g_graphics.drawTexturedRect(Rect(0, 0, screenSize), m_background, texCoords);
|
g_graphics.drawTexturedRect(Rect(0, 0, screenSize), m_background, texCoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuState::createMainMenu()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
int y = 0;
|
|
||||||
|
|
||||||
m_menuPanel = UIPanelPtr(new UIPanel);
|
|
||||||
m_menuPanel->setSkin("roundedGridPanel");
|
|
||||||
m_menuPanel->anchorLeft(g_ui->left());
|
|
||||||
m_menuPanel->anchorBottom(g_ui->bottom());
|
|
||||||
m_menuPanel->setSize(Size(118, 172));
|
|
||||||
m_menuPanel->setMargin(0, 60, 70, 0);
|
|
||||||
g_ui->addChild(m_menuPanel);
|
|
||||||
|
|
||||||
// main menu
|
|
||||||
UIButtonPtr enterGameButton = UIButtonPtr(new UIButton("Enter Game"));
|
|
||||||
enterGameButton->anchorTop(m_menuPanel->top());
|
|
||||||
enterGameButton->anchorHorizontalCenter(m_menuPanel->horizontalCenter());
|
|
||||||
enterGameButton->setMargin(y += 16);
|
|
||||||
m_menuPanel->addChild(enterGameButton);
|
|
||||||
|
|
||||||
UIButtonPtr button = UIButtonPtr(new UIButton("Access Account"));
|
|
||||||
button->anchorTop(m_menuPanel->top());
|
|
||||||
button->anchorHorizontalCenter(m_menuPanel->horizontalCenter());
|
|
||||||
button->setMargin(y += 30);
|
|
||||||
m_menuPanel->addChild(button);
|
|
||||||
|
|
||||||
button = UIButtonPtr(new UIButton("Options"));
|
|
||||||
button->anchorTop(m_menuPanel->top());
|
|
||||||
button->anchorHorizontalCenter(m_menuPanel->horizontalCenter());
|
|
||||||
button->setMargin(y += 30);
|
|
||||||
m_menuPanel->addChild(button);
|
|
||||||
|
|
||||||
button = UIButtonPtr(new UIButton("Info"));
|
|
||||||
button->anchorTop(m_menuPanel->top());
|
|
||||||
button->anchorHorizontalCenter(m_menuPanel->horizontalCenter());
|
|
||||||
button->setMargin(y += 30);
|
|
||||||
m_menuPanel->addChild(button);
|
|
||||||
|
|
||||||
button = UIButtonPtr(new UIButton("Exit Game"));
|
|
||||||
button->anchorLeft(m_menuPanel->left());
|
|
||||||
button->anchorTop(m_menuPanel->top());
|
|
||||||
button->anchorHorizontalCenter(m_menuPanel->horizontalCenter());
|
|
||||||
button->setMargin(y += 30);
|
|
||||||
button->onClick([]{ g_engine.stop(); });
|
|
||||||
m_menuPanel->addChild(button);
|
|
||||||
|
|
||||||
// login window
|
|
||||||
UIWindowPtr window(new UIWindow("Enter Game"));
|
|
||||||
UIElementWeakPtr weakWindow(window);
|
|
||||||
window->setSize(Size(236, 178));
|
|
||||||
window->anchorHorizontalCenter(g_ui->horizontalCenter());
|
|
||||||
window->anchorVerticalCenter(g_ui->verticalCenter());
|
|
||||||
window->setVisible(false);
|
|
||||||
g_ui->addChild(window);
|
|
||||||
|
|
||||||
UILabelPtr label(new UILabel("Account name:"));
|
|
||||||
label->anchorLeft(window->left());
|
|
||||||
label->anchorTop(window->top());
|
|
||||||
label->setMargin(18, 33);
|
|
||||||
window->addChild(label);
|
|
||||||
|
|
||||||
label = UILabelPtr(new UILabel("Password:"));
|
|
||||||
label->anchorLeft(window->left());
|
|
||||||
label->anchorTop(window->top());
|
|
||||||
label->setMargin(18, 62);
|
|
||||||
window->addChild(label);
|
|
||||||
|
|
||||||
label = UILabelPtr(new UILabel("If you don't have\nan account yet:"));
|
|
||||||
label->anchorLeft(window->left());
|
|
||||||
label->anchorTop(window->top());
|
|
||||||
label->setMargin(18, 87);
|
|
||||||
window->addChild(label);
|
|
||||||
|
|
||||||
button = UIButtonPtr(new UIButton("Create Account"));
|
|
||||||
button->anchorLeft(window->left());
|
|
||||||
button->anchorTop(window->top());
|
|
||||||
button->setMargin(132, 94);
|
|
||||||
window->addChild(button);
|
|
||||||
|
|
||||||
button = UIButtonPtr(new UIButton("Ok"));
|
|
||||||
button->setSize(Size(43, 20));
|
|
||||||
button->anchorRight(window->right());
|
|
||||||
button->anchorBottom(window->bottom());
|
|
||||||
button->setMargin(0, 0, 10, 66);
|
|
||||||
button->onClick([weakWindow]{
|
|
||||||
UIElementPtr window = weakWindow.lock();
|
|
||||||
if(window)
|
|
||||||
window->setVisible(false);
|
|
||||||
});
|
|
||||||
window->addChild(button);
|
|
||||||
|
|
||||||
button = UIButtonPtr(new UIButton("Cancel"));
|
|
||||||
button->setSize(Size(43, 20));
|
|
||||||
button->anchorRight(window->right());
|
|
||||||
button->anchorBottom(window->bottom());
|
|
||||||
button->setMargin(0, 0, 10, 13);
|
|
||||||
button->onClick([weakWindow]{
|
|
||||||
UIElementPtr window = weakWindow.lock();
|
|
||||||
if(window)
|
|
||||||
window->setVisible(false);
|
|
||||||
});
|
|
||||||
window->addChild(button);
|
|
||||||
|
|
||||||
UITextEditPtr textEdit(new UITextEdit);
|
|
||||||
textEdit->anchorRight(window->right());
|
|
||||||
textEdit->anchorTop(window->top());
|
|
||||||
textEdit->setMargin(32, 0, 0, 18);
|
|
||||||
window->addChild(textEdit);
|
|
||||||
|
|
||||||
textEdit = UITextEditPtr(new UITextEdit);
|
|
||||||
textEdit->anchorRight(window->right());
|
|
||||||
textEdit->anchorTop(window->top());
|
|
||||||
textEdit->setMargin(61, 0, 0, 18);
|
|
||||||
window->addChild(textEdit);
|
|
||||||
|
|
||||||
enterGameButton->onClick([weakWindow]{
|
|
||||||
UIElementPtr window = weakWindow.lock();
|
|
||||||
if(window)
|
|
||||||
window->setVisible(true);
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
void onLeave();
|
void onLeave();
|
||||||
|
|
||||||
void onClose();
|
void onClose();
|
||||||
void onInputEvent(const InputEvent& event);
|
bool onInputEvent(const InputEvent& event);
|
||||||
void onResize(const Size& size);
|
void onResize(const Size& size);
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
|
|
|
@ -44,9 +44,9 @@ void TestState::onClose()
|
||||||
g_engine.stop();
|
g_engine.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestState::onInputEvent(const InputEvent& event)
|
bool TestState::onInputEvent(const InputEvent& event)
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestState::onResize(const Size& size)
|
void TestState::onResize(const Size& size)
|
||||||
|
|
|
@ -37,7 +37,7 @@ public:
|
||||||
void onLeave();
|
void onLeave();
|
||||||
|
|
||||||
void onClose();
|
void onClose();
|
||||||
void onInputEvent(const InputEvent& event);
|
bool onInputEvent(const InputEvent& event);
|
||||||
void onResize(const Size& size);
|
void onResize(const Size& size);
|
||||||
|
|
||||||
virtual void render();
|
virtual void render();
|
||||||
|
|
Loading…
Reference in New Issue