bauiv1lib.settings.touchscreen

UI settings functionality related to touchscreens.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""UI settings functionality related to touchscreens."""
  4from __future__ import annotations
  5
  6from typing import override
  7
  8import bauiv1 as bui
  9import bascenev1 as bs
 10
 11
 12class TouchscreenSettingsWindow(bui.MainWindow):
 13    """Settings window for touchscreens."""
 14
 15    def __del__(self) -> None:
 16        # Note - this happens in 'back' too;
 17        # we just do it here too in case the window is closed by other means.
 18
 19        # FIXME: Could switch to a UI destroy callback now that those are a
 20        #  thing that exists.
 21        bs.set_touchscreen_editing(False)
 22
 23    def __init__(
 24        self,
 25        transition: str | None = 'in_right',
 26        origin_widget: bui.Widget | None = None,
 27    ) -> None:
 28        self._width = 650
 29        self._height = 380
 30        self._spacing = 40
 31        self._r = 'configTouchscreenWindow'
 32
 33        bs.set_touchscreen_editing(True)
 34
 35        assert bui.app.classic is not None
 36        uiscale = bui.app.ui_v1.uiscale
 37        super().__init__(
 38            root_widget=bui.containerwidget(
 39                size=(self._width, self._height),
 40                scale=(
 41                    1.9
 42                    if uiscale is bui.UIScale.SMALL
 43                    else 1.55 if uiscale is bui.UIScale.MEDIUM else 1.2
 44                ),
 45            ),
 46            transition=transition,
 47            origin_widget=origin_widget,
 48        )
 49
 50        btn = bui.buttonwidget(
 51            parent=self._root_widget,
 52            position=(55, self._height - 60),
 53            size=(120, 60),
 54            label=bui.Lstr(resource='backText'),
 55            button_type='back',
 56            scale=0.8,
 57            on_activate_call=self._back,
 58        )
 59        bui.containerwidget(edit=self._root_widget, cancel_button=btn)
 60
 61        bui.textwidget(
 62            parent=self._root_widget,
 63            position=(25, self._height - 50),
 64            size=(self._width, 25),
 65            text=bui.Lstr(resource=f'{self._r}.titleText'),
 66            color=bui.app.ui_v1.title_color,
 67            maxwidth=280,
 68            h_align='center',
 69            v_align='center',
 70        )
 71
 72        bui.buttonwidget(
 73            edit=btn,
 74            button_type='backSmall',
 75            size=(60, 60),
 76            label=bui.charstr(bui.SpecialChar.BACK),
 77        )
 78
 79        self._scroll_width = self._width - 100
 80        self._scroll_height = self._height - 110
 81        self._sub_width = self._scroll_width - 20
 82        self._sub_height = 360
 83
 84        self._scrollwidget = bui.scrollwidget(
 85            parent=self._root_widget,
 86            position=(
 87                (self._width - self._scroll_width) * 0.5,
 88                self._height - 65 - self._scroll_height,
 89            ),
 90            size=(self._scroll_width, self._scroll_height),
 91            claims_left_right=True,
 92            claims_tab=True,
 93            selection_loops_to_parent=True,
 94        )
 95        self._subcontainer = bui.containerwidget(
 96            parent=self._scrollwidget,
 97            size=(self._sub_width, self._sub_height),
 98            background=False,
 99            claims_left_right=True,
100            claims_tab=True,
101            selection_loops_to_parent=True,
102        )
103        self._build_gui()
104
105    @override
106    def get_main_window_state(self) -> bui.MainWindowState:
107        # Support recreating our window for back/refresh purposes.
108        cls = type(self)
109        return bui.BasicMainWindowState(
110            create_call=lambda transition, origin_widget: cls(
111                transition=transition, origin_widget=origin_widget
112            )
113        )
114
115    def _build_gui(self) -> None:
116        from bauiv1lib.config import ConfigNumberEdit, ConfigCheckBox
117        from bauiv1lib.radiogroup import make_radio_group
118
119        # Clear anything already there.
120        children = self._subcontainer.get_children()
121        for child in children:
122            child.delete()
123        h = 30
124        v = self._sub_height - 85
125        clr = (0.8, 0.8, 0.8, 1.0)
126        clr2 = (0.8, 0.8, 0.8)
127        bui.textwidget(
128            parent=self._subcontainer,
129            position=(-10, v + 43),
130            size=(self._sub_width, 25),
131            text=bui.Lstr(resource=f'{self._r}.swipeInfoText'),
132            flatness=1.0,
133            color=(0, 0.9, 0.1, 0.7),
134            maxwidth=self._sub_width * 0.9,
135            scale=0.55,
136            h_align='center',
137            v_align='center',
138        )
139        cur_val = bui.app.config.get('Touch Movement Control Type', 'swipe')
140        bui.textwidget(
141            parent=self._subcontainer,
142            position=(h, v - 2),
143            size=(0, 30),
144            text=bui.Lstr(resource=f'{self._r}.movementText'),
145            maxwidth=190,
146            color=clr,
147            v_align='center',
148        )
149        cb1 = bui.checkboxwidget(
150            parent=self._subcontainer,
151            position=(h + 220, v),
152            size=(170, 30),
153            text=bui.Lstr(resource=f'{self._r}.joystickText'),
154            maxwidth=100,
155            textcolor=clr2,
156            scale=0.9,
157        )
158        cb2 = bui.checkboxwidget(
159            parent=self._subcontainer,
160            position=(h + 357, v),
161            size=(170, 30),
162            text=bui.Lstr(resource=f'{self._r}.swipeText'),
163            maxwidth=100,
164            textcolor=clr2,
165            value=False,
166            scale=0.9,
167        )
168        make_radio_group(
169            (cb1, cb2), ('joystick', 'swipe'), cur_val, self._movement_changed
170        )
171        v -= 50
172        ConfigNumberEdit(
173            parent=self._subcontainer,
174            position=(h, v),
175            xoffset=65,
176            configkey='Touch Controls Scale Movement',
177            displayname=bui.Lstr(
178                resource=f'{self._r}.movementControlScaleText'
179            ),
180            changesound=False,
181            minval=0.1,
182            maxval=4.0,
183            increment=0.1,
184        )
185        v -= 50
186        cur_val = bui.app.config.get('Touch Action Control Type', 'buttons')
187        bui.textwidget(
188            parent=self._subcontainer,
189            position=(h, v - 2),
190            size=(0, 30),
191            text=bui.Lstr(resource=f'{self._r}.actionsText'),
192            maxwidth=190,
193            color=clr,
194            v_align='center',
195        )
196        cb1 = bui.checkboxwidget(
197            parent=self._subcontainer,
198            position=(h + 220, v),
199            size=(170, 30),
200            text=bui.Lstr(resource=f'{self._r}.buttonsText'),
201            maxwidth=100,
202            textcolor=clr2,
203            scale=0.9,
204        )
205        cb2 = bui.checkboxwidget(
206            parent=self._subcontainer,
207            position=(h + 357, v),
208            size=(170, 30),
209            text=bui.Lstr(resource=f'{self._r}.swipeText'),
210            maxwidth=100,
211            textcolor=clr2,
212            scale=0.9,
213        )
214        make_radio_group(
215            (cb1, cb2), ('buttons', 'swipe'), cur_val, self._actions_changed
216        )
217        v -= 50
218        ConfigNumberEdit(
219            parent=self._subcontainer,
220            position=(h, v),
221            xoffset=65,
222            configkey='Touch Controls Scale Actions',
223            displayname=bui.Lstr(resource=f'{self._r}.actionControlScaleText'),
224            changesound=False,
225            minval=0.1,
226            maxval=4.0,
227            increment=0.1,
228        )
229
230        v -= 50
231        ConfigCheckBox(
232            parent=self._subcontainer,
233            position=(h, v),
234            size=(400, 30),
235            maxwidth=400,
236            configkey='Touch Controls Swipe Hidden',
237            displayname=bui.Lstr(resource=f'{self._r}.swipeControlsHiddenText'),
238        )
239        v -= 65
240
241        bui.buttonwidget(
242            parent=self._subcontainer,
243            position=(self._sub_width * 0.5 - 70, v),
244            size=(170, 60),
245            label=bui.Lstr(resource=f'{self._r}.resetText'),
246            scale=0.75,
247            on_activate_call=self._reset,
248        )
249
250        bui.textwidget(
251            parent=self._root_widget,
252            position=(self._width * 0.5, 38),
253            size=(0, 0),
254            h_align='center',
255            text=bui.Lstr(resource=f'{self._r}.dragControlsText'),
256            maxwidth=self._width * 0.8,
257            scale=0.65,
258            color=(1, 1, 1, 0.4),
259        )
260
261    def _actions_changed(self, v: str) -> None:
262        cfg = bui.app.config
263        cfg['Touch Action Control Type'] = v
264        cfg.apply_and_commit()
265
266    def _movement_changed(self, v: str) -> None:
267        cfg = bui.app.config
268        cfg['Touch Movement Control Type'] = v
269        cfg.apply_and_commit()
270
271    def _reset(self) -> None:
272        cfg = bui.app.config
273        cfgkeys = [
274            'Touch Movement Control Type',
275            'Touch Action Control Type',
276            'Touch Controls Scale',
277            'Touch Controls Scale Movement',
278            'Touch Controls Scale Actions',
279            'Touch Controls Swipe Hidden',
280            'Touch DPad X',
281            'Touch DPad Y',
282            'Touch Buttons X',
283            'Touch Buttons Y',
284        ]
285        for cfgkey in cfgkeys:
286            if cfgkey in cfg:
287                del cfg[cfgkey]
288        cfg.apply_and_commit()
289        bui.apptimer(0, self._build_gui)
290
291    def _back(self) -> None:
292        from bauiv1lib.settings import controls
293
294        # no-op if our underlying widget is dead or on its way out.
295        if not self._root_widget or self._root_widget.transitioning_out:
296            return
297
298        bui.containerwidget(edit=self._root_widget, transition='out_right')
299        assert bui.app.classic is not None
300        bui.app.ui_v1.set_main_window(
301            controls.ControlsSettingsWindow(transition='in_left'),
302            from_window=self,
303            is_back=True,
304        )
305        bs.set_touchscreen_editing(False)
class TouchscreenSettingsWindow(bauiv1._uitypes.MainWindow):
 13class TouchscreenSettingsWindow(bui.MainWindow):
 14    """Settings window for touchscreens."""
 15
 16    def __del__(self) -> None:
 17        # Note - this happens in 'back' too;
 18        # we just do it here too in case the window is closed by other means.
 19
 20        # FIXME: Could switch to a UI destroy callback now that those are a
 21        #  thing that exists.
 22        bs.set_touchscreen_editing(False)
 23
 24    def __init__(
 25        self,
 26        transition: str | None = 'in_right',
 27        origin_widget: bui.Widget | None = None,
 28    ) -> None:
 29        self._width = 650
 30        self._height = 380
 31        self._spacing = 40
 32        self._r = 'configTouchscreenWindow'
 33
 34        bs.set_touchscreen_editing(True)
 35
 36        assert bui.app.classic is not None
 37        uiscale = bui.app.ui_v1.uiscale
 38        super().__init__(
 39            root_widget=bui.containerwidget(
 40                size=(self._width, self._height),
 41                scale=(
 42                    1.9
 43                    if uiscale is bui.UIScale.SMALL
 44                    else 1.55 if uiscale is bui.UIScale.MEDIUM else 1.2
 45                ),
 46            ),
 47            transition=transition,
 48            origin_widget=origin_widget,
 49        )
 50
 51        btn = bui.buttonwidget(
 52            parent=self._root_widget,
 53            position=(55, self._height - 60),
 54            size=(120, 60),
 55            label=bui.Lstr(resource='backText'),
 56            button_type='back',
 57            scale=0.8,
 58            on_activate_call=self._back,
 59        )
 60        bui.containerwidget(edit=self._root_widget, cancel_button=btn)
 61
 62        bui.textwidget(
 63            parent=self._root_widget,
 64            position=(25, self._height - 50),
 65            size=(self._width, 25),
 66            text=bui.Lstr(resource=f'{self._r}.titleText'),
 67            color=bui.app.ui_v1.title_color,
 68            maxwidth=280,
 69            h_align='center',
 70            v_align='center',
 71        )
 72
 73        bui.buttonwidget(
 74            edit=btn,
 75            button_type='backSmall',
 76            size=(60, 60),
 77            label=bui.charstr(bui.SpecialChar.BACK),
 78        )
 79
 80        self._scroll_width = self._width - 100
 81        self._scroll_height = self._height - 110
 82        self._sub_width = self._scroll_width - 20
 83        self._sub_height = 360
 84
 85        self._scrollwidget = bui.scrollwidget(
 86            parent=self._root_widget,
 87            position=(
 88                (self._width - self._scroll_width) * 0.5,
 89                self._height - 65 - self._scroll_height,
 90            ),
 91            size=(self._scroll_width, self._scroll_height),
 92            claims_left_right=True,
 93            claims_tab=True,
 94            selection_loops_to_parent=True,
 95        )
 96        self._subcontainer = bui.containerwidget(
 97            parent=self._scrollwidget,
 98            size=(self._sub_width, self._sub_height),
 99            background=False,
100            claims_left_right=True,
101            claims_tab=True,
102            selection_loops_to_parent=True,
103        )
104        self._build_gui()
105
106    @override
107    def get_main_window_state(self) -> bui.MainWindowState:
108        # Support recreating our window for back/refresh purposes.
109        cls = type(self)
110        return bui.BasicMainWindowState(
111            create_call=lambda transition, origin_widget: cls(
112                transition=transition, origin_widget=origin_widget
113            )
114        )
115
116    def _build_gui(self) -> None:
117        from bauiv1lib.config import ConfigNumberEdit, ConfigCheckBox
118        from bauiv1lib.radiogroup import make_radio_group
119
120        # Clear anything already there.
121        children = self._subcontainer.get_children()
122        for child in children:
123            child.delete()
124        h = 30
125        v = self._sub_height - 85
126        clr = (0.8, 0.8, 0.8, 1.0)
127        clr2 = (0.8, 0.8, 0.8)
128        bui.textwidget(
129            parent=self._subcontainer,
130            position=(-10, v + 43),
131            size=(self._sub_width, 25),
132            text=bui.Lstr(resource=f'{self._r}.swipeInfoText'),
133            flatness=1.0,
134            color=(0, 0.9, 0.1, 0.7),
135            maxwidth=self._sub_width * 0.9,
136            scale=0.55,
137            h_align='center',
138            v_align='center',
139        )
140        cur_val = bui.app.config.get('Touch Movement Control Type', 'swipe')
141        bui.textwidget(
142            parent=self._subcontainer,
143            position=(h, v - 2),
144            size=(0, 30),
145            text=bui.Lstr(resource=f'{self._r}.movementText'),
146            maxwidth=190,
147            color=clr,
148            v_align='center',
149        )
150        cb1 = bui.checkboxwidget(
151            parent=self._subcontainer,
152            position=(h + 220, v),
153            size=(170, 30),
154            text=bui.Lstr(resource=f'{self._r}.joystickText'),
155            maxwidth=100,
156            textcolor=clr2,
157            scale=0.9,
158        )
159        cb2 = bui.checkboxwidget(
160            parent=self._subcontainer,
161            position=(h + 357, v),
162            size=(170, 30),
163            text=bui.Lstr(resource=f'{self._r}.swipeText'),
164            maxwidth=100,
165            textcolor=clr2,
166            value=False,
167            scale=0.9,
168        )
169        make_radio_group(
170            (cb1, cb2), ('joystick', 'swipe'), cur_val, self._movement_changed
171        )
172        v -= 50
173        ConfigNumberEdit(
174            parent=self._subcontainer,
175            position=(h, v),
176            xoffset=65,
177            configkey='Touch Controls Scale Movement',
178            displayname=bui.Lstr(
179                resource=f'{self._r}.movementControlScaleText'
180            ),
181            changesound=False,
182            minval=0.1,
183            maxval=4.0,
184            increment=0.1,
185        )
186        v -= 50
187        cur_val = bui.app.config.get('Touch Action Control Type', 'buttons')
188        bui.textwidget(
189            parent=self._subcontainer,
190            position=(h, v - 2),
191            size=(0, 30),
192            text=bui.Lstr(resource=f'{self._r}.actionsText'),
193            maxwidth=190,
194            color=clr,
195            v_align='center',
196        )
197        cb1 = bui.checkboxwidget(
198            parent=self._subcontainer,
199            position=(h + 220, v),
200            size=(170, 30),
201            text=bui.Lstr(resource=f'{self._r}.buttonsText'),
202            maxwidth=100,
203            textcolor=clr2,
204            scale=0.9,
205        )
206        cb2 = bui.checkboxwidget(
207            parent=self._subcontainer,
208            position=(h + 357, v),
209            size=(170, 30),
210            text=bui.Lstr(resource=f'{self._r}.swipeText'),
211            maxwidth=100,
212            textcolor=clr2,
213            scale=0.9,
214        )
215        make_radio_group(
216            (cb1, cb2), ('buttons', 'swipe'), cur_val, self._actions_changed
217        )
218        v -= 50
219        ConfigNumberEdit(
220            parent=self._subcontainer,
221            position=(h, v),
222            xoffset=65,
223            configkey='Touch Controls Scale Actions',
224            displayname=bui.Lstr(resource=f'{self._r}.actionControlScaleText'),
225            changesound=False,
226            minval=0.1,
227            maxval=4.0,
228            increment=0.1,
229        )
230
231        v -= 50
232        ConfigCheckBox(
233            parent=self._subcontainer,
234            position=(h, v),
235            size=(400, 30),
236            maxwidth=400,
237            configkey='Touch Controls Swipe Hidden',
238            displayname=bui.Lstr(resource=f'{self._r}.swipeControlsHiddenText'),
239        )
240        v -= 65
241
242        bui.buttonwidget(
243            parent=self._subcontainer,
244            position=(self._sub_width * 0.5 - 70, v),
245            size=(170, 60),
246            label=bui.Lstr(resource=f'{self._r}.resetText'),
247            scale=0.75,
248            on_activate_call=self._reset,
249        )
250
251        bui.textwidget(
252            parent=self._root_widget,
253            position=(self._width * 0.5, 38),
254            size=(0, 0),
255            h_align='center',
256            text=bui.Lstr(resource=f'{self._r}.dragControlsText'),
257            maxwidth=self._width * 0.8,
258            scale=0.65,
259            color=(1, 1, 1, 0.4),
260        )
261
262    def _actions_changed(self, v: str) -> None:
263        cfg = bui.app.config
264        cfg['Touch Action Control Type'] = v
265        cfg.apply_and_commit()
266
267    def _movement_changed(self, v: str) -> None:
268        cfg = bui.app.config
269        cfg['Touch Movement Control Type'] = v
270        cfg.apply_and_commit()
271
272    def _reset(self) -> None:
273        cfg = bui.app.config
274        cfgkeys = [
275            'Touch Movement Control Type',
276            'Touch Action Control Type',
277            'Touch Controls Scale',
278            'Touch Controls Scale Movement',
279            'Touch Controls Scale Actions',
280            'Touch Controls Swipe Hidden',
281            'Touch DPad X',
282            'Touch DPad Y',
283            'Touch Buttons X',
284            'Touch Buttons Y',
285        ]
286        for cfgkey in cfgkeys:
287            if cfgkey in cfg:
288                del cfg[cfgkey]
289        cfg.apply_and_commit()
290        bui.apptimer(0, self._build_gui)
291
292    def _back(self) -> None:
293        from bauiv1lib.settings import controls
294
295        # no-op if our underlying widget is dead or on its way out.
296        if not self._root_widget or self._root_widget.transitioning_out:
297            return
298
299        bui.containerwidget(edit=self._root_widget, transition='out_right')
300        assert bui.app.classic is not None
301        bui.app.ui_v1.set_main_window(
302            controls.ControlsSettingsWindow(transition='in_left'),
303            from_window=self,
304            is_back=True,
305        )
306        bs.set_touchscreen_editing(False)

Settings window for touchscreens.

TouchscreenSettingsWindow( transition: str | None = 'in_right', origin_widget: _bauiv1.Widget | None = None)
 24    def __init__(
 25        self,
 26        transition: str | None = 'in_right',
 27        origin_widget: bui.Widget | None = None,
 28    ) -> None:
 29        self._width = 650
 30        self._height = 380
 31        self._spacing = 40
 32        self._r = 'configTouchscreenWindow'
 33
 34        bs.set_touchscreen_editing(True)
 35
 36        assert bui.app.classic is not None
 37        uiscale = bui.app.ui_v1.uiscale
 38        super().__init__(
 39            root_widget=bui.containerwidget(
 40                size=(self._width, self._height),
 41                scale=(
 42                    1.9
 43                    if uiscale is bui.UIScale.SMALL
 44                    else 1.55 if uiscale is bui.UIScale.MEDIUM else 1.2
 45                ),
 46            ),
 47            transition=transition,
 48            origin_widget=origin_widget,
 49        )
 50
 51        btn = bui.buttonwidget(
 52            parent=self._root_widget,
 53            position=(55, self._height - 60),
 54            size=(120, 60),
 55            label=bui.Lstr(resource='backText'),
 56            button_type='back',
 57            scale=0.8,
 58            on_activate_call=self._back,
 59        )
 60        bui.containerwidget(edit=self._root_widget, cancel_button=btn)
 61
 62        bui.textwidget(
 63            parent=self._root_widget,
 64            position=(25, self._height - 50),
 65            size=(self._width, 25),
 66            text=bui.Lstr(resource=f'{self._r}.titleText'),
 67            color=bui.app.ui_v1.title_color,
 68            maxwidth=280,
 69            h_align='center',
 70            v_align='center',
 71        )
 72
 73        bui.buttonwidget(
 74            edit=btn,
 75            button_type='backSmall',
 76            size=(60, 60),
 77            label=bui.charstr(bui.SpecialChar.BACK),
 78        )
 79
 80        self._scroll_width = self._width - 100
 81        self._scroll_height = self._height - 110
 82        self._sub_width = self._scroll_width - 20
 83        self._sub_height = 360
 84
 85        self._scrollwidget = bui.scrollwidget(
 86            parent=self._root_widget,
 87            position=(
 88                (self._width - self._scroll_width) * 0.5,
 89                self._height - 65 - self._scroll_height,
 90            ),
 91            size=(self._scroll_width, self._scroll_height),
 92            claims_left_right=True,
 93            claims_tab=True,
 94            selection_loops_to_parent=True,
 95        )
 96        self._subcontainer = bui.containerwidget(
 97            parent=self._scrollwidget,
 98            size=(self._sub_width, self._sub_height),
 99            background=False,
100            claims_left_right=True,
101            claims_tab=True,
102            selection_loops_to_parent=True,
103        )
104        self._build_gui()

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.

@override
def get_main_window_state(self) -> bauiv1.MainWindowState:
106    @override
107    def get_main_window_state(self) -> bui.MainWindowState:
108        # Support recreating our window for back/refresh purposes.
109        cls = type(self)
110        return bui.BasicMainWindowState(
111            create_call=lambda transition, origin_widget: cls(
112                transition=transition, origin_widget=origin_widget
113            )
114        )

Return a WindowState to recreate this window, if supported.

Inherited Members
bauiv1._uitypes.MainWindow
main_window_back_state
main_window_close
can_change_main_window
main_window_back
main_window_replace
on_main_window_close
bauiv1._uitypes.Window
get_root_widget