|
2 | 2 | from serial.tools import list_ports |
3 | 3 | from logging import getLogger, debug, info, error |
4 | 4 | from os.path import expanduser |
| 5 | +from customtkinter import CTkButton, CTkFrame |
5 | 6 | from tkinter import filedialog, Event |
6 | 7 | from webbrowser import open_new |
7 | | -from typing import Optional, Callable |
8 | 8 | from queue import Queue, Empty |
| 9 | +from typing import Optional, Callable, Tuple |
9 | 10 | from ui.base_ui import BaseUI |
10 | 11 | from ui.frame_device_information import FrameDeviceInformation |
11 | 12 | from ui.frame_erase_device import FrameEraseDevice |
|
16 | 17 | from esptool_plugin.esptool_command_runner import CommandRunner |
17 | 18 | from serial_plugin.serial_command_runner import SerialCommandRunner |
18 | 19 | from config.device_configuration import BAUDRATE_OPTIONS, DEFAULT_URL, CONFIGURED_DEVICES |
19 | | -from config.application_configuration import (FONT_PATH, FONT_CATEGORY, FONT_DESCRIPTION, CONSOLE_INFO, |
20 | | - CONSOLE_COMMAND, CONSOLE_ERROR) |
21 | 20 |
|
22 | 21 |
|
23 | 22 | logger = getLogger(__name__) |
@@ -55,74 +54,62 @@ def __init__(self): |
55 | 54 | debug('Adding frames to UI and configuring elements') |
56 | 55 | # Search Device |
57 | 56 | self.search_device = FrameSearchDevice(self) |
58 | | - self.search_device.label.configure(font=FONT_PATH) |
59 | 57 | self.search_device.reload_btn.configure(command=self._search_devices) |
60 | 58 | self.search_device.device_option.configure(command=self._set_device) |
61 | 59 |
|
62 | 60 | # Device Information |
63 | 61 | self.information = FrameDeviceInformation(self) |
64 | | - self.information.label.configure(font=FONT_CATEGORY) |
| 62 | + |
65 | 63 | self.information.chip_info_btn.configure(command=lambda: self._esptool_command("chip_id")) |
66 | 64 | self.information.memory_info_btn.configure(command=lambda: self._esptool_command("flash_id")) |
67 | 65 | self.information.mac_info_btn.configure(command=lambda: self._esptool_command("read_mac")) |
68 | | - self.information.mac_info_btn.pack_forget() |
69 | 66 | self.information.flash_status_btn.configure(command=lambda: self._esptool_command("read_flash_status")) |
| 67 | + |
| 68 | + self.information.mac_info_btn.pack_forget() |
70 | 69 | self.information.flash_status_btn.pack_forget() |
71 | 70 |
|
72 | 71 | # PlugIns |
73 | 72 | self.plugins = FramePlugIns(self) |
74 | | - self.plugins.label.configure(font=FONT_CATEGORY) |
75 | | - # self.plugins.mp_debug_btn.configure(command=self._debug_device) |
| 73 | + |
| 74 | + self.plugins.mp_debug_btn.configure(command=self._handler_toplevel_serial_debug) |
76 | 75 | self.plugins.mp_version_btn.configure(command=self._get_version) |
77 | | - self.plugins.mp_version_btn.pack_forget() |
78 | 76 | self.plugins.mp_structure_btn.configure(command=self._get_structure) |
| 77 | + |
| 78 | + self.plugins.mp_version_btn.pack_forget() |
79 | 79 | self.plugins.mp_structure_btn.pack_forget() |
80 | 80 |
|
81 | 81 | # Erase Device |
82 | 82 | self.erase_device = FrameEraseDevice(self) |
83 | | - self.erase_device.label.configure(font=FONT_CATEGORY) |
84 | 83 | self.erase_device.erase_btn.configure(command=lambda: self._esptool_command("erase_flash")) |
85 | 84 |
|
86 | 85 | # Flash Firmware |
87 | 86 | self.flash_firmware = FrameFirmwareFlash(self) |
88 | | - self.flash_firmware.label.configure(font=FONT_CATEGORY) |
| 87 | + |
89 | 88 | self.flash_firmware.expert_mode.configure(command=self.toggle_expert_mode) |
90 | | - self.flash_firmware.chip_option.set("Select Chip") |
91 | 89 | self.flash_firmware.chip_option.configure(command=self._set_chip) |
92 | | - self.flash_firmware.chip_info.configure(font=FONT_DESCRIPTION) |
93 | 90 | self.flash_firmware.firmware_btn.configure(command=self._handle_firmware_selection) |
94 | | - self.flash_firmware.link_label.configure(font=(*FONT_DESCRIPTION, "underline")) |
95 | 91 | self.flash_firmware.link_label.bind("<Button-1>", self.open_url) |
96 | | - self.flash_firmware.firmware_info.configure(font=FONT_DESCRIPTION) |
97 | 92 | self.flash_firmware.baudrate_option.set(str(self.__selected_baudrate)) |
98 | 93 | self.flash_firmware.baudrate_option.configure(command=self._set_baudrate) |
99 | 94 | self.flash_firmware.baudrate_checkbox.select() |
100 | | - self.flash_firmware.baudrate_info.configure(font=FONT_DESCRIPTION) |
101 | 95 | self.flash_firmware.sector_input.bind("<KeyRelease>", self._handle_sector_input) |
102 | | - self.flash_firmware.sector_info.configure(font=FONT_DESCRIPTION) |
| 96 | + self.flash_firmware.flash_btn.configure(command=self._flash_firmware_command) |
| 97 | + |
103 | 98 | self.flash_firmware.flash_mode_label.grid_remove() |
104 | | - self.flash_firmware.flash_mode_option.set("keep") |
105 | 99 | self.flash_firmware.flash_mode_option.grid_remove() |
106 | 100 | self.flash_firmware.flash_mode_info.grid_remove() |
107 | 101 | self.flash_firmware.flash_frequency_label.grid_remove() |
108 | | - self.flash_firmware.flash_frequency_option.set("keep") |
109 | 102 | self.flash_firmware.flash_frequency_option.grid_remove() |
110 | 103 | self.flash_firmware.flash_frequency_info.grid_remove() |
111 | 104 | self.flash_firmware.flash_size_label.grid_remove() |
112 | | - self.flash_firmware.flash_size_option.set("detect") |
113 | 105 | self.flash_firmware.flash_size_option.grid_remove() |
114 | 106 | self.flash_firmware.flash_size_info.grid_remove() |
115 | 107 | self.flash_firmware.erase_before_label.grid_remove() |
116 | 108 | self.flash_firmware.erase_before_switch.grid_remove() |
117 | 109 | self.flash_firmware.erase_before_info.grid_remove() |
118 | | - self.flash_firmware.flash_btn.configure(command=self._flash_firmware_command) |
119 | 110 |
|
120 | 111 | # Console |
121 | 112 | self.console = FrameConsole(self) |
122 | | - self.console.label.configure(font=FONT_CATEGORY) |
123 | | - self.console.console_text.tag_config("info", foreground=CONSOLE_INFO) |
124 | | - self.console.console_text.tag_config("normal", foreground=CONSOLE_COMMAND) |
125 | | - self.console.console_text.tag_config("error", foreground=CONSOLE_ERROR) |
126 | 113 | self.console.console_text.bind("<Key>", BaseUI._block_text_input) |
127 | 114 |
|
128 | 115 | debug('Searching for USB devices') |
@@ -226,31 +213,35 @@ def _disable_buttons(self) -> None: |
226 | 213 |
|
227 | 214 | :return: None |
228 | 215 | """ |
229 | | - self.information.chip_info_btn.configure(state='disabled') |
230 | | - self.information.memory_info_btn.configure(state='disabled') |
231 | | - self.information.mac_info_btn.configure(state='disabled') |
232 | | - self.information.flash_status_btn.configure(state='disabled') |
233 | | - # self.plugins.mp_debug_btn.configure(state='disabled') |
234 | | - self.plugins.mp_version_btn.configure(state='disabled') |
235 | | - self.plugins.mp_structure_btn.configure(state='disabled') |
236 | | - self.erase_device.erase_btn.configure(state='disabled') |
237 | | - self.flash_firmware.flash_btn.configure(state='disabled') |
| 216 | + frames: Tuple[CTkFrame, ...] = (self.information, self.plugins, self.erase_device, self.flash_firmware) |
| 217 | + |
| 218 | + buttons = [ |
| 219 | + widget |
| 220 | + for frame in frames if isinstance(frame, CTkFrame) |
| 221 | + for widget in frame.winfo_children() |
| 222 | + if isinstance(widget, CTkButton) |
| 223 | + ] |
| 224 | + |
| 225 | + for button in buttons: |
| 226 | + button.configure(state='disabled') |
238 | 227 |
|
239 | 228 | def _enable_buttons(self) -> None: |
240 | 229 | """ |
241 | 230 | Enables specific UI buttons by changing their state to 'normal'. |
242 | 231 |
|
243 | 232 | :return: None |
244 | 233 | """ |
245 | | - self.information.chip_info_btn.configure(state='normal') |
246 | | - self.information.memory_info_btn.configure(state='normal') |
247 | | - self.information.mac_info_btn.configure(state='normal') |
248 | | - self.information.flash_status_btn.configure(state='normal') |
249 | | - # self.plugins.mp_debug_btn.configure(state='normal') |
250 | | - self.plugins.mp_version_btn.configure(state='normal') |
251 | | - self.plugins.mp_structure_btn.configure(state='normal') |
252 | | - self.erase_device.erase_btn.configure(state='normal') |
253 | | - self.flash_firmware.flash_btn.configure(state='normal') |
| 234 | + frames: Tuple[CTkFrame, ...] = (self.information, self.plugins, self.erase_device, self.flash_firmware) |
| 235 | + |
| 236 | + buttons = [ |
| 237 | + widget |
| 238 | + for frame in frames if isinstance(frame, CTkFrame) |
| 239 | + for widget in frame.winfo_children() |
| 240 | + if isinstance(widget, CTkButton) |
| 241 | + ] |
| 242 | + |
| 243 | + for button in buttons: |
| 244 | + button.configure(state='normal') |
254 | 245 |
|
255 | 246 | def _search_devices(self) -> None: |
256 | 247 | """ |
@@ -416,8 +407,19 @@ def _run_serial_task(self, info_text: str, command: Callable[[SerialCommandRunne |
416 | 407 | runner = SerialCommandRunner() |
417 | 408 | command(runner) |
418 | 409 |
|
419 | | - def _debug_device(self) -> None: |
420 | | - pass |
| 410 | + def _handler_toplevel_serial_debug(self) -> None: |
| 411 | + """ |
| 412 | + Handles the creation or focus of a top-level debug window. |
| 413 | +
|
| 414 | + :return: None |
| 415 | + """ |
| 416 | + self._run_serial_task( |
| 417 | + info_text="Start Serial debugging", |
| 418 | + command=lambda runner: runner.get_debug( |
| 419 | + port=self.__device_path, |
| 420 | + callback=lambda output: self._handle_serial_output(output) |
| 421 | + ) |
| 422 | + ) |
421 | 423 |
|
422 | 424 | def _get_version(self) -> None: |
423 | 425 | """ |
|
0 commit comments