From 740e728827d996facd8f1061a224890629900f03 Mon Sep 17 00:00:00 2001 From: Skyler Lehmkuhl Date: Tue, 26 Nov 2024 19:07:41 -0500 Subject: [PATCH] add new file dialog --- src/main.js | 42 +++++++++++++++++++++++-- src/newfile.js | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/styles.css | 58 +++++++++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 src/newfile.js diff --git a/src/main.js b/src/main.js index 09f8830..a5fc5a4 100644 --- a/src/main.js +++ b/src/main.js @@ -2,6 +2,7 @@ const { invoke } = window.__TAURI__.core; import * as fitCurve from '/fit-curve.js'; import { Bezier } from "/bezier.js"; import { Quadtree } from './quadtree.js'; +import { createNewFileDialog, showNewFileDialog, closeDialog } from './newfile.js'; const { writeTextFile: writeTextFile, readTextFile: readTextFile }= window.__TAURI__.fs; const { open: openFileDialog, @@ -39,6 +40,8 @@ let minFileVersion = "1.0" let maxFileVersion = "2.0" let filePath = undefined +let fileWidth = 1500 +let fileHeight = 1000 let tools = { @@ -113,6 +116,7 @@ let config = { // undo: "+z" undo: "z", redo: "Z", + new: "n", save: "s", saveAs: "S", open: "o", @@ -1143,6 +1147,8 @@ window.addEventListener("keypress", (e) => { undo() } else if (e.key == config.shortcuts.redo && e.ctrlKey == true) { redo() + } else if (e.key == config.shortcuts.new && e.ctrlKey == true) { + newFile() } else if (e.key == config.shortcuts.save && e.ctrlKey == true) { save() } else if (e.key == config.shortcuts.saveAs && e.ctrlKey == true) { @@ -1154,10 +1160,33 @@ window.addEventListener("keypress", (e) => { } }) +function _newFile(width, height) { + root = new GraphicsObject("root"); + context.activeObject = root + fileWidth = width + fileHeight = height + for (let stage of document.querySelectorAll(".stage")) { + stage.width = width + stage.height = height + stage.style.width = `${width}px` + stage.style.height = `${height}px` + } + updateUI() +} + +async function newFile() { + if (await confirmDialog("Create a new file? Unsaved work will be lost.", {title: "New file", kind: "warning"})) { + showNewFileDialog() + // updateUI() + } +} + async function _save(path) { try { const fileData = { - version: "1.0", + version: "1.1", + width: fileWidth, + height: fileHeight, actions: undoStack } const contents = JSON.stringify(fileData ); @@ -1213,8 +1242,7 @@ async function open() { } if (file.version >= minFileVersion) { if (file.version < maxFileVersion) { - root = new GraphicsObject("root"); - context.activeObject = root + _newFile(file.width, file.height) if (file.actions == undefined) { await messageDialog("File has no content!", {title: "Parse error", kind: 'error'}) return @@ -1703,6 +1731,11 @@ async function setupMenu() { const fileSubmenu = await Submenu.new({ text: 'File', items: [ + { + text: 'New file...', + enabled: true, + action: newFile, + }, { text: 'Save', enabled: true, @@ -1795,6 +1828,9 @@ async function setupMenu() { // Initialize the menu when the app starts setupMenu(); +createNewFileDialog(_newFile); +showNewFileDialog() + function createPane(content=undefined) { let div = document.createElement("div") let header = document.createElement("div") diff --git a/src/newfile.js b/src/newfile.js new file mode 100644 index 0000000..a6acf15 --- /dev/null +++ b/src/newfile.js @@ -0,0 +1,83 @@ +let overlay; +let newFileDialog; + +function createNewFileDialog(callback) { + overlay = document.createElement('div'); + overlay.id = 'overlay'; + document.body.appendChild(overlay); + + newFileDialog = document.createElement('div'); + newFileDialog.id = 'newFileDialog'; + newFileDialog.classList.add('hidden'); + document.body.appendChild(newFileDialog); + + // Create dialog content dynamically + const title = document.createElement('h3'); + title.textContent = 'Create New File'; + newFileDialog.appendChild(title); + + // Create Width input + const widthLabel = document.createElement('label'); + widthLabel.setAttribute('for', 'width'); + widthLabel.classList.add('dialog-label'); + widthLabel.textContent = 'Width:'; + newFileDialog.appendChild(widthLabel); + + const widthInput = document.createElement('input'); + widthInput.type = 'number'; + widthInput.id = 'width'; + widthInput.classList.add('dialog-input'); + widthInput.value = '1500'; // Default value + newFileDialog.appendChild(widthInput); + + // Create Height input + const heightLabel = document.createElement('label'); + heightLabel.setAttribute('for', 'height'); + heightLabel.classList.add('dialog-label'); + heightLabel.textContent = 'Height:'; + newFileDialog.appendChild(heightLabel); + + const heightInput = document.createElement('input'); + heightInput.type = 'number'; + heightInput.id = 'height'; + heightInput.classList.add('dialog-input'); + heightInput.value = '1000'; // Default value + newFileDialog.appendChild(heightInput); + + // Create Create button + const createButton = document.createElement('button'); + createButton.textContent = 'Create'; + createButton.classList.add('dialog-button'); + createButton.onclick = createNewFile; + newFileDialog.appendChild(createButton); + + + // Create the new file (simulation) + function createNewFile() { + const width = document.getElementById('width').value; + const height = document.getElementById('height').value; + console.log(`New file created with width: ${width} and height: ${height}`); + console.log(callback) + callback(width, height) + + // Add any further logic to handle the new file creation here + + closeDialog(); // Close the dialog after file creation + } + + // Close the dialog if the overlay is clicked + overlay.onclick = closeDialog; +} + +// Show the dialog +function showNewFileDialog() { + overlay.style.display = 'block'; + newFileDialog.style.display = 'block'; +} + +// Close the dialog +function closeDialog() { + overlay.style.display = 'none'; + newFileDialog.style.display = 'none'; +} +export { createNewFileDialog, showNewFileDialog, closeDialog }; \ No newline at end of file diff --git a/src/styles.css b/src/styles.css index 6a08714..9489948 100644 --- a/src/styles.css +++ b/src/styles.css @@ -169,6 +169,7 @@ button { overflow: scroll; width: 100%; height: 100%; + background-color: #555; } .stage { width: 1500px; @@ -284,4 +285,61 @@ button { } .frame:hover { background-color: #555555; +} + + +.hidden { + display: none; +} + +#overlay { + display: none; /* Hidden by default */ + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + z-index: 999; /* Under the dialog */ +} + +/* Scoped styles for the dialog */ +#newFileDialog { + display: none; /* Hidden by default */ + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: #444; + border: 1px solid #333; + border-radius: 5px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); + padding: 20px; + width: 300px; + z-index: 1000; /* Make sure it's in front of other elements */ +} + +#newFileDialog .dialog-label { + display: block; + margin: 10px 0 5px; +} + +#newFileDialog .dialog-input { + width: 100%; + padding: 8px; + margin: 5px 0; + border: 1px solid #333; +} + +#newFileDialog .dialog-button { + width: 100%; + padding: 10px; + background-color: #007bff; + color: white; + border: none; + cursor: pointer; +} + +#newFileDialog .dialog-button:hover { + background-color: #0056b3; } \ No newline at end of file