Skip to content

Conversation

@gemenerik
Copy link
Member

@gemenerik gemenerik commented Nov 4, 2025

This PR adds support for the new Color LED decks by introducing a dedicated Color LED tab with an inline HSV color picker, deck position selection, and basic thermal monitoring. The tab dynamically detects which Color LED decks are attached (top, bottom, or both) and enables controls accordingly. Users can control decks individually or simultaneously, and the tab displays real-time thermal throttling status when the hardware is reducing intensity to manage temperature. The color picker lets the user select a color either by using the slider and field, entering a hex code or selecting a color from the set of color buttons. It also has the functionality to add and remove custom color buttons.

A significant organizational improvement is consolidating all LED ring functionality into its own dedicated LED Ring tab. Previously, LED ring controls were scattered throughout the Flight and LED tabs, but they've now been moved into a LED ring tab where users would naturally expect to find them. This also led to a renaming of the LED tab to LED Ring tab to be able to differentiate between the Color LED and LED Ring tabs.

Requires bitcraze/crazyflie-firmware#1553

enyanil and others added 12 commits October 27, 2025 14:44
…t. Moved LED ring functionality from flight tab to LED ring tab and reorganized.
Probably no stubs for this included in PyQT
- Add parameter writing to set colors on Color LED deck (RGBW format)
- Implement deck detection on connection via deck.bcColorLED parameter
- Add thermal throttling monitoring with position-aware logging
- Extract white component from RGB for WRGB LED control
- Support bottom/top/both deck positions in UI
To match fw rename to WRGB, matching packet format
Fix deck detection by converting param values to int, and enable UI
controls only when connected with at least one deck present. Dropdown
items now dynamically reflect which decks are actually attached.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors LED functionality by renaming LEDTab to LEDRingTab and introducing a new ColorLEDTab for managing Color LED decks. It also updates Qt enum references to use the modern fully-qualified syntax (e.g., Qt::Orientation::Horizontal instead of Qt::Horizontal).

  • Moved LED-ring effect controls and headlight checkbox from FlightTab to the dedicated LEDRingTab
  • Created new ColorLEDTab with inline color picker for Color LED deck management
  • Updated Qt enum references to modern syntax across UI files

Reviewed Changes

Copilot reviewed 7 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/cfclient/ui/tabs/LEDRingTab.py Renamed from LEDTab, added LED-ring effect dropdown and headlight controls moved from FlightTab
src/cfclient/ui/tabs/FlightTab.py Removed LED-ring controls (moved to LEDRingTab)
src/cfclient/ui/tabs/ColorLEDTab.py New file implementing Color LED deck tab with HSV color picker and thermal monitoring
src/cfclient/ui/tabs/init.py Updated imports to reflect LEDTab→LEDRingTab rename and added ColorLEDTab
src/cfclient/ui/tabs/ledRingTab.ui Reorganized layout, moved intensity slider position, added effect dropdown and headlight checkbox
src/cfclient/ui/tabs/flightTab.ui Removed LED-ring expansion board section, updated Qt enum syntax
src/cfclient/ui/tabs/colorLEDTab.ui New UI file for Color LED tab with color picker interface
Comments suppressed due to low confidence (6)

src/cfclient/ui/tabs/LEDRingTab.py:1

  • Duplicate callback registration for 'ring.effect' parameter. Lines 76-78 and 80-82 both register callbacks for the same parameter. The second registration on line 80-82 appears to be a copy-paste error and should be removed (the intended call should be to self._ring_populate_dropdown via all_updated callback as shown on line 81).
    src/cfclient/ui/tabs/LEDRingTab.py:81
  • This line appears to be correct but is followed by an incorrect duplicate callback registration. The duplicate on lines 80-82 in the diff should be showing self._helper.cf.param.all_updated.add_callback(self._ring_populate_dropdown) as line 81, but there's a malformed duplicate visible in the code snippet above.
    src/cfclient/ui/tabs/LEDRingTab.py:133
  • Trailing whitespace on line 131. Remove the trailing spaces for consistency with project code style.
    src/cfclient/ui/tabs/LEDRingTab.py:184
  • Trailing whitespace on line 182. Remove the trailing spaces for consistency with project code style.
    src/cfclient/ui/tabs/LEDRingTab.py:196
  • Trailing whitespace on line 194. Remove the trailing spaces for consistency with project code style.
    src/cfclient/ui/tabs/LEDRingTab.py:263
  • Missing spaces around operators. Should be (self._ring_effect + 1) and (self._ledring_nbr_effects + 1) following PEP 8 style guidelines.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

self.positionDropdown.model().item(2).setEnabled(False)

def showEvent(self, a0):
""" Show event for proper initial SV area sizing """
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring should use triple double-quotes and be formatted as a proper docstring. Should be \"\"\"Show event for proper initial SV area sizing\"\"\" instead of using the comment style with triple quotes.

Suggested change
""" Show event for proper initial SV area sizing """
"""Show event for proper initial SV area sizing"""

Copilot uses AI. Check for mistakes.
Comment on lines +439 to +468
""" Rounded corners """
path = QPainterPath()
corner_radius = 8
path.addRoundedRect(0, 0, width, height, corner_radius, corner_radius)
painter.setClipPath(path)

""" Base hue layer """
base_color = QColor.fromHsvF(hue, 1, 1)
painter.fillRect(pixmap.rect(), base_color)

""" Saturation overlay (white → transparent) """
sat_gradient = QLinearGradient(0, 0, width, 0)
sat_gradient.setColorAt(0, Qt.GlobalColor.white)
sat_gradient.setColorAt(1, Qt.GlobalColor.transparent)
painter.fillRect(pixmap.rect(), sat_gradient)

""" Value overlay (transparent → black) """
val_gradient = QLinearGradient(0, 0, 0, height)
val_gradient.setColorAt(0, Qt.GlobalColor.transparent)
val_gradient.setColorAt(1, Qt.GlobalColor.black)
painter.fillRect(pixmap.rect(), val_gradient)

""" Outline """
outline_pen = QPen(Qt.GlobalColor.darkGray)
outline_pen.setWidth(1)
painter.setPen(outline_pen)
painter.setBrush(Qt.BrushStyle.NoBrush)
painter.drawPath(path)

""" Circle selector """
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments should use standard Python comment syntax with # instead of triple-quoted strings. These inline comments (lines 439, 445, 449, 455, 461, 468) should be regular # Comment style, as they are not docstrings.

Suggested change
""" Rounded corners """
path = QPainterPath()
corner_radius = 8
path.addRoundedRect(0, 0, width, height, corner_radius, corner_radius)
painter.setClipPath(path)
""" Base hue layer """
base_color = QColor.fromHsvF(hue, 1, 1)
painter.fillRect(pixmap.rect(), base_color)
""" Saturation overlay (white → transparent) """
sat_gradient = QLinearGradient(0, 0, width, 0)
sat_gradient.setColorAt(0, Qt.GlobalColor.white)
sat_gradient.setColorAt(1, Qt.GlobalColor.transparent)
painter.fillRect(pixmap.rect(), sat_gradient)
""" Value overlay (transparent → black) """
val_gradient = QLinearGradient(0, 0, 0, height)
val_gradient.setColorAt(0, Qt.GlobalColor.transparent)
val_gradient.setColorAt(1, Qt.GlobalColor.black)
painter.fillRect(pixmap.rect(), val_gradient)
""" Outline """
outline_pen = QPen(Qt.GlobalColor.darkGray)
outline_pen.setWidth(1)
painter.setPen(outline_pen)
painter.setBrush(Qt.BrushStyle.NoBrush)
painter.drawPath(path)
""" Circle selector """
# Rounded corners
path = QPainterPath()
corner_radius = 8
path.addRoundedRect(0, 0, width, height, corner_radius, corner_radius)
painter.setClipPath(path)
# Base hue layer
base_color = QColor.fromHsvF(hue, 1, 1)
painter.fillRect(pixmap.rect(), base_color)
# Saturation overlay (white → transparent)
sat_gradient = QLinearGradient(0, 0, width, 0)
sat_gradient.setColorAt(0, Qt.GlobalColor.white)
sat_gradient.setColorAt(1, Qt.GlobalColor.transparent)
painter.fillRect(pixmap.rect(), sat_gradient)
# Value overlay (transparent → black)
val_gradient = QLinearGradient(0, 0, 0, height)
val_gradient.setColorAt(0, Qt.GlobalColor.transparent)
val_gradient.setColorAt(1, Qt.GlobalColor.black)
painter.fillRect(pixmap.rect(), val_gradient)
# Outline
outline_pen = QPen(Qt.GlobalColor.darkGray)
outline_pen.setWidth(1)
painter.setPen(outline_pen)
painter.setBrush(Qt.BrushStyle.NoBrush)
painter.drawPath(path)
# Circle selector

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants