Make mesh visibility options available from context menu #102
This commit is contained in:
parent
d911e45988
commit
9405aff3dd
@ -245,6 +245,7 @@ OV.Navigation = class
|
||||
|
||||
this.onUpdate = null;
|
||||
this.onClick = null;
|
||||
this.onContext = null;
|
||||
|
||||
if (this.canvas.addEventListener) {
|
||||
this.canvas.addEventListener ('mousedown', this.OnMouseDown.bind (this));
|
||||
@ -271,6 +272,11 @@ OV.Navigation = class
|
||||
this.onClick = onClick;
|
||||
}
|
||||
|
||||
SetContextMenuHandler (onContext)
|
||||
{
|
||||
this.onContext = onContext;
|
||||
}
|
||||
|
||||
IsFixUpVector ()
|
||||
{
|
||||
return this.fixUpVector;
|
||||
@ -375,12 +381,15 @@ OV.Navigation = class
|
||||
OnMouseDown (ev)
|
||||
{
|
||||
ev.preventDefault ();
|
||||
|
||||
this.mouse.Down (this.canvas, ev);
|
||||
this.clickDetector.Down (ev);
|
||||
}
|
||||
|
||||
OnMouseMove (ev)
|
||||
{
|
||||
ev.preventDefault ();
|
||||
|
||||
this.mouse.Move (this.canvas, ev);
|
||||
this.clickDetector.Move ();
|
||||
if (!this.mouse.IsButtonDown ()) {
|
||||
@ -403,6 +412,8 @@ OV.Navigation = class
|
||||
|
||||
OnMouseUp (ev)
|
||||
{
|
||||
ev.preventDefault ();
|
||||
|
||||
this.mouse.Up (this.canvas, ev);
|
||||
this.clickDetector.Up (ev);
|
||||
if (this.clickDetector.IsClick ()) {
|
||||
@ -413,6 +424,8 @@ OV.Navigation = class
|
||||
|
||||
OnMouseLeave (ev)
|
||||
{
|
||||
ev.preventDefault ();
|
||||
|
||||
this.mouse.Leave (this.canvas, ev);
|
||||
this.clickDetector.Leave (ev);
|
||||
}
|
||||
@ -420,12 +433,14 @@ OV.Navigation = class
|
||||
OnTouchStart (ev)
|
||||
{
|
||||
ev.preventDefault ();
|
||||
|
||||
this.touch.Start (this.canvas, ev);
|
||||
}
|
||||
|
||||
OnTouchMove (ev)
|
||||
{
|
||||
ev.preventDefault ();
|
||||
|
||||
this.touch.Move (this.canvas, ev);
|
||||
if (!this.touch.IsFingerDown ()) {
|
||||
return;
|
||||
@ -450,12 +465,14 @@ OV.Navigation = class
|
||||
OnTouchEnd (ev)
|
||||
{
|
||||
ev.preventDefault ();
|
||||
|
||||
this.touch.End (this.canvas, ev);
|
||||
}
|
||||
|
||||
OnMouseWheel (ev)
|
||||
{
|
||||
ev.preventDefault ();
|
||||
|
||||
let params = ev || window.event;
|
||||
|
||||
let delta = -params.deltaY / 40;
|
||||
@ -471,6 +488,11 @@ OV.Navigation = class
|
||||
OnContextMenu (ev)
|
||||
{
|
||||
ev.preventDefault ();
|
||||
|
||||
this.clickDetector.Up (ev);
|
||||
if (this.clickDetector.IsClick ()) {
|
||||
this.Context (ev.clientX, ev.clientY);
|
||||
}
|
||||
}
|
||||
|
||||
Orbit (angleX, angleY)
|
||||
@ -541,5 +563,17 @@ OV.Navigation = class
|
||||
let mouseCoords = OV.GetClientCoordinates (this.canvas, clientX, clientY);
|
||||
this.onClick (button, isCtrlPressed, mouseCoords);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context (clientX, clientY)
|
||||
{
|
||||
if (this.onContext) {
|
||||
let globalCoords = {
|
||||
x : clientX,
|
||||
y : clientY
|
||||
};
|
||||
let localCoords = OV.GetClientCoordinates (this.canvas, clientX, clientY);
|
||||
this.onContext (globalCoords, localCoords);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -180,6 +180,11 @@ OV.Viewer = class
|
||||
this.navigation.SetClickHandler (onClick);
|
||||
}
|
||||
|
||||
SetContextMenuHandler (onContext)
|
||||
{
|
||||
this.navigation.SetContextMenuHandler (onContext);
|
||||
}
|
||||
|
||||
SetBackgroundColor (color)
|
||||
{
|
||||
let hexColor = '#' + OV.ColorToHexString (color);
|
||||
|
||||
@ -17,10 +17,16 @@ OV.ShowMessageDialog = function (title, message, subMessage)
|
||||
return dialog;
|
||||
};
|
||||
|
||||
OV.ShowListPopup = function (button, items, callbacks)
|
||||
OV.ShowListPopup = function (items, callbacks)
|
||||
{
|
||||
if (items.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let popup = new OV.ListPopup ();
|
||||
popup.Init (button);
|
||||
popup.Init (() => {
|
||||
return callbacks.calculatePosition (popup.GetContentDiv ());
|
||||
});
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let item = items[i];
|
||||
popup.AddListItem (item, {
|
||||
|
||||
@ -157,7 +157,8 @@ OV.ExportDialog = class
|
||||
|
||||
if (selectedFormat.type === OV.ExportType.Model) {
|
||||
let progressDialog = new OV.ProgressDialog ();
|
||||
progressDialog.Show ('Exporting Model');
|
||||
progressDialog.Init ('Exporting Model');
|
||||
progressDialog.Show ();
|
||||
OV.RunTaskAsync (() => {
|
||||
let exporter = new OV.Exporter ();
|
||||
exporter.AddExporter (new OV.Exporter3dm ());
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
OV.FeatureSet =
|
||||
{
|
||||
SettingsPanel : false
|
||||
SettingsPanel : false,
|
||||
ContextMenu : false
|
||||
};
|
||||
|
||||
@ -38,7 +38,8 @@ OV.InitModelLoader = function (modelLoader, callbacks)
|
||||
CloseDialogIfOpen (errorDialog);
|
||||
callbacks.onStart ();
|
||||
progressDialog = new OV.ProgressDialog ();
|
||||
progressDialog.Show ('Loading Model');
|
||||
progressDialog.Init ('Loading Model');
|
||||
progressDialog.Show ();
|
||||
},
|
||||
onImportStart : () => {
|
||||
progressDialog.SetText ('Importing Model');
|
||||
|
||||
@ -5,7 +5,7 @@ OV.Modal = class
|
||||
this.modalDiv = $('<div>').css ('position', 'absolute');
|
||||
this.overlayDiv = null;
|
||||
this.resizeHandler = null;
|
||||
this.customResizeHandler = null;
|
||||
this.positionCalculator = null;
|
||||
this.closeHandler = null;
|
||||
this.isOpen = false;
|
||||
this.closeable = true;
|
||||
@ -21,9 +21,9 @@ OV.Modal = class
|
||||
this.closeable = closeable;
|
||||
}
|
||||
|
||||
SetCustomResizeHandler (customResizeHandler)
|
||||
SetPositionCalculator (positionCalculator)
|
||||
{
|
||||
this.customResizeHandler = customResizeHandler;
|
||||
this.positionCalculator = positionCalculator;
|
||||
}
|
||||
|
||||
SetCloseHandler (closeHandler)
|
||||
@ -43,6 +43,11 @@ OV.Modal = class
|
||||
windowObj.bind ('resize', this.resizeHandler);
|
||||
if (this.closeable) {
|
||||
this.overlayDiv.click ((ev) => {
|
||||
ev.preventDefault ();
|
||||
this.Close ();
|
||||
});
|
||||
this.overlayDiv.contextmenu ((ev) => {
|
||||
ev.preventDefault ();
|
||||
this.Close ();
|
||||
});
|
||||
}
|
||||
@ -86,33 +91,69 @@ OV.Modal = class
|
||||
left : 0,
|
||||
top : 0
|
||||
});
|
||||
if (this.customResizeHandler) {
|
||||
this.customResizeHandler (this.modalDiv);
|
||||
} else {
|
||||
this.modalDiv.offset ({
|
||||
left : (windowWidth - this.modalDiv.outerWidth ()) / 2,
|
||||
top : (windowHeight - this.modalDiv.outerHeight ()) / 3
|
||||
});
|
||||
let positionX = (windowWidth - this.modalDiv.outerWidth ()) / 2;
|
||||
let positionY = (windowHeight - this.modalDiv.outerHeight ()) / 3;
|
||||
if (this.positionCalculator !== null) {
|
||||
let calculatedPosition = this.positionCalculator ();
|
||||
positionX = calculatedPosition.x;
|
||||
positionY = calculatedPosition.y;
|
||||
}
|
||||
this.modalDiv.offset ({
|
||||
left : positionX,
|
||||
top : positionY
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
OV.ProgressDialog = class
|
||||
OV.Dialog = class
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.modal = new OV.Modal ();
|
||||
}
|
||||
|
||||
GetContentDiv ()
|
||||
{
|
||||
return this.modal.GetContentDiv ();
|
||||
}
|
||||
|
||||
SetCloseable (closeable)
|
||||
{
|
||||
this.modal.SetCloseable (closeable);
|
||||
}
|
||||
|
||||
SetCloseHandler (closeHandler)
|
||||
{
|
||||
this.modal.SetCloseHandler (closeHandler);
|
||||
}
|
||||
|
||||
SetPositionCalculator (positionCalculator)
|
||||
{
|
||||
this.modal.SetPositionCalculator (positionCalculator);
|
||||
}
|
||||
|
||||
Show ()
|
||||
{
|
||||
this.modal.Open ();
|
||||
}
|
||||
|
||||
Hide ()
|
||||
{
|
||||
this.modal.Close ();
|
||||
}
|
||||
};
|
||||
|
||||
OV.ProgressDialog = class extends OV.Dialog
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
super ();
|
||||
this.modal.SetCloseable (false);
|
||||
this.imageDiv = null;
|
||||
this.textDiv = null;
|
||||
}
|
||||
|
||||
SetText (text)
|
||||
{
|
||||
this.textDiv.html (text);
|
||||
}
|
||||
|
||||
Show (text)
|
||||
Init (text)
|
||||
{
|
||||
let contentDiv = this.modal.GetContentDiv ();
|
||||
contentDiv.addClass ('ov_progress');
|
||||
@ -121,20 +162,19 @@ OV.ProgressDialog = class
|
||||
this.textDiv = $('<div>').addClass ('ov_progress_text').appendTo (contentDiv);
|
||||
|
||||
this.SetText (text);
|
||||
this.modal.Open ();
|
||||
}
|
||||
|
||||
Hide ()
|
||||
SetText (text)
|
||||
{
|
||||
this.modal.Close ();
|
||||
this.textDiv.html (text);
|
||||
}
|
||||
};
|
||||
|
||||
OV.ButtonDialog = class
|
||||
OV.ButtonDialog = class extends OV.Dialog
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.modal = new OV.Modal ();
|
||||
super ();
|
||||
}
|
||||
|
||||
Init (title, buttons)
|
||||
@ -163,65 +203,22 @@ OV.ButtonDialog = class
|
||||
|
||||
return dialogContentDiv;
|
||||
}
|
||||
|
||||
SetCloseable (closeable)
|
||||
{
|
||||
this.modal.SetCloseable (closeable);
|
||||
}
|
||||
|
||||
SetCloseHandler (closeHandler)
|
||||
{
|
||||
this.modal.SetCloseHandler (closeHandler);
|
||||
}
|
||||
|
||||
Show ()
|
||||
{
|
||||
this.modal.Open ();
|
||||
}
|
||||
|
||||
Hide ()
|
||||
{
|
||||
this.modal.Close ();
|
||||
}
|
||||
};
|
||||
|
||||
OV.PopupDialog = class
|
||||
OV.PopupDialog = class extends OV.Dialog
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.modal = new OV.Modal ();
|
||||
super ();
|
||||
}
|
||||
|
||||
Init (parentItem)
|
||||
Init (positionCalculator)
|
||||
{
|
||||
let contentDiv = this.modal.GetContentDiv ();
|
||||
contentDiv.addClass ('ov_popup');
|
||||
this.modal.SetCustomResizeHandler ((modalDiv) => {
|
||||
let offset = parentItem.offset ();
|
||||
let left = offset.left + parentItem.outerWidth (false);
|
||||
let bottom = offset.top + parentItem.outerHeight (false);
|
||||
modalDiv.offset ({
|
||||
left : left,
|
||||
top : bottom - modalDiv.outerHeight (true)
|
||||
});
|
||||
});
|
||||
this.modal.SetPositionCalculator (positionCalculator);
|
||||
return contentDiv;
|
||||
}
|
||||
|
||||
SetCustomResizeHandler (customResizeHandler)
|
||||
{
|
||||
this.modal.SetCustomResizeHandler (customResizeHandler);
|
||||
}
|
||||
|
||||
Show ()
|
||||
{
|
||||
this.modal.Open ();
|
||||
}
|
||||
|
||||
Hide ()
|
||||
{
|
||||
this.modal.Close ();
|
||||
}
|
||||
};
|
||||
|
||||
OV.ListPopup = class extends OV.PopupDialog
|
||||
@ -232,9 +229,9 @@ OV.ListPopup = class extends OV.PopupDialog
|
||||
this.listDiv = null;
|
||||
}
|
||||
|
||||
Init (parentItem)
|
||||
Init (positionCalculator)
|
||||
{
|
||||
let contentDiv = super.Init (parentItem);
|
||||
let contentDiv = super.Init (positionCalculator);
|
||||
this.listDiv = $('<div>').addClass ('ov_popup_list').addClass ('ov_thin_scrollbar').appendTo (contentDiv);
|
||||
return contentDiv;
|
||||
}
|
||||
|
||||
@ -41,15 +41,22 @@ OV.NavigatorInfoPanel = class
|
||||
if (meshItems.length === 0) {
|
||||
return;
|
||||
}
|
||||
this.popup = OV.ShowListPopup (button, meshItems, {
|
||||
onHoverStart : function (index) {
|
||||
this.popup = OV.ShowListPopup (meshItems, {
|
||||
calculatePosition : (contentDiv) => {
|
||||
let offset = button.offset ();
|
||||
return {
|
||||
x : offset.left + button.outerWidth (false),
|
||||
y : offset.top + button.outerHeight (false) - contentDiv.outerHeight (true)
|
||||
};
|
||||
},
|
||||
onHoverStart : (index) => {
|
||||
const meshItem = usedByMeshes[index];
|
||||
callbacks.onMeshHover (meshItem.index);
|
||||
},
|
||||
onHoverStop : function (index) {
|
||||
onHoverStop : (index) => {
|
||||
callbacks.onMeshHover (null);
|
||||
},
|
||||
onClick : function (index) {
|
||||
onClick : (index) => {
|
||||
const meshItem = usedByMeshes[index];
|
||||
callbacks.onMeshSelect (meshItem.index);
|
||||
}
|
||||
@ -75,13 +82,20 @@ OV.NavigatorInfoPanel = class
|
||||
|
||||
let materialsText = 'Materials (' + materialItems.length + ')';
|
||||
this.CreateButton (this.parentDiv, materialsText, (button) => {
|
||||
this.popup = OV.ShowListPopup (button, materialItems, {
|
||||
this.popup = OV.ShowListPopup (materialItems, {
|
||||
calculatePosition : (contentDiv) => {
|
||||
let offset = button.offset ();
|
||||
return {
|
||||
x : offset.left + button.outerWidth (false),
|
||||
y : offset.top + button.outerHeight (false) - contentDiv.outerHeight (true)
|
||||
};
|
||||
},
|
||||
onClick : (index) => {
|
||||
let usedMaterial = usedMaterials[index];
|
||||
callbacks.onMaterialSelect (usedMaterial.index);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
CreateButton (parentDiv, buttonText, onClick)
|
||||
@ -214,16 +228,20 @@ OV.Navigator = class
|
||||
return meshData.IsVisible ();
|
||||
}
|
||||
|
||||
IsolateMesh (meshIndex)
|
||||
IsMeshIsolated (meshIndex)
|
||||
{
|
||||
let isIsolated = true;
|
||||
for (let i = 0; i < this.modelData.MeshCount (); i++) {
|
||||
let meshData = this.modelData.GetMeshData (i);
|
||||
if (i !== meshIndex && meshData.IsVisible ()) {
|
||||
isIsolated = false;
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
IsolateMesh (meshIndex)
|
||||
{
|
||||
let isIsolated = this.IsMeshIsolated (meshIndex);
|
||||
for (let i = 0; i < this.modelData.MeshCount (); i++) {
|
||||
let meshData = this.modelData.GetMeshData (i);
|
||||
if (i === meshIndex || isIsolated) {
|
||||
@ -248,7 +266,7 @@ OV.Navigator = class
|
||||
return this.tempSelectedMeshIndex;
|
||||
}
|
||||
if (this.selection === null || this.selection.type !== OV.SelectionType.Mesh) {
|
||||
return -1;
|
||||
return null;
|
||||
}
|
||||
return this.selection.index;
|
||||
}
|
||||
|
||||
@ -54,6 +54,7 @@ OV.Website = class
|
||||
this.InitCookieConsent ();
|
||||
|
||||
this.viewer.SetClickHandler (this.OnModelClicked.bind (this));
|
||||
this.viewer.SetContextMenuHandler (this.OnModelContextMenu.bind (this));
|
||||
this.Resize ();
|
||||
|
||||
this.hashHandler.SetEventListener (this.OnHashChange.bind (this));
|
||||
@ -141,6 +142,68 @@ OV.Website = class
|
||||
}
|
||||
}
|
||||
|
||||
OnModelContextMenu (globalMouseCoordinates, mouseCoordinates)
|
||||
{
|
||||
if (!OV.FeatureSet.ContextMenu) {
|
||||
return;
|
||||
}
|
||||
|
||||
let meshUserData = this.viewer.GetMeshUserDataUnderMouse (mouseCoordinates);
|
||||
let items = [];
|
||||
if (meshUserData === null) {
|
||||
items = [
|
||||
{
|
||||
name : 'Fit model to window',
|
||||
onClick : () => {
|
||||
this.FitModelToWindow (false);
|
||||
}
|
||||
}
|
||||
];
|
||||
} else {
|
||||
let meshIndex = meshUserData.originalMeshIndex;
|
||||
let isSelectedMesh = (meshIndex === this.navigator.GetSelectedMeshIndex ());
|
||||
let isMeshIsolated = this.navigator.IsMeshIsolated (meshIndex);
|
||||
items = [
|
||||
{
|
||||
name : isSelectedMesh ? 'Deselect mesh' : 'Select mesh',
|
||||
onClick : () => {
|
||||
this.navigator.SetSelection (new OV.Selection (OV.SelectionType.Mesh, meshIndex));
|
||||
}
|
||||
},
|
||||
{
|
||||
name : 'Hide mesh',
|
||||
onClick : () => {
|
||||
this.navigator.ToggleMeshVisibility (meshIndex);
|
||||
}
|
||||
},
|
||||
{
|
||||
name : 'Fit to window',
|
||||
onClick : () => {
|
||||
this.navigator.FitMeshToWindow (meshIndex);
|
||||
}
|
||||
},
|
||||
{
|
||||
name : isMeshIsolated ? 'Remove mesh isolation' : 'Isolate mesh',
|
||||
onClick : () => {
|
||||
this.navigator.IsolateMesh (meshIndex);
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
this.dialog = OV.ShowListPopup (items, {
|
||||
calculatePosition : (contentDiv) => {
|
||||
return {
|
||||
x : globalMouseCoordinates.x,
|
||||
y : globalMouseCoordinates.y
|
||||
};
|
||||
},
|
||||
onClick : (index) => {
|
||||
let clickedItem = items[index];
|
||||
clickedItem.onClick ();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
OpenFileBrowserDialog ()
|
||||
{
|
||||
this.parameters.fileInput.trigger ('click');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user