From 05fb350d4f7af1d0b21b02aceca80bcd69fb889d Mon Sep 17 00:00:00 2001 From: Skybladev2 Date: Mon, 13 Apr 2026 18:06:26 +0300 Subject: [PATCH 1/3] fix calibration points overflow text styling --- gui/builtinStatsViews/resourcesViewFull.py | 5 +++- gui/utils/resourceWarnings.py | 8 ++++++ .../test_gui/test_resourceWarnings.py | 28 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 gui/utils/resourceWarnings.py create mode 100644 tests/test_modules/test_gui/test_resourceWarnings.py diff --git a/gui/builtinStatsViews/resourcesViewFull.py b/gui/builtinStatsViews/resourcesViewFull.py index 77d0b57553..c49af4fa56 100644 --- a/gui/builtinStatsViews/resourcesViewFull.py +++ b/gui/builtinStatsViews/resourcesViewFull.py @@ -25,6 +25,7 @@ import gui.mainFrame from gui.chrome_tabs import EVT_NOTEBOOK_PAGE_CHANGED from gui.utils import fonts +from gui.utils.resourceWarnings import is_calibration_over_limit from eos.const import FittingHardpoint @@ -322,7 +323,7 @@ def refreshPanel(self, fit): colorF = colorWarn else: colorF = colorNormal - if usedCalibrationPoints > totalCalibrationPoints: + if is_calibration_over_limit(usedCalibrationPoints, totalCalibrationPoints): colorC = colorWarn else: colorC = colorNormal @@ -337,6 +338,8 @@ def refreshPanel(self, fit): labelTFT.SetForegroundColour(colorF) labelUCP.SetForegroundColour(colorC) labelTCP.SetForegroundColour(colorC) + labelUCP.Refresh() + labelTCP.Refresh() if fit is not None: resMax = ( diff --git a/gui/utils/resourceWarnings.py b/gui/utils/resourceWarnings.py new file mode 100644 index 0000000000..13fa564cc0 --- /dev/null +++ b/gui/utils/resourceWarnings.py @@ -0,0 +1,8 @@ +def is_calibration_over_limit(used_points, total_points): + """ + Decide when calibration values should be shown as warning (red). + Warn only when used points are meaningfully above total points. + """ + used = 0.0 if used_points is None else float(used_points) + total = 0.0 if total_points is None else float(total_points) + return (used - total) > 1e-6 diff --git a/tests/test_modules/test_gui/test_resourceWarnings.py b/tests/test_modules/test_gui/test_resourceWarnings.py new file mode 100644 index 0000000000..e00971466c --- /dev/null +++ b/tests/test_modules/test_gui/test_resourceWarnings.py @@ -0,0 +1,28 @@ +import os +import sys +script_dir = os.path.dirname(os.path.abspath(__file__)) +sys.path.append(os.path.realpath(os.path.join(script_dir, '..', '..', '..'))) + +from gui.utils.resourceWarnings import is_calibration_over_limit + + +def test_calibration_equal_limit_is_not_warning(): + assert is_calibration_over_limit(400, 400) is False + + +def test_calibration_over_limit_is_warning(): + assert is_calibration_over_limit(401, 400) is True + + +def test_calibration_float_precision_not_warning_at_equal_display_value(): + # Values below total should not trigger warning. + assert is_calibration_over_limit(399.9999999, 400) is False + + +def test_calibration_float_precision_warning_when_meaningfully_above_limit(): + assert is_calibration_over_limit(400.01, 400) is True + + +def test_calibration_none_values_are_safe(): + assert is_calibration_over_limit(None, 400) is False + assert is_calibration_over_limit(450, None) is True From 69340b805babfcdcd14d73c3317ff94763153618 Mon Sep 17 00:00:00 2001 From: Skybladev2 Date: Tue, 14 Apr 2026 09:11:04 +0300 Subject: [PATCH 2/3] revert unnneeded changes --- gui/builtinStatsViews/resourcesViewFull.py | 3 +- gui/utils/resourceWarnings.py | 8 ------ .../test_gui/test_resourceWarnings.py | 28 ------------------- 3 files changed, 1 insertion(+), 38 deletions(-) delete mode 100644 gui/utils/resourceWarnings.py delete mode 100644 tests/test_modules/test_gui/test_resourceWarnings.py diff --git a/gui/builtinStatsViews/resourcesViewFull.py b/gui/builtinStatsViews/resourcesViewFull.py index c49af4fa56..234412d716 100644 --- a/gui/builtinStatsViews/resourcesViewFull.py +++ b/gui/builtinStatsViews/resourcesViewFull.py @@ -25,7 +25,6 @@ import gui.mainFrame from gui.chrome_tabs import EVT_NOTEBOOK_PAGE_CHANGED from gui.utils import fonts -from gui.utils.resourceWarnings import is_calibration_over_limit from eos.const import FittingHardpoint @@ -323,7 +322,7 @@ def refreshPanel(self, fit): colorF = colorWarn else: colorF = colorNormal - if is_calibration_over_limit(usedCalibrationPoints, totalCalibrationPoints): + if usedCalibrationPoints > totalCalibrationPoints: colorC = colorWarn else: colorC = colorNormal diff --git a/gui/utils/resourceWarnings.py b/gui/utils/resourceWarnings.py deleted file mode 100644 index 13fa564cc0..0000000000 --- a/gui/utils/resourceWarnings.py +++ /dev/null @@ -1,8 +0,0 @@ -def is_calibration_over_limit(used_points, total_points): - """ - Decide when calibration values should be shown as warning (red). - Warn only when used points are meaningfully above total points. - """ - used = 0.0 if used_points is None else float(used_points) - total = 0.0 if total_points is None else float(total_points) - return (used - total) > 1e-6 diff --git a/tests/test_modules/test_gui/test_resourceWarnings.py b/tests/test_modules/test_gui/test_resourceWarnings.py deleted file mode 100644 index e00971466c..0000000000 --- a/tests/test_modules/test_gui/test_resourceWarnings.py +++ /dev/null @@ -1,28 +0,0 @@ -import os -import sys -script_dir = os.path.dirname(os.path.abspath(__file__)) -sys.path.append(os.path.realpath(os.path.join(script_dir, '..', '..', '..'))) - -from gui.utils.resourceWarnings import is_calibration_over_limit - - -def test_calibration_equal_limit_is_not_warning(): - assert is_calibration_over_limit(400, 400) is False - - -def test_calibration_over_limit_is_warning(): - assert is_calibration_over_limit(401, 400) is True - - -def test_calibration_float_precision_not_warning_at_equal_display_value(): - # Values below total should not trigger warning. - assert is_calibration_over_limit(399.9999999, 400) is False - - -def test_calibration_float_precision_warning_when_meaningfully_above_limit(): - assert is_calibration_over_limit(400.01, 400) is True - - -def test_calibration_none_values_are_safe(): - assert is_calibration_over_limit(None, 400) is False - assert is_calibration_over_limit(450, None) is True From 22f2a34880724c845736e86e44550e1d816bb0ca Mon Sep 17 00:00:00 2001 From: Skybladev2 Date: Tue, 14 Apr 2026 11:14:52 +0300 Subject: [PATCH 3/3] Guard module sorting against transient invalid slots. Avoid tab-switch crashes by filtering null module entries and sorting unknown slot modules last during fitting view refresh. Made-with: Cursor --- gui/builtinViews/fittingView.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/gui/builtinViews/fittingView.py b/gui/builtinViews/fittingView.py index 8df91591c7..5f261539d7 100644 --- a/gui/builtinViews/fittingView.py +++ b/gui/builtinViews/fittingView.py @@ -557,8 +557,19 @@ def generateMods(self): ] if fit is not None: - self.mods = fit.modules[:] - self.mods.sort(key=lambda _mod: (slotOrder.index(_mod.slot), _mod.position)) + self.mods = [mod for mod in fit.modules if mod is not None] + + def _get_sort_key(mod): + slot = getattr(mod, "slot", None) + try: + slot_index = slotOrder.index(slot) + except ValueError: + # During rapid fit switches we may briefly see transient modules + # with unresolved slot references; keep UI stable by sorting them last. + slot_index = len(slotOrder) + return slot_index, getattr(mod, "position", 0) + + self.mods.sort(key=_get_sort_key) # Blanks is a list of indexes that mark non-module positions (such # as Racks and tactical Modes. This allows us to skip over common