Przeglądaj źródła

Various styling improvements, moved settings to separate overlay.

Thokoop 1 rok temu
rodzic
commit
733da59b53
3 zmienionych plików z 212 dodań i 192 usunięć
  1. 85 63
      static/css/style.css
  2. 35 67
      static/js/main.js
  3. 92 62
      templates/index.html

+ 85 - 63
static/css/style.css

@@ -180,77 +180,84 @@ input, select {
     border-color: var(--theme-primary-hover);
 }
 
-.dropdown {
-    position: relative;
+
+/* Scrollable Selection Styles */
+.scrollable-selection {
     display: flex;
-    flex-grow: 1;
+    flex-direction: row;
+    align-items: center;
+    min-width: 50%;
+    position: relative;
 }
 
-.dropdown-button {
+.scroll-arrow {
     border: none;
-    cursor: pointer;
-    display: inline-flex;
-    align-items: center;
-    justify-content: space-between;
-    position: relative;
+    padding: 5px;
     width: 100%;
-    height: 100%;
-    padding: 0;
+    cursor: pointer;
+    font-size: 1.2rem;
+    transition: background-color 0.3s;
 }
 
-.dropdown-button > span {
-    padding: 10px;
+.scroll-arrow:hover {
+    background: var(--theme-primary-hover);
 }
 
-.dropdown-toggle {
-    margin-left: 10px;
-    cursor: pointer;
-    user-select: none;
-    height: 100%;
-    aspect-ratio: 1 / 2;
+.selection-container {
+    overflow: hidden;
+    height: 50px; /* Adjust based on visible area */
+    width: 100%;
+    position: relative;
+    border: 1px solid var(--border-primary);
+    background: var(--theme-primary);
+    color: var(--text-secondary);
+    border-radius: 5px;
+}
+
+.nav-items {
+    position: absolute;
+    right: 0;
+    top: 0;
     display: flex;
+    height: 100%;
+    flex-direction: column;
     justify-content: center;
     align-items: center;
 }
 
-.dropdown-toggle:hover {
+.selection-container .nav-items > button {
+    height: 50%;
+    padding: 0;
+    width: 100% !important;
+}
+
+.selection-container .nav-items > button:hover {
     background: var(--text-secondary);
     color: var(--theme-primary);
-    border-radius: 5px;
 }
 
-.dropdown-content {
-    position: absolute;
-    width: 100%;
-    top: 100%;
-    color: var(--theme-primary);
-    background: var(--text-secondary);
-    min-width: 120px;
-    box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2);
-    z-index: 1;
-    display: none;
-    border-radius: 5px;
-    padding: 5px;
+.selection-items {
+    display: flex;
+    flex-direction: column;
+    transition: transform 0.3s ease;
+    padding-right: 30px;
 }
 
-.dropdown-content button.no-bg {
-    width: 100%;
-    color: var(--theme-primary);
-    background: none;
-    border: none;
-    text-align: left;
-    padding: 10px;
+.selection-item {
+    height: 50px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
     cursor: pointer;
-    aspect-ratio: auto;
-    font-size: 0.9rem;
-    margin: 0;
+    padding: 5px;
+    transition: background-color 0.3s ease;
 }
 
-.dropdown-content button:hover {
-    background-color: var(--background-tertiary);
+.selection-item:hover {
+    background: var(--theme-primary-hover);
+    color: var(--text-secondary);
 }
 
-
 /* Buttons */
 button {
     background: var(--theme-primary);
@@ -326,7 +333,7 @@ section.main {
 
 section.debug {
     flex-direction: row;
-    align-items: center;
+    align-items: flex-end;
     justify-content: space-between;
 }
 
@@ -403,6 +410,10 @@ section .header h2 {
     flex-grow: 1;
 }
 
+section .header #open-settings-button:hover{
+    color: var(--theme-primary);
+}
+
 /* Close Button Styling */
 button.no-bg {
     background: none;
@@ -617,7 +628,10 @@ section .header .add-button {
     gap: 10px;
     flex-wrap: wrap;
     width: 100%;
-    justify-content: flex-end;
+}
+
+.action-buttons .scrollable-selection {
+    width: calc(50% - 10px);
 }
 
 .action-buttons.square button {
@@ -629,14 +643,8 @@ section .header .add-button {
     align-items: center;
 }
 
-.action-buttons.square .dropdown-content button {
-    width: 100%;
-    aspect-ratio: auto;
-    padding: 10px;
-}
-
 .action-buttons.square button i{
-    font-size: 2rem;
+    font-size: 2.5rem;
 }
 
 button i + span{
@@ -659,13 +667,6 @@ button i + span.small {
     display: block;
 }
 
-.action-buttons button.dropdown-button {
-    aspect-ratio: auto;
-    width: 100%;
-    flex-direction: row;
-    justify-content: space-between;
-}
-
 .action-buttons button.m {
     width: calc(50% - 10px);
 }
@@ -688,6 +689,7 @@ button#debug_button {
     padding: 0;
     height: 40px;
     background: transparent;
+    color: var(--text-primary);
     font-size: 1.5rem;
     margin-left: 40px;
     flex: 0 0 auto;
@@ -699,10 +701,29 @@ button#debug_button.active {
     box-shadow: inset 0 0 4px var(--border-secondary);
 }
 
-#settings-tab .dropdown {
+#device-tab .dropdown {
     width: 50%;
 }
 
+#settings-container {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background-color: #FFFFFF80;
+    backdrop-filter: blur(10px);
+    z-index: 1000;
+    overflow-y: auto;
+    display: none; /* Hidden by default */
+    flex-direction: column;
+}
+
+#settings-container.open{
+    display: flex;
+}
+
+
 /* Preview Canvas */
 #patternPreviewCanvas {
     width: 100%;
@@ -1139,6 +1160,7 @@ input[type="number"]:focus {
         grid-template-columns: repeat(3, 1fr);
         gap: 0 16px;
         height: calc(100vh - 60px);
+        padding: 0 15px;
     }
 
     #status_log {

+ 35 - 67
static/js/main.js

@@ -253,7 +253,7 @@ function togglePausePlay() {
             .then(data => {
                 if (data.success) {
                     isPaused = false;
-                    button.innerHTML = ""; // Change to pause icon
+                    button.innerHTML = "<i class=\"fa-solid fa-pause\"></i>"; // Change to pause icon
                 }
             })
             .catch(error => console.error("Error resuming execution:", error));
@@ -264,7 +264,7 @@ function togglePausePlay() {
             .then(data => {
                 if (data.success) {
                     isPaused = true;
-                    button.innerHTML = ""; // Change to play icon
+                    button.innerHTML = "<i class=\"fa-solid fa-play\"></i>"; // Change to play icon
                 }
             })
             .catch(error => console.error("Error pausing execution:", error));
@@ -489,46 +489,33 @@ async function runClearSide() {
     await runFile('side_wiper.thr');
 }
 
-let currentClearAction = 'runClearIn';
+let scrollPosition = 0;
 
-function toggleClearDropdown(event) {
-    event.stopPropagation(); // Prevent the main button click event
-    const dropdown = document.getElementById('clear_dropdown');
-    dropdown.style.display = dropdown.style.display === 'none' ? 'block' : 'none';
-}
-
-function updateClearAction(label, actionFunction) {
-    // Update the button label
-    const clearActionLabel = document.getElementById('clear_action_label');
-    clearActionLabel.textContent = label;
-
-    // Update the current action function
-    currentClearAction = actionFunction;
+function scrollSelection(direction) {
+    const container = document.getElementById('clear_selection');
+    const itemHeight = 50; // Adjust based on CSS height
+    const maxScroll = container.children.length - 1;
 
-    // Save the new action to a cookie
-    setCookie('clear_action', label, 7);
+    // Update scroll position
+    scrollPosition += direction;
+    scrollPosition = Math.max(0, Math.min(scrollPosition, maxScroll));
 
-    // Close the dropdown
-    const dropdown = document.getElementById('clear_dropdown');
-    dropdown.style.display = 'none';
+    // Update the transform to scroll items
+    container.style.transform = `translateY(-${scrollPosition * itemHeight}px)`;
+    setCookie('clear_action_index', scrollPosition, 365);
 }
 
-function executeClearAction() {
-    if (currentClearAction && typeof window[currentClearAction] === 'function') {
-        window[currentClearAction](); // Execute the selected clear action
+function executeClearAction(actionFunction) {
+    // Save the new action to a cookie (optional)
+    setCookie('clear_action', actionFunction, 365);
+
+    if (actionFunction && typeof window[actionFunction] === 'function') {
+        window[actionFunction](); // Execute the selected clear action
     } else {
         logMessage('No clear action selected or function not found.', LOG_TYPE.ERROR);
     }
 }
 
-// Close the dropdown if clicking outside
-document.addEventListener('click', () => {
-    const dropdown = document.getElementById('clear_dropdown');
-    if (dropdown) dropdown.style.display = 'none';
-});
-// Update the clear button's onclick handler to execute the selected action
-document.getElementById('clear_button').onclick = () => executeClearAction();
-
 async function runFile(fileName) {
     const response = await fetch(`/run_theta_rho_file/${fileName}`, { method: 'POST' });
     const result = await response.json();
@@ -871,8 +858,8 @@ function clearSchedule() {
     document.getElementById("start_time").value = "";
     document.getElementById("end_time").value = "";
     document.getElementById('clear_time').style.display = 'none';
-    setCookie('start_time', '', 7);
-    setCookie('end_time', '', 7);
+    setCookie('start_time', '', 365);
+    setCookie('end_time', '', 365);
 }
 
 // Function to run the selected playlist with specified parameters
@@ -1067,7 +1054,7 @@ function populatePlaylistDropdown() {
             // Attach the onchange event listener after populating the dropdown
             select.addEventListener('change', function () {
                 const selectedPlaylist = this.value;
-                setCookie('selected_playlist', selectedPlaylist, 7); // Save to cookie
+                setCookie('selected_playlist', selectedPlaylist, 365); // Save to cookie
                 logMessage(`Selected playlist saved: ${selectedPlaylist}`);
             });
 
@@ -1548,10 +1535,11 @@ async function updateCurrentlyPlaying() {
     }
 }
 
-function hideCurrentlyPlaying() {
-    const currentlyPlayingSection = document.getElementById('currently-playing-container');
-    currentlyPlayingSection.classList.add('hidden');
-    currentlyPlayingSection.classList.remove('visible');
+function toggleSettings() {
+    const settingsContainer = document.getElementById('settings-container');
+    if (settingsContainer) {
+        settingsContainer.classList.toggle('open');
+    }
 }
 
 // Utility function to manage cookies
@@ -1577,33 +1565,29 @@ function getCookie(name) {
 function saveSettingsToCookies() {
     // Save the pause time
     const pauseTime = document.getElementById('pause_time').value;
-    setCookie('pause_time', pauseTime, 7);
+    setCookie('pause_time', pauseTime, 365);
 
     // Save the clear pattern
     const clearPattern = document.getElementById('clear_pattern').value;
-    setCookie('clear_pattern', clearPattern, 7);
+    setCookie('clear_pattern', clearPattern, 365);
 
     // Save the run mode
     const runMode = document.querySelector('input[name="run_mode"]:checked').value;
-    setCookie('run_mode', runMode, 7);
+    setCookie('run_mode', runMode, 365);
 
     // Save shuffle playlist checkbox state
     const shufflePlaylist = document.getElementById('shuffle_playlist').checked;
-    setCookie('shuffle_playlist', shufflePlaylist, 7);
+    setCookie('shuffle_playlist', shufflePlaylist, 365);
 
     // Save pre-execution action
     const preExecution = document.getElementById('pre_execution').value;
-    setCookie('pre_execution', preExecution, 7);
-
-    // Save selected clear action
-    const clearAction = document.getElementById('clear_action_label').textContent.trim();
-    setCookie('clear_action', clearAction, 7);
+    setCookie('pre_execution', preExecution, 365);
 
     // Save start and end times
     const startTime = document.getElementById('start_time').value;
     const endTime = document.getElementById('end_time').value;
-    setCookie('start_time', startTime, 7);
-    setCookie('end_time', endTime, 7);
+    setCookie('start_time', startTime, 365);
+    setCookie('end_time', endTime, 365);
 
     logMessage('Settings saved.');
 }
@@ -1640,22 +1624,6 @@ function loadSettingsFromCookies() {
         document.getElementById('pre_execution').value = preExecution;
     }
 
-    // Load selected clear action
-    const clearAction = getCookie('clear_action');
-    if (clearAction !== null) {
-        const clearLabel = document.getElementById('clear_action_label');
-        clearLabel.textContent = clearAction;
-
-        // Update the corresponding action function
-        if (clearAction === 'From Center') {
-            currentClearAction = 'runClearIn';
-        } else if (clearAction === 'From Perimeter') {
-            currentClearAction = 'runClearOut';
-        } else if (clearAction === 'Sideways') {
-            currentClearAction = 'runClearSide';
-        }
-    }
-
     // Load start and end times
     const startTime = getCookie('start_time');
     if (startTime !== null) {
@@ -1691,7 +1659,7 @@ function attachSettingsSaveListeners() {
 // Tab switching logic with cookie storage
 function switchTab(tabName) {
     // Store the active tab in a cookie
-    setCookie('activeTab', tabName, 7); // Store for 7 days
+    setCookie('activeTab', tabName, 365); // Store for 7 days
 
     // Deactivate all tab content
     document.querySelectorAll('.tab-content').forEach(tab => {

+ 92 - 62
templates/index.html

@@ -44,7 +44,9 @@
         <section id="pattern-preview-container" class="sticky hidden">
             <div class="header">
                 <h2>Preview</h2>
-                <button class="fullscreen-button no-bg">⛶</button>
+                <button class="fullscreen-button no-bg">
+                    <i class="fa-solid fa-expand"></i>
+                </button>
                 <button class="close-button no-bg" onclick="closeStickySection('pattern-preview-container')">
                     <i class="fa-solid fa-xmark"></i>
                 </button>
@@ -213,23 +215,28 @@
         <section class="main">
             <div class="header">
                 <h2>Device Controls</h2>
+                <button id="open-settings-button" class="no-bg" onclick="toggleSettings()">
+                    <i class="fa-solid fa-wrench"></i>
+                </button>
             </div>
-
             <div class="action-buttons square">
-                <div class="dropdown">
-                    <button id="clear_button" class="dropdown-button" onclick="executeClearAction()">
-                        <span>Clear <span id="clear_action_label">From Center</span></span>
-                        <span id="dropdown_toggle" class="dropdown-toggle" onclick="toggleClearDropdown(event)">▼</span>
-                    </button>
-                    <div id="clear_dropdown" class="dropdown-content" style="display: none;">
-                        <button class="no-bg" onclick="updateClearAction('From Center', 'runClearIn')">Clear From Center</button>
-                        <button class="no-bg" onclick="updateClearAction('From Perimeter', 'runClearOut')">Clear From Perimeter</button>
-                        <button class="no-bg" onclick="updateClearAction('Sideways', 'runClearSide')">Clear Sideways</button>
-                    </div>
-                </div>
+                <button onclick="stopExecution()" class="cancel"><i class="fa-solid fa-stop"></i><span class="small">Stop</span></button>
                 <button onclick="moveToCenter()"><i class="fa-solid fa-circle-dot"></i><span class="small">Move to Center</span></button>
                 <button onclick="moveToPerimeter()"><i class="fa-solid fa-circle-notch"></i><span class="small">Move to Perimeter</span></button>
                 <button onclick="sendHomeCommand()" class="warn"><i class="fa-solid fa-house"></i><span class="small">Home</span></button>
+                <div class="scrollable-selection">
+                    <div class="selection-container">
+                        <div id="clear_selection" class="selection-items">
+                            <div id="runClearIn" class="selection-item" onclick="executeClearAction('runClearIn')">Clear From Center</div>
+                            <div id="runClearOut" class="selection-item" onclick="executeClearAction('runClearOut')">Clear From Perimeter</div>
+                            <div id="runClearSide" class="selection-item" onclick="executeClearAction('runClearSide')">Clear Sideways</div>
+                        </div>
+                        <div class="nav-items">
+                            <button class="scroll-arrow up-arrow" onclick="scrollSelection(-1)">▲</button>
+                            <button class="scroll-arrow down-arrow" onclick="scrollSelection(1)">▼</button>
+                        </div>
+                    </div>
+                </div>
             </div>
             <h3>Send to Coordinate</h3>
             <div class="control-group">
@@ -243,7 +250,7 @@
                 </div>
                 <div class="item cta">
                     <button onclick="sendCoordinate()">
-                        <i class="fa-solid fa-map-pin"></i><span>Send</span>
+                        <i class="fa-solid fa-map-pin"></i><span class="small">Send</span>
                     </button>
                 </div>
             </div>
@@ -262,63 +269,82 @@
                     <input type="number" id="speed_input" placeholder="1-100" min="1" step="1" max="100">
                 </div>
                 <div class="item cta">
-                    <button class="small-button"  onclick="changeSpeed()"><i class="fa-solid fa-gauge-high"></i><span>Set Speed</span></button>
+                    <button class="small-button" onclick="changeSpeed()">
+                        <i class="fa-solid fa-gauge-high"></i>
+                        <span class="small">Set Speed</span>
+                    </button>
                 </div>
             </div>
         </section>
 
-        <section>
+        <section id="settings-container">
             <div class="header">
-                <h2>Serial Connection</h2>
-            </div>
-            <div id="serial_status_container">Status: <span id="serial_status" class="status"> Not connected</span></div>
-            <div id="serial_ports_container">
-                <label for="serial_ports">Available Ports:</label>
-                <select id="serial_ports"></select>
-                <button onclick="connectSerial()" class="cta"><span class="small">Connect</span></button>
-            </div>
-            <div id="serial_ports_buttons" class="button-group">
-                <button onclick="disconnectSerial()" class="cancel">
-                    <i class="fa-solid fa-power-off"></i><span class="small">Disconnect</span></button>
-                <button onclick="restartSerial()" class="warn">
-                    <i class="fa-solid fa-rotate-left"></i><span class="small">Restart</span></button>
+                <h2>Settings</h2>
+                <button class="no-bg" onclick="toggleSettings()">
+                    <i class="fa-solid fa-xmark"></i>
+                </button>
             </div>
-        </section>
+            <section>
+                <div class="header">
+                    <h2>Serial Connection</h2>
+                </div>
+                <div id="serial_status_container">Status: <span id="serial_status" class="status"> Not connected</span></div>
+                <div id="serial_ports_container">
+                    <label for="serial_ports">Available Ports:</label>
+                    <select id="serial_ports"></select>
+                    <button onclick="connectSerial()" class="cta">
+                        <i class="fa-solid fa-link"></i>
+                        <span>Connect</span>
+                    </button>
+                </div>
+                <div id="serial_ports_buttons" class="button-group">
+                    <button onclick="disconnectSerial()" class="cancel">
+                        <i class="fa-solid fa-link-slash"></i><span>Disconnect</span></button>
+                    <button onclick="restartSerial()" class="warn">
+                        <i class="fa-solid fa-rotate-left"></i><span>Restart</span></button>
+                </div>
+            </section>
 
-        <section class="version">
-            <div class="header">
-                <h2>Firmware Update</h2>
-            </div>
-            <div id="firmware_info">
-                <div id="motor_type"></div>
-                <div id="current_firmware_version"></div>
-                <div id="new_firmware_version"></div>
-            </div>
-            <div class="button-group">
-                <div id="motor_selection" style="display: none;">
-                    <h3>Select installed motor driver</h3>
-                    <select id="manual_motor_type">
-                        <option value="TMC2209">Arduino TMC2209</option>
-                        <option value="DRV8825">Arduino DRV8825</option>
-                        <option value="esp32">ESP32</option>
-                    </select>
-                    <button id="set_motor_type_button" onclick="setMotorType()">Set Motor Type</button>
+            <section class="version">
+                <div class="header">
+                    <h2>Firmware Update</h2>
                 </div>
-                <button id="check_updates_button" onclick="fetchFirmwareInfo()">Check for Updates</button>
-                <button id="update_firmware_button" class="cta" style="display: none;" onclick="updateFirmware()">Update Firmware</button>
-            </div>
-        </section>
-        <section class="debug">
-            <div id="github">
+                <div id="firmware_info">
+                    <div id="motor_type"></div>
+                    <div id="current_firmware_version"></div>
+                    <div id="new_firmware_version"></div>
+                </div>
+                <div class="button-group">
+                    <div id="motor_selection" style="display: none;">
+                        <h3>Select installed motor driver</h3>
+                        <select id="manual_motor_type">
+                            <option value="TMC2209">Arduino TMC2209</option>
+                            <option value="DRV8825">Arduino DRV8825</option>
+                            <option value="esp32">ESP32</option>
+                        </select>
+                        <button id="set_motor_type_button" onclick="setMotorType()">Set Motor Type</button>
+                    </div>
+                    <button id="check_updates_button" onclick="fetchFirmwareInfo()">Check for Updates</button>
+                    <button id="update_firmware_button" class="cta" style="display: none;" onclick="updateFirmware()">
+                        <i class="fa-solid fa-file-import"></i>
+                        <span>Update Firmware</span>
+                    </button>
+                </div>
+            </section>
+            <section class="debug main">
+                <div id="github">
                 <span>Help us improve! <a href="https://github.com/tuanchris/dune-weaver/pulls" target="_blank">Submit a Pull Request</a> or <a
                         href="https://github.com/tuanchris/dune-weaver/issues/new"
                         target="_blank">Report a Bug</a>.</span>
-                <a href="https://github.com/tuanchris/dune-weaver/issues" target="_blank">
-                    <img src="https://img.shields.io/github/issues/tuanchris/dune-weaver?style=flat-square"
-                         alt="GitHub Issues">
-                </a>
-            </div>
-            <button id="debug_button" onclick="toggleDebugLog()">🪲</button>
+                    <a href="https://github.com/tuanchris/dune-weaver/issues" target="_blank">
+                        <img src="https://img.shields.io/github/issues/tuanchris/dune-weaver?style=flat-square"
+                             alt="GitHub Issues">
+                    </a>
+                </div>
+                <button id="debug_button" onclick="toggleDebugLog()">
+                    <i class="fa-solid fa-bug"></i>
+                </button>
+            </section>
         </section>
     </main>
 </div>
@@ -337,8 +363,12 @@
             <p id="currently-playing-position"></p>
         </div>
         <div class="play-buttons">
-            <button id="stopCurrent" onclick="stopExecution()" class="cancel">■</button>
-            <button id="pausePlayCurrent" class="cta" onclick="togglePausePlay()">⏸</button>
+            <button id="stopCurrent" onclick="stopExecution()" class="cancel">
+                <i class="fa-solid fa-stop"></i>
+            </button>
+            <button id="pausePlayCurrent" class="cta" onclick="togglePausePlay()">
+                <i class="fa-solid fa-pause"></i>
+            </button>
         </div>
         <div id="progress-container">
             <progress id="play_progress" value="0" max="100"></progress>