bauiv1lib.playlist.editcontroller

Defines a controller for wrangling playlist edit UIs.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Defines a controller for wrangling playlist edit UIs."""
  4
  5from __future__ import annotations
  6
  7import copy
  8from typing import TYPE_CHECKING
  9
 10import bascenev1 as bs
 11import bauiv1 as bui
 12
 13if TYPE_CHECKING:
 14    from typing import Any
 15
 16
 17class PlaylistEditController:
 18    """Coordinates various UIs involved in playlist editing."""
 19
 20    def __init__(
 21        self,
 22        sessiontype: type[bs.Session],
 23        existing_playlist_name: str | None = None,
 24        transition: str = 'in_right',
 25        playlist: list[dict[str, Any]] | None = None,
 26        playlist_name: str | None = None,
 27    ):
 28        from bascenev1 import filter_playlist
 29        from bauiv1lib.playlist import PlaylistTypeVars
 30        from bauiv1lib.playlist.edit import PlaylistEditWindow
 31
 32        appconfig = bui.app.config
 33
 34        # Since we may be showing our map list momentarily,
 35        # lets go ahead and preload all map preview textures.
 36        if bui.app.classic is not None:
 37            bui.app.classic.preload_map_preview_media()
 38
 39        self._sessiontype = sessiontype
 40
 41        self._editing_game = False
 42        self._editing_game_type: type[bs.GameActivity] | None = None
 43        self._pvars = PlaylistTypeVars(sessiontype)
 44        self._existing_playlist_name = existing_playlist_name
 45        self._config_name_full = self._pvars.config_name + ' Playlists'
 46
 47        # Make sure config exists.
 48        if self._config_name_full not in appconfig:
 49            appconfig[self._config_name_full] = {}
 50
 51        self._selected_index = 0
 52        if existing_playlist_name:
 53            self._name = existing_playlist_name
 54
 55            # Filter out invalid games.
 56            self._playlist = filter_playlist(
 57                appconfig[self._pvars.config_name + ' Playlists'][
 58                    existing_playlist_name
 59                ],
 60                sessiontype=sessiontype,
 61                remove_unowned=False,
 62                name=existing_playlist_name,
 63            )
 64            self._edit_ui_selection = None
 65        else:
 66            if playlist is not None:
 67                self._playlist = playlist
 68            else:
 69                self._playlist = []
 70            if playlist_name is not None:
 71                self._name = playlist_name
 72            else:
 73                # Find a good unused name.
 74                i = 1
 75                while True:
 76                    self._name = (
 77                        self._pvars.default_new_list_name.evaluate()
 78                        + ((' ' + str(i)) if i > 1 else '')
 79                    )
 80                    if (
 81                        self._name
 82                        not in appconfig[self._pvars.config_name + ' Playlists']
 83                    ):
 84                        break
 85                    i += 1
 86
 87            # Also we want it to start with 'add' highlighted since its empty
 88            # and that's all they can do.
 89            self._edit_ui_selection = 'add_button'
 90
 91        assert bui.app.classic is not None
 92        bui.app.ui_v1.set_main_window(
 93            PlaylistEditWindow(editcontroller=self, transition=transition),
 94            from_window=False,  # Disable this check.
 95        )
 96
 97    def get_config_name(self) -> str:
 98        """(internal)"""
 99        return self._pvars.config_name
100
101    def get_existing_playlist_name(self) -> str | None:
102        """(internal)"""
103        return self._existing_playlist_name
104
105    def get_edit_ui_selection(self) -> str | None:
106        """(internal)"""
107        return self._edit_ui_selection
108
109    def set_edit_ui_selection(self, selection: str) -> None:
110        """(internal)"""
111        self._edit_ui_selection = selection
112
113    def getname(self) -> str:
114        """(internal)"""
115        return self._name
116
117    def setname(self, name: str) -> None:
118        """(internal)"""
119        self._name = name
120
121    def get_playlist(self) -> list[dict[str, Any]]:
122        """Return the current state of the edited playlist."""
123        return copy.deepcopy(self._playlist)
124
125    def set_playlist(self, playlist: list[dict[str, Any]]) -> None:
126        """Set the playlist contents."""
127        self._playlist = copy.deepcopy(playlist)
128
129    def get_session_type(self) -> type[bs.Session]:
130        """Return the bascenev1.Session type for this edit-session."""
131        return self._sessiontype
132
133    def get_selected_index(self) -> int:
134        """Return the index of the selected playlist."""
135        return self._selected_index
136
137    def get_default_list_name(self) -> bui.Lstr:
138        """(internal)"""
139        return self._pvars.default_list_name
140
141    def set_selected_index(self, index: int) -> None:
142        """Sets the selected playlist index."""
143        self._selected_index = index
144
145    def add_game_pressed(self) -> None:
146        """(internal)"""
147        from bauiv1lib.playlist.addgame import PlaylistAddGameWindow
148
149        assert bui.app.classic is not None
150        bui.app.ui_v1.clear_main_window()
151        bui.app.ui_v1.set_main_window(
152            PlaylistAddGameWindow(editcontroller=self), from_window=None
153        )
154
155    def edit_game_pressed(self) -> None:
156        """Should be called by supplemental UIs when a game is to be edited."""
157
158        if not self._playlist:
159            return
160        self._show_edit_ui(
161            gametype=bui.getclass(
162                self._playlist[self._selected_index]['type'],
163                subclassof=bs.GameActivity,
164            ),
165            settings=self._playlist[self._selected_index],
166        )
167
168    # def add_game_cancelled(self) -> None:
169    #     """(internal)"""
170    #     from bauiv1lib.playlist.edit import PlaylistEditWindow
171
172    #     assert bui.app.classic is not None
173    #     bui.app.ui_v1.clear_main_window(transition='out_right')
174    #     bui.app.ui_v1.set_main_window(
175    #         PlaylistEditWindow(editcontroller=self, transition='in_left'),
176    #         from_window=None,
177    #         is_back=True,
178    #     )
179
180    def _show_edit_ui(
181        self, gametype: type[bs.GameActivity], settings: dict[str, Any] | None
182    ) -> None:
183        self._editing_game = settings is not None
184        self._editing_game_type = gametype
185        assert self._sessiontype is not None
186        gametype.create_settings_ui(
187            self._sessiontype, copy.deepcopy(settings), self._edit_game_done
188        )
189
190    def add_game_type_selected(self, gametype: type[bs.GameActivity]) -> None:
191        """(internal)"""
192        self._show_edit_ui(gametype=gametype, settings=None)
193
194    def _edit_game_done(self, config: dict[str, Any] | None) -> None:
195        from bauiv1lib.playlist.edit import PlaylistEditWindow
196        from bauiv1lib.playlist.addgame import PlaylistAddGameWindow
197
198        assert bui.app.classic is not None
199        if config is None:
200            # If we were editing, go back to our list.
201            if self._editing_game:
202                bui.getsound('powerdown01').play()
203                bui.app.ui_v1.clear_main_window()
204                bui.app.ui_v1.set_main_window(
205                    PlaylistEditWindow(
206                        editcontroller=self, transition='in_left'
207                    ),
208                    from_window=None,
209                    is_back=True,
210                )
211
212            # Otherwise we were adding; go back to the add type choice list.
213            else:
214                bui.app.ui_v1.clear_main_window()
215                bui.app.ui_v1.set_main_window(
216                    PlaylistAddGameWindow(
217                        editcontroller=self, transition='in_left'
218                    ),
219                    from_window=None,
220                    is_back=True,
221                )
222        else:
223            # Make sure type is in there.
224            assert self._editing_game_type is not None
225            config['type'] = bui.get_type_name(self._editing_game_type)
226
227            if self._editing_game:
228                self._playlist[self._selected_index] = copy.deepcopy(config)
229            else:
230                # Add a new entry to the playlist.
231                insert_index = min(
232                    len(self._playlist), self._selected_index + 1
233                )
234                self._playlist.insert(insert_index, copy.deepcopy(config))
235                self._selected_index = insert_index
236
237            bui.getsound('gunCocking').play()
238            bui.app.ui_v1.clear_main_window()
239            bui.app.ui_v1.set_main_window(
240                PlaylistEditWindow(editcontroller=self, transition='in_left'),
241                from_window=None,
242                is_back=True,
243            )
class PlaylistEditController:
 18class PlaylistEditController:
 19    """Coordinates various UIs involved in playlist editing."""
 20
 21    def __init__(
 22        self,
 23        sessiontype: type[bs.Session],
 24        existing_playlist_name: str | None = None,
 25        transition: str = 'in_right',
 26        playlist: list[dict[str, Any]] | None = None,
 27        playlist_name: str | None = None,
 28    ):
 29        from bascenev1 import filter_playlist
 30        from bauiv1lib.playlist import PlaylistTypeVars
 31        from bauiv1lib.playlist.edit import PlaylistEditWindow
 32
 33        appconfig = bui.app.config
 34
 35        # Since we may be showing our map list momentarily,
 36        # lets go ahead and preload all map preview textures.
 37        if bui.app.classic is not None:
 38            bui.app.classic.preload_map_preview_media()
 39
 40        self._sessiontype = sessiontype
 41
 42        self._editing_game = False
 43        self._editing_game_type: type[bs.GameActivity] | None = None
 44        self._pvars = PlaylistTypeVars(sessiontype)
 45        self._existing_playlist_name = existing_playlist_name
 46        self._config_name_full = self._pvars.config_name + ' Playlists'
 47
 48        # Make sure config exists.
 49        if self._config_name_full not in appconfig:
 50            appconfig[self._config_name_full] = {}
 51
 52        self._selected_index = 0
 53        if existing_playlist_name:
 54            self._name = existing_playlist_name
 55
 56            # Filter out invalid games.
 57            self._playlist = filter_playlist(
 58                appconfig[self._pvars.config_name + ' Playlists'][
 59                    existing_playlist_name
 60                ],
 61                sessiontype=sessiontype,
 62                remove_unowned=False,
 63                name=existing_playlist_name,
 64            )
 65            self._edit_ui_selection = None
 66        else:
 67            if playlist is not None:
 68                self._playlist = playlist
 69            else:
 70                self._playlist = []
 71            if playlist_name is not None:
 72                self._name = playlist_name
 73            else:
 74                # Find a good unused name.
 75                i = 1
 76                while True:
 77                    self._name = (
 78                        self._pvars.default_new_list_name.evaluate()
 79                        + ((' ' + str(i)) if i > 1 else '')
 80                    )
 81                    if (
 82                        self._name
 83                        not in appconfig[self._pvars.config_name + ' Playlists']
 84                    ):
 85                        break
 86                    i += 1
 87
 88            # Also we want it to start with 'add' highlighted since its empty
 89            # and that's all they can do.
 90            self._edit_ui_selection = 'add_button'
 91
 92        assert bui.app.classic is not None
 93        bui.app.ui_v1.set_main_window(
 94            PlaylistEditWindow(editcontroller=self, transition=transition),
 95            from_window=False,  # Disable this check.
 96        )
 97
 98    def get_config_name(self) -> str:
 99        """(internal)"""
100        return self._pvars.config_name
101
102    def get_existing_playlist_name(self) -> str | None:
103        """(internal)"""
104        return self._existing_playlist_name
105
106    def get_edit_ui_selection(self) -> str | None:
107        """(internal)"""
108        return self._edit_ui_selection
109
110    def set_edit_ui_selection(self, selection: str) -> None:
111        """(internal)"""
112        self._edit_ui_selection = selection
113
114    def getname(self) -> str:
115        """(internal)"""
116        return self._name
117
118    def setname(self, name: str) -> None:
119        """(internal)"""
120        self._name = name
121
122    def get_playlist(self) -> list[dict[str, Any]]:
123        """Return the current state of the edited playlist."""
124        return copy.deepcopy(self._playlist)
125
126    def set_playlist(self, playlist: list[dict[str, Any]]) -> None:
127        """Set the playlist contents."""
128        self._playlist = copy.deepcopy(playlist)
129
130    def get_session_type(self) -> type[bs.Session]:
131        """Return the bascenev1.Session type for this edit-session."""
132        return self._sessiontype
133
134    def get_selected_index(self) -> int:
135        """Return the index of the selected playlist."""
136        return self._selected_index
137
138    def get_default_list_name(self) -> bui.Lstr:
139        """(internal)"""
140        return self._pvars.default_list_name
141
142    def set_selected_index(self, index: int) -> None:
143        """Sets the selected playlist index."""
144        self._selected_index = index
145
146    def add_game_pressed(self) -> None:
147        """(internal)"""
148        from bauiv1lib.playlist.addgame import PlaylistAddGameWindow
149
150        assert bui.app.classic is not None
151        bui.app.ui_v1.clear_main_window()
152        bui.app.ui_v1.set_main_window(
153            PlaylistAddGameWindow(editcontroller=self), from_window=None
154        )
155
156    def edit_game_pressed(self) -> None:
157        """Should be called by supplemental UIs when a game is to be edited."""
158
159        if not self._playlist:
160            return
161        self._show_edit_ui(
162            gametype=bui.getclass(
163                self._playlist[self._selected_index]['type'],
164                subclassof=bs.GameActivity,
165            ),
166            settings=self._playlist[self._selected_index],
167        )
168
169    # def add_game_cancelled(self) -> None:
170    #     """(internal)"""
171    #     from bauiv1lib.playlist.edit import PlaylistEditWindow
172
173    #     assert bui.app.classic is not None
174    #     bui.app.ui_v1.clear_main_window(transition='out_right')
175    #     bui.app.ui_v1.set_main_window(
176    #         PlaylistEditWindow(editcontroller=self, transition='in_left'),
177    #         from_window=None,
178    #         is_back=True,
179    #     )
180
181    def _show_edit_ui(
182        self, gametype: type[bs.GameActivity], settings: dict[str, Any] | None
183    ) -> None:
184        self._editing_game = settings is not None
185        self._editing_game_type = gametype
186        assert self._sessiontype is not None
187        gametype.create_settings_ui(
188            self._sessiontype, copy.deepcopy(settings), self._edit_game_done
189        )
190
191    def add_game_type_selected(self, gametype: type[bs.GameActivity]) -> None:
192        """(internal)"""
193        self._show_edit_ui(gametype=gametype, settings=None)
194
195    def _edit_game_done(self, config: dict[str, Any] | None) -> None:
196        from bauiv1lib.playlist.edit import PlaylistEditWindow
197        from bauiv1lib.playlist.addgame import PlaylistAddGameWindow
198
199        assert bui.app.classic is not None
200        if config is None:
201            # If we were editing, go back to our list.
202            if self._editing_game:
203                bui.getsound('powerdown01').play()
204                bui.app.ui_v1.clear_main_window()
205                bui.app.ui_v1.set_main_window(
206                    PlaylistEditWindow(
207                        editcontroller=self, transition='in_left'
208                    ),
209                    from_window=None,
210                    is_back=True,
211                )
212
213            # Otherwise we were adding; go back to the add type choice list.
214            else:
215                bui.app.ui_v1.clear_main_window()
216                bui.app.ui_v1.set_main_window(
217                    PlaylistAddGameWindow(
218                        editcontroller=self, transition='in_left'
219                    ),
220                    from_window=None,
221                    is_back=True,
222                )
223        else:
224            # Make sure type is in there.
225            assert self._editing_game_type is not None
226            config['type'] = bui.get_type_name(self._editing_game_type)
227
228            if self._editing_game:
229                self._playlist[self._selected_index] = copy.deepcopy(config)
230            else:
231                # Add a new entry to the playlist.
232                insert_index = min(
233                    len(self._playlist), self._selected_index + 1
234                )
235                self._playlist.insert(insert_index, copy.deepcopy(config))
236                self._selected_index = insert_index
237
238            bui.getsound('gunCocking').play()
239            bui.app.ui_v1.clear_main_window()
240            bui.app.ui_v1.set_main_window(
241                PlaylistEditWindow(editcontroller=self, transition='in_left'),
242                from_window=None,
243                is_back=True,
244            )

Coordinates various UIs involved in playlist editing.

PlaylistEditController( sessiontype: type[bascenev1.Session], existing_playlist_name: str | None = None, transition: str = 'in_right', playlist: list[dict[str, typing.Any]] | None = None, playlist_name: str | None = None)
21    def __init__(
22        self,
23        sessiontype: type[bs.Session],
24        existing_playlist_name: str | None = None,
25        transition: str = 'in_right',
26        playlist: list[dict[str, Any]] | None = None,
27        playlist_name: str | None = None,
28    ):
29        from bascenev1 import filter_playlist
30        from bauiv1lib.playlist import PlaylistTypeVars
31        from bauiv1lib.playlist.edit import PlaylistEditWindow
32
33        appconfig = bui.app.config
34
35        # Since we may be showing our map list momentarily,
36        # lets go ahead and preload all map preview textures.
37        if bui.app.classic is not None:
38            bui.app.classic.preload_map_preview_media()
39
40        self._sessiontype = sessiontype
41
42        self._editing_game = False
43        self._editing_game_type: type[bs.GameActivity] | None = None
44        self._pvars = PlaylistTypeVars(sessiontype)
45        self._existing_playlist_name = existing_playlist_name
46        self._config_name_full = self._pvars.config_name + ' Playlists'
47
48        # Make sure config exists.
49        if self._config_name_full not in appconfig:
50            appconfig[self._config_name_full] = {}
51
52        self._selected_index = 0
53        if existing_playlist_name:
54            self._name = existing_playlist_name
55
56            # Filter out invalid games.
57            self._playlist = filter_playlist(
58                appconfig[self._pvars.config_name + ' Playlists'][
59                    existing_playlist_name
60                ],
61                sessiontype=sessiontype,
62                remove_unowned=False,
63                name=existing_playlist_name,
64            )
65            self._edit_ui_selection = None
66        else:
67            if playlist is not None:
68                self._playlist = playlist
69            else:
70                self._playlist = []
71            if playlist_name is not None:
72                self._name = playlist_name
73            else:
74                # Find a good unused name.
75                i = 1
76                while True:
77                    self._name = (
78                        self._pvars.default_new_list_name.evaluate()
79                        + ((' ' + str(i)) if i > 1 else '')
80                    )
81                    if (
82                        self._name
83                        not in appconfig[self._pvars.config_name + ' Playlists']
84                    ):
85                        break
86                    i += 1
87
88            # Also we want it to start with 'add' highlighted since its empty
89            # and that's all they can do.
90            self._edit_ui_selection = 'add_button'
91
92        assert bui.app.classic is not None
93        bui.app.ui_v1.set_main_window(
94            PlaylistEditWindow(editcontroller=self, transition=transition),
95            from_window=False,  # Disable this check.
96        )
def get_playlist(self) -> list[dict[str, typing.Any]]:
122    def get_playlist(self) -> list[dict[str, Any]]:
123        """Return the current state of the edited playlist."""
124        return copy.deepcopy(self._playlist)

Return the current state of the edited playlist.

def set_playlist(self, playlist: list[dict[str, typing.Any]]) -> None:
126    def set_playlist(self, playlist: list[dict[str, Any]]) -> None:
127        """Set the playlist contents."""
128        self._playlist = copy.deepcopy(playlist)

Set the playlist contents.

def get_session_type(self) -> type[bascenev1.Session]:
130    def get_session_type(self) -> type[bs.Session]:
131        """Return the bascenev1.Session type for this edit-session."""
132        return self._sessiontype

Return the bascenev1.Session type for this edit-session.

def get_selected_index(self) -> int:
134    def get_selected_index(self) -> int:
135        """Return the index of the selected playlist."""
136        return self._selected_index

Return the index of the selected playlist.

def set_selected_index(self, index: int) -> None:
142    def set_selected_index(self, index: int) -> None:
143        """Sets the selected playlist index."""
144        self._selected_index = index

Sets the selected playlist index.

def edit_game_pressed(self) -> None:
156    def edit_game_pressed(self) -> None:
157        """Should be called by supplemental UIs when a game is to be edited."""
158
159        if not self._playlist:
160            return
161        self._show_edit_ui(
162            gametype=bui.getclass(
163                self._playlist[self._selected_index]['type'],
164                subclassof=bs.GameActivity,
165            ),
166            settings=self._playlist[self._selected_index],
167        )

Should be called by supplemental UIs when a game is to be edited.