bauiv1lib.settings.testing

Provides UI for test settings.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Provides UI for test settings."""
  4
  5from __future__ import annotations
  6
  7import copy
  8from typing import TYPE_CHECKING, override
  9
 10import bauiv1 as bui
 11
 12if TYPE_CHECKING:
 13    from typing import Any, Callable
 14
 15
 16class TestingWindow(bui.MainWindow):
 17    """Window for conveniently testing various settings."""
 18
 19    def __init__(
 20        self,
 21        title: bui.Lstr,
 22        entries: list[dict[str, Any]],
 23        transition: str | None = 'in_right',
 24        origin_widget: bui.Widget | None = None,
 25    ):
 26        assert bui.app.classic is not None
 27        uiscale = bui.app.ui_v1.uiscale
 28        self._width = 690 if uiscale is bui.UIScale.SMALL else 600
 29        self._height = 400 if uiscale is bui.UIScale.SMALL else 400
 30        self._entries_orig = copy.deepcopy(entries)
 31        self._entries = copy.deepcopy(entries)
 32        yoffs = -50 if uiscale is bui.UIScale.SMALL else 0
 33
 34        super().__init__(
 35            root_widget=bui.containerwidget(
 36                size=(self._width, self._height),
 37                scale=(
 38                    2.27
 39                    if uiscale is bui.UIScale.SMALL
 40                    else 1.2 if uiscale is bui.UIScale.MEDIUM else 1.0
 41                ),
 42                stack_offset=(
 43                    (0, 0) if uiscale is bui.UIScale.SMALL else (0, 0)
 44                ),
 45                toolbar_visibility=(
 46                    'menu_minimal'
 47                    if uiscale is bui.UIScale.SMALL
 48                    else 'menu_full'
 49                ),
 50            ),
 51            transition=transition,
 52            origin_widget=origin_widget,
 53        )
 54
 55        if uiscale is bui.UIScale.SMALL:
 56            self._back_button = bui.get_special_widget('back_button')
 57            bui.containerwidget(
 58                edit=self._root_widget, on_cancel_call=self.main_window_back
 59            )
 60        else:
 61            self._back_button = btn = bui.buttonwidget(
 62                parent=self._root_widget,
 63                autoselect=True,
 64                position=(65, self._height - 59 + yoffs),
 65                size=(130, 60),
 66                scale=0.8,
 67                text_scale=1.2,
 68                label=bui.Lstr(resource='backText'),
 69                button_type='back',
 70                on_activate_call=self.main_window_back,
 71            )
 72            bui.buttonwidget(
 73                edit=self._back_button,
 74                button_type='backSmall',
 75                size=(60, 60),
 76                label=bui.charstr(bui.SpecialChar.BACK),
 77            )
 78            bui.containerwidget(edit=self._root_widget, cancel_button=btn)
 79
 80        self.title = title
 81        bui.textwidget(
 82            parent=self._root_widget,
 83            position=(
 84                self._width * 0.5,
 85                self._height
 86                - (42 if uiscale is bui.UIScale.SMALL else 35)
 87                + yoffs,
 88            ),
 89            size=(0, 0),
 90            color=bui.app.ui_v1.title_color,
 91            h_align='center',
 92            v_align='center',
 93            maxwidth=245,
 94            text=self.title,
 95        )
 96
 97        bui.textwidget(
 98            parent=self._root_widget,
 99            position=(
100                self._width * 0.5,
101                self._height
102                - (80 if uiscale is bui.UIScale.SMALL else 80)
103                + yoffs,
104            ),
105            size=(0, 0),
106            color=bui.app.ui_v1.infotextcolor,
107            h_align='center',
108            v_align='center',
109            maxwidth=self._width * 0.75,
110            text=bui.Lstr(resource='settingsWindowAdvanced.forTestingText'),
111        )
112        self._scroll_width = self._width - 130
113        self._scroll_height = self._height - (
114            220 if uiscale is bui.UIScale.SMALL else 140
115        )
116        self._scrollwidget = bui.scrollwidget(
117            parent=self._root_widget,
118            size=(self._scroll_width, self._scroll_height),
119            highlight=False,
120            position=(
121                (self._width - self._scroll_width) * 0.5,
122                (120 if uiscale is bui.UIScale.SMALL else 40) + yoffs,
123            ),
124        )
125        bui.containerwidget(edit=self._scrollwidget, claims_left_right=True)
126
127        self._spacing = 50
128
129        self._sub_width = self._scroll_width * 0.95
130        self._sub_height = 50 + len(self._entries) * self._spacing + 60
131        self._subcontainer = bui.containerwidget(
132            parent=self._scrollwidget,
133            size=(self._sub_width, self._sub_height),
134            background=False,
135        )
136
137        h = 230
138        v = self._sub_height - 48
139
140        for i, entry in enumerate(self._entries):
141            entry_name = entry['name']
142
143            # If we haven't yet, record the default value for this name so
144            # we can reset if we want..
145            if entry_name not in bui.app.classic.value_test_defaults:
146                bui.app.classic.value_test_defaults[entry_name] = (
147                    bui.app.classic.value_test(entry_name)
148                )
149
150            bui.textwidget(
151                parent=self._subcontainer,
152                position=(h, v),
153                size=(0, 0),
154                h_align='right',
155                v_align='center',
156                maxwidth=200,
157                text=entry['label'],
158            )
159            btn = bui.buttonwidget(
160                parent=self._subcontainer,
161                position=(h + 20, v - 19),
162                size=(40, 40),
163                autoselect=True,
164                repeat=True,
165                left_widget=self._back_button,
166                button_type='square',
167                label='-',
168                on_activate_call=bui.Call(self._on_minus_press, entry['name']),
169            )
170            if i == 0:
171                bui.widget(edit=btn, up_widget=self._back_button)
172            entry['widget'] = bui.textwidget(
173                parent=self._subcontainer,
174                position=(h + 100, v),
175                size=(0, 0),
176                h_align='center',
177                v_align='center',
178                maxwidth=60,
179                text=f'{bui.app.classic.value_test(entry_name):.4g}',
180            )
181            btn = bui.buttonwidget(
182                parent=self._subcontainer,
183                position=(h + 140, v - 19),
184                size=(40, 40),
185                autoselect=True,
186                repeat=True,
187                button_type='square',
188                label='+',
189                on_activate_call=bui.Call(self._on_plus_press, entry['name']),
190            )
191            if i == 0:
192                bui.widget(edit=btn, up_widget=self._back_button)
193            v -= self._spacing
194        v -= 35
195        bui.buttonwidget(
196            parent=self._subcontainer,
197            autoselect=True,
198            size=(200, 50),
199            position=(self._sub_width * 0.5 - 100, v),
200            label=bui.Lstr(resource='settingsWindowAdvanced.resetText'),
201            right_widget=btn,
202            on_activate_call=self._on_reset_press,
203        )
204
205    def _get_entry(self, name: str) -> dict[str, Any]:
206        for entry in self._entries:
207            if entry['name'] == name:
208                return entry
209        raise bui.NotFoundError(f'Entry not found: {name}')
210
211    def _on_reset_press(self) -> None:
212        assert bui.app.classic is not None
213        for entry in self._entries:
214            bui.app.classic.value_test(
215                entry['name'],
216                absolute=bui.app.classic.value_test_defaults[entry['name']],
217            )
218            bui.textwidget(
219                edit=entry['widget'],
220                text=f'{bui.app.classic.value_test(entry['name']):.4g}',
221            )
222
223    def _on_minus_press(self, entry_name: str) -> None:
224        assert bui.app.classic is not None
225        entry = self._get_entry(entry_name)
226        bui.app.classic.value_test(entry['name'], change=-entry['increment'])
227        # pylint: disable=consider-using-f-string
228        bui.textwidget(
229            edit=entry['widget'],
230            text='%.4g' % bui.app.classic.value_test(entry['name']),
231        )
232
233    def _on_plus_press(self, entry_name: str) -> None:
234        assert bui.app.classic is not None
235        entry = self._get_entry(entry_name)
236        bui.app.classic.value_test(entry['name'], change=entry['increment'])
237        # pylint: disable=consider-using-f-string
238        bui.textwidget(
239            edit=entry['widget'],
240            text='%.4g' % bui.app.classic.value_test(entry['name']),
241        )
242
243    @override
244    def get_main_window_state(self) -> bui.MainWindowState:
245        # Support recreating our window for back/refresh purposes.
246        cls = type(self)
247
248        # Pull values from self here; if we do it in the lambda we'll keep
249        # self alive which we don't want.
250        title = self.title
251        entries = self._entries_orig
252
253        return bui.BasicMainWindowState(
254            create_call=lambda transition, origin_widget: cls(
255                title=title,
256                entries=entries,
257                transition=transition,
258                origin_widget=origin_widget,
259            )
260        )
class TestingWindow(bauiv1._uitypes.MainWindow):
 17class TestingWindow(bui.MainWindow):
 18    """Window for conveniently testing various settings."""
 19
 20    def __init__(
 21        self,
 22        title: bui.Lstr,
 23        entries: list[dict[str, Any]],
 24        transition: str | None = 'in_right',
 25        origin_widget: bui.Widget | None = None,
 26    ):
 27        assert bui.app.classic is not None
 28        uiscale = bui.app.ui_v1.uiscale
 29        self._width = 690 if uiscale is bui.UIScale.SMALL else 600
 30        self._height = 400 if uiscale is bui.UIScale.SMALL else 400
 31        self._entries_orig = copy.deepcopy(entries)
 32        self._entries = copy.deepcopy(entries)
 33        yoffs = -50 if uiscale is bui.UIScale.SMALL else 0
 34
 35        super().__init__(
 36            root_widget=bui.containerwidget(
 37                size=(self._width, self._height),
 38                scale=(
 39                    2.27
 40                    if uiscale is bui.UIScale.SMALL
 41                    else 1.2 if uiscale is bui.UIScale.MEDIUM else 1.0
 42                ),
 43                stack_offset=(
 44                    (0, 0) if uiscale is bui.UIScale.SMALL else (0, 0)
 45                ),
 46                toolbar_visibility=(
 47                    'menu_minimal'
 48                    if uiscale is bui.UIScale.SMALL
 49                    else 'menu_full'
 50                ),
 51            ),
 52            transition=transition,
 53            origin_widget=origin_widget,
 54        )
 55
 56        if uiscale is bui.UIScale.SMALL:
 57            self._back_button = bui.get_special_widget('back_button')
 58            bui.containerwidget(
 59                edit=self._root_widget, on_cancel_call=self.main_window_back
 60            )
 61        else:
 62            self._back_button = btn = bui.buttonwidget(
 63                parent=self._root_widget,
 64                autoselect=True,
 65                position=(65, self._height - 59 + yoffs),
 66                size=(130, 60),
 67                scale=0.8,
 68                text_scale=1.2,
 69                label=bui.Lstr(resource='backText'),
 70                button_type='back',
 71                on_activate_call=self.main_window_back,
 72            )
 73            bui.buttonwidget(
 74                edit=self._back_button,
 75                button_type='backSmall',
 76                size=(60, 60),
 77                label=bui.charstr(bui.SpecialChar.BACK),
 78            )
 79            bui.containerwidget(edit=self._root_widget, cancel_button=btn)
 80
 81        self.title = title
 82        bui.textwidget(
 83            parent=self._root_widget,
 84            position=(
 85                self._width * 0.5,
 86                self._height
 87                - (42 if uiscale is bui.UIScale.SMALL else 35)
 88                + yoffs,
 89            ),
 90            size=(0, 0),
 91            color=bui.app.ui_v1.title_color,
 92            h_align='center',
 93            v_align='center',
 94            maxwidth=245,
 95            text=self.title,
 96        )
 97
 98        bui.textwidget(
 99            parent=self._root_widget,
100            position=(
101                self._width * 0.5,
102                self._height
103                - (80 if uiscale is bui.UIScale.SMALL else 80)
104                + yoffs,
105            ),
106            size=(0, 0),
107            color=bui.app.ui_v1.infotextcolor,
108            h_align='center',
109            v_align='center',
110            maxwidth=self._width * 0.75,
111            text=bui.Lstr(resource='settingsWindowAdvanced.forTestingText'),
112        )
113        self._scroll_width = self._width - 130
114        self._scroll_height = self._height - (
115            220 if uiscale is bui.UIScale.SMALL else 140
116        )
117        self._scrollwidget = bui.scrollwidget(
118            parent=self._root_widget,
119            size=(self._scroll_width, self._scroll_height),
120            highlight=False,
121            position=(
122                (self._width - self._scroll_width) * 0.5,
123                (120 if uiscale is bui.UIScale.SMALL else 40) + yoffs,
124            ),
125        )
126        bui.containerwidget(edit=self._scrollwidget, claims_left_right=True)
127
128        self._spacing = 50
129
130        self._sub_width = self._scroll_width * 0.95
131        self._sub_height = 50 + len(self._entries) * self._spacing + 60
132        self._subcontainer = bui.containerwidget(
133            parent=self._scrollwidget,
134            size=(self._sub_width, self._sub_height),
135            background=False,
136        )
137
138        h = 230
139        v = self._sub_height - 48
140
141        for i, entry in enumerate(self._entries):
142            entry_name = entry['name']
143
144            # If we haven't yet, record the default value for this name so
145            # we can reset if we want..
146            if entry_name not in bui.app.classic.value_test_defaults:
147                bui.app.classic.value_test_defaults[entry_name] = (
148                    bui.app.classic.value_test(entry_name)
149                )
150
151            bui.textwidget(
152                parent=self._subcontainer,
153                position=(h, v),
154                size=(0, 0),
155                h_align='right',
156                v_align='center',
157                maxwidth=200,
158                text=entry['label'],
159            )
160            btn = bui.buttonwidget(
161                parent=self._subcontainer,
162                position=(h + 20, v - 19),
163                size=(40, 40),
164                autoselect=True,
165                repeat=True,
166                left_widget=self._back_button,
167                button_type='square',
168                label='-',
169                on_activate_call=bui.Call(self._on_minus_press, entry['name']),
170            )
171            if i == 0:
172                bui.widget(edit=btn, up_widget=self._back_button)
173            entry['widget'] = bui.textwidget(
174                parent=self._subcontainer,
175                position=(h + 100, v),
176                size=(0, 0),
177                h_align='center',
178                v_align='center',
179                maxwidth=60,
180                text=f'{bui.app.classic.value_test(entry_name):.4g}',
181            )
182            btn = bui.buttonwidget(
183                parent=self._subcontainer,
184                position=(h + 140, v - 19),
185                size=(40, 40),
186                autoselect=True,
187                repeat=True,
188                button_type='square',
189                label='+',
190                on_activate_call=bui.Call(self._on_plus_press, entry['name']),
191            )
192            if i == 0:
193                bui.widget(edit=btn, up_widget=self._back_button)
194            v -= self._spacing
195        v -= 35
196        bui.buttonwidget(
197            parent=self._subcontainer,
198            autoselect=True,
199            size=(200, 50),
200            position=(self._sub_width * 0.5 - 100, v),
201            label=bui.Lstr(resource='settingsWindowAdvanced.resetText'),
202            right_widget=btn,
203            on_activate_call=self._on_reset_press,
204        )
205
206    def _get_entry(self, name: str) -> dict[str, Any]:
207        for entry in self._entries:
208            if entry['name'] == name:
209                return entry
210        raise bui.NotFoundError(f'Entry not found: {name}')
211
212    def _on_reset_press(self) -> None:
213        assert bui.app.classic is not None
214        for entry in self._entries:
215            bui.app.classic.value_test(
216                entry['name'],
217                absolute=bui.app.classic.value_test_defaults[entry['name']],
218            )
219            bui.textwidget(
220                edit=entry['widget'],
221                text=f'{bui.app.classic.value_test(entry['name']):.4g}',
222            )
223
224    def _on_minus_press(self, entry_name: str) -> None:
225        assert bui.app.classic is not None
226        entry = self._get_entry(entry_name)
227        bui.app.classic.value_test(entry['name'], change=-entry['increment'])
228        # pylint: disable=consider-using-f-string
229        bui.textwidget(
230            edit=entry['widget'],
231            text='%.4g' % bui.app.classic.value_test(entry['name']),
232        )
233
234    def _on_plus_press(self, entry_name: str) -> None:
235        assert bui.app.classic is not None
236        entry = self._get_entry(entry_name)
237        bui.app.classic.value_test(entry['name'], change=entry['increment'])
238        # pylint: disable=consider-using-f-string
239        bui.textwidget(
240            edit=entry['widget'],
241            text='%.4g' % bui.app.classic.value_test(entry['name']),
242        )
243
244    @override
245    def get_main_window_state(self) -> bui.MainWindowState:
246        # Support recreating our window for back/refresh purposes.
247        cls = type(self)
248
249        # Pull values from self here; if we do it in the lambda we'll keep
250        # self alive which we don't want.
251        title = self.title
252        entries = self._entries_orig
253
254        return bui.BasicMainWindowState(
255            create_call=lambda transition, origin_widget: cls(
256                title=title,
257                entries=entries,
258                transition=transition,
259                origin_widget=origin_widget,
260            )
261        )

Window for conveniently testing various settings.

TestingWindow( title: babase.Lstr, entries: list[dict[str, typing.Any]], transition: str | None = 'in_right', origin_widget: _bauiv1.Widget | None = None)
 20    def __init__(
 21        self,
 22        title: bui.Lstr,
 23        entries: list[dict[str, Any]],
 24        transition: str | None = 'in_right',
 25        origin_widget: bui.Widget | None = None,
 26    ):
 27        assert bui.app.classic is not None
 28        uiscale = bui.app.ui_v1.uiscale
 29        self._width = 690 if uiscale is bui.UIScale.SMALL else 600
 30        self._height = 400 if uiscale is bui.UIScale.SMALL else 400
 31        self._entries_orig = copy.deepcopy(entries)
 32        self._entries = copy.deepcopy(entries)
 33        yoffs = -50 if uiscale is bui.UIScale.SMALL else 0
 34
 35        super().__init__(
 36            root_widget=bui.containerwidget(
 37                size=(self._width, self._height),
 38                scale=(
 39                    2.27
 40                    if uiscale is bui.UIScale.SMALL
 41                    else 1.2 if uiscale is bui.UIScale.MEDIUM else 1.0
 42                ),
 43                stack_offset=(
 44                    (0, 0) if uiscale is bui.UIScale.SMALL else (0, 0)
 45                ),
 46                toolbar_visibility=(
 47                    'menu_minimal'
 48                    if uiscale is bui.UIScale.SMALL
 49                    else 'menu_full'
 50                ),
 51            ),
 52            transition=transition,
 53            origin_widget=origin_widget,
 54        )
 55
 56        if uiscale is bui.UIScale.SMALL:
 57            self._back_button = bui.get_special_widget('back_button')
 58            bui.containerwidget(
 59                edit=self._root_widget, on_cancel_call=self.main_window_back
 60            )
 61        else:
 62            self._back_button = btn = bui.buttonwidget(
 63                parent=self._root_widget,
 64                autoselect=True,
 65                position=(65, self._height - 59 + yoffs),
 66                size=(130, 60),
 67                scale=0.8,
 68                text_scale=1.2,
 69                label=bui.Lstr(resource='backText'),
 70                button_type='back',
 71                on_activate_call=self.main_window_back,
 72            )
 73            bui.buttonwidget(
 74                edit=self._back_button,
 75                button_type='backSmall',
 76                size=(60, 60),
 77                label=bui.charstr(bui.SpecialChar.BACK),
 78            )
 79            bui.containerwidget(edit=self._root_widget, cancel_button=btn)
 80
 81        self.title = title
 82        bui.textwidget(
 83            parent=self._root_widget,
 84            position=(
 85                self._width * 0.5,
 86                self._height
 87                - (42 if uiscale is bui.UIScale.SMALL else 35)
 88                + yoffs,
 89            ),
 90            size=(0, 0),
 91            color=bui.app.ui_v1.title_color,
 92            h_align='center',
 93            v_align='center',
 94            maxwidth=245,
 95            text=self.title,
 96        )
 97
 98        bui.textwidget(
 99            parent=self._root_widget,
100            position=(
101                self._width * 0.5,
102                self._height
103                - (80 if uiscale is bui.UIScale.SMALL else 80)
104                + yoffs,
105            ),
106            size=(0, 0),
107            color=bui.app.ui_v1.infotextcolor,
108            h_align='center',
109            v_align='center',
110            maxwidth=self._width * 0.75,
111            text=bui.Lstr(resource='settingsWindowAdvanced.forTestingText'),
112        )
113        self._scroll_width = self._width - 130
114        self._scroll_height = self._height - (
115            220 if uiscale is bui.UIScale.SMALL else 140
116        )
117        self._scrollwidget = bui.scrollwidget(
118            parent=self._root_widget,
119            size=(self._scroll_width, self._scroll_height),
120            highlight=False,
121            position=(
122                (self._width - self._scroll_width) * 0.5,
123                (120 if uiscale is bui.UIScale.SMALL else 40) + yoffs,
124            ),
125        )
126        bui.containerwidget(edit=self._scrollwidget, claims_left_right=True)
127
128        self._spacing = 50
129
130        self._sub_width = self._scroll_width * 0.95
131        self._sub_height = 50 + len(self._entries) * self._spacing + 60
132        self._subcontainer = bui.containerwidget(
133            parent=self._scrollwidget,
134            size=(self._sub_width, self._sub_height),
135            background=False,
136        )
137
138        h = 230
139        v = self._sub_height - 48
140
141        for i, entry in enumerate(self._entries):
142            entry_name = entry['name']
143
144            # If we haven't yet, record the default value for this name so
145            # we can reset if we want..
146            if entry_name not in bui.app.classic.value_test_defaults:
147                bui.app.classic.value_test_defaults[entry_name] = (
148                    bui.app.classic.value_test(entry_name)
149                )
150
151            bui.textwidget(
152                parent=self._subcontainer,
153                position=(h, v),
154                size=(0, 0),
155                h_align='right',
156                v_align='center',
157                maxwidth=200,
158                text=entry['label'],
159            )
160            btn = bui.buttonwidget(
161                parent=self._subcontainer,
162                position=(h + 20, v - 19),
163                size=(40, 40),
164                autoselect=True,
165                repeat=True,
166                left_widget=self._back_button,
167                button_type='square',
168                label='-',
169                on_activate_call=bui.Call(self._on_minus_press, entry['name']),
170            )
171            if i == 0:
172                bui.widget(edit=btn, up_widget=self._back_button)
173            entry['widget'] = bui.textwidget(
174                parent=self._subcontainer,
175                position=(h + 100, v),
176                size=(0, 0),
177                h_align='center',
178                v_align='center',
179                maxwidth=60,
180                text=f'{bui.app.classic.value_test(entry_name):.4g}',
181            )
182            btn = bui.buttonwidget(
183                parent=self._subcontainer,
184                position=(h + 140, v - 19),
185                size=(40, 40),
186                autoselect=True,
187                repeat=True,
188                button_type='square',
189                label='+',
190                on_activate_call=bui.Call(self._on_plus_press, entry['name']),
191            )
192            if i == 0:
193                bui.widget(edit=btn, up_widget=self._back_button)
194            v -= self._spacing
195        v -= 35
196        bui.buttonwidget(
197            parent=self._subcontainer,
198            autoselect=True,
199            size=(200, 50),
200            position=(self._sub_width * 0.5 - 100, v),
201            label=bui.Lstr(resource='settingsWindowAdvanced.resetText'),
202            right_widget=btn,
203            on_activate_call=self._on_reset_press,
204        )

Create a MainWindow given a root widget and transition info.

Automatically handles in and out transitions on the provided widget, so there is no need to set transitions when creating it.

title
@override
def get_main_window_state(self) -> bauiv1.MainWindowState:
244    @override
245    def get_main_window_state(self) -> bui.MainWindowState:
246        # Support recreating our window for back/refresh purposes.
247        cls = type(self)
248
249        # Pull values from self here; if we do it in the lambda we'll keep
250        # self alive which we don't want.
251        title = self.title
252        entries = self._entries_orig
253
254        return bui.BasicMainWindowState(
255            create_call=lambda transition, origin_widget: cls(
256                title=title,
257                entries=entries,
258                transition=transition,
259                origin_widget=origin_widget,
260            )
261        )

Return a WindowState to recreate this window, if supported.