28#include "sdl_widget.hpp"
29#include "../sdl_utils.hpp"
31#include "res/sdl2_resource_manager.hpp"
33#include <freerdp/log.h>
35#if defined(WITH_SDL_IMAGE_DIALOGS)
39#define TAG CLIENT_TAG("SDL.widget")
41static const SDL_Color backgroundcolor = { 0x38, 0x36, 0x35, 0xff };
43static const Uint32 hpadding = 10;
45SdlWidget::SdlWidget([[maybe_unused]] SDL_Renderer* renderer, SDL_Rect rect,
bool input)
46 : _rect(rect), _input(input)
51 "OpenSans-VariableFont_wdth,wght.ttf");
53 widget_log_error(-1,
"SDLResourceManager::get");
56 _font = TTF_OpenFontRW(ops, 1, 64);
58 widget_log_error(-1,
"TTF_OpenFontRW");
62#if defined(WITH_SDL_IMAGE_DIALOGS)
63SdlWidget::SdlWidget(SDL_Renderer* renderer, SDL_Rect rect, SDL_RWops* ops) : _rect(rect)
67 _image = IMG_LoadTexture_RW(renderer, ops, 1);
69 widget_log_error(-1,
"IMG_LoadTextureTyped_RW");
74SdlWidget::SdlWidget(
SdlWidget&& other) noexcept
75 : _font(other._font), _image(other._image), _rect(other._rect), _input(other._input),
76 _wrap(other._wrap), _text_width(other._text_width)
78 other._font =
nullptr;
79 other._image =
nullptr;
82SDL_Texture* SdlWidget::render_text(SDL_Renderer* renderer,
const std::string& text,
83 SDL_Color fgcolor, SDL_Rect& src, SDL_Rect& dst)
85 auto surface = TTF_RenderUTF8_Blended(_font, text.c_str(), fgcolor);
88 widget_log_error(-1,
"TTF_RenderText_Blended");
92 auto texture = SDL_CreateTextureFromSurface(renderer, surface);
93 SDL_FreeSurface(surface);
96 widget_log_error(-1,
"SDL_CreateTextureFromSurface");
100 TTF_SizeUTF8(_font, text.c_str(), &src.w, &src.h);
109 dst.w -= 2 * hpadding;
110 const auto scale =
static_cast<float>(dst.h) /
static_cast<float>(src.h);
111 const auto sws =
static_cast<float>(src.w) * scale;
112 const auto dws =
static_cast<float>(dst.w) / scale;
113 if (
static_cast<float>(dst.w) > sws)
114 dst.w =
static_cast<int>(sws);
115 if (
static_cast<float>(src.w) > dws)
117 src.x = src.w -
static_cast<int>(dws);
118 src.w =
static_cast<int>(dws);
123static int scale(
int w,
int h)
125 const auto dw =
static_cast<double>(w);
126 const auto dh =
static_cast<double>(h);
127 const auto scale = dh / dw;
128 const auto dr = dh * scale;
129 return static_cast<int>(dr);
132SDL_Texture* SdlWidget::render_text_wrapped(SDL_Renderer* renderer,
const std::string& text,
133 SDL_Color fgcolor, SDL_Rect& src, SDL_Rect& dst)
137 TTF_SizeUTF8(_font,
" ", &w, &h);
139 assert(_text_width <= UINT32_MAX);
140 auto surface = TTF_RenderUTF8_Blended_Wrapped(_font, text.c_str(), fgcolor,
141 static_cast<Uint32
>(_text_width));
144 widget_log_error(-1,
"TTF_RenderText_Blended");
151 auto texture = SDL_CreateTextureFromSurface(renderer, surface);
152 SDL_FreeSurface(surface);
155 widget_log_error(-1,
"SDL_CreateTextureFromSurface");
166 dst.w -= 2 * hpadding;
167 auto dh = scale(src.w, src.h);
168 dst.h = std::min<int>(dh, dst.h);
173SdlWidget::~SdlWidget()
175 TTF_CloseFont(_font);
177 SDL_DestroyTexture(_image);
180bool SdlWidget::error_ex(Sint32 res,
const char* what,
const char* file,
size_t line,
183 static wLog* log =
nullptr;
186 return sdl_log_error_ex(res, log, what, file, line, fkt);
189static bool draw_rect(SDL_Renderer* renderer,
const SDL_Rect* rect, SDL_Color color)
191 const int drc = SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
192 if (widget_log_error(drc,
"SDL_SetRenderDrawColor"))
195 const int rc = SDL_RenderFillRect(renderer, rect);
196 return !widget_log_error(rc,
"SDL_RenderFillRect");
199bool SdlWidget::fill(SDL_Renderer* renderer, SDL_Color color)
201 std::vector<SDL_Color> colors = { color };
202 return fill(renderer, colors);
205bool SdlWidget::fill(SDL_Renderer* renderer,
const std::vector<SDL_Color>& colors)
208 SDL_BlendMode mode = SDL_BLENDMODE_INVALID;
209 SDL_GetRenderDrawBlendMode(renderer, &mode);
210 SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
211 for (
auto color : colors)
213 draw_rect(renderer, &_rect, color);
214 SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD);
216 SDL_SetRenderDrawBlendMode(renderer, mode);
220bool SdlWidget::update_text(SDL_Renderer* renderer,
const std::string& text, SDL_Color fgcolor,
225 if (!fill(renderer, bgcolor))
227 return update_text(renderer, text, fgcolor);
230bool SdlWidget::wrap()
const
235bool SdlWidget::set_wrap(
bool wrap,
size_t width)
242const SDL_Rect& SdlWidget::rect()
const
247bool SdlWidget::update_text(SDL_Renderer* renderer,
const std::string& text, SDL_Color fgcolor)
256 SDL_Texture* texture =
nullptr;
261 auto rc = SDL_QueryTexture(_image,
nullptr,
nullptr, &src.w, &src.h);
263 widget_log_error(rc,
"SDL_QueryTexture");
266 texture = render_text_wrapped(renderer, text, fgcolor, src, dst);
268 texture = render_text(renderer, text, fgcolor, src, dst);
272 const int rc = SDL_RenderCopy(renderer, texture, &src, &dst);
274 SDL_DestroyTexture(texture);
276 return !widget_log_error(rc,
"SDL_RenderCopy");
280bool clear_window(SDL_Renderer* renderer)
284 const int drc = SDL_SetRenderDrawColor(renderer, backgroundcolor.r, backgroundcolor.g,
285 backgroundcolor.b, backgroundcolor.a);
286 if (widget_log_error(drc,
"SDL_SetRenderDrawColor"))
289 const int rcls = SDL_RenderClear(renderer);
290 return !widget_log_error(rcls,
"SDL_RenderClear");
static SDL_RWops * get(const std::string &type, const std::string &id)
static std::string typeFonts()