bastd.ui.config

Functionality for editing config values and applying them to the game.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Functionality for editing config values and applying them to the game."""
  4
  5from __future__ import annotations
  6
  7from typing import TYPE_CHECKING
  8
  9import ba
 10
 11if TYPE_CHECKING:
 12    from typing import Any, Callable
 13
 14
 15class ConfigCheckBox:
 16    """A checkbox wired up to control a config value.
 17
 18    It will automatically save and apply the config when its
 19    value changes.
 20    """
 21
 22    widget: ba.Widget
 23    """The underlying ba.Widget instance."""
 24
 25    def __init__(
 26        self,
 27        parent: ba.Widget,
 28        configkey: str,
 29        position: tuple[float, float],
 30        size: tuple[float, float],
 31        displayname: str | ba.Lstr | None = None,
 32        scale: float | None = None,
 33        maxwidth: float | None = None,
 34        autoselect: bool = True,
 35        value_change_call: Callable[[Any], Any] | None = None,
 36    ):
 37        if displayname is None:
 38            displayname = configkey
 39        self._value_change_call = value_change_call
 40        self._configkey = configkey
 41        self.widget = ba.checkboxwidget(
 42            parent=parent,
 43            autoselect=autoselect,
 44            position=position,
 45            size=size,
 46            text=displayname,
 47            textcolor=(0.8, 0.8, 0.8),
 48            value=ba.app.config.resolve(configkey),
 49            on_value_change_call=self._value_changed,
 50            scale=scale,
 51            maxwidth=maxwidth,
 52        )
 53        # complain if we outlive our checkbox
 54        ba.uicleanupcheck(self, self.widget)
 55
 56    def _value_changed(self, val: bool) -> None:
 57        cfg = ba.app.config
 58        cfg[self._configkey] = val
 59        if self._value_change_call is not None:
 60            self._value_change_call(val)
 61        cfg.apply_and_commit()
 62
 63
 64class ConfigNumberEdit:
 65    """A set of controls for editing a numeric config value.
 66
 67    It will automatically save and apply the config when its
 68    value changes.
 69    """
 70
 71    nametext: ba.Widget
 72    """The text widget displaying the name."""
 73
 74    valuetext: ba.Widget
 75    """The text widget displaying the current value."""
 76
 77    minusbutton: ba.Widget
 78    """The button widget used to reduce the value."""
 79
 80    plusbutton: ba.Widget
 81    """The button widget used to increase the value."""
 82
 83    def __init__(
 84        self,
 85        parent: ba.Widget,
 86        configkey: str,
 87        position: tuple[float, float],
 88        minval: float = 0.0,
 89        maxval: float = 100.0,
 90        increment: float = 1.0,
 91        callback: Callable[[float], Any] | None = None,
 92        xoffset: float = 0.0,
 93        displayname: str | ba.Lstr | None = None,
 94        changesound: bool = True,
 95        textscale: float = 1.0,
 96    ):
 97        if displayname is None:
 98            displayname = configkey
 99
100        self._configkey = configkey
101        self._minval = minval
102        self._maxval = maxval
103        self._increment = increment
104        self._callback = callback
105        self._value = ba.app.config.resolve(configkey)
106
107        self.nametext = ba.textwidget(
108            parent=parent,
109            position=position,
110            size=(100, 30),
111            text=displayname,
112            maxwidth=160 + xoffset,
113            color=(0.8, 0.8, 0.8, 1.0),
114            h_align='left',
115            v_align='center',
116            scale=textscale,
117        )
118        self.valuetext = ba.textwidget(
119            parent=parent,
120            position=(246 + xoffset, position[1]),
121            size=(60, 28),
122            editable=False,
123            color=(0.3, 1.0, 0.3, 1.0),
124            h_align='right',
125            v_align='center',
126            text=str(self._value),
127            padding=2,
128        )
129        self.minusbutton = ba.buttonwidget(
130            parent=parent,
131            position=(330 + xoffset, position[1]),
132            size=(28, 28),
133            label='-',
134            autoselect=True,
135            on_activate_call=ba.Call(self._down),
136            repeat=True,
137            enable_sound=changesound,
138        )
139        self.plusbutton = ba.buttonwidget(
140            parent=parent,
141            position=(380 + xoffset, position[1]),
142            size=(28, 28),
143            label='+',
144            autoselect=True,
145            on_activate_call=ba.Call(self._up),
146            repeat=True,
147            enable_sound=changesound,
148        )
149        # Complain if we outlive our widgets.
150        ba.uicleanupcheck(self, self.nametext)
151        self._update_display()
152
153    def _up(self) -> None:
154        self._value = min(self._maxval, self._value + self._increment)
155        self._changed()
156
157    def _down(self) -> None:
158        self._value = max(self._minval, self._value - self._increment)
159        self._changed()
160
161    def _changed(self) -> None:
162        self._update_display()
163        if self._callback:
164            self._callback(self._value)
165        ba.app.config[self._configkey] = self._value
166        ba.app.config.apply_and_commit()
167
168    def _update_display(self) -> None:
169        ba.textwidget(edit=self.valuetext, text=f'{self._value:.1f}')
class ConfigCheckBox:
16class ConfigCheckBox:
17    """A checkbox wired up to control a config value.
18
19    It will automatically save and apply the config when its
20    value changes.
21    """
22
23    widget: ba.Widget
24    """The underlying ba.Widget instance."""
25
26    def __init__(
27        self,
28        parent: ba.Widget,
29        configkey: str,
30        position: tuple[float, float],
31        size: tuple[float, float],
32        displayname: str | ba.Lstr | None = None,
33        scale: float | None = None,
34        maxwidth: float | None = None,
35        autoselect: bool = True,
36        value_change_call: Callable[[Any], Any] | None = None,
37    ):
38        if displayname is None:
39            displayname = configkey
40        self._value_change_call = value_change_call
41        self._configkey = configkey
42        self.widget = ba.checkboxwidget(
43            parent=parent,
44            autoselect=autoselect,
45            position=position,
46            size=size,
47            text=displayname,
48            textcolor=(0.8, 0.8, 0.8),
49            value=ba.app.config.resolve(configkey),
50            on_value_change_call=self._value_changed,
51            scale=scale,
52            maxwidth=maxwidth,
53        )
54        # complain if we outlive our checkbox
55        ba.uicleanupcheck(self, self.widget)
56
57    def _value_changed(self, val: bool) -> None:
58        cfg = ba.app.config
59        cfg[self._configkey] = val
60        if self._value_change_call is not None:
61            self._value_change_call(val)
62        cfg.apply_and_commit()

A checkbox wired up to control a config value.

It will automatically save and apply the config when its value changes.

ConfigCheckBox( parent: _ba.Widget, configkey: str, position: tuple[float, float], size: tuple[float, float], displayname: str | ba._language.Lstr | None = None, scale: float | None = None, maxwidth: float | None = None, autoselect: bool = True, value_change_call: Optional[Callable[[Any], Any]] = None)
26    def __init__(
27        self,
28        parent: ba.Widget,
29        configkey: str,
30        position: tuple[float, float],
31        size: tuple[float, float],
32        displayname: str | ba.Lstr | None = None,
33        scale: float | None = None,
34        maxwidth: float | None = None,
35        autoselect: bool = True,
36        value_change_call: Callable[[Any], Any] | None = None,
37    ):
38        if displayname is None:
39            displayname = configkey
40        self._value_change_call = value_change_call
41        self._configkey = configkey
42        self.widget = ba.checkboxwidget(
43            parent=parent,
44            autoselect=autoselect,
45            position=position,
46            size=size,
47            text=displayname,
48            textcolor=(0.8, 0.8, 0.8),
49            value=ba.app.config.resolve(configkey),
50            on_value_change_call=self._value_changed,
51            scale=scale,
52            maxwidth=maxwidth,
53        )
54        # complain if we outlive our checkbox
55        ba.uicleanupcheck(self, self.widget)
widget: _ba.Widget

The underlying ba.Widget instance.

class ConfigNumberEdit:
 65class ConfigNumberEdit:
 66    """A set of controls for editing a numeric config value.
 67
 68    It will automatically save and apply the config when its
 69    value changes.
 70    """
 71
 72    nametext: ba.Widget
 73    """The text widget displaying the name."""
 74
 75    valuetext: ba.Widget
 76    """The text widget displaying the current value."""
 77
 78    minusbutton: ba.Widget
 79    """The button widget used to reduce the value."""
 80
 81    plusbutton: ba.Widget
 82    """The button widget used to increase the value."""
 83
 84    def __init__(
 85        self,
 86        parent: ba.Widget,
 87        configkey: str,
 88        position: tuple[float, float],
 89        minval: float = 0.0,
 90        maxval: float = 100.0,
 91        increment: float = 1.0,
 92        callback: Callable[[float], Any] | None = None,
 93        xoffset: float = 0.0,
 94        displayname: str | ba.Lstr | None = None,
 95        changesound: bool = True,
 96        textscale: float = 1.0,
 97    ):
 98        if displayname is None:
 99            displayname = configkey
100
101        self._configkey = configkey
102        self._minval = minval
103        self._maxval = maxval
104        self._increment = increment
105        self._callback = callback
106        self._value = ba.app.config.resolve(configkey)
107
108        self.nametext = ba.textwidget(
109            parent=parent,
110            position=position,
111            size=(100, 30),
112            text=displayname,
113            maxwidth=160 + xoffset,
114            color=(0.8, 0.8, 0.8, 1.0),
115            h_align='left',
116            v_align='center',
117            scale=textscale,
118        )
119        self.valuetext = ba.textwidget(
120            parent=parent,
121            position=(246 + xoffset, position[1]),
122            size=(60, 28),
123            editable=False,
124            color=(0.3, 1.0, 0.3, 1.0),
125            h_align='right',
126            v_align='center',
127            text=str(self._value),
128            padding=2,
129        )
130        self.minusbutton = ba.buttonwidget(
131            parent=parent,
132            position=(330 + xoffset, position[1]),
133            size=(28, 28),
134            label='-',
135            autoselect=True,
136            on_activate_call=ba.Call(self._down),
137            repeat=True,
138            enable_sound=changesound,
139        )
140        self.plusbutton = ba.buttonwidget(
141            parent=parent,
142            position=(380 + xoffset, position[1]),
143            size=(28, 28),
144            label='+',
145            autoselect=True,
146            on_activate_call=ba.Call(self._up),
147            repeat=True,
148            enable_sound=changesound,
149        )
150        # Complain if we outlive our widgets.
151        ba.uicleanupcheck(self, self.nametext)
152        self._update_display()
153
154    def _up(self) -> None:
155        self._value = min(self._maxval, self._value + self._increment)
156        self._changed()
157
158    def _down(self) -> None:
159        self._value = max(self._minval, self._value - self._increment)
160        self._changed()
161
162    def _changed(self) -> None:
163        self._update_display()
164        if self._callback:
165            self._callback(self._value)
166        ba.app.config[self._configkey] = self._value
167        ba.app.config.apply_and_commit()
168
169    def _update_display(self) -> None:
170        ba.textwidget(edit=self.valuetext, text=f'{self._value:.1f}')

A set of controls for editing a numeric config value.

It will automatically save and apply the config when its value changes.

ConfigNumberEdit( parent: _ba.Widget, configkey: str, position: tuple[float, float], minval: float = 0.0, maxval: float = 100.0, increment: float = 1.0, callback: Optional[Callable[[float], Any]] = None, xoffset: float = 0.0, displayname: str | ba._language.Lstr | None = None, changesound: bool = True, textscale: float = 1.0)
 84    def __init__(
 85        self,
 86        parent: ba.Widget,
 87        configkey: str,
 88        position: tuple[float, float],
 89        minval: float = 0.0,
 90        maxval: float = 100.0,
 91        increment: float = 1.0,
 92        callback: Callable[[float], Any] | None = None,
 93        xoffset: float = 0.0,
 94        displayname: str | ba.Lstr | None = None,
 95        changesound: bool = True,
 96        textscale: float = 1.0,
 97    ):
 98        if displayname is None:
 99            displayname = configkey
100
101        self._configkey = configkey
102        self._minval = minval
103        self._maxval = maxval
104        self._increment = increment
105        self._callback = callback
106        self._value = ba.app.config.resolve(configkey)
107
108        self.nametext = ba.textwidget(
109            parent=parent,
110            position=position,
111            size=(100, 30),
112            text=displayname,
113            maxwidth=160 + xoffset,
114            color=(0.8, 0.8, 0.8, 1.0),
115            h_align='left',
116            v_align='center',
117            scale=textscale,
118        )
119        self.valuetext = ba.textwidget(
120            parent=parent,
121            position=(246 + xoffset, position[1]),
122            size=(60, 28),
123            editable=False,
124            color=(0.3, 1.0, 0.3, 1.0),
125            h_align='right',
126            v_align='center',
127            text=str(self._value),
128            padding=2,
129        )
130        self.minusbutton = ba.buttonwidget(
131            parent=parent,
132            position=(330 + xoffset, position[1]),
133            size=(28, 28),
134            label='-',
135            autoselect=True,
136            on_activate_call=ba.Call(self._down),
137            repeat=True,
138            enable_sound=changesound,
139        )
140        self.plusbutton = ba.buttonwidget(
141            parent=parent,
142            position=(380 + xoffset, position[1]),
143            size=(28, 28),
144            label='+',
145            autoselect=True,
146            on_activate_call=ba.Call(self._up),
147            repeat=True,
148            enable_sound=changesound,
149        )
150        # Complain if we outlive our widgets.
151        ba.uicleanupcheck(self, self.nametext)
152        self._update_display()
nametext: _ba.Widget

The text widget displaying the name.

valuetext: _ba.Widget

The text widget displaying the current value.

minusbutton: _ba.Widget

The button widget used to reduce the value.

plusbutton: _ba.Widget

The button widget used to increase the value.