bauiv1lib.achievements

Provides a popup window to view achievements.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Provides a popup window to view achievements."""
  4
  5from __future__ import annotations
  6
  7from typing import override
  8
  9import bauiv1 as bui
 10
 11
 12class AchievementsWindow(bui.MainWindow):
 13    """Popup window to view achievements."""
 14
 15    def __init__(
 16        self,
 17        transition: str | None = 'in_right',
 18        origin_widget: bui.Widget | None = None,
 19    ):
 20        # pylint: disable=too-many-locals
 21        # pylint: disable=too-many-statements
 22        # pylint: disable=cyclic-import
 23        from baclassic import (
 24            CHEST_APPEARANCE_DISPLAY_INFOS,
 25            CHEST_APPEARANCE_DISPLAY_INFO_DEFAULT,
 26        )
 27
 28        assert bui.app.classic is not None
 29        uiscale = bui.app.ui_v1.uiscale
 30
 31        self._width = 700 if uiscale is bui.UIScale.SMALL else 550
 32        self._height = (
 33            450
 34            if uiscale is bui.UIScale.SMALL
 35            else 370 if uiscale is bui.UIScale.MEDIUM else 450
 36        )
 37
 38        # Do some fancy math to fill all available screen area up to the
 39        # size of our backing container. This lets us fit to the exact
 40        # screen shape at small ui scale.
 41        screensize = bui.get_virtual_screen_size()
 42        scale = (
 43            2.7
 44            if uiscale is bui.UIScale.SMALL
 45            else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.2
 46        )
 47        # Calc screen size in our local container space and clamp to a
 48        # bit smaller than our container size.
 49        target_width = min(self._width - 60, screensize[0] / scale)
 50        target_height = min(self._height - 70, screensize[1] / scale)
 51
 52        # To get top/left coords, go to the center of our window and
 53        # offset by half the width/height of our target area.
 54        yoffs = 0.5 * self._height + 0.5 * target_height + 30.0
 55
 56        scroll_width = target_width
 57        scroll_height = target_height - 25
 58        scroll_bottom = yoffs - 54 - scroll_height
 59
 60        super().__init__(
 61            root_widget=bui.containerwidget(
 62                size=(self._width, self._height),
 63                toolbar_visibility=(
 64                    'menu_minimal'
 65                    if uiscale is bui.UIScale.SMALL
 66                    else 'menu_full'
 67                ),
 68                scale=scale,
 69            ),
 70            transition=transition,
 71            origin_widget=origin_widget,
 72            # We're affected by screen size only at small ui-scale.
 73            refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL,
 74        )
 75
 76        if uiscale is bui.UIScale.SMALL:
 77            bui.containerwidget(
 78                edit=self._root_widget, on_cancel_call=self.main_window_back
 79            )
 80            self._back_button = None
 81        else:
 82            self._back_button = bui.buttonwidget(
 83                parent=self._root_widget,
 84                autoselect=True,
 85                position=(50, yoffs - 48),
 86                size=(60, 60),
 87                scale=0.6,
 88                label=bui.charstr(bui.SpecialChar.BACK),
 89                button_type='backSmall',
 90                on_activate_call=self.main_window_back,
 91            )
 92            bui.containerwidget(
 93                edit=self._root_widget, cancel_button=self._back_button
 94            )
 95
 96        achievements = bui.app.classic.ach.achievements
 97        num_complete = len([a for a in achievements if a.complete])
 98
 99        txt_final = bui.Lstr(
100            resource='accountSettingsWindow.achievementProgressText',
101            subs=[
102                ('${COUNT}', str(num_complete)),
103                ('${TOTAL}', str(len(achievements))),
104            ],
105        )
106        self._title_text = bui.textwidget(
107            parent=self._root_widget,
108            position=(
109                self._width * 0.5,
110                yoffs - (42 if uiscale is bui.UIScale.SMALL else 30),
111            ),
112            size=(0, 0),
113            h_align='center',
114            v_align='center',
115            scale=0.6,
116            text=txt_final,
117            maxwidth=200,
118            color=bui.app.ui_v1.title_color,
119        )
120
121        self._scrollwidget = bui.scrollwidget(
122            parent=self._root_widget,
123            size=(scroll_width, scroll_height),
124            position=(self._width * 0.5 - scroll_width * 0.5, scroll_bottom),
125            capture_arrows=True,
126            simple_culling_v=10,
127            border_opacity=0.4,
128        )
129        bui.widget(edit=self._scrollwidget, autoselect=True)
130        if uiscale is bui.UIScale.SMALL:
131            bui.widget(
132                edit=self._scrollwidget,
133                left_widget=bui.get_special_widget('back_button'),
134            )
135
136        bui.containerwidget(
137            edit=self._root_widget, cancel_button=self._back_button
138        )
139
140        incr = 36
141        sub_width = scroll_width - 25
142        sub_height = 40 + len(achievements) * incr
143
144        eq_rsrc = 'coopSelectWindow.powerRankingPointsEqualsText'
145        pts_rsrc = 'coopSelectWindow.powerRankingPointsText'
146
147        self._subcontainer = bui.containerwidget(
148            parent=self._scrollwidget,
149            size=(sub_width, sub_height),
150            background=False,
151        )
152
153        total_pts = 0
154        for i, ach in enumerate(achievements):
155            complete = ach.complete
156            bui.textwidget(
157                parent=self._subcontainer,
158                position=(sub_width * 0.08 - 5, sub_height - 20 - incr * i),
159                maxwidth=20,
160                scale=0.5,
161                color=(0.6, 0.6, 0.7) if complete else (0.6, 0.6, 0.7, 0.2),
162                flatness=1.0,
163                shadow=0.0,
164                text=str(i + 1),
165                size=(0, 0),
166                h_align='right',
167                v_align='center',
168            )
169
170            bui.imagewidget(
171                parent=self._subcontainer,
172                position=(
173                    (sub_width * 0.10 + 1, sub_height - 20 - incr * i - 9)
174                    if complete
175                    else (sub_width * 0.10 - 4, sub_height - 20 - incr * i - 14)
176                ),
177                size=(18, 18) if complete else (27, 27),
178                opacity=1.0 if complete else 0.3,
179                color=ach.get_icon_color(complete)[:3],
180                texture=ach.get_icon_ui_texture(complete),
181            )
182            if complete:
183                bui.imagewidget(
184                    parent=self._subcontainer,
185                    position=(
186                        sub_width * 0.10 - 4,
187                        sub_height - 25 - incr * i - 9,
188                    ),
189                    size=(28, 28),
190                    color=(2, 1.4, 0),
191                    texture=bui.gettexture('achievementOutline'),
192                )
193            bui.textwidget(
194                parent=self._subcontainer,
195                position=(sub_width * 0.19, sub_height - 19 - incr * i + 3),
196                maxwidth=sub_width * 0.62,
197                scale=0.6,
198                flatness=1.0,
199                shadow=0.0,
200                color=(1, 1, 1) if complete else (1, 1, 1, 0.2),
201                text=ach.display_name,
202                size=(0, 0),
203                h_align='left',
204                v_align='center',
205            )
206
207            bui.textwidget(
208                parent=self._subcontainer,
209                position=(sub_width * 0.19, sub_height - 19 - incr * i - 10),
210                maxwidth=sub_width * 0.62,
211                scale=0.4,
212                flatness=1.0,
213                shadow=0.0,
214                color=(0.83, 0.8, 0.85) if complete else (0.8, 0.8, 0.8, 0.2),
215                text=(
216                    ach.description_full_complete
217                    if complete
218                    else ach.description_full
219                ),
220                size=(0, 0),
221                h_align='left',
222                v_align='center',
223            )
224            chest_type = ach.get_award_chest_type()
225            chestdisplayinfo = CHEST_APPEARANCE_DISPLAY_INFOS.get(
226                chest_type, CHEST_APPEARANCE_DISPLAY_INFO_DEFAULT
227            )
228            chestsize = 24.0
229            bui.imagewidget(
230                parent=self._subcontainer,
231                opacity=0.0 if complete else 1.0,
232                position=(
233                    sub_width * 0.92 - 40.0 - chestsize * 0.5,
234                    sub_height - 20 - incr * i - chestsize * 0.5,
235                ),
236                size=(chestsize, chestsize),
237                color=chestdisplayinfo.color,
238                texture=bui.gettexture(chestdisplayinfo.texclosed),
239                tint_texture=bui.gettexture(chestdisplayinfo.texclosedtint),
240                tint_color=chestdisplayinfo.tint,
241                tint2_color=chestdisplayinfo.tint2,
242            )
243
244            pts = ach.power_ranking_value
245            bui.textwidget(
246                parent=self._subcontainer,
247                position=(sub_width * 0.92, sub_height - 20 - incr * i),
248                maxwidth=sub_width * 0.15,
249                color=(0.7, 0.8, 1.0) if complete else (0.9, 0.9, 1.0, 0.3),
250                flatness=1.0,
251                shadow=0.0,
252                scale=0.6,
253                text=bui.Lstr(
254                    resource=pts_rsrc, subs=[('${NUMBER}', str(pts))]
255                ),
256                size=(0, 0),
257                h_align='center',
258                v_align='center',
259            )
260            if complete:
261                total_pts += pts
262
263        bui.textwidget(
264            parent=self._subcontainer,
265            position=(
266                sub_width * 1.0,
267                sub_height - 20 - incr * len(achievements),
268            ),
269            maxwidth=sub_width * 0.5,
270            scale=0.7,
271            color=(0.7, 0.8, 1.0),
272            flatness=1.0,
273            shadow=0.0,
274            text=bui.Lstr(
275                value='${A} ${B}',
276                subs=[
277                    ('${A}', bui.Lstr(resource='coopSelectWindow.totalText')),
278                    (
279                        '${B}',
280                        bui.Lstr(
281                            resource=eq_rsrc,
282                            subs=[('${NUMBER}', str(total_pts))],
283                        ),
284                    ),
285                ],
286            ),
287            size=(0, 0),
288            h_align='right',
289            v_align='center',
290        )
291
292    @override
293    def get_main_window_state(self) -> bui.MainWindowState:
294        # Support recreating our window for back/refresh purposes.
295        cls = type(self)
296        return bui.BasicMainWindowState(
297            create_call=lambda transition, origin_widget: cls(
298                transition=transition, origin_widget=origin_widget
299            )
300        )
class AchievementsWindow(bauiv1._uitypes.MainWindow):
 13class AchievementsWindow(bui.MainWindow):
 14    """Popup window to view achievements."""
 15
 16    def __init__(
 17        self,
 18        transition: str | None = 'in_right',
 19        origin_widget: bui.Widget | None = None,
 20    ):
 21        # pylint: disable=too-many-locals
 22        # pylint: disable=too-many-statements
 23        # pylint: disable=cyclic-import
 24        from baclassic import (
 25            CHEST_APPEARANCE_DISPLAY_INFOS,
 26            CHEST_APPEARANCE_DISPLAY_INFO_DEFAULT,
 27        )
 28
 29        assert bui.app.classic is not None
 30        uiscale = bui.app.ui_v1.uiscale
 31
 32        self._width = 700 if uiscale is bui.UIScale.SMALL else 550
 33        self._height = (
 34            450
 35            if uiscale is bui.UIScale.SMALL
 36            else 370 if uiscale is bui.UIScale.MEDIUM else 450
 37        )
 38
 39        # Do some fancy math to fill all available screen area up to the
 40        # size of our backing container. This lets us fit to the exact
 41        # screen shape at small ui scale.
 42        screensize = bui.get_virtual_screen_size()
 43        scale = (
 44            2.7
 45            if uiscale is bui.UIScale.SMALL
 46            else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.2
 47        )
 48        # Calc screen size in our local container space and clamp to a
 49        # bit smaller than our container size.
 50        target_width = min(self._width - 60, screensize[0] / scale)
 51        target_height = min(self._height - 70, screensize[1] / scale)
 52
 53        # To get top/left coords, go to the center of our window and
 54        # offset by half the width/height of our target area.
 55        yoffs = 0.5 * self._height + 0.5 * target_height + 30.0
 56
 57        scroll_width = target_width
 58        scroll_height = target_height - 25
 59        scroll_bottom = yoffs - 54 - scroll_height
 60
 61        super().__init__(
 62            root_widget=bui.containerwidget(
 63                size=(self._width, self._height),
 64                toolbar_visibility=(
 65                    'menu_minimal'
 66                    if uiscale is bui.UIScale.SMALL
 67                    else 'menu_full'
 68                ),
 69                scale=scale,
 70            ),
 71            transition=transition,
 72            origin_widget=origin_widget,
 73            # We're affected by screen size only at small ui-scale.
 74            refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL,
 75        )
 76
 77        if uiscale is bui.UIScale.SMALL:
 78            bui.containerwidget(
 79                edit=self._root_widget, on_cancel_call=self.main_window_back
 80            )
 81            self._back_button = None
 82        else:
 83            self._back_button = bui.buttonwidget(
 84                parent=self._root_widget,
 85                autoselect=True,
 86                position=(50, yoffs - 48),
 87                size=(60, 60),
 88                scale=0.6,
 89                label=bui.charstr(bui.SpecialChar.BACK),
 90                button_type='backSmall',
 91                on_activate_call=self.main_window_back,
 92            )
 93            bui.containerwidget(
 94                edit=self._root_widget, cancel_button=self._back_button
 95            )
 96
 97        achievements = bui.app.classic.ach.achievements
 98        num_complete = len([a for a in achievements if a.complete])
 99
100        txt_final = bui.Lstr(
101            resource='accountSettingsWindow.achievementProgressText',
102            subs=[
103                ('${COUNT}', str(num_complete)),
104                ('${TOTAL}', str(len(achievements))),
105            ],
106        )
107        self._title_text = bui.textwidget(
108            parent=self._root_widget,
109            position=(
110                self._width * 0.5,
111                yoffs - (42 if uiscale is bui.UIScale.SMALL else 30),
112            ),
113            size=(0, 0),
114            h_align='center',
115            v_align='center',
116            scale=0.6,
117            text=txt_final,
118            maxwidth=200,
119            color=bui.app.ui_v1.title_color,
120        )
121
122        self._scrollwidget = bui.scrollwidget(
123            parent=self._root_widget,
124            size=(scroll_width, scroll_height),
125            position=(self._width * 0.5 - scroll_width * 0.5, scroll_bottom),
126            capture_arrows=True,
127            simple_culling_v=10,
128            border_opacity=0.4,
129        )
130        bui.widget(edit=self._scrollwidget, autoselect=True)
131        if uiscale is bui.UIScale.SMALL:
132            bui.widget(
133                edit=self._scrollwidget,
134                left_widget=bui.get_special_widget('back_button'),
135            )
136
137        bui.containerwidget(
138            edit=self._root_widget, cancel_button=self._back_button
139        )
140
141        incr = 36
142        sub_width = scroll_width - 25
143        sub_height = 40 + len(achievements) * incr
144
145        eq_rsrc = 'coopSelectWindow.powerRankingPointsEqualsText'
146        pts_rsrc = 'coopSelectWindow.powerRankingPointsText'
147
148        self._subcontainer = bui.containerwidget(
149            parent=self._scrollwidget,
150            size=(sub_width, sub_height),
151            background=False,
152        )
153
154        total_pts = 0
155        for i, ach in enumerate(achievements):
156            complete = ach.complete
157            bui.textwidget(
158                parent=self._subcontainer,
159                position=(sub_width * 0.08 - 5, sub_height - 20 - incr * i),
160                maxwidth=20,
161                scale=0.5,
162                color=(0.6, 0.6, 0.7) if complete else (0.6, 0.6, 0.7, 0.2),
163                flatness=1.0,
164                shadow=0.0,
165                text=str(i + 1),
166                size=(0, 0),
167                h_align='right',
168                v_align='center',
169            )
170
171            bui.imagewidget(
172                parent=self._subcontainer,
173                position=(
174                    (sub_width * 0.10 + 1, sub_height - 20 - incr * i - 9)
175                    if complete
176                    else (sub_width * 0.10 - 4, sub_height - 20 - incr * i - 14)
177                ),
178                size=(18, 18) if complete else (27, 27),
179                opacity=1.0 if complete else 0.3,
180                color=ach.get_icon_color(complete)[:3],
181                texture=ach.get_icon_ui_texture(complete),
182            )
183            if complete:
184                bui.imagewidget(
185                    parent=self._subcontainer,
186                    position=(
187                        sub_width * 0.10 - 4,
188                        sub_height - 25 - incr * i - 9,
189                    ),
190                    size=(28, 28),
191                    color=(2, 1.4, 0),
192                    texture=bui.gettexture('achievementOutline'),
193                )
194            bui.textwidget(
195                parent=self._subcontainer,
196                position=(sub_width * 0.19, sub_height - 19 - incr * i + 3),
197                maxwidth=sub_width * 0.62,
198                scale=0.6,
199                flatness=1.0,
200                shadow=0.0,
201                color=(1, 1, 1) if complete else (1, 1, 1, 0.2),
202                text=ach.display_name,
203                size=(0, 0),
204                h_align='left',
205                v_align='center',
206            )
207
208            bui.textwidget(
209                parent=self._subcontainer,
210                position=(sub_width * 0.19, sub_height - 19 - incr * i - 10),
211                maxwidth=sub_width * 0.62,
212                scale=0.4,
213                flatness=1.0,
214                shadow=0.0,
215                color=(0.83, 0.8, 0.85) if complete else (0.8, 0.8, 0.8, 0.2),
216                text=(
217                    ach.description_full_complete
218                    if complete
219                    else ach.description_full
220                ),
221                size=(0, 0),
222                h_align='left',
223                v_align='center',
224            )
225            chest_type = ach.get_award_chest_type()
226            chestdisplayinfo = CHEST_APPEARANCE_DISPLAY_INFOS.get(
227                chest_type, CHEST_APPEARANCE_DISPLAY_INFO_DEFAULT
228            )
229            chestsize = 24.0
230            bui.imagewidget(
231                parent=self._subcontainer,
232                opacity=0.0 if complete else 1.0,
233                position=(
234                    sub_width * 0.92 - 40.0 - chestsize * 0.5,
235                    sub_height - 20 - incr * i - chestsize * 0.5,
236                ),
237                size=(chestsize, chestsize),
238                color=chestdisplayinfo.color,
239                texture=bui.gettexture(chestdisplayinfo.texclosed),
240                tint_texture=bui.gettexture(chestdisplayinfo.texclosedtint),
241                tint_color=chestdisplayinfo.tint,
242                tint2_color=chestdisplayinfo.tint2,
243            )
244
245            pts = ach.power_ranking_value
246            bui.textwidget(
247                parent=self._subcontainer,
248                position=(sub_width * 0.92, sub_height - 20 - incr * i),
249                maxwidth=sub_width * 0.15,
250                color=(0.7, 0.8, 1.0) if complete else (0.9, 0.9, 1.0, 0.3),
251                flatness=1.0,
252                shadow=0.0,
253                scale=0.6,
254                text=bui.Lstr(
255                    resource=pts_rsrc, subs=[('${NUMBER}', str(pts))]
256                ),
257                size=(0, 0),
258                h_align='center',
259                v_align='center',
260            )
261            if complete:
262                total_pts += pts
263
264        bui.textwidget(
265            parent=self._subcontainer,
266            position=(
267                sub_width * 1.0,
268                sub_height - 20 - incr * len(achievements),
269            ),
270            maxwidth=sub_width * 0.5,
271            scale=0.7,
272            color=(0.7, 0.8, 1.0),
273            flatness=1.0,
274            shadow=0.0,
275            text=bui.Lstr(
276                value='${A} ${B}',
277                subs=[
278                    ('${A}', bui.Lstr(resource='coopSelectWindow.totalText')),
279                    (
280                        '${B}',
281                        bui.Lstr(
282                            resource=eq_rsrc,
283                            subs=[('${NUMBER}', str(total_pts))],
284                        ),
285                    ),
286                ],
287            ),
288            size=(0, 0),
289            h_align='right',
290            v_align='center',
291        )
292
293    @override
294    def get_main_window_state(self) -> bui.MainWindowState:
295        # Support recreating our window for back/refresh purposes.
296        cls = type(self)
297        return bui.BasicMainWindowState(
298            create_call=lambda transition, origin_widget: cls(
299                transition=transition, origin_widget=origin_widget
300            )
301        )

Popup window to view achievements.

AchievementsWindow( transition: str | None = 'in_right', origin_widget: _bauiv1.Widget | None = None)
 16    def __init__(
 17        self,
 18        transition: str | None = 'in_right',
 19        origin_widget: bui.Widget | None = None,
 20    ):
 21        # pylint: disable=too-many-locals
 22        # pylint: disable=too-many-statements
 23        # pylint: disable=cyclic-import
 24        from baclassic import (
 25            CHEST_APPEARANCE_DISPLAY_INFOS,
 26            CHEST_APPEARANCE_DISPLAY_INFO_DEFAULT,
 27        )
 28
 29        assert bui.app.classic is not None
 30        uiscale = bui.app.ui_v1.uiscale
 31
 32        self._width = 700 if uiscale is bui.UIScale.SMALL else 550
 33        self._height = (
 34            450
 35            if uiscale is bui.UIScale.SMALL
 36            else 370 if uiscale is bui.UIScale.MEDIUM else 450
 37        )
 38
 39        # Do some fancy math to fill all available screen area up to the
 40        # size of our backing container. This lets us fit to the exact
 41        # screen shape at small ui scale.
 42        screensize = bui.get_virtual_screen_size()
 43        scale = (
 44            2.7
 45            if uiscale is bui.UIScale.SMALL
 46            else 1.5 if uiscale is bui.UIScale.MEDIUM else 1.2
 47        )
 48        # Calc screen size in our local container space and clamp to a
 49        # bit smaller than our container size.
 50        target_width = min(self._width - 60, screensize[0] / scale)
 51        target_height = min(self._height - 70, screensize[1] / scale)
 52
 53        # To get top/left coords, go to the center of our window and
 54        # offset by half the width/height of our target area.
 55        yoffs = 0.5 * self._height + 0.5 * target_height + 30.0
 56
 57        scroll_width = target_width
 58        scroll_height = target_height - 25
 59        scroll_bottom = yoffs - 54 - scroll_height
 60
 61        super().__init__(
 62            root_widget=bui.containerwidget(
 63                size=(self._width, self._height),
 64                toolbar_visibility=(
 65                    'menu_minimal'
 66                    if uiscale is bui.UIScale.SMALL
 67                    else 'menu_full'
 68                ),
 69                scale=scale,
 70            ),
 71            transition=transition,
 72            origin_widget=origin_widget,
 73            # We're affected by screen size only at small ui-scale.
 74            refresh_on_screen_size_changes=uiscale is bui.UIScale.SMALL,
 75        )
 76
 77        if uiscale is bui.UIScale.SMALL:
 78            bui.containerwidget(
 79                edit=self._root_widget, on_cancel_call=self.main_window_back
 80            )
 81            self._back_button = None
 82        else:
 83            self._back_button = bui.buttonwidget(
 84                parent=self._root_widget,
 85                autoselect=True,
 86                position=(50, yoffs - 48),
 87                size=(60, 60),
 88                scale=0.6,
 89                label=bui.charstr(bui.SpecialChar.BACK),
 90                button_type='backSmall',
 91                on_activate_call=self.main_window_back,
 92            )
 93            bui.containerwidget(
 94                edit=self._root_widget, cancel_button=self._back_button
 95            )
 96
 97        achievements = bui.app.classic.ach.achievements
 98        num_complete = len([a for a in achievements if a.complete])
 99
100        txt_final = bui.Lstr(
101            resource='accountSettingsWindow.achievementProgressText',
102            subs=[
103                ('${COUNT}', str(num_complete)),
104                ('${TOTAL}', str(len(achievements))),
105            ],
106        )
107        self._title_text = bui.textwidget(
108            parent=self._root_widget,
109            position=(
110                self._width * 0.5,
111                yoffs - (42 if uiscale is bui.UIScale.SMALL else 30),
112            ),
113            size=(0, 0),
114            h_align='center',
115            v_align='center',
116            scale=0.6,
117            text=txt_final,
118            maxwidth=200,
119            color=bui.app.ui_v1.title_color,
120        )
121
122        self._scrollwidget = bui.scrollwidget(
123            parent=self._root_widget,
124            size=(scroll_width, scroll_height),
125            position=(self._width * 0.5 - scroll_width * 0.5, scroll_bottom),
126            capture_arrows=True,
127            simple_culling_v=10,
128            border_opacity=0.4,
129        )
130        bui.widget(edit=self._scrollwidget, autoselect=True)
131        if uiscale is bui.UIScale.SMALL:
132            bui.widget(
133                edit=self._scrollwidget,
134                left_widget=bui.get_special_widget('back_button'),
135            )
136
137        bui.containerwidget(
138            edit=self._root_widget, cancel_button=self._back_button
139        )
140
141        incr = 36
142        sub_width = scroll_width - 25
143        sub_height = 40 + len(achievements) * incr
144
145        eq_rsrc = 'coopSelectWindow.powerRankingPointsEqualsText'
146        pts_rsrc = 'coopSelectWindow.powerRankingPointsText'
147
148        self._subcontainer = bui.containerwidget(
149            parent=self._scrollwidget,
150            size=(sub_width, sub_height),
151            background=False,
152        )
153
154        total_pts = 0
155        for i, ach in enumerate(achievements):
156            complete = ach.complete
157            bui.textwidget(
158                parent=self._subcontainer,
159                position=(sub_width * 0.08 - 5, sub_height - 20 - incr * i),
160                maxwidth=20,
161                scale=0.5,
162                color=(0.6, 0.6, 0.7) if complete else (0.6, 0.6, 0.7, 0.2),
163                flatness=1.0,
164                shadow=0.0,
165                text=str(i + 1),
166                size=(0, 0),
167                h_align='right',
168                v_align='center',
169            )
170
171            bui.imagewidget(
172                parent=self._subcontainer,
173                position=(
174                    (sub_width * 0.10 + 1, sub_height - 20 - incr * i - 9)
175                    if complete
176                    else (sub_width * 0.10 - 4, sub_height - 20 - incr * i - 14)
177                ),
178                size=(18, 18) if complete else (27, 27),
179                opacity=1.0 if complete else 0.3,
180                color=ach.get_icon_color(complete)[:3],
181                texture=ach.get_icon_ui_texture(complete),
182            )
183            if complete:
184                bui.imagewidget(
185                    parent=self._subcontainer,
186                    position=(
187                        sub_width * 0.10 - 4,
188                        sub_height - 25 - incr * i - 9,
189                    ),
190                    size=(28, 28),
191                    color=(2, 1.4, 0),
192                    texture=bui.gettexture('achievementOutline'),
193                )
194            bui.textwidget(
195                parent=self._subcontainer,
196                position=(sub_width * 0.19, sub_height - 19 - incr * i + 3),
197                maxwidth=sub_width * 0.62,
198                scale=0.6,
199                flatness=1.0,
200                shadow=0.0,
201                color=(1, 1, 1) if complete else (1, 1, 1, 0.2),
202                text=ach.display_name,
203                size=(0, 0),
204                h_align='left',
205                v_align='center',
206            )
207
208            bui.textwidget(
209                parent=self._subcontainer,
210                position=(sub_width * 0.19, sub_height - 19 - incr * i - 10),
211                maxwidth=sub_width * 0.62,
212                scale=0.4,
213                flatness=1.0,
214                shadow=0.0,
215                color=(0.83, 0.8, 0.85) if complete else (0.8, 0.8, 0.8, 0.2),
216                text=(
217                    ach.description_full_complete
218                    if complete
219                    else ach.description_full
220                ),
221                size=(0, 0),
222                h_align='left',
223                v_align='center',
224            )
225            chest_type = ach.get_award_chest_type()
226            chestdisplayinfo = CHEST_APPEARANCE_DISPLAY_INFOS.get(
227                chest_type, CHEST_APPEARANCE_DISPLAY_INFO_DEFAULT
228            )
229            chestsize = 24.0
230            bui.imagewidget(
231                parent=self._subcontainer,
232                opacity=0.0 if complete else 1.0,
233                position=(
234                    sub_width * 0.92 - 40.0 - chestsize * 0.5,
235                    sub_height - 20 - incr * i - chestsize * 0.5,
236                ),
237                size=(chestsize, chestsize),
238                color=chestdisplayinfo.color,
239                texture=bui.gettexture(chestdisplayinfo.texclosed),
240                tint_texture=bui.gettexture(chestdisplayinfo.texclosedtint),
241                tint_color=chestdisplayinfo.tint,
242                tint2_color=chestdisplayinfo.tint2,
243            )
244
245            pts = ach.power_ranking_value
246            bui.textwidget(
247                parent=self._subcontainer,
248                position=(sub_width * 0.92, sub_height - 20 - incr * i),
249                maxwidth=sub_width * 0.15,
250                color=(0.7, 0.8, 1.0) if complete else (0.9, 0.9, 1.0, 0.3),
251                flatness=1.0,
252                shadow=0.0,
253                scale=0.6,
254                text=bui.Lstr(
255                    resource=pts_rsrc, subs=[('${NUMBER}', str(pts))]
256                ),
257                size=(0, 0),
258                h_align='center',
259                v_align='center',
260            )
261            if complete:
262                total_pts += pts
263
264        bui.textwidget(
265            parent=self._subcontainer,
266            position=(
267                sub_width * 1.0,
268                sub_height - 20 - incr * len(achievements),
269            ),
270            maxwidth=sub_width * 0.5,
271            scale=0.7,
272            color=(0.7, 0.8, 1.0),
273            flatness=1.0,
274            shadow=0.0,
275            text=bui.Lstr(
276                value='${A} ${B}',
277                subs=[
278                    ('${A}', bui.Lstr(resource='coopSelectWindow.totalText')),
279                    (
280                        '${B}',
281                        bui.Lstr(
282                            resource=eq_rsrc,
283                            subs=[('${NUMBER}', str(total_pts))],
284                        ),
285                    ),
286                ],
287            ),
288            size=(0, 0),
289            h_align='right',
290            v_align='center',
291        )

Create a MainWindow given a root widget and transition info.

Automatically handles in and out transitions on the provided widget, so there is no need to set transitions when creating it.

@override
def get_main_window_state(self) -> bauiv1.MainWindowState:
293    @override
294    def get_main_window_state(self) -> bui.MainWindowState:
295        # Support recreating our window for back/refresh purposes.
296        cls = type(self)
297        return bui.BasicMainWindowState(
298            create_call=lambda transition, origin_widget: cls(
299                transition=transition, origin_widget=origin_widget
300            )
301        )

Return a WindowState to recreate this window, if supported.