diff --git a/system/ui/sunnypilot/widgets/__init__.py b/system/ui/sunnypilot/widgets/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/system/ui/sunnypilot/widgets/input_dialog.py b/system/ui/sunnypilot/widgets/input_dialog.py new file mode 100644 index 0000000000..f532bd9fed --- /dev/null +++ b/system/ui/sunnypilot/widgets/input_dialog.py @@ -0,0 +1,35 @@ +from collections.abc import Callable + +from openpilot.common.params import Params +from openpilot.system.ui.lib.application import gui_app +from openpilot.system.ui.lib.multilang import tr +from openpilot.system.ui.widgets import DialogResult +from openpilot.system.ui.widgets.keyboard import Keyboard + + +class InputDialogSP: + def __init__(self, title: str, sub_title: str | None = None, current_text: str = "", param: str | None = None, + callback: Callable[[DialogResult, str], None] | None = None, + min_text_size: int = 0, password_mode: bool = False): + self.callback = callback + self.current_text = current_text + self.keyboard = Keyboard(max_text_size=255, min_text_size=min_text_size, password_mode=password_mode) + self.param = param + self._params = Params() + self.sub_title = sub_title + self.title = title + + def show(self): + self.keyboard.reset(min_text_size=self.keyboard._min_text_size) + self.keyboard.set_title(tr(self.title), *(tr(self.sub_title),) if self.sub_title else ()) + self.keyboard.set_text(self.current_text) + + def internal_callback(result: DialogResult): + text = self.keyboard.text if result == DialogResult.CONFIRM else "" + if result == DialogResult.CONFIRM: + if self.param: + self._params.put(self.param, text) + if self.callback: + self.callback(result, text) + + gui_app.set_modal_overlay(self.keyboard, internal_callback) diff --git a/system/ui/sunnypilot/widgets/tests/__init__.py b/system/ui/sunnypilot/widgets/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/system/ui/sunnypilot/widgets/tests/test_input_dialog.py b/system/ui/sunnypilot/widgets/tests/test_input_dialog.py new file mode 100644 index 0000000000..46a7979fd9 --- /dev/null +++ b/system/ui/sunnypilot/widgets/tests/test_input_dialog.py @@ -0,0 +1,58 @@ +import os +import pytest + +from openpilot.common.params import Params +from openpilot.system.ui.lib.application import gui_app +from openpilot.system.ui.widgets.keyboard import Keyboard +from openpilot.system.ui.sunnypilot.widgets.input_dialog import InputDialogSP + +os.environ['SDL_VIDEODRIVER'] = 'dummy' +if not os.environ.get('CI'): + pytest.skip("Test in CI environment, or comment out this flag to test locally", allow_module_level=True) + + +class TestInputDialog: + def setup_method(self): + self.params = Params() + + def test_input_dialog_int(self): + gui_app.init_window("test window") + dialog = InputDialogSP("title", current_text="current_text", param="MapTargetVelocities") + dialog.show() + + dialog.keyboard._render_return_status = 1 + gui_app._handle_modal_overlay() + + assert self.params.get("MapTargetVelocities") == "current_text" + + def test_before_input_dialog(self): + gui_app.init_window("test window") + current_apn = "gsmapn" + # This tests the pre InputDialogSP, where keyboard setup had to be done for every single dialog box you want to use. + self.keyboard = Keyboard() + self.keyboard.reset(min_text_size=0) + self.keyboard.set_title(("Enter APN"), ("networking")) + self.keyboard.set_text(current_apn) + + def pre_input_dialog_callback(result): + if result == 1: + apn = self.keyboard.text.strip() + self.params.put("GsmApn", apn) + + gui_app.set_modal_overlay(self.keyboard, pre_input_dialog_callback) + self.keyboard.set_text("new_apn") + self.keyboard._render_return_status = 1 + gui_app._handle_modal_overlay() + pre_input_dialog_result = self.params.get("GsmApn") + + assert pre_input_dialog_result == "new_apn" + + dialog = InputDialogSP(title="Enter APN", sub_title="networking", current_text=current_apn, param="GsmApn") + dialog.show() + dialog.keyboard.set_text("new_apn") + dialog.keyboard._render_return_status = 1 + gui_app._handle_modal_overlay() + input_dialog_result = self.params.get("GsmApn") + + assert input_dialog_result == "new_apn" + assert pre_input_dialog_result == input_dialog_result