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 std::size_t size() const;
|
||||||
virtual void resize(std::size_t size);
|
virtual void resize(std::size_t size);
|
||||||
virtual void add(std::shared_ptr<element> child);
|
virtual void add(std::shared_ptr<element> child, bool submenu = false);
|
||||||
virtual std::shared_ptr<element> get(std::size_t index);
|
virtual std::shared_ptr<element> get(std::size_t index) const;
|
||||||
|
virtual bool submenu(std::size_t index) const;
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
virtual std::optional<std::size_t> selected() const { return selected_; }
|
virtual std::optional<std::size_t> selected() const { return selected_; }
|
||||||
|
|
@ -35,6 +36,9 @@ namespace psemek::ui
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
// extra width for each element with a submenu
|
||||||
|
virtual int submenu_extra() const { return 0; }
|
||||||
|
|
||||||
// extra distance between successive elements
|
// extra distance between successive elements
|
||||||
virtual int y_extra() const { return 0; }
|
virtual int y_extra() const { return 0; }
|
||||||
|
|
||||||
|
|
@ -43,6 +47,7 @@ namespace psemek::ui
|
||||||
private:
|
private:
|
||||||
container_impl container_;
|
container_impl container_;
|
||||||
box_shape shape_;
|
box_shape shape_;
|
||||||
|
std::vector<bool> submenu_;
|
||||||
|
|
||||||
std::optional<std::size_t> selected_;
|
std::optional<std::size_t> selected_;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,22 +52,27 @@ namespace psemek::ui
|
||||||
|
|
||||||
geom::box<float, 2> selector::size_constraints() const
|
geom::box<float, 2> selector::size_constraints() const
|
||||||
{
|
{
|
||||||
|
auto st = merged_own_style();
|
||||||
|
|
||||||
auto x_range = geom::interval<float>::full();
|
auto x_range = geom::interval<float>::full();
|
||||||
|
|
||||||
float y_sum = 0.f;
|
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;
|
if (!c) continue;
|
||||||
|
|
||||||
auto sc = c->size_constraints();
|
auto sc = c->size_constraints();
|
||||||
|
|
||||||
|
if (submenu_[i])
|
||||||
|
sc[0] += *st->scale * submenu_extra();
|
||||||
|
|
||||||
x_range &= sc[0];
|
x_range &= sc[0];
|
||||||
|
|
||||||
y_sum += sc[1].min;
|
y_sum += sc[1].min;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto st = merged_own_style();
|
|
||||||
|
|
||||||
x_range += (*st->inner_margin)[0] * 2.f;
|
x_range += (*st->inner_margin)[0] * 2.f;
|
||||||
|
|
||||||
y_sum += (*st->inner_margin)[1] * 2.f * container_.size();
|
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);
|
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)
|
for (std::size_t i = 0; i < child_boxes_.size(); ++i)
|
||||||
{
|
{
|
||||||
if (geom::contains(child_boxes_[i], p))
|
if (geom::contains(child_boxes_[i], p))
|
||||||
{
|
{
|
||||||
selected_ = i;
|
new_selected = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new_selected && new_selected != selected_ && submenu_[*new_selected] && callback_)
|
||||||
|
post([cb = callback_, i = *new_selected]{ cb(i); });
|
||||||
|
|
||||||
|
selected_ = new_selected;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,7 +108,7 @@ namespace psemek::ui
|
||||||
{
|
{
|
||||||
if (e.down && e.button == mouse_button::left && selected_)
|
if (e.down && e.button == mouse_button::left && selected_)
|
||||||
{
|
{
|
||||||
if (callback_)
|
if (!submenu_[*selected_] && callback_)
|
||||||
post([cb = callback_, i = *selected_]{ cb(i); });
|
post([cb = callback_, i = *selected_]{ cb(i); });
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -114,21 +124,31 @@ namespace psemek::ui
|
||||||
void selector::resize(std::size_t size)
|
void selector::resize(std::size_t size)
|
||||||
{
|
{
|
||||||
container_.resize(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);
|
return container_.get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool selector::submenu(std::size_t index) const
|
||||||
|
{
|
||||||
|
return submenu_[index];
|
||||||
|
}
|
||||||
|
|
||||||
void selector::clear()
|
void selector::clear()
|
||||||
{
|
{
|
||||||
container_.clear();
|
container_.clear();
|
||||||
|
submenu_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void selector::on_selected(std::function<void(std::size_t)> callback)
|
void selector::on_selected(std::function<void(std::size_t)> callback)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue