From 251021118a590e0c445a8db447e3c3522fd6d3fc Mon Sep 17 00:00:00 2001 From: MiriShulman Date: Sun, 18 Jan 2026 02:28:59 +0200 Subject: [PATCH 1/4] after adding the fitcher before checking if it's work --- cpp/open3d/visualization/gui/TreeView.cpp | 30 ++++++++++++++++++++--- cpp/open3d/visualization/gui/TreeView.h | 4 +++ cpp/pybind/visualization/gui/gui.cpp | 6 +++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/cpp/open3d/visualization/gui/TreeView.cpp b/cpp/open3d/visualization/gui/TreeView.cpp index 72fca10bd0e..21bcf3e0611 100644 --- a/cpp/open3d/visualization/gui/TreeView.cpp +++ b/cpp/open3d/visualization/gui/TreeView.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include "open3d/visualization/gui/Checkbox.h" #include "open3d/visualization/gui/ColorEdit.h" @@ -212,6 +213,7 @@ struct TreeView::Impl { std::shared_ptr cell; Item *parent = nullptr; std::list children; + std::optional expanded; }; int id_; Item root_; @@ -361,6 +363,21 @@ void TreeView::Layout(const LayoutContext &context) { // to defer layout to Draw(). } +void TreeView::Expand(ItemId id) { + auto it = impl_->id2item_.find(id); + if (it != impl_->id2item_.end()) { + it->second->expanded = true; + } + Invalidate(); +} + +void TreeView::Collapse(ItemId id) { + auto it = impl_->id2item_.find(id); + if (it != impl_->id2item_.end()) { + it->second->expanded = false; + } +} + Widget::DrawResult TreeView::Draw(const DrawContext &context) { auto result = Widget::DrawResult::NONE; auto &frame = GetFrame(); @@ -417,8 +434,12 @@ Widget::DrawResult TreeView::Draw(const DrawContext &context) { colorToImguiRGBA(context.theme.tree_selected_color)); } - int flags = ImGuiTreeNodeFlags_DefaultOpen | - ImGuiTreeNodeFlags_AllowItemOverlap; + int flags = ImGuiTreeNodeFlags_AllowItemOverlap; + bool expanded = item.expanded.value_or(true); + + if (expanded) { + flags |= ImGuiTreeNodeFlags_DefaultOpen; + } if (impl_->can_select_parents_) { flags |= ImGuiTreeNodeFlags_OpenOnDoubleClick; flags |= ImGuiTreeNodeFlags_OpenOnArrow; @@ -465,7 +486,10 @@ Widget::DrawResult TreeView::Draw(const DrawContext &context) { } }; - if (ImGui::TreeNodeEx(item.id_string.c_str(), flags, "%s", "")) { + bool open = ImGui::TreeNodeEx(item.id_string.c_str(), flags, "%s", ""); + item.expanded = open; + + if (open) { DrawThis(item, height, is_selectable); for (auto &child : item.children) { diff --git a/cpp/open3d/visualization/gui/TreeView.h b/cpp/open3d/visualization/gui/TreeView.h index 956f896149e..30cb9b08855 100644 --- a/cpp/open3d/visualization/gui/TreeView.h +++ b/cpp/open3d/visualization/gui/TreeView.h @@ -134,6 +134,10 @@ class TreeView : public Widget { void SetOnSelectionChanged( std::function on_selection_changed); + void Expand(ItemId); + void Collapse(ItemId); + + private: struct Impl; std::unique_ptr impl_; diff --git a/cpp/pybind/visualization/gui/gui.cpp b/cpp/pybind/visualization/gui/gui.cpp index 2d92297062f..6ce1e8b2d31 100644 --- a/cpp/pybind/visualization/gui/gui.cpp +++ b/cpp/pybind/visualization/gui/gui.cpp @@ -1665,6 +1665,12 @@ void pybind_gui_definitions(py::module &m) { .def("set_on_selection_changed", &TreeView::SetOnSelectionChanged, "Sets f(new_item_id) which is called when the user " "changes the selection."); + .def("expand", &TreeView::Expand, + "Expand (open) the given TreeView item.") + + .def("collapse", &TreeView::Collapse, + "Collapse (close) the given TreeView item.") + // ---- TreeView cells ---- auto checkable_cell = static_cast< From 6f49f25691f12bd8c434b620fc5fd96c86692a28 Mon Sep 17 00:00:00 2001 From: MiriShulman Date: Thu, 22 Jan 2026 10:30:23 +0200 Subject: [PATCH 2/4] GUI: add expand / collapse helpers to TreeView --- cpp/open3d/visualization/gui/TreeView.cpp | 2 +- cpp/open3d/visualization/gui/TreeView.h | 1 - cpp/tests/visualization/CMakeLists.txt | 14 +++++++ cpp/tests/visualization/TreeViewTest.cpp | 45 +++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 cpp/tests/visualization/TreeViewTest.cpp diff --git a/cpp/open3d/visualization/gui/TreeView.cpp b/cpp/open3d/visualization/gui/TreeView.cpp index 21bcf3e0611..7a89b26f041 100644 --- a/cpp/open3d/visualization/gui/TreeView.cpp +++ b/cpp/open3d/visualization/gui/TreeView.cpp @@ -368,7 +368,7 @@ void TreeView::Expand(ItemId id) { if (it != impl_->id2item_.end()) { it->second->expanded = true; } - Invalidate(); + // Invalidate(); } void TreeView::Collapse(ItemId id) { diff --git a/cpp/open3d/visualization/gui/TreeView.h b/cpp/open3d/visualization/gui/TreeView.h index 30cb9b08855..64d0e88fcce 100644 --- a/cpp/open3d/visualization/gui/TreeView.h +++ b/cpp/open3d/visualization/gui/TreeView.h @@ -137,7 +137,6 @@ class TreeView : public Widget { void Expand(ItemId); void Collapse(ItemId); - private: struct Impl; std::unique_ptr impl_; diff --git a/cpp/tests/visualization/CMakeLists.txt b/cpp/tests/visualization/CMakeLists.txt index 1d216c0591f..dbee3c13870 100644 --- a/cpp/tests/visualization/CMakeLists.txt +++ b/cpp/tests/visualization/CMakeLists.txt @@ -3,3 +3,17 @@ if (BUILD_GUI) rendering/MaterialModifier.cpp ) endif() + + +add_executable(TreeViewTest + TreeViewTest.cpp +) + +target_link_libraries(TreeViewTest + PRIVATE + Open3D::Open3D +) + +set_target_properties(TreeViewTest PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) diff --git a/cpp/tests/visualization/TreeViewTest.cpp b/cpp/tests/visualization/TreeViewTest.cpp new file mode 100644 index 00000000000..88d6afa28b3 --- /dev/null +++ b/cpp/tests/visualization/TreeViewTest.cpp @@ -0,0 +1,45 @@ +#include +#include + +#include "open3d/visualization/gui/Application.h" +#include "open3d/visualization/gui/Window.h" +#include "open3d/visualization/gui/TreeView.h" +#include "open3d/visualization/gui/Layout.h" + +using namespace open3d::visualization::gui; + +int main() { + auto& app = Application::GetInstance(); + app.Initialize(); + + auto window = std::make_shared("TreeView GUI Test", 400, 300); + + // Layout + auto layout = std::make_shared(10); // spacing = 10 + + // TreeView + auto tree = std::make_shared(); + auto root = tree->GetRootItem(); + tree->AddTextItem(root, "Item A"); + tree->AddTextItem(root, "Item B"); + + layout->AddChild(tree); + window->AddChild(layout); + + app.AddWindow(window); + + // Close automatically after 2 seconds + app.PostToMainThread(nullptr, []() { + // NOTE: + // This is a GUI smoke test. + // The window is shown briefly to ensure TreeView can be + // created, attached, and rendered without crashing. + // The application exits automatically to avoid blocking CI. + + std::this_thread::sleep_for(std::chrono::seconds(2)); + Application::GetInstance().Quit(); + }); + + app.Run(); + return 0; +} From e120d57a37cd7bcb33a4a307b2c558353ff50a65 Mon Sep 17 00:00:00 2001 From: MiriShulman Date: Wed, 25 Feb 2026 16:53:20 +0200 Subject: [PATCH 3/4] Implement TreeView expand/collapse support --- cpp/open3d/visualization/gui/TreeView.cpp | 21 +++++++++++---------- cpp/open3d/visualization/gui/TreeView.h | 4 ++-- cpp/pybind/visualization/gui/gui.cpp | 10 +++------- git | 0 treeview-clean | 0 5 files changed, 16 insertions(+), 19 deletions(-) create mode 100644 git create mode 100644 treeview-clean diff --git a/cpp/open3d/visualization/gui/TreeView.cpp b/cpp/open3d/visualization/gui/TreeView.cpp index 7a89b26f041..821b79c1b14 100644 --- a/cpp/open3d/visualization/gui/TreeView.cpp +++ b/cpp/open3d/visualization/gui/TreeView.cpp @@ -11,9 +11,9 @@ #include #include +#include #include #include -#include #include "open3d/visualization/gui/Checkbox.h" #include "open3d/visualization/gui/ColorEdit.h" @@ -363,19 +363,20 @@ void TreeView::Layout(const LayoutContext &context) { // to defer layout to Draw(). } -void TreeView::Expand(ItemId id) { - auto it = impl_->id2item_.find(id); - if (it != impl_->id2item_.end()) { - it->second->expanded = true; +bool TreeView::IsItemExpanded(ItemId item_id) const { + auto it = impl_->id2item_.find(item_id); + if (it == impl_->id2item_.end()) { + return false; } - // Invalidate(); + return it->second->expanded.value_or(true); } -void TreeView::Collapse(ItemId id) { - auto it = impl_->id2item_.find(id); - if (it != impl_->id2item_.end()) { - it->second->expanded = false; +void TreeView::SetItemExpanded(ItemId item_id, bool expanded) { + auto it = impl_->id2item_.find(item_id); + if (it == impl_->id2item_.end()) { + return; } + it->second->expanded = expanded; } Widget::DrawResult TreeView::Draw(const DrawContext &context) { diff --git a/cpp/open3d/visualization/gui/TreeView.h b/cpp/open3d/visualization/gui/TreeView.h index 64d0e88fcce..d19527492e7 100644 --- a/cpp/open3d/visualization/gui/TreeView.h +++ b/cpp/open3d/visualization/gui/TreeView.h @@ -134,8 +134,8 @@ class TreeView : public Widget { void SetOnSelectionChanged( std::function on_selection_changed); - void Expand(ItemId); - void Collapse(ItemId); + bool IsItemExpanded(ItemId item_id) const; + void SetItemExpanded(ItemId item_id, bool expanded); private: struct Impl; diff --git a/cpp/pybind/visualization/gui/gui.cpp b/cpp/pybind/visualization/gui/gui.cpp index 6ce1e8b2d31..e3f5d0c331b 100644 --- a/cpp/pybind/visualization/gui/gui.cpp +++ b/cpp/pybind/visualization/gui/gui.cpp @@ -1664,13 +1664,9 @@ void pybind_gui_definitions(py::module &m) { "The currently selected item") .def("set_on_selection_changed", &TreeView::SetOnSelectionChanged, "Sets f(new_item_id) which is called when the user " - "changes the selection."); - .def("expand", &TreeView::Expand, - "Expand (open) the given TreeView item.") - - .def("collapse", &TreeView::Collapse, - "Collapse (close) the given TreeView item.") - + "changes the selection.") + .def("is_item_expanded", &TreeView::IsItemExpanded) + .def("set_item_expanded", &TreeView::SetItemExpanded); // ---- TreeView cells ---- auto checkable_cell = static_cast< diff --git a/git b/git new file mode 100644 index 00000000000..e69de29bb2d diff --git a/treeview-clean b/treeview-clean new file mode 100644 index 00000000000..e69de29bb2d From e87e1afa9a09209df93f69edfa0729e10b4e72a8 Mon Sep 17 00:00:00 2001 From: MiriShulman Date: Wed, 18 Mar 2026 18:25:15 +0200 Subject: [PATCH 4/4] fix the file change.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce980c4b417..5a144ccd703 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,6 +70,7 @@ - Fix linker error "library limit of 65535 objects exceeded" with Ninja generator on MSVC (PR #7335) - Download tarballs instead of Git repos for "3rdparty/uvatlas" (PR #7371) - macOS x86_64 not longer supported, only macOS arm64 is supported. +- Add expand/collapse state support for TreeView items in GUI (PR #7451) ## 0.13