Ver código fonte

Added tabs to image to pattern function

Thokoop 11 meses atrás
pai
commit
1669bfdbbe
5 arquivos alterados com 97 adições e 34 exclusões
  1. 33 12
      static/css/image2sand.css
  2. 10 4
      static/css/style.css
  3. 28 0
      static/js/image2sand-init.js
  4. 12 10
      static/js/main.js
  5. 14 8
      templates/index.html

+ 33 - 12
static/css/image2sand.css

@@ -7,14 +7,42 @@
     flex-grow: 1;
     flex-grow: 1;
 }
 }
 
 
-.image-converter-steps {
-    flex-wrap: wrap;
-    gap: 10px;
+.image-converter-steps .tab-container {
     display: flex;
     display: flex;
+    width: 100%;
+}
+
+.image-converter-steps canvas {
+    background-color: white;
+}
+
+.image-converter-steps .tab-content.active {
+    flex: auto;
+}
+
+#generate-button.loading {
+    position: relative;
+    pointer-events: none;
+    opacity: 0.7;
+}
+
+#generate-button.loading i {
+    display: none;
 }
 }
 
 
-.image-converter-steps > .image-converter-preview {
-    width: 33%;
+#generate-button.loading::before {
+    content: "";
+    width: 16px;
+    height: 16px;
+    border: 3px solid white;
+    border-top-color: transparent;
+    border-radius: 50%;
+    animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+    from { transform: rotate(0deg); }
+    to { transform: rotate(360deg); }
 }
 }
 
 
 .image-converter-header {
 .image-converter-header {
@@ -287,11 +315,4 @@ canvas#connect-image {
         width: calc(100% / 3);
         width: calc(100% / 3);
     }
     }
 
 
-    .image-converter-steps {
-        overflow-y: auto;
-    }
-
-    .image-converter-steps > .image-converter-preview:last-of-type {
-        max-width: none;
-    }
 }
 }

+ 10 - 4
static/css/style.css

@@ -410,6 +410,9 @@ button.warning:hover{}
     display: none;
     display: none;
     flex: 1;
     flex: 1;
     overflow-y: auto;
     overflow-y: auto;
+}
+
+.app > .tab-content {
     background: var(--background-secondary);
     background: var(--background-secondary);
 }
 }
 
 
