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 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 42 if uiscale is bui.UIScale.MEDIUM 43 else 1.23 44 ) 45 46 self._delegate = delegate 47 self._transitioning_out = False 48 49 assert bui.app.classic is not None 50 self._icons = [ 51 bui.charstr(bui.SpecialChar.LOGO) 52 ] + bui.app.classic.accounts.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 bui.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 super().__init__( 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 = bui.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 bui.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 = bui.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 = bui.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=bui.Call( 123 self._select_icon, self._icons[index] 124 ), 125 position=pos, 126 ) 127 bui.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 bui.widget(edit=btn, show_buffer_top=60, show_buffer_bottom=60) 138 if self._icons[index] == selected_icon: 139 bui.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 = bui.buttonwidget( 151 parent=self._subcontainer, 152 size=(self._sub_width * 0.8, 60), 153 position=(self._sub_width * 0.1, 30), 154 label=bui.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 bui.widget(edit=btn, show_buffer_top=30, show_buffer_bottom=30) 161 162 def _on_store_press(self) -> None: 163 from bauiv1lib.account import show_sign_in_prompt 164 from bauiv1lib.store.browser import StoreBrowserWindow 165 166 plus = bui.app.plus 167 assert plus is not None 168 169 if plus.get_v1_account_state() != 'signed_in': 170 show_sign_in_prompt() 171 return 172 self._transition_out() 173 StoreBrowserWindow( 174 modal=True, 175 show_tab=StoreBrowserWindow.TabID.ICONS, 176 origin_widget=self._get_more_icons_button, 177 ) 178 179 def _select_icon(self, icon: str) -> None: 180 if self._delegate is not None: 181 self._delegate.on_icon_picker_pick(icon) 182 self._transition_out() 183 184 def _transition_out(self) -> None: 185 if not self._transitioning_out: 186 self._transitioning_out = True 187 bui.containerwidget(edit=self.root_widget, transition='out_scale') 188 189 def on_popup_cancel(self) -> None: 190 bui.getsound('swish').play() 191 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 43 if uiscale is bui.UIScale.MEDIUM 44 else 1.23 45 ) 46 47 self._delegate = delegate 48 self._transitioning_out = False 49 50 assert bui.app.classic is not None 51 self._icons = [ 52 bui.charstr(bui.SpecialChar.LOGO) 53 ] + bui.app.classic.accounts.get_purchased_icons() 54 count = len(self._icons) 55 columns = 4 56 rows = int(math.ceil(float(count) / columns)) 57 58 button_width = 50 59 button_height = 50 60 button_buffer_h = 10 61 button_buffer_v = 5 62 63 self._width = 10 + columns * (button_width + 2 * button_buffer_h) * ( 64 1.0 / 0.95 65 ) * (1.0 / 0.8) 66 self._height = self._width * ( 67 0.8 if uiscale is bui.UIScale.SMALL else 1.06 68 ) 69 70 self._scroll_width = self._width * 0.8 71 self._scroll_height = self._height * 0.8 72 self._scroll_position = ( 73 (self._width - self._scroll_width) * 0.5, 74 (self._height - self._scroll_height) * 0.5, 75 ) 76 77 # creates our _root_widget 78 super().__init__( 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 = bui.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 bui.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 = bui.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 = bui.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=bui.Call( 124 self._select_icon, self._icons[index] 125 ), 126 position=pos, 127 ) 128 bui.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 bui.widget(edit=btn, show_buffer_top=60, show_buffer_bottom=60) 139 if self._icons[index] == selected_icon: 140 bui.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 = bui.buttonwidget( 152 parent=self._subcontainer, 153 size=(self._sub_width * 0.8, 60), 154 position=(self._sub_width * 0.1, 30), 155 label=bui.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 bui.widget(edit=btn, show_buffer_top=30, show_buffer_bottom=30) 162 163 def _on_store_press(self) -> None: 164 from bauiv1lib.account import show_sign_in_prompt 165 from bauiv1lib.store.browser import StoreBrowserWindow 166 167 plus = bui.app.plus 168 assert plus is not None 169 170 if plus.get_v1_account_state() != 'signed_in': 171 show_sign_in_prompt() 172 return 173 self._transition_out() 174 StoreBrowserWindow( 175 modal=True, 176 show_tab=StoreBrowserWindow.TabID.ICONS, 177 origin_widget=self._get_more_icons_button, 178 ) 179 180 def _select_icon(self, icon: str) -> None: 181 if self._delegate is not None: 182 self._delegate.on_icon_picker_pick(icon) 183 self._transition_out() 184 185 def _transition_out(self) -> None: 186 if not self._transitioning_out: 187 self._transitioning_out = True 188 bui.containerwidget(edit=self.root_widget, transition='out_scale') 189 190 def on_popup_cancel(self) -> None: 191 bui.getsound('swish').play() 192 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 43 if uiscale is bui.UIScale.MEDIUM 44 else 1.23 45 ) 46 47 self._delegate = delegate 48 self._transitioning_out = False 49 50 assert bui.app.classic is not None 51 self._icons = [ 52 bui.charstr(bui.SpecialChar.LOGO) 53 ] + bui.app.classic.accounts.get_purchased_icons() 54 count = len(self._icons) 55 columns = 4 56 rows = int(math.ceil(float(count) / columns)) 57 58 button_width = 50 59 button_height = 50 60 button_buffer_h = 10 61 button_buffer_v = 5 62 63 self._width = 10 + columns * (button_width + 2 * button_buffer_h) * ( 64 1.0 / 0.95 65 ) * (1.0 / 0.8) 66 self._height = self._width * ( 67 0.8 if uiscale is bui.UIScale.SMALL else 1.06 68 ) 69 70 self._scroll_width = self._width * 0.8 71 self._scroll_height = self._height * 0.8 72 self._scroll_position = ( 73 (self._width - self._scroll_width) * 0.5, 74 (self._height - self._scroll_height) * 0.5, 75 ) 76 77 # creates our _root_widget 78 super().__init__( 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 = bui.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 bui.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 = bui.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 = bui.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=bui.Call( 124 self._select_icon, self._icons[index] 125 ), 126 position=pos, 127 ) 128 bui.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 bui.widget(edit=btn, show_buffer_top=60, show_buffer_bottom=60) 139 if self._icons[index] == selected_icon: 140 bui.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 = bui.buttonwidget( 152 parent=self._subcontainer, 153 size=(self._sub_width * 0.8, 60), 154 position=(self._sub_width * 0.1, 30), 155 label=bui.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 bui.widget(edit=btn, show_buffer_top=30, show_buffer_bottom=30)
def
on_popup_cancel(self) -> None:
Called when the popup is canceled.
Cancels can occur due to clicking outside the window, hitting escape, etc.