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<frame> make_frame() override;
|
||||||
std::shared_ptr<window> make_window(std::string caption) override;
|
std::shared_ptr<window> make_window(std::string caption) override;
|
||||||
std::shared_ptr<slider> make_slider() override;
|
std::shared_ptr<slider> make_slider() override;
|
||||||
|
std::shared_ptr<spinbox> make_spinbox() override;
|
||||||
|
|
||||||
// directions:
|
// directions:
|
||||||
// 0 - up
|
// 0 - up
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include <psemek/ui/image_view.hpp>
|
#include <psemek/ui/image_view.hpp>
|
||||||
#include <psemek/ui/rich_image_view.hpp>
|
#include <psemek/ui/rich_image_view.hpp>
|
||||||
#include <psemek/ui/slider.hpp>
|
#include <psemek/ui/slider.hpp>
|
||||||
|
#include <psemek/ui/spinbox.hpp>
|
||||||
|
|
||||||
#include <psemek/gfx/texture.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<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<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<slider> make_slider();
|
||||||
|
virtual std::shared_ptr<spinbox> make_spinbox();
|
||||||
|
|
||||||
virtual ~element_factory() {}
|
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_;
|
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
|
struct default_element_factory::impl
|
||||||
|
|
@ -516,6 +577,11 @@ namespace psemek::ui
|
||||||
return r;
|
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()
|
std::shared_ptr<slider> default_element_factory::make_slider()
|
||||||
{
|
{
|
||||||
return std::make_shared<slider_impl>();
|
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<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