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

Called when the color picker is closing.

def color_picker_selected_color( self, picker: bastd.ui.colorpicker.ColorPicker, color: Sequence[float]) -> None:
117    def color_picker_selected_color(self, picker: ColorPicker,
118                                    color: Sequence[float]) -> None:
119        """Called when a color is selected in the color picker."""
120        self._colors[picker.get_tag()] = color
121        self._update()

Called when a color is selected in the color picker.

def on_popup_cancel(self) -> None:
186    def on_popup_cancel(self) -> None:
187        ba.playsound(ba.getsound('swish'))
188        self._transition_out()

Called when the popup is canceled.

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