From 66959b7ad640406a365595bb1f9ab085b6df8957 Mon Sep 17 00:00:00 2001 From: kovacsv Date: Mon, 8 Nov 2021 12:20:36 +0100 Subject: [PATCH] Add icon bar to the meshes panel. --- website/o3dv/css/website.css | 31 +++++++-- website/o3dv/js/featureset.js | 2 +- website/o3dv/js/navigator.js | 3 + website/o3dv/js/navigatoritems.js | 14 +++- website/o3dv/js/navigatorpanels.js | 108 ++++++++++++++++++++++++++--- website/o3dv/js/panelset.js | 2 +- website/o3dv/js/treeview.js | 50 +++++++++---- 7 files changed, 176 insertions(+), 34 deletions(-) diff --git a/website/o3dv/css/website.css b/website/o3dv/css/website.css index e7a21b2..dd0842c 100644 --- a/website/o3dv/css/website.css +++ b/website/o3dv/css/website.css @@ -148,10 +148,6 @@ div.ov_toolbar div.ov_toolbar_button { float: left; cursor: pointer; -} - -div.ov_toolbar div.ov_toolbar_button div.ov_svg_icon -{ padding: 10px; } @@ -169,6 +165,26 @@ div.ov_toolbar div.ov_toolbar_separator float: left; } +div.ov_navigator_buttons +{ + border-bottom: 1px solid var(--ov_border_color); + margin-bottom: 10px; + padding: 5px; + overflow: auto; +} + +div.ov_navigator_buttons div.ov_navigator_button +{ + float: left; + cursor: pointer; + padding: 5px; +} + +div.ov_navigator_buttons div.ov_navigator_button.right +{ + float: right; +} + div.ov_navigator_tree_title { font-weight: bold; @@ -176,12 +192,12 @@ div.ov_navigator_tree_title text-overflow: ellipsis; overflow: hidden; padding-bottom: 10px; - margin-bottom: 10px; border-bottom: 1px solid var(--ov_border_color); } div.ov_navigator_tree_panel { + margin-top: 10px; overflow: auto; } @@ -379,6 +395,11 @@ div.ov_navigator_info_panel div.ov_navigator_info_button:hover background: var(--ov_hover_color); } +div.ov_navigator_buttons div.ov_navigator_button:hover +{ + background: var(--ov_hover_color); +} + } @media only screen and (max-width: 800px) diff --git a/website/o3dv/js/featureset.js b/website/o3dv/js/featureset.js index 5e65cc5..13f41b9 100644 --- a/website/o3dv/js/featureset.js +++ b/website/o3dv/js/featureset.js @@ -1,4 +1,4 @@ OV.FeatureSet = { - NavigatorTree : false + }; diff --git a/website/o3dv/js/navigator.js b/website/o3dv/js/navigator.js index c44e161..cdd485d 100644 --- a/website/o3dv/js/navigator.js +++ b/website/o3dv/js/navigator.js @@ -113,6 +113,9 @@ OV.Navigator = class }, onMaterialSelected : (materialIndex) => { this.SetSelection (new OV.Selection (OV.SelectionType.Material, materialIndex)); + }, + onSelectionRemoved : () => { + this.SetSelection (null); } }); diff --git a/website/o3dv/js/navigatoritems.js b/website/o3dv/js/navigatoritems.js index ed5bc63..771fc4d 100644 --- a/website/o3dv/js/navigatoritems.js +++ b/website/o3dv/js/navigatoritems.js @@ -64,20 +64,27 @@ OV.NodeItem = class extends OV.TreeViewGroupButtonItem constructor (name, nodeId, callbacks) { super (name, null); + this.nodeId = nodeId; + this.callbacks = callbacks; this.fitToWindowButton = new OV.TreeViewButton ('fit'); this.fitToWindowButton.OnClick (() => { - callbacks.onFitToWindow (nodeId); + this.callbacks.onFitToWindow (nodeId); }); this.AppendButton (this.fitToWindowButton); this.showHideButton = new OV.TreeViewButton ('visible'); this.showHideButton.OnClick (() => { - callbacks.onShowHide (nodeId); + this.callbacks.onShowHide (nodeId); }); this.AppendButton (this.showHideButton); } + GetNodeId () + { + return this.nodeId; + } + IsVisible () { let isVisible = false; @@ -126,5 +133,8 @@ OV.NodeItem = class extends OV.TreeViewGroupButtonItem } else { this.showHideButton.SetImage ('hidden'); } + if (OV.IsDefined (this.callbacks.onVisibilityChanged)) { + this.callbacks.onVisibilityChanged (visible); + } } }; diff --git a/website/o3dv/js/navigatorpanels.js b/website/o3dv/js/navigatorpanels.js index 0fa2f44..1659c20 100644 --- a/website/o3dv/js/navigatorpanels.js +++ b/website/o3dv/js/navigatorpanels.js @@ -334,6 +334,11 @@ OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel this.callbacks = null; this.nodeIdToItem = new Map (); this.meshInstanceIdToItem = new Map (); + this.rootItem = null; + this.showHideButton = null; + this.isHierarchical = false; + + this.buttonsDiv = $('
').addClass ('ov_navigator_buttons').insertBefore (this.treeDiv); this.popupDiv = $('
').addClass ('ov_navigator_info_panel').addClass ('ov_thin_scrollbar').appendTo (this.panelDiv); this.materialsButton = new OV.NavigatorMaterialsPopupButton (this.popupDiv); @@ -352,17 +357,26 @@ OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel Resize () { let titleHeight = this.titleDiv.outerHeight (true); + let buttonsHeight = this.buttonsDiv.outerHeight (true); let popupHeight = this.popupDiv.outerHeight (true); let height = this.parentDiv.height (); - this.treeDiv.outerHeight (height - titleHeight - popupHeight, true); + this.treeDiv.outerHeight (height - titleHeight - buttonsHeight - popupHeight, true); } Clear () + { + this.ClearMeshTree (); + this.buttonsDiv.empty (); + this.showHideButton = null; + } + + ClearMeshTree () { super.Clear (); this.materialsButton.Clear (); this.nodeIdToItem = new Map (); this.meshInstanceIdToItem = new Map (); + this.rootItem = null; } Init (callbacks) @@ -386,13 +400,67 @@ OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel super.Fill (importResult); const model = importResult.model; - const isFlat = !OV.FeatureSet.NavigatorTree; - this.FillMeshTree (model, isFlat); + this.FillButtons (importResult); + this.FillMeshTree (model); this.Resize (); } - FillMeshTree (model, isFlat) + FillButtons (importResult) + { + function CreateButton (parentDiv, tooltip, icon, extraClasses, onClick) + { + let button = $('
').addClass ('ov_navigator_button').attr ('title', tooltip).appendTo (parentDiv); + if (extraClasses !== null) { + button.addClass (extraClasses); + } + let buttonIcon = OV.AddSvgIcon (button, icon); + button.click (() => { + onClick (); + }); + return buttonIcon; + } + + CreateButton (this.buttonsDiv, 'Flat list', 'meshes', null, () => { + if (!this.isHierarchical) { + return; + } + this.isHierarchical = false; + this.ClearMeshTree (); + this.FillMeshTree (importResult.model); + this.callbacks.onSelectionRemoved (); + }); + + CreateButton (this.buttonsDiv, 'Tree view', 'meshes', null, () => { + if (this.isHierarchical) { + return; + } + this.isHierarchical = true; + this.ClearMeshTree (); + this.FillMeshTree (importResult.model); + this.callbacks.onSelectionRemoved (); + }); + + CreateButton (this.buttonsDiv, 'Expand all', 'meshes', null, () => { + this.rootItem.ExpandAll (true); + }); + + CreateButton (this.buttonsDiv, 'Collapse all', 'meshes', null, () => { + this.rootItem.ExpandAll (false); + }); + + this.showHideButton = CreateButton (this.buttonsDiv, 'Show/hide meshes', 'visible', 'right', () => { + let nodeId = this.rootItem.GetNodeId (); + this.callbacks.onNodeShowHide (nodeId); + }); + + CreateButton (this.buttonsDiv, 'Fit meshes to window', 'fit', 'right', () => { + let nodeId = this.rootItem.GetNodeId (); + this.callbacks.onNodeFitToWindow (nodeId); + }); + } + + FillMeshTree (model) { function AddMeshToNodeTree (navigator, model, node, meshIndex, parentItem) { @@ -430,15 +498,34 @@ OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel return nodeItem; } - function AddModelNodeToTree (navigator, model, node, parentItem, isFlat) + function CreateDummyRootItem (navigator, node) + { + const nodeId = node.GetId (); + let rootItem = new OV.NodeItem (null, nodeId, { + onVisibilityChanged : (isVisible) => { + if (isVisible) { + OV.SetSvgIconImage (navigator.showHideButton, 'visible'); + } else { + OV.SetSvgIconImage (navigator.showHideButton, 'hidden'); + } + } + }); + rootItem.Show (false); + rootItem.ShowChildren (true); + navigator.treeView.AddChild (rootItem); + navigator.nodeIdToItem.set (nodeId, rootItem); + return rootItem; + } + + function AddModelNodeToTree (navigator, model, node, parentItem, isHierarchical) { for (let childNode of node.GetChildNodes ()) { - if (isFlat) { - AddModelNodeToTree (navigator, model, childNode, parentItem, isFlat); - } else { + if (isHierarchical) { let nodeItem = CreateNodeItem (navigator, node.GetName (), childNode); parentItem.AddChild (nodeItem); - AddModelNodeToTree (navigator, model, childNode, nodeItem, isFlat); + AddModelNodeToTree (navigator, model, childNode, nodeItem, isHierarchical); + } else { + AddModelNodeToTree (navigator, model, childNode, parentItem, isHierarchical); } } @@ -448,7 +535,8 @@ OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel } let rootNode = model.GetRootNode (); - AddModelNodeToTree (this, model, rootNode, this.treeView, isFlat); + this.rootItem = CreateDummyRootItem (this, rootNode); + AddModelNodeToTree (this, model, rootNode, this.rootItem, this.isHierarchical); } UpdateMaterialList (materialInfoArray) diff --git a/website/o3dv/js/panelset.js b/website/o3dv/js/panelset.js index ae469e1..e54d6d2 100644 --- a/website/o3dv/js/panelset.js +++ b/website/o3dv/js/panelset.js @@ -76,7 +76,7 @@ OV.PanelSet = class { this.panels.push (panel); let button = OV.AddSvgIcon (this.menuDiv, panel.GetIcon (), 'ov_panel_set_menu_button'); - button.attr ('title', panel.GetName ()); + button.attr ('alt', panel.GetName ()).attr ('title', panel.GetName ()); this.panelButtons.push (button); button.click (() => { if (panel === this.GetVisiblePanel ()) { diff --git a/website/o3dv/js/treeview.js b/website/o3dv/js/treeview.js index efccf4c..403672e 100644 --- a/website/o3dv/js/treeview.js +++ b/website/o3dv/js/treeview.js @@ -52,11 +52,6 @@ OV.TreeViewItem = class this.mainElement.click (onClick); } - IsGroup () - { - return false; - } - SetParent (parent) { this.parent = parent; @@ -123,7 +118,8 @@ OV.TreeViewGroupItem = class extends OV.TreeViewItem { super (name); this.children = []; - this.showChildren = false; + this.isVisible = true; + this.isChildrenVisible = false; this.childrenDiv = null; this.openButtonIcon = 'arrow_down'; @@ -135,11 +131,6 @@ OV.TreeViewGroupItem = class extends OV.TreeViewItem } } - IsGroup () - { - return true; - } - AddChild (child) { this.CreateChildrenDiv (); @@ -148,9 +139,34 @@ OV.TreeViewGroupItem = class extends OV.TreeViewItem child.AddDomElements (this.childrenDiv); } + ExpandAll (expand) + { + for (let child of this.children) { + if (child instanceof OV.TreeViewGroupItem) { + child.ShowChildren (expand); + child.ExpandAll (expand); + } + } + } + + Show (show) + { + this.isVisible = show; + if (this.childrenDiv === null) { + return; + } + if (this.isVisible) { + this.mainElement.show (); + this.childrenDiv.addClass ('ov_tree_view_children'); + } else { + this.mainElement.hide (); + this.childrenDiv.removeClass ('ov_tree_view_children'); + } + } + ShowChildren (show, onComplete) { - this.showChildren = show; + this.isChildrenVisible = show; if (this.childrenDiv === null) { return; } @@ -167,10 +183,11 @@ OV.TreeViewGroupItem = class extends OV.TreeViewItem { if (this.childrenDiv === null) { this.childrenDiv = $('
').addClass ('ov_tree_view_children').insertAfter (this.mainElement); - this.ShowChildren (this.showChildren, null); + this.Show (this.isVisible); + this.ShowChildren (this.isChildrenVisible, null); this.OnClick ((ev) => { - this.showChildren = !this.showChildren; - this.ShowChildren (this.showChildren, null); + this.isChildrenVisible = !this.isChildrenVisible; + this.ShowChildren (this.isChildrenVisible, null); }); } return this.childrenDiv; @@ -201,15 +218,18 @@ OV.TreeView = class constructor (parentDiv) { this.mainDiv = $('
').addClass ('ov_tree_view').appendTo (parentDiv); + this.children = []; } AddChild (child) { child.AddDomElements (this.mainDiv); + this.children.push (child); } Clear () { this.mainDiv.empty (); + this.children = []; } };