81 lines
2.3 KiB
C++
81 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include <psemek/ui/element.hpp>
|
|
#include <psemek/ui/box_shape.hpp>
|
|
|
|
#include <vector>
|
|
|
|
namespace psemek::ui
|
|
{
|
|
|
|
struct selector
|
|
: element
|
|
{
|
|
selector();
|
|
~selector() override;
|
|
|
|
void set_parent(element * parent) override;
|
|
|
|
children_range children() const override { return children_range_; }
|
|
|
|
struct shape const & shape() const override { return shape_; }
|
|
|
|
void reshape(geom::box<float, 2> const & box) override;
|
|
|
|
geom::box<float, 2> size_constraints() const override;
|
|
|
|
bool on_event(mouse_move const & e) override;
|
|
bool on_event(mouse_click const & e) override;
|
|
|
|
virtual std::size_t size() const;
|
|
virtual void resize(std::size_t size);
|
|
virtual std::size_t add(std::shared_ptr<element> child);
|
|
virtual std::shared_ptr<element> get(std::size_t index) const;
|
|
virtual void set_submenu(std::size_t index, std::shared_ptr<selector> submenu);
|
|
virtual std::shared_ptr<selector> submenu(std::size_t index) const;
|
|
virtual void clear();
|
|
|
|
virtual geom::interval<float> y_range(std::size_t index) const;
|
|
|
|
using callback_type = std::function<void(std::size_t)>;
|
|
|
|
virtual std::optional<std::size_t> selected() const;
|
|
virtual void on_selected(callback_type callback);
|
|
virtual void on_mouseover(std::function<void(std::optional<std::size_t>)> callback);
|
|
|
|
virtual callback_type on_selected() const;
|
|
|
|
virtual geom::box<float, 2> const & item_box(std::size_t index) const { return child_boxes_[index]; }
|
|
|
|
protected:
|
|
|
|
// extra width for each element with a submenu
|
|
virtual int submenu_extra() const { return 0; }
|
|
|
|
// extra distance between successive elements
|
|
virtual int y_extra() const { return 0; }
|
|
|
|
virtual void on_submenu(std::size_t index);
|
|
|
|
virtual void release_submenu();
|
|
|
|
private:
|
|
std::vector<std::shared_ptr<element>> children_;
|
|
std::vector<element *> children_range_;
|
|
|
|
box_shape shape_;
|
|
std::vector<std::shared_ptr<selector>> submenu_;
|
|
std::optional<std::size_t> active_submenu_;
|
|
float active_submenu_y_ = 0.f;
|
|
|
|
std::vector<geom::box<float, 2>> child_boxes_;
|
|
|
|
std::optional<std::size_t> selected_;
|
|
|
|
callback_type callback_;
|
|
std::function<void(std::optional<std::size_t>)> mouseover_callback_;
|
|
};
|
|
|
|
bool spawn_selector(element * root, std::shared_ptr<selector> selector, geom::point<float, 2> const & position, std::function<void()> on_canceled = nullptr);
|
|
|
|
}
|