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

Called when a color is selected in the color picker.

def on_popup_cancel(self) -> None:
221    def on_popup_cancel(self) -> None:
222        bui.getsound('swish').play()
223        self._transition_out()

Called when the popup is canceled.

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