Add drag-and-drop for presets and colors, max_colors validation, and 2D grid layout
- Add drag-and-drop to reorder presets in tabs (2D grid layout) - Add drag-and-drop to reorder colors within presets - Add max_colors field to pattern definitions - Hide color section when max_colors is 0 - Validate color count against pattern max_colors limit - Store presets in 2D grid format (3 columns) - Remove left panel from tab content, show only presets - Update color palette to show swatches instead of hex codes - Improve preset editor UI with visual color swatches
This commit is contained in:
@@ -163,88 +163,17 @@ async def tab_content_fragment(request, session, id):
|
||||
return send_file('templates/index.html')
|
||||
|
||||
tab_name = tab.get('name', 'Tab ' + str(id))
|
||||
device_ids = ', '.join(tab.get('names', []))
|
||||
|
||||
html = (
|
||||
'<div class="left-panel">'
|
||||
'<div class="left-panel-header">'
|
||||
'<div class="ids-display">'
|
||||
'<label>IDs: </label>'
|
||||
'<span id="current-ids">' + device_ids + '</span>'
|
||||
'</div>'
|
||||
'<button id="toggle-left-panel" class="btn btn-small left-panel-toggle" title="Collapse/expand controls">◀</button>'
|
||||
'</div>'
|
||||
'<div class="left-panel-body">'
|
||||
'<div class="color-palette-section">'
|
||||
'<h3>Color Palette</h3>'
|
||||
'<div id="color-palette" class="color-palette" data-tab-id="' + str(id) + '">'
|
||||
'<!-- Colors will be loaded here -->'
|
||||
'</div>'
|
||||
'<div class="palette-actions">'
|
||||
'<input type="color" id="tab-color-input" value="#ffffff">'
|
||||
'<button class="btn btn-small" id="tab-color-add-btn">Add Color</button>'
|
||||
'<button class="btn btn-small" id="tab-color-add-from-palette-btn">Add from Palette</button>'
|
||||
'</div>'
|
||||
'</div>'
|
||||
'<div class="controls-section">'
|
||||
'<div class="control-group">'
|
||||
'<label for="brightness-slider">Brightness:</label>'
|
||||
'<input type="range" id="brightness-slider" min="0" max="255" value="127" class="slider">'
|
||||
'<span id="brightness-value" class="slider-value">127</span>'
|
||||
'</div>'
|
||||
'<div class="control-group">'
|
||||
'<label for="delay-slider">Delay:</label>'
|
||||
'<input type="range" id="delay-slider" min="0" max="1000" value="0" class="slider">'
|
||||
'<span id="delay-value" class="slider-value">100 ms</span>'
|
||||
'</div>'
|
||||
'</div>'
|
||||
'<div class="n-params-section">'
|
||||
'<h3>N Parameters</h3>'
|
||||
'<div class="n-params-grid">'
|
||||
'<div class="n-param-group">'
|
||||
'<label for="n1-input" id="n1-label">n1:</label>'
|
||||
'<input type="number" id="n1-input" min="0" max="255" value="10" class="n-input">'
|
||||
'</div>'
|
||||
'<div class="n-param-group">'
|
||||
'<label for="n2-input" id="n2-label">n2:</label>'
|
||||
'<input type="number" id="n2-input" min="0" max="255" value="10" class="n-input">'
|
||||
'</div>'
|
||||
'<div class="n-param-group">'
|
||||
'<label for="n3-input" id="n3-label">n3:</label>'
|
||||
'<input type="number" id="n3-input" min="0" max="255" value="10" class="n-input">'
|
||||
'</div>'
|
||||
'<div class="n-param-group">'
|
||||
'<label for="n4-input" id="n4-label">n4:</label>'
|
||||
'<input type="number" id="n4-input" min="0" max="255" value="10" class="n-input">'
|
||||
'</div>'
|
||||
'<div class="n-param-group">'
|
||||
'<label for="n5-input" id="n5-label">n5:</label>'
|
||||
'<input type="number" id="n5-input" min="0" max="255" value="10" class="n-input">'
|
||||
'</div>'
|
||||
'<div class="n-param-group">'
|
||||
'<label for="n6-input" id="n6-label">n6:</label>'
|
||||
'<input type="number" id="n6-input" min="0" max="255" value="10" class="n-input">'
|
||||
'</div>'
|
||||
'<div class="n-param-group">'
|
||||
'<label for="n7-input" id="n7-label">n7:</label>'
|
||||
'<input type="number" id="n7-input" min="0" max="255" value="10" class="n-input">'
|
||||
'</div>'
|
||||
'<div class="n-param-group">'
|
||||
'<label for="n8-input" id="n8-label">n8:</label>'
|
||||
'<input type="number" id="n8-input" min="0" max="255" value="10" class="n-input">'
|
||||
'</div>'
|
||||
'</div>'
|
||||
'</div>'
|
||||
'</div>'
|
||||
'</div>'
|
||||
'<div class="right-panel">'
|
||||
'<div class="presets-section">'
|
||||
'<div class="presets-section" data-tab-id="' + str(id) + '">'
|
||||
'<h3>Presets</h3>'
|
||||
'<div class="profiles-actions" style="margin-bottom: 1rem;">'
|
||||
'<button class="btn btn-primary" id="preset-add-btn-tab">Add Preset</button>'
|
||||
'</div>'
|
||||
'<div id="presets-list-tab" class="presets-list">'
|
||||
'<!-- Presets will be loaded here -->'
|
||||
'</div>'
|
||||
'</div>'
|
||||
'</div>'
|
||||
)
|
||||
return html, 200, {'Content-Type': 'text/html'}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user