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

@ -75,4 +75,15 @@ MainWindow::MainWindow(int32_t w, int32_t h) : GuiFrame(w, h) {
button->setSoundClick(sound);
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(int32_t w, int32_t h);
void process() override;
private:
GuiText *label = nullptr;
GuiTrigger *touchTrigger = nullptr;

View File

@ -41,6 +41,7 @@ GuiText::~GuiText(){
FC_FreeFont(fc_font);
fc_font = nullptr;
}
delete texture;
}
void GuiText::draw(CVideo *pVideo) {
@ -57,7 +58,31 @@ void GuiText::draw(CVideo *pVideo) {
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() {
@ -67,12 +92,12 @@ void GuiText::process() {
auto height = FC_GetColumnHeight(fc_font, maxWidth, text.c_str());
auto width = FC_GetWidth(fc_font, text.c_str());
width = width > maxWidth ? maxWidth : width;
DEBUG_FUNCTION_LINE("width %d height %d", width, height);
this->setSize(width, height);
updateText = false;
}
}
void GuiText::setMaxWidth(float width) {
this->maxWidth = width;
// Rebuild the texture cache.
updateText = true;
}

View File

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

View File

@ -13,6 +13,17 @@ GuiTexture::GuiTexture(const std::string& path) {
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) {
if(!pSurface){
@ -28,30 +39,35 @@ GuiTexture::GuiTexture(SDL_Surface *pSurface) {
* Destructor for the GuiImage class.
*/
GuiTexture::~GuiTexture() {
if(imgSurface){
SDL_FreeSurface(imgSurface);
imgSurface = NULL;
if (this->imgSurface) {
SDL_FreeSurface(this->imgSurface);
this->imgSurface = nullptr;
}
if(texture){
SDL_DestroyTexture(texture);
texture = NULL;
if (this->texture) {
SDL_DestroyTexture(this->texture);
this->texture = nullptr;
}
}
void GuiTexture::draw(CVideo *pVideo) {
if (!this->isVisible()) {
DEBUG_FUNCTION_LINE("not visible!");
return;
}
if(texture == NULL){
SDL_Surface * optimizedSurface = SDL_ConvertSurfaceFormat(imgSurface, pVideo->getPixelFormat(), 0 );
if(optimizedSurface != NULL){
if (texture == NULL && imgSurface) {
SDL_Surface *optimizedSurface = SDL_ConvertSurfaceFormat(imgSurface, pVideo->getPixelFormat(), 0);
if (optimizedSurface != NULL) {
SDL_FreeSurface(imgSurface);
imgSurface = optimizedSurface;
DEBUG_FUNCTION_LINE("Optimized surface");
}
texture = SDL_CreateTextureFromSurface(pVideo->getRenderer(), imgSurface);
}
if (!texture) {
DEBUG_FUNCTION_LINE("no texture!");
return;
}
float currScaleX = getScaleX();
float currScaleY = getScaleY();
@ -59,13 +75,29 @@ void GuiTexture::draw(CVideo *pVideo) {
SDL_Rect rect;
rect.x = getLeft();
rect.y = getTop();
rect.w = currScaleX * getWidth();
rect.w = currScaleX * getWidth();
rect.h = currScaleY * getHeight();
// 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);
}else{
} else {
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 {
public:
explicit GuiTexture(const std::string &path);
GuiTexture(SDL_Surface *pSurface);
explicit GuiTexture(SDL_Texture * texture);
explicit GuiTexture(SDL_Surface *pSurface);
//!Destructor
~GuiTexture() override;
//!Constantly called to draw the image
void draw(CVideo *pVideo) override;
void setBlend(SDL_BlendMode blendMode);
protected:
SDL_Surface *imgSurface = nullptr;
SDL_Texture *texture = nullptr;
SDL_BlendMode blendMode = SDL_BLENDMODE_NONE;
};