CSS: add led_count field; calibration dialog improvements; color corrections collapsible section

- Add explicit led_count to PictureColorStripSource (0 = auto from calibration)
- Stream pads with black or truncates to match led_count exactly
- Calibration dialog: show led_count input above visual editor in CSS mode
- Calibration dialog: pre-populate led_count with effective count (cal sum) when stored value is 0
- Calibration dialog: sync preview label live as led_count input changes
- CSS editor: group brightness/saturation/gamma into collapsible "Color Corrections" section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-20 16:42:32 +03:00
parent 7de3546b14
commit a3aeafef13
14 changed files with 173 additions and 47 deletions

View File

@@ -142,7 +142,8 @@ class PictureColorStripStream(ColorStripStream):
self._pixel_mapper = PixelMapper(
self._calibration, interpolation_mode=self._interpolation_mode
)
self._led_count: int = self._calibration.get_total_leds()
cal_leds = self._calibration.get_total_leds()
self._led_count: int = source.led_count if source.led_count > 0 else cal_leds
self._gamma_lut: np.ndarray = _build_gamma_lut(self._gamma)
# Thread-safe color cache
@@ -224,10 +225,12 @@ class PictureColorStripStream(ColorStripStream):
if (
source.interpolation_mode != self._interpolation_mode
or source.calibration != self._calibration
or source.led_count != self._led_count
):
self._interpolation_mode = source.interpolation_mode
self._calibration = source.calibration
self._led_count = source.calibration.get_total_leds()
cal_leds = source.calibration.get_total_leds()
self._led_count = source.led_count if source.led_count > 0 else cal_leds
self._pixel_mapper = PixelMapper(
source.calibration, interpolation_mode=source.interpolation_mode
)
@@ -263,6 +266,15 @@ class PictureColorStripStream(ColorStripStream):
led_colors = self._pixel_mapper.map_border_to_leds(border_pixels)
t2 = time.perf_counter()
# Pad or truncate to match the declared led_count
target_count = self._led_count
if target_count > 0 and len(led_colors) != target_count:
if len(led_colors) < target_count:
pad = np.zeros((target_count - len(led_colors), 3), dtype=np.uint8)
led_colors = np.concatenate([led_colors, pad])
else:
led_colors = led_colors[:target_count]
# Temporal smoothing
smoothing = self._smoothing
if (