diff --git a/src/controller/FarmlandsGame.cpp b/src/controller/FarmlandsGame.cpp index bef745c..e2cca9e 100644 --- a/src/controller/FarmlandsGame.cpp +++ b/src/controller/FarmlandsGame.cpp @@ -61,7 +61,7 @@ void FarmlandsGame::onRender() { m_gameState.sdlRenderer.renderBegin(); m_gameState.gameRenderer.render(); - m_gameState.guiRenderer.render(); +// m_gameState.guiRenderer.render(); m_guiController.render(); m_gameState.sdlRenderer.renderEnd(); } diff --git a/src/controller/GuiController.cpp b/src/controller/GuiController.cpp index 15e209f..9bd30e9 100644 --- a/src/controller/GuiController.cpp +++ b/src/controller/GuiController.cpp @@ -7,8 +7,8 @@ #include #include -#include -#include +#include +#include #include @@ -37,14 +37,16 @@ void GuiController::initialize(GameState* gameState) m_canvas.setSize(m_gameState->viewport.width, m_gameState->viewport.height); // Add a text element - auto text = new gui::primitives::TextArea(); - text->setText("Hello world!\nMy name is Tibi!\nThis is a really really long long long, even the longest ever, line."); - text->setSize(200, 100); + auto text = new gui::widgets::TextArea(); + text->setText("Hello world!\nMy name is Tibi!\nThis is a really really long long long, even the longest ever, line.\nThis is a very loooooooooooooooooong word."); + text->setSize(200, 200); text->setPosition(100, 10); text->setColor(0, 1, 0); text->setBackColor(0.5f, 0, 0, 0.5f); text->setTextSize(11); - text->setHorizontalWrap(gui::primitives::TextHorizontalWrapping::Ellipsis); + text->setHorizontalWrap(gui::widgets::TextHorizontalWrapping::Wrap); + text->setVerticalWrap(gui::widgets::TextVerticalWrapping::Trim); + text->setAlignment(gui::widgets::TextAlign::BottomRight); m_canvas.addChild(text); } @@ -57,11 +59,11 @@ bool GuiController::processEvent(SDL_Event& event) if (event.type == SDL_EventType::SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_HOME) { - m_canvas.child(0)->setSize(currentW + 50, currentH); + m_canvas.child(0)->setSize(currentW + 5, currentH); } if (event.type == SDL_EventType::SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_END) { - m_canvas.child(0)->setSize(currentW - 50, currentH); + m_canvas.child(0)->setSize(currentW - 5, currentH); } return handled; @@ -70,7 +72,7 @@ bool GuiController::processEvent(SDL_Event& event) void GuiController::render() { // Compute render context - gui::primitives::RenderContext renderContext = + gui::RenderContext renderContext = { .sdlRenderer = &m_gameState->sdlRenderer, .resManager = &m_gameState->resManager, diff --git a/src/controller/GuiController.h b/src/controller/GuiController.h index 4555d46..9ca825e 100644 --- a/src/controller/GuiController.h +++ b/src/controller/GuiController.h @@ -8,7 +8,7 @@ #ifndef CONTROLLER_GUICONTROLLER_H_ #define CONTROLLER_GUICONTROLLER_H_ -#include +#include #include @@ -42,7 +42,7 @@ namespace controller { private: GameState* m_gameState; - gui::Canvas m_canvas; + gui::layout::Canvas m_canvas; }; } /* namespace controller */ diff --git a/src/gui/primitives/RenderContext.h b/src/gui/RenderContext.h similarity index 94% rename from src/gui/primitives/RenderContext.h rename to src/gui/RenderContext.h index cc3c2c5..8676ed9 100644 --- a/src/gui/primitives/RenderContext.h +++ b/src/gui/RenderContext.h @@ -13,7 +13,6 @@ namespace farmlands { namespace gui { -namespace primitives { struct RenderContext { @@ -24,6 +23,5 @@ namespace primitives { } } -} #endif /* GUI_PRIMITIVES_RENDERCONTEXT_H_ */ diff --git a/src/gui/Canvas.cpp b/src/gui/layout/Canvas.cpp similarity index 73% rename from src/gui/Canvas.cpp rename to src/gui/layout/Canvas.cpp index ed68b8d..9560f49 100644 --- a/src/gui/Canvas.cpp +++ b/src/gui/layout/Canvas.cpp @@ -5,10 +5,11 @@ * Author: tibi */ -#include +#include namespace farmlands { namespace gui { +namespace layout { Canvas::Canvas() { @@ -18,11 +19,12 @@ Canvas::~Canvas() { } -void Canvas::render(primitives::RenderContext& context) +void Canvas::render(RenderContext& context) { for (auto child : m_children) child->render(context); } +} } /* namespace gui */ } /* namespace farmlands */ diff --git a/src/gui/Canvas.h b/src/gui/layout/Canvas.h similarity index 78% rename from src/gui/Canvas.h rename to src/gui/layout/Canvas.h index f173f37..165e17a 100644 --- a/src/gui/Canvas.h +++ b/src/gui/layout/Canvas.h @@ -9,10 +9,11 @@ #define GUI_PRIMITIVES_CANVAS_H_ #include -#include +#include namespace farmlands { namespace gui { +namespace layout { class Canvas: public primitives::UILayout { @@ -20,9 +21,10 @@ namespace gui { Canvas(); virtual ~Canvas(); - virtual void render(primitives::RenderContext& context) override; + virtual void render(RenderContext& context) override; }; +} } /* namespace gui */ } /* namespace farmlands */ diff --git a/src/gui/primitives/UIElement.h b/src/gui/primitives/UIElement.h index 344fccc..6e4fc5b 100644 --- a/src/gui/primitives/UIElement.h +++ b/src/gui/primitives/UIElement.h @@ -10,7 +10,7 @@ #include -#include +#include namespace farmlands { namespace gui { diff --git a/src/gui/primitives/Image.cpp b/src/gui/widgets/Image.cpp similarity index 85% rename from src/gui/primitives/Image.cpp rename to src/gui/widgets/Image.cpp index dd9c5dd..bf6d49f 100644 --- a/src/gui/primitives/Image.cpp +++ b/src/gui/widgets/Image.cpp @@ -5,13 +5,13 @@ * Author: tibi */ -#include +#include namespace farmlands { namespace gui { -namespace primitives +namespace widgets { Image::Image() diff --git a/src/gui/primitives/Image.h b/src/gui/widgets/Image.h similarity index 85% rename from src/gui/primitives/Image.h rename to src/gui/widgets/Image.h index 636d844..a55aec3 100644 --- a/src/gui/primitives/Image.h +++ b/src/gui/widgets/Image.h @@ -12,9 +12,9 @@ namespace farmlands { namespace gui { -namespace primitives { +namespace widgets { - class Image: public UIElement + class Image: public primitives::UIElement { public: Image(); diff --git a/src/gui/primitives/TextArea.cpp b/src/gui/widgets/TextArea.cpp similarity index 68% rename from src/gui/primitives/TextArea.cpp rename to src/gui/widgets/TextArea.cpp index 842f060..acf7ab9 100644 --- a/src/gui/primitives/TextArea.cpp +++ b/src/gui/widgets/TextArea.cpp @@ -5,7 +5,7 @@ * Author: tibi */ -#include +#include #include #include @@ -18,7 +18,7 @@ namespace farmlands { namespace gui { -namespace primitives +namespace widgets { TextArea::TextArea() @@ -30,7 +30,8 @@ TextArea::TextArea() m_color(), m_align(TextAlign::MiddleCenter), m_horWrap(TextHorizontalWrapping::Wrap), - m_verWrap(TextVerticalWrapping::Overflow) + m_verWrap(TextVerticalWrapping::Overflow), + m_renderedLines() { } @@ -49,26 +50,51 @@ void TextArea::render(RenderContext& context) // Split text in lines if (m_textChanged) + { wrapText(font); + renderLines(context, font); + } - std::vector lines; - boost::split(lines, m_wrappedText, boost::is_any_of("\n"), boost::token_compress_off); - - // Render lines + // Compute y location of first line int lineH = TTF_FontLineSkip(font); int totalH = 0; - for (auto line : lines) + if (m_align == TextAlign::MiddleLeft || m_align == TextAlign::MiddleCenter || m_align == TextAlign::MiddleRight) { - SDL_Rect dest = - { - (int) x(), (int) (y() + totalH), - 0, 0 - }; + int spaceLeft = height() - lineH * m_renderedLines.size(); + totalH = spaceLeft / 2; + } + else if (m_align == TextAlign::BottomLeft || m_align == TextAlign::BottomCenter || m_align == TextAlign::BottomRight) + { + int spaceLeft = height() - lineH * m_renderedLines.size(); + totalH = spaceLeft; + } - SDL_Texture* tex = context.sdlRenderer->renderText(line.c_str(), font, m_color); - SDL_QueryTexture(tex, NULL, NULL, &dest.w, &dest.h); - SDL_RenderCopy(context.sdlRenderer->internalRenderer(), tex, NULL, &dest); + // Draw each line + for (SDL_Texture* lineTexture : m_renderedLines) + { + SDL_Rect dest; + SDL_QueryTexture(lineTexture, NULL, NULL, &dest.w, &dest.h); + + // Compute X position + dest.x = x(); + + if (m_align == TextAlign::TopCenter || m_align == TextAlign::MiddleCenter || m_align == TextAlign::BottomCenter) + { + int spaceLeft = width() - dest.w; + dest.x += spaceLeft / 2; + } + else if (m_align == TextAlign::TopRight || m_align == TextAlign::MiddleRight || m_align == TextAlign::BottomRight) + { + int spaceLeft = width() - dest.w; + dest.x += spaceLeft; + } + + // Compute Y position + dest.y = y() + totalH; + + // Draw + SDL_RenderCopy(context.sdlRenderer->internalRenderer(), lineTexture, NULL, &dest); totalH += lineH; } @@ -199,17 +225,16 @@ void TextArea::wrapText(TTF_Font* font) } m_wrappedText[wordBegin] = '\n'; + i = wordBegin; - // Trim line + // Trim rest of line if (m_horWrap == TextHorizontalWrapping::Trim || m_horWrap == TextHorizontalWrapping::Ellipsis) { - i = wordBegin + 1; - size_t nextLine = i; - + size_t nextLine = i + 1; while (nextLine < m_wrappedText.size() && m_wrappedText[nextLine] != '\n') ++nextLine; - m_wrappedText.erase(i, nextLine + 1); + m_wrappedText.erase(i, nextLine - i); } } } @@ -227,6 +252,27 @@ void TextArea::wrapText(TTF_Font* font) totalH += lineHeight; } } + + m_wrappedText.erase(m_wrappedText.size() - 1); +} + +void TextArea::renderLines(RenderContext& context, TTF_Font* font) +{ + // Clean up old textures + for (SDL_Texture* tex : m_renderedLines) + SDL_DestroyTexture(tex); + m_renderedLines.clear(); + + // Break down string into lines + std::vector lines; + boost::split(lines, m_wrappedText, boost::is_any_of("\n"), boost::token_compress_off); + + for (std::string line : lines) + { + // Render line + SDL_Texture* tex = context.sdlRenderer->renderText(line, font, m_color); + m_renderedLines.push_back(tex); + } } } /* namespace primitives */ diff --git a/src/gui/primitives/TextArea.h b/src/gui/widgets/TextArea.h similarity index 91% rename from src/gui/primitives/TextArea.h rename to src/gui/widgets/TextArea.h index 8ce76e6..2d8d524 100644 --- a/src/gui/primitives/TextArea.h +++ b/src/gui/widgets/TextArea.h @@ -14,7 +14,7 @@ namespace farmlands { namespace gui { -namespace primitives { +namespace widgets { enum class TextAlign { @@ -43,7 +43,7 @@ namespace primitives { Trim }; - class TextArea: public UIElement + class TextArea: public primitives::UIElement { public: TextArea(); @@ -71,6 +71,7 @@ namespace primitives { private: void wrapText(TTF_Font* font); + void renderLines(RenderContext& context, TTF_Font* font); std::string m_text; std::string m_wrappedText; @@ -82,6 +83,8 @@ namespace primitives { TextAlign m_align; TextHorizontalWrapping m_horWrap; TextVerticalWrapping m_verWrap; + + std::vector m_renderedLines; }; } /* namespace primitives */