paintLibraryPanel.py (8748B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\cosmetics\structure\components\paintLibraryPanel.py 2 import uthread2 3 from carbonui import const as uiconst 4 from carbonui.control.scrollContainer import ScrollContainer 5 from carbonui.control.checkbox import Checkbox 6 from carbonui.primitives.container import Container 7 from carbonui.primitives.containerAutoSize import ContainerAutoSize 8 from carbonui.primitives.flowcontainer import FlowContainer 9 from carbonui.primitives.line import Line 10 from eve.client.script.ui import eveColor 11 from eve.client.script.ui.control.eveLabel import EveLabelLarge 12 from eve.client.script.ui.cosmetics.structure import const as paintToolConst 13 from eve.client.script.ui.cosmetics.structure import paintToolSelections 14 from eve.client.script.ui.cosmetics.structure.components.paintCard import PaintCard, CARD_WIDTH, CARD_HEIGHT 15 from eve.client.script.ui.util.uix import GetTextHeight 16 from localization import GetByLabel 17 from paints.data import dataLoader as paintsDataLoader 18 CONTENT_SPACING = 8 19 HEADER_ID_MATTE = 'matte' 20 HEADER_ID_COATED = 'coated' 21 HEADER_ID_SATIN = 'satin' 22 23 class PaintLibraryPanel(Container): 24 25 def __init__(self, target_slot, **kw): 26 self._target_slot_id = None 27 self._selected_paint_id = None 28 self._paint_cards = {} 29 self._name_checkbox = None 30 self._loading_thread = None 31 self.set_target_slot(target_slot) 32 super(PaintLibraryPanel, self).__init__(**kw) 33 self._construct_layout() 34 35 def Close(self): 36 if self._loading_thread is not None: 37 self._loading_thread.kill() 38 self._loading_thread = None 39 for paint_card in self._paint_cards.itervalues(): 40 paint_card.on_paint_card_clicked.disconnect(self._on_paint_card_clicked) 41 42 super(PaintLibraryPanel, self).Close() 43 44 def _construct_layout(self): 45 top_cont = ContainerAutoSize(parent=self, name='topCont', align=uiconst.TOTOP, padBottom=8, padRight=24) 46 self._slot_label = EveLabelLarge(parent=top_cont, name='slotLabel', align=uiconst.TOTOP, padBottom=8, color=eveColor.WHITE) 47 Line(parent=top_cont, align=uiconst.TOTOP, color=eveColor.WHITE, opacity=0.1, padBottom=8) 48 self._name_checkbox = Checkbox(parent=top_cont, align=uiconst.TOTOP, text=GetByLabel('UI/Personalization/PaintTool/PaintLibrary/ShowNames'), checked=settings.user.ui.Get('paintLibraryPanel_showNames', True), callback=self._on_name_checkbox_change, padBottom=8) 49 matte_text = GetByLabel('UI/Personalization/PaintTool/PaintLibrary/Finishes/Matte') 50 coated_text = GetByLabel('UI/Personalization/PaintTool/PaintLibrary/Finishes/Coated') 51 satin_text = GetByLabel('UI/Personalization/PaintTool/PaintLibrary/Finishes/Satin') 52 font_size = EveLabelLarge.default_fontsize 53 font_style = EveLabelLarge.default_fontStyle 54 matte_text_height = GetTextHeight(matte_text, fontsize=font_size, fontStyle=font_style, width=CARD_WIDTH) 55 coated_text_height = GetTextHeight(coated_text, fontsize=font_size, fontStyle=font_style, width=CARD_WIDTH) 56 satin_text_height = GetTextHeight(satin_text, fontsize=font_size, fontStyle=font_style, width=CARD_WIDTH) 57 header_height = max(max(matte_text_height, coated_text_height), satin_text_height) 58 self._headers_cont = Container(parent=top_cont, name='headersCont', align=uiconst.TOTOP, height=header_height) 59 self._add_header(HEADER_ID_MATTE, matte_text) 60 self._add_header(HEADER_ID_COATED, coated_text) 61 self._add_header(HEADER_ID_SATIN, satin_text) 62 self._scroll_cont = ScrollContainer(parent=self, name='scrollCont') 63 self._cards_cont = FlowContainer(name='cardsLibraryCont', parent=self._scroll_cont, align=uiconst.TOTOP, contentSpacing=(CONTENT_SPACING, CONTENT_SPACING), padBottom=8) 64 self._loading_thread = uthread2.StartTasklet(self._load_paints_thread) 65 66 def _add_header(self, header_id, label): 67 EveLabelLarge(parent=self._headers_cont, name='label_%s' % header_id, align=uiconst.TOLEFT, text=label, width=CARD_WIDTH, padRight=CONTENT_SPACING) 68 69 def _load_paints_thread(self): 70 try: 71 for i, paint_id in enumerate(self._get_sorted_paints()): 72 paint_card = PaintCard(parent=self._cards_cont, name='paint_card_%s' % paint_id, align=uiconst.NOALIGN, paint_id=paint_id, width=CARD_WIDTH, height=CARD_HEIGHT, index=i) 73 self._paint_cards[paint_id] = paint_card 74 paint_card.on_paint_card_clicked.connect(self._on_paint_card_clicked) 75 76 finally: 77 self._loading_thread = None 78 self._update_card_names() 79 80 def _get_sorted_paints(self): 81 82 def _get_paint_order(paint_id): 83 material_name = paintsDataLoader.get_paint_material_name(paint_id) 84 finish = paintsDataLoader.get_paint_finish(paint_id) 85 if finish == 'matt': 86 return 1 87 if finish == 'coated': 88 return 2 89 if finish == 'satin': 90 return 3 91 92 def _sort_hues(val): 93 return val['hue_value'] 94 95 def _sort_paints(val): 96 return val['order'] 97 98 paints = paintsDataLoader.get_paint_ids() 99 paint_by_hues = [] 100 for hue_id in paintsDataLoader.get_hue_category_ids(): 101 paint_by_hues.append({'hue_id': hue_id, 102 'hue_value': paintsDataLoader.get_hue_category_hue(hue_id), 103 'paints': sorted([ {'paint_id': p, 104 'material_name': paintsDataLoader.get_paint_material_name(p), 105 'finish': paintsDataLoader.get_paint_finish(p), 106 'order': _get_paint_order(p)} for p in paints if paintsDataLoader.get_paint_hue_category(p) == hue_id ], key=_sort_paints)}) 107 108 paint_by_hues.sort(key=_sort_hues) 109 sorted_paints = [] 110 for hue_dict in paint_by_hues: 111 grouped_paints = {} 112 for paint in hue_dict['paints']: 113 hsb_suffix = '_'.join(paint['material_name'].split('_')[-3:]) 114 if hsb_suffix not in grouped_paints: 115 grouped_paints[hsb_suffix] = [paint] 116 else: 117 grouped_paints[hsb_suffix].append(paint) 118 119 for group in grouped_paints.values(): 120 group.sort(key=lambda p: p['order']) 121 sorted_paints.extend([ p['paint_id'] for p in group ]) 122 123 return sorted_paints 124 125 def set_target_slot(self, slot_id): 126 self._target_slot_id = slot_id 127 if self._target_slot_id is not None: 128 self._selected_paint_id = paintToolSelections.SELECTED_PAINTWORK.get_slot(self._target_slot_id) 129 slot_name = GetByLabel(paintToolConst.PAINT_SLOT_NAMES[self._target_slot_id]) 130 self._slot_label.text = GetByLabel('UI/Personalization/PaintTool/PaintLibrary/PaintSelection', slotName=slot_name) 131 if self._selected_paint_id is not None: 132 self._scroll_to(self._selected_paint_id) 133 else: 134 self._selected_paint_id = None 135 self._slot_label = '' 136 for paint_id, paint_card in self._paint_cards.iteritems(): 137 paint_card.set_selected(paint_id == self._selected_paint_id) 138 139 def _on_paint_card_clicked(self, paint_id): 140 if self._selected_paint_id: 141 self._paint_cards[self._selected_paint_id].set_selected(False) 142 if paint_id == self._selected_paint_id: 143 self._selected_paint_id = None 144 else: 145 self._selected_paint_id = paint_id 146 if self._selected_paint_id: 147 self._paint_cards[self._selected_paint_id].set_selected(True) 148 paintToolSelections.select_paint_slot(slot_id=self._target_slot_id, paint_id=self._selected_paint_id) 149 150 def _scroll_to(self, paint_id): 151 paint_card = self._paint_cards.get(paint_id, None) 152 if paint_card: 153 scroll_position = float(paint_card.index) / float(len(self._paint_cards)) 154 if scroll_position < 0.1: 155 scroll_position = 0.0 156 elif scroll_position > 0.9: 157 scroll_position = 1.0 158 self._scroll_cont.ScrollToVertical(scroll_position) 159 160 def _update_card_names(self): 161 if not self._name_checkbox: 162 return 163 selected = self._name_checkbox.GetValue() 164 settings.user.ui.Set('paintLibraryPanel_showNames', selected) 165 for paint_card in self._paint_cards.values(): 166 paint_card.is_label_visible(selected) 167 168 self._scroll_cont.UpdateAlignment() 169 170 def _on_name_checkbox_change(self, *args): 171 self._update_card_names() 172 self._scroll_to(self._selected_paint_id)