@@ -1389,16 +1392,19 @@ input[type="number"]:focus {
 
 
     /* Show all tabs in grid layout */
     /* Show all tabs in grid layout */
     .tab-content {
     .tab-content {
-        display: flex !important; /* Always display tab-content */
         flex-direction: column;
         flex-direction: column;
-        border: 1px solid var(--border-primary);
-        background-color: var(--background-primary);
-        border-radius: 8px;
         overflow-y: auto;
         overflow-y: auto;
         overflow-x: hidden;
         overflow-x: hidden;
         position: relative;
         position: relative;
     }
     }
 
 
+    .app > .tab-content {
+        display: flex !important; /* Always display main tab-content */
+        border-radius: 8px;
+        background-color: var(--background-primary);
+        border: 1px solid var(--border-primary);
+    }
+
     body.playing .app {
     body.playing .app {
         padding: 15px 0 150px 15px;
         padding: 15px 0 150px 15px;
         margin-bottom: -140px;
         margin-bottom: -140px;

+ 28 - 0
static/js/image2sand-init.js

@@ -251,6 +251,34 @@ async function generateOpenAIImage(apiKey, prompt) {
 
 
 }
 }
 
 
+function regeneratePattern() {
+    const generateButton = document.getElementById('generate-button');
+
+    // Disable button & show existing loader
+    generateButton.disabled = true;
+    generateButton.classList.add('loading');
+    // Wrap convertImage() in a Promise
+    new Promise((resolve, reject) => {
+        try {
+            convertImage();
+            setTimeout(resolve, 1000);
+        } catch (error) {
+            reject(error);
+        }
+    })
+        .then(() => {
+            logMessage("Pattern regenerated successfully.", LOG_TYPE.SUCCESS);
+        })
+        .catch(error => {
+            logMessage("Error regenerating pattern: " + error.message, LOG_TYPE.ERROR);
+        })
+        .finally(() => {
+            // Re-enable button & hide loader
+            generateButton.disabled = false;
+            generateButton.classList.remove('loading');
+        });
+}
+
 // Override the uploadThetaRho function to handle image files
 // Override the uploadThetaRho function to handle image files
 const originalUploadThetaRho = window.uploadThetaRho;
 const originalUploadThetaRho = window.uploadThetaRho;
 
 

+ 12 - 10
static/js/main.js

@@ -1618,12 +1618,12 @@ function attachSettingsSaveListeners() {
 
 
 
 
 // Tab switching logic with cookie storage
 // Tab switching logic with cookie storage
-function switchTab(tabName) {
-    // Store the active tab in a cookie
-    setCookie('activeTab', tabName, 365); // Store for 7 days
+function switchTab(tabName, tabGroup = 'main') {
+    // Store the active tab in a cookie (per tab group)
+    setCookie(`activeTab-${tabGroup}`, tabName, 365);
 
 
-    // Deactivate all tab content
-    document.querySelectorAll('.tab-content').forEach(tab => {
+    // Deactivate all tab content in the specific group
+    document.querySelectorAll(`.tab-content[data-group="${tabGroup}"]`).forEach(tab => {
         tab.classList.remove('active');
         tab.classList.remove('active');
     });
     });
 
 
@@ -1635,8 +1635,8 @@ function switchTab(tabName) {
         console.error(`Error: Tab "${tabName}" not found.`);
         console.error(`Error: Tab "${tabName}" not found.`);
     }
     }
 
 
-    // Deactivate all nav buttons
-    document.querySelectorAll('.bottom-nav .tab-button').forEach(button => {
+    // Deactivate all buttons in this group
+    document.querySelectorAll(`.tab-button[data-group="${tabGroup}"]`).forEach(button => {
         button.classList.remove('active');
         button.classList.remove('active');
     });
     });
 
 
@@ -1824,8 +1824,10 @@ function stopStatusUpdates() {
 }
 }
 
 
 document.addEventListener('DOMContentLoaded', () => {
 document.addEventListener('DOMContentLoaded', () => {
-    const activeTab = getCookie('activeTab') || 'patterns'; // Default to 'patterns' tab
-    switchTab(activeTab); // Load the active tab
+    const activeMainTab = getCookie('activeTab-main') || 'patterns';
+    switchTab(activeMainTab, 'main');
+    const activeImageConverterTab = getCookie('activeTab-image-converter') || 'dot';
+    switchTab(activeImageConverterTab, 'image-converter');
     checkSerialStatus(); // Check connection status
     checkSerialStatus(); // Check connection status
     loadThetaRhoFiles(); // Load files on page load
     loadThetaRhoFiles(); // Load files on page load
     loadAllPlaylists(); // Load all playlists on page load
     loadAllPlaylists(); // Load all playlists on page load
@@ -1834,7 +1836,7 @@ document.addEventListener('DOMContentLoaded', () => {
     loadWledIp();
     loadWledIp();
     updateWledUI();
     updateWledUI();
     checkForUpdates();
     checkForUpdates();
-    requestStatusUpdate(); // Request initial status update on page load
+    requestStatusUpdate(); // Request initial status upstdate on page load
 });
 });
 
 
 // Track the last time we had a file playing
 // Track the last time we had a file playing

+ 14 - 8
templates/index.html

@@ -138,24 +138,30 @@
                     <i class="fa-solid fa-xmark"></i>
                     <i class="fa-solid fa-xmark"></i>
                 </button>
                 </button>
             </div>
             </div>
-            <div class="image-converter-content">
+            <div class="image-converter-content grid">
                 <div id="processing-status" class="processing-indicator">
                 <div id="processing-status" class="processing-indicator">
                     <div class="spinner"></div>
                     <div class="spinner"></div>
                     <span id="processing-message">Processing image...</span>
                     <span id="processing-message">Processing image...</span>
                 </div>
                 </div>
                 <div class="image-converter-steps">
                 <div class="image-converter-steps">
-                    <div class="image-converter-preview">
-                        <h3>Original Image</h3>
+                    <div class="tab-content" id="original-tab" data-group="image-converter">
                         <canvas id="original-image"></canvas>
                         <canvas id="original-image"></canvas>
                     </div>
                     </div>
-                    <div class="image-converter-preview">
-                        <h3>Detected Edges</h3>
+
+                    <div class="tab-content" id="edge-tab" data-group="image-converter">
                         <canvas id="edge-image"></canvas>
                         <canvas id="edge-image"></canvas>
                     </div>
                     </div>
-                    <div class="image-converter-preview">
-                        <h3>Identified Points</h3>
+
+                    <div class="tab-content" id="dot-tab" data-group="image-converter">
                         <canvas id="dot-image"></canvas>
                         <canvas id="dot-image"></canvas>
                     </div>
                     </div>
+
+                    <div class="tab-container">
+                        <button class="tab-button" onclick="switchTab('original', 'image-converter')" id="nav-original" data-group="image-converter">Original Image</button>
+                        <button class="tab-button" onclick="switchTab('edge', 'image-converter')" id="nav-edge" data-group="image-converter">Detected Edges</button>
+                        <button class="tab-button" onclick="switchTab('dot', 'image-converter')" id="nav-dot" data-group="image-converter">Identified Points</button>
+                    </div>
+
                 </div>
                 </div>
 
 
                 <div class="image-converter-settings">
                 <div class="image-converter-settings">
@@ -200,7 +206,7 @@
                     </div>
                     </div>
                     <input type="hidden" id="output-type" value="2">
                     <input type="hidden" id="output-type" value="2">
                     <div class="generate-button-container">
                     <div class="generate-button-container">
-                        <button id="generate-button" class="cta" onclick="convertImage()">
+                        <button id="generate-button" class="cta" onclick="regeneratePattern()">
                             <i class="fa-solid fa-wand-magic-sparkles"></i>
                             <i class="fa-solid fa-wand-magic-sparkles"></i>
                             <span>Regenerate Pattern</span>
                             <span>Regenerate Pattern</span>
                         </button>
                         </button>