diff --git a/source/website/modal.js b/source/website/dialog.js similarity index 86% rename from source/website/modal.js rename to source/website/dialog.js index 436750c..64e411d 100644 --- a/source/website/modal.js +++ b/source/website/dialog.js @@ -1,7 +1,29 @@ import { AddDiv, CreateDiv } from '../engine/viewer/domutils.js'; import { AddSvgIconElement, CreateInlineColorCircle, IsHoverEnabled } from './utils.js'; -export class Modal +let currentDialog = null; + +export function CloseAllDialogs () +{ + if (currentDialog === null) { + return; + } + currentDialog.Close (); + currentDialog = null; +} + +function OnCloseDialog () +{ + currentDialog = null; +} + +function OnOpenDialog (dialog) +{ + CloseAllDialogs (); + currentDialog = dialog; +} + +class Dialog { constructor () { @@ -40,6 +62,12 @@ export class Modal Open () { + if (this.isOpen) { + return; + } + + OnOpenDialog (this); + this.overlayDiv = AddDiv (document.body, 'ov_modal_overlay'); document.body.appendChild (this.modalDiv); @@ -69,6 +97,8 @@ export class Modal return; } + OnCloseDialog (); + window.removeEventListener ('resize', this.resizeHandler); if (this.closeHandler !== null) { this.closeHandler (); @@ -82,11 +112,6 @@ export class Modal this.isOpen = false; } - IsOpen () - { - return this.isOpen; - } - Resize () { let windowWidth = window.innerWidth; @@ -103,56 +128,18 @@ export class Modal } } -export class Dialog -{ - constructor () - { - this.modal = new 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 (); - } -} - export class ProgressDialog extends Dialog { constructor () { super (); - this.modal.SetCloseable (false); + this.SetCloseable (false); this.textDiv = null; } Init (text) { - let contentDiv = this.modal.GetContentDiv (); + let contentDiv = this.GetContentDiv (); contentDiv.classList.add ('ov_progress'); AddDiv (contentDiv, 'ov_progress_img', ''); @@ -186,7 +173,7 @@ export class ButtonDialog extends Dialog }); } - let contentDiv = this.modal.GetContentDiv (); + let contentDiv = this.GetContentDiv (); contentDiv.classList.add ('ov_dialog'); AddDiv (contentDiv, 'ov_dialog_title', title); @@ -210,9 +197,9 @@ export class PopupDialog extends Dialog Init (positionCalculator) { - let contentDiv = this.modal.GetContentDiv (); + let contentDiv = this.GetContentDiv (); contentDiv.classList.add ('ov_popup'); - this.modal.SetPositionCalculator (positionCalculator); + this.SetPositionCalculator (positionCalculator); return contentDiv; } } diff --git a/source/website/dialogs.js b/source/website/dialogs.js index d7ae8ed..602de83 100644 --- a/source/website/dialogs.js +++ b/source/website/dialogs.js @@ -1,5 +1,5 @@ import { AddDiv } from '../engine/viewer/domutils.js'; -import { ButtonDialog, ListPopup } from './modal.js'; +import { ButtonDialog, ListPopup } from './dialog.js'; export function ShowMessageDialog (title, message, subMessage) { @@ -8,7 +8,7 @@ export function ShowMessageDialog (title, message, subMessage) { name : 'OK', onClick () { - dialog.Hide (); + dialog.Close (); } } ]); @@ -16,7 +16,7 @@ export function ShowMessageDialog (title, message, subMessage) if (subMessage !== null) { AddDiv (contentDiv, 'ov_dialog_submessage', subMessage); } - dialog.Show (); + dialog.Open (); return dialog; } @@ -44,12 +44,12 @@ export function ShowListPopup (items, callbacks) } }, onClick : function () { - popup.Hide (); + popup.Close (); callbacks.onClick (i); } }); } - popup.Show (); + popup.Open (); return popup; } diff --git a/source/website/exportdialog.js b/source/website/exportdialog.js index f7e469f..724faaa 100644 --- a/source/website/exportdialog.js +++ b/source/website/exportdialog.js @@ -7,7 +7,7 @@ import { Exporter } from '../engine/export/exporter.js'; import { ExporterModel, ExporterSettings } from '../engine/export/exportermodel.js'; import { AddDiv, AddSelect, ClearDomElement } from '../engine/viewer/domutils.js'; import { ShowMessageDialog } from './dialogs.js'; -import { ButtonDialog, ProgressDialog } from './modal.js'; +import { ButtonDialog, ProgressDialog } from './dialog.js'; import { DownloadArrayBufferAsFile, DownloadUrlAsFile } from './utils.js'; import { CookieGetStringVal, CookieSetStringVal } from './cookiehandler.js'; import { HandleEvent } from './eventhandler.js'; @@ -90,30 +90,29 @@ export class ModelExporterUI extends ExporterUI let exporterModel = new ExporterModel (model, settings); if (exporterModel.MeshInstanceCount () === 0) { - let errorDialog = ShowMessageDialog ( + ShowMessageDialog ( 'Export Failed', 'The model doesn\'t contain any meshes.', null ); - callbacks.onDialog (errorDialog); return; } let progressDialog = new ProgressDialog (); progressDialog.Init ('Exporting Model'); - progressDialog.Show (); + progressDialog.Open (); RunTaskAsync (() => { let exporter = new Exporter (); exporter.Export (model, settings, this.format, this.extension, { onError : () => { - progressDialog.Hide (); + progressDialog.Close (); }, onSuccess : (files) => { if (files.length === 0) { - progressDialog.Hide (); + progressDialog.Close (); } else if (files.length === 1) { - progressDialog.Hide (); + progressDialog.Close (); let file = files[0]; DownloadArrayBufferAsFile (file.GetBufferContent (), file.GetName ()); } else if (files.length > 1) { @@ -124,10 +123,10 @@ export class ModelExporterUI extends ExporterUI } let zippedContent = fflate.zipSync (filesInZip); let zippedBuffer = zippedContent.buffer; - progressDialog.Hide (); + progressDialog.Close (); DownloadArrayBufferAsFile (zippedBuffer, 'model.zip'); }).catch (() => { - progressDialog.Hide (); + progressDialog.Close (); }); } } @@ -197,7 +196,7 @@ export class ExportDialog ]; } - Show (model, viewer) + Open (model, viewer) { let mainDialog = new ButtonDialog (); let contentDiv = mainDialog.Init ('Export', [ @@ -205,13 +204,13 @@ export class ExportDialog name : 'Close', subClass : 'outline', onClick () { - mainDialog.Hide (); + mainDialog.Close (); } }, { name : 'Export', onClick : () => { - mainDialog.Hide (); + mainDialog.Close (); this.ExportFormat (model, viewer); } } @@ -234,8 +233,7 @@ export class ExportDialog }); this.OnFormatSelected (defaultFormatIndex); - mainDialog.Show (); - this.callbacks.onDialog (mainDialog); + mainDialog.Open (); } OnFormatSelected (selectedIndex) @@ -251,9 +249,6 @@ export class ExportDialog this.selectedExporter.ExportModel (model, { isMeshVisible : (meshInstanceId) => { return this.callbacks.isMeshVisible (meshInstanceId); - }, - onDialog : (filesDialog) => { - this.callbacks.onDialog (filesDialog); } }); HandleEvent ('model_exported', this.selectedExporter.GetName ()); diff --git a/source/website/navigatorpanel.js b/source/website/navigatorpanel.js index a008639..3dce6e5 100644 --- a/source/website/navigatorpanel.js +++ b/source/website/navigatorpanel.js @@ -32,7 +32,7 @@ export class NavigatorPopupButton Clear () { if (this.popup !== null) { - this.popup.Hide (); + this.popup.Close (); this.popup = null; } } diff --git a/source/website/openurldialog.js b/source/website/openurldialog.js index 938655f..765f28a 100644 --- a/source/website/openurldialog.js +++ b/source/website/openurldialog.js @@ -1,6 +1,6 @@ import { ReadLines } from '../engine/import/importerutils.js'; import { AddDiv, CreateDomElement } from '../engine/viewer/domutils.js'; -import { ButtonDialog } from './modal.js'; +import { ButtonDialog } from './dialog.js'; export function ShowOpenUrlDialog (onOk) { @@ -11,7 +11,7 @@ export function ShowOpenUrlDialog (onOk) name : 'Cancel', subClass : 'outline', onClick () { - dialog.Hide (); + dialog.Close (); } }, { @@ -21,7 +21,7 @@ export function ShowOpenUrlDialog (onOk) ReadLines (urlsTextArea.value, (line) => { urls.push (line); }); - dialog.Hide (); + dialog.Close (); onOk (urls); } } @@ -29,7 +29,7 @@ export function ShowOpenUrlDialog (onOk) let text = 'Here you can load models based on their urls. You can add more lines if your model builds up from multiple files.'; AddDiv (contentDiv, 'ov_dialog_section', text); contentDiv.appendChild (urlsTextArea); - dialog.Show (); + dialog.Open (); urlsTextArea.focus (); return dialog; } diff --git a/source/website/sharingdialog.js b/source/website/sharingdialog.js index d05b68b..ee0d3be 100644 --- a/source/website/sharingdialog.js +++ b/source/website/sharingdialog.js @@ -2,7 +2,7 @@ import { FileSource } from '../engine/io/fileutils.js'; import { AddDiv, AddDomElement, AddCheckbox } from '../engine/viewer/domutils.js'; import { CreateUrlBuilder } from '../engine/parameters/parameterlist.js'; import { ShowMessageDialog } from './dialogs.js'; -import { ButtonDialog } from './modal.js'; +import { ButtonDialog } from './dialog.js'; import { CopyToClipboard } from './utils.js'; import { HandleEvent } from './eventhandler.js'; @@ -125,7 +125,7 @@ export function ShowSharingDialog (fileList, settings, camera) { name : 'Close', onClick () { - dialog.Hide (); + dialog.Close (); } } ]); @@ -133,6 +133,6 @@ export function ShowSharingDialog (fileList, settings, camera) AddSharingLinkTab (contentDiv, modelFiles); AddEmbeddingCodeTab (contentDiv, modelFiles, settings, camera); - dialog.Show (); + dialog.Open (); return dialog; } diff --git a/source/website/sidebarsettingspanel.js b/source/website/sidebarsettingspanel.js index 223df04..1842813 100644 --- a/source/website/sidebarsettingspanel.js +++ b/source/website/sidebarsettingspanel.js @@ -2,7 +2,7 @@ import { Color, ColorToHexString } from '../engine/model/color.js'; import { AddDiv, AddDomElement, AddRangeSlider, AddToggle, AddCheckbox, ShowDomElement, SetDomElementOuterHeight } from '../engine/viewer/domutils.js'; import { CalculatePopupPositionToElementTopLeft } from './dialogs.js'; import { FeatureSet } from './featureset.js'; -import { PopupDialog } from './modal.js'; +import { PopupDialog } from './dialog.js'; import { Settings, Theme } from './settings.js'; import { SidebarPanel } from './sidebarpanel.js'; import { AddSvgIconElement } from './utils.js'; @@ -106,7 +106,7 @@ class EnvironmentMapPopup extends PopupDialog }); contentDiv.classList.add ('sidebar'); - this.Show (); + this.Open (); } } @@ -243,7 +243,7 @@ class SettingsModelDisplaySection extends SettingsSection Clear () { if (this.environmentMapPopup !== null) { - this.environmentMapPopup.Hide (); + this.environmentMapPopup.Close (); this.environmentMapPopup = null; } diff --git a/source/website/threemodelloaderui.js b/source/website/threemodelloaderui.js index 1172019..1005151 100644 --- a/source/website/threemodelloaderui.js +++ b/source/website/threemodelloaderui.js @@ -1,7 +1,7 @@ import { AddDiv } from '../engine/viewer/domutils.js'; import { ThreeModelLoader } from '../engine/threejs/threemodelloader.js'; import { ShowMessageDialog } from './dialogs.js'; -import { ButtonDialog, ProgressDialog } from './modal.js'; +import { ButtonDialog, ProgressDialog } from './dialog.js'; import { AddSvgIconElement } from './utils.js'; import { ImportErrorCode } from '../engine/import/importer.js'; @@ -26,12 +26,12 @@ export class ThreeModelLoaderUI callbacks.onStart (); progressDialog = new ProgressDialog (); progressDialog.Init ('Loading Model'); - progressDialog.Show (); + progressDialog.Open (); }, onSelectMainFile : (fileNames, selectFile) => { - progressDialog.Hide (); + progressDialog.Close (); this.modalDialog = this.ShowFileSelectorDialog (fileNames, (index) => { - progressDialog.Show (); + progressDialog.Open (); selectFile (index); }); }, @@ -42,14 +42,14 @@ export class ThreeModelLoaderUI progressDialog.SetText ('Visualizing Model'); }, onModelFinished : (importResult, threeObject) => { - progressDialog.Hide (); + progressDialog.Close (); callbacks.onFinish (importResult, threeObject); }, onTextureLoaded : () => { callbacks.onRender (); }, onLoadError : (importError) => { - progressDialog.Hide (); + progressDialog.Close (); callbacks.onError (importError); this.modalDialog = this.ShowErrorDialog (importError); }, @@ -103,7 +103,7 @@ export class ThreeModelLoaderUI name : 'Cancel', subClass : 'outline', onClick () { - dialog.Hide (); + dialog.Close (); } } ]); @@ -124,19 +124,19 @@ export class ThreeModelLoaderUI AddDiv (fileLink, 'ov_dialog_file_link_text', fileName); fileLink.addEventListener ('click', () => { dialog.SetCloseHandler (null); - dialog.Hide (); + dialog.Close (); onSelect (i); }); } - dialog.Show (); + dialog.Open (); return dialog; } CloseDialogIfOpen () { if (this.modalDialog !== null) { - this.modalDialog.Hide (); + this.modalDialog.Close (); this.modalDialog = null; } } diff --git a/source/website/website.js b/source/website/website.js index 445cbb4..9a544c6 100644 --- a/source/website/website.js +++ b/source/website/website.js @@ -20,6 +20,7 @@ import { Direction } from '../engine/geometry/geometry.js'; import { CookieGetBoolVal, CookieSetBoolVal } from './cookiehandler.js'; import { ShadingType } from '../engine/threejs/threeutils.js'; import { MeasureTool } from './measuretool.js'; +import { CloseAllDialogs } from './dialog.js'; export const WebsiteUIState = { @@ -46,7 +47,6 @@ export class Website this.highlightColor = new THREE.Color (0x8ec9f0); this.uiState = WebsiteUIState.Undefined; this.model = null; - this.dialog = null; } Load () @@ -156,7 +156,7 @@ export class Website ClearModel () { - this.HidePopups (); + CloseAllDialogs (); this.model = null; this.viewer.Clear (); @@ -257,7 +257,7 @@ export class Website }); } } - this.dialog = ShowListPopup (items, { + ShowListPopup (items, { calculatePosition : (contentDiv) => { return CalculatePopupPositionToScreen (globalMouseCoordinates, contentDiv); }, @@ -290,14 +290,6 @@ export class Website } } - HidePopups () - { - if (this.dialog !== null) { - this.dialog.Hide (); - this.dialog = null; - } - } - OpenFileBrowserDialog () { this.parameters.fileInput.click (); @@ -538,7 +530,7 @@ export class Website this.OpenFileBrowserDialog (); }); AddButton (this.toolbar, 'open_url', 'Open model from a url', [], () => { - this.dialog = ShowOpenUrlDialog ((urls) => { + ShowOpenUrlDialog ((urls) => { if (urls.length > 0) { this.hashHandler.SetModelFilesToHash (urls); } @@ -577,15 +569,12 @@ export class Website let exportDialog = new ExportDialog ({ isMeshVisible : (meshInstanceId) => { return this.navigator.IsMeshVisible (meshInstanceId); - }, - onDialog : (dialog) => { - this.dialog = dialog; } }); - exportDialog.Show (this.model, this.viewer); + exportDialog.Open (this.model, this.viewer); }); AddButton (this.toolbar, 'share', 'Share model', ['only_full_width', 'only_on_model'], () => { - this.dialog = ShowSharingDialog (importer.GetFileList (), this.settings, this.viewer.GetCamera ()); + ShowSharingDialog (importer.GetFileList (), this.settings, this.viewer.GetCamera ()); }); this.parameters.fileInput.addEventListener ('change', (ev) => {