combo.py (27760B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\control\combo.py 2 import logging 3 import random 4 import weakref 5 import blue 6 import eveformat 7 import eveicon 8 import localization 9 import uthread 10 from carbon.client.script.environment.AudioUtil import PlaySound 11 from carbonui import fontconst, uiconst 12 from carbonui.button import styling 13 from carbonui.button.const import HEIGHT_NORMAL 14 from carbonui.control.comboEntries import ComboCaptionEntry, ComboEntry, ComboSeparatorEntry 15 from carbonui.control.comboEntryData import BaseComboEntryData, ComboEntryData, ComboEntryDataCaption, ComboEntryDataSeparator, ComboEntryDataText 16 from carbonui.control.contextMenu.menuUtil import ClearMenuLayer 17 from carbonui.control.scrollentries import ScrollEntryNode 18 from carbonui.primitives.container import Container 19 from carbonui.primitives.frame import Frame 20 from carbonui.primitives.line import Line 21 from carbonui.text.color import TextColor 22 from carbonui.uianimations import animations 23 from carbonui.uiconst import Density 24 from carbonui.uicore import uicore 25 from carbonui.util.color import Color 26 from carbonui.util.various_unsorted import GetAttrs, GetBrowser 27 from eve.client.script.ui import eveColor 28 from eve.client.script.ui.control import eveLabel 29 from carbonui.decorative.blurredSceneUnderlay import BlurredSceneUnderlay 30 from carbonui.control.buttonIcon import ButtonIcon 31 from eve.client.script.ui.control.entries.text import Text 32 from eve.client.script.ui.control.eveIcon import Icon 33 from eve.client.script.ui.control.eveScroll import Scroll 34 from eve.client.script.ui.control.glowSprite import GlowSprite 35 log = logging.getLogger(__name__) 36 OPACITY_TEXT_IDLE = TextColor.NORMAL.opacity 37 OPACITY_TEXT_HOVER = 1.0 38 ALIGNMENTS_THAT_DONT_SUPPORT_AUTO_WIDTH = (uiconst.TOTOP, 39 uiconst.TOBOTTOM, 40 uiconst.TOALL, 41 uiconst.TOLEFT_PROP, 42 uiconst.TORIGHT_PROP) 43 44 class Combo(Container): 45 default_adjustWidth = True 46 default_align = uiconst.TOPLEFT 47 default_callback = None 48 default_cursor = uiconst.UICURSOR_SELECT 49 default_fontFamily = None 50 default_fontPath = None 51 default_fontStyle = None 52 default_fontsize = fontconst.EVE_MEDIUM_FONTSIZE 53 default_hasClearButton = False 54 default_iconOnly = False 55 default_label = '' 56 default_labelleft = None 57 default_maxVisibleEntries = 8 58 default_name = 'combo' 59 default_noChoiceLabel = None 60 default_nothingSelectedText = '' 61 default_options = [] 62 default_prefskey = None 63 default_select = None 64 default_state = uiconst.UI_NORMAL 65 default_width = 140 66 default_height = HEIGHT_NORMAL 67 default_density = Density.NORMAL 68 isTabStop = 1 69 _hovered = False 70 71 def ApplyAttributes(self, attributes): 72 self._comboDropDown = None 73 self._disabled = False 74 self._expanding = False 75 self.clearButton = None 76 self.selectedValue = None 77 self.sr.label = None 78 self._entries = None 79 self._hidden_values = [] 80 super(Combo, self).ApplyAttributes(attributes) 81 self.adjustWidth = attributes.get('adjustWidth', self.default_adjustWidth) 82 if self.align not in ALIGNMENTS_THAT_DONT_SUPPORT_AUTO_WIDTH and attributes.get('width', 0) > 0: 83 self.adjustWidth = False 84 self.prefskey = attributes.get('prefskey', self.default_prefskey) 85 self.fontStyle = attributes.get('fontStyle', self.default_fontStyle) 86 self.fontFamily = attributes.get('fontFamily', self.default_fontFamily) 87 self.fontPath = attributes.get('fontPath', self.default_fontPath) 88 self.fontsize = attributes.get('fontsize', self.default_fontsize) 89 self.iconOnly = attributes.get('iconOnly', self.default_iconOnly) 90 self.density = attributes.get('density', self.default_density) 91 options = attributes.get('options', self.default_options) 92 select = attributes.get('select', self.default_select) 93 self.maxVisibleEntries = attributes.get('maxVisibleEntries', self.default_maxVisibleEntries) 94 self.noChoiceLabel = attributes.Get('noChoiceLabel', self.default_noChoiceLabel) 95 self.nothingSelectedText = attributes.Get('nothingSelectedText', self.default_nothingSelectedText) 96 self.color = attributes.get('color', self.default_bgColor) 97 self.hasClearButton = attributes.get('hasClearButton', self.default_hasClearButton) 98 self.labelleft = attributes.get('labelleft', self.default_labelleft) 99 self.OnChange = attributes.get('callback', self.default_callback) 100 self.Prepare_() 101 self.SetLabel_(attributes.get('label', self.default_label)) 102 self.LoadOptions(options, select) 103 if self.adjustWidth and self.align not in ALIGNMENTS_THAT_DONT_SUPPORT_AUTO_WIDTH: 104 self.AutoAdjustWidth_() 105 elif self.align == uiconst.TOALL: 106 self.width = 0 107 else: 108 self.width = attributes.get('width', self.default_width) 109 if self.align in (uiconst.TOLEFT, uiconst.TORIGHT, uiconst.TOALL): 110 self.height = 0 111 else: 112 self.height = styling.get_height(self.density) 113 114 def Prepare_(self): 115 self.sr.content = Container(parent=self, name='__maincontent') 116 self.sr.iconParent = Container(parent=self.sr.content, name='iconParent', align=uiconst.TOLEFT, width=24, state=uiconst.UI_HIDDEN) 117 self.sr.selectedIcon = Icon(name='icon', parent=self.sr.iconParent, align=uiconst.CENTERRIGHT, state=uiconst.UI_DISABLED, width=16, height=16) 118 self.sr.textclipper = Container(name='__textclipper', parent=self.sr.content, align=uiconst.TOALL, padLeft=8, clipChildren=True) 119 self.Prepare_SelectedText_() 120 self.Prepare_Expander_() 121 self.Prepare_Underlay_() 122 self.Prepare_Label_() 123 124 def Prepare_SelectedText_(self): 125 self.sr.selected = eveLabel.EveLabelMedium(name='value', parent=self.sr.textclipper, align=uiconst.CENTERLEFT, state=uiconst.UI_DISABLED, color=self._get_selected_color(), autoFadeSides=16) 126 127 def Prepare_Underlay_(self): 128 self.sr.backgroundFrame = ComboUnderlay(parent=self, align=uiconst.TOALL) 129 130 def Select(self, animate = True): 131 self.sr.backgroundFrame.Select() 132 133 def Deselect(self, animate = True): 134 self.sr.backgroundFrame.Deselect() 135 136 def Disable(self): 137 self._disabled = True 138 self.sr.backgroundFrame.SetDisabled() 139 self._update_selected_color() 140 141 def Enable(self): 142 self._disabled = False 143 self.sr.backgroundFrame.SetEnabled() 144 self._update_selected_color() 145 146 def Prepare_Expander_(self): 147 self.sr.expanderParent = Container(name='__expanderParent', parent=self.sr.content, align=uiconst.TORIGHT, state=uiconst.UI_DISABLED, width=16, padding=(8, 0, 8, 0), idx=0) 148 self.sr.expander = GlowSprite(parent=self.sr.expanderParent, align=uiconst.CENTER, texturePath='res:/UI/Texture/Icons/38_16_229.png', pos=(0, 0, 16, 16), opacity=0.8) 149 150 def Prepare_Label_(self): 151 self.sr.label = eveLabel.EveLabelSmall(text='', parent=self, name='label', top=-13, left=1, state=uiconst.UI_HIDDEN, idx=1, lineSpacing=-0.1) 152 153 def HideText(self): 154 self.sr.textclipper.state = uiconst.UI_HIDDEN 155 156 def Close(self, *args, **kwds): 157 self.Cleanup(0) 158 super(Combo, self).Close() 159 160 def Confirm(self, setfocus = 1): 161 self._TriggerCallback() 162 if not self.destroyed: 163 self.Cleanup(setfocus) 164 165 def OnUp(self, *args): 166 if not self._Expanded(): 167 self.Expand() 168 if self._Expanded(): 169 self._comboDropDown().sr.scroll.BrowseNodes(1) 170 171 def OnDown(self, *args): 172 if not self._Expanded(): 173 self.Expand() 174 if self._Expanded(): 175 self._comboDropDown().sr.scroll.BrowseNodes(0) 176 177 def SetHint(self, hint): 178 self.hint = hint 179 180 def SetLabel_(self, label): 181 if self.labelleft is not None: 182 self.padLeft = self.labelleft 183 self.sr.label.left = -self.labelleft 184 self.sr.label.width = self.labelleft - 6 185 if label: 186 self.sr.label.text = label 187 if self.labelleft is not None: 188 self.sr.label.top = 0 189 self.sr.label.SetAlign(uiconst.CENTERLEFT) 190 else: 191 self.sr.label.top = -self.sr.label.textheight 192 self.sr.label.state = uiconst.UI_DISABLED 193 else: 194 self.sr.label.state = uiconst.UI_HIDDEN 195 196 def OnSetFocus(self, *args): 197 if self and not self.destroyed and self.parent and self.parent.name == 'inlines': 198 if self.parent.parent and self.parent.parent.sr.node: 199 browser = GetBrowser(self) 200 if browser: 201 uthread.new(browser.ShowObject, self) 202 203 def LoadOptions(self, entries, select = None, hints = None): 204 if entries is None: 205 raise RuntimeError("'%s' combo option entries to load are None" % self.name) 206 self.entries = entries 207 screwed = [ each for each in self.entries if not isinstance(each.label, basestring) ] 208 if screwed: 209 raise RuntimeError("'%s' combo option keys are not strings: %s" % (self.name, repr(screwed))) 210 if not self.entries: 211 self.entries = [ComboEntryDataText(localization.GetByLabel('/Carbon/UI/Controls/Combo/NoChoices'))] 212 self.hints = hints 213 if not select and self.nothingSelectedText: 214 self.SetNothingSelected() 215 else: 216 self._SelectEntry(select) 217 self.AutoAdjustWidth_() 218 219 @property 220 def entries(self): 221 return self._entries 222 223 @entries.setter 224 def entries(self, value): 225 self._entries = self._ConvertTuplesToComboEntryData(value) 226 227 def _ConvertTuplesToComboEntryData(self, entries): 228 ret = [] 229 for entry in entries: 230 if not isinstance(entry, BaseComboEntryData): 231 entry = ComboEntryData(*entry) 232 ret.append(entry) 233 234 return ret 235 236 def SetNothingSelected(self): 237 self.selectedValue = None 238 self.sr.selected.text = self.nothingSelectedText 239 self._update_selected_color() 240 241 def _SelectEntry(self, select): 242 selectableEntries = self.GetSelectableEntries() 243 if not selectableEntries: 244 return 245 if select == '__random__': 246 select = random.choice(selectableEntries).returnValue 247 elif select is None: 248 select = selectableEntries[0].returnValue 249 success = self.SelectItemByValue(select) 250 if not success: 251 self.SelectItemByValue(selectableEntries[0].returnValue) 252 253 def _UpdateClearButton(self): 254 if not self.hasClearButton: 255 return 256 if self.selectedValue is not None: 257 self._CheckConstructClearButton() 258 self.clearButton.Show() 259 elif self.clearButton: 260 self.clearButton.Hide() 261 262 def _CheckConstructClearButton(self): 263 if not self.clearButton: 264 self.clearButton = ButtonIcon(parent=self, align=uiconst.CENTERRIGHT, left=24, width=24, height=24, iconSize=16, texturePath=eveicon.close, hint=localization.GetByLabel('UI/Calendar/Hints/Clear'), func=self.OnClearButton, idx=0) 265 266 def OnClearButton(self, *args): 267 self.SetNothingSelected() 268 self._UpdateClearButton() 269 self._TriggerCallback() 270 271 def _TriggerCallback(self): 272 if self.OnChange: 273 uthread.new(self.OnChange, self, self.GetKey(), self.GetValue()) 274 275 def AutoAdjustWidth_(self): 276 currentAlign = self.GetAlign() 277 if self.adjustWidth and self.entries and currentAlign not in ALIGNMENTS_THAT_DONT_SUPPORT_AUTO_WIDTH: 278 if self.iconOnly: 279 width = self.sr.iconParent.left + self.sr.iconParent.padLeft + self.sr.iconParent.width + self.sr.iconParent.padRight + self.sr.expanderParent.left + self.sr.expanderParent.padLeft + self.sr.expanderParent.width + self.sr.expanderParent.padRight 280 if self.hasClearButton: 281 width += self.clearButton.left + self.clearButton.padLeft + self.clearButton.width + self.clearButton.padRight 282 self.width = max(width, 32) 283 else: 284 horizontal_padding = self.sr.textclipper.left + self.sr.textclipper.padLeft + self.sr.textclipper.padRight 285 horizontal_padding += self.sr.expanderParent.left + self.sr.expanderParent.padLeft + self.sr.expanderParent.width + self.sr.expanderParent.padRight 286 if self.sr.iconParent.display: 287 horizontal_padding += self.sr.iconParent.left + self.sr.iconParent.padLeft + self.sr.iconParent.width + self.sr.iconParent.padRight 288 if self.hasClearButton: 289 horizontal_padding += 24 290 max_text_width = max((self.GetTextWidth(entry.label) for entry in self.entries)) 291 self.width = max(32, max_text_width) + horizontal_padding 292 293 def GetKey(self): 294 return self.sr.selected.text 295 296 def GetValue(self): 297 if self.selectedValue is not None: 298 return self.selectedValue 299 else: 300 return 301 302 def GetIndex(self): 303 if self.sr.selected.text: 304 i = 0 305 for entry in self.GetSelectableEntries(): 306 if entry.label == self.sr.selected.text: 307 return i 308 i += 1 309 310 def GetSelectedEntry(self): 311 if self.selectedValue is None: 312 return 313 for entry in self.GetSelectableEntries(): 314 if self.selectedValue == entry.returnValue: 315 return entry 316 317 def GetSelectableEntries(self): 318 return [ entry for entry in self.entries if isinstance(entry, ComboEntryData) ] 319 320 def SelectItemByIndex(self, i): 321 self.SelectItemByLabel(self.GetSelectableEntries()[i].label) 322 323 def SelectItemByLabel(self, label): 324 for each in self.GetSelectableEntries(): 325 if each.label == label: 326 self.UpdateSelectedValue(each) 327 return 328 329 raise RuntimeError('LabelNotInEntries', label) 330 331 def SelectItemByValue(self, val, triggerCallback = False): 332 for each in self.GetSelectableEntries(): 333 if each.returnValue == val: 334 self.UpdateSelectedValue(each) 335 if triggerCallback: 336 self._TriggerCallback() 337 return True 338 339 log.warn('Combo has no value %s', val) 340 return False 341 342 SetValue = SelectItemByValue 343 344 def UpdateSelectedValue(self, entry): 345 self.selectedValue = entry.returnValue 346 if not self.iconOnly: 347 self.sr.selected.text = entry.label 348 self._update_selected_color() 349 if entry.icon: 350 self.sr.selectedIcon.LoadIcon(entry.icon, ignoreSize=True) 351 self.sr.selectedIcon.rgba = entry.iconColor 352 self.sr.iconParent.state = uiconst.UI_DISABLED 353 else: 354 self.sr.iconParent.state = uiconst.UI_HIDDEN 355 if self.hasClearButton: 356 self._UpdateClearButton() 357 358 def UpdateSettings(self): 359 prefskey = self.prefskey 360 if prefskey is None: 361 return 362 config = prefskey[-1] 363 prefstype = prefskey[:-1] 364 s = GetAttrs(settings, *prefstype) 365 try: 366 s.Set(config, self.GetValue()) 367 except Exception: 368 log.error('Failed to assign setting to: %s, %s' % (prefstype, config)) 369 370 def _Expanded(self): 371 return bool(self._comboDropDown and self._comboDropDown()) 372 373 def OnMouseEnter(self, *args): 374 self._hovered = True 375 self._update_selected_color(duration=uiconst.TIME_ENTRY) 376 if self._disabled: 377 return 378 self.sr.backgroundFrame.OnMouseEnter() 379 self.sr.expander.OnMouseEnter() 380 PlaySound(uiconst.SOUND_BUTTON_HOVER) 381 382 def OnMouseExit(self, *args): 383 self._hovered = False 384 self.sr.backgroundFrame.OnMouseExit() 385 self.sr.expander.OnMouseExit() 386 self._update_selected_color(duration=uiconst.TIME_EXIT) 387 388 def OnMouseDown(self, *args): 389 self.sr.backgroundFrame.OnMouseDown() 390 391 def OnMouseUp(self, *args): 392 if self._disabled: 393 return 394 self.sr.backgroundFrame.OnMouseUp() 395 396 def OnClick(self, *args): 397 if len(self._hidden_values) >= len(self.GetSelectableEntries()): 398 return 399 if self._disabled: 400 return 401 if not self._Expanded(): 402 uthread.new(self.Expand) 403 404 def Prepare_OptionMenu_(self): 405 ClearMenuLayer() 406 self.ConstructOptionMenuContainer() 407 self.ConstructOptionMenuScroll() 408 self.ConstructOptionMenuBackground() 409 return (self.optionMenu, self.optionMenu.sr.scroll) 410 411 def ConstructOptionMenuBackground(self): 412 Frame(bgParent=self.optionMenu, texturePath='res:/UI/Texture/classes/combo/underlay_lower_stroke.png', cornerSize=9, color=eveColor.WHITE[:3] + (0.1,)) 413 BlurredSceneUnderlay(bgParent=self.optionMenu, isInFocus=True, color=Color.HextoRGBA('#ff0b0a12')) 414 415 def ConstructOptionMenuScroll(self): 416 self.optionMenu.sr.scroll = self._ConstructOptionMenuScroll() 417 self.optionMenu.sr.scroll.OnKillFocus = self.OnScrollFocusLost 418 self.optionMenu.sr.scroll.OnSelectionChange = self.OnScrollSelectionChange 419 self.optionMenu.sr.scroll.Confirm = self.Confirm 420 self.optionMenu.sr.scroll.OnUp = self.OnUp 421 self.optionMenu.sr.scroll.OnDown = self.OnDown 422 self.optionMenu.sr.scroll.OnRight = self.Confirm 423 self.optionMenu.sr.scroll.OnLeft = self.Confirm 424 self.optionMenu.sr.scroll.HideBackground() 425 self.optionMenu.sr.scroll.padding = (1, 0, 1, 1) 426 427 def _ConstructOptionMenuScroll(self): 428 return Scroll(parent=self.optionMenu, pushContent=False) 429 430 def ConstructOptionMenuContainer(self): 431 self.optionMenu = Container(parent=uicore.layer.menu, align=uiconst.RELATIVE) 432 433 def GetSelectedIcon(self): 434 for each in self.GetSelectableEntries(): 435 if each.returnValue == self.selectedValue: 436 return each.icon 437 438 def GetEntryClass(self): 439 return ComboEntry 440 441 def GetTextWidth(self, text): 442 width, _ = eveLabel.EveLabelMedium.MeasureTextSize(text) 443 return width 444 445 def GetEntryWidth(self, data): 446 width = self.GetTextWidth(data['label']) 447 if data['icon'] is not None: 448 width += 24 449 return width 450 451 def GetScrollEntry(self, entryData): 452 if isinstance(entryData, ComboEntryData): 453 return self._GetScrollEntryData(entryData) 454 if isinstance(entryData, ComboEntryDataCaption): 455 return self._GetScrollEntryDataCaption(entryData) 456 if isinstance(entryData, ComboEntryDataText): 457 return self._GetScrollEntryDataText(entryData) 458 if isinstance(entryData, ComboEntryDataSeparator): 459 return self._GetScrollEntryDataSeparator(entryData) 460 461 def _GetScrollEntryData(self, entryData): 462 if not entryData.hint and self.hints: 463 hint = self.hints.get(entryData.label, '') 464 else: 465 hint = entryData.GetHint() 466 data = {'OnClick': self.OnEntryClick, 467 'data': (entryData.label, entryData.returnValue), 468 'label': unicode(entryData.label), 469 'fontStyle': self.fontStyle, 470 'fontFamily': self.fontFamily, 471 'fontPath': self.fontPath, 472 'fontsize': self.fontsize, 473 'decoClass': self.GetEntryClass(), 474 'hideLines': True, 475 'icon': entryData.icon, 476 'iconColor': entryData.iconColor, 477 'indentLevel': entryData.indentLevel, 478 'loadTooltipFunc': entryData.GetLoadTooltipFunc(), 479 'hint': hint} 480 if entryData.returnValue == self.selectedValue: 481 data['isSelected'] = True 482 return data 483 484 def _GetScrollEntryDataText(self, entryData): 485 return {'label': entryData.label, 486 'text': entryData.label, 487 'icon': entryData.icon, 488 'decoClass': Text, 489 'hint': entryData.GetHint()} 490 491 def _GetScrollEntryDataCaption(self, entryData): 492 return {'label': entryData.label, 493 'text': entryData.label, 494 'icon': entryData.icon, 495 'decoClass': ComboCaptionEntry, 496 'hint': entryData.GetHint()} 497 498 def _GetScrollEntryDataSeparator(self, entryData): 499 return {'label': entryData.label, 500 'text': entryData.label, 501 'icon': entryData.icon, 502 'decoClass': ComboSeparatorEntry, 503 'hint': entryData.GetHint()} 504 505 def GetMaxEntryWidth(self, scrollEntries, w): 506 maxWidth = max([ self.GetEntryWidth(entry) for entry in scrollEntries ]) 507 return max(maxWidth + 24, w) 508 509 def GetScrollList(self): 510 scrolllist = [] 511 if self.noChoiceLabel and len(self.entries) == 1: 512 data = {'label': eveformat.color(self.noChoiceLabel, TextColor.SECONDARY), 513 'icon': None, 514 'selectable': False} 515 scrollEntry = ScrollEntryNode(**data) 516 scrolllist.append(scrollEntry) 517 else: 518 for entryData in self.entries: 519 if entryData.returnValue in self._hidden_values: 520 continue 521 label = entryData.label 522 if not label: 523 continue 524 data = self.GetScrollEntry(entryData) 525 scrollEntry = ScrollEntryNode(**data) 526 scrolllist.append(scrollEntry) 527 528 return scrolllist 529 530 def Expand(self, position = None): 531 if self._expanding: 532 return 533 try: 534 self._expanding = True 535 PlaySound(uiconst.SOUND_EXPAND) 536 menu, scroll = self.Prepare_OptionMenu_() 537 scrolllist = self.GetScrollList() 538 scroll.LoadContent(contentList=scrolllist) 539 if position: 540 l, t, w, h = position 541 else: 542 l, t, w, h = self.GetAbsolute() 543 menu.width = self.GetMaxEntryWidth(scrolllist, w) 544 totalHeight = self.GetScrollHeight(scroll) 545 menu.height = totalHeight + 2 + scroll.padTop + scroll.padBottom 546 menu.left = l 547 self.SetMenuTop(menu, t, h) 548 self._comboDropDown = weakref.ref(menu) 549 uthread.new(self.ShowSelected) 550 if hasattr(self.sr.backgroundFrame, 'Expand'): 551 self.sr.backgroundFrame.Expand(totalHeight) 552 return scroll 553 finally: 554 self._expanding = False 555 556 def GetScrollHeight(self, scroll): 557 return sum([ each.height for each in scroll.sr.nodes[:self.maxVisibleEntries] ]) 558 559 def SetMenuTop(self, menu, t, h): 560 if t + h + menu.height > uicore.desktop.height: 561 menu.top = t - menu.height 562 else: 563 menu.top = t + h 564 565 def GetExpanderIconWidth(self): 566 if self.sr.expanderParent: 567 return self.sr.expanderParent.width + self.sr.expanderParent.padLeft + self.sr.expanderParent.padRight 568 return 0 569 570 def ShowSelected(self, *args): 571 blue.synchro.Yield() 572 if self.destroyed or not self._comboDropDown(): 573 return 574 scroll = self._comboDropDown().sr.scroll 575 uicore.registry.SetFocus(scroll) 576 scroll.ScrollToSelectedNode() 577 578 def OnEntryClick(self, entry, *args): 579 PlaySound(uiconst.SOUND_BUTTON_CLICK) 580 key, val = entry.sr.node.data 581 self.SelectItemByValue(val) 582 self.Cleanup() 583 if self.OnChange: 584 self.OnChange(self, key, val) 585 586 def OnComboClose(self, *args): 587 self.Cleanup(0) 588 589 def Cleanup(self, setfocus = 1): 590 if self._comboDropDown: 591 ClearMenuLayer() 592 self._comboDropDown = None 593 try: 594 self.CollapseBackground() 595 except Exception: 596 log.exception("Failed to collapse the Combo's background") 597 598 if setfocus: 599 uicore.registry.SetFocus(self) 600 601 def OnScrollFocusLost(self, *args): 602 self.Confirm(setfocus=False) 603 604 def CollapseBackground(self): 605 if hasattr(self.sr.backgroundFrame, 'Collapse'): 606 self.sr.backgroundFrame.Collapse() 607 608 def OnScrollSelectionChange(self, selected): 609 if selected: 610 self.SelectItemByLabel(selected[0].label) 611 612 def OnChar(self, enteredChar, *args): 613 if enteredChar < 32 and enteredChar != uiconst.VK_RETURN: 614 return False 615 if not self._Expanded(): 616 scroll = self.Expand() 617 scroll.OnChar(enteredChar, *args) 618 return True 619 620 def Startup(self, *args): 621 pass 622 623 def _get_selected_color(self): 624 if self._disabled: 625 return TextColor.DISABLED 626 elif self._hovered: 627 return TextColor.HIGHLIGHT 628 elif self.selectedValue is None: 629 return TextColor.SECONDARY 630 else: 631 return TextColor.NORMAL 632 633 def _update_selected_color(self, duration = 0.3): 634 animations.SpColorMorphTo(self.sr.selected, endColor=self._get_selected_color(), duration=duration) 635 636 def HideEntry(self, entry_value): 637 if entry_value in self._hidden_values: 638 return 639 self._hidden_values.append(entry_value) 640 641 def ShowEntry(self, entry_value): 642 if entry_value in self._hidden_values: 643 self._hidden_values.remove(entry_value) 644 645 646 class SelectCore(Scroll): 647 648 def LoadEntries(self, entries): 649 scrolllist = [] 650 for entryName, entryValue, selected in entries: 651 scrolllist.append(ScrollEntryNode(label=entryName, value=entryValue, isSelected=selected)) 652 653 self.LoadContent(contentList=scrolllist) 654 655 def GetValue(self): 656 return [ node.value for node in self.GetSelected() ] or None 657 658 def SetValue(self, val): 659 if type(val) != list: 660 val = [val] 661 for node in self.GetNodes(): 662 if node.value in val: 663 self._SelectNode(node) 664 665 666 class ComboUnderlay(Container): 667 668 def __init__(self, parent = None, align = uiconst.TOALL): 669 super(ComboUnderlay, self).__init__(parent=parent, align=align) 670 self.strokeFrame = Frame(parent=self, texturePath='res:/UI/Texture/classes/combo/underlay_stroke.png', cornerSize=9, color=eveColor.WHITE[:3] + (0.1,)) 671 self.fillFrame = Frame(parent=self, texturePath='res:/UI/Texture/classes/combo/underlay_fill.png', cornerSize=9, color=eveColor.BLACK[:3] + (0.1,)) 672 self.line = Line(parent=Container(parent=self, padding=(8, 0, 8, 0)), align=uiconst.TOBOTTOM, state=uiconst.UI_HIDDEN, height=1, color=eveColor.WHITE[:3] + (0.1,)) 673 self.fill = BlurredSceneUnderlay(parent=self, align=uiconst.TOALL, state=uiconst.UI_HIDDEN, isInFocus=True, color=Color.HextoRGBA('#ff0b0a12')) 674 675 def Expand(self, height): 676 self.strokeFrame.texturePath = 'res:/UI/Texture/classes/combo/underlay_upper_stroke.png' 677 self.fillFrame.Hide() 678 self.line.Show() 679 self.fill.Show() 680 681 def Collapse(self): 682 self.strokeFrame.texturePath = 'res:/UI/Texture/classes/combo/underlay_stroke.png' 683 self.fillFrame.Show() 684 self.line.Hide() 685 self.fill.Hide() 686 687 def SetEnabled(self): 688 pass 689 690 def SetDisabled(self): 691 pass 692 693 def OnMouseEnter(self): 694 pass 695 696 def OnMouseExit(self): 697 pass 698 699 def OnMouseDown(self): 700 pass 701 702 def OnMouseUp(self): 703 pass 704 705 def OnWindowAboveSetActive(self): 706 animations.FadeTo(self.fillFrame, startVal=self.fillFrame.opacity, endVal=0.5, duration=uiconst.TIME_ENTRY) 707 708 def OnWindowAboveSetInactive(self): 709 animations.FadeTo(self.fillFrame, startVal=self.fillFrame.opacity, endVal=0.1, duration=uiconst.TIME_EXIT)