Skip to content

Commit 33de635

Browse files
committed
feat(stage progress): present non-optional stage progress in simple mode
1 parent 62c1f5a commit 33de635

File tree

3 files changed

+50
-17
lines changed

3 files changed

+50
-17
lines changed

ardupilot_methodic_configurator/frontend_tkinter_parameter_editor.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def __init__(self, current_file: str, flight_controller: FlightController, local
150150
self.tempcal_imu_progress_window: ProgressWindow
151151
self.file_upload_progress_window: ProgressWindow
152152
self.last_time_asked_to_save: float = 0
153-
self.gui_complexity = ProgramSettings.get_setting("gui_complexity")
153+
self.gui_complexity = str(ProgramSettings.get_setting("gui_complexity"))
154154

155155
self.root.title(
156156
_("Amilcar Lucas's - ArduPilot methodic configurator ") + __version__ + _(" - Parameter file editor and uploader")
@@ -177,10 +177,9 @@ def __init__(self, current_file: str, flight_controller: FlightController, local
177177
last_step_nr = int(last_step_filename[:2]) + 1 if len(last_step_filename) >= 2 else 1
178178

179179
self.stage_progress_bar = StageProgressBar(
180-
self.main_frame, self.local_filesystem.configuration_phases, last_step_nr
180+
self.main_frame, self.local_filesystem.configuration_phases, last_step_nr, self.gui_complexity
181181
)
182-
if self.gui_complexity != "simple":
183-
self.stage_progress_bar.pack(side=tk.TOP, fill="x", expand=False, pady=(2, 2), padx=(4, 4))
182+
self.stage_progress_bar.pack(side=tk.TOP, fill="x", expand=False, pady=(2, 2), padx=(4, 4))
184183

185184
# Create a DocumentationFrame object for the Documentation Content
186185
self.documentation_frame = DocumentationFrame(self.main_frame, self.local_filesystem, self.current_file)
@@ -558,7 +557,9 @@ def __should_copy_fc_values_to_file(self, selected_file: str) -> None: # pylint
558557
def __should_jump_to_file(self, selected_file: str) -> str:
559558
jump_possible = self.local_filesystem.jump_possible(selected_file)
560559
for dest_file, msg in jump_possible.items():
561-
if messagebox.askyesno(_("Skip some steps?"), _(msg) if msg else _("Skip to {dest_file}?").format(**locals())):
560+
if self.gui_complexity == "simple" or messagebox.askyesno(
561+
_("Skip some steps?"), _(msg) if msg else _("Skip to {dest_file}?").format(**locals())
562+
):
562563
self.file_selection_combobox.set(dest_file)
563564
return dest_file
564565
return selected_file
@@ -821,6 +822,23 @@ def on_skip_click(self, _event: Union[None, tk.Event] = None, force_focus_out_ev
821822
return
822823
try:
823824
next_file_index = files.index(self.current_file) + 1
825+
# Skip files with mandatory_level == 0
826+
while next_file_index < len(files):
827+
next_file = files[next_file_index]
828+
mandatory_text, _mandatory_url = self.local_filesystem.get_documentation_text_and_url(next_file, "mandatory")
829+
# Extract percentage from mandatory_text like "80% mandatory (20% optional)"
830+
percentage = 0
831+
if mandatory_text:
832+
try:
833+
percentage = int(mandatory_text.split("%")[0])
834+
except (ValueError, IndexError):
835+
percentage = 0
836+
837+
# If the file has mandatory_level > 0, use it
838+
if percentage > 0:
839+
break
840+
841+
next_file_index += 1
824842
if next_file_index >= len(files):
825843
self.write_summary_files()
826844
# Close the application and the connection

ardupilot_methodic_configurator/frontend_tkinter_stage_progress.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@
5353
class StageProgressBar(ttk.LabelFrame): # pylint: disable=too-many-ancestors
5454
"""Stage-segmented Configuration sequence progress UI."""
5555

56-
def __init__(self, master: Union[tk.Widget, tk.Tk], phases: dict[str, dict], total_steps: int, **kwargs) -> None:
56+
def __init__(
57+
self, master: Union[tk.Widget, tk.Tk], phases: dict[str, dict], total_steps: int, gui_complexity: str, **kwargs
58+
) -> None:
5759
super().__init__(master, text=_("Configuration sequence progress"), **kwargs)
5860
self.phases = phases
5961
self.total_files = total_steps
@@ -63,7 +65,7 @@ def __init__(self, master: Union[tk.Widget, tk.Tk], phases: dict[str, dict], tot
6365
self.grid_columnconfigure(0, weight=1)
6466
self.grid_rowconfigure(0, weight=1)
6567

66-
self.create_phase_frames()
68+
self.create_phase_frames(gui_complexity)
6769
self.bind("<Configure>", self._on_resize)
6870
show_tooltip(
6971
self,
@@ -74,27 +76,40 @@ def __init__(self, master: Union[tk.Widget, tk.Tk], phases: dict[str, dict], tot
7476
position_below=False,
7577
)
7678

77-
def create_phase_frames(self) -> None:
79+
def create_phase_frames(self, gui_complexity: str) -> None:
7880
"""Create frames for each phase with progress bars and labels."""
7981
# Get phases with start positions
8082
active_phases = {k: v for k, v in self.phases.items() if "start" in v}
8183

8284
# Sort phases by start position
8385
sorted_phases = dict(sorted(active_phases.items(), key=lambda x: x[1]["start"]))
8486

85-
num_phases = len(sorted_phases)
87+
# Add the end information to each phase using the start of the next phase
88+
phase_names = list(sorted_phases.keys())
89+
for i, phase_name in enumerate(phase_names):
90+
if i < len(phase_names) - 1:
91+
next_phase_name = phase_names[i + 1]
92+
sorted_phases[phase_name]["end"] = sorted_phases[next_phase_name]["start"]
93+
else:
94+
sorted_phases[phase_name]["end"] = self.total_files
95+
sorted_phases[phase_name]["weight"] = max(2, sorted_phases[phase_name]["end"] - sorted_phases[phase_name]["start"])
96+
97+
# Calculate non-optional phases
98+
non_optional_sorted_phases = {name: data for name, data in sorted_phases.items() if not data.get("optional", False)}
99+
100+
phases_to_display = non_optional_sorted_phases if gui_complexity == "simple" else sorted_phases
86101

87102
# Create container frame that will expand
88103
container = ttk.Frame(self)
89104
container.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
90105

91106
# Configure container columns to expand equally
92-
for i in range(num_phases):
93-
container.grid_columnconfigure(i, weight=1, uniform="phase")
94-
95-
for i, (phase_name, phase_data) in enumerate(sorted_phases.items()):
107+
for i, (phase_name, phase_data) in enumerate(phases_to_display.items()):
108+
container.grid_columnconfigure(
109+
i, weight=phase_data["weight"] if gui_complexity == "simple" else 1, uniform="phase"
110+
)
96111
start = phase_data["start"]
97-
end = list(sorted_phases.values())[i + 1]["start"] if i < num_phases - 1 else self.total_files
112+
end = phase_data["end"]
98113
self.phase_frames[phase_name] = self._create_phase_frame(container, i, phase_name, phase_data, (start, end))
99114

100115
def _create_phase_frame( # pylint: disable=too-many-arguments, too-many-positional-arguments
@@ -229,7 +244,7 @@ def main() -> None:
229244
config_steps = ConfigurationSteps("", "ArduCopter")
230245
config_steps.re_init("", "ArduCopter")
231246

232-
progress = StageProgressBar(root, config_steps.configuration_phases, 54)
247+
progress = StageProgressBar(root, config_steps.configuration_phases, 54, "normal")
233248
progress.pack(padx=10, pady=10, fill="both", expand=True)
234249

235250
# Demo update function

tests/test_frontend_tkinter_stage_progress.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def setUp(self) -> None:
3030
"Milestone": {"description": "A milestone without start"},
3131
}
3232
self.total_steps = 30
33-
self.progress_bar = StageProgressBar(self.root, self.test_phases, self.total_steps)
33+
self.progress_bar = StageProgressBar(self.root, self.test_phases, self.total_steps, gui_complexity="normal")
3434

3535
def tearDown(self) -> None:
3636
"""Clean up after tests."""
@@ -137,7 +137,7 @@ def test_label_text_splitting(self) -> None:
137137
"Very Long Phase Name Example": {"start": 5}, # Long with spaces
138138
}
139139

140-
test_progress = StageProgressBar(self.root, test_texts, 10)
140+
test_progress = StageProgressBar(self.root, test_texts, 10, "normal")
141141

142142
for phase_name, frame in test_progress.phase_frames.items():
143143
label = None

0 commit comments

Comments
 (0)