bastd.ui.iconpicker
Provides a picker for icons.
1# Released under the MIT License. See LICENSE for details. 2# 3"""Provides a picker for icons.""" 4 5from __future__ import annotations 6 7import math 8from typing import TYPE_CHECKING 9 10import ba 11import ba.internal 12from bastd.ui import popup 13 14if TYPE_CHECKING: 15 from typing import Any, Sequence 16 17 18class IconPicker(popup.PopupWindow): 19 """Picker for icons.""" 20 21 def __init__( 22 self, 23 parent: ba.Widget, 24 position: tuple[float, float] = (0.0, 0.0), 25 delegate: Any = None, 26 scale: float | None = None, 27 offset: tuple[float, float] = (0.0, 0.0), 28 tint_color: Sequence[float] = (1.0, 1.0, 1.0), 29 tint2_color: Sequence[float] = (1.0, 1.0, 1.0), 30 selected_icon: str | None = None, 31 ): 32 # pylint: disable=too-many-locals 33 del parent # unused here 34 del tint_color # unused_here 35 del tint2_color # unused here 36 uiscale = ba.app.ui.uiscale 37 if scale is None: 38 scale = ( 39 1.85 40 if uiscale is ba.UIScale.SMALL 41 else 1.65 42 if uiscale is ba.UIScale.MEDIUM 43 else 1.23 44 ) 45 46 self._delegate = delegate 47 self._transitioning_out = False 48 49 self._icons = [ 50 ba.charstr(ba.SpecialChar.LOGO) 51 ] + ba.app.accounts_v1.get_purchased_icons() 52 count = len(self._icons) 53 columns = 4 54 rows = int(math.ceil(float(count) / columns)) 55 56 button_width = 50 57 button_height = 50 58 button_buffer_h = 10 59 button_buffer_v = 5 60 61 self._width = 10 + columns * (button_width + 2 * button_buffer_h) * ( 62 1.0 / 0.95 63 ) * (1.0 / 0.8) 64 self._height = self._width * ( 65 0.8 if uiscale is ba.UIScale.SMALL else 1.06 66 ) 67 68 self._scroll_width = self._width * 0.8 69 self._scroll_height = self._height * 0.8 70 self._scroll_position = ( 71 (self._width - self._scroll_width) * 0.5, 72 (self._height - self._scroll_height) * 0.5, 73 ) 74 75 # creates our _root_widget 76 popup.PopupWindow.__init__( 77 self, 78 position=position, 79 size=(self._width, self._height), 80 scale=scale, 81 bg_color=(0.5, 0.5, 0.5), 82 offset=offset, 83 focus_position=self._scroll_position, 84 focus_size=(self._scroll_width, self._scroll_height), 85 ) 86 87 self._scrollwidget = ba.scrollwidget( 88 parent=self.root_widget, 89 size=(self._scroll_width, self._scroll_height), 90 color=(0.55, 0.55, 0.55), 91 highlight=False, 92 position=self._scroll_position, 93 ) 94 ba.containerwidget(edit=self._scrollwidget, claims_left_right=True) 95 96 self._sub_width = self._scroll_width * 0.95 97 self._sub_height = ( 98 5 + rows * (button_height + 2 * button_buffer_v) + 100 99 ) 100 self._subcontainer = ba.containerwidget( 101 parent=self._scrollwidget, 102 size=(self._sub_width, self._sub_height), 103 background=False, 104 ) 105 index = 0 106 for y in range(rows): 107 for x in range(columns): 108 pos = ( 109 x * (button_width + 2 * button_buffer_h) + button_buffer_h, 110 self._sub_height 111 - (y + 1) * (button_height + 2 * button_buffer_v) 112 + 0, 113 ) 114 btn = ba.buttonwidget( 115 parent=self._subcontainer, 116 button_type='square', 117 size=(button_width, button_height), 118 autoselect=True, 119 text_scale=1.2, 120 label='', 121 color=(0.65, 0.65, 0.65), 122 on_activate_call=ba.Call( 123 self._select_icon, self._icons[index] 124 ), 125 position=pos, 126 ) 127 ba.textwidget( 128 parent=self._subcontainer, 129 h_align='center', 130 v_align='center', 131 size=(0, 0), 132 position=(pos[0] + 0.5 * button_width - 1, pos[1] + 15), 133 draw_controller=btn, 134 text=self._icons[index], 135 scale=1.8, 136 ) 137 ba.widget(edit=btn, show_buffer_top=60, show_buffer_bottom=60) 138 if self._icons[index] == selected_icon: 139 ba.containerwidget( 140 edit=self._subcontainer, 141 selected_child=btn, 142 visible_child=btn, 143 ) 144 index += 1 145 146 if index >= count: 147 break 148 if index >= count: 149 break 150 self._get_more_icons_button = btn = ba.buttonwidget( 151 parent=self._subcontainer, 152 size=(self._sub_width * 0.8, 60), 153 position=(self._sub_width * 0.1, 30), 154 label=ba.Lstr(resource='editProfileWindow.getMoreIconsText'), 155 on_activate_call=self._on_store_press, 156 color=(0.6, 0.6, 0.6), 157 textcolor=(0.8, 0.8, 0.8), 158 autoselect=True, 159 ) 160 ba.widget(edit=btn, show_buffer_top=30, show_buffer_bottom=30) 161 162 def _on_store_press(self) -> None: 163 from bastd.ui.account import show_sign_in_prompt 164 from bastd.ui.store.browser import StoreBrowserWindow 165 166 if ba.internal.get_v1_account_state() != 'signed_in': 167 show_sign_in_prompt() 168 return 169 self._transition_out() 170 StoreBrowserWindow( 171 modal=True, 172 show_tab=StoreBrowserWindow.TabID.ICONS, 173 origin_widget=self._get_more_icons_button, 174 ) 175 176 def _select_icon(self, icon: str) -> None: 177 if self._delegate is not None: 178 self._delegate.on_icon_picker_pick(icon) 179 self._transition_out() 180 181 def _transition_out(self) -> None: 182 if not self._transitioning_out: 183 self._transitioning_out = True 184 ba.containerwidget(edit=self.root_widget, transition='out_scale') 185 186 def on_popup_cancel(self) -> None: 187 ba.playsound(ba.getsound('swish')) 188 self._transition_out()
19class IconPicker(popup.PopupWindow): 20 """Picker for icons.""" 21 22 def __init__( 23 self, 24 parent: ba.Widget, 25 position: tuple[float, float] = (0.0, 0.0), 26 delegate: Any = None, 27 scale: float | None = None, 28 offset: tuple[float, float] = (0.0, 0.0), 29 tint_color: Sequence[float] = (1.0, 1.0, 1.0), 30 tint2_color: Sequence[float] = (1.0, 1.0, 1.0), 31 selected_icon: str | None = None, 32 ): 33 # pylint: disable=too-many-locals 34 del parent # unused here 35 del tint_color # unused_here 36 del tint2_color # unused here 37 uiscale = ba.app.ui.uiscale 38 if scale is None: 39 scale = ( 40 1.85 41 if uiscale is ba.UIScale.SMALL 42 else 1.65 43 if uiscale is ba.UIScale.MEDIUM 44 else 1.23 45 ) 46 47 self._delegate = delegate 48 self._transitioning_out = False 49 50 self._icons = [ 51 ba.charstr(ba.SpecialChar.LOGO) 52 ] + ba.app.accounts_v1.get_purchased_icons() 53 count = len(self._icons) 54 columns = 4 55 rows = int(math.ceil(float(count) / columns)) 56 57 button_width = 50 58 button_height = 50 59 button_buffer_h = 10 60 button_buffer_v = 5 61 62 self._width = 10 + columns * (button_width + 2 * button_buffer_h) * ( 63 1.0 / 0.95 64 ) * (1.0 / 0.8) 65 self._height = self._width * ( 66 0.8 if uiscale is ba.UIScale.SMALL else 1.06 67 ) 68 69 self._scroll_width = self._width * 0.8 70 self._scroll_height = self._height * 0.8 71 self._scroll_position = ( 72 (self._width - self._scroll_width) * 0.5, 73 (self._height - self._scroll_height) * 0.5, 74 ) 75 76 # creates our _root_widget 77 popup.PopupWindow.__init__( 78 self, 79 position=position, 80 size=(self._width, self._height), 81 scale=scale, 82 bg_color=(0.5, 0.5, 0.5), 83 offset=offset, 84 focus_position=self._scroll_position, 85 focus_size=(self._scroll_width, self._scroll_height), 86 ) 87 88 self._scrollwidget = ba.scrollwidget( 89 parent=self.root_widget, 90 size=(self._scroll_width, self._scroll_height), 91 color=(0.55, 0.55, 0.55), 92 highlight=False, 93 position=self._scroll_position, 94 ) 95 ba.containerwidget(edit=self._scrollwidget, claims_left_right=True) 96 97 self._sub_width = self._scroll_width * 0.95 98 self._sub_height = ( 99 5 + rows * (button_height + 2 * button_buffer_v) + 100 100 ) 101 self._subcontainer = ba.containerwidget( 102 parent=self._scrollwidget, 103 size=(self._sub_width, self._sub_height), 104 background=False, 105 ) 106 index = 0 107 for y in range(rows): 108 for x in range(columns): 109 pos = ( 110 x * (button_width + 2 * button_buffer_h) + button_buffer_h, 111 self._sub_height 112 - (y + 1) * (button_height + 2 * button_buffer_v) 113 + 0, 114 ) 115 btn = ba.buttonwidget( 116 parent=self._subcontainer, 117 button_type='square', 118 size=(button_width, button_height), 119 autoselect=True, 120 text_scale=1.2, 121 label='', 122 color=(0.65, 0.65, 0.65), 123 on_activate_call=ba.Call( 124 self._select_icon, self._icons[index] 125 ), 126 position=pos, 127 ) 128 ba.textwidget( 129 parent=self._subcontainer, 130 h_align='center', 131 v_align='center', 132 size=(0, 0), 133 position=(pos[0] + 0.5 * button_width - 1, pos[1] + 15), 134 draw_controller=btn, 135 text=self._icons[index], 136 scale=1.8, 137 ) 138 ba.widget(edit=btn, show_buffer_top=60, show_buffer_bottom=60) 139 if self._icons[index] == selected_icon: 140 ba.containerwidget( 141 edit=self._subcontainer, 142 selected_child=btn, 143 visible_child=btn, 144 ) 145 index += 1 146 147 if index >= count: 148 break 149 if index >= count: 150 break 151 self._get_more_icons_button = btn = ba.buttonwidget( 152 parent=self._subcontainer, 153 size=(self._sub_width * 0.8, 60), 154 position=(self._sub_width * 0.1, 30), 155 label=ba.Lstr(resource='editProfileWindow.getMoreIconsText'), 156 on_activate_call=self._on_store_press, 157 color=(0.6, 0.6, 0.6), 158 textcolor=(0.8, 0.8, 0.8), 159 autoselect=True, 160 ) 161 ba.widget(edit=btn, show_buffer_top=30, show_buffer_bottom=30) 162 163 def _on_store_press(self) -> None: 164 from bastd.ui.account import show_sign_in_prompt 165 from bastd.ui.store.browser import StoreBrowserWindow 166 167 if ba.internal.get_v1_account_state() != 'signed_in': 168 show_sign_in_prompt() 169 return 170 self._transition_out() 171 StoreBrowserWindow( 172 modal=True, 173 show_tab=StoreBrowserWindow.TabID.ICONS, 174 origin_widget=self._get_more_icons_button, 175 ) 176 177 def _select_icon(self, icon: str) -> None: 178 if self._delegate is not None: 179 self._delegate.on_icon_picker_pick(icon) 180 self._transition_out() 181 182 def _transition_out(self) -> None: 183 if not self._transitioning_out: 184 self._transitioning_out = True 185 ba.containerwidget(edit=self.root_widget, transition='out_scale') 186 187 def on_popup_cancel(self) -> None: 188 ba.playsound(ba.getsound('swish')) 189 self._transition_out()
Picker for icons.
IconPicker( parent: _ba.Widget, position: tuple[float, float] = (0.0, 0.0), delegate: Any = None, scale: float | None = None, offset: tuple[float, float] = (0.0, 0.0), tint_color: Sequence[float] = (1.0, 1.0, 1.0), tint2_color: Sequence[float] = (1.0, 1.0, 1.0), selected_icon: str | None = None)
22 def __init__( 23 self, 24 parent: ba.Widget, 25 position: tuple[float, float] = (0.0, 0.0), 26 delegate: Any = None, 27 scale: float | None = None, 28 offset: tuple[float, float] = (0.0, 0.0), 29 tint_color: Sequence[float] = (1.0, 1.0, 1.0), 30 tint2_color: Sequence[float] = (1.0, 1.0, 1.0), 31 selected_icon: str | None = None, 32 ): 33 # pylint: disable=too-many-locals 34 del parent # unused here 35 del tint_color # unused_here 36 del tint2_color # unused here 37 uiscale = ba.app.ui.uiscale 38 if scale is None: 39 scale = ( 40 1.85 41 if uiscale is ba.UIScale.SMALL 42 else 1.65 43 if uiscale is ba.UIScale.MEDIUM 44 else 1.23 45 ) 46 47 self._delegate = delegate 48 self._transitioning_out = False 49 50 self._icons = [ 51 ba.charstr(ba.SpecialChar.LOGO) 52 ] + ba.app.accounts_v1.get_purchased_icons() 53 count = len(self._icons) 54 columns = 4 55 rows = int(math.ceil(float(count) / columns)) 56 57 button_width = 50 58 button_height = 50 59 button_buffer_h = 10 60 button_buffer_v = 5 61 62 self._width = 10 + columns * (button_width + 2 * button_buffer_h) * ( 63 1.0 / 0.95 64 ) * (1.0 / 0.8) 65 self._height = self._width * ( 66 0.8 if uiscale is ba.UIScale.SMALL else 1.06 67 ) 68 69 self._scroll_width = self._width * 0.8 70 self._scroll_height = self._height * 0.8 71 self._scroll_position = ( 72 (self._width - self._scroll_width) * 0.5, 73 (self._height - self._scroll_height) * 0.5, 74 ) 75 76 # creates our _root_widget 77 popup.PopupWindow.__init__( 78 self, 79 position=position, 80 size=(self._width, self._height), 81 scale=scale, 82 bg_color=(0.5, 0.5, 0.5), 83 offset=offset, 84 focus_position=self._scroll_position, 85 focus_size=(self._scroll_width, self._scroll_height), 86 ) 87 88 self._scrollwidget = ba.scrollwidget( 89 parent=self.root_widget, 90 size=(self._scroll_width, self._scroll_height), 91 color=(0.55, 0.55, 0.55), 92 highlight=False, 93 position=self._scroll_position, 94 ) 95 ba.containerwidget(edit=self._scrollwidget, claims_left_right=True) 96 97 self._sub_width = self._scroll_width * 0.95 98 self._sub_height = ( 99 5 + rows * (button_height + 2 * button_buffer_v) + 100 100 ) 101 self._subcontainer = ba.containerwidget( 102 parent=self._scrollwidget, 103 size=(self._sub_width, self._sub_height), 104 background=False, 105 ) 106 index = 0 107 for y in range(rows): 108 for x in range(columns): 109 pos = ( 110 x * (button_width + 2 * button_buffer_h) + button_buffer_h, 111 self._sub_height 112 - (y + 1) * (button_height + 2 * button_buffer_v) 113 + 0, 114 ) 115 btn = ba.buttonwidget( 116 parent=self._subcontainer, 117 button_type='square', 118 size=(button_width, button_height), 119 autoselect=True, 120 text_scale=1.2, 121 label='', 122 color=(0.65, 0.65, 0.65), 123 on_activate_call=ba.Call( 124 self._select_icon, self._icons[index] 125 ), 126 position=pos, 127 ) 128 ba.textwidget( 129 parent=self._subcontainer, 130 h_align='center', 131 v_align='center', 132 size=(0, 0), 133 position=(pos[0] + 0.5 * button_width - 1, pos[1] + 15), 134 draw_controller=btn, 135 text=self._icons[index], 136 scale=1.8, 137 ) 138 ba.widget(edit=btn, show_buffer_top=60, show_buffer_bottom=60) 139 if self._icons[index] == selected_icon: 140 ba.containerwidget( 141 edit=self._subcontainer, 142 selected_child=btn, 143 visible_child=btn, 144 ) 145 index += 1 146 147 if index >= count: 148 break 149 if index >= count: 150 break 151 self._get_more_icons_button = btn = ba.buttonwidget( 152 parent=self._subcontainer, 153 size=(self._sub_width * 0.8, 60), 154 position=(self._sub_width * 0.1, 30), 155 label=ba.Lstr(resource='editProfileWindow.getMoreIconsText'), 156 on_activate_call=self._on_store_press, 157 color=(0.6, 0.6, 0.6), 158 textcolor=(0.8, 0.8, 0.8), 159 autoselect=True, 160 ) 161 ba.widget(edit=btn, show_buffer_top=30, show_buffer_bottom=30)