fix: UI polish — notification history buttons, CSS test error handling, schedule time picker, empty state labels
Lint & Test / test (push) Successful in 31s
Lint & Test / test (push) Successful in 31s
- Notification history: replace text buttons with icon buttons, use modal-footer for proper positioning - CSS test: reject 0-LED picture sources with clear error message, show WS close reason in UI - Calibration: distribute LEDs by aspect ratio (16:9 default) instead of evenly across edges - Value source schedule: replace native time input with custom HH:MM picker matching automation style - Remove "No ... yet" empty state labels from all CardSection instances
This commit is contained in:
@@ -668,14 +668,20 @@ def create_pixel_mapper(
|
||||
return PixelMapper(calibration, interpolation_mode)
|
||||
|
||||
|
||||
def create_default_calibration(led_count: int) -> CalibrationConfig:
|
||||
def create_default_calibration(
|
||||
led_count: int,
|
||||
aspect_width: int = 16,
|
||||
aspect_height: int = 9,
|
||||
) -> CalibrationConfig:
|
||||
"""Create a default calibration for a rectangular screen.
|
||||
|
||||
Assumes LEDs are evenly distributed around the screen edges in clockwise order
|
||||
starting from bottom-left.
|
||||
Distributes LEDs proportionally to the screen aspect ratio so that
|
||||
horizontal and vertical edges have equal LED density.
|
||||
|
||||
Args:
|
||||
led_count: Total number of LEDs
|
||||
aspect_width: Screen width component of the aspect ratio (default 16)
|
||||
aspect_height: Screen height component of the aspect ratio (default 9)
|
||||
|
||||
Returns:
|
||||
Default calibration configuration
|
||||
@@ -683,15 +689,48 @@ def create_default_calibration(led_count: int) -> CalibrationConfig:
|
||||
if led_count < 4:
|
||||
raise ValueError("Need at least 4 LEDs for default calibration")
|
||||
|
||||
# Distribute LEDs evenly across 4 edges
|
||||
leds_per_edge = led_count // 4
|
||||
remainder = led_count % 4
|
||||
# Distribute LEDs proportionally to aspect ratio (same density per edge)
|
||||
perimeter = 2 * (aspect_width + aspect_height)
|
||||
h_frac = aspect_width / perimeter # fraction for each horizontal edge
|
||||
v_frac = aspect_height / perimeter # fraction for each vertical edge
|
||||
|
||||
# Distribute remainder to longer edges (bottom and top)
|
||||
bottom_count = leds_per_edge + (1 if remainder > 0 else 0)
|
||||
right_count = leds_per_edge
|
||||
top_count = leds_per_edge + (1 if remainder > 1 else 0)
|
||||
left_count = leds_per_edge + (1 if remainder > 2 else 0)
|
||||
# Float counts, then round so total == led_count
|
||||
raw_h = led_count * h_frac
|
||||
raw_v = led_count * v_frac
|
||||
bottom_count = round(raw_h)
|
||||
top_count = round(raw_h)
|
||||
right_count = round(raw_v)
|
||||
left_count = round(raw_v)
|
||||
|
||||
# Fix rounding error
|
||||
diff = led_count - (bottom_count + top_count + right_count + left_count)
|
||||
# Distribute remainder to horizontal edges first (longer edges)
|
||||
if diff > 0:
|
||||
bottom_count += 1
|
||||
diff -= 1
|
||||
if diff > 0:
|
||||
top_count += 1
|
||||
diff -= 1
|
||||
if diff > 0:
|
||||
right_count += 1
|
||||
diff -= 1
|
||||
if diff > 0:
|
||||
left_count += 1
|
||||
diff -= 1
|
||||
# If we over-counted, remove from shorter edges first
|
||||
if diff < 0:
|
||||
left_count += diff # diff is negative
|
||||
diff = 0
|
||||
if left_count < 0:
|
||||
diff = left_count
|
||||
left_count = 0
|
||||
right_count += diff
|
||||
|
||||
# Ensure each edge has at least 1 LED
|
||||
bottom_count = max(1, bottom_count)
|
||||
top_count = max(1, top_count)
|
||||
right_count = max(1, right_count)
|
||||
left_count = max(1, left_count)
|
||||
|
||||
config = CalibrationConfig(
|
||||
layout="clockwise",
|
||||
@@ -703,7 +742,8 @@ def create_default_calibration(led_count: int) -> CalibrationConfig:
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Created default calibration for {led_count} LEDs: "
|
||||
f"Created default calibration for {led_count} LEDs "
|
||||
f"(aspect {aspect_width}:{aspect_height}): "
|
||||
f"bottom={bottom_count}, right={right_count}, "
|
||||
f"top={top_count}, left={left_count}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user