diff --git a/website/o3dv/css/website.css b/website/o3dv/css/website.css index 4bf07ec..1c021db 100644 --- a/website/o3dv/css/website.css +++ b/website/o3dv/css/website.css @@ -5,7 +5,7 @@ div.ov_color_circle width: 14px; height: 14px; display: inline-block; - margin-right: 5px; + margin-right: 8px; margin-bottom: -2px; border-radius: 10px; } diff --git a/website/o3dv/js/navigator.js b/website/o3dv/js/navigator.js index 474adb7..0422fad 100644 --- a/website/o3dv/js/navigator.js +++ b/website/o3dv/js/navigator.js @@ -77,6 +77,13 @@ OV.Navigator = class this.materialsPanel.Init ({ onMaterialSelected : (materialIndex) => { this.SetSelection (new OV.Selection (OV.SelectionType.Material, materialIndex)); + }, + onMeshTemporarySelected : (meshInstanceId) => { + this.tempSelectedMeshId = meshInstanceId; + this.callbacks.updateMeshesSelection (); + }, + onMeshSelected : (meshInstanceId) => { + this.SetSelection (new OV.Selection (OV.SelectionType.Mesh, meshInstanceId)); } }); @@ -95,6 +102,9 @@ OV.Navigator = class }, onNodeFitToWindow : (nodeId) => { this.FitNodeToWindow (nodeId); + }, + onMaterialSelected : (materialIndex) => { + this.SetSelection (new OV.Selection (OV.SelectionType.Material, materialIndex)); } }); @@ -206,7 +216,7 @@ OV.Navigator = class if (select) { navigator.panelSet.ShowPanel (navigator.materialsPanel); } - navigator.materialsPanel.GetMaterialItem (selection.materialIndex).SetSelected (select); + navigator.materialsPanel.SelectMaterialItem (selection.materialIndex, select); } else if (selection.type === OV.SelectionType.Mesh) { if (select) { navigator.panelSet.ShowPanel (navigator.meshesPanel); @@ -252,9 +262,29 @@ OV.Navigator = class this.callbacks.onMeshSelected (this.selection.meshInstanceId); } } + this.UpdatePanels (); this.Resize (); } + UpdatePanels () + { + let materialIndex = null; + let meshInstanceId = null; + if (this.selection !== null) { + if (this.selection.type === OV.SelectionType.Material) { + materialIndex = this.selection.materialIndex; + } else if (this.selection.type === OV.SelectionType.Mesh) { + meshInstanceId = this.selection.meshInstanceId; + } + } + + let usedByMeshes = this.callbacks.getMeshesForMaterial (materialIndex); + this.materialsPanel.UpdateMeshList (usedByMeshes); + + let usedByMaterials = this.callbacks.getMaterialsForMesh (meshInstanceId); + this.meshesPanel.UpdateMaterialList (usedByMaterials); + } + FitNodeToWindow (nodeId) { let meshInstanceIdSet = new Set (); diff --git a/website/o3dv/js/navigatorpanels.js b/website/o3dv/js/navigatorpanels.js index 9f837a3..c601d38 100644 --- a/website/o3dv/js/navigatorpanels.js +++ b/website/o3dv/js/navigatorpanels.js @@ -1,3 +1,144 @@ +OV.NavigatorPopupButton = class +{ + constructor (parentDiv) + { + this.parentDiv = parentDiv; + this.callbacks = null; + this.popup = null; + + this.button = $('
').addClass ('ov_navigator_info_button').appendTo (this.parentDiv); + this.buttonText = $('
').addClass ('ov_navigator_info_button_text').appendTo (this.button); + OV.AddSvgIcon (this.button, 'arrow_right', 'ov_navigator_info_button_icon'); + this.button.click (() => { + this.OnButtonClick (); + }); + } + + Init (callbacks) + { + this.callbacks = callbacks; + } + + OnButtonClick () + { + + } + + Clear () + { + if (this.popup !== null) { + this.popup.Hide (); + this.popup = null; + } + } +}; + +OV.NavigatorMeshesPopupButton = class extends OV.NavigatorPopupButton +{ + constructor (parentDiv) + { + super (parentDiv); + this.meshInfoArray = null; + } + + Update (meshInfoArray) + { + this.meshInfoArray = meshInfoArray; + if (this.meshInfoArray === null) { + return; + } + + let meshesText = 'Meshes (' + this.meshInfoArray.length + ')'; + this.buttonText.html (meshesText); + } + + OnButtonClick () + { + if (this.meshInfoArray === null) { + return; + } + + let meshItems = []; + for (let i = 0; i < this.meshInfoArray.length; i++) { + let meshInfo = this.meshInfoArray[i]; + meshItems.push ({ + name : OV.GetMeshName (meshInfo.name) + }); + } + + if (meshItems.length === 0) { + return; + } + + this.popup = OV.ShowListPopup (meshItems, { + calculatePosition : (contentDiv) => { + return OV.CalculatePopupPositionToElementBottomRight (this.button, contentDiv); + }, + onHoverStart : (index) => { + const meshData = this.meshInfoArray[index]; + this.callbacks.onMeshHover (meshData.meshId); + }, + onHoverStop : (index) => { + this.callbacks.onMeshHover (null); + }, + onClick : (index) => { + const meshData = this.meshInfoArray[index]; + this.callbacks.onMeshSelected (meshData.meshId); + } + }); + } +}; + +OV.NavigatorMaterialsPopupButton = class extends OV.NavigatorPopupButton +{ + constructor (parentDiv) + { + super (parentDiv); + this.materialInfoArray = null; + } + + Update (materialInfoArray) + { + this.materialInfoArray = materialInfoArray; + if (this.materialInfoArray === null) { + return; + } + + let materialsText = 'Materials (' + this.materialInfoArray.length + ')'; + this.buttonText.html (materialsText); + } + + OnButtonClick () + { + if (this.materialInfoArray === null) { + return; + } + + let materialItems = []; + for (let i = 0; i < this.materialInfoArray.length; i++) { + let usedMaterial = this.materialInfoArray[i]; + materialItems.push ({ + name : OV.GetMaterialName (usedMaterial.name), + color : usedMaterial.color + }); + } + + if (materialItems.length === 0) { + return; + } + + this.popup = OV.ShowListPopup (materialItems, { + calculatePosition : (contentDiv) => { + return OV.CalculatePopupPositionToElementBottomRight (this.button, contentDiv); + }, + onClick : (index) => { + let usedMaterial = this.materialInfoArray[index]; + this.callbacks.onMaterialSelected (usedMaterial.index); + } + }); + } +}; + OV.NavigatorPanel = class extends OV.Panel { constructor (parentDiv) @@ -47,7 +188,6 @@ OV.NavigatorFilesPanel = class extends OV.NavigatorPanel Resize () { - // TODO: height is not ok let titleHeight = this.titleDiv.outerHeight (true); let height = this.parentDiv.height (); this.treeDiv.outerHeight (height - titleHeight, true); @@ -103,6 +243,9 @@ OV.NavigatorMaterialsPanel = class extends OV.NavigatorPanel super (parentDiv); this.callbacks = null; this.materialIndexToItem = new Map (); + + this.popupDiv = $('
').addClass ('ov_navigator_info_panel').addClass ('ov_thin_scrollbar').appendTo (this.panelDiv); + this.meshesButton = new OV.NavigatorMeshesPopupButton (this.popupDiv); } GetIcon () @@ -112,15 +255,16 @@ OV.NavigatorMaterialsPanel = class extends OV.NavigatorPanel Resize () { - // TODO: height is not ok let titleHeight = this.titleDiv.outerHeight (true); + let popupHeight = this.popupDiv.outerHeight (true); let height = this.parentDiv.height (); - this.treeDiv.outerHeight (height - titleHeight, true); + this.treeDiv.outerHeight (height - titleHeight - popupHeight, true); } Clear () { super.Clear (); + this.meshesButton.Clear (); this.materialIndexToItem = new Map (); } @@ -132,6 +276,14 @@ OV.NavigatorMaterialsPanel = class extends OV.NavigatorPanel Init (callbacks) { super.Init (callbacks); + this.meshesButton.Init ({ + onMeshHover : (meshInstanceId) => { + this.callbacks.onMeshTemporarySelected (meshInstanceId); + }, + onMeshSelected : (meshInstanceId) => { + this.callbacks.onMeshSelected (meshInstanceId); + } + }); } Fill (importResult) @@ -155,103 +307,15 @@ OV.NavigatorMaterialsPanel = class extends OV.NavigatorPanel { return this.materialIndexToItem.get (materialIndex); } -}; -// TODO: delete -OV.NavigatorPopupButton = class -{ - constructor (parentDiv) + SelectMaterialItem (materialIndex, isSelected) { - this.parentDiv = parentDiv; - this.popup = null; + this.GetMaterialItem (materialIndex).SetSelected (isSelected); } - FillWithMaterialInfo (usedByMeshes, callbacks) + UpdateMeshList (meshInfoArray) { - this.Clear (); - if (usedByMeshes === null) { - return; - } - - let meshItems = []; - for (let i = 0; i < usedByMeshes.length; i++) { - let meshInfo = usedByMeshes[i]; - meshItems.push ({ - name : OV.GetMeshName (meshInfo.name) - }); - } - - let meshesText = 'Meshes (' + meshItems.length + ')'; - this.CreateButton (this.parentDiv, meshesText, (button) => { - if (meshItems.length === 0) { - return; - } - this.popup = OV.ShowListPopup (meshItems, { - calculatePosition : (contentDiv) => { - return OV.CalculatePopupPositionToElementBottomRight (button, contentDiv); - }, - onHoverStart : (index) => { - const meshData = usedByMeshes[index]; - callbacks.onMeshHover (meshData.meshId); - }, - onHoverStop : (index) => { - callbacks.onMeshHover (null); - }, - onClick : (index) => { - const meshData = usedByMeshes[index]; - callbacks.onMeshSelect (meshData.meshId); - } - }); - }); - } - - FillWithModelInfo (usedMaterials, callbacks) - { - this.Clear (); - if (usedMaterials === null) { - return; - } - - let materialItems = []; - for (let i = 0; i < usedMaterials.length; i++) { - let usedMaterial = usedMaterials[i]; - materialItems.push ({ - name : OV.GetMaterialName (usedMaterial.name), - color : usedMaterial.color - }); - } - - let materialsText = 'Materials (' + materialItems.length + ')'; - this.CreateButton (this.parentDiv, materialsText, (button) => { - this.popup = OV.ShowListPopup (materialItems, { - calculatePosition : (contentDiv) => { - return OV.CalculatePopupPositionToElementBottomRight (button, contentDiv); - }, - onClick : (index) => { - let usedMaterial = usedMaterials[index]; - callbacks.onMaterialSelect (usedMaterial.index); - } - }); - }); - } - - CreateButton (parentDiv, buttonText, onClick) - { - let button = $('
').addClass ('ov_navigator_info_button').appendTo (parentDiv); - $('
').addClass ('ov_navigator_info_button_text').html (buttonText).appendTo (button); - OV.AddSvgIcon (button, 'arrow_right', 'ov_navigator_info_button_icon'); - button.click (() => { - onClick (button); - }); - } - - Clear () - { - if (this.popup !== null) { - this.popup.Hide (); - this.popup = null; - } - this.parentDiv.empty (); + this.meshesButton.Update (meshInfoArray); } }; @@ -265,7 +329,8 @@ OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel this.nodeIdToItem = new Map (); this.meshInstanceIdToItem = new Map (); - this.treeView = new OV.TreeView (this.treeDiv); + this.popupDiv = $('
').addClass ('ov_navigator_info_panel').addClass ('ov_thin_scrollbar').appendTo (this.panelDiv); + this.materialsButton = new OV.NavigatorMaterialsPopupButton (this.popupDiv); } GetIcon () @@ -276,20 +341,33 @@ OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel Resize () { let titleHeight = this.titleDiv.outerHeight (true); + let popupHeight = this.popupDiv.outerHeight (true); let height = this.parentDiv.height (); - this.treeDiv.outerHeight (height - titleHeight, true); + this.treeDiv.outerHeight (height - titleHeight - popupHeight, true); } Clear () { super.Clear (); + this.materialsButton.Clear (); this.nodeIdToItem = new Map (); this.meshInstanceIdToItem = new Map (); } Init (callbacks) { - this.callbacks = callbacks; + super.Init (callbacks); + this.materialsButton.Init ({ + onMeshHover : (meshInstanceId) => { + this.callbacks.onMeshTemporarySelected (meshInstanceId); + }, + onMeshSelected : (meshInstanceId) => { + this.callbacks.onMeshSelected (meshInstanceId); + }, + onMaterialSelected : (materialIndex) => { + this.callbacks.onMaterialSelected (materialIndex); + } + }); } GetName () @@ -371,6 +449,11 @@ OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel AddModelNodeToTree (this, model, rootNode, meshesItem, isFlat); } + UpdateMaterialList (materialInfoArray) + { + this.materialsButton.Update (materialInfoArray); + } + GetNodeItem (nodeId) { return this.nodeIdToItem.get (nodeId); diff --git a/website/o3dv/js/website.js b/website/o3dv/js/website.js index 39e4088..6499c4a 100644 --- a/website/o3dv/js/website.js +++ b/website/o3dv/js/website.js @@ -635,7 +635,7 @@ OV.Website = class { let usedByMeshes = []; viewer.EnumerateMeshesUserData ((meshUserData) => { - if (meshUserData.originalMaterials.indexOf (materialIndex) !== -1) { + if (materialIndex === null || meshUserData.originalMaterials.indexOf (materialIndex) !== -1) { const mesh = model.GetMesh (meshUserData.originalMeshId.meshIndex); usedByMeshes.push ({ meshId : meshUserData.originalMeshId, @@ -659,10 +659,16 @@ OV.Website = class function GetMaterialsForMesh (viewer, model, meshInstanceId) { let usedMaterials = []; - let userData = GetMeshUserData (viewer, meshInstanceId); - for (let i = 0; i < userData.originalMaterials.length; i++) { - const materialIndex = userData.originalMaterials[i]; - usedMaterials.push (GetMaterialReferenceInfo (model, materialIndex)); + if (meshInstanceId === null) { + for (let materialIndex = 0; materialIndex < model.MaterialCount (); materialIndex++) { + usedMaterials.push (GetMaterialReferenceInfo (model, materialIndex)); + } + } else { + let userData = GetMeshUserData (viewer, meshInstanceId); + for (let i = 0; i < userData.originalMaterials.length; i++) { + const materialIndex = userData.originalMaterials[i]; + usedMaterials.push (GetMaterialReferenceInfo (model, materialIndex)); + } } usedMaterials.sort ((a, b) => { return a.index - b.index; @@ -670,15 +676,6 @@ OV.Website = class return usedMaterials; } - function GetMaterialsForModel (model) - { - let usedMaterials = []; - for (let materialIndex = 0; materialIndex < model.MaterialCount (); materialIndex++) { - usedMaterials.push (GetMaterialReferenceInfo (model, materialIndex)); - } - return usedMaterials; - } - this.navigator.Init ({ openFileBrowserDialog : () => { this.OpenFileBrowserDialog (); @@ -701,9 +698,6 @@ OV.Website = class getMaterialsForMesh : (meshInstanceId) => { return GetMaterialsForMesh (this.viewer, this.model, meshInstanceId); }, - getMaterialsForModel : () => { - return GetMaterialsForModel (this.model); - }, onModelSelected : () => { this.detailsPanel.AddObject3DProperties (this.model); },