GuiText: Add support rotation

This commit is contained in:
Maschell 2020-08-30 22:06:10 +02:00
parent b596a533ba
commit 65bbe1f82f
6 changed files with 93 additions and 19 deletions

View File

@ -76,3 +76,14 @@ MainWindow::MainWindow(int32_t w, int32_t h) : GuiFrame(w, h) {
button->clicked.connect(this, &MainWindow::test); button->clicked.connect(this, &MainWindow::test);
} }
void MainWindow::process() {
GuiFrame::process();
// Rotate the button for fun.
auto res = button->getAngle() + 1;
if(res > 360){
res = 0;
}
button->setAngle(res);
}

View File

@ -14,7 +14,7 @@ public:
~MainWindow(); ~MainWindow();
MainWindow(int32_t w, int32_t h); MainWindow(int32_t w, int32_t h);
void process() override;
private: private:
GuiText *label = nullptr; GuiText *label = nullptr;
GuiTrigger *touchTrigger = nullptr; GuiTrigger *touchTrigger = nullptr;

View File

@ -41,6 +41,7 @@ GuiText::~GuiText(){
FC_FreeFont(fc_font); FC_FreeFont(fc_font);
fc_font = nullptr; fc_font = nullptr;
} }
delete texture;
} }
void GuiText::draw(CVideo *pVideo) { void GuiText::draw(CVideo *pVideo) {
@ -57,7 +58,31 @@ void GuiText::draw(CVideo *pVideo) {
DEBUG_FUNCTION_LINE("FC_CACHE init done"); DEBUG_FUNCTION_LINE("FC_CACHE init done");
} }
FC_DrawColumnScale(fc_font, pVideo->getRenderer(), getLeft(), getTop(), maxWidth * getScaleX(), {getScaleX(), getScaleY()}, text.c_str()); if(updateText || !texture){
delete texture;
// Create the intermediate texture target
SDL_Texture* temp = SDL_CreateTexture(pVideo->getRenderer(), pVideo->getPixelFormat(), SDL_TEXTUREACCESS_TARGET, width, height);
if(temp){
texture = new GuiTexture(temp);
texture->setParent(this);
texture->setBlend(SDL_BLENDMODE_BLEND);
// Draw the text onto it
SDL_SetRenderTarget(pVideo->getRenderer(), temp);
SDL_SetTextureBlendMode(temp, SDL_BLENDMODE_BLEND);
FC_DrawColumn(fc_font, pVideo->getRenderer(), 0, 0, maxWidth, text.c_str());
SDL_SetRenderTarget(pVideo->getRenderer(), NULL);
updateText = false;
}else{
DEBUG_FUNCTION_LINE("Failed to create texture");
}
}
if(texture){
texture->draw(pVideo);
}
} }
void GuiText::process() { void GuiText::process() {
@ -67,12 +92,12 @@ void GuiText::process() {
auto height = FC_GetColumnHeight(fc_font, maxWidth, text.c_str()); auto height = FC_GetColumnHeight(fc_font, maxWidth, text.c_str());
auto width = FC_GetWidth(fc_font, text.c_str()); auto width = FC_GetWidth(fc_font, text.c_str());
width = width > maxWidth ? maxWidth : width; width = width > maxWidth ? maxWidth : width;
DEBUG_FUNCTION_LINE("width %d height %d", width, height);
this->setSize(width, height); this->setSize(width, height);
updateText = false;
} }
} }
void GuiText::setMaxWidth(float width) { void GuiText::setMaxWidth(float width) {
this->maxWidth = width; this->maxWidth = width;
// Rebuild the texture cache.
updateText = true;
} }

View File

@ -18,6 +18,7 @@
#include "GuiElement.h" #include "GuiElement.h"
#include "SDL_FontCache.h" #include "SDL_FontCache.h"
#include "GuiTexture.h"
#include <mutex> #include <mutex>
#include <SDL2/SDL_ttf.h> #include <SDL2/SDL_ttf.h>
@ -39,6 +40,7 @@ public:
void setMaxWidth(float width); void setMaxWidth(float width);
protected: protected:
GuiTexture* texture = nullptr;
std::string text; std::string text;
int32_t size; int32_t size;
SDL_Color color; SDL_Color color;

View File

@ -13,6 +13,17 @@ GuiTexture::GuiTexture(const std::string& path) {
this->height = imgSurface->h; this->height = imgSurface->h;
} }
GuiTexture::GuiTexture(SDL_Texture *texture) {
if (this->texture) {
SDL_DestroyTexture(this->texture);
this->texture = NULL;
}
this->texture = texture;
int w, h;
SDL_QueryTexture(texture, nullptr, nullptr, &w, &h);
this->setSize(w, h);
}
GuiTexture::GuiTexture(SDL_Surface *pSurface) { GuiTexture::GuiTexture(SDL_Surface *pSurface) {
if(!pSurface){ if(!pSurface){
@ -28,30 +39,35 @@ GuiTexture::GuiTexture(SDL_Surface *pSurface) {
* Destructor for the GuiImage class. * Destructor for the GuiImage class.
*/ */
GuiTexture::~GuiTexture() { GuiTexture::~GuiTexture() {
if(imgSurface){ if (this->imgSurface) {
SDL_FreeSurface(imgSurface); SDL_FreeSurface(this->imgSurface);
imgSurface = NULL; this->imgSurface = nullptr;
} }
if(texture){ if (this->texture) {
SDL_DestroyTexture(texture); SDL_DestroyTexture(this->texture);
texture = NULL; this->texture = nullptr;
} }
} }
void GuiTexture::draw(CVideo *pVideo) { void GuiTexture::draw(CVideo *pVideo) {
if (!this->isVisible()) { if (!this->isVisible()) {
DEBUG_FUNCTION_LINE("not visible!");
return; return;
} }
if(texture == NULL){ if (texture == NULL && imgSurface) {
SDL_Surface * optimizedSurface = SDL_ConvertSurfaceFormat(imgSurface, pVideo->getPixelFormat(), 0 ); SDL_Surface *optimizedSurface = SDL_ConvertSurfaceFormat(imgSurface, pVideo->getPixelFormat(), 0);
if(optimizedSurface != NULL){ if (optimizedSurface != NULL) {
SDL_FreeSurface(imgSurface); SDL_FreeSurface(imgSurface);
imgSurface = optimizedSurface; imgSurface = optimizedSurface;
DEBUG_FUNCTION_LINE("Optimized surface"); DEBUG_FUNCTION_LINE("Optimized surface");
} }
texture = SDL_CreateTextureFromSurface(pVideo->getRenderer(), imgSurface); texture = SDL_CreateTextureFromSurface(pVideo->getRenderer(), imgSurface);
} }
if (!texture) {
DEBUG_FUNCTION_LINE("no texture!");
return;
}
float currScaleX = getScaleX(); float currScaleX = getScaleX();
float currScaleY = getScaleY(); float currScaleY = getScaleY();
@ -59,13 +75,29 @@ void GuiTexture::draw(CVideo *pVideo) {
SDL_Rect rect; SDL_Rect rect;
rect.x = getLeft(); rect.x = getLeft();
rect.y = getTop(); rect.y = getTop();
rect.w = currScaleX * getWidth(); rect.w = currScaleX * getWidth();
rect.h = currScaleY * getHeight(); rect.h = currScaleY * getHeight();
// copy the texture to the rendering context // copy the texture to the rendering context
if(getAngle() == 0){ SDL_BlendMode mode;
SDL_GetRenderDrawBlendMode(pVideo->getRenderer(), &mode);
// adjust blend mode
if(blendMode != mode){
SDL_SetRenderDrawBlendMode(pVideo->getRenderer(), blendMode);
}
if (getAngle() == 0) {
SDL_RenderCopy(pVideo->getRenderer(), texture, NULL, &rect); SDL_RenderCopy(pVideo->getRenderer(), texture, NULL, &rect);
}else{ } else {
SDL_RenderCopyEx(pVideo->getRenderer(), texture, NULL, &rect, getAngle(), NULL, SDL_FLIP_NONE); SDL_RenderCopyEx(pVideo->getRenderer(), texture, NULL, &rect, getAngle(), NULL, SDL_FLIP_NONE);
} }
// Restore blend mode
if(blendMode != mode) {
SDL_SetRenderDrawBlendMode(pVideo->getRenderer(), mode);
}
} }
void GuiTexture::setBlend(SDL_BlendMode blendmode) {
this->blendMode = blendMode;
}

View File

@ -5,15 +5,19 @@
class GuiTexture : public GuiElement { class GuiTexture : public GuiElement {
public: public:
explicit GuiTexture(const std::string &path); explicit GuiTexture(const std::string &path);
explicit GuiTexture(SDL_Texture * texture);
GuiTexture(SDL_Surface *pSurface); explicit GuiTexture(SDL_Surface *pSurface);
//!Destructor //!Destructor
~GuiTexture() override; ~GuiTexture() override;
//!Constantly called to draw the image //!Constantly called to draw the image
void draw(CVideo *pVideo) override; void draw(CVideo *pVideo) override;
void setBlend(SDL_BlendMode blendMode);
protected: protected:
SDL_Surface *imgSurface = nullptr; SDL_Surface *imgSurface = nullptr;
SDL_Texture *texture = nullptr; SDL_Texture *texture = nullptr;
SDL_BlendMode blendMode = SDL_BLENDMODE_NONE;
}; };