Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 55 additions & 6 deletions src/cfclient/ui/dialogs/bootloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
import zipfile

from PyQt6 import QtWidgets, uic
from PyQt6.QtCore import pyqtSlot, pyqtSignal, QThread
from PyQt6.QtCore import pyqtSlot, pyqtSignal, QThread, Qt
from PyQt6.QtGui import QPixmap

import cfclient
import cflib.crazyflie
Expand Down Expand Up @@ -132,10 +133,33 @@ def __init__(self, helper, *args):

self._platform_filter_checkboxes = []

self._set_image(self.image_1, "src/cfclient/ui/icons/bolt.webp")
self._set_image(self.image_2, "src/cfclient/ui/icons/cf21.webp")
self._set_image(self.image_3, "src/cfclient/ui/icons/bl.webp")
self._set_image(self.image_4, "src/cfclient/ui/icons/flapper.webp")
self._set_image(self.image_5, "src/cfclient/ui/icons/tag.webp")

def _ui_connection_fail(self, message):
self._cold_boot_error_message = message
self.setUiState(self.UIState.DISCONNECTED)

def _set_image(self, image_label, image_path):
IMAGE_WIDTH = 100
IMAGE_HEIGHT = 100

pixmap = QPixmap(image_path)

if pixmap.isNull():
logger.warning(f"Failed to load image: {image_path}")
image_label.setText("Missing image")
else:
scaled_pixmap = pixmap.scaled(
IMAGE_WIDTH, IMAGE_HEIGHT,
Qt.AspectRatioMode.KeepAspectRatio,
Qt.TransformationMode.SmoothTransformation
)
image_label.setPixmap(scaled_pixmap)

def setUiState(self, state):
self._state = state

Expand Down Expand Up @@ -163,7 +187,10 @@ def setUiState(self, state):
elif (state == self.UIState.COLD_CONNECTED):
self._cold_boot_error_message = None
self.resetButton.setEnabled(True)
self.programButton.setEnabled(True)
if any(button.isChecked() for button in self._platform_filter_checkboxes):
self.programButton.setEnabled(True)
else:
self.programButton.setToolTip("Select a platform before programming.")
self.setStatusLabel("Connected to bootloader")
self.coldBootButton.setEnabled(False)
self.imagePathBrowseButton.setEnabled(True)
Expand All @@ -189,7 +216,10 @@ def setUiState(self, state):
self.setStatusLabel("Connected using USB")
self.setSourceSelectionUiEnabled(False)
else:
self.programButton.setEnabled(True)
if any(button.isChecked() for button in self._platform_filter_checkboxes):
self.programButton.setEnabled(True)
else:
self.programButton.setToolTip("Select a platform before programming.")
self.setStatusLabel("Connected in firmware mode")
self.setSourceSelectionUiEnabled(True)
elif (state == self.UIState.FW_SCANNING):
Expand All @@ -216,6 +246,7 @@ def setUiState(self, state):
self.coldBootButton.setEnabled(False)
self.setSourceSelectionUiEnabled(True)
self._helper.connectivity_manager.set_enable(False)
self._update_program_button_state()

def setSourceSelectionUiEnabled(self, enabled):
self.imagePathBrowseButton.setEnabled(enabled)
Expand Down Expand Up @@ -265,19 +296,37 @@ def _populate_firmware_dropdown(self, releases):
platforms.add(platform)

for platform in sorted(platforms, reverse=True):
RADIO_BUTTON_WIDTH = 100

radio_button = QtWidgets.QRadioButton(platform)

# Use cf2 as default platform
if platform == 'cf2':
radio_button.setChecked(True)
radio_button.setFixedWidth(RADIO_BUTTON_WIDTH)

radio_button.toggled.connect(self._update_firmware_dropdown)
radio_button.toggled.connect(self._update_program_button_state)

self._platform_filter_checkboxes.append(radio_button)
self.filterLayout.insertWidget(0, radio_button)

self.firmwareDropdown.setSizeAdjustPolicy(QtWidgets.QComboBox.SizeAdjustPolicy.AdjustToContents)
self._update_firmware_dropdown(True)

def _update_program_button_state(self):
any_checked = any(button.isChecked() for button in self._platform_filter_checkboxes)
is_connected = self._state in [
self.UIState.COLD_CONNECTED,
self.UIState.FW_CONNECTED
]

self.programButton.setEnabled(any_checked and is_connected)

if not is_connected:
self.programButton.setToolTip("Connect your device before programming.")
elif not any_checked:
self.programButton.setToolTip("Select a platform before programming.")
else:
self.programButton.setToolTip("")

def _update_firmware_dropdown(self, active: bool):
if active:
platform = None
Expand Down
134 changes: 110 additions & 24 deletions src/cfclient/ui/dialogs/bootloader.ui
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
<enum>Qt::WindowModality::ApplicationModal</enum>
</property>
<property name="enabled">
<bool>true</bool>
Expand Down Expand Up @@ -94,7 +94,7 @@
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand Down Expand Up @@ -133,7 +133,7 @@
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand Down Expand Up @@ -177,36 +177,122 @@
<string>From release</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<item row="1" column="0">
<widget class="QGroupBox" name="platform_filter_gb">
<property name="title">
<string>Platform filter</string>
<string>Select a platform:</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<layout class="QHBoxLayout" name="filterLayout">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="2">
<widget class="QLabel" name="image_3">
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string>Image 3</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="image_2">
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string>Image 2</string>
</property>
</widget>
</item>
<item row="0" column="5">
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="3">
<widget class="QLabel" name="image_4">
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string>Image 4</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="image_1">
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string>Image 1</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="image_5">
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string>Image 5</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="filterLayout">
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand All @@ -216,7 +302,7 @@
</property>
</spacer>
</item>
<item row="1" column="0">
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
Expand All @@ -231,7 +317,7 @@
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand Down Expand Up @@ -286,7 +372,7 @@
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand All @@ -305,7 +391,7 @@
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand All @@ -320,7 +406,7 @@
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand Down
Binary file added src/cfclient/ui/icons/bl.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/cfclient/ui/icons/bolt.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/cfclient/ui/icons/cf21.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/cfclient/ui/icons/flapper.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/cfclient/ui/icons/tag.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.