Make polyfilled save dialog consistent with other dialogs
This commit is contained in:
parent
2ab0df9835
commit
df3e2832bf
|
|
@ -4841,7 +4841,7 @@ function createProgressModal() {
|
||||||
// Create text to show the current frame info
|
// Create text to show the current frame info
|
||||||
const progressText = document.createElement('p');
|
const progressText = document.createElement('p');
|
||||||
progressText.id = 'progressText';
|
progressText.id = 'progressText';
|
||||||
progressText.innerText = 'Rendering frame 0 of 0';
|
progressText.innerText = 'Initializing...';
|
||||||
|
|
||||||
// Append elements to modalContent
|
// Append elements to modalContent
|
||||||
modalContent.appendChild(progressBar);
|
modalContent.appendChild(progressBar);
|
||||||
|
|
|
||||||
|
|
@ -490,7 +490,7 @@ button {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#overlay {
|
#overlay, #saveOverlay {
|
||||||
display: none; /* Hidden by default */
|
display: none; /* Hidden by default */
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
@ -502,7 +502,7 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scoped styles for the dialog */
|
/* Scoped styles for the dialog */
|
||||||
#newFileDialog {
|
#newFileDialog, #saveDialog {
|
||||||
display: none; /* Hidden by default */
|
display: none; /* Hidden by default */
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
|
|
@ -517,19 +517,19 @@ button {
|
||||||
z-index: 1000; /* Make sure it's in front of other elements */
|
z-index: 1000; /* Make sure it's in front of other elements */
|
||||||
}
|
}
|
||||||
|
|
||||||
#newFileDialog .dialog-label {
|
#newFileDialog .dialog-label, #saveDialog label {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 10px 0 5px;
|
margin: 10px 0 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#newFileDialog .dialog-input {
|
#newFileDialog .dialog-input, #saveDialog input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
border: 1px solid #aaa;
|
border: 1px solid #aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
#newFileDialog .dialog-button {
|
#newFileDialog .dialog-button, #saveDialog button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
@ -632,11 +632,11 @@ button {
|
||||||
background-color: #0f0f0f69;
|
background-color: #0f0f0f69;
|
||||||
}
|
}
|
||||||
|
|
||||||
#newFileDialog {
|
#newFileDialog, #saveDialog {
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
border: 1px solid #333;
|
border: 1px solid #333;
|
||||||
}
|
}
|
||||||
#newFileDialog .dialog-input {
|
#newFileDialog .dialog-input, #saveDialog input {
|
||||||
border: 1px solid #333;
|
border: 1px solid #333;
|
||||||
}
|
}
|
||||||
#recentFilesList li:hover {
|
#recentFilesList li:hover {
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,88 @@ if (!window.__TAURI__) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function promptForFilename(filters, defaultFilename = '') {
|
||||||
|
function createLabel(text, forId) {
|
||||||
|
const label = document.createElement('label');
|
||||||
|
label.setAttribute('for', forId);
|
||||||
|
label.textContent = text;
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// Create and style modal dynamically
|
||||||
|
const modal = document.createElement('div');
|
||||||
|
const modalContent = document.createElement('div');
|
||||||
|
const filenameInput = document.createElement('input');
|
||||||
|
const fileFilter = document.createElement('select');
|
||||||
|
const submitBtn = document.createElement('button');
|
||||||
|
const cancelBtn = document.createElement('button');
|
||||||
|
|
||||||
|
// Append elements
|
||||||
|
modal.appendChild(modalContent);
|
||||||
|
modalContent.appendChild(createLabel('Enter filename:', 'filenameInput'));
|
||||||
|
modalContent.appendChild(filenameInput);
|
||||||
|
modalContent.appendChild(createLabel('Select file type:', 'fileFilter'));
|
||||||
|
modalContent.appendChild(fileFilter);
|
||||||
|
modalContent.appendChild(submitBtn);
|
||||||
|
modalContent.appendChild(cancelBtn);
|
||||||
|
|
||||||
|
document.body.appendChild(modal);
|
||||||
|
|
||||||
|
// Style modal elements
|
||||||
|
modal.id = "saveOverlay";
|
||||||
|
modal.style.display = 'block';
|
||||||
|
modalContent.id = "saveDialog";
|
||||||
|
modalContent.style.display = 'block';
|
||||||
|
[filenameInput, fileFilter].forEach(el => Object.assign(el.style, {
|
||||||
|
width: '100%', padding: '10px', marginBottom: '10px'
|
||||||
|
}));
|
||||||
|
[submitBtn, cancelBtn].forEach(el => el.style.padding = '10px 20px');
|
||||||
|
|
||||||
|
// Populate filter dropdown and set default filename
|
||||||
|
filters.forEach(filter => fileFilter.add(new Option(filter.name, filter.extensions[0])));
|
||||||
|
// filenameInput.value = defaultFilename.split('.')[0];
|
||||||
|
filenameInput.value = defaultFilename
|
||||||
|
const extension = defaultFilename.split('.').pop();
|
||||||
|
filenameInput.focus()
|
||||||
|
filenameInput.setSelectionRange(0, defaultFilename.length - extension.length - 1); // Select only the base filename
|
||||||
|
|
||||||
|
// Update extension based on selected filter
|
||||||
|
fileFilter.addEventListener('change', () => updateFilename(true));
|
||||||
|
filenameInput.addEventListener('input', () => updateFilename(false));
|
||||||
|
|
||||||
|
function updateFilename(reselect) {
|
||||||
|
const base = filenameInput.value.split('.')[0];
|
||||||
|
filenameInput.value = `${base}.${fileFilter.value}`;
|
||||||
|
if (reselect) {
|
||||||
|
filenameInput.focus()
|
||||||
|
filenameInput.setSelectionRange(0, base.length); // Select only the base filename
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle buttons
|
||||||
|
submitBtn.textContent = 'Submit';
|
||||||
|
cancelBtn.textContent = 'Cancel';
|
||||||
|
submitBtn.onclick = () => {
|
||||||
|
const chosenFilename = filenameInput.value;
|
||||||
|
if (!chosenFilename) reject(new Error('Filename missing.'));
|
||||||
|
resolve(chosenFilename);
|
||||||
|
modal.remove();
|
||||||
|
};
|
||||||
|
cancelBtn.onclick = () => {
|
||||||
|
reject(new Error('User canceled.'));
|
||||||
|
modal.remove();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Close modal if clicked outside
|
||||||
|
window.addEventListener('click', (e) => {
|
||||||
|
if (e.target === modal) {
|
||||||
|
reject(new Error('User clicked outside.'));
|
||||||
|
modal.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
window.__TAURI__ = {
|
window.__TAURI__ = {
|
||||||
core: {
|
core: {
|
||||||
invoke: () => {}
|
invoke: () => {}
|
||||||
|
|
@ -184,8 +266,8 @@ if (!window.__TAURI__) {
|
||||||
input.click();
|
input.click();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
save: async () => {
|
save: async (params) => {
|
||||||
return prompt("Filename", "untitled.beam")
|
return await promptForFilename(params.filters, params.defaultPath)
|
||||||
},
|
},
|
||||||
message: () => {},
|
message: () => {},
|
||||||
confirm: () => {},
|
confirm: () => {},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue