Support submenu options in ui::selector
This commit is contained in:
parent
727db57092
commit
cc6691c633
2 changed files with 36 additions and 11 deletions
|
|
@ -26,8 +26,9 @@ namespace psemek::ui
|
|||
|
||||
virtual std::size_t size() const;
|
||||
virtual void resize(std::size_t size);
|
||||
virtual void add(std::shared_ptr<element> child);
|
||||
virtual std::shared_ptr<element> get(std::size_t index);
|
||||
virtual void add(std::shared_ptr<element> child, bool submenu = false);
|
||||
virtual std::shared_ptr<element> get(std::size_t index) const;
|
||||
virtual bool submenu(std::size_t index) const;
|
||||
virtual void clear();
|
||||
|
||||
virtual std::optional<std::size_t> selected() const { return selected_; }
|
||||
|
|
@ -35,6 +36,9 @@ namespace psemek::ui
|
|||
|
||||
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; }
|
||||
|
||||
|
|
@ -43,6 +47,7 @@ namespace psemek::ui
|
|||
private:
|
||||
container_impl container_;
|
||||
box_shape shape_;
|
||||
std::vector<bool> submenu_;
|
||||
|
||||
std::optional<std::size_t> selected_;
|
||||
|
||||
|
|
|
|||
|
|
@ -52,22 +52,27 @@ namespace psemek::ui
|
|||
|
||||
geom::box<float, 2> selector::size_constraints() const
|
||||
{
|
||||
auto st = merged_own_style();
|
||||
|
||||
auto x_range = geom::interval<float>::full();
|
||||
|
||||
float y_sum = 0.f;
|
||||
|
||||
for (auto c : children())
|
||||
for (std::size_t i = 0; i < size(); ++i)
|
||||
{
|
||||
auto c = get(i);
|
||||
if (!c) continue;
|
||||
|
||||
auto sc = c->size_constraints();
|
||||
|
||||
if (submenu_[i])
|
||||
sc[0] += *st->scale * submenu_extra();
|
||||
|
||||
x_range &= sc[0];
|
||||
|
||||
y_sum += sc[1].min;
|
||||
}
|
||||
|
||||
auto st = merged_own_style();
|
||||
|
||||
x_range += (*st->inner_margin)[0] * 2.f;
|
||||
|
||||
y_sum += (*st->inner_margin)[1] * 2.f * container_.size();
|
||||
|
|
@ -81,16 +86,21 @@ namespace psemek::ui
|
|||
{
|
||||
auto const p = geom::cast<float>(e.position);
|
||||
|
||||
selected_ = std::nullopt;
|
||||
std::optional<std::size_t> new_selected;
|
||||
for (std::size_t i = 0; i < child_boxes_.size(); ++i)
|
||||
{
|
||||
if (geom::contains(child_boxes_[i], p))
|
||||
{
|
||||
selected_ = i;
|
||||
new_selected = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_selected && new_selected != selected_ && submenu_[*new_selected] && callback_)
|
||||
post([cb = callback_, i = *new_selected]{ cb(i); });
|
||||
|
||||
selected_ = new_selected;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +108,7 @@ namespace psemek::ui
|
|||
{
|
||||
if (e.down && e.button == mouse_button::left && selected_)
|
||||
{
|
||||
if (callback_)
|
||||
if (!submenu_[*selected_] && callback_)
|
||||
post([cb = callback_, i = *selected_]{ cb(i); });
|
||||
return true;
|
||||
}
|
||||
|
|
@ -114,21 +124,31 @@ namespace psemek::ui
|
|||
void selector::resize(std::size_t size)
|
||||
{
|
||||
container_.resize(size);
|
||||
submenu_.resize(size);
|
||||
}
|
||||
|
||||
void selector::add(std::shared_ptr<element> child)
|
||||
void selector::add(std::shared_ptr<element> child, bool submenu)
|
||||
{
|
||||
container_.add(child);
|
||||
std::size_t index = container_.add(child);
|
||||
if (index >= submenu_.size())
|
||||
submenu_.resize(index + 1);
|
||||
submenu_[index] = submenu;
|
||||
}
|
||||
|
||||
std::shared_ptr<element> selector::get(std::size_t index)
|
||||
std::shared_ptr<element> selector::get(std::size_t index) const
|
||||
{
|
||||
return container_.get(index);
|
||||
}
|
||||
|
||||
bool selector::submenu(std::size_t index) const
|
||||
{
|
||||
return submenu_[index];
|
||||
}
|
||||
|
||||
void selector::clear()
|
||||
{
|
||||
container_.clear();
|
||||
submenu_.clear();
|
||||
}
|
||||
|
||||
void selector::on_selected(std::function<void(std::size_t)> callback)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue