19 namespace visualization {
23 static const int NO_SELECTION = -1;
24 static int g_next_list_box_id = 1;
25 static const int g_min_visible_items = 3;
37 impl_->imgui_id_ =
"##listview_" +
std::to_string(g_next_list_box_id++);
43 impl_->items_ = items;
44 impl_->selected_index_ = NO_SELECTION;
50 if (impl_->selected_index_ < 0 ||
51 impl_->selected_index_ >=
int(impl_->items_.size())) {
54 return impl_->items_[impl_->selected_index_].c_str();
59 impl_->selected_index_ =
std::min(
int(impl_->items_.size() - 1), index);
64 impl_->max_visible_item_ =
std::max(g_min_visible_items, num);
67 impl_->max_visible_item_ = -1;
72 std::function<
void(
const char *,
bool)> on_value_changed) {
73 impl_->on_value_changed_ = on_value_changed;
78 auto padding = ImGui::GetStyle().FramePadding;
79 auto fh = ImGui::GetFrameHeight();
80 auto *font = ImGui::GetFont();
83 for (
auto &item : impl_->items_) {
84 auto item_size = font->CalcTextSizeA(
float(
context.theme.font_size),
85 float(constraints.
width), 0.0,
91 if (impl_->max_visible_item_ > 0) {
94 h =
std::max((
int)impl_->items_.size(), g_min_visible_items);
95 h =
std::min(h, impl_->max_visible_item_);
102 return Size(0, g_min_visible_items *
context.theme.font_size);
107 ImGui::SetCursorScreenPos(
108 ImVec2(
float(
frame.x),
float(
frame.y) + ImGui::GetScrollY()));
109 ImGui::PushItemWidth(
float(
frame.width));
111 ImGui::PushStyleColor(ImGuiCol_FrameBg,
113 ImGui::PushStyleColor(ImGuiCol_Header,
115 ImGui::PushStyleColor(ImGuiCol_HeaderHovered,
117 ImGui::PushStyleColor(ImGuiCol_HeaderActive,
120 int height_in_items =
124 auto new_selected_idx = impl_->selected_index_;
125 bool is_double_click =
false;
127 if (ImGui::ListBoxHeader(impl_->imgui_id_.c_str(),
128 int(impl_->items_.size()), height_in_items)) {
129 for (
size_t i = 0; i < impl_->items_.size(); ++i) {
130 bool is_selected = (int(i) == impl_->selected_index_);
138 ImGui::PushStyleColor(
139 ImGuiCol_HeaderHovered,
142 ImGui::PushStyleColor(ImGuiCol_HeaderHovered,
145 if (ImGui::Selectable(impl_->items_[i].c_str(), &is_selected,
146 ImGuiSelectableFlags_AllowDoubleClick)) {
148 new_selected_idx = int(i);
153 if (ImGui::IsMouseDoubleClicked(0)) {
154 is_double_click =
true;
157 ImGui::PopStyleColor();
159 ImGui::ListBoxFooter();
161 if (new_selected_idx != impl_->selected_index_ || is_double_click) {
162 impl_->selected_index_ = new_selected_idx;
163 if (impl_->on_value_changed_) {
171 ImGui::PopStyleColor(4);
173 ImGui::PopItemWidth();
DrawResult Draw(const DrawContext &context) override
void SetOnValueChanged(std::function< void(const char *, bool)> on_value_changed)
const char * GetSelectedValue() const
Returns the value of the currently selected item in the list.
int GetSelectedIndex() const
Returns the currently selected item in the list.
Size CalcPreferredSize(const LayoutContext &context, const Constraints &constraints) const override
void SetMaxVisibleItems(int num)
Size CalcMinimumSize(const LayoutContext &context) const override
void SetItems(const std::vector< std::string > &items)
void SetSelectedIndex(int index)
Selects the indicated row of the list. Does not call onValueChanged.
MiniVec< float, N > floor(const MiniVec< float, N > &a)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
ImVec4 colorToImgui(const Color &color)
Generic file read and write utility for python interface.
std::string to_string(const T &n)
std::function< void(const char *, bool)> on_value_changed_
std::vector< std::string > items_