baseCardSectionContainer.py (10570B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\cosmetics\ship\controls\baseCardSectionContainer.py 2 import carbonui.text.styles 3 import logging 4 import carbonui 5 import uthread2 6 from carbonui import Align, TextColor, Density, TextAlign 7 from carbonui.button.group import ButtonGroup 8 from carbonui.control.baseScrollContEntry import LazyLoadVerticalMixin 9 from carbonui.control.button import Button 10 from carbonui.primitives.container import Container 11 from carbonui.primitives.containerAutoSize import ContainerAutoSize 12 from carbonui.primitives.flowcontainer import FlowContainer 13 from carbonui.primitives.layoutGrid import LayoutGrid 14 from carbonui.services import deviceSignals 15 from carbonui.uianimations import animations 16 from eve.client.script.ui.control.eveLoadingWheel import LoadingWheel 17 from eve.client.script.ui.cosmetics.ship.pages import current_page 18 from eve.client.script.ui.cosmetics.ship.pages.cards import cardConst 19 from eve.client.script.ui.cosmetics.ship.pages.store.paginationButtons import PaginationButtons 20 from localization import GetByLabel 21 log = logging.getLogger(__name__) 22 23 class BaseCardSectionContainer(ContainerAutoSize, LazyLoadVerticalMixin): 24 default_height = 290 25 default_minHeight = 290 26 default_alignMode = Align.TOTOP 27 28 def __init__(self, section_controller = None, single_row = False, **kw): 29 super(BaseCardSectionContainer, self).__init__(**kw) 30 self._set_section_controller(section_controller) 31 self.reconstruct_listings_thread = None 32 self.cards = [] 33 self.emptyCards = [] 34 self.pagination_buttons = None 35 self.single_row = single_row 36 self.selected_card = None 37 self.connect_signals() 38 39 def _set_section_controller(self, section_controller = None): 40 self.section_controller = section_controller 41 42 def lazy_load(self): 43 self.construct_layout() 44 self.update() 45 46 def connect_signals(self): 47 deviceSignals.on_end_change_device.connect(self.on_end_change_device) 48 self.on_size_changed.connect(self._on_size_changed) 49 50 def disconnect_signals(self): 51 deviceSignals.on_end_change_device.disconnect(self.on_end_change_device) 52 53 def on_end_change_device(self): 54 if self.IsVisible(): 55 self.reconstruct_cards() 56 57 def _on_size_changed(self, width, height): 58 if not self.single_row: 59 return 60 if not self.IsVisible(): 61 return 62 num_per_page = self.get_num_cards_per_row() 63 if self.section_controller.num_per_page < num_per_page: 64 self.reconstruct_cards() 65 return 66 allCards = self.cards + self.emptyCards 67 for i, card in enumerate(allCards): 68 if i < num_per_page: 69 card.Show() 70 else: 71 card.Hide() 72 73 def Close(self): 74 try: 75 if self.reconstruct_listings_thread: 76 self.reconstruct_listings_thread.kill() 77 self.disconnect_signals() 78 finally: 79 super(BaseCardSectionContainer, self).Close() 80 81 def update(self): 82 if not self.is_loaded: 83 return 84 self.reconstruct_cards() 85 uthread2.start_tasklet(self.update_values) 86 87 def update_values(self): 88 self.header_name_label.text = self.section_controller.get_name() 89 self.update_num_items_label() 90 91 def update_num_items_label(self): 92 num_listings = self.section_controller.get_num_entries() 93 if num_listings: 94 self.num_items_label.text = GetByLabel('UI/Personalization/ShipSkins/SKINR/NumItems', num_items=num_listings) 95 96 def construct_layout(self): 97 self.top_cont = Container(name='top_cont', parent=self, align=Align.TOTOP, alignMode=Align.CENTERRIGHT, height=32) 98 self.construct_top_right_buttons() 99 self.construct_top_cont() 100 self.construct_loading_indicators() 101 self.content_overlay = Container(name='content_overlay', parent=self, padTop=24) 102 self.content = FlowContainer(name='content', parent=self, align=Align.TOTOP, height=128, padTop=24, contentSpacing=(16, 16)) 103 104 def construct_loading_indicators(self): 105 self.loading_cont = Container(name='loading_cont', parent=self, align=Align.TOTOP_NOPUSH, display=False, padding=(8, 0, 8, 0), height=self._get_card_height(), opacity=0.0) 106 LoadingWheel(parent=self.loading_cont, align=Align.CENTER) 107 self.no_content_caption = carbonui.text.styles.TextHeader(parent=self.loading_cont, align=Align.CENTER, padding=(0, 8, 0, 8), text=GetByLabel('UI/Common/NothingFound'), textAlign=TextAlign.CENTER, color=TextColor.SECONDARY, display=False) 108 109 def _get_card_height(self): 110 return cardConst.card_height 111 112 def construct_top_right_buttons(self): 113 self.top_right_cont = ContainerAutoSize(name='top_right_buttons', parent=self.top_cont, align=Align.TORIGHT) 114 self.top_right_buttons = ButtonGroup(parent=self.top_right_cont, align=Align.CENTERRIGHT, density=Density.COMPACT) 115 116 def reconstruct_cards(self, page_num = None): 117 if not self.is_loaded: 118 return 119 if self.reconstruct_listings_thread: 120 self.reconstruct_listings_thread.kill() 121 self.reconstruct_listings_thread = uthread2.start_tasklet(self._reconstruct_cards, page_num) 122 123 def _reconstruct_cards(self, page_num): 124 for card in self.cards: 125 if card.is_selected: 126 self.selected_card = card 127 break 128 129 if self.single_row: 130 self.section_controller.num_per_page = self.get_num_cards_per_row() 131 card_controllers = self._get_controllers_to_show(page_num) 132 self.update_pagination_buttons() 133 self.content.Flush() 134 self.content_overlay.Flush() 135 self.cards = [] 136 self.emptyCards = [] 137 if card_controllers: 138 self.no_content_caption.display = False 139 self.construct_cards(card_controllers) 140 else: 141 self.construct_empty_state() 142 143 def verify_cards(self): 144 for card in self.cards: 145 if not card.finished_loading: 146 card.construct_live_rendered_icon_sprite() 147 148 def get_num_cards_per_row(self): 149 width, _ = self.GetAbsoluteSize() 150 num_cards = (width + 16) / (cardConst.card_width + 16) 151 return max(1, num_cards) 152 153 def update_pagination_buttons(self): 154 self._check_construct_pagination_buttons() 155 if self.pagination_buttons or not self.section_controller.is_paginated(): 156 if self.pagination_buttons: 157 if self.section_controller.is_paginated(): 158 self.pagination_buttons.Show() 159 else: 160 self.pagination_buttons.Hide() 161 162 def construct_empty_state(self): 163 card_class = self.section_controller.blank_card_class 164 self.no_content_caption.display = False 165 if card_class: 166 for i in range(self.get_num_cards_per_row()): 167 emptyCard = card_class(parent=self.content) 168 self.emptyCards.append(emptyCard) 169 170 def construct_cards(self, card_controllers): 171 for card_controller in card_controllers: 172 card = self.construct_card(card_controller) 173 self.cards.append(card) 174 if self.selected_card and card.name == self.selected_card.name: 175 card.is_selected = True 176 177 if not self.section_controller.is_paginated(): 178 empty_cards_to_add = self.get_num_cards_per_row() - len(card_controllers) 179 if empty_cards_to_add > 0: 180 for i in range(empty_cards_to_add): 181 emptyCard = self.section_controller.blank_card_class(parent=self.content) 182 self.emptyCards.append(emptyCard) 183 184 def _check_construct_pagination_buttons(self): 185 if self.pagination_buttons: 186 return 187 self.construct_pagination_container() 188 self.pagination_buttons = PaginationButtons(parent=self.pagination_container, align=Align.CENTER, pagination_controller=self.section_controller.pagination_controller, density=Density.COMPACT) 189 self.pagination_buttons.on_page_selected.connect(self.on_page_selected) 190 191 def construct_pagination_container(self): 192 self.pagination_container = ContainerAutoSize(name='pagination_container', parent=self.top_cont, align=Align.TORIGHT) 193 194 def on_page_selected(self, page_num): 195 self.reconstruct_cards(page_num) 196 197 def construct_card(self, card_controller): 198 pass 199 200 def _get_controllers_to_show(self, page_num = None): 201 try: 202 self.loading_cont.display = True 203 animations.FadeIn(self.loading_cont, duration=0.3, timeOffset=0.1) 204 controllers = self.section_controller.get_card_controllers(page_num) 205 except Exception as e: 206 log.exception(e) 207 return 208 finally: 209 animations.FadeOut(self.loading_cont, duration=0.3, callback=self.loading_cont.Hide) 210 211 return controllers 212 213 def construct_top_cont(self): 214 self.construct_header() 215 self.construct_top_right_button() 216 self.filter_and_sorting_cont = ContainerAutoSize(parent=self.top_cont, align=Align.TORIGHT, padding=(8, 0, 8, 0)) 217 self.construct_filter_and_sorting() 218 219 def construct_header(self): 220 self.construct_header_layout_grid() 221 self.construct_header_name_label() 222 self.construct_header_num_items_label() 223 224 def construct_header_layout_grid(self): 225 self.header_layout_grid = LayoutGrid(parent=self.top_cont, align=Align.CENTERLEFT, cellSpacing=8, columns=2) 226 227 def construct_header_name_label(self): 228 self.header_name_label = carbonui.text.styles.TextHeadline(parent=self.header_layout_grid, align=Align.CENTERLEFT) 229 230 def construct_header_num_items_label(self): 231 self.num_items_label = carbonui.text.styles.TextBody(parent=self.header_layout_grid, align=Align.CENTERLEFT, color=TextColor.SECONDARY) 232 233 def construct_filter_and_sorting(self): 234 pass 235 236 def construct_top_right_button(self): 237 if self.single_row: 238 page_id, page_args = self.section_controller.get_page_id_and_args() 239 Button(name='view_more_btn', parent=self.top_right_buttons, label=GetByLabel('UI/Common/ViewMore'), func=lambda *args: current_page.set_page_id(page_id, page_args)) 240 else: 241 Button(name='view_more_btn', parent=self.top_right_buttons, label=GetByLabel('UI/Commands/Back'), func=lambda *args: current_page.go_back())