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