bwidgets/src/w/button_impl.cpp

103 lines
3 KiB
C++
Raw Normal View History

2021-08-06 14:22:56 +02:00
#include <cmath>
#include <basic_widgets/core/math.hpp>
2021-08-17 11:40:03 +02:00
#include <basic_widgets/w/button_impl.hpp>
#include <basic_widgets/w/widget_factory.hpp>
2021-07-10 19:55:53 +02:00
using namespace bwidgets;
2021-07-14 17:33:54 +02:00
ButtonImpl::ButtonImpl(Widget* parent) noexcept
: WidgetImpl {parent}, _caption {create_caption(this)}
2021-07-11 17:06:18 +02:00
{
enable_mouse_handler(_widget_area, _viewport);
_caption->alignment = Caption::Alignment::CENTER;
_caption->render_mode(Font::RenderMode::BLENDED);
2021-08-06 14:22:56 +02:00
border_gradient = [this](const int len, const int pos,
const float divider) -> Color {
const auto& end_color = hovered() ? color_bg_hover : color_bg;
return lerp(end_color / divider, end_color, linear(pos, 0, len));
};
2021-07-11 17:06:18 +02:00
}
2021-08-17 11:40:03 +02:00
auto ButtonImpl::size() const noexcept -> Size
{
return _caption->size() + border_size * 2;
}
auto ButtonImpl::text() const noexcept -> std::string_view
{
return _caption->text();
}
void ButtonImpl::text(std::string txt)
2021-06-04 15:43:46 +02:00
{
_caption->text(std::move(txt));
2021-07-16 17:18:13 +02:00
_handle_geometry_change(_viewport);
2021-06-04 15:43:46 +02:00
}
2021-08-17 11:40:03 +02:00
void ButtonImpl::_handle_font_change(const std::shared_ptr<Font>& f)
{
_caption->font(f);
2021-07-16 17:18:13 +02:00
_handle_geometry_change(_viewport);
}
void ButtonImpl::_handle_font_color_change(const Color fg, Color)
{
_caption->font_color_fg(fg);
}
2021-08-17 11:40:03 +02:00
void ButtonImpl::_handle_geometry_change(const SDL_Rect& vp)
2021-06-04 15:43:46 +02:00
{
const auto h = _caption->size().h + 2 * border_size.h;
_widget_area = {0, center_line(vp.h, _caption->size().h) - border_size.h, vp.w, h};
const auto txt_size = _caption->size();
_caption_area = {center_line(vp.w, txt_size.w), center_line(vp.h, txt_size.h),
2021-08-06 14:22:56 +02:00
txt_size.w, txt_size.h};
_caption->viewport(rect_offset(_caption_area, vp));
2021-06-04 15:43:46 +02:00
}
2021-07-16 17:18:13 +02:00
2021-08-17 11:40:03 +02:00
void ButtonImpl::_handle_renderer_change(const std::shared_ptr<Renderer>& r)
2021-07-16 17:18:13 +02:00
{
_caption->renderer(r);
2021-07-16 17:18:13 +02:00
}
2021-08-17 11:40:03 +02:00
void ButtonImpl::_handle_rendering()
2021-07-16 17:18:13 +02:00
{
const Color& c = hovered() ? color_bg_hover : color_bg;
const auto divider = pushed() ? 1.5F : 2.F;
auto x = 0;
auto y = 0;
const auto biggest_dimension =
border_size.w > border_size.h ? border_size.w : border_size.h;
2021-08-24 00:10:09 +02:00
const auto& max_xy = border_size.w > border_size.h ? x : y;
2021-08-27 01:21:25 +02:00
// Render button borders.
while (x < border_size.w || y < border_size.h) {
2021-08-24 00:10:09 +02:00
_renderer->draw_color(border_gradient(biggest_dimension, max_xy, divider))
->draw_rect(rect_margin(_widget_area, {x, y}));
if (x < border_size.w) x++;
if (y < border_size.h) y++;
2021-07-16 17:18:13 +02:00
}
_renderer->draw_color(c)->fill_rect(rect_margin(_widget_area, border_size));
_caption->font_color_bg(c);
_caption->render();
2021-07-16 17:18:13 +02:00
}
void ButtonImpl::_on_push(const bool state)
{
2021-08-27 01:21:25 +02:00
// Move slightly the caption position to give a push effect.
const auto offset = [state, this]() -> SDL_Point {
if (state) {
return {_viewport.x + 1, _viewport.y + 1};
}
return {_viewport.x, _viewport.y};
}();
_caption->viewport(rect_offset(_caption_area, offset));
}