Fixed text rendering bug. Organized UI stuff.
This commit is contained in:
parent
70f79935da
commit
d2c335bfa5
@ -61,7 +61,7 @@ void FarmlandsGame::onRender()
|
|||||||
{
|
{
|
||||||
m_gameState.sdlRenderer.renderBegin();
|
m_gameState.sdlRenderer.renderBegin();
|
||||||
m_gameState.gameRenderer.render();
|
m_gameState.gameRenderer.render();
|
||||||
m_gameState.guiRenderer.render();
|
// m_gameState.guiRenderer.render();
|
||||||
m_guiController.render();
|
m_guiController.render();
|
||||||
m_gameState.sdlRenderer.renderEnd();
|
m_gameState.sdlRenderer.renderEnd();
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
#include <GameState.h>
|
#include <GameState.h>
|
||||||
#include <controller/GuiController.h>
|
#include <controller/GuiController.h>
|
||||||
#include <gui/primitives/RenderContext.h>
|
#include <gui/RenderContext.h>
|
||||||
#include <gui/primitives/TextArea.h>
|
#include <gui/widgets/TextArea.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
@ -37,14 +37,16 @@ void GuiController::initialize(GameState* gameState)
|
|||||||
m_canvas.setSize(m_gameState->viewport.width, m_gameState->viewport.height);
|
m_canvas.setSize(m_gameState->viewport.width, m_gameState->viewport.height);
|
||||||
|
|
||||||
// Add a text element
|
// Add a text element
|
||||||
auto text = new gui::primitives::TextArea();
|
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.");
|
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, 100);
|
text->setSize(200, 200);
|
||||||
text->setPosition(100, 10);
|
text->setPosition(100, 10);
|
||||||
text->setColor(0, 1, 0);
|
text->setColor(0, 1, 0);
|
||||||
text->setBackColor(0.5f, 0, 0, 0.5f);
|
text->setBackColor(0.5f, 0, 0, 0.5f);
|
||||||
text->setTextSize(11);
|
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);
|
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)
|
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)
|
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;
|
return handled;
|
||||||
@ -70,7 +72,7 @@ bool GuiController::processEvent(SDL_Event& event)
|
|||||||
void GuiController::render()
|
void GuiController::render()
|
||||||
{
|
{
|
||||||
// Compute render context
|
// Compute render context
|
||||||
gui::primitives::RenderContext renderContext =
|
gui::RenderContext renderContext =
|
||||||
{
|
{
|
||||||
.sdlRenderer = &m_gameState->sdlRenderer,
|
.sdlRenderer = &m_gameState->sdlRenderer,
|
||||||
.resManager = &m_gameState->resManager,
|
.resManager = &m_gameState->resManager,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#ifndef CONTROLLER_GUICONTROLLER_H_
|
#ifndef CONTROLLER_GUICONTROLLER_H_
|
||||||
#define CONTROLLER_GUICONTROLLER_H_
|
#define CONTROLLER_GUICONTROLLER_H_
|
||||||
|
|
||||||
#include <gui/Canvas.h>
|
#include <gui/layout/Canvas.h>
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ namespace controller {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
GameState* m_gameState;
|
GameState* m_gameState;
|
||||||
gui::Canvas m_canvas;
|
gui::layout::Canvas m_canvas;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace controller */
|
} /* namespace controller */
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
namespace primitives {
|
|
||||||
|
|
||||||
struct RenderContext
|
struct RenderContext
|
||||||
{
|
{
|
||||||
@ -24,6 +23,5 @@ namespace primitives {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* GUI_PRIMITIVES_RENDERCONTEXT_H_ */
|
#endif /* GUI_PRIMITIVES_RENDERCONTEXT_H_ */
|
@ -5,10 +5,11 @@
|
|||||||
* Author: tibi
|
* Author: tibi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gui/Canvas.h>
|
#include <gui/layout/Canvas.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
namespace layout {
|
||||||
|
|
||||||
Canvas::Canvas()
|
Canvas::Canvas()
|
||||||
{
|
{
|
||||||
@ -18,11 +19,12 @@ Canvas::~Canvas()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::render(primitives::RenderContext& context)
|
void Canvas::render(RenderContext& context)
|
||||||
{
|
{
|
||||||
for (auto child : m_children)
|
for (auto child : m_children)
|
||||||
child->render(context);
|
child->render(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
} /* namespace gui */
|
} /* namespace gui */
|
||||||
} /* namespace farmlands */
|
} /* namespace farmlands */
|
@ -9,10 +9,11 @@
|
|||||||
#define GUI_PRIMITIVES_CANVAS_H_
|
#define GUI_PRIMITIVES_CANVAS_H_
|
||||||
|
|
||||||
#include <gui/primitives/UILayout.h>
|
#include <gui/primitives/UILayout.h>
|
||||||
#include <gui/primitives/RenderContext.h>
|
#include <gui/RenderContext.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
namespace layout {
|
||||||
|
|
||||||
class Canvas: public primitives::UILayout
|
class Canvas: public primitives::UILayout
|
||||||
{
|
{
|
||||||
@ -20,9 +21,10 @@ namespace gui {
|
|||||||
Canvas();
|
Canvas();
|
||||||
virtual ~Canvas();
|
virtual ~Canvas();
|
||||||
|
|
||||||
virtual void render(primitives::RenderContext& context) override;
|
virtual void render(RenderContext& context) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
} /* namespace gui */
|
} /* namespace gui */
|
||||||
} /* namespace farmlands */
|
} /* namespace farmlands */
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#include <gui/primitives/RenderContext.h>
|
#include <gui/RenderContext.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
* Author: tibi
|
* Author: tibi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gui/primitives/Image.h>
|
#include <gui/widgets/Image.h>
|
||||||
|
|
||||||
namespace farmlands
|
namespace farmlands
|
||||||
{
|
{
|
||||||
namespace gui
|
namespace gui
|
||||||
{
|
{
|
||||||
namespace primitives
|
namespace widgets
|
||||||
{
|
{
|
||||||
|
|
||||||
Image::Image()
|
Image::Image()
|
@ -12,9 +12,9 @@
|
|||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
namespace primitives {
|
namespace widgets {
|
||||||
|
|
||||||
class Image: public UIElement
|
class Image: public primitives::UIElement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Image();
|
Image();
|
@ -5,7 +5,7 @@
|
|||||||
* Author: tibi
|
* Author: tibi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gui/primitives/TextArea.h>
|
#include <gui/widgets/TextArea.h>
|
||||||
#include <resources/Resources.h>
|
#include <resources/Resources.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -18,7 +18,7 @@ namespace farmlands
|
|||||||
{
|
{
|
||||||
namespace gui
|
namespace gui
|
||||||
{
|
{
|
||||||
namespace primitives
|
namespace widgets
|
||||||
{
|
{
|
||||||
|
|
||||||
TextArea::TextArea()
|
TextArea::TextArea()
|
||||||
@ -30,7 +30,8 @@ TextArea::TextArea()
|
|||||||
m_color(),
|
m_color(),
|
||||||
m_align(TextAlign::MiddleCenter),
|
m_align(TextAlign::MiddleCenter),
|
||||||
m_horWrap(TextHorizontalWrapping::Wrap),
|
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
|
// Split text in lines
|
||||||
if (m_textChanged)
|
if (m_textChanged)
|
||||||
|
{
|
||||||
wrapText(font);
|
wrapText(font);
|
||||||
|
renderLines(context, font);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> lines;
|
// Compute y location of first line
|
||||||
boost::split(lines, m_wrappedText, boost::is_any_of("\n"), boost::token_compress_off);
|
|
||||||
|
|
||||||
// Render lines
|
|
||||||
int lineH = TTF_FontLineSkip(font);
|
int lineH = TTF_FontLineSkip(font);
|
||||||
int totalH = 0;
|
int totalH = 0;
|
||||||
|
|
||||||
for (auto line : lines)
|
if (m_align == TextAlign::MiddleLeft || m_align == TextAlign::MiddleCenter || m_align == TextAlign::MiddleRight)
|
||||||
{
|
{
|
||||||
SDL_Rect dest =
|
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) x(), (int) (y() + totalH),
|
int spaceLeft = height() - lineH * m_renderedLines.size();
|
||||||
0, 0
|
totalH = spaceLeft;
|
||||||
};
|
}
|
||||||
|
|
||||||
SDL_Texture* tex = context.sdlRenderer->renderText(line.c_str(), font, m_color);
|
// Draw each line
|
||||||
SDL_QueryTexture(tex, NULL, NULL, &dest.w, &dest.h);
|
for (SDL_Texture* lineTexture : m_renderedLines)
|
||||||
SDL_RenderCopy(context.sdlRenderer->internalRenderer(), tex, NULL, &dest);
|
{
|
||||||
|
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;
|
totalH += lineH;
|
||||||
}
|
}
|
||||||
@ -199,17 +225,16 @@ void TextArea::wrapText(TTF_Font* font)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_wrappedText[wordBegin] = '\n';
|
m_wrappedText[wordBegin] = '\n';
|
||||||
|
i = wordBegin;
|
||||||
|
|
||||||
// Trim line
|
// Trim rest of line
|
||||||
if (m_horWrap == TextHorizontalWrapping::Trim || m_horWrap == TextHorizontalWrapping::Ellipsis)
|
if (m_horWrap == TextHorizontalWrapping::Trim || m_horWrap == TextHorizontalWrapping::Ellipsis)
|
||||||
{
|
{
|
||||||
i = wordBegin + 1;
|
size_t nextLine = i + 1;
|
||||||
size_t nextLine = i;
|
|
||||||
|
|
||||||
while (nextLine < m_wrappedText.size() && m_wrappedText[nextLine] != '\n')
|
while (nextLine < m_wrappedText.size() && m_wrappedText[nextLine] != '\n')
|
||||||
++nextLine;
|
++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;
|
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<std::string> 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 */
|
} /* namespace primitives */
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace gui {
|
namespace gui {
|
||||||
namespace primitives {
|
namespace widgets {
|
||||||
|
|
||||||
enum class TextAlign
|
enum class TextAlign
|
||||||
{
|
{
|
||||||
@ -43,7 +43,7 @@ namespace primitives {
|
|||||||
Trim
|
Trim
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextArea: public UIElement
|
class TextArea: public primitives::UIElement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextArea();
|
TextArea();
|
||||||
@ -71,6 +71,7 @@ namespace primitives {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void wrapText(TTF_Font* font);
|
void wrapText(TTF_Font* font);
|
||||||
|
void renderLines(RenderContext& context, TTF_Font* font);
|
||||||
|
|
||||||
std::string m_text;
|
std::string m_text;
|
||||||
std::string m_wrappedText;
|
std::string m_wrappedText;
|
||||||
@ -82,6 +83,8 @@ namespace primitives {
|
|||||||
TextAlign m_align;
|
TextAlign m_align;
|
||||||
TextHorizontalWrapping m_horWrap;
|
TextHorizontalWrapping m_horWrap;
|
||||||
TextVerticalWrapping m_verWrap;
|
TextVerticalWrapping m_verWrap;
|
||||||
|
|
||||||
|
std::vector<SDL_Texture*> m_renderedLines;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace primitives */
|
} /* namespace primitives */
|
Loading…
Reference in New Issue
Block a user