little fixes/enhancements here and there

This commit is contained in:
Andrea Blankenstijn 2021-07-12 00:58:59 +02:00
parent 59d4f88e3d
commit 7d5bfefff0
16 changed files with 177 additions and 151 deletions

View file

@ -30,10 +30,10 @@ namespace bwidgets::abstract
public MouseHandler
{
protected:
const int _border_width {3};
SDL_Rect _input_area {};
const int _border_width {3};
SDL_Rect _input_area {};
widget::Caption _input_caption;
T _value {};
T _value {};
Input(Widget* parent=nullptr)
: Widget(parent)
@ -103,9 +103,9 @@ namespace bwidgets::abstract
_widget_area = {
0,
utils::math::center_rect(_viewport.h,
_input_caption.text_size().h + 2 * _border_width),
_input_caption.size().h + 2 * _border_width),
_viewport.w,
_input_caption.text_size().h + 2 * _border_width
_input_caption.size().h + 2 * _border_width
};
_input_area = {
_widget_area.x + _border_width,
@ -152,6 +152,7 @@ namespace bwidgets::abstract
SDL_RenderSetViewport(r, &_viewport);
// TODO: smoothstep
for (int i = _border_width; i > 0; i--)
{
SDL_SetRenderDrawColor(
@ -170,7 +171,7 @@ namespace bwidgets::abstract
SDL_RenderDrawRect(r, &border_area);
}
if (MouseHandler::_is_hovered || MouseHandler::_has_focus)
if (MouseHandler::_is_hovered || FocusHandler::_has_focus)
_input_caption.color_bg = color_bg_focused;
else
_input_caption.color_bg = color_bg;
@ -186,7 +187,6 @@ namespace bwidgets::abstract
void value(T new_value)
{
_value = new_value;
_update_widget_area();
}
T value_from_string(std::string s)
@ -242,7 +242,7 @@ namespace bwidgets::abstract
return s;
}
virtual void viewport(SDL_Rect vp)
virtual void viewport(const SDL_Rect& vp)
{
Widget::viewport(vp);

View file

@ -10,17 +10,20 @@ namespace bwidgets::abstract
class Layout : public abstract::Widget
{
protected:
int _interspace = 8;
std::vector<Widget*> _widgets;
virtual void _update_layout() = 0;
public:
Widget::Size margins {4, 4};
virtual ~Layout();
virtual void add_widget(Widget*);
virtual void handle_event(const SDL_Event&);
virtual void render(SDL_Renderer*);
virtual void viewport(SDL_Rect);
virtual void viewport(const SDL_Rect&);
virtual Widget::Size size() const = 0;
};
}

View file

@ -18,7 +18,6 @@ namespace bwidgets::abstract
bool _is_hovered = false;
bool _is_pushed = false;
virtual void _handle_focus_change();
virtual void _handle_mouse_button(const SDL_MouseButtonEvent&,
const SDL_Rect&);
virtual void _handle_mouse_motion(const SDL_MouseMotionEvent&,

View file

@ -30,10 +30,13 @@ namespace bwidgets::abstract
virtual ~Widget();
virtual void handle_event(const SDL_Event&);
virtual int height() const;
virtual void render(SDL_Renderer*);
virtual void viewport(SDL_Rect);
virtual int width() const;
virtual void viewport(const SDL_Rect&);
inline virtual Size size() const
{
return {_widget_area.w, _widget_area.h};
}
};
}

View file

@ -14,13 +14,11 @@ namespace bwidgets::widget
{
protected:
widget::Caption _caption;
SDL_Rect _caption_area;
float _caption_height_multiplicator = 1.2;
SDL_Color _color_foreground = {0, 0, 0, SDL_ALPHA_OPAQUE};
SDL_Rect _caption_area;
float _caption_height_multiplicator {1.2};
SDL_Color _color_foreground {0, 0, 0, SDL_ALPHA_OPAQUE};
void _handle_font_change();
void _update_caption_area();
void _update_widget_area();
public:
@ -30,12 +28,10 @@ namespace bwidgets::widget
Button(Widget* parent=nullptr);
int height() const;
void render(SDL_Renderer*);
const std::string& text() const;
void text(std::string);
void viewport(SDL_Rect);
int width() const;
void render(SDL_Renderer*);
abstract::Widget::Size size() const;
const std::string& text() const;
void text(std::string);
};
}

View file

@ -44,12 +44,12 @@ namespace bwidgets::widget
SDL_Color color_bg {0, 0, 0, SDL_ALPHA_TRANSPARENT};
abstract::Widget::Size margins {3, 0};
Caption(Widget* parent=nullptr);
~Caption();
void color_fg(const SDL_Color&);
void render(SDL_Renderer*);
abstract::Widget::Size size() const;
abstract::Widget::Size text_size() const;
const std::string& text() const;
void text(const std::string&);
};

View file

@ -5,10 +5,13 @@
namespace bwidgets::widget
{
class Horizontal_Layout : public abstract::Layout
class Horizontal_Layout final : public abstract::Layout
{
private:
void _update_layout();
public:
abstract::Widget::Size size() const;
};
}

View file

@ -19,10 +19,10 @@ namespace bwidgets::widget
class Numeric_Input : public abstract::Input<T>
{
private:
Button _increment_button;
SDL_Rect _increment_button_area;
Button _decrement_button;
SDL_Rect _decrement_button_area;
Button _increment_button;
SDL_Rect _increment_button_area;
Button _decrement_button;
SDL_Rect _decrement_button_area;
std::pair<T, T> _value_range {
std::numeric_limits<T>::lowest(),
std::numeric_limits<T>::max()
@ -40,9 +40,9 @@ namespace bwidgets::widget
abstract::Input<T>::_update_widget_area();
const int widest_button =
_increment_button.width() > _decrement_button.width()
? _increment_button.width()
: _decrement_button.width();
_increment_button.size().w
? _increment_button.size().w
: _decrement_button.size().w;
const int button_area_width = 2 * widest_button;
const int spacing = utils::math::center_rect(button_area_width, widest_button);
const int field_width = abstract::Widget::_viewport.w - 2 * button_area_width;
@ -53,16 +53,16 @@ namespace bwidgets::widget
_increment_button_area = {
spacing,
utils::math::center_rect(abstract::Widget::_viewport.h, _increment_button.height()),
_increment_button.width(),
_increment_button.height()
utils::math::center_rect(abstract::Widget::_viewport.h, _increment_button.size().h),
_increment_button.size().w,
_increment_button.size().h
};
_decrement_button_area = {
abstract::Widget::_viewport.w - spacing - _decrement_button.width(),
utils::math::center_rect(abstract::Widget::_viewport.h, _decrement_button.height()),
_decrement_button.width(),
_decrement_button.height()
abstract::Widget::_viewport.w - spacing - _decrement_button.size().w,
utils::math::center_rect(abstract::Widget::_viewport.h, _decrement_button.size().h),
_decrement_button.size().w,
_decrement_button.size().h
};
}
@ -71,12 +71,14 @@ namespace bwidgets::widget
Numeric_Input(abstract::Widget* parent=nullptr)
: abstract::Input<T>(parent),
_increment_button(), // FIXME: parenthood
_decrement_button()
_increment_button(this),
_decrement_button(this)
{
abstract::Input<T>::_input_caption.alignment.h =
widget::Caption::AlignmentH::RIGHT;
_increment_button.text("+");
_increment_button.click_handler = [this](const SDL_MouseButtonEvent&) {
T new_value = this->value() + button_step;
if (_value_range.second - this->value() < button_step)
@ -85,7 +87,9 @@ namespace bwidgets::widget
this->value(new_value);
this->input_text(this->value_to_string(new_value));
};
_decrement_button.text("-");
_decrement_button.click_handler = [this](const SDL_MouseButtonEvent&) {
T new_value = this->value() - button_step;
if (this->value() - _value_range.first < button_step)
@ -157,7 +161,7 @@ namespace bwidgets::widget
_value_range = {min, max};
}
void viewport(SDL_Rect vp)
void viewport(const SDL_Rect& vp)
{
abstract::Input<T>::viewport(vp);

View file

@ -5,10 +5,13 @@
namespace bwidgets::widget
{
class Vertical_Layout : public abstract::Layout
class Vertical_Layout final : public abstract::Layout
{
protected:
private:
void _update_layout();
public:
abstract::Widget::Size size() const;
};
}

View file

@ -8,18 +8,13 @@ using namespace bwidgets;
using namespace bwidgets::utils;
widget::Button::Button(Widget* parent)
: abstract::Widget(parent)
: abstract::Widget(parent),
_caption(parent)
{
_focus_area = _click_area = &_widget_area;
_caption.alignment.h = Caption::AlignmentH::CENTER;
}
int widget::Button::height() const
{
return _caption.text_size().h * _caption_height_multiplicator
+ 2 * border_width;
}
void widget::Button::render(SDL_Renderer* r)
{
Widget::render(r);
@ -78,6 +73,16 @@ void widget::Button::render(SDL_Renderer* r)
_caption.render(r);
}
abstract::Widget::Size widget::Button::size() const
{
return {
(int)(_caption.size().w * _caption_height_multiplicator)
+ 2 * border_width,
(int)(_caption.size().h * _caption_height_multiplicator)
+ 2 * border_width
};
}
const std::string& widget::Button::text() const
{
return _caption.text();
@ -87,31 +92,30 @@ void widget::Button::text(std::string txt)
{
_caption.text(txt);
_update_widget_area();
_update_caption_area();
}
void widget::Button::viewport(SDL_Rect vp)
{
Widget::viewport(vp);
_update_caption_area();
}
int widget::Button::width() const
{
return _caption.text_size().w * _caption_height_multiplicator
+ 2 * border_width;
}
void widget::Button::_handle_font_change()
{
_caption.font(_font);
_update_widget_area();
_update_caption_area();
}
void widget::Button::_update_caption_area()
void widget::Button::_update_widget_area()
{
auto txt_size = _caption.text_size();
int h = _caption.size().h * _caption_height_multiplicator
+ 2 * border_width;
_widget_area = {
0,
math::center_rect(
_viewport.h,
_caption.size().h * _caption_height_multiplicator
) - border_width,
_viewport.w,
h
};
auto txt_size = _caption.size();
_caption_area = {
math::center_rect(_viewport.w, txt_size.w),
@ -126,19 +130,3 @@ void widget::Button::_update_caption_area()
_caption_area.h
});
}
void widget::Button::_update_widget_area()
{
int h = _caption.text_size().h * _caption_height_multiplicator
+ 2 * border_width;
_widget_area = {
0,
math::center_rect(
_viewport.h,
_caption.text_size().h * _caption_height_multiplicator
) - border_width,
_viewport.w,
h
};
}

View file

@ -8,6 +8,11 @@
using namespace bwidgets;
using namespace bwidgets::utils;
widget::Caption::Caption(abstract::Widget* parent)
: abstract::Widget(parent)
{
}
widget::Caption::~Caption()
{
SDL_FreeSurface(_text_surface);
@ -20,23 +25,16 @@ void widget::Caption::color_fg(const SDL_Color& c)
_render_text();
}
void widget::Caption::_handle_font_change()
{
_render_text();
}
void widget::Caption::render(SDL_Renderer* r)
{
Widget::render(r);
_renderer = r;
SDL_RenderSetViewport(r, &_viewport);
SDL_SetRenderDrawColor(r, color_bg.r, color_bg.g, color_bg.b, color_bg.a);
SDL_RenderFillRect(r, &_widget_area);
if (_text_surface== nullptr)
if (_text_surface == nullptr)
return;
if (_text_texture == nullptr || _renderer != r)
@ -84,6 +82,33 @@ void widget::Caption::render(SDL_Renderer* r)
);
}
abstract::Widget::Size widget::Caption::size() const
{
if (_font == nullptr)
return {-1, -1};
abstract::Widget::Size size;
TTF_SizeUTF8(_font, _text.c_str(), &size.w, &size.h);
return size;
}
const std::string& widget::Caption::text() const
{
return _text;
}
void widget::Caption::text(const std::string& t)
{
_text = t;
_render_text();
}
void widget::Caption::_handle_font_change()
{
_render_text();
}
void widget::Caption::_render_text()
{
if (_font == nullptr)
@ -100,26 +125,3 @@ void widget::Caption::_render_text()
_update_widget_area();
}
const std::string& widget::Caption::text() const
{
return _text;
}
void widget::Caption::text(const std::string& t)
{
_text = t;
_render_text();
}
abstract::Widget::Size widget::Caption::text_size() const
{
if (_font == nullptr)
return {-1, -1};
abstract::Widget::Size size;
TTF_SizeUTF8(_font, _text.c_str(), &size.w, &size.h);
return size;
}

View file

@ -2,18 +2,36 @@
using namespace bwidgets;
abstract::Widget::Size widget::Horizontal_Layout::size() const
{
abstract::Widget::Size max {0, 0};
for (const auto* w : _widgets)
{
if (w->size().w > max.w)
max.w = w->size().w;
if (w->size().h > max.h)
max.h = w->size().h;
}
return {
(int)_widgets.size() * max.w + ((int)_widgets.size() + 1) * margins.w,
max.h + 2 * margins.h
};
}
void widget::Horizontal_Layout::_update_layout()
{
int widget_size = (_viewport.w - _widgets.size() * _interspace) / _widgets.size();
int widget_size = (_viewport.w - (_widgets.size() + 1) * margins.w)
/ _widgets.size();
for (std::vector<Widget*>::size_type i = 0; i < _widgets.size(); i++)
{
_widgets.at(i)->viewport({
_viewport.x + (int)(_interspace +
i * (widget_size + _interspace)),
_viewport.y,
widget_size - _interspace,
_viewport.h
_viewport.x + margins.w + (int)i * (widget_size + margins.w),
_viewport.y + margins.h,
widget_size - margins.w,
_viewport.h - margins.h
});
}
}

View file

@ -29,7 +29,7 @@ void abstract::Layout::render(SDL_Renderer* r)
widget_ptr->render(r);
}
void abstract::Layout::viewport(SDL_Rect vp)
void abstract::Layout::viewport(const SDL_Rect& vp)
{
Widget::viewport(vp);
_update_layout();

View file

@ -14,7 +14,8 @@ void abstract::MouseHandler::handle_mouse(const SDL_MouseButtonEvent& ev,
return;
SDL_Point p {ev.x, ev.y};
SDL_Rect vp = math::rect_offset(*_click_area, orig);
SDL_Rect vp {math::rect_offset(*_click_area, orig)};
if (ev.type == SDL_MOUSEBUTTONDOWN)
{
if (SDL_PointInRect(&p, &vp))
@ -45,11 +46,12 @@ void abstract::MouseHandler::handle_mouse(const SDL_MouseButtonEvent& ev,
void abstract::MouseHandler::handle_mouse(const SDL_MouseMotionEvent& ev,
const SDL_Rect& orig)
{
if (_focus_area == nullptr)
if (_click_area == nullptr)
return;
SDL_Point p {ev.x, ev.y};
SDL_Rect vp {math::rect_offset(*_click_area, orig)};
if (SDL_PointInRect(&p, &vp))
_is_hovered = true;
else
@ -59,10 +61,6 @@ void abstract::MouseHandler::handle_mouse(const SDL_MouseMotionEvent& ev,
_handle_mouse_motion(ev, orig);
}
void abstract::MouseHandler::_handle_focus_change()
{
}
void abstract::MouseHandler::_handle_mouse_button(const SDL_MouseButtonEvent&,
const SDL_Rect&)
{

View file

@ -2,17 +2,36 @@
using namespace bwidgets;
abstract::Widget::Size widget::Vertical_Layout::size() const
{
abstract::Widget::Size max {0, 0};
for (const auto* w : _widgets)
{
if (w->size().w > max.w)
max.w = w->size().w;
if (w->size().h > max.h)
max.h = w->size().h;
}
return {
max.w + 2 * margins.w,
(int)_widgets.size() * max.h + ((int)_widgets.size() + 1) * margins.h
};
}
void widget::Vertical_Layout::_update_layout()
{
int widget_size = _viewport.h / _widgets.size();
int widget_size = (_viewport.h - (_widgets.size() + 1) * margins.h)
/ _widgets.size();
for (int i = 0; i < _widgets.size(); i++)
for (std::vector<Widget*>::size_type i = 0; i < _widgets.size(); i++)
{
SDL_Rect widget_vp = {
_viewport.x,
_viewport.y + _interspace / 2 + i * (widget_size + _interspace / 2),
_viewport.w,
widget_size - _interspace,
_viewport.x + margins.w,
_viewport.y + margins.h + (int)i * (widget_size + margins.h),
_viewport.w - margins.w,
widget_size - margins.h,
};
_widgets.at(i)->viewport(widget_vp);
}

View file

@ -19,7 +19,7 @@ abstract::Widget::~Widget()
void abstract::Widget::handle_event(const SDL_Event &ev)
{
if (auto handler = dynamic_cast<KeyboardHandler*>(this);
handler != nullptr)
handler != nullptr)
{
switch (ev.type)
{
@ -34,7 +34,7 @@ void abstract::Widget::handle_event(const SDL_Event &ev)
}
if (auto handler = dynamic_cast<MouseHandler*>(this);
handler != nullptr)
handler != nullptr)
{
switch (ev.type)
{
@ -49,11 +49,6 @@ void abstract::Widget::handle_event(const SDL_Event &ev)
}
}
int abstract::Widget::height() const
{
return _widget_area.h;
}
void abstract::Widget::render(SDL_Renderer* r)
{
SDL_RenderSetViewport(r, NULL);
@ -61,28 +56,23 @@ void abstract::Widget::render(SDL_Renderer* r)
_viewport.x - 1, _viewport.y - 1,
_viewport.w + 2, _viewport.h + 2
};
SDL_SetRenderDrawColor(r, 0, 255, 0, SDL_ALPHA_OPAQUE / 2);
SDL_SetRenderDrawColor(r, 0, 255, 0, SDL_ALPHA_TRANSPARENT);
SDL_RenderDrawRect(r, &dbg_outline);
}
void abstract::Widget::viewport(SDL_Rect vp)
void abstract::Widget::viewport(const SDL_Rect& vp)
{
_viewport = vp;
_update_widget_area();
}
int abstract::Widget::width() const
{
return _widget_area.w;
}
void abstract::Widget::_update_widget_area()
{
_widget_area = {
0,
0,
_viewport.w - 1, // needed?
_viewport.h - 1
_viewport.w,
_viewport.h
};
}