bauiv1lib.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 bauiv1 as bui
 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: bui.Widget
 23    """The underlying bui.Widget instance."""
 24
 25    def __init__(
 26        self,
 27        parent: bui.Widget,
 28        configkey: str,
 29        position: tuple[float, float],
 30        size: tuple[float, float],
 31        *,
 32        displayname: str | bui.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 = bui.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=bui.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        bui.uicleanupcheck(self, self.widget)
 56
 57    def _value_changed(self, val: bool) -> None:
 58        cfg = bui.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()
 63
 64
 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: bui.Widget
 73    """The text widget displaying the name."""
 74
 75    valuetext: bui.Widget
 76    """The text widget displaying the current value."""
 77
 78    minusbutton: bui.Widget
 79    """The button widget used to reduce the value."""
 80
 81    plusbutton: bui.Widget
 82    """The button widget used to increase the value."""
 83
 84    def __init__(
 85        self,
 86        parent: bui.Widget,
 87        configkey: str,
 88        position: tuple[float, float],
 89        *,
 90        minval: float = 0.0,
 91        maxval: float = 100.0,
 92        increment: float = 1.0,
 93        callback: Callable[[float], Any] | None = None,
 94        xoffset: float = 0.0,
 95        displayname: str | bui.Lstr | None = None,
 96        changesound: bool = True,
 97        textscale: float = 1.0,
 98        as_percent: bool = False,
 99        fallback_value: float = 0.0,
100        f: int = 1,
101    ):
102        if displayname is None:
103            displayname = configkey
104
105        self._configkey = configkey
106        self._minval = minval
107        self._maxval = maxval
108        self._increment = increment
109        self._callback = callback
110        try:
111            self._value = bui.app.config.resolve(configkey)
112        except ValueError:
113            self._value = bui.app.config.get(configkey, fallback_value)
114        self._value = (
115            self._minval
116            if self._minval > self._value
117            else self._maxval if self._maxval < self._value else self._value
118        )
119        self._as_percent = as_percent
120        self._f = f
121
122        self.nametext = bui.textwidget(
123            parent=parent,
124            position=(position[0], position[1] + 12.0),
125            size=(0, 0),
126            text=displayname,
127            maxwidth=150 + xoffset,
128            color=(0.8, 0.8, 0.8, 1.0),
129            h_align='left',
130            v_align='center',
131            scale=textscale,
132        )
133        self.valuetext = bui.textwidget(
134            parent=parent,
135            position=(position[0] + 216 + xoffset, position[1] + 12.0),
136            size=(0, 0),
137            editable=False,
138            color=(0.3, 1.0, 0.3, 1.0),
139            h_align='right',
140            v_align='center',
141            text=str(self._value),
142            padding=2,
143        )
144        self.minusbutton = bui.buttonwidget(
145            parent=parent,
146            position=(position[0] + 230 + xoffset, position[1]),
147            size=(28, 28),
148            label='-',
149            autoselect=True,
150            on_activate_call=bui.Call(self._down),
151            repeat=True,
152            enable_sound=changesound,
153        )
154        self.plusbutton = bui.buttonwidget(
155            parent=parent,
156            position=(position[0] + 280 + xoffset, position[1]),
157            size=(28, 28),
158            label='+',
159            autoselect=True,
160            on_activate_call=bui.Call(self._up),
161            repeat=True,
162            enable_sound=changesound,
163        )
164        # Complain if we outlive our widgets.
165        bui.uicleanupcheck(self, self.nametext)
166        self._update_display()
167
168    def _up(self) -> None:
169        self._value = min(self._maxval, self._value + self._increment)
170        self._changed()
171
172    def _down(self) -> None:
173        self._value = max(self._minval, self._value - self._increment)
174        self._changed()
175
176    def _changed(self) -> None:
177        self._update_display()
178        if self._callback:
179            self._callback(self._value)
180        bui.app.config[self._configkey] = self._value
181        bui.app.config.apply_and_commit()
182
183    def _update_display(self) -> None:
184        if self._as_percent:
185            val = f'{round(self._value*100.0)}%'
186        else:
187            val = f'{self._value:.{self._f}f}'
188        bui.textwidget(edit=self.valuetext, text=val)
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: bui.Widget
24    """The underlying bui.Widget instance."""
25
26    def __init__(
27        self,
28        parent: bui.Widget,
29        configkey: str,
30        position: tuple[float, float],
31        size: tuple[float, float],
32        *,
33        displayname: str | bui.Lstr | None = None,
34        scale: float | None = None,
35        maxwidth: float | None = None,
36        autoselect: bool = True,
37        value_change_call: Callable[[Any], Any] | None = None,
38    ):
39        if displayname is None:
40            displayname = configkey
41        self._value_change_call = value_change_call
42        self._configkey = configkey
43        self.widget = bui.checkboxwidget(
44            parent=parent,
45            autoselect=autoselect,
46            position=position,
47            size=size,
48            text=displayname,
49            textcolor=(0.8, 0.8, 0.8),
50            value=bui.app.config.resolve(configkey),
51            on_value_change_call=self._value_changed,
52            scale=scale,
53            maxwidth=maxwidth,
54        )
55        # complain if we outlive our checkbox
56        bui.uicleanupcheck(self, self.widget)
57
58    def _value_changed(self, val: bool) -> None:
59        cfg = bui.app.config
60        cfg[self._configkey] = val
61        if self._value_change_call is not None:
62            self._value_change_call(val)
63        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: _bauiv1.Widget, configkey: str, position: tuple[float, float], size: tuple[float, float], *, displayname: str | babase.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: bui.Widget,
29        configkey: str,
30        position: tuple[float, float],
31        size: tuple[float, float],
32        *,
33        displayname: str | bui.Lstr | None = None,
34        scale: float | None = None,
35        maxwidth: float | None = None,
36        autoselect: bool = True,
37        value_change_call: Callable[[Any], Any] | None = None,
38    ):
39        if displayname is None:
40            displayname = configkey
41        self._value_change_call = value_change_call
42        self._configkey = configkey
43        self.widget = bui.checkboxwidget(
44            parent=parent,
45            autoselect=autoselect,
46            position=position,
47            size=size,
48            text=displayname,
49            textcolor=(0.8, 0.8, 0.8),
50            value=bui.app.config.resolve(configkey),
51            on_value_change_call=self._value_changed,
52            scale=scale,
53            maxwidth=maxwidth,
54        )
55        # complain if we outlive our checkbox
56        bui.uicleanupcheck(self, self.widget)
widget: _bauiv1.Widget

The underlying bui.Widget instance.

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

A set of controls for editing a numeric config value.

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

ConfigNumberEdit( parent: _bauiv1.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 | babase.Lstr | None = None, changesound: bool = True, textscale: float = 1.0, as_percent: bool = False, fallback_value: float = 0.0, f: int = 1)
 85    def __init__(
 86        self,
 87        parent: bui.Widget,
 88        configkey: str,
 89        position: tuple[float, float],
 90        *,
 91        minval: float = 0.0,
 92        maxval: float = 100.0,
 93        increment: float = 1.0,
 94        callback: Callable[[float], Any] | None = None,
 95        xoffset: float = 0.0,
 96        displayname: str | bui.Lstr | None = None,
 97        changesound: bool = True,
 98        textscale: float = 1.0,
 99        as_percent: bool = False,
100        fallback_value: float = 0.0,
101        f: int = 1,
102    ):
103        if displayname is None:
104            displayname = configkey
105
106        self._configkey = configkey
107        self._minval = minval
108        self._maxval = maxval
109        self._increment = increment
110        self._callback = callback
111        try:
112            self._value = bui.app.config.resolve(configkey)
113        except ValueError:
114            self._value = bui.app.config.get(configkey, fallback_value)
115        self._value = (
116            self._minval
117            if self._minval > self._value
118            else self._maxval if self._maxval < self._value else self._value
119        )
120        self._as_percent = as_percent
121        self._f = f
122
123        self.nametext = bui.textwidget(
124            parent=parent,
125            position=(position[0], position[1] + 12.0),
126            size=(0, 0),
127            text=displayname,
128            maxwidth=150 + xoffset,
129            color=(0.8, 0.8, 0.8, 1.0),
130            h_align='left',
131            v_align='center',
132            scale=textscale,
133        )
134        self.valuetext = bui.textwidget(
135            parent=parent,
136            position=(position[0] + 216 + xoffset, position[1] + 12.0),
137            size=(0, 0),
138            editable=False,
139            color=(0.3, 1.0, 0.3, 1.0),
140            h_align='right',
141            v_align='center',
142            text=str(self._value),
143            padding=2,
144        )
145        self.minusbutton = bui.buttonwidget(
146            parent=parent,
147            position=(position[0] + 230 + xoffset, position[1]),
148            size=(28, 28),
149            label='-',
150            autoselect=True,
151            on_activate_call=bui.Call(self._down),
152            repeat=True,
153            enable_sound=changesound,
154        )
155        self.plusbutton = bui.buttonwidget(
156            parent=parent,
157            position=(position[0] + 280 + xoffset, position[1]),
158            size=(28, 28),
159            label='+',
160            autoselect=True,
161            on_activate_call=bui.Call(self._up),
162            repeat=True,
163            enable_sound=changesound,
164        )
165        # Complain if we outlive our widgets.
166        bui.uicleanupcheck(self, self.nametext)
167        self._update_display()
nametext: _bauiv1.Widget

The text widget displaying the name.

valuetext: _bauiv1.Widget

The text widget displaying the current value.

minusbutton: _bauiv1.Widget

The button widget used to reduce the value.

plusbutton: _bauiv1.Widget

The button widget used to increase the value.