UI spinbox implementation
This commit is contained in:
parent
3faccd1256
commit
27bd390381
6 changed files with 166 additions and 0 deletions
|
|
@ -17,6 +17,7 @@ namespace psemek::ui
|
|||
std::shared_ptr<frame> make_frame() override;
|
||||
std::shared_ptr<window> make_window(std::string caption) override;
|
||||
std::shared_ptr<slider> make_slider() override;
|
||||
std::shared_ptr<spinbox> make_spinbox() override;
|
||||
|
||||
// directions:
|
||||
// 0 - up
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <psemek/ui/image_view.hpp>
|
||||
#include <psemek/ui/rich_image_view.hpp>
|
||||
#include <psemek/ui/slider.hpp>
|
||||
#include <psemek/ui/spinbox.hpp>
|
||||
|
||||
#include <psemek/gfx/texture.hpp>
|
||||
|
||||
|
|
@ -29,6 +30,7 @@ namespace psemek::ui
|
|||
virtual std::shared_ptr<image_view> make_image_view(std::shared_ptr<gfx::texture_2d> image);
|
||||
virtual std::shared_ptr<rich_image_view> make_rich_image_view(std::shared_ptr<gfx::texture_2d> image);
|
||||
virtual std::shared_ptr<slider> make_slider();
|
||||
virtual std::shared_ptr<spinbox> make_spinbox();
|
||||
|
||||
virtual ~element_factory() {}
|
||||
};
|
||||
|
|
|
|||
39
libs/ui/include/psemek/ui/spinbox.hpp
Normal file
39
libs/ui/include/psemek/ui/spinbox.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/ui/element.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace psemek::ui
|
||||
{
|
||||
|
||||
struct spinbox
|
||||
: element
|
||||
{
|
||||
virtual int value() const { return value_; }
|
||||
virtual void set_value(int v);
|
||||
|
||||
virtual geom::interval<int> value_range() const { return value_range_; }
|
||||
virtual void set_value_range(geom::interval<int> i);
|
||||
|
||||
virtual bool wrap() const { return wrap_; }
|
||||
virtual void set_wrap(bool w);
|
||||
|
||||
virtual void inc();
|
||||
virtual void dec();
|
||||
|
||||
using on_value_changed_callback = std::function<void(int)>;
|
||||
|
||||
virtual void on_value_changed(on_value_changed_callback callback);
|
||||
|
||||
protected:
|
||||
virtual void post_value_changed();
|
||||
|
||||
private:
|
||||
int value_ = 0;
|
||||
geom::interval<int> value_range_ = geom::interval<int>::full();
|
||||
bool wrap_ = false;
|
||||
on_value_changed_callback on_value_changed_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -476,6 +476,67 @@ namespace psemek::ui
|
|||
geom::triangle<geom::point<float, 2>> triangle_;
|
||||
};
|
||||
|
||||
struct spinbox_impl
|
||||
: spinbox
|
||||
{
|
||||
spinbox_impl()
|
||||
{
|
||||
auto layout = std::make_shared<grid_layout>();
|
||||
layout->set_row_count(2);
|
||||
|
||||
auto inc_button = std::make_shared<arrow_button_impl>(0);
|
||||
auto dec_button = std::make_shared<arrow_button_impl>(1);
|
||||
|
||||
inc_button->on_click([this]{
|
||||
inc();
|
||||
});
|
||||
|
||||
dec_button->on_click([this]{
|
||||
dec();
|
||||
});
|
||||
|
||||
layout->set(0, 0, inc_button);
|
||||
layout->set(1, 0, dec_button);
|
||||
layout->set_outer_margin(false);
|
||||
|
||||
child_ = layout;
|
||||
children_range_[0] = child_.get();
|
||||
child_->set_parent(this);
|
||||
}
|
||||
|
||||
geom::box<float, 2> size_constraints() const override
|
||||
{
|
||||
return child_->size_constraints();
|
||||
}
|
||||
|
||||
children_range children() const override
|
||||
{
|
||||
return {children_range_};
|
||||
}
|
||||
|
||||
struct shape const & shape() const override
|
||||
{
|
||||
return child_->shape();
|
||||
}
|
||||
|
||||
void reshape(geom::box<float, 2> const & box) override
|
||||
{
|
||||
child_->reshape(box);
|
||||
}
|
||||
|
||||
void draw(painter &) const override
|
||||
{}
|
||||
|
||||
~spinbox_impl()
|
||||
{
|
||||
release_children();
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<element> child_;
|
||||
element * children_range_[1] {nullptr};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
struct default_element_factory::impl
|
||||
|
|
@ -516,6 +577,11 @@ namespace psemek::ui
|
|||
return r;
|
||||
}
|
||||
|
||||
std::shared_ptr<spinbox> default_element_factory::make_spinbox()
|
||||
{
|
||||
return std::make_shared<spinbox_impl>();
|
||||
}
|
||||
|
||||
std::shared_ptr<slider> default_element_factory::make_slider()
|
||||
{
|
||||
return std::make_shared<slider_impl>();
|
||||
|
|
|
|||
|
|
@ -75,4 +75,6 @@ namespace psemek::ui
|
|||
|
||||
std::shared_ptr<slider> element_factory::make_slider() { return nullptr; }
|
||||
|
||||
std::shared_ptr<spinbox> element_factory::make_spinbox() { return nullptr; }
|
||||
|
||||
}
|
||||
|
|
|
|||
56
libs/ui/source/spinbox.cpp
Normal file
56
libs/ui/source/spinbox.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include <psemek/ui/spinbox.hpp>
|
||||
|
||||
namespace psemek::ui
|
||||
{
|
||||
|
||||
void spinbox::set_value(int v)
|
||||
{
|
||||
v = geom::clamp(v, value_range_);
|
||||
if (v != value_)
|
||||
{
|
||||
value_ = v;
|
||||
post_value_changed();
|
||||
}
|
||||
}
|
||||
|
||||
void spinbox::set_value_range(geom::interval<int> i)
|
||||
{
|
||||
value_range_ = i;
|
||||
set_value(value_);
|
||||
}
|
||||
|
||||
void spinbox::set_wrap(bool w)
|
||||
{
|
||||
wrap_ = w;
|
||||
}
|
||||
|
||||
void spinbox::inc()
|
||||
{
|
||||
if (wrap_)
|
||||
set_value(((value_ + 1 - value_range_.min) % (value_range_.length() + 1)) + value_range_.min);
|
||||
else
|
||||
set_value(value_ + 1);
|
||||
}
|
||||
|
||||
void spinbox::dec()
|
||||
{
|
||||
int const range = value_range_.length() + 1;
|
||||
if (wrap_)
|
||||
set_value(((value_ + range - 1 - value_range_.min) % range) + value_range_.min);
|
||||
else
|
||||
set_value(value_ - 1);
|
||||
}
|
||||
|
||||
void spinbox::on_value_changed(on_value_changed_callback callback)
|
||||
{
|
||||
on_value_changed_ = std::move(callback);
|
||||
post_value_changed();
|
||||
}
|
||||
|
||||
void spinbox::post_value_changed()
|
||||
{
|
||||
if (on_value_changed_)
|
||||
post([cb = on_value_changed_, v = value_]{ cb(v); });
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue