diff --git a/CMakeLists.txt b/CMakeLists.txt index 7692392a..83164980 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,7 @@ SET(SOURCES src/framework/graphics/framebuffer.cpp src/framework/graphics/font.cpp src/framework/graphics/fonts.cpp + src/framework/graphics/fonttext.cpp src/framework/graphics/textureloader.cpp src/framework/graphics/texture.cpp src/framework/graphics/textures.cpp diff --git a/data/skins/tibiaskin.yml b/data/skins/tibiaskin.yml index ed8ccd19..139a9d56 100644 --- a/data/skins/tibiaskin.yml +++ b/data/skins/tibiaskin.yml @@ -16,6 +16,7 @@ buttons: center: [46,139,84,18] down state: + translate: [1, 1] bordered image: left border: [45,159,1,18] right border: [130,159,1,18] @@ -74,6 +75,7 @@ windows: text edits: default: default size: [86, 16] + text margin: 2 bordered image: left border: [308,97,1,1] right border: [319,97,1,10] diff --git a/data/ui/enterGame-window.yml b/data/ui/enterGameWindow.yml similarity index 100% rename from data/ui/enterGame-window.yml rename to data/ui/enterGameWindow.yml diff --git a/data/ui/mainMenu.yml b/data/ui/mainMenu.yml index 65ac26b1..4a84bb19 100644 --- a/data/ui/mainMenu.yml +++ b/data/ui/mainMenu.yml @@ -6,31 +6,31 @@ panel#mainMenu: margin.left: 60 margin.bottom: 70 - button#enterGame: + button#enterGameButton: text: Enter Game anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter margin.top: 16 - button#accessAccount: + button#accessAccountButton: text: Access Account anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter margin.top: 46 - button#options: + button#optionsButton: text: Options anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter margin.top: 76 - button#info: + button#infoButton: text: Info anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter margin.top: 106 - button#exitGame: + button#exitGameButton: text: Exit anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter diff --git a/src/framework/core/engine.cpp b/src/framework/core/engine.cpp index 2db5edc4..b320b7d3 100644 --- a/src/framework/core/engine.cpp +++ b/src/framework/core/engine.cpp @@ -141,10 +141,13 @@ void Engine::onResize(const Size& size) void Engine::onInputEvent(const InputEvent& event) { - // inputs goest to gui first - if(!UIContainer::getRootContainer()->onInputEvent(event)) { - // if gui didnt capture the input then goes to the state - if(m_currentState) - m_currentState->onInputEvent(event); - } + bool eventCaptured = false; + + // events goes to the state first + if(m_currentState) + eventCaptured = m_currentState->onInputEvent(event); + + // if the state didn't capture the input then goes to the gui + if(!eventCaptured) + UIContainer::getRootContainer()->onInputEvent(event); } diff --git a/src/framework/core/gamestate.h b/src/framework/core/gamestate.h index 23662feb..1450ed75 100644 --- a/src/framework/core/gamestate.h +++ b/src/framework/core/gamestate.h @@ -40,7 +40,7 @@ public: virtual void onLeave() = 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 render() = 0; diff --git a/src/framework/core/input.h b/src/framework/core/input.h index c20a4f73..4bb25466 100644 --- a/src/framework/core/input.h +++ b/src/framework/core/input.h @@ -176,22 +176,31 @@ enum EKeyCode { }; enum EEvent { - EV_KEY_DOWN = 0, - EV_KEY_UP, - EV_TEXT_ENTER, - EV_MOUSE_LDOWN, - EV_MOUSE_LUP, - EV_MOUSE_MDOWN, - EV_MOUSE_MUP, - EV_MOUSE_RDOWN, - EV_MOUSE_RUP, - EV_MOUSE_WHEEL_UP, - EV_MOUSE_WHEEL_DOWN, - EV_MOUSE_MOVE + EV_MOUSE = 1, + EV_KEYBOARD = 2, + EV_DOWN = 4, + EV_UP = 8, + EV_MOUSE_MOVE = 32, + EV_MOUSE_WHEEL = 64, + EV_MOUSE_LEFT = 128, + EV_MOUSE_RIGHT = 256, + EV_MOUSE_MIDDLE = 512, + + EV_TEXT_ENTER = EV_KEYBOARD | 1024, + 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 { - EEvent type; + int type; Point mousePos; char keychar; uchar keycode; diff --git a/src/framework/graphics/font.cpp b/src/framework/graphics/font.cpp index 836b1cf3..fd3ab463 100644 --- a/src/framework/graphics/font.cpp +++ b/src/framework/graphics/font.cpp @@ -143,7 +143,9 @@ void Font::renderText(const std::string& text, const Rect& screenCoords, int align, const Color& color, - const Point& startInternalPos) + const Point& startInternalPos, + int cursorPos, + const Color& cursorColor) { // prevent glitches from invalid rects if(!screenCoords.isValid()) @@ -219,6 +221,17 @@ void Font::renderText(const std::string& text, // render glyph 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); + } } } diff --git a/src/framework/graphics/font.h b/src/framework/graphics/font.h index 1a5b1c26..b2a2a7c2 100644 --- a/src/framework/graphics/font.h +++ b/src/framework/graphics/font.h @@ -65,7 +65,10 @@ public: const Rect& screenCoords, int align = ALIGN_TOP_LEFT, 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 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); const std::string& getName() const { return m_name; } - + int getGlyphHeight() const { return m_glyphHeight; } + private: void calculateGlyphsWidthsAutomatically(const Size& glyphSize); diff --git a/src/framework/graphics/fonttext.cpp b/src/framework/graphics/fonttext.cpp new file mode 100644 index 00000000..dae0aa61 --- /dev/null +++ b/src/framework/graphics/fonttext.cpp @@ -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" + diff --git a/src/framework/graphics/fonttext.h b/src/framework/graphics/fonttext.h new file mode 100644 index 00000000..edb7f41d --- /dev/null +++ b/src/framework/graphics/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 diff --git a/src/framework/ui/uibutton.cpp b/src/framework/ui/uibutton.cpp index 093037fa..449f0613 100644 --- a/src/framework/ui/uibutton.cpp +++ b/src/framework/ui/uibutton.cpp @@ -23,27 +23,16 @@ #include "uibutton.h" -#include "graphics/fonts.h" -#include "graphics/font.h" -void UIButton::render() +void UIButton::onInputEvent(const InputEvent& event) { - UIElement::render(); - - 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)) { + if(event.type == EV_MOUSE_LDOWN && getRect().contains(event.mousePos)) { 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; if(getRect().contains(event.mousePos)) { if(m_buttonClickCallback) m_buttonClickCallback(); } } - return false; } diff --git a/src/framework/ui/uibutton.h b/src/framework/ui/uibutton.h index 03141474..d22e40b2 100644 --- a/src/framework/ui/uibutton.h +++ b/src/framework/ui/uibutton.h @@ -40,8 +40,7 @@ public: UIElement(); } - virtual void render(); - bool onInputEvent(const InputEvent& event); + void onInputEvent(const InputEvent& event); void setText(const std::string& text) { m_text = text; } const std::string& getText() const { return m_text; } diff --git a/src/framework/ui/uibuttonskin.cpp b/src/framework/ui/uibuttonskin.cpp index 52d48df4..180d2f36 100644 --- a/src/framework/ui/uibuttonskin.cpp +++ b/src/framework/ui/uibuttonskin.cpp @@ -24,27 +24,38 @@ #include "uibuttonskin.h" #include "uibutton.h" +#include "graphics/fonts.h" void UIButtonSkin::draw(UIElement *element) { UIButton *button = static_cast(element); + Rect textRect = button->getRect(); + if(button->getState() == UI::ButtonDown && m_buttonDownImage) { m_buttonDownImage->draw(element->getRect()); + textRect.translate(m_buttonDownTranslate); } else if(button->getState() == UI::ButtonMouseOver && m_buttonHoverImage) { m_buttonHoverImage->draw(element->getRect()); } else { UIElementSkin::draw(element); } + + g_fonts.get("tibia-8px-antialised")->renderText(button->getText(), textRect, ALIGN_CENTER, Color(0xFFEEEEEE)); } void UIButtonSkin::load(const YAML::Node& node) { UIElementSkin::load(node); - if(node.FindValue("down state")) + if(node.FindValue("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")) m_buttonHoverImage = loadImage(node["mouse over state"]); + } diff --git a/src/framework/ui/uibuttonskin.h b/src/framework/ui/uibuttonskin.h index 5b2f2222..74d11689 100644 --- a/src/framework/ui/uibuttonskin.h +++ b/src/framework/ui/uibuttonskin.h @@ -41,6 +41,7 @@ public: private: ImagePtr m_buttonDownImage; ImagePtr m_buttonHoverImage; + Point m_buttonDownTranslate; }; #endif // UIBUTTONSKIN_H diff --git a/src/framework/ui/uicontainer.cpp b/src/framework/ui/uicontainer.cpp index 2f2d61d2..4b4e93c4 100644 --- a/src/framework/ui/uicontainer.cpp +++ b/src/framework/ui/uicontainer.cpp @@ -45,8 +45,8 @@ void UIContainer::addChild(UIElementPtr child) void UIContainer::removeChild(UIElementPtr child) { - if(m_activeElement == child) - setActiveElement(UIElementPtr()); + if(m_focusedElement == child) + setFocusedElement(UIElementPtr()); m_children.remove(child); if(child->getParent() == shared_from_this()) 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) { const UIElementPtr& child = (*it); - if(child->isEnabled() && child->isVisible()) - ret = child->onInputEvent(event) || ret; + bool shouldFire = false; + + // 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; } diff --git a/src/framework/ui/uicontainer.h b/src/framework/ui/uicontainer.h index 0eeeaa55..91cc1086 100644 --- a/src/framework/ui/uicontainer.h +++ b/src/framework/ui/uicontainer.h @@ -41,10 +41,10 @@ public: UIElementPtr recursiveGetChildById(const std::string& id); virtual void render(); - virtual bool onInputEvent(const InputEvent& event); + virtual void onInputEvent(const InputEvent& event); - void setActiveElement(UIElementPtr activeElement); - UIElementPtr getActiveElement() const { return m_activeElement; } + void setFocusedElement(UIElementPtr focusedElement); + UIElementPtr getFocusedElement() const { return m_focusedElement; } virtual UI::EElementType getElementType() const { return UI::Container; } @@ -54,7 +54,7 @@ public: protected: std::list m_children; - UIElementPtr m_activeElement; + UIElementPtr m_focusedElement; }; #endif // UICONTAINER_H diff --git a/src/framework/ui/uielement.cpp b/src/framework/ui/uielement.cpp index 540b6b2d..58f9c835 100644 --- a/src/framework/ui/uielement.cpp +++ b/src/framework/ui/uielement.cpp @@ -31,7 +31,8 @@ UIElement::UIElement(UI::EElementType type) : m_type(type), m_skin(NULL), m_visible(true), - m_enabled(true) + m_enabled(true), + m_focused(false) { // set default skin if(type > UI::Container) @@ -58,7 +59,6 @@ void UIElement::render() m_skin->draw(this); } - UIElementPtr UIElement::backwardsGetElementById(const std::string& id) { if(getId() == id) diff --git a/src/framework/ui/uielement.h b/src/framework/ui/uielement.h index 89f61e55..8984790d 100644 --- a/src/framework/ui/uielement.h +++ b/src/framework/ui/uielement.h @@ -47,7 +47,7 @@ public: virtual ~UIElement() { } virtual void render(); - virtual bool onInputEvent(const InputEvent& event) { return false; } + virtual void onInputEvent(const InputEvent& event) { } UIElementPtr backwardsGetElementById(const std::string& id); @@ -64,6 +64,9 @@ public: void setEnabled(bool enabled) { m_enabled = 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; } bool isVisible() const { return m_visible; } @@ -79,6 +82,7 @@ private: std::string m_id; bool m_visible; bool m_enabled; + bool m_focused; }; #endif // UIELEMENT_H diff --git a/src/framework/ui/uilayout.cpp b/src/framework/ui/uilayout.cpp index 1945ede8..e65b9e9d 100644 --- a/src/framework/ui/uilayout.cpp +++ b/src/framework/ui/uilayout.cpp @@ -52,7 +52,10 @@ int AnchorLine::getPos() const 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 recalculateAnchors(); diff --git a/src/framework/ui/uiloader.cpp b/src/framework/ui/uiloader.cpp index 921bcc78..c4b6c26b 100644 --- a/src/framework/ui/uiloader.cpp +++ b/src/framework/ui/uiloader.cpp @@ -91,6 +91,8 @@ UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& p // now do the real load loadElements(element, doc.begin().second()); + + return element; } catch (YAML::Exception& e) { logFatal("Failed to load ui file \"%s\":\n %s", file.c_str(), e.what()); } diff --git a/src/framework/ui/uiloader.h b/src/framework/ui/uiloader.h index 83a2e9dc..366c9ac2 100644 --- a/src/framework/ui/uiloader.h +++ b/src/framework/ui/uiloader.h @@ -35,7 +35,7 @@ namespace UILoader UIElementPtr createElementFromId(const std::string& id); /// Loads an UIElement and it's children from a YAML file - UIElementPtr loadFile(const std::string& file, const UIContainerPtr& parent); + UIElementPtr loadFile(const std::string& file, const UIContainerPtr& parent = UIContainer::getRootContainer()); /// Populate container children from a YAML node void populateContainer(const UIContainerPtr& parent, const YAML::Node& node); diff --git a/src/framework/ui/uitextedit.cpp b/src/framework/ui/uitextedit.cpp index c5014e15..1b832140 100644 --- a/src/framework/ui/uitextedit.cpp +++ b/src/framework/ui/uitextedit.cpp @@ -27,6 +27,8 @@ UITextEdit::UITextEdit(Font* font) : UIElement(UI::TextEdit), + m_cursorPos(0), + m_startRenderPos(0), m_font(font) { if(!font) @@ -36,10 +38,67 @@ UITextEdit::UITextEdit(Font* font) : void UITextEdit::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) { 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; +} + diff --git a/src/framework/ui/uitextedit.h b/src/framework/ui/uitextedit.h index 056f554b..f9122633 100644 --- a/src/framework/ui/uitextedit.h +++ b/src/framework/ui/uitextedit.h @@ -35,12 +35,24 @@ class UITextEdit : public UIElement public: UITextEdit(Font *font = NULL); + void onInputEvent(const InputEvent& event); + void render(); + void clearText(); void setText(const std::string& text); const std::string& getText() const { return m_text; } + void setCursorPos(uint pos); + uint getCursorPos() { return m_cursorPos; } + private: + void appendCharacter(char c); + void removeCharacter(bool right); + void recalculate(); + + uint m_cursorPos; + int m_startRenderPos; std::string m_text; Font *m_font; }; diff --git a/src/framework/util/point.h b/src/framework/util/point.h index baa4f93b..af05ab30 100644 --- a/src/framework/util/point.h +++ b/src/framework/util/point.h @@ -80,7 +80,6 @@ typedef TPoint PointF; template inline void operator>>(const YAML::Node& node, TPoint& point) { - T x, y; node[0] >> point.x; node[1] >> point.y; } diff --git a/src/menustate.cpp b/src/menustate.cpp index b668d2fe..6178af56 100644 --- a/src/menustate.cpp +++ b/src/menustate.cpp @@ -39,15 +39,20 @@ void MenuState::onEnter() m_background = g_textures.get("background.png"); m_background->enableBilinearFilter(); - UIElementPtr mainMenuPanel = UILoader::loadFile("ui/mainMenu.yml", UIContainer::getRootContainer()); -/* - UIButtonPtr button = std::static_pointer_cast(mainMenuPanel->getChildById("exitGame-button")); - button->onClick([]{ g_engine.stop(); }); - - button = std::static_pointer_cast(mainMenuPanel->getChildById("enterGame-button")); - button->onClick([]{ - UIContainer::load("ui/enterGame-window.yml"); - });*/ + UIContainerPtr mainMenuPanel = UILoader::loadFile("ui/mainMenu.yml")->asUIContainer(); + + UIButtonPtr button = std::static_pointer_cast(mainMenuPanel->getChildById("exitGameButton")); + button->onClick([this]{ + this->onClose(); + }); + + button = std::static_pointer_cast(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() @@ -60,9 +65,9 @@ void MenuState::onClose() g_engine.stop(); } -void MenuState::onInputEvent(const InputEvent& event) +bool MenuState::onInputEvent(const InputEvent& event) { - + return false; } void MenuState::onResize(const Size& size) @@ -84,126 +89,3 @@ void MenuState::render() texCoords.moveBottomRight(texSize.toPoint()); 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); - }); - */ -} diff --git a/src/menustate.h b/src/menustate.h index b71896b4..1069d336 100644 --- a/src/menustate.h +++ b/src/menustate.h @@ -40,7 +40,7 @@ public: void onLeave(); void onClose(); - void onInputEvent(const InputEvent& event); + bool onInputEvent(const InputEvent& event); void onResize(const Size& size); void render(); diff --git a/src/teststate.cpp b/src/teststate.cpp index 091045e4..3bdf398b 100644 --- a/src/teststate.cpp +++ b/src/teststate.cpp @@ -44,9 +44,9 @@ void TestState::onClose() g_engine.stop(); } -void TestState::onInputEvent(const InputEvent& event) +bool TestState::onInputEvent(const InputEvent& event) { - + return false; } void TestState::onResize(const Size& size) diff --git a/src/teststate.h b/src/teststate.h index 8ea12e95..208d2996 100644 --- a/src/teststate.h +++ b/src/teststate.h @@ -37,7 +37,7 @@ public: void onLeave(); void onClose(); - void onInputEvent(const InputEvent& event); + bool onInputEvent(const InputEvent& event); void onResize(const Size& size); virtual void render();