bauiv1lib.teamnamescolors

Provides a window to customize team names and colors.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Provides a window to customize team names and colors."""
  4
  5from __future__ import annotations
  6
  7from typing import TYPE_CHECKING, cast, override
  8
  9from bauiv1lib.popup import PopupWindow
 10from bauiv1lib.colorpicker import ColorPicker
 11import bauiv1 as bui
 12
 13if TYPE_CHECKING:
 14    from typing import Sequence
 15
 16
 17class TeamNamesColorsWindow(PopupWindow):
 18    """A popup window for customizing team names and colors."""
 19
 20    def __init__(self, scale_origin: tuple[float, float]):
 21        from bascenev1 import DEFAULT_TEAM_COLORS, DEFAULT_TEAM_NAMES
 22
 23        self._width = 500
 24        self._height = 330
 25        self._transitioning_out = False
 26        self._max_name_length = 16
 27
 28        # Creates our _root_widget.
 29        assert bui.app.classic is not None
 30        uiscale = bui.app.ui_v1.uiscale
 31        scale = (
 32            1.69
 33            if uiscale is bui.UIScale.SMALL
 34            else 1.1 if uiscale is bui.UIScale.MEDIUM else 0.85
 35        )
 36        super().__init__(
 37            position=scale_origin, size=(self._width, self._height), scale=scale
 38        )
 39
 40        appconfig = bui.app.config
 41        self._names = list(
 42            appconfig.get('Custom Team Names', DEFAULT_TEAM_NAMES)
 43        )
 44
 45        # We need to flatten the translation since it will be an
 46        # editable string.
 47        self._names = [
 48            bui.Lstr(translate=('teamNames', n)).evaluate() for n in self._names
 49        ]
 50        self._colors = list(
 51            appconfig.get('Custom Team Colors', DEFAULT_TEAM_COLORS)
 52        )
 53
 54        self._color_buttons: list[bui.Widget] = []
 55        self._color_text_fields: list[bui.Widget] = []
 56
 57        resetbtn = bui.buttonwidget(
 58            parent=self.root_widget,
 59            label=bui.Lstr(resource='settingsWindowAdvanced.resetText'),
 60            autoselect=True,
 61            scale=0.7,
 62            on_activate_call=self._reset,
 63            size=(120, 50),
 64            position=(self._width * 0.5 - 60 * 0.7, self._height - 60),
 65        )
 66
 67        for i in range(2):
 68            self._color_buttons.append(
 69                bui.buttonwidget(
 70                    parent=self.root_widget,
 71                    autoselect=True,
 72                    position=(50, 0 + 195 - 90 * i),
 73                    on_activate_call=bui.Call(self._color_click, i),
 74                    size=(70, 70),
 75                    color=self._colors[i],
 76                    label='',
 77                    button_type='square',
 78                )
 79            )
 80            self._color_text_fields.append(
 81                bui.textwidget(
 82                    parent=self.root_widget,
 83                    position=(135, 0 + 201 - 90 * i),
 84                    size=(280, 46),
 85                    text=self._names[i],
 86                    h_align='left',
 87                    v_align='center',
 88                    max_chars=self._max_name_length,
 89                    color=self._colors[i],
 90                    description=bui.Lstr(resource='nameText'),
 91                    editable=True,
 92                    padding=4,
 93                )
 94            )
 95        bui.widget(
 96            edit=self._color_text_fields[0],
 97            down_widget=self._color_text_fields[1],
 98        )
 99        bui.widget(
100            edit=self._color_text_fields[1],
101            up_widget=self._color_text_fields[0],
102        )
103        bui.widget(edit=self._color_text_fields[0], up_widget=resetbtn)
104
105        cancelbtn = bui.buttonwidget(
106            parent=self.root_widget,
107            label=bui.Lstr(resource='cancelText'),
108            autoselect=True,
109            on_activate_call=self._on_cancel_press,
110            size=(150, 50),
111            position=(self._width * 0.5 - 200, 20),
112        )
113        okbtn = bui.buttonwidget(
114            parent=self.root_widget,
115            label=bui.Lstr(resource='okText'),
116            autoselect=True,
117            on_activate_call=self._ok,
118            size=(150, 50),
119            position=(self._width * 0.5 + 50, 20),
120        )
121        bui.containerwidget(
122            edit=self.root_widget, selected_child=self._color_buttons[0]
123        )
124        bui.widget(edit=okbtn, left_widget=cancelbtn)
125        self._update()
126
127    def _color_click(self, i: int) -> None:
128        ColorPicker(
129            parent=self.root_widget,
130            position=self._color_buttons[i].get_screen_space_center(),
131            offset=(270.0, 0),
132            initial_color=self._colors[i],
133            delegate=self,
134            tag=i,
135        )
136
137    def color_picker_closing(self, picker: ColorPicker) -> None:
138        """Called when the color picker is closing."""
139
140    def color_picker_selected_color(
141        self, picker: ColorPicker, color: Sequence[float]
142    ) -> None:
143        """Called when a color is selected in the color picker."""
144        self._colors[picker.get_tag()] = color
145        self._update()
146
147    def _reset(self) -> None:
148        from bascenev1 import DEFAULT_TEAM_NAMES, DEFAULT_TEAM_COLORS
149
150        for i in range(2):
151            self._colors[i] = DEFAULT_TEAM_COLORS[i]
152            name = bui.Lstr(
153                translate=('teamNames', DEFAULT_TEAM_NAMES[i])
154            ).evaluate()
155            if len(name) > self._max_name_length:
156                print('GOT DEFAULT TEAM NAME LONGER THAN MAX LENGTH')
157            bui.textwidget(edit=self._color_text_fields[i], text=name)
158        self._update()
159
160    def _update(self) -> None:
161        for i in range(2):
162            bui.buttonwidget(edit=self._color_buttons[i], color=self._colors[i])
163            bui.textwidget(
164                edit=self._color_text_fields[i], color=self._colors[i]
165            )
166
167    def _ok(self) -> None:
168        from bascenev1 import DEFAULT_TEAM_COLORS, DEFAULT_TEAM_NAMES
169
170        cfg = bui.app.config
171
172        # First, determine whether the values here are defaults, in which case
173        # we can clear any values from prefs.  Currently if the string matches
174        # either the default raw value or its translation we consider it
175        # default. (the fact that team names get translated makes this
176        # situation a bit sloppy)
177        new_names: list[str] = []
178        is_default = True
179        for i in range(2):
180            name = cast(str, bui.textwidget(query=self._color_text_fields[i]))
181            if not name:
182                bui.screenmessage(
183                    bui.Lstr(resource='nameNotEmptyText'), color=(1, 0, 0)
184                )
185                bui.getsound('error').play()
186                return
187            new_names.append(name)
188
189        for i in range(2):
190            if self._colors[i] != DEFAULT_TEAM_COLORS[i]:
191                is_default = False
192            default_team_name = DEFAULT_TEAM_NAMES[i]
193            default_team_name_translated = bui.Lstr(
194                translate=('teamNames', default_team_name)
195            ).evaluate()
196            if (
197                new_names[i] != default_team_name
198                and new_names[i] != default_team_name_translated
199            ):
200                is_default = False
201
202        if is_default:
203            for key in ('Custom Team Names', 'Custom Team Colors'):
204                if key in cfg:
205                    del cfg[key]
206        else:
207            cfg['Custom Team Names'] = list(new_names)
208            cfg['Custom Team Colors'] = list(self._colors)
209
210        cfg.commit()
211        self._transition_out()
212
213    def _transition_out(self, transition: str = 'out_scale') -> None:
214        if not self._transitioning_out:
215            self._transitioning_out = True
216            bui.containerwidget(edit=self.root_widget, transition=transition)
217
218    @override
219    def on_popup_cancel(self) -> None:
220        bui.getsound('swish').play()
221        self._transition_out()
222
223    def _on_cancel_press(self) -> None:
224        self._transition_out()
class TeamNamesColorsWindow(bauiv1lib.popup.PopupWindow):
 18class TeamNamesColorsWindow(PopupWindow):
 19    """A popup window for customizing team names and colors."""
 20
 21    def __init__(self, scale_origin: tuple[float, float]):
 22        from bascenev1 import DEFAULT_TEAM_COLORS, DEFAULT_TEAM_NAMES
 23
 24        self._width = 500
 25        self._height = 330
 26        self._transitioning_out = False
 27        self._max_name_length = 16
 28
 29        # Creates our _root_widget.
 30        assert bui.app.classic is not None
 31        uiscale = bui.app.ui_v1.uiscale
 32        scale = (
 33            1.69
 34            if uiscale is bui.UIScale.SMALL
 35            else 1.1 if uiscale is bui.UIScale.MEDIUM else 0.85
 36        )
 37        super().__init__(
 38            position=scale_origin, size=(self._width, self._height), scale=scale
 39        )
 40
 41        appconfig = bui.app.config
 42        self._names = list(
 43            appconfig.get('Custom Team Names', DEFAULT_TEAM_NAMES)
 44        )
 45
 46        # We need to flatten the translation since it will be an
 47        # editable string.
 48        self._names = [
 49            bui.Lstr(translate=('teamNames', n)).evaluate() for n in self._names
 50        ]
 51        self._colors = list(
 52            appconfig.get('Custom Team Colors', DEFAULT_TEAM_COLORS)
 53        )
 54
 55        self._color_buttons: list[bui.Widget] = []
 56        self._color_text_fields: list[bui.Widget] = []
 57
 58        resetbtn = bui.buttonwidget(
 59            parent=self.root_widget,
 60            label=bui.Lstr(resource='settingsWindowAdvanced.resetText'),
 61            autoselect=True,
 62            scale=0.7,
 63            on_activate_call=self._reset,
 64            size=(120, 50),
 65            position=(self._width * 0.5 - 60 * 0.7, self._height - 60),
 66        )
 67
 68        for i in range(2):
 69            self._color_buttons.append(
 70                bui.buttonwidget(
 71                    parent=self.root_widget,
 72                    autoselect=True,
 73                    position=(50, 0 + 195 - 90 * i),
 74                    on_activate_call=bui.Call(self._color_click, i),
 75                    size=(70, 70),
 76                    color=self._colors[i],
 77                    label='',
 78                    button_type='square',
 79                )
 80            )
 81            self._color_text_fields.append(
 82                bui.textwidget(
 83                    parent=self.root_widget,
 84                    position=(135, 0 + 201 - 90 * i),
 85                    size=(280, 46),
 86                    text=self._names[i],
 87                    h_align='left',
 88                    v_align='center',
 89                    max_chars=self._max_name_length,
 90                    color=self._colors[i],
 91                    description=bui.Lstr(resource='nameText'),
 92                    editable=True,
 93                    padding=4,
 94                )
 95            )
 96        bui.widget(
 97            edit=self._color_text_fields[0],
 98            down_widget=self._color_text_fields[1],
 99        )
100        bui.widget(
101            edit=self._color_text_fields[1],
102            up_widget=self._color_text_fields[0],
103        )
104        bui.widget(edit=self._color_text_fields[0], up_widget=resetbtn)
105
106        cancelbtn = bui.buttonwidget(
107            parent=self.root_widget,
108            label=bui.Lstr(resource='cancelText'),
109            autoselect=True,
110            on_activate_call=self._on_cancel_press,
111            size=(150, 50),
112            position=(self._width * 0.5 - 200, 20),
113        )
114        okbtn = bui.buttonwidget(
115            parent=self.root_widget,
116            label=bui.Lstr(resource='okText'),
117            autoselect=True,
118            on_activate_call=self._ok,
119            size=(150, 50),
120            position=(self._width * 0.5 + 50, 20),
121        )
122        bui.containerwidget(
123            edit=self.root_widget, selected_child=self._color_buttons[0]
124        )
125        bui.widget(edit=okbtn, left_widget=cancelbtn)
126        self._update()
127
128    def _color_click(self, i: int) -> None:
129        ColorPicker(
130            parent=self.root_widget,
131            position=self._color_buttons[i].get_screen_space_center(),
132            offset=(270.0, 0),
133            initial_color=self._colors[i],
134            delegate=self,
135            tag=i,
136        )
137
138    def color_picker_closing(self, picker: ColorPicker) -> None:
139        """Called when the color picker is closing."""
140
141    def color_picker_selected_color(
142        self, picker: ColorPicker, color: Sequence[float]
143    ) -> None:
144        """Called when a color is selected in the color picker."""
145        self._colors[picker.get_tag()] = color
146        self._update()
147
148    def _reset(self) -> None:
149        from bascenev1 import DEFAULT_TEAM_NAMES, DEFAULT_TEAM_COLORS
150
151        for i in range(2):
152            self._colors[i] = DEFAULT_TEAM_COLORS[i]
153            name = bui.Lstr(
154                translate=('teamNames', DEFAULT_TEAM_NAMES[i])
155            ).evaluate()
156            if len(name) > self._max_name_length:
157                print('GOT DEFAULT TEAM NAME LONGER THAN MAX LENGTH')
158            bui.textwidget(edit=self._color_text_fields[i], text=name)
159        self._update()
160
161    def _update(self) -> None:
162        for i in range(2):
163            bui.buttonwidget(edit=self._color_buttons[i], color=self._colors[i])
164            bui.textwidget(
165                edit=self._color_text_fields[i], color=self._colors[i]
166            )
167
168    def _ok(self) -> None:
169        from bascenev1 import DEFAULT_TEAM_COLORS, DEFAULT_TEAM_NAMES
170
171        cfg = bui.app.config
172
173        # First, determine whether the values here are defaults, in which case
174        # we can clear any values from prefs.  Currently if the string matches
175        # either the default raw value or its translation we consider it
176        # default. (the fact that team names get translated makes this
177        # situation a bit sloppy)
178        new_names: list[str] = []
179        is_default = True
180        for i in range(2):
181            name = cast(str, bui.textwidget(query=self._color_text_fields[i]))
182            if not name:
183                bui.screenmessage(
184                    bui.Lstr(resource='nameNotEmptyText'), color=(1, 0, 0)
185                )
186                bui.getsound('error').play()
187                return
188            new_names.append(name)
189
190        for i in range(2):
191            if self._colors[i] != DEFAULT_TEAM_COLORS[i]:
192                is_default = False
193            default_team_name = DEFAULT_TEAM_NAMES[i]
194            default_team_name_translated = bui.Lstr(
195                translate=('teamNames', default_team_name)
196            ).evaluate()
197            if (
198                new_names[i] != default_team_name
199                and new_names[i] != default_team_name_translated
200            ):
201                is_default = False
202
203        if is_default:
204            for key in ('Custom Team Names', 'Custom Team Colors'):
205                if key in cfg:
206                    del cfg[key]
207        else:
208            cfg['Custom Team Names'] = list(new_names)
209            cfg['Custom Team Colors'] = list(self._colors)
210
211        cfg.commit()
212        self._transition_out()
213
214    def _transition_out(self, transition: str = 'out_scale') -> None:
215        if not self._transitioning_out:
216            self._transitioning_out = True
217            bui.containerwidget(edit=self.root_widget, transition=transition)
218
219    @override
220    def on_popup_cancel(self) -> None:
221        bui.getsound('swish').play()
222        self._transition_out()
223
224    def _on_cancel_press(self) -> None:
225        self._transition_out()

A popup window for customizing team names and colors.

TeamNamesColorsWindow(scale_origin: tuple[float, float])
 21    def __init__(self, scale_origin: tuple[float, float]):
 22        from bascenev1 import DEFAULT_TEAM_COLORS, DEFAULT_TEAM_NAMES
 23
 24        self._width = 500
 25        self._height = 330
 26        self._transitioning_out = False
 27        self._max_name_length = 16
 28
 29        # Creates our _root_widget.
 30        assert bui.app.classic is not None
 31        uiscale = bui.app.ui_v1.uiscale
 32        scale = (
 33            1.69
 34            if uiscale is bui.UIScale.SMALL
 35            else 1.1 if uiscale is bui.UIScale.MEDIUM else 0.85
 36        )
 37        super().__init__(
 38            position=scale_origin, size=(self._width, self._height), scale=scale
 39        )
 40
 41        appconfig = bui.app.config
 42        self._names = list(
 43            appconfig.get('Custom Team Names', DEFAULT_TEAM_NAMES)
 44        )
 45
 46        # We need to flatten the translation since it will be an
 47        # editable string.
 48        self._names = [
 49            bui.Lstr(translate=('teamNames', n)).evaluate() for n in self._names
 50        ]
 51        self._colors = list(
 52            appconfig.get('Custom Team Colors', DEFAULT_TEAM_COLORS)
 53        )
 54
 55        self._color_buttons: list[bui.Widget] = []
 56        self._color_text_fields: list[bui.Widget] = []
 57
 58        resetbtn = bui.buttonwidget(
 59            parent=self.root_widget,
 60            label=bui.Lstr(resource='settingsWindowAdvanced.resetText'),
 61            autoselect=True,
 62            scale=0.7,
 63            on_activate_call=self._reset,
 64            size=(120, 50),
 65            position=(self._width * 0.5 - 60 * 0.7, self._height - 60),
 66        )
 67
 68        for i in range(2):
 69            self._color_buttons.append(
 70                bui.buttonwidget(
 71                    parent=self.root_widget,
 72                    autoselect=True,
 73                    position=(50, 0 + 195 - 90 * i),
 74                    on_activate_call=bui.Call(self._color_click, i),
 75                    size=(70, 70),
 76                    color=self._colors[i],
 77                    label='',
 78                    button_type='square',
 79                )
 80            )
 81            self._color_text_fields.append(
 82                bui.textwidget(
 83                    parent=self.root_widget,
 84                    position=(135, 0 + 201 - 90 * i),
 85                    size=(280, 46),
 86                    text=self._names[i],
 87                    h_align='left',
 88                    v_align='center',
 89                    max_chars=self._max_name_length,
 90                    color=self._colors[i],
 91                    description=bui.Lstr(resource='nameText'),
 92                    editable=True,
 93                    padding=4,
 94                )
 95            )
 96        bui.widget(
 97            edit=self._color_text_fields[0],
 98            down_widget=self._color_text_fields[1],
 99        )
100        bui.widget(
101            edit=self._color_text_fields[1],
102            up_widget=self._color_text_fields[0],
103        )
104        bui.widget(edit=self._color_text_fields[0], up_widget=resetbtn)
105
106        cancelbtn = bui.buttonwidget(
107            parent=self.root_widget,
108            label=bui.Lstr(resource='cancelText'),
109            autoselect=True,
110            on_activate_call=self._on_cancel_press,
111            size=(150, 50),
112            position=(self._width * 0.5 - 200, 20),
113        )
114        okbtn = bui.buttonwidget(
115            parent=self.root_widget,
116            label=bui.Lstr(resource='okText'),
117            autoselect=True,
118            on_activate_call=self._ok,
119            size=(150, 50),
120            position=(self._width * 0.5 + 50, 20),
121        )
122        bui.containerwidget(
123            edit=self.root_widget, selected_child=self._color_buttons[0]
124        )
125        bui.widget(edit=okbtn, left_widget=cancelbtn)
126        self._update()
def color_picker_closing(self, picker: bauiv1lib.colorpicker.ColorPicker) -> None:
138    def color_picker_closing(self, picker: ColorPicker) -> None:
139        """Called when the color picker is closing."""

Called when the color picker is closing.

def color_picker_selected_color( self, picker: bauiv1lib.colorpicker.ColorPicker, color: Sequence[float]) -> None:
141    def color_picker_selected_color(
142        self, picker: ColorPicker, color: Sequence[float]
143    ) -> None:
144        """Called when a color is selected in the color picker."""
145        self._colors[picker.get_tag()] = color
146        self._update()

Called when a color is selected in the color picker.

@override
def on_popup_cancel(self) -> None:
219    @override
220    def on_popup_cancel(self) -> None:
221        bui.getsound('swish').play()
222        self._transition_out()

Called when the popup is canceled.

Cancels can occur due to clicking outside the window, hitting escape, etc.