more flexible skins
This commit is contained in:
		
							parent
							
								
									da2993d1f9
								
							
						
					
					
						commit
						c3f0ca2b4f
					
				|  | @ -90,6 +90,7 @@ SET(SOURCES | ||||||
|     src/framework/ui/uielement.cpp |     src/framework/ui/uielement.cpp | ||||||
|     src/framework/ui/uielementskin.cpp |     src/framework/ui/uielementskin.cpp | ||||||
|     src/framework/ui/uibuttonskin.cpp |     src/framework/ui/uibuttonskin.cpp | ||||||
|  |     src/framework/ui/uilabelskin.cpp | ||||||
|     src/framework/ui/uicontainer.cpp |     src/framework/ui/uicontainer.cpp | ||||||
|     src/framework/ui/uiskins.cpp |     src/framework/ui/uiskins.cpp | ||||||
|     src/framework/ui/uiloader.cpp |     src/framework/ui/uiloader.cpp | ||||||
|  |  | ||||||
|  | @ -2,6 +2,8 @@ default skin image: tibiaskin.png | ||||||
| 
 | 
 | ||||||
| buttons: | buttons: | ||||||
|   default: |   default: | ||||||
|  |     font: tibia-8px-antialised | ||||||
|  |     text color: [238, 238, 238, 255] | ||||||
|     default size: [86, 20] |     default size: [86, 20] | ||||||
| 
 | 
 | ||||||
|     bordered image: |     bordered image: | ||||||
|  | @ -16,7 +18,7 @@ buttons: | ||||||
|       center: [46,139,84,18] |       center: [46,139,84,18] | ||||||
|      |      | ||||||
|     down state: |     down state: | ||||||
|       translate: [1, 1] |       text 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] | ||||||
|  | @ -46,11 +48,13 @@ panels: | ||||||
|        |        | ||||||
| labels: | labels: | ||||||
|   default: |   default: | ||||||
|     # the default label is empty |     font: tibia-10px-antialised | ||||||
|  |     text color: [238, 238, 238, 255] | ||||||
| 
 | 
 | ||||||
| windows: | windows: | ||||||
|   default: |   default: | ||||||
|     head: |     head: | ||||||
|  |       text color: [143, 143, 143, 255] | ||||||
|       height: 17 |       height: 17 | ||||||
|       font: tibia-10px-antialised |       font: tibia-10px-antialised | ||||||
|       bordered image: |       bordered image: | ||||||
|  |  | ||||||
|  | @ -133,7 +133,7 @@ void Engine::onClose() | ||||||
| void Engine::onResize(const Size& size) | void Engine::onResize(const Size& size) | ||||||
| { | { | ||||||
|     g_graphics.resize(size); |     g_graphics.resize(size); | ||||||
|     UIContainer::getRootContainer()->setSize(size); |     UIContainer::getRootContainer()->setSize(Size(size.width()-1, size.height()-1)); | ||||||
| 
 | 
 | ||||||
|     if(m_currentState) |     if(m_currentState) | ||||||
|         m_currentState->onResize(size); |         m_currentState->onResize(size); | ||||||
|  |  | ||||||
|  | @ -132,11 +132,12 @@ bool Font::load(const std::string& file) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Font::renderText(const std::string& text, | void Font::renderText(const std::string& text, | ||||||
|                       const Point& startPos) |                       const Point& startPos, | ||||||
|  |                       const Color& color) | ||||||
| { | { | ||||||
|     Size boxSize = g_graphics.getScreenSize() - startPos.toSize(); |     Size boxSize = g_graphics.getScreenSize() - startPos.toSize(); | ||||||
|     Rect screenCoords(startPos, boxSize); |     Rect screenCoords(startPos, boxSize); | ||||||
|     Font::renderText(text, screenCoords); |     Font::renderText(text, screenCoords, ALIGN_TOP_LEFT, color); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Font::renderText(const std::string& text, | void Font::renderText(const std::string& text, | ||||||
|  | @ -158,7 +159,7 @@ void Font::renderText(const std::string& text, | ||||||
|     Point *glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize); |     Point *glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize); | ||||||
| 
 | 
 | ||||||
|     for(int i = 0; i < textLenght; ++i) { |     for(int i = 0; i < textLenght; ++i) { | ||||||
|         int glyph = (int)text[i]; |         int glyph = (uchar)text[i]; | ||||||
| 
 | 
 | ||||||
|         // skip invalid glyphs
 |         // skip invalid glyphs
 | ||||||
|         if(glyph < 32) |         if(glyph < 32) | ||||||
|  | @ -253,7 +254,7 @@ Point* Font::calculateGlyphsPositions(const std::string& text, int align, Size * | ||||||
|     if((align & ALIGN_RIGHT || align & ALIGN_HORIZONTAL_CENTER) || textBoxSize) { |     if((align & ALIGN_RIGHT || align & ALIGN_HORIZONTAL_CENTER) || textBoxSize) { | ||||||
|         lineWidths[0] = 0; |         lineWidths[0] = 0; | ||||||
|         for(i = 0; i< numGlyphs; ++i) { |         for(i = 0; i< numGlyphs; ++i) { | ||||||
|             glyph = (int)text[i]; |             glyph = (uchar)text[i]; | ||||||
| 
 | 
 | ||||||
|             if(glyph == (uchar)'\n') { |             if(glyph == (uchar)'\n') { | ||||||
|                 lineWidths[++lines] = 0; |                 lineWidths[++lines] = 0; | ||||||
|  | @ -267,7 +268,7 @@ Point* Font::calculateGlyphsPositions(const std::string& text, int align, Size * | ||||||
|     Point virtualPos(0, m_topMargin); |     Point virtualPos(0, m_topMargin); | ||||||
|     lines = 0; |     lines = 0; | ||||||
|     for(i = 0; i < numGlyphs; ++i) { |     for(i = 0; i < numGlyphs; ++i) { | ||||||
|         glyph = (int)text[i]; |         glyph = (uchar)text[i]; | ||||||
| 
 | 
 | ||||||
|         // store current glyph topLeft
 |         // store current glyph topLeft
 | ||||||
|         glyphsPositions[i] = virtualPos; |         glyphsPositions[i] = virtualPos; | ||||||
|  |  | ||||||
|  | @ -55,7 +55,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     /// Simple text render starting at pos
 |     /// Simple text render starting at pos
 | ||||||
|     void renderText(const std::string& text, |     void renderText(const std::string& text, | ||||||
|                     const Point& startPos); |                     const Point& startPos, | ||||||
|  |                     const Color& color = Color::white); | ||||||
| 
 | 
 | ||||||
|     /** Advanced text render
 |     /** Advanced text render
 | ||||||
|      * screenCoords is the rect that will be filled on the screen |      * screenCoords is the rect that will be filled on the screen | ||||||
|  |  | ||||||
|  | @ -34,11 +34,9 @@ typedef std::function<void()> Callback; | ||||||
| class UIButton : public UIElement | class UIButton : public UIElement | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     UIButton(const std::string& text = std::string()) : UIElement(UI::Button), |     UIButton() : | ||||||
|         m_text(text), |         UIElement(UI::Button), | ||||||
|         m_state(UI::ButtonUp) { |         m_state(UI::ButtonUp) {  } | ||||||
|             UIElement(); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|     void onInputEvent(const InputEvent& event); |     void onInputEvent(const InputEvent& event); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -26,6 +26,27 @@ | ||||||
| #include "uibutton.h" | #include "uibutton.h" | ||||||
| #include "graphics/fonts.h" | #include "graphics/fonts.h" | ||||||
| 
 | 
 | ||||||
|  | void UIButtonSkin::load(const YAML::Node& node) | ||||||
|  | { | ||||||
|  |     UIElementSkin::load(node); | ||||||
|  | 
 | ||||||
|  |     std::string tmp; | ||||||
|  | 
 | ||||||
|  |     m_buttonDownImage = loadImage(node["down state"]); | ||||||
|  | 
 | ||||||
|  |     if(node["down state"].FindValue("text translate")) | ||||||
|  |         node["down state"]["text translate"] >> m_buttonDownTranslate; | ||||||
|  | 
 | ||||||
|  |     if(node.FindValue("mouse over state")) | ||||||
|  |         m_buttonHoverImage = loadImage(node["mouse over state"]); | ||||||
|  | 
 | ||||||
|  |     node["font"] >> tmp; | ||||||
|  |     m_font = g_fonts.get(tmp); | ||||||
|  | 
 | ||||||
|  |     node["text color"] >> m_textColor; | ||||||
|  |     m_textColor = Color::white; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void UIButtonSkin::draw(UIElement *element) | void UIButtonSkin::draw(UIElement *element) | ||||||
| { | { | ||||||
|     UIButton *button = static_cast<UIButton*>(element); |     UIButton *button = static_cast<UIButton*>(element); | ||||||
|  | @ -41,21 +62,5 @@ void UIButtonSkin::draw(UIElement *element) | ||||||
|         UIElementSkin::draw(element); |         UIElementSkin::draw(element); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     g_fonts.get("tibia-8px-antialised")->renderText(button->getText(), textRect, ALIGN_CENTER, Color(0xFFEEEEEE)); |     m_font->renderText(button->getText(), textRect, ALIGN_CENTER, m_textColor); | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void UIButtonSkin::load(const YAML::Node& node) |  | ||||||
| { |  | ||||||
|     UIElementSkin::load(node); |  | ||||||
| 
 |  | ||||||
|     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"]); |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -29,6 +29,8 @@ | ||||||
| #include "uiconstants.h" | #include "uiconstants.h" | ||||||
| #include "uielementskin.h" | #include "uielementskin.h" | ||||||
| 
 | 
 | ||||||
|  | class Font; | ||||||
|  | 
 | ||||||
| class UIButtonSkin : public UIElementSkin | class UIButtonSkin : public UIElementSkin | ||||||
| { | { | ||||||
| public: | public: | ||||||
|  | @ -42,6 +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_textColor; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif // UIBUTTONSKIN_H
 | #endif // UIBUTTONSKIN_H
 | ||||||
|  |  | ||||||
|  | @ -34,15 +34,15 @@ public: | ||||||
|     UIContainer(UI::EElementType type = UI::Container) : UIElement(type) { } |     UIContainer(UI::EElementType type = UI::Container) : UIElement(type) { } | ||||||
|     virtual ~UIContainer() { } |     virtual ~UIContainer() { } | ||||||
| 
 | 
 | ||||||
|  |     virtual void render(); | ||||||
|  |     virtual void onInputEvent(const InputEvent& event); | ||||||
|  | 
 | ||||||
|     void addChild(UIElementPtr child); |     void addChild(UIElementPtr child); | ||||||
|     void removeChild(UIElementPtr child); |     void removeChild(UIElementPtr child); | ||||||
|     UIElementPtr getChildById(const std::string& id); |     UIElementPtr getChildById(const std::string& id); | ||||||
| 
 | 
 | ||||||
|     UIElementPtr recursiveGetChildById(const std::string& id); |     UIElementPtr recursiveGetChildById(const std::string& id); | ||||||
| 
 | 
 | ||||||
|     virtual void render(); |  | ||||||
|     virtual void onInputEvent(const InputEvent& event); |  | ||||||
| 
 |  | ||||||
|     void setFocusedElement(UIElementPtr focusedElement); |     void setFocusedElement(UIElementPtr focusedElement); | ||||||
|     UIElementPtr getFocusedElement() const { return m_focusedElement; } |     UIElementPtr getFocusedElement() const { return m_focusedElement; } | ||||||
| 
 | 
 | ||||||
|  | @ -52,7 +52,7 @@ public: | ||||||
| 
 | 
 | ||||||
|     static UIContainerPtr& getRootContainer(); |     static UIContainerPtr& getRootContainer(); | ||||||
| 
 | 
 | ||||||
| protected: | private: | ||||||
|     std::list<UIElementPtr> m_children; |     std::list<UIElementPtr> m_children; | ||||||
|     UIElementPtr m_focusedElement; |     UIElementPtr m_focusedElement; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -25,6 +25,7 @@ | ||||||
| #include "uielement.h" | #include "uielement.h" | ||||||
| #include "uiskins.h" | #include "uiskins.h" | ||||||
| #include "uielementskin.h" | #include "uielementskin.h" | ||||||
|  | #include <graphics/graphics.h> | ||||||
| 
 | 
 | ||||||
| UIElement::UIElement(UI::EElementType type) : | UIElement::UIElement(UI::EElementType type) : | ||||||
|     UILayout(), |     UILayout(), | ||||||
|  | @ -57,6 +58,7 @@ void UIElement::render() | ||||||
| { | { | ||||||
|     if(m_skin) |     if(m_skin) | ||||||
|         m_skin->draw(this); |         m_skin->draw(this); | ||||||
|  |     //g_graphics.drawBoundingRect(getRect());
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| UIElementPtr UIElement::backwardsGetElementById(const std::string& id) | UIElementPtr UIElement::backwardsGetElementById(const std::string& id) | ||||||
|  |  | ||||||
|  | @ -55,7 +55,7 @@ public: | ||||||
|     void setSkin(UIElementSkin *skin); |     void setSkin(UIElementSkin *skin); | ||||||
|     UIElementSkin *getSkin() { return m_skin; } |     UIElementSkin *getSkin() { return m_skin; } | ||||||
| 
 | 
 | ||||||
|     virtual void setParent(UIContainerPtr parent) { m_parent = parent; } |     void setParent(UIContainerPtr parent) { m_parent = parent; } | ||||||
|     UIContainerPtr getParent() const { return m_parent.lock(); } |     UIContainerPtr getParent() const { return m_parent.lock(); } | ||||||
| 
 | 
 | ||||||
|     void setId(const std::string& id) { m_id = id; } |     void setId(const std::string& id) { m_id = id; } | ||||||
|  | @ -75,6 +75,8 @@ public: | ||||||
|     UIElementPtr asUIElement() { return std::static_pointer_cast<UIElement>(shared_from_this()); } |     UIElementPtr asUIElement() { return std::static_pointer_cast<UIElement>(shared_from_this()); } | ||||||
|     virtual UIContainerPtr asUIContainer() { return UIContainerPtr(); } |     virtual UIContainerPtr asUIContainer() { return UIContainerPtr(); } | ||||||
| 
 | 
 | ||||||
|  |     friend class UIContainer; | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     UI::EElementType m_type; |     UI::EElementType m_type; | ||||||
|     UIContainerWeakPtr m_parent; |     UIContainerWeakPtr m_parent; | ||||||
|  |  | ||||||
|  | @ -24,25 +24,12 @@ | ||||||
| 
 | 
 | ||||||
| #include "uilabel.h" | #include "uilabel.h" | ||||||
| #include "graphics/fonts.h" | #include "graphics/fonts.h" | ||||||
| 
 | #include "uilabelskin.h" | ||||||
| UILabel::UILabel(const std::string& text, Font* font) : |  | ||||||
|     UIElement(UI::Label), |  | ||||||
|     m_text(text), |  | ||||||
|     m_font(font) |  | ||||||
| { |  | ||||||
|     if(!font) |  | ||||||
|         m_font = g_fonts.get("tibia-10px-antialised"); |  | ||||||
|     setSize(m_font->calculateTextRectSize(text)); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void UILabel::render() |  | ||||||
| { |  | ||||||
|     m_font->renderText(m_text, getRect(), ALIGN_LEFT, Color(0xFFBFBFBF)); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| void UILabel::setText(const std::string& text) | void UILabel::setText(const std::string& text) | ||||||
| { | { | ||||||
|     setSize(m_font->calculateTextRectSize(text)); |     UILabelSkin *skin = static_cast<UILabelSkin*>(getSkin()); | ||||||
|  |     setSize(skin->getFont()->calculateTextRectSize(text)); | ||||||
|     m_text = text; |     m_text = text; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -33,16 +33,14 @@ class Font; | ||||||
| class UILabel : public UIElement | class UILabel : public UIElement | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     UILabel(const std::string& text = std::string(), Font *font = NULL); |     UILabel() : | ||||||
| 
 |         UIElement(UI::Label) { } | ||||||
|     void render(); |  | ||||||
| 
 | 
 | ||||||
|     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; } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     std::string m_text; |     std::string m_text; | ||||||
|     Font *m_font; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef std::shared_ptr<UILabel> UILabelPtr; | typedef std::shared_ptr<UILabel> UILabelPtr; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,51 @@ | ||||||
|  | /* 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 "uilabelskin.h" | ||||||
|  | #include "uilabel.h" | ||||||
|  | #include "graphics/fonts.h" | ||||||
|  | 
 | ||||||
|  | void UILabelSkin::load(const YAML::Node& node) | ||||||
|  | { | ||||||
|  |     UIElementSkin::load(node); | ||||||
|  |     std::string tmp; | ||||||
|  | 
 | ||||||
|  |     if(node.FindValue("font")) { | ||||||
|  |         node["font"] >> tmp; | ||||||
|  |         m_font = g_fonts.get(tmp); | ||||||
|  |     } else | ||||||
|  |         m_font = g_fonts.getDefaultFont(); | ||||||
|  | 
 | ||||||
|  |     if(node.FindValue("text color")) | ||||||
|  |         node["text color"] >> m_textColor; | ||||||
|  |     else | ||||||
|  |         m_textColor = Color::white; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UILabelSkin::draw(UIElement *element) | ||||||
|  | { | ||||||
|  |     UILabel *label = static_cast<UILabel*>(element); | ||||||
|  | 
 | ||||||
|  |     m_font->renderText(label->getText(), label->getRect(), ALIGN_TOP_LEFT, m_textColor); | ||||||
|  | } | ||||||
|  | @ -0,0 +1,50 @@ | ||||||
|  | /* 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 UILABELSKIN_H | ||||||
|  | #define UILABELSKIN_H | ||||||
|  | 
 | ||||||
|  | #include "prerequisites.h" | ||||||
|  | #include "uiconstants.h" | ||||||
|  | #include "uielementskin.h" | ||||||
|  | 
 | ||||||
|  | class Font; | ||||||
|  | 
 | ||||||
|  | class UILabelSkin : public UIElementSkin | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     UILabelSkin(const std::string& name) : | ||||||
|  |         UIElementSkin(name, UI::Label) { } | ||||||
|  | 
 | ||||||
|  |     void load(const YAML::Node& node); | ||||||
|  |     void draw(UIElement *element); | ||||||
|  | 
 | ||||||
|  |     Font *getFont() const { return m_font; } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     Font *m_font; | ||||||
|  |     Color m_textColor; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif // UILABELSKIN_H
 | ||||||
|  | @ -58,7 +58,7 @@ void UILayout::setSize(const Size& size) | ||||||
|         m_rect = Rect(0, 0, size); |         m_rect = Rect(0, 0, size); | ||||||
| 
 | 
 | ||||||
|     // rect updated, recalculate itself and anchored elements positions
 |     // rect updated, recalculate itself and anchored elements positions
 | ||||||
|     recalculateAnchors(); |     recalculateLayout(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void UILayout::setRect(const Rect& rect) | void UILayout::setRect(const Rect& rect) | ||||||
|  | @ -66,7 +66,7 @@ void UILayout::setRect(const Rect& rect) | ||||||
|     m_rect = rect; |     m_rect = rect; | ||||||
| 
 | 
 | ||||||
|     // rect updated, recalculate itself and anchored elements positions
 |     // rect updated, recalculate itself and anchored elements positions
 | ||||||
|     recalculateAnchors(); |     recalculateLayout(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool UILayout::addAnchor(EAnchorType type, const AnchorLine& anchorLine) | bool UILayout::addAnchor(EAnchorType type, const AnchorLine& anchorLine) | ||||||
|  | @ -91,7 +91,7 @@ bool UILayout::addAnchor(EAnchorType type, const AnchorLine& anchorLine) | ||||||
|     anchorLine.getRelativeElement()->addAnchoredElement(asUILayout()); |     anchorLine.getRelativeElement()->addAnchoredElement(asUILayout()); | ||||||
| 
 | 
 | ||||||
|     // recalculate itself and anchored elements
 |     // recalculate itself and anchored elements
 | ||||||
|     recalculateAnchors(); |     recalculateLayout(); | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -111,7 +111,7 @@ void UILayout::addAnchoredElement(UILayoutPtr anchoredElement) | ||||||
|         m_anchoredElements.push_back(anchoredElement); |         m_anchoredElements.push_back(anchoredElement); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void UILayout::recalculateAnchors() | void UILayout::recalculateLayout() | ||||||
| { | { | ||||||
|     // recalculate horizontal position
 |     // recalculate horizontal position
 | ||||||
|     if(m_anchors[ANCHOR_HORIZONTAL_CENTER].isValid()) { |     if(m_anchors[ANCHOR_HORIZONTAL_CENTER].isValid()) { | ||||||
|  | @ -145,6 +145,10 @@ void UILayout::recalculateAnchors() | ||||||
|     for(auto it = m_anchoredElements.begin(); it != m_anchoredElements.end(); ++it) { |     for(auto it = m_anchoredElements.begin(); it != m_anchoredElements.end(); ++it) { | ||||||
|         UILayoutPtr element = (*it).lock(); |         UILayoutPtr element = (*it).lock(); | ||||||
|         if(element) |         if(element) | ||||||
|             element->recalculateAnchors(); |             element->recalculateLayout(); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     // fire layotu update event
 | ||||||
|  |     onLayoutRectChange(m_rect); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -98,19 +98,22 @@ public: | ||||||
|     AnchorLine verticalCenter() { return AnchorLine(asUILayout(), ANCHOR_VERTICAL_CENTER); } |     AnchorLine verticalCenter() { return AnchorLine(asUILayout(), ANCHOR_VERTICAL_CENTER); } | ||||||
| 
 | 
 | ||||||
|     // margins
 |     // margins
 | ||||||
|     void setMargin(int top, int left, int bottom, int right) { m_marginLeft = left; m_marginRight = right; m_marginTop = top; m_marginBottom = bottom; recalculateAnchors(); } |     void setMargin(int top, int left, int bottom, int right) { m_marginLeft = left; m_marginRight = right; m_marginTop = top; m_marginBottom = bottom; recalculateLayout(); } | ||||||
|     void setMargin(int horizontal, int vertical) { m_marginLeft = m_marginRight = horizontal; m_marginTop = m_marginBottom = vertical; recalculateAnchors(); } |     void setMargin(int horizontal, int vertical) { m_marginLeft = m_marginRight = horizontal; m_marginTop = m_marginBottom = vertical; recalculateLayout(); } | ||||||
|     void setMargin(int margin) { m_marginLeft = m_marginRight = m_marginTop = m_marginBottom = margin; recalculateAnchors(); } |     void setMargin(int margin) { m_marginLeft = m_marginRight = m_marginTop = m_marginBottom = margin; recalculateLayout(); } | ||||||
|     void setMarginLeft(int margin) { m_marginLeft = margin; recalculateAnchors(); } |     void setMarginLeft(int margin) { m_marginLeft = margin; recalculateLayout(); } | ||||||
|     void setMarginRight(int margin) { m_marginRight = margin; recalculateAnchors(); } |     void setMarginRight(int margin) { m_marginRight = margin; recalculateLayout(); } | ||||||
|     void setMarginTop(int margin) { m_marginTop = margin; recalculateAnchors(); } |     void setMarginTop(int margin) { m_marginTop = margin; recalculateLayout(); } | ||||||
|     void setMarginBottom(int margin) { m_marginBottom = margin; recalculateAnchors(); } |     void setMarginBottom(int margin) { m_marginBottom = margin; recalculateLayout(); } | ||||||
| 
 | 
 | ||||||
|     UILayoutPtr asUILayout() { return shared_from_this(); } |     UILayoutPtr asUILayout() { return shared_from_this(); } | ||||||
| 
 | 
 | ||||||
|  | protected: | ||||||
|  |     virtual void onLayoutRectChange(const Rect& newRect) { } | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     /// Recalculate itself and anchored elements positions
 |     /// Recalculate itself and anchored elements positions
 | ||||||
|     void recalculateAnchors(); |     void recalculateLayout(); | ||||||
|     void addAnchoredElement(UILayoutPtr anchoredElement); |     void addAnchoredElement(UILayoutPtr anchoredElement); | ||||||
| 
 | 
 | ||||||
|     AnchorLine m_anchors[6]; |     AnchorLine m_anchors[6]; | ||||||
|  |  | ||||||
|  | @ -29,6 +29,7 @@ | ||||||
| #include "uibuttonskin.h" | #include "uibuttonskin.h" | ||||||
| #include "uiwindowskin.h" | #include "uiwindowskin.h" | ||||||
| #include "uitexteditskin.h" | #include "uitexteditskin.h" | ||||||
|  | #include "uilabelskin.h" | ||||||
| 
 | 
 | ||||||
| UISkins g_uiSkins; | UISkins g_uiSkins; | ||||||
| 
 | 
 | ||||||
|  | @ -108,12 +109,13 @@ bool UISkins::load(const std::string& file) | ||||||
|                 std::string name; |                 std::string name; | ||||||
|                 it.first() >> name; |                 it.first() >> name; | ||||||
| 
 | 
 | ||||||
|                 UIElementSkin *skin = new UIElementSkin(name, UI::Label); |                 UIElementSkin *skin = new UILabelSkin(name); | ||||||
|                 skin->load(it.second()); |                 skin->load(it.second()); | ||||||
|                 m_elementSkins.push_back(skin); |                 m_elementSkins.push_back(skin); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|         { |         { | ||||||
|             const YAML::Node& node = doc["text edits"]; |             const YAML::Node& node = doc["text edits"]; | ||||||
|             for(auto it = node.begin(); it != node.end(); ++it) { |             for(auto it = node.begin(); it != node.end(); ++it) { | ||||||
|  | @ -125,10 +127,8 @@ bool UISkins::load(const std::string& file) | ||||||
|                 m_elementSkins.push_back(skin); |                 m_elementSkins.push_back(skin); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 |     } catch (YAML::Exception& e) { | ||||||
|          |         logError("Malformed skin file \"%s\":\n  %s", file.c_str(), e.what()); | ||||||
|     } catch (YAML::ParserException& e) { |  | ||||||
|         logError("Malformed font file \"%s\"", file.c_str()); |  | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|     return true; |     return true; | ||||||
|  |  | ||||||
|  | @ -102,3 +102,9 @@ void UITextEdit::setCursorPos(uint pos) | ||||||
|         m_cursorPos = pos; |         m_cursorPos = pos; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void UITextEdit::onLayoutRectChange(const Rect& rect) | ||||||
|  | { | ||||||
|  |     m_textRect = rect; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -46,11 +46,14 @@ public: | ||||||
|     void setCursorPos(uint pos); |     void setCursorPos(uint pos); | ||||||
|     uint getCursorPos() { return m_cursorPos; } |     uint getCursorPos() { return m_cursorPos; } | ||||||
| 
 | 
 | ||||||
|  |     void onLayoutRectChange(const Rect& rect); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     void appendCharacter(char c); |     void appendCharacter(char c); | ||||||
|     void removeCharacter(bool right); |     void removeCharacter(bool right); | ||||||
|     void recalculate(); |     void recalculate(); | ||||||
| 
 | 
 | ||||||
|  |     Rect m_textRect; | ||||||
|     uint m_cursorPos; |     uint m_cursorPos; | ||||||
|     int m_startRenderPos; |     int m_startRenderPos; | ||||||
|     std::string m_text; |     std::string m_text; | ||||||
|  |  | ||||||
|  | @ -31,9 +31,8 @@ | ||||||
| class UIWindow : public UIContainer | class UIWindow : public UIContainer | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     UIWindow(const std::string& title = std::string()) : |     UIWindow() : | ||||||
|         UIContainer(UI::Window), |         UIContainer(UI::Window) { } | ||||||
|         m_title(title) { } |  | ||||||
| 
 | 
 | ||||||
|     void setTitle(const std::string& title) { m_title = title; } |     void setTitle(const std::string& title) { m_title = title; } | ||||||
|     const std::string& getTitle() const { return m_title; } |     const std::string& getTitle() const { return m_title; } | ||||||
|  |  | ||||||
|  | @ -25,6 +25,21 @@ | ||||||
| #include "uiwindow.h" | #include "uiwindow.h" | ||||||
| #include "graphics/fonts.h" | #include "graphics/fonts.h" | ||||||
| 
 | 
 | ||||||
|  | void UIWindowSkin::load(const YAML::Node& node) | ||||||
|  | { | ||||||
|  |     UIElementSkin::load(node); | ||||||
|  | 
 | ||||||
|  |     node["head"]["height"] >> m_headHeight; | ||||||
|  |     m_headImage = loadImage(node["head"]); | ||||||
|  |     m_bodyImage = loadImage(node["body"]); | ||||||
|  | 
 | ||||||
|  |     std::string fontName; | ||||||
|  |     node["head"]["font"] >> fontName; | ||||||
|  |     m_titleFont = g_fonts.get(fontName); | ||||||
|  | 
 | ||||||
|  |     node["head"]["text color"] >> m_headTextColor; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void UIWindowSkin::draw(UIElement* element) | void UIWindowSkin::draw(UIElement* element) | ||||||
| { | { | ||||||
|     UIElementSkin::draw(element); |     UIElementSkin::draw(element); | ||||||
|  | @ -41,20 +56,7 @@ void UIWindowSkin::draw(UIElement* element) | ||||||
|     m_titleFont->renderText(window->getTitle(), |     m_titleFont->renderText(window->getTitle(), | ||||||
|                             headRect, |                             headRect, | ||||||
|                             ALIGN_CENTER, |                             ALIGN_CENTER, | ||||||
|                             Color(0xFF8F8F8F)); |                             m_headTextColor); | ||||||
| 
 | 
 | ||||||
|     m_bodyImage->draw(bodyRect); |     m_bodyImage->draw(bodyRect); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| void UIWindowSkin::load(const YAML::Node& node) |  | ||||||
| { |  | ||||||
|     UIElementSkin::load(node); |  | ||||||
| 
 |  | ||||||
|     node["head"]["height"] >> m_headHeight; |  | ||||||
|     m_headImage = loadImage(node["head"]); |  | ||||||
|     m_bodyImage = loadImage(node["body"]); |  | ||||||
| 
 |  | ||||||
|     std::string fontName; |  | ||||||
|     node["head"]["font"] >> fontName; |  | ||||||
|     m_titleFont = g_fonts.get(fontName); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | @ -43,6 +43,7 @@ private: | ||||||
|     ImagePtr m_bodyImage; |     ImagePtr m_bodyImage; | ||||||
|     Font *m_titleFont; |     Font *m_titleFont; | ||||||
|     int m_headHeight; |     int m_headHeight; | ||||||
|  |     Color m_headTextColor; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif // UIWINDOWSKIN_H
 | #endif // UIWINDOWSKIN_H
 | ||||||
|  |  | ||||||
|  | @ -33,22 +33,22 @@ class Color | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     inline Color() : color(0) { } |     inline Color() : color(0) { } | ||||||
|     inline Color(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) : color(((r & 0xff)<<24) | ((g & 0xff)<<16) | ((b & 0xff)<<8) | (a & 0xff)) { } |     inline Color(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) : color(((a & 0xff)<<24) | ((b & 0xff)<<16) | ((g & 0xff)<<8) | (r & 0xff)) { } | ||||||
|     inline Color(const Color& other) : color(other.color) { } |     inline Color(const Color& other) : color(other.color) { } | ||||||
|     inline Color(RGBA rgba) : color(rgba) { } |     inline Color(RGBA rgba) : color(rgba) { } | ||||||
| 
 | 
 | ||||||
|     inline uint8 r()   const { return (color >> 24) & 0xFF; } |     inline uint8 a()   const { return (color >> 24) & 0xFF; } | ||||||
|     inline uint8 g() const { return (color >> 16) & 0xFF; } |     inline uint8 b() const { return (color >> 16) & 0xFF; } | ||||||
|     inline uint8 b()  const { return (color >> 8) & 0xFF; } |     inline uint8 g()  const { return (color >> 8) & 0xFF; } | ||||||
|     inline uint8 a() const { return color & 0xFF; } |     inline uint8 r() const { return color & 0xFF; } | ||||||
|     inline RGBA rgba() const { return color; } |     inline RGBA rgba() const { return color; } | ||||||
|     inline const uint8* rgbaPtr() const { return (const uint8*)&color; } |     inline const uint8* rgbaPtr() const { return (const uint8*)&color; } | ||||||
| 
 | 
 | ||||||
|     inline void setRed(uint8 r) { color = ((r & 0xff)<<24) | (color & 0x00ffffff); } |     inline void setAlpha(uint8 a) { color = ((a & 0xff)<<24) | (color & 0x00ffffff); } | ||||||
|     inline void setGreen(uint8 g)   { color = ((g & 0xff)<<16) | (color & 0xff00ffff); } |     inline void setBlue(uint8 b)   { color = ((b & 0xff)<<16) | (color & 0xff00ffff); } | ||||||
|     inline void setBlue(uint8 b) { color = ((b & 0xff)<<8) | (color & 0xffff00ff); } |     inline void setGreen(uint8 g) { color = ((g & 0xff)<<8) | (color & 0xffff00ff); } | ||||||
|     inline void setAlpha(uint8 a)  { color = (a & 0xff) | (color & 0xffffff00); } |     inline void setRed(uint8 r)  { color = (r & 0xff) | (color & 0xffffff00); } | ||||||
|     inline void setRGBA(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) { color = ((r & 0xff)<<24) | ((g & 0xff)<<16) | ((b & 0xff)<<8) | (a & 0xff); } |     inline void setRGBA(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) { color = ((a & 0xff)<<24) | ((b & 0xff)<<16) | ((g & 0xff)<<8) | (r & 0xff); } | ||||||
|     inline void setRGBA(uint32 rgba) { color = rgba; } |     inline void setRGBA(uint32 rgba) { color = rgba; } | ||||||
| 
 | 
 | ||||||
|     inline Color& operator=(const Color& other) { color = other.color;  return *this; } |     inline Color& operator=(const Color& other) { color = other.color;  return *this; } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Eduardo Bart
						Eduardo Bart