@@ -239,6 +239,61 @@ class vtkF3DRenderDataAssemblyVisitor : public vtkDataAssemblyVisitor
239239};
240240vtkStandardNewMacro (vtkF3DRenderDataAssemblyVisitor);
241241
242+ /* *
243+ * Visitor used to traverse a full tree (one per importer).
244+ * It will take care of estimate the maximum width of the tree nodes in order to set the width of
245+ * the scene hierarchy UI widget.
246+ */
247+ class vtkF3DMaxWidthAssemblyVisitor : public vtkDataAssemblyVisitor
248+ {
249+ public:
250+ static vtkF3DMaxWidthAssemblyVisitor* New ();
251+ vtkTypeMacro (vtkF3DMaxWidthAssemblyVisitor, vtkDataAssemblyVisitor);
252+
253+ float GetMaxWidth () const
254+ {
255+ return this ->MaxWidth ;
256+ }
257+
258+ protected:
259+ bool GetTraverseSubtree (int nodeid) override
260+ {
261+ return this ->GetAssembly ()->GetAttributeOrDefault (nodeid, " f3d_collapsed" , 0 ) == 0 ;
262+ }
263+
264+ void Visit (int nodeid) override
265+ {
266+ const char * defaultLabel =
267+ this ->GetAssembly ()->GetNumberOfChildren (nodeid) > 0 ? " <group>" : " <object>" ;
268+
269+ float width =
270+ ImGui::CalcTextSize (this ->GetAssembly ()->GetAttributeOrDefault (nodeid, " label" , defaultLabel))
271+ .x ;
272+
273+ // arrow or bullet
274+ width += ImGui::GetFontSize ();
275+
276+ // spacing between arrow/bullet and checkbox
277+ width += ImGui::GetStyle ().ItemSpacing .x ;
278+
279+ // checkbox
280+ width += ImGui::GetFontSize () + ImGui::GetStyle ().ItemInnerSpacing .x ;
281+
282+ // indentation for parent nodes
283+ while (nodeid != vtkDataAssembly::GetRootNode ())
284+ {
285+ width += ImGui::GetStyle ().IndentSpacing ;
286+ nodeid = this ->GetAssembly ()->GetParent (nodeid);
287+ }
288+
289+ this ->MaxWidth = std::max (this ->MaxWidth , width);
290+ }
291+
292+ private:
293+ float MaxWidth = 0 .f;
294+ };
295+ vtkStandardNewMacro (vtkF3DMaxWidthAssemblyVisitor);
296+
242297}
243298
244299struct vtkF3DImguiActor ::Internals
@@ -586,8 +641,14 @@ void vtkF3DImguiActor::RenderSceneHierarchy(vtkOpenGLRenderWindow* renWin)
586641 const ImGuiViewport* viewport = ImGui::GetMainViewport ();
587642 assert (viewport);
588643
644+ vtkF3DRenderer* ren = vtkF3DRenderer::SafeDownCast (renWin->GetRenderers ()->GetFirstRenderer ());
645+ assert (ren != nullptr );
646+
647+ vtkF3DMetaImporter* importer = ren->GetMetaImporter ();
648+ assert (importer != nullptr );
649+
589650 constexpr float margin = F3DStyle::GetDefaultMargin ();
590- constexpr float defaultWidth = 200 . f ;
651+ float defaultWidth = this -> CalculateHierarchyWidth (importer) ;
591652 float winHeight = viewport->WorkSize .y - 2 .0f * margin;
592653
593654 float posX = margin;
@@ -608,12 +669,6 @@ void vtkF3DImguiActor::RenderSceneHierarchy(vtkOpenGLRenderWindow* renWin)
608669
609670 ImGui::Begin (" Scene Hierarchy" , nullptr , flags);
610671
611- vtkF3DRenderer* ren = vtkF3DRenderer::SafeDownCast (renWin->GetRenderers ()->GetFirstRenderer ());
612- assert (ren != nullptr );
613-
614- vtkF3DMetaImporter* importer = ren->GetMetaImporter ();
615- assert (importer != nullptr );
616-
617672 for (int i = 0 ; i < importer->GetImporterInfoCount (); i++)
618673 {
619674 vtkF3DMetaImporter::ImporterInfo info = importer->GetImporterInfo (i);
@@ -629,6 +684,30 @@ void vtkF3DImguiActor::RenderSceneHierarchy(vtkOpenGLRenderWindow* renWin)
629684 ImGui::End ();
630685}
631686
687+ // ----------------------------------------------------------------------------
688+ float vtkF3DImguiActor::CalculateHierarchyWidth (vtkF3DMetaImporter* importer)
689+ {
690+ float maxWidth = 0 .0f ;
691+ const float indentPerLevel = ImGui::GetStyle ().IndentSpacing ;
692+ const float treeArrowWidth = ImGui::GetFontSize ();
693+ const float checkboxWidth = ImGui::GetFrameHeight () + ImGui::GetStyle ().ItemInnerSpacing .x ;
694+
695+ for (int i = 0 ; i < importer->GetImporterInfoCount (); i++)
696+ {
697+ vtkF3DMetaImporter::ImporterInfo info = importer->GetImporterInfo (i);
698+
699+ vtkNew<::vtkF3DMaxWidthAssemblyVisitor> visitor;
700+ info.DataAssembly ->Visit (vtkDataAssembly::GetRootNode (), visitor);
701+
702+ maxWidth = std::max (maxWidth, visitor->GetMaxWidth ());
703+ }
704+
705+ float totalWidth =
706+ maxWidth + 2 .0f * ImGui::GetStyle ().WindowPadding .x + ImGui::GetStyle ().ScrollbarSize ;
707+
708+ return std::min (totalWidth, static_cast <float >(this ->SceneHierarchyMaxWidth ));
709+ }
710+
632711// ----------------------------------------------------------------------------
633712void vtkF3DImguiActor::RenderDropZone ()
634713{
0 commit comments