Select file to import when there are more importable files #176

This commit is contained in:
kovacsv 2021-11-29 19:48:12 +01:00
parent 7d3a454503
commit db57efeaf1
10 changed files with 130 additions and 38 deletions

View File

@ -22,7 +22,7 @@
src="../../website/embed.html#model=../test/testfiles/3ds/cube_four_instances.3ds,../test/testfiles/3ds/texture.png$camera=3.929421317669367,6.153966358575169,2.7076091223424714,1.5,1.5,0.5,0,0,1"
width=360 height=240
style="border:1px solid #eeeeee;">
</iframe>
</iframe>
<iframe
src="../../website/embed.html#model=../test/testfiles/obj/hundred_cubes.obj,../test/testfiles/obj/hundred_cubes.mtl$camera=1,1,1,0,0,0,0,0,1"
width=360 height=240
@ -47,7 +47,7 @@
src="../../website/embed.html#model=wrong.3ds"
width=360 height=240
style="border:1px solid #eeeeee;">
</iframe>
</iframe>
</body>
</html>

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<title>Online 3D Viewer</title>
</head>
<body>
<iframe
src="../../website/embed.html#model=../test/testfiles/3ds/cube_four_instances.3ds,../test/testfiles/3ds/texture.png,../test/testfiles/obj/hundred_cubes.obj,../test/testfiles/obj/hundred_cubes.mtl"
width=600 height=400
style="border:1px solid #eeeeee;">
</iframe>
</body>
</html>

View File

@ -54,7 +54,7 @@ global.FileReader = class
};
let settings = new OV.ImportSettings ();
importer.ImportFilesFromFileObjects (files, settings, {
importer.ImportFiles (files, OV.FileSource.File, settings, {
onFilesLoaded : function () {
},

View File

@ -103,16 +103,6 @@ OV.Importer = class
this.importers.push (importer);
}
ImportFilesFromUrls (urlList, settings, callbacks)
{
this.ImportFiles (urlList, OV.FileSource.Url, settings, callbacks);
}
ImportFilesFromFileObjects (fileList, settings, callbacks)
{
this.ImportFiles (fileList, OV.FileSource.File, settings, callbacks);
}
ImportFiles (fileList, fileSource, settings, callbacks)
{
this.LoadFiles (fileList, fileSource, () => {
@ -132,7 +122,7 @@ OV.Importer = class
newFileList.FillFromFileObjects (fileList);
}
let reset = false;
if (this.HasMainFile (newFileList)) {
if (this.HasImportableFile (newFileList)) {
reset = true;
} else {
let foundMissingFile = false;
@ -162,7 +152,29 @@ OV.Importer = class
ImportLoadedFiles (settings, callbacks)
{
let mainFile = this.GetMainFile (this.fileList);
let importableFiles = this.GetImportableFiles (this.fileList);
if (importableFiles.length === 0) {
callbacks.onImportError (new OV.ImportError (OV.ImportErrorCode.NoImportableFile, null));
return;
}
if (importableFiles.length === 1 || !callbacks.onSelectMainFile) {
let mainFile = importableFiles[0];
this.ImportLoadedMainFile (mainFile, settings, callbacks);
} else {
callbacks.onSelectMainFile (importableFiles, (mainFileIndex) => {
if (mainFileIndex === null) {
callbacks.onImportError (new OV.ImportError (OV.ImportErrorCode.NoImportableFile, null));
return;
}
let mainFile = importableFiles[mainFileIndex];
this.ImportLoadedMainFile (mainFile, settings, callbacks);
});
}
}
ImportLoadedMainFile (mainFile, settings, callbacks)
{
if (mainFile === null || mainFile.file === null || mainFile.file.content === null) {
callbacks.onImportError (new OV.ImportError (OV.ImportErrorCode.NoImportableFile, null));
return;
@ -256,12 +268,13 @@ OV.Importer = class
return this.fileList;
}
HasMainFile (fileList)
HasImportableFile (fileList)
{
return this.GetMainFile (fileList) !== null;
let importableFiles = this.GetImportableFiles (fileList);
return importableFiles.length > 0;
}
GetMainFile (fileList)
GetImportableFiles (fileList)
{
function FindImporter (file, importers)
{
@ -274,18 +287,19 @@ OV.Importer = class
return null;
}
let importableFiles = [];
let files = fileList.GetFiles ();
for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
let file = files[fileIndex];
let importer = FindImporter (file, this.importers);
if (importer !== null) {
return {
importableFiles.push ({
file : file,
importer : importer
};
});
}
}
return null;
return importableFiles;
}
RevokeModelUrls ()

View File

@ -36,6 +36,13 @@ OV.ThreeModelLoader = class
onFilesLoaded : () => {
this.callbacks.onImportStart ();
},
onSelectMainFile : (files, selectFile) => {
if (!this.callbacks.onSelectMainFile) {
selectFile (0);
} else {
this.callbacks.onSelectMainFile (files, selectFile);
}
},
onImportSuccess : (importResult) => {
this.OnModelImported (importResult);
},

View File

@ -12,7 +12,7 @@ function ExportImport (model, format, extension, onReady)
}
let importer = new OV.Importer ();
let settings = new OV.ImportSettings ();
importer.ImportFilesFromFileObjects (fileObjects, settings, {
importer.ImportFiles (fileObjects, OV.FileSource.File, settings, {
onFilesLoaded : function () {
},

View File

@ -4,7 +4,7 @@ var path = require ('path');
function ImportFilesWithImporter (importer, files, callbacks)
{
let settings = new OV.ImportSettings ();
importer.ImportFilesFromFileObjects (files, settings, {
importer.ImportFiles (files, OV.FileSource.File, settings, {
onFilesLoaded : function () {
},
@ -254,7 +254,7 @@ describe ('Importer Test', function () {
let theImporter = new OV.Importer ();
let settings = new OV.ImportSettings ();
settings.defaultColor = new OV.Color (200, 0, 0);
theImporter.ImportFilesFromFileObjects (files, settings, {
theImporter.ImportFiles (files, OV.FileSource.File, settings, {
onFilesLoaded : function () {
},

View File

@ -116,22 +116,31 @@ div.ov_dialog div.ov_dialog_file_list
overflow: auto;
}
div.ov_dialog a.ov_dialog_file_link
div.ov_dialog div.ov_dialog_import_file_list
{
max-height: 300px;
overflow: auto;
}
div.ov_dialog div.ov_dialog_file_link
{
color: var(--ov_button_color);
padding: 5px;
display: block;
overflow: auto;
border-radius: 5px;
cursor: pointer;
}
div.ov_dialog a.ov_dialog_file_link div.ov_file_link_img
div.ov_dialog div.ov_dialog_file_link div.ov_file_link_img
{
color: var(--ov_button_color);
margin-top: 2px;
margin-right: 10px;
float: left;
}
div.ov_dialog a.ov_dialog_file_link div.ov_dialog_file_link_text
div.ov_dialog div.ov_dialog_file_link div.ov_dialog_file_link_text
{
float: left;
}
@ -234,13 +243,13 @@ div.ov_progress div.ov_progress_text
@media (hover)
{
div.ov_dialog a.ov_dialog_file_link:hover
div.ov_dialog div.ov_dialog_file_link:hover
{
color: var(--ov_hover_text_color);
background: var(--ov_hover_color);
}
div.ov_dialog a.ov_dialog_file_link:hover div.ov_file_link_img
div.ov_dialog div.ov_dialog_file_link:hover div.ov_file_link_img
{
color: var(--ov_hover_text_color);
}

View File

@ -212,14 +212,13 @@ OV.ExportDialog = class
let fileListSection = OV.AddDiv (contentDiv, 'ov_dialog_section');
let fileList = OV.AddDiv (fileListSection, 'ov_dialog_file_list ov_thin_scrollbar');
for (let i = 0; i < files.length; i++) {
let file = files[i];
let url = OV.CreateObjectUrl (file.GetBufferContent ());
let fileLink = OV.AddDomElement (fileList, 'a', 'ov_dialog_file_link');
fileLink.setAttribute ('href', url);
fileLink.setAttribute ('download', file.GetName ());
for (let file of files) {
let fileLink = OV.AddDiv (fileList, 'ov_dialog_file_link');
OV.AddSvgIconElement (fileLink, 'file_download', 'ov_file_link_img');
OV.AddDiv (fileLink, 'ov_dialog_file_link_text', file.GetName ());
fileLink.addEventListener ('click', () => {
OV.DownloadArrayBufferAsFile (file.GetBufferContent (), file.GetName ());
});
}
dialog.Show ();

View File

@ -23,6 +23,44 @@ OV.InitModelLoader = function (modelLoader, callbacks)
}
}
function ShowFileSelectorDialog (files, onSelect)
{
let dialog = new OV.ButtonDialog ();
let contentDiv = dialog.Init ('Select Model', [
{
name : 'Cancel',
subClass : 'outline',
onClick () {
dialog.Hide ();
}
}
]);
dialog.SetCloseHandler (() => {
onSelect (null);
});
let text = 'Multiple importable models found. Select the model you would like to import from the list below.';
OV.AddDiv (contentDiv, 'ov_dialog_message', text);
let fileListSection = OV.AddDiv (contentDiv, 'ov_dialog_section');
let fileList = OV.AddDiv (fileListSection, 'ov_dialog_import_file_list ov_thin_scrollbar');
for (let i = 0; i < files.length; i++) {
let file = files[i];
let fileLink = OV.AddDiv (fileList, 'ov_dialog_file_link');
OV.AddSvgIconElement (fileLink, 'meshes', 'ov_file_link_img');
OV.AddDiv (fileLink, 'ov_dialog_file_link_text', file.file.name);
fileLink.addEventListener ('click', () => {
dialog.SetCloseHandler (null);
dialog.Hide ();
onSelect (i);
});
}
dialog.Show ();
return dialog;
}
function CloseDialogIfOpen (dialog)
{
if (dialog !== null) {
@ -31,16 +69,23 @@ OV.InitModelLoader = function (modelLoader, callbacks)
}
}
let errorDialog = null;
let modalDialog = null;
let progressDialog = null;
modelLoader.Init ({
onLoadStart : () => {
CloseDialogIfOpen (errorDialog);
CloseDialogIfOpen (modalDialog);
callbacks.onStart ();
progressDialog = new OV.ProgressDialog ();
progressDialog.Init ('Loading Model');
progressDialog.Show ();
},
onSelectMainFile : (files, selectFile) => {
progressDialog.Hide ();
modalDialog = ShowFileSelectorDialog (files, (index) => {
progressDialog.Show ();
selectFile (index);
});
},
onImportStart : () => {
progressDialog.SetText ('Importing Model');
},
@ -57,7 +102,7 @@ OV.InitModelLoader = function (modelLoader, callbacks)
onLoadError : (importError) => {
progressDialog.Hide ();
callbacks.onError (importError);
errorDialog = OpenErrorDialog (importError);
modalDialog = OpenErrorDialog (importError);
},
});
};