From 856917d529ad6ea5301a1af3271265787933fc2f Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Mon, 17 Jun 2024 18:21:48 -0400 Subject: [PATCH 01/12] Added test setup for instruments.button --- .../instruments/button/button_test_button.py | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/instruments/button/button_test_button.py diff --git a/tests/instruments/button/button_test_button.py b/tests/instruments/button/button_test_button.py new file mode 100644 index 00000000..73479674 --- /dev/null +++ b/tests/instruments/button/button_test_button.py @@ -0,0 +1,37 @@ +import pytest +from unittest import mock +from PyQt5.QtWidgets import QApplication, QWidget +from PyQt5.QtCore import Qt, qRound +from PyQt5.QtGui import QColor, QBrush, QPen, QFont, QPaintEvent, QFontMetrics +from pyefis.instruments import button +import pyefis.hmi as hmi +from tests.utils import track_calls + + +@pytest.fixture +def app(qtbot): + test_app = QApplication.instance() + if test_app is None: + test_app = QApplication([]) + return test_app + +@pytest.fixture +def mock_parent_widget(): + real_parent = QWidget() # Create a real QWidget instance + real_parent.screenName = "TEST" + real_parent.parent = mock.Mock() + real_parent.parent.nodeID = 1 + real_parent.parent.config_path = "tests/data/listbox/" + return real_parent + +def test_simple_button(fix,mock_parent_widget,qtbot): + widget = button.Button(mock_parent_widget, config_file="tests/data/buttons/simple.yaml") + qtbot.addWidget(mock_parent_widget) + qtbot.addWidget(widget) + mock_parent_widget.resize(200,200) + mock_parent_widget.show() + widget.resize(100,80) + widget.show() + qtbot.waitExposed(widget) + qtbot.wait(2000) + From bff2fdabfc199b523a4237e6d9bec565cbf60520 Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Mon, 17 Jun 2024 20:36:22 -0400 Subject: [PATCH 02/12] Added tests for instruments.button --- conftest.py | 101 ++++++++++++++++++ tests/data/buttons/repeat.yaml | 13 +++ tests/data/buttons/simple.yaml | 29 +++++ tests/data/buttons/toggle.yaml | 37 +++++++ tests/instruments/button/__init__.py | 0 .../instruments/button/button_test_button.py | 37 ------- tests/instruments/button/test_button.py | 94 ++++++++++++++++ 7 files changed, 274 insertions(+), 37 deletions(-) create mode 100644 tests/data/buttons/repeat.yaml create mode 100644 tests/data/buttons/simple.yaml create mode 100644 tests/data/buttons/toggle.yaml create mode 100644 tests/instruments/button/__init__.py delete mode 100644 tests/instruments/button/button_test_button.py create mode 100644 tests/instruments/button/test_button.py diff --git a/conftest.py b/conftest.py index 78bef5c7..aef751d5 100644 --- a/conftest.py +++ b/conftest.py @@ -264,5 +264,106 @@ def create_numbers(key, value, old=False, bad=False, fail=False, annunciate=Fals fix.db.get_item("ROT").bad = False fix.db.get_item("ROT").fail = False + fix.db.define_item( + "HIDEBUTTON", + "Hide or show buttons", + "bool", + None, + None, + '', + 50000, + '' + ) + fix.db.set_value("HIDEBUTTON", False) + fix.db.get_item("HIDEBUTTON").bad = False + fix.db.get_item("HIDEBUTTON").fail = False + + for i in range(5): + fix.db.define_item( + f"TSBTN1{i}", + f"Touch Button {i}", + "bool", + None, + None, + '', + 50000, + '' + ) + fix.db.set_value(f"TSBTN1{i}", False) + fix.db.get_item(f"TSBTN1{i}").bad = False + fix.db.get_item(f"TSBTN1{i}").fail = False + + + fix.db.define_item( + "MAVREQADJ", + "", + "bool", + None, + None, + '', + 50000, + '' + ) + fix.db.set_value("MAVREQADJ", False) + fix.db.get_item("MAVREQADJ").bad = False + fix.db.get_item("MAVREQADJ").fail = False + + + fix.db.define_item( + "MAVADJ", + "", + "bool", + None, + None, + '', + 50000, + '' + ) + fix.db.set_value("MAVADJ", False) + fix.db.get_item("MAVADJ").bad = False + fix.db.get_item("MAVADJ").fail = False + + + fix.db.define_item( + "MAVSTATE", + "", + "str", + None, + None, + '', + 50000, + '' + ) + fix.db.set_value("MAVSTATE", "INIT") + fix.db.get_item("MAVSTATE").bad = False + fix.db.get_item("MAVSTATE").fail = False + + fix.db.define_item( + "MAVMODE", + "", + "str", + None, + None, + '', + 50000, + '' + ) + fix.db.set_value("MAVMODE", "TRIM") + fix.db.get_item("MAVMODE").bad = False + fix.db.get_item("MAVMODE").fail = False + + fix.db.define_item( + "BARO", + "", + "float", + 0, + 35.0, + 'inHg', + 50000, + '' + ) + fix.db.set_value("BARO", 29.92) + fix.db.get_item("BARO").bad = False + fix.db.get_item("BARO").fail = False return fix diff --git a/tests/data/buttons/repeat.yaml b/tests/data/buttons/repeat.yaml new file mode 100644 index 00000000..7a5c050e --- /dev/null +++ b/tests/data/buttons/repeat.yaml @@ -0,0 +1,13 @@ +type: repeat +text: "+" +dbkey: TSBTN{id}3 +transparent: true +# If repeats too fast can cause VARO set loops +# This is more of an issue when the variable, BARO in this case, is ued +# by the compute plugin in Fix Gateway +repeat_interval: 200 +repeat_delay: 500 +conditions: + - when: "CLICKED eq true" + actions: + - change value: "BARO, 0.01" diff --git a/tests/data/buttons/simple.yaml b/tests/data/buttons/simple.yaml new file mode 100644 index 00000000..f3d7ffc4 --- /dev/null +++ b/tests/data/buttons/simple.yaml @@ -0,0 +1,29 @@ +type: simple +text: "Units" +dbkey: TSBTN{id}0 +condition_keys: +- HIDEBUTTON +conditions: + - when: "HIDEBUTTON" + actions: + #- button: disable + - set text: "Show\nMenu" + #- set bg color: "#00000000" + #- set fg color: "#00000000" + continue: true + - when: "not HIDEBUTTON" + actions: + #- button: enable + - set text: "Units" + #- set bg color: lightgray + #- set fg color: black + continue: true + - when: "CLICKED eq true and HIDEBUTTON" + actions: + - set text: Units + - set value: HIDEBUTTON,False + - when: "CLICKED eq true and not HIDEBUTTON" + actions: + - Set Instrument Units: "OAT,OILT1,Temperature,Pressure,Altitude:Toggle" + - set value: HIDEBUTTON,False + diff --git a/tests/data/buttons/toggle.yaml b/tests/data/buttons/toggle.yaml new file mode 100644 index 00000000..56faac23 --- /dev/null +++ b/tests/data/buttons/toggle.yaml @@ -0,0 +1,37 @@ +type: toggle +text: "AP\nAdjust" +dbkey: TSBTN{id}2 +condition_keys: + - MAVMODE + - MAVSTATE + - MAVADJ +conditions: + - when: "MAVMODE eq 'TRIM'" + actions: + - button: disable + - set bg color: "#5d5b59" + - button: unchecked + # Maybethis should be done in the mavlink plugin? + - set value: MAVREQADJ, false + - when: "CLICKED eq true and DBKEY eq false and MAVMODE ne 'TRIM'" + actions: + - set bg color: yellow + - set value: MAVREQADJ, false + - when: "CLICKED eq true and DBKEY eq true and MAVMODE ne 'TRIM'" + actions: + - set bg color: yellow + - set value: MAVREQADJ, true + - when: "MAVSTATE eq 'ARMED' and MAVMODE ne 'TRIM' and MAVADJ eq true" + actions: + - set bg color: green + - button: checked + - button: enabled + continue: true + - when: "MAVSTATE eq 'ARMED' and MAVMODE ne 'TRIM' and MAVADJ eq false" + actions: + - set bg color: lightgray + - button: unchecked + - button: enable + continue: true + + diff --git a/tests/instruments/button/__init__.py b/tests/instruments/button/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/instruments/button/button_test_button.py b/tests/instruments/button/button_test_button.py deleted file mode 100644 index 73479674..00000000 --- a/tests/instruments/button/button_test_button.py +++ /dev/null @@ -1,37 +0,0 @@ -import pytest -from unittest import mock -from PyQt5.QtWidgets import QApplication, QWidget -from PyQt5.QtCore import Qt, qRound -from PyQt5.QtGui import QColor, QBrush, QPen, QFont, QPaintEvent, QFontMetrics -from pyefis.instruments import button -import pyefis.hmi as hmi -from tests.utils import track_calls - - -@pytest.fixture -def app(qtbot): - test_app = QApplication.instance() - if test_app is None: - test_app = QApplication([]) - return test_app - -@pytest.fixture -def mock_parent_widget(): - real_parent = QWidget() # Create a real QWidget instance - real_parent.screenName = "TEST" - real_parent.parent = mock.Mock() - real_parent.parent.nodeID = 1 - real_parent.parent.config_path = "tests/data/listbox/" - return real_parent - -def test_simple_button(fix,mock_parent_widget,qtbot): - widget = button.Button(mock_parent_widget, config_file="tests/data/buttons/simple.yaml") - qtbot.addWidget(mock_parent_widget) - qtbot.addWidget(widget) - mock_parent_widget.resize(200,200) - mock_parent_widget.show() - widget.resize(100,80) - widget.show() - qtbot.waitExposed(widget) - qtbot.wait(2000) - diff --git a/tests/instruments/button/test_button.py b/tests/instruments/button/test_button.py new file mode 100644 index 00000000..d4417a6c --- /dev/null +++ b/tests/instruments/button/test_button.py @@ -0,0 +1,94 @@ +import pytest +from unittest import mock +from PyQt5.QtWidgets import QApplication, QWidget +from PyQt5.QtCore import Qt, qRound +from PyQt5.QtGui import QColor, QBrush, QPen, QFont, QPaintEvent, QFontMetrics +from pyefis.instruments import button +import pyefis.hmi as hmi +from tests.utils import track_calls + + +@pytest.fixture +def app(qtbot): + test_app = QApplication.instance() + if test_app is None: + test_app = QApplication([]) + return test_app + +@pytest.fixture +def mock_parent_widget(): + real_parent = QWidget() # Create a real QWidget instance + real_parent.screenName = "TEST" + real_parent.parent = mock.Mock() + real_parent.parent.nodeID = 1 + return real_parent + +def test_simple_button(fix,mock_parent_widget,qtbot): + hmi.initialize({}) + widget = button.Button(mock_parent_widget, config_file="tests/data/buttons/simple.yaml") + qtbot.addWidget(mock_parent_widget) + qtbot.addWidget(widget) + mock_parent_widget.resize(200,200) + mock_parent_widget.show() + widget.resize(100,80) + widget.show() + qtbot.waitExposed(widget) + assert widget._title == "Units" + assert widget.config['dbkey'] == 'TSBTN{id}0' + assert widget._toggle == False + assert widget._button.isCheckable() == False + fix.db.get_item("HIDEBUTTON").value = True + assert widget._title == "Show\nMenu" + qtbot.mouseClick(widget._button, Qt.LeftButton) + assert widget._title == "Units" + with qtbot.waitSignal(hmi.actions.setInstUnits, timeout=2000): + qtbot.mouseClick(widget._button, Qt.LeftButton) + + + +def test_toggle_button(fix,mock_parent_widget,qtbot): + hmi.initialize({}) + widget = button.Button(mock_parent_widget, config_file="tests/data/buttons/toggle.yaml") + qtbot.addWidget(mock_parent_widget) + qtbot.addWidget(widget) + mock_parent_widget.resize(200,200) + mock_parent_widget.show() + widget.resize(100,80) + widget.show() + qtbot.waitExposed(widget) + assert widget._title == "AP\nAdjust" + assert widget.config['dbkey'] == 'TSBTN{id}2' + assert widget._toggle == True + assert widget._button.isCheckable() == True + assert widget._style['bg'] == QColor("#5d5b59") + assert widget.isEnabled() == False + #qtbot.wait(2000) + + +def test_repeat_button(fix,mock_parent_widget,qtbot): + hmi.initialize({}) + widget = button.Button(mock_parent_widget, config_file="tests/data/buttons/repeat.yaml") + qtbot.addWidget(mock_parent_widget) + qtbot.addWidget(widget) + mock_parent_widget.resize(200,200) + mock_parent_widget.show() + widget.resize(100,80) + widget.show() + qtbot.waitExposed(widget) + assert widget._title == "+" + assert widget.config['dbkey'] == 'TSBTN{id}3' + assert widget._toggle == False + assert widget._repeat == True + assert widget._button.isCheckable() == False + assert widget._style['transparent'] == True + assert widget._button.autoRepeatInterval() == 200 + baro = fix.db.get_item("BARO") + before = baro.value + qtbot.mouseClick(widget._button, Qt.LeftButton) + assert baro.value == before + 0.01 + before = baro.value + fix.db.get_item("TSBTN13").value = True + qtbot.wait(1000) + fix.db.get_item("TSBTN13").value = False + assert round(baro.value,2) >= round(before + 0.03,2) + From 6eb9d9bc70ec7433f145e73c66e39c6746924d13 Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Mon, 17 Jun 2024 21:31:14 -0400 Subject: [PATCH 03/12] Ensure Active/Standby on radio interface is rendered same font size --- .../v16/rectangle-radio-volume-primary-secondary-display.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pyefis/config/includes/mgl/v16/rectangle-radio-volume-primary-secondary-display.yaml b/src/pyefis/config/includes/mgl/v16/rectangle-radio-volume-primary-secondary-display.yaml index 99e5e32a..d0ee91cf 100644 --- a/src/pyefis/config/includes/mgl/v16/rectangle-radio-volume-primary-secondary-display.yaml +++ b/src/pyefis/config/includes/mgl/v16/rectangle-radio-volume-primary-secondary-display.yaml @@ -9,12 +9,12 @@ instruments: row: 0 column: 29 span: - rows: 4 + rows: 5 columns: 27 preferences: TEXT3 options: text: "Active:" - font_mask: "XXXXXX:" + font_mask: "XXXXXXX:" alignment: AlignLeft - type: static_text row: 0 From ad79058b3e4c890bbed5063fd3dfa4cc55e4a11e Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Mon, 17 Jun 2024 21:51:27 -0400 Subject: [PATCH 04/12] Adjusted font mask helper, had a bug and tight font metrics did not work well --- .../instruments/NumericalDisplay/__init__.py | 1 - src/pyefis/instruments/helpers/__init__.py | 46 +++++++++---------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/pyefis/instruments/NumericalDisplay/__init__.py b/src/pyefis/instruments/NumericalDisplay/__init__.py index fbd2bf9b..d8ab50de 100644 --- a/src/pyefis/instruments/NumericalDisplay/__init__.py +++ b/src/pyefis/instruments/NumericalDisplay/__init__.py @@ -158,7 +158,6 @@ def redraw(self): if self._bad or self._old: prest = "" self.pre_scroll_text.setText(prest) - print(dir(self.pre_scroll_text.text)) if not (self._bad or self._old or self._fail): self.scrolling_area.value = scroll_value diff --git a/src/pyefis/instruments/helpers/__init__.py b/src/pyefis/instruments/helpers/__init__.py index 6c0c0104..c59691c4 100644 --- a/src/pyefis/instruments/helpers/__init__.py +++ b/src/pyefis/instruments/helpers/__init__.py @@ -1,52 +1,47 @@ from PyQt5.QtWidgets import * from PyQt5.QtGui import * -def fit_to_mask(iwidth,iheight,mask,font,units_mask=None, units_ratio=0.8): - - # Could not get font metrics to work perfectly - # Seems like text it rendered starting slightly to the right - # rsulting in the right side of the text getting cut off - # Fitting to a slightly smaller width and height - # seems to resolve the issue. - width = iwidth * 0.95 - height = iheight * 0.96 +def fit_to_mask(width,height,mask,font,units_mask=None, units_ratio=0.8): + # This works well for text, but renderes numbers undersized font_size = height - text_font = QFont(font, int(font_size)) - units_font = QFont(font, int(font_size * units_ratio)) + text_font = QFont(font) + text_font.setPointSizeF(font_size) + units_font = QFont(font) + units_font.setPointSizeF(font_size * units_ratio) fm = QFontMetrics(text_font) - text_width = fm.tightBoundingRect(mask).width() - text_height = fm.tightBoundingRect(mask).height() + text_width = fm.boundingRect(mask).width() + text_height = fm.boundingRect(mask).height() - fm.leading() units_width = 0 units_height = 0 if units_mask: fmu = QFontMetrics(units_font) - units_width = fmu.tightBoundingRect(units_mask).width() - units_height = fmu.tightBoundingRect(units_mask).height() + units_width = fmu.boundingRect(units_mask).width() + units_height = fmu.boundingRect(units_mask).height() # IF needed, shrink until it fits while ( (text_width + units_width > width) or text_height > height ) and font_size > 0.5: font_size -= 0.2 text_font.setPointSizeF(font_size) fm = QFontMetrics(text_font) - text_width = fm.tightBoundingRect(mask).width() - text_height = fm.tightBoundingRect(mask).height() + text_width = fm.boundingRect(mask).width() + text_height = fm.boundingRect(mask).height() if units_mask: units_font.setPointSizeF(font_size * units_ratio) fmu = QFontMetrics(units_font) - units_width = fmu.tightBoundingRect(units_mask).width() - units_height = fmu.tightBoundingRect(units_mask).height() + units_width = fmu.boundingRect(units_mask).width() + units_height = fmu.boundingRect(units_mask).height() # If needed, grow until it fills while (text_width + units_width < width) and text_height < height: font_size += 0.2 text_font.setPointSizeF(font_size) fm = QFontMetrics(text_font) - text_width = fm.tightBoundingRect(mask).width() - text_height = fm.tightBoundingRect(mask).height() + text_width = fm.boundingRect(mask).width() + text_height = fm.boundingRect(mask).height() if units_mask: units_font.setPointSizeF(font_size * units_ratio) fmu = QFontMetrics(units_font) - units_width = fmu.tightBoundingRect(units_mask).width() - units_height = fmu.tightBoundingRect(units_mask).height() + units_width = fmu.boundingRect(units_mask).width() + units_height = fmu.boundingRect(units_mask).height() font_size -= 0.2 @@ -55,8 +50,9 @@ def fit_to_mask(iwidth,iheight,mask,font,units_mask=None, units_ratio=0.8): font_size -= 0.2 text_font.setPointSizeF(font_size) fm = QFontMetrics(text_font) - text_width = fm.tightBoundingRect(mask).width() - + text_height = fm.boundingRect(mask).height() + if font_size <= 0: + raise "Error" return(font_size) From 93fa2aec146953db69e03afdd8f274ac8badfa6e Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Tue, 18 Jun 2024 18:25:13 -0400 Subject: [PATCH 05/12] Adjusted version display --- src/pyefis/config/includes/ahrs/virtual_vfr.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pyefis/config/includes/ahrs/virtual_vfr.yaml b/src/pyefis/config/includes/ahrs/virtual_vfr.yaml index 80bfa711..803019de 100644 --- a/src/pyefis/config/includes/ahrs/virtual_vfr.yaml +++ b/src/pyefis/config/includes/ahrs/virtual_vfr.yaml @@ -298,7 +298,7 @@ instruments: columns: 9 options: text: "pyefis:" - font_mask: "pyefis:" + font_mask: "gateway:" alignment: AlignRight - type: value_text disabled: VERSION_DISPLAY @@ -312,7 +312,7 @@ instruments: font_mask: X.X.XX - type: static_text disabled: VERSION_DISPLAY - row: 107 + row: 107.5 column: 0 span: rows: 2.5 @@ -323,7 +323,7 @@ instruments: alignment: AlignRight - type: value_text disabled: VERSION_DISPLAY - row: 107 + row: 107.5 column: 9 span: rows: 2.5 From 0a0922faa69e1b8e011bc16d500373e409cde9b3 Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Tue, 18 Jun 2024 18:28:35 -0400 Subject: [PATCH 06/12] Updated font size calcualtion for performance and added option for numbers vs text to get the largest possible size --- src/pyefis/instruments/gauges/numeric.py | 2 +- src/pyefis/instruments/helpers/__init__.py | 87 ++++++++++------------ 2 files changed, 39 insertions(+), 50 deletions(-) diff --git a/src/pyefis/instruments/gauges/numeric.py b/src/pyefis/instruments/gauges/numeric.py index 67143aa4..1deb0ecb 100644 --- a/src/pyefis/instruments/gauges/numeric.py +++ b/src/pyefis/instruments/gauges/numeric.py @@ -38,7 +38,7 @@ def resizeEvent(self, event): self.font_size = self.height() if self.font_mask: - self.font_size = helpers.fit_to_mask(self.width(),self.height(),self.font_mask,self.font_family,self.units_font_mask,self.small_font_percent) + self.font_size = helpers.fit_to_mask(self.width(),self.height(),self.font_mask,self.font_family,self.units_font_mask,self.small_font_percent,True) self.bigFont = QFont(self.font_family) self.bigFont.setPointSizeF(self.font_size) self.smallFont = QFont(self.font_family) diff --git a/src/pyefis/instruments/helpers/__init__.py b/src/pyefis/instruments/helpers/__init__.py index c59691c4..8241d3e9 100644 --- a/src/pyefis/instruments/helpers/__init__.py +++ b/src/pyefis/instruments/helpers/__init__.py @@ -1,58 +1,47 @@ from PyQt5.QtWidgets import * from PyQt5.QtGui import * -def fit_to_mask(width,height,mask,font,units_mask=None, units_ratio=0.8): - # This works well for text, but renderes numbers undersized - font_size = height - text_font = QFont(font) - text_font.setPointSizeF(font_size) - units_font = QFont(font) - units_font.setPointSizeF(font_size * units_ratio) - fm = QFontMetrics(text_font) - text_width = fm.boundingRect(mask).width() - text_height = fm.boundingRect(mask).height() - fm.leading() - units_width = 0 - units_height = 0 - if units_mask: - fmu = QFontMetrics(units_font) - units_width = fmu.boundingRect(units_mask).width() - units_height = fmu.boundingRect(units_mask).height() - - # IF needed, shrink until it fits - while ( (text_width + units_width > width) or text_height > height ) and font_size > 0.5: - font_size -= 0.2 - text_font.setPointSizeF(font_size) - fm = QFontMetrics(text_font) - text_width = fm.boundingRect(mask).width() - text_height = fm.boundingRect(mask).height() - if units_mask: - units_font.setPointSizeF(font_size * units_ratio) - fmu = QFontMetrics(units_font) - units_width = fmu.boundingRect(units_mask).width() - units_height = fmu.boundingRect(units_mask).height() - # If needed, grow until it fills - while (text_width + units_width < width) and text_height < height: - font_size += 0.2 +def fit_to_mask(width,height,mask,font,units_mask=None, units_ratio=0.8, numeric=False): + font_size = 100 + error = 100 + minerror = 100 + goal = 0.02 + count = 0 + while ( error > goal): + count += 1 + text_font = QFont(font) text_font.setPointSizeF(font_size) - fm = QFontMetrics(text_font) - text_width = fm.boundingRect(mask).width() - text_height = fm.boundingRect(mask).height() + fm = QFontMetricsF(text_font) + text_width = fm.horizontalAdvance(mask) + if numeric: + text_height = fm.tightBoundingRect(mask).height() + else: + text_height = fm.boundingRect(mask).height() + units_width = 0 + units_height = 0 if units_mask: + units_font = QFont(font) units_font.setPointSizeF(font_size * units_ratio) - fmu = QFontMetrics(units_font) - units_width = fmu.boundingRect(units_mask).width() - units_height = fmu.boundingRect(units_mask).height() - - font_size -= 0.2 + fmu = QFontMetricsF(units_font) + units_width = fmu.horizontalAdvance(units_mask) + hfactor = height / text_height + wfactor = width / ( text_width + units_width) + if hfactor < 1 and wfactor < 1: + factor = min(hfactor, wfactor) + elif hfactor > 1 and wfactor > 1: + factor = max(hfactor,wfactor) + elif hfactor < 1 and wfactor > 1: + factor = hfactor + else: + factor = wfactor + error = abs(factor - 1) + if factor > 1: + if error < minerror: + minerror = error + else: + break + font_size = font_size * factor + return font_size - # The above took care of the width, this addresses the height: - while (text_height >= height) and font_size > 0.5: - font_size -= 0.2 - text_font.setPointSizeF(font_size) - fm = QFontMetrics(text_font) - text_height = fm.boundingRect(mask).height() - if font_size <= 0: - raise "Error" - return(font_size) From dcce504446d78fcc84f1682ac5757e79fe55581c Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Tue, 18 Jun 2024 18:29:22 -0400 Subject: [PATCH 07/12] Updated listbox to use font_mask for the name of the list to ensure the bottom of txt is not cut off --- src/pyefis/instruments/listbox/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pyefis/instruments/listbox/__init__.py b/src/pyefis/instruments/listbox/__init__.py index 66aae562..1ac1f115 100644 --- a/src/pyefis/instruments/listbox/__init__.py +++ b/src/pyefis/instruments/listbox/__init__.py @@ -33,6 +33,7 @@ def __init__(self, parent=None, lists=[], replace=None, font_family="DejaVu Sans self.active_list = list(self.tlists.keys())[0] self.header = misc.StaticText(text=self.active_list, color=QColor(Qt.white), parent=self) + self.header.font_mask = self.active_list self.selected_row = 0 self.columns = len(self.tlists[self.active_list]['display']['columns']) self.rows = len(self.tlists[self.active_list]['list']) @@ -196,6 +197,7 @@ def loadList(self): self.table.setRowCount(0) self.header.hide() self.header.text = self.active_list + self.header.font_mask = self.active_list self.header.show() self.column_names = [ item['name'] for item in self.tlists[self.active_list]['display']['columns'] ] From ad7acd16a1c878f5d39462534b350d31d558137c Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Tue, 18 Jun 2024 18:42:20 -0400 Subject: [PATCH 08/12] Updated arc gauge test, previous test asserts were wrong --- tests/instruments/gauges/test_arc.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/instruments/gauges/test_arc.py b/tests/instruments/gauges/test_arc.py index 6f2b9aa0..af8bfad1 100644 --- a/tests/instruments/gauges/test_arc.py +++ b/tests/instruments/gauges/test_arc.py @@ -42,18 +42,15 @@ def test_arc_gauge(fix,qtbot): assert int(widget.valueFontSize) == 33 assert int(widget.unitsFontSize) == 25 assert int(widget.nameFontSize) == 17 - widget.font_mask = "00" widget.units_font_mask = "00" widget.name_font_mask = "0000" widget.resizeEvent(None) - assert widget.valueFontSize < 0.5 - assert widget.unitsFontSize < 0.4 - assert widget.nameFontSize < 10 - assert widget.nameFontSize > 9 + assert widget.valueFontSize != 33 + assert widget.unitsFontSize != 25 + assert widget.nameFontSize != 17 widget.name_location = "right" widget.resizeEvent(None) - assert widget.nameFontSize < 0.4 # Switch to NUOK with aux data to check the bar colors widget.setDbkey("NUMOK") widget.setupGauge() @@ -73,7 +70,6 @@ def test_arc_gauge(fix,qtbot): assert tracker.was_called_with("width", "0000") assert tracker2.was_called_with("setAlpha", widget.font_ghost_alpha) - widget.name_location = "top" widget.paintEvent(None) From 3466c26616de38a7a21399b13350549d6337509e Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Tue, 18 Jun 2024 20:42:36 -0400 Subject: [PATCH 09/12] Updated airspeed and altimeter tapes so they display the same number of lines when rendered at different resolutions --- src/pyefis/instruments/airspeed/__init__.py | 3 +-- src/pyefis/instruments/altimeter/__init__.py | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/pyefis/instruments/airspeed/__init__.py b/src/pyefis/instruments/airspeed/__init__.py index 5d6c2769..d5a87b16 100644 --- a/src/pyefis/instruments/airspeed/__init__.py +++ b/src/pyefis/instruments/airspeed/__init__.py @@ -277,8 +277,7 @@ def __init__( def resizeEvent(self, event): if self.font_percent: self.fontsize = qRound(self.width() * self.font_percent) - self.pph = qRound(self.fontsize * 0.4) - + self.pph = self.height() / 100 w = self.width() h = self.height() self.markWidth = w / 5 diff --git a/src/pyefis/instruments/altimeter/__init__.py b/src/pyefis/instruments/altimeter/__init__.py index c5bc7a3a..4399b136 100644 --- a/src/pyefis/instruments/altimeter/__init__.py +++ b/src/pyefis/instruments/altimeter/__init__.py @@ -262,8 +262,7 @@ def __init__( def resizeEvent(self, event): if self.font_percent: self.fontsize = qRound(self.width() * self.font_percent) - self.pph = self.fontsize / (self.height() / 20) - + self.pph = self.height() / 1000 w = self.width() w_2 = w / 2 h = self.height() @@ -281,7 +280,6 @@ def resizeEvent(self, event): self.height_pixel = ( self.maxalt * 2 * self.pph + h ) # + abs(self.minalt*self.pph) - dialPen = QPen(QColor(Qt.white)) dialPen.setWidth(int(self.height() * 0.005)) From c86f25ff5554fb1b0e8aec7c01998d86314d7adf Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Tue, 18 Jun 2024 20:50:54 -0400 Subject: [PATCH 10/12] Improve coverage for helper --- tests/instruments/gauges/test_numeric.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/instruments/gauges/test_numeric.py b/tests/instruments/gauges/test_numeric.py index 9042428c..62ab4fed 100644 --- a/tests/instruments/gauges/test_numeric.py +++ b/tests/instruments/gauges/test_numeric.py @@ -31,6 +31,7 @@ def test_numeric_gauge(fix,qtbot): assert widget.font_size != 200 oldvalueTextRect = widget.valueTextRect widget.show_units = True + widget.units_font_mask = "XXX" widget.resizeEvent(None) assert oldvalueTextRect != widget.valueTextRect widget.font_ghost_mask = "0000" From 668612a8f5fb507229c6c0808623ba14f28fa628 Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Tue, 18 Jun 2024 21:57:59 -0400 Subject: [PATCH 11/12] Improvd button tests --- tests/instruments/button/test_button.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/tests/instruments/button/test_button.py b/tests/instruments/button/test_button.py index d4417a6c..90d85808 100644 --- a/tests/instruments/button/test_button.py +++ b/tests/instruments/button/test_button.py @@ -43,7 +43,16 @@ def test_simple_button(fix,mock_parent_widget,qtbot): assert widget._title == "Units" with qtbot.waitSignal(hmi.actions.setInstUnits, timeout=2000): qtbot.mouseClick(widget._button, Qt.LeftButton) - + widget.enc_highlight(True) + assert widget._style['bg_override'] == QColor('orange') + with qtbot.waitSignal(hmi.actions.setInstUnits, timeout=2000): + widget.enc_select() + fix.db.set_value("HIDEBUTTON", True) + assert fix.db.get_item("HIDEBUTTON").value == True + assert widget._buttonhide == True + widget.enterEvent(None) + assert fix.db.get_item("HIDEBUTTON").value == False + #qtbot.wait(2000) def test_toggle_button(fix,mock_parent_widget,qtbot): @@ -56,12 +65,24 @@ def test_toggle_button(fix,mock_parent_widget,qtbot): widget.resize(100,80) widget.show() qtbot.waitExposed(widget) + widget.enterEvent(None) assert widget._title == "AP\nAdjust" assert widget.config['dbkey'] == 'TSBTN{id}2' assert widget._toggle == True assert widget._button.isCheckable() == True assert widget._style['bg'] == QColor("#5d5b59") assert widget.isEnabled() == False + fix.db.set_value("MAVMODE","HH") + fix.db.set_value("MAVSTATE","ARMED") + widget.enc_highlight(True) + assert widget._style['bg_override'] == QColor('orange') + widget.enc_select() + assert widget._style['bg'] == QColor('yellow') + fix.db.set_value("MAVADJ",True) + assert widget._style['bg'] == QColor('green') + widget.enc_highlight(False) + assert widget._style['bg_override'] == None + assert widget.enc_selectable() == True #qtbot.wait(2000) @@ -88,7 +109,7 @@ def test_repeat_button(fix,mock_parent_widget,qtbot): assert baro.value == before + 0.01 before = baro.value fix.db.get_item("TSBTN13").value = True - qtbot.wait(1000) + #qtbot.wait(1000) fix.db.get_item("TSBTN13").value = False assert round(baro.value,2) >= round(before + 0.03,2) From 561a03f9fcc3400796dd2c9bdfebee54c7c8e9cf Mon Sep 17 00:00:00 2001 From: Eric Blevins Date: Tue, 18 Jun 2024 22:03:26 -0400 Subject: [PATCH 12/12] Forgot to commit the config change for the button test --- tests/data/buttons/simple.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/data/buttons/simple.yaml b/tests/data/buttons/simple.yaml index f3d7ffc4..47af1316 100644 --- a/tests/data/buttons/simple.yaml +++ b/tests/data/buttons/simple.yaml @@ -1,6 +1,7 @@ type: simple text: "Units" dbkey: TSBTN{id}0 +hover_show: True condition_keys: - HIDEBUTTON conditions: