redeemItemsContainer.py (29180B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\redeem\redeemItemsContainer.py 2 import math 3 import eveformat 4 import evelink.client 5 import eveui 6 import homestation.client 7 import localization 8 import redeem.client 9 import signals 10 import threadutils 11 import uthread2 12 from carbon.client.script.environment.AudioUtil import PlaySound 13 from carbonui import ButtonVariant, Color, uiconst 14 from carbonui.control.button import Button 15 from carbonui.control.combo import Combo 16 from carbonui.control.scroll import Scroll 17 from carbonui.primitives.fill import Fill 18 from carbonui.primitives.frame import Frame 19 from carbonui.uianimations import animations 20 from carbonui.uicore import uicore 21 from carbonui.primitives.container import Container 22 from carbonui.primitives.containerAutoSize import ContainerAutoSize 23 from carbonui.primitives.sprite import Sprite 24 from eve.client.script.ui import eveColor, eveThemeColor 25 from eve.client.script.ui.control import eveLabel, itemIcon 26 from carbonui.control.buttonIcon import ButtonIcon 27 from carbonui.control.message import QuickMessage 28 from eve.client.script.ui.quickFilter import QuickFilterEdit 29 from eve.client.script.ui.shared.inventory.invContainers import RedeemItems, GetRedeemSortOptions 30 from eve.client.script.ui.shared.redeem.redeemItem import RedeemItem, DraggableRedeemItem, REDEEM_ITEM_WIDTH, GetRedeemItemHeight, GetRedeemItemHeightWithoutDescription 31 from eve.client.script.ui.shared.redeem.redeemUiConst import CREATION_DATE_SORT_KEY 32 from uihider import CommandBlockerService 33 34 def alert_user(text): 35 message = QuickMessage(parent=uicore.layer.abovemain, name='RedeemActionAlert') 36 message.minTop = uicore.desktop.height / 2 - 56 37 msg = u'\n{}\n'.format(text) 38 message.ShowMsg(msg) 39 uthread2.call_after_wallclocktime_delay(message.Close, 3) 40 41 42 PADDING_NORMAL = 8 43 PADDING_WIDE = 2 * PADDING_NORMAL 44 FOOTER_HEIGHT = 50 45 BUTTON_CONTAINER_HEIGHT = 35 46 ITEM_ROW_PADDING = 12 47 INFO_CONTAINER_COLOR = (0.0, 0.0, 0.0, 0.5) 48 INV_NAME = 'redeemItems' 49 50 class RedeemItemsContainer(Container): 51 default_name = 'RedeemItemsContainer' 52 default_showHeaderCount = True 53 default_showDeliveryInfo = True 54 default_showFooter = True 55 default_areItemsDraggable = False 56 default_sidePadding = 50 57 default_topPadding = 4 58 default_bottomPadding = 6 59 60 def ApplyAttributes(self, attributes): 61 super(RedeemItemsContainer, self).ApplyAttributes(attributes) 62 self.isReady = False 63 self._is_updating_scroll_selection = False 64 self.controller = attributes.controller 65 if not self.controller: 66 self.controller = Controller(redeem_data=attributes.redeemData, redeem_service=sm.GetService('redeem'), home_station_service=homestation.Service.instance()) 67 self.onContentUpdateCallback = attributes.get('onContentUpdateCallback', None) 68 self.areItemsDraggable = attributes.get('areItemsDraggable', self.default_areItemsDraggable) 69 self.showHeaderCount = attributes.get('showHeaderCount', self.default_showHeaderCount) 70 self.showDeliveryInfo = attributes.get('showDeliveryInfo', self.default_showDeliveryInfo) 71 self.showFooter = attributes.get('showFooter', self.default_showFooter) 72 self.sidePadding = attributes.get('sidePadding', self.default_sidePadding) 73 self.topPadding = attributes.get('topPadding', self.default_topPadding) 74 self.bottomPadding = attributes.get('bottomPadding', self.default_bottomPadding) 75 self.redeemItems = None 76 self.redeemItemsContainer = None 77 self.dragArea = Container(name='dragArea', parent=self, align=uiconst.TOALL) 78 if self.showHeaderCount: 79 self.ConstructHeader() 80 if self.showFooter: 81 self.ConstructFooter() 82 if self.showDeliveryInfo: 83 self.ConstructDeliveryInfo() 84 self.redeemItemsContainer = Container(name='redeemItemsContainer', parent=self, align=uiconst.TOALL, padding=(self.sidePadding, 85 self.topPadding, 86 self.sidePadding, 87 self.bottomPadding)) 88 self.ConstructRedeemItemsContainer() 89 self.controller.on_selection_changed.connect(self._OnSelectionChanged) 90 self.controller.on_load.connect(self._OnTokensUpdated) 91 self.controller.on_redeem.connect(self._OnRedeem) 92 self.controller.on_trash.connect(self._OnTrash) 93 self.controller.on_refresh_sort.connect(self._RefreshSort) 94 self.controller.on_text_filter_changed.connect(self._OnTextFilterChanged) 95 self.controller.select_all_triggered.connect(self._SelectAllTriggered) 96 uthread2.start_tasklet(self.controller.load) 97 98 def ConstructHeader(self): 99 Header(parent=self, align=uiconst.TOTOP, padding=(self.sidePadding, 100 PADDING_WIDE, 101 self.sidePadding, 102 0), controller=self.controller) 103 ControlContainer(parent=self, align=uiconst.TOTOP, controller=self.controller, padding=(self.sidePadding, 104 10, 105 self.sidePadding, 106 16)) 107 108 def ConstructDeliveryInfo(self): 109 if not CommandBlockerService.instance().is_blocked(['redeem_to_home_station']): 110 HomeStationSection(parent=self, align=uiconst.TOBOTTOM, padding=(self.sidePadding, 111 0, 112 self.sidePadding, 113 PADDING_NORMAL), controller=self.controller) 114 CurrentStationSection(parent=self, align=uiconst.TOBOTTOM, padding=(self.sidePadding, 115 0, 116 self.sidePadding, 117 PADDING_NORMAL), controller=self.controller) 118 AutoInjectNotice(parent=self, align=uiconst.TOBOTTOM, padding=(self.sidePadding, 119 0, 120 self.sidePadding, 121 PADDING_NORMAL), controller=self.controller) 122 123 def ConstructFooter(self): 124 Footer(parent=self, align=uiconst.TOBOTTOM, controller=self.controller) 125 126 @eveui.skip_if_destroyed 127 def ConstructRedeemItemsContainer(self): 128 if self.redeemItems and not self.redeemItems.destroyed: 129 self.redeemItems.Close() 130 self.redeemItems = RedeemItems(name=INV_NAME, parent=self.redeemItemsContainer, showControls=False, state=uiconst.UI_NORMAL, itemID='redeemItems', hasCapacity=False, oneWay=True, viewOnly=True, hasScrollBackground=False, rowPadding=ITEM_ROW_PADDING, shouldAddFinalRowPadding=False, getItemClass=self.GetItemClass, scrollClass=Scroll, shouldShowHint=self.ShouldShowHint(), selectAllOnFirstLoad=True, onSelectionChange=self._OnScrollSelectionChanged) 131 self.redeemItems.GetRubberbandParentContainer = self.GetDragArea 132 self.OnMouseDown = self.redeemItems.scroll.OnMouseDown 133 self.OnMouseUp = self.redeemItems.scroll.OnMouseUp 134 135 def GetDragArea(self): 136 return self.dragArea 137 138 def _OnTokensUpdated(self): 139 if self.redeemItems and not self.redeemItems.destroyed: 140 self.redeemItems.Refresh() 141 else: 142 self.ConstructRedeemItemsContainer() 143 self.isReady = True 144 if self.onContentUpdateCallback: 145 self.onContentUpdateCallback() 146 147 def _OnScrollSelectionChanged(self, selected_nodes): 148 if self._is_updating_scroll_selection: 149 return 150 self.controller.on_selection_changed.disconnect(self._OnSelectionChanged) 151 try: 152 selected_tokens = [ node.item for node in selected_nodes ] 153 self.controller.select_exclusive(selected_tokens) 154 finally: 155 self.controller.on_selection_changed.connect(self._OnSelectionChanged) 156 157 def _OnSelectionChanged(self): 158 self._is_updating_scroll_selection = True 159 try: 160 selected_nodes = [ node for node in self.redeemItems.scroll.GetNodes() if token_key(node.item) in self.controller.selected_keys ] 161 self.redeemItems.scroll.SelectNodes(selected_nodes) 162 finally: 163 self._is_updating_scroll_selection = False 164 165 def _SelectAllTriggered(self): 166 self.redeemItems.scroll.SelectAll() 167 168 def IsReady(self): 169 return self.isReady 170 171 def HasTokens(self): 172 return self.controller.tokens_count > 0 173 174 def RedeemAll(self): 175 self.controller.redeem_all(destination=Destination.current_station) 176 177 def GetItemClass(self): 178 if self.areItemsDraggable: 179 return DraggableRedeemItem 180 return RedeemItem 181 182 def ShouldShowHint(self): 183 return not self.areItemsDraggable 184 185 def _OnRedeem(self, delivery_location_id, redeem_result): 186 PlaySound(uiconst.SOUND_ADD_OR_USE) 187 alert_message = None 188 if redeem_result['itemsCreated']: 189 alert_message = localization.GetByLabel('UI/Redeem/RedeemToStationModalConfirmation', station=delivery_location_id) 190 elif any((redeem_result[x] for x in ['activated_licenses', 'itemsCreated', 'isk_rewarded'])): 191 alert_message = localization.GetByLabel('UI/Redeem/RedeemModalConfirmation') 192 if alert_message: 193 alert_user(alert_message) 194 195 def _OnTrash(self): 196 alert_user(localization.GetByLabel('UI/Redeem/TrashModalConfirmation')) 197 PlaySound(uiconst.SOUND_REMOVE) 198 199 def _RefreshSort(self, sortby, direction): 200 self.redeemItems.RefreshSort(sortby, direction) 201 202 def _OnTextFilterChanged(self, text): 203 self.redeemItems.SetQuickFilterInput(text) 204 205 206 class Station(object): 207 208 def __init__(self, station_id, type_id): 209 self.id = station_id 210 self.type_id = type_id 211 212 @staticmethod 213 def from_session(session): 214 docked_id = get_docked_id(session) 215 if docked_id: 216 return Station(station_id=docked_id, type_id=sm.GetService('map').GetItem(docked_id).typeID) 217 218 @property 219 def name(self): 220 return cfg.evelocations.Get(self.id).name 221 222 @property 223 def link(self): 224 return evelink.location_link(self.id) 225 226 227 def get_docked_id(session): 228 station_id = getattr(session, 'stationid', None) 229 structure_id = getattr(session, 'structureid', None) 230 ship_id = getattr(session, 'shipid', None) 231 if station_id is not None: 232 return station_id 233 if structure_id is not None and structure_id != ship_id: 234 return structure_id 235 236 237 class Destination(object): 238 current_station = 'current_station' 239 home_station = 'home_station' 240 241 242 class Controller(object): 243 __notifyevents__ = ('OnRedeemingTokensUpdated', 'OnSessionChanged') 244 245 def __init__(self, redeem_data, redeem_service, home_station_service): 246 self._redeem_data = redeem_data 247 self._redeem_service = redeem_service 248 self._home_station_service = home_station_service 249 self._raw_tokens = [] 250 self._tokens = {} 251 self._selected = set() 252 self.invName = INV_NAME 253 self.on_selection_changed = signals.Signal('on_selection_changed') 254 self.on_load = signals.Signal('on_load') 255 self.on_station_changed = signals.Signal('on_station_changed') 256 self.on_redeem = signals.Signal('on_redeem') 257 self.on_trash = signals.Signal('on_trash') 258 self.on_refresh_sort = signals.Signal('on_refresh_sort') 259 self.on_text_filter_changed = signals.Signal('on_text_filter_changed') 260 self.select_all_triggered = signals.Signal('select_all_triggered') 261 sm.RegisterNotify(self) 262 263 @property 264 def tokens(self): 265 return self._tokens.values() 266 267 @property 268 def tokens_count(self): 269 return len(self._tokens) 270 271 @property 272 def selected(self): 273 return [ self._tokens[key] for key in self._selected ] 274 275 @property 276 def selected_keys(self): 277 return [ key for key in self._selected ] 278 279 @property 280 def selected_count(self): 281 return len(self._selected) 282 283 @property 284 def current_station(self): 285 return Station.from_session(session) 286 287 @property 288 def auto_injected_selected_count(self): 289 return len(filter(lambda token: self._redeem_data.is_auto_injected(token), self.selected)) 290 291 def load(self): 292 self.deselect_all() 293 self._raw_tokens = [] 294 self._tokens = [] 295 self._raw_tokens = self._redeem_service.GetRedeemTokens() 296 self._tokens = {token_key(token):token for token in self._raw_tokens} 297 self.on_load() 298 299 def get_by_key(self, key): 300 return self._tokens[key] 301 302 def select(self, tokens): 303 self._selected = self._selected.union(set((token_key(token) for token in tokens))) 304 self.on_selection_changed() 305 306 def select_all(self): 307 self.select(self.tokens) 308 309 def select_exclusive(self, tokens): 310 self._selected = set((token_key(token) for token in tokens)) 311 self.on_selection_changed() 312 313 def deselect(self, tokens): 314 if any((token_key(token) in self._selected for token in tokens)): 315 self._selected = self._selected.difference(set((token_key(token) for token in tokens))) 316 self.on_selection_changed() 317 318 def deselect_all(self): 319 self.deselect(self.selected) 320 321 def redeem(self, tokens, destination): 322 if destination == Destination.current_station: 323 delivery_location_id = self.current_station.id 324 elif destination == Destination.home_station: 325 delivery_location_id = self._home_station_service.get_home_station().id 326 else: 327 raise RuntimeError('Unknown destination {!r}'.format(destination)) 328 confirmed = redeem.confirm_redeem(character_id=session.charid, tokens=tokens, delivery_location_id=delivery_location_id, redeem_data=self._redeem_data) 329 if not confirmed: 330 return 331 tokens = [ {'tokenID': token.tokenID, 332 'massTokenID': token.massTokenID, 333 'typeID': token.typeID} for token in tokens ] 334 redeem_result = self._redeem_service.ClaimRedeemTokens(tokens=tokens, charID=session.charid, useHomeStation=destination == Destination.home_station) 335 self.on_redeem(delivery_location_id, redeem_result) 336 337 def redeem_all(self, destination): 338 self.redeem(self.tokens, destination) 339 340 def redeem_selected(self, destination): 341 self.redeem(self.selected, destination) 342 343 def trash(self, tokens): 344 if not tokens: 345 return 346 if not redeem.confirm_trash(tokens): 347 return 348 token_keys = [ token_key(token) for token in tokens ] 349 self._redeem_service.TrashRedeemTokens(token_keys) 350 self.on_trash() 351 352 def trash_selected(self): 353 self.trash(self.selected) 354 355 def change_sort_order(self, sortby, direction): 356 self.on_refresh_sort(sortby, direction) 357 358 def change_text_filter(self, text): 359 self.deselect_all() 360 self.on_text_filter_changed(text) 361 362 def OnRedeemingTokensUpdated(self): 363 uthread2.start_tasklet(self.load) 364 365 def OnSessionChanged(self, is_remote, session, changes): 366 docked_or_undocked = any((name in changes for name in ('stationid', 'structureid'))) 367 took_or_released_structure_control = 'shipid' in changes and session.structureid and session.structureid in changes['shipid'] 368 if docked_or_undocked or took_or_released_structure_control: 369 uthread2.start_tasklet(self.on_station_changed) 370 371 372 def token_key(token): 373 return (token.tokenID, token.massTokenID) 374 375 376 class Header(ContainerAutoSize): 377 378 def __init__(self, controller, **kwargs): 379 super(Header, self).__init__(alignMode=uiconst.TOTOP, **kwargs) 380 self._controller = controller 381 self._label = None 382 self.layout() 383 self.update() 384 self._controller.on_load.connect(self.update) 385 386 def layout(self): 387 self._label = eveLabel.EveCaptionLarge(parent=self, state=uiconst.UI_DISABLED, align=uiconst.TOTOP) 388 389 @threadutils.threaded 390 def update(self): 391 text = localization.GetByLabel('UI/RedeemWindow/ReedemNumItems', num=self._controller.tokens_count) 392 self._label.SetText(text) 393 394 395 class Footer(Container): 396 397 def __init__(self, controller, **kwargs): 398 super(Footer, self).__init__(bgColor=eveColor.BLACK, height=FOOTER_HEIGHT, **kwargs) 399 self._controller = controller 400 self._label = None 401 self.layout() 402 self.update() 403 self._controller.on_selection_changed.connect(self.update) 404 self._controller.on_load.connect(self.update) 405 406 def layout(self): 407 ButtonIcon(parent=self, align=uiconst.CENTERLEFT, left=PADDING_WIDE, width=32, height=32, texturePath='res:/UI/Texture/Classes/RedeemPanel/trashcan_icon.png', iconSize=24, func=self._controller.trash_selected, args=(), hint=localization.GetByLabel('UI/RedeemWindow/TrashSelectedItems')) 408 self._label = eveLabel.EveLabelMedium(parent=self, align=uiconst.CENTERRIGHT, left=PADDING_WIDE) 409 410 @threadutils.threaded 411 def update(self): 412 self._label.SetText(localization.GetByLabel('UI/Redeem/RedeemItemsSelected', selected=self._controller.selected_count, total=self._controller.tokens_count)) 413 414 415 class AutoInjectNotice(ContainerAutoSize): 416 icon_size = 24 417 color = Color.from_hex('#369ebd') 418 419 def __init__(self, controller, **kwargs): 420 super(AutoInjectNotice, self).__init__(alignMode=uiconst.TOTOP, minHeight=(self.icon_size + 2 * PADDING_NORMAL), clipChildren=True, **kwargs) 421 self.display = False 422 self._controller = controller 423 self._frame = None 424 self._corner = None 425 self._icon = None 426 self._label = None 427 self._padding_before = (self.padTop, self.padBottom) 428 self._is_revealed = False 429 self.layout() 430 self.update(animate=False) 431 self._controller.on_selection_changed.connect(self.update) 432 433 def layout(self): 434 color = eveThemeColor.THEME_ACCENT 435 self._frame = Frame(bgParent=self, texturePath='res:/UI/Texture/Shared/DarkStyle/panel1Corner_Solid.png', cornerSize=9, rotation=math.pi, color=color, opacity=0.1) 436 self._corner = Sprite(name='AUTOINJECT_SPRITE_A', parent=self, align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/Shared/DarkStyle/cornerTriSmall.png', width=5, height=5, color=color) 437 self._icon = Sprite(name='AUTOINJECT_SPRITE_B', parent=self, align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED, top=PADDING_NORMAL, left=PADDING_NORMAL, width=self.icon_size, height=self.icon_size, texturePath='res:/UI/Texture/classes/RedeemPanel/autoInjectFlat.png', color=color) 438 self._label = eveLabel.EveLabelMedium(name='AUTOINJECT_LABEL_A', parent=self, align=uiconst.TOTOP, state=uiconst.UI_DISABLED, padding=(PADDING_NORMAL + self.icon_size + PADDING_NORMAL, 439 PADDING_NORMAL, 440 PADDING_NORMAL, 441 PADDING_NORMAL), color=color) 442 443 def reveal(self): 444 self.padTop, self.padBottom = self._padding_before 445 self.display = True 446 self.EnableAutoSize() 447 448 def anim_reveal(self): 449 if self.display: 450 return 451 self.display = True 452 _, height = self.GetAutoSize() 453 self.DisableAutoSize() 454 duration = 0.2 455 animations.FadeIn(self, duration=duration) 456 animations.MorphScalar(self, 'height', startVal=0, endVal=height, duration=duration / 2.0, callback=self.EnableAutoSize) 457 animations.MorphScalar(self, 'padTop', startVal=0, endVal=self._padding_before[0], duration=duration) 458 animations.MorphScalar(self, 'padBottom', startVal=0, endVal=self._padding_before[1], duration=duration) 459 460 def hide(self): 461 self.display = False 462 463 def anim_hide(self): 464 if not self.display: 465 return 466 self.DisableAutoSize() 467 duration = 0.2 468 animations.FadeOut(self, duration=duration) 469 animations.MorphScalar(self, 'height', startVal=self.height, endVal=0, duration=duration / 2.0, callback=self.Hide) 470 animations.MorphScalar(self, 'padTop', startVal=self._padding_before[0], endVal=0, duration=duration) 471 animations.MorphScalar(self, 'padBottom', startVal=self._padding_before[1], endVal=0, duration=duration) 472 473 @threadutils.threaded 474 def update(self, animate = True): 475 self._label.SetText(localization.GetByLabel('UI/RedeemWindow/AutoInjectNotification', count=self._controller.auto_injected_selected_count)) 476 if self._controller.auto_injected_selected_count > 0: 477 self.anim_reveal() if animate else self.reveal() 478 else: 479 self.anim_hide() if animate else self.hide() 480 481 def OnColorThemeChanged(self): 482 super(AutoInjectNotice, self).OnColorThemeChanged() 483 newColor = eveThemeColor.THEME_ACCENT.rgb 484 self._frame.SetRGB(*newColor) 485 self._corner.SetRGB(*newColor) 486 self._icon.SetRGB(*newColor) 487 self._label.SetRGB(*newColor) 488 489 490 class StationSection(ContainerAutoSize): 491 icon_size = 48 492 background_color = INFO_CONTAINER_COLOR 493 494 def __init__(self, button_text, primary = False, **kwargs): 495 super(StationSection, self).__init__(bgColor=self.background_color, **kwargs) 496 self._button_text = button_text 497 self._primary = primary 498 self._icon = None 499 self._label = None 500 self._button = None 501 self._feedback = None 502 self.layout() 503 self.update() 504 505 def redeem(self): 506 raise NotImplementedError() 507 508 def get_text(self): 509 raise NotImplementedError() 510 511 def update_icon(self, icon): 512 raise NotImplementedError() 513 514 def is_enabled(self): 515 raise NotImplementedError() 516 517 def layout(self): 518 inner = ContainerAutoSize(parent=self, align=uiconst.TOTOP, alignMode=uiconst.TOTOP, minHeight=self.icon_size + 2 * PADDING_NORMAL) 519 self._feedback = Fill(parent=inner, align=uiconst.TOALL, color=(1.0, 1.0, 1.0), opacity=0.0) 520 icon_cont = ContainerAutoSize(parent=inner, align=uiconst.TOLEFT, padding=8) 521 self._icon = itemIcon.ItemIcon(parent=icon_cont, align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED, width=self.icon_size, height=self.icon_size, showOmegaOverlay=False) 522 button_cont = ContainerAutoSize(parent=inner, align=uiconst.TORIGHT, padding=(PADDING_NORMAL, 523 0, 524 PADDING_NORMAL, 525 0)) 526 if self._primary: 527 button_variant = ButtonVariant.PRIMARY 528 else: 529 button_variant = ButtonVariant.NORMAL 530 self._button = Button(parent=button_cont, align=uiconst.CENTER, label=self._button_text, func=self.redeem, args=(), variant=button_variant) 531 self._button.Disable() 532 label_cont = ContainerAutoSize(parent=inner, align=uiconst.TOTOP, minHeight=self.icon_size, padding=(0, 533 PADDING_NORMAL, 534 0, 535 PADDING_NORMAL)) 536 self._label = eveLabel.EveLabelMedium(parent=label_cont, align=uiconst.CENTERLEFT, state=uiconst.UI_NORMAL, autoFadeSides=25) 537 538 @threadutils.threaded 539 def update(self, animate = False, feedback = False): 540 if animate: 541 animations.FadeOut(self._icon, duration=0.25) 542 animations.FadeOut(self._label, duration=0.25, sleep=True) 543 self.update_icon(self._icon) 544 self._label.SetText(self.get_text()) 545 if self.is_enabled(): 546 self._button.Enable() 547 else: 548 self._button.Disable() 549 if animate: 550 animations.FadeIn(self._icon, duration=0.25) 551 animations.FadeIn(self._label, endVal=self._label.default_color[3], duration=0.25) 552 if feedback: 553 animations.FadeTo(self._feedback, endVal=0.5, duration=0.35, timeOffset=0.1, curveType=uiconst.ANIM_WAVE) 554 555 556 class CurrentStationSection(StationSection): 557 558 def __init__(self, controller, **kwargs): 559 self._controller = controller 560 super(CurrentStationSection, self).__init__(button_text=localization.GetByLabel('UI/RedeemWindow/RedeemToCurrentStation'), primary=True, **kwargs) 561 self._controller.on_station_changed.connect(self.handle_station_changed) 562 self._controller.on_selection_changed.connect(self.update) 563 564 def is_enabled(self): 565 return self._controller.current_station is not None and self._controller.selected_count > 0 566 567 def get_text(self): 568 current_station = self._controller.current_station 569 if current_station is None: 570 return u'{}<br>{}'.format(localization.GetByLabel('UI/RedeemWindow/CurrentStationHeader'), eveformat.color(localization.GetByLabel('UI/RedeemWindow/NotDocked'), eveColor.WARNING_ORANGE)) 571 else: 572 return u'{}<br>{}'.format(localization.GetByLabel('UI/RedeemWindow/CurrentStationHeader'), current_station.link) 573 574 def update_icon(self, icon): 575 current_station = self._controller.current_station 576 if current_station is None: 577 icon.SetTexturePath('res:/UI/Texture/Icons/5_64_11.png') 578 icon.opacity = 0.5 579 else: 580 icon.SetTypeIDandItemID(typeID=current_station.type_id, itemID=current_station.id) 581 icon.opacity = 1.0 582 583 def redeem(self): 584 self._controller.redeem_selected(Destination.current_station) 585 586 def handle_station_changed(self): 587 self.update(animate=True, feedback=True) 588 589 590 class HomeStationSection(StationSection): 591 592 def __init__(self, controller, **kwargs): 593 super(HomeStationSection, self).__init__(button_text=localization.GetByLabel('UI/RedeemWindow/RedeemToHomeStation'), **kwargs) 594 self._controller = controller 595 homestation.Service.instance().on_home_station_changed.connect(self.handle_home_station_changed) 596 self._controller.on_selection_changed.connect(self.update) 597 598 @property 599 def home_station(self): 600 return homestation.Service.instance().get_home_station() 601 602 def is_enabled(self): 603 return self._controller.selected_count > 0 604 605 def get_text(self): 606 try: 607 return u'{}<br>{}'.format(localization.GetByLabel('UI/RedeemWindow/HomeStationHeader'), self.home_station.link) 608 except homestation.NotLoggedInError: 609 return '' 610 611 def update_icon(self, icon): 612 try: 613 icon.SetTypeIDandItemID(itemID=self.home_station.id, typeID=self.home_station.type_id) 614 except homestation.NotLoggedInError: 615 pass 616 617 def redeem(self): 618 self._controller.redeem_selected(destination=Destination.home_station) 619 620 def handle_home_station_changed(self): 621 self.update(animate=True, feedback=True) 622 623 624 class ControlContainer(ContainerAutoSize): 625 __notifyevents__ = ('OnInvContRefreshed',) 626 default_height = 30 627 default_availableSpace = None 628 629 def __init__(self, controller, **kwargs): 630 super(ControlContainer, self).__init__(alignMode=uiconst.TOLEFT, **kwargs) 631 self._controller = controller 632 self.availableSpace = kwargs.get('availableSpace', None) 633 self.sortCombo = None 634 self.layout() 635 sm.RegisterNotify(self) 636 637 def layout(self): 638 options = [] 639 for eachOption in GetRedeemSortOptions(): 640 if eachOption is None: 641 continue 642 labelPath, value = eachOption 643 options.append((localization.GetByLabel(labelPath), value)) 644 645 selectedValue = self.GetSelectedOptionFromSettings() 646 labelCont = ContainerAutoSize(name='labelCont', parent=self, align=uiconst.TOLEFT) 647 text = localization.GetByLabel('UI/Common/SortBy') 648 label = eveLabel.EveLabelMedium(parent=labelCont, align=uiconst.CENTERRIGHT, left=uiconst.CENTERLEFT, text=text) 649 comboCont = ContainerAutoSize(name='comboCont', parent=self, align=uiconst.TOLEFT) 650 self.sortCombo = Combo(name='myCombo', parent=comboCont, label='', options=options, align=uiconst.CENTER, callback=self.OnSortOrderChanged, select=selectedValue, width=100) 651 buttonCont = ContainerAutoSize(name='buttonCont', parent=self, align=uiconst.TOLEFT, left=10) 652 btn = Button(parent=buttonCont, align=uiconst.CENTERRIGHT, label=localization.GetByLabel('UI/RedeemWindow/SelectAll'), func=self._controller.select_all_triggered, args=()) 653 filterAlign = uiconst.TORIGHT if self.align == uiconst.TOTOP else uiconst.TOLEFT 654 filtCont = ContainerAutoSize(name='filtCont', parent=self, align=filterAlign, left=10) 655 self.quickFilter = QuickFilterEdit(parent=filtCont, align=uiconst.CENTERRIGHT, width=190) 656 self.quickFilter.ReloadFunction = self.OnQuickFilter 657 self.height = max(label.height, self.sortCombo.height, btn.height) 658 if self.availableSpace is not None: 659 self.AdjustWidths() 660 661 def AdjustWidths(self): 662 if self.availableSpace is None: 663 return 664 if self.availableSpace < self.width + 50: 665 self.quickFilter.width = 100 666 667 def GetSelectedOptionFromSettings(self): 668 return settings.char.ui.Get('containerSortIconsBy_%s' % self._controller.invName, (CREATION_DATE_SORT_KEY, 1)) 669 670 def OnInvContRefreshed(self, invCont): 671 if invCont.name == self._controller.invName: 672 if self.sortCombo and not self.sortCombo.destroyed: 673 selectedValue = self.GetSelectedOptionFromSettings() 674 self.sortCombo.SelectItemByValue(selectedValue) 675 676 def OnSortOrderChanged(self, cb, key, value): 677 self._controller.on_refresh_sort(*value) 678 679 def OnQuickFilter(self, *args): 680 text = self.quickFilter.GetValue() 681 self._controller.change_text_filter(text)