reagentBayWnd.py (18119B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\sov\reagentBay\reagentBayWnd.py 2 import carbonui.text.styles 3 import evetypes 4 import locks 5 import mathext 6 import uthread2 7 from carbon.common.script.sys.serviceConst import ROLE_PROGRAMMER 8 from carbon.common.script.util.format import FmtAmt 9 from carbonui import TextColor, uiconst 10 from carbonui.button.group import ButtonGroup 11 from carbonui.control.button import Button 12 from carbonui.control.combo import Combo 13 from carbonui.control.singlelineedits.singleLineEditInteger import SingleLineEditInteger 14 from carbonui.control.window import Window 15 import carbonui 16 from carbonui.primitives.container import Container 17 from carbonui.primitives.containerAutoSize import ContainerAutoSize 18 from carbonui.primitives.layoutGrid import LayoutGrid 19 from carbonui.primitives.sprite import Sprite 20 from eve.client.script.ui import eveColor 21 from eve.client.script.ui.control.eveLoadingWheel import LoadingWheel 22 from eve.client.script.ui.control.gaugeCircular import GaugeCircular 23 from eve.client.script.ui.control.loadingContainer import LoadingContainer 24 from eve.client.script.ui.shared.sov.reagentBay.controllers import ReagentBayWndController, InputItemController 25 from eve.client.script.ui.shared.sov.threadedLoader import ThreadedLoader 26 from eveservices.menu import GetMenuService 27 from eveui import animation 28 from inventorycommon.const import shipColonyResourcesHold 29 from localization import GetByLabel 30 import inventorycommon.const as invConst 31 from player_messaging.client.ui_message import prompt_player_fsd_dialog 32 from sovereignty.client.quasarCallWrapper import DATA_NOT_AVAILABLE 33 from threadutils import throttled 34 import math 35 import logging 36 logger = logging.getLogger(__name__) 37 38 def OpenReagnetBay(sovHubID, solarSystemID, isStationMgr): 39 wnd = ReagnetBayWnd.GetIfOpen(windowInstanceID=sovHubID) 40 if wnd and not wnd.destroyed: 41 wnd.Maximize() 42 if not wnd.wnController.IsSameItemID(sovHubID): 43 wnd.LoadWnd(sovHubID, solarSystemID, isStationMgr) 44 else: 45 ReagnetBayWnd.Open(sovHubID=sovHubID, solarSystemID=solarSystemID, isStationMgr=isStationMgr) 46 47 48 class ReagnetBayWnd(Window): 49 __guid__ = 'ReagnetBayWnd' 50 default_minSize = [500, 290] 51 default_windowID = 'reagnetBayWnd' 52 default_captionLabelPath = 'UI/Sovereignty/SovHub/ReagentBay/SovereigntyHubReagentBay' 53 __notifyevents__ = ['OnSessionChanged', 'OnItemChange'] 54 55 def DebugReload(self, *args): 56 sovHubID = self.wnController.sovHubID 57 solarSystemID = self.wnController.solarSystemID 58 isStationMgr = self.wnController.isStationMgr 59 self.Close() 60 OpenReagnetBay(sovHubID, solarSystemID, isStationMgr) 61 62 def ApplyAttributes(self, attributes): 63 super(ReagnetBayWnd, self).ApplyAttributes(attributes) 64 sovHubID = attributes.sovHubID 65 solarSystemID = attributes.solarSystemID 66 isStationMgr = attributes.isStationMgr 67 self.wnController = ReagentBayWndController(sovHubID, solarSystemID, isStationMgr) 68 self.inputEntriesByTypeID = {} 69 self.threadedLoader = ThreadedLoader('ReagnetBayWnd') 70 self.ConstructUI() 71 sm.RegisterNotify(self) 72 73 def ConstructUI(self): 74 self.loadingCont = LoadingContainer(parent=self.content, failureStateMessage=GetByLabel('UI/Sovereignty/SovHub/HubWnd/FailedToFetchData'), retryBtnLabel=GetByLabel('UI/Personalization/PaintTool/ErrorRetry')) 75 btnGroup = ButtonGroup(parent=self.loadingCont, button_alignment=carbonui.AxisAlignment.END) 76 self.upgradesLabel = carbonui.text.styles.TextBody(parent=self.loadingCont, text='', align=carbonui.Align.BOTTOMLEFT) 77 self.comboParent = ContainerAutoSize(parent=self.loadingCont, name='comboParent', align=carbonui.Align.TOTOP) 78 self.sourceCombo = Combo(parent=self.comboParent, align=carbonui.Align.TOPRIGHT, prefskey=self.wnController.GetComboPrefsKey(), callback=self.OnComboChanged) 79 reagentParentCont = ContainerAutoSize(parent=self.loadingCont, name='reagentParentCont', align=carbonui.Align.TOTOP, minHeight=64, alignMode=carbonui.Align.TOTOP) 80 self.reagentCont = ContainerAutoSize(parent=reagentParentCont, name='reagentCont', align=carbonui.Align.TOTOP) 81 self.reagentLoadingWheel = LoadingWheel(parent=reagentParentCont, align=carbonui.Align.CENTER, width=64, height=64) 82 noReagentDataText = GetByLabel('UI/Sovereignty/SovHub/ReagentBay/NoReagentDataAvailable') 83 self.noReagentDataAvailableLabel = carbonui.text.styles.TextBody(parent=reagentParentCont, align=carbonui.Align.CENTER, text=noReagentDataText) 84 self.noReagentDataAvailableLabel.display = False 85 depositText = GetByLabel('UI/Sovereignty/SovHub/ReagentBay/DepositReagentBtn') 86 self.depositBtn = Button(parent=self.loadingCont, label=depositText, func=self.Deposit) 87 btnGroup.add_button(self.depositBtn) 88 self.loadingCont.LoadContent(loadCallback=self.LoadWnd) 89 90 def LoadWnd(self): 91 self.wnController.PrimeFuelByTypeID() 92 self.reagentCont.Flush() 93 self.LoadCombo() 94 self.threadedLoader.StartLoading(self.LoadReagents_thread, self) 95 self.threadedLoader.StartLoading(self.LoadInstalledUpgrades_thread, self) 96 self.UpdateBtn() 97 solarSystemName = cfg.evelocations.Get(self.wnController.solarSystemID).name 98 self.caption = GetByLabel('UI/Sovereignty/SovHub/ReagentBay/SovereigntyHubReagentBayWithSystemName', solarSystemName=solarSystemName) 99 100 def LoadCombo(self): 101 sourceOptions = self.wnController.GetSourceOptions() 102 self.comboParent.display = bool(sourceOptions) 103 if not sourceOptions: 104 self.comboParent.display = False 105 return 106 self.sourceCombo.LoadOptions(sourceOptions) 107 self._SetUseResourceHoldValue(self.sourceCombo.GetValue()) 108 109 def LoadInstalledUpgrades_thread(self): 110 self.upgradesLabel.text = '' 111 if not self.wnController.CanSeeUpgrades(): 112 return 113 installedUpgradesText = self.wnController.GetNumOnlineAndInstalledUpgradesText() 114 if installedUpgradesText == DATA_NOT_AVAILABLE: 115 self.upgradesLabel.text = GetByLabel('UI/Sovereignty/SovHub/ReagentBay/NoDataAvailable') 116 self.upgradesLabel.text = installedUpgradesText 117 118 def LoadReagents_thread(self): 119 if self.destroyed: 120 return 121 animation.fade_in(self.reagentLoadingWheel) 122 self.noReagentDataAvailableLabel.Hide() 123 try: 124 fuelByTypeID = self.wnController.GetFuelByTypeID() 125 if self.destroyed: 126 return 127 if fuelByTypeID == DATA_NOT_AVAILABLE: 128 self.noReagentDataAvailableLabel.Show() 129 return 130 self._LoadReagents(fuelByTypeID) 131 finally: 132 animation.fade_out(self.reagentLoadingWheel, duration=0.1) 133 134 def _LoadReagents(self, fuelByTypeID): 135 self.inputEntriesByTypeID.clear() 136 cargoQtyByTypeID = self.wnController.GetQtyByTypeID_InHold() 137 for typeID, fuel in fuelByTypeID.iteritems(): 138 itemController = InputItemController(typeID, fuel.amount_now, fuel.burned_per_hour) 139 qtyInCargo = cargoQtyByTypeID.get(typeID, 0) 140 inputEntry = ReagentBayInputItem(parent=self.reagentCont, align=carbonui.Align.TOTOP, itemController=itemController, wndController=self.wnController, inputFieldChangedCallback=self.OnInputChanged, qtyInCargo=qtyInCargo, paddingValue=3, padBottom=1) 141 self.inputEntriesByTypeID[typeID] = inputEntry 142 143 self.Refresh() 144 145 def OnInputChanged(self, *args): 146 self.Refresh() 147 148 def OnComboChanged(self, cb, key, val): 149 self._SetUseResourceHoldValue(val) 150 self.Refresh() 151 152 def _SetUseResourceHoldValue(self, val): 153 if val and val[0] == shipColonyResourcesHold: 154 useResourceHold = True 155 else: 156 useResourceHold = False 157 self.wnController.useResourceHold = useResourceHold 158 159 def Refresh(self): 160 self._RefreshThrottled() 161 162 @throttled(0.5) 163 def _RefreshThrottled(self): 164 if self.wnController.busyDepositingItems: 165 return 166 self.UpdateInputEntries() 167 self.UpdateBtn() 168 169 def UpdateInputEntries(self): 170 sovHubFuelByTypeID = self.wnController.GetFuelByTypeID() 171 cargoQtyByTypeID = self.wnController.GetQtyByTypeID_InHold() 172 for typeID, inputEntry in self.inputEntriesByTypeID.iteritems(): 173 if inputEntry.destroyed: 174 continue 175 fuelInSovHub = sovHubFuelByTypeID.get(typeID, 0) 176 qtyInCargo = cargoQtyByTypeID.get(typeID, 0) 177 amountInSovHub = fuelInSovHub.amount_now 178 inputEntry.UpdateEntry(amountInSovHub, qtyInCargo, fuelInSovHub.burned_per_hour) 179 180 def UpdateBtn(self): 181 if self.wnController.depositBtnDelay: 182 return 183 numItems = sum((qty for qty in self.GetTypeIDsAndQtyFromInputEntries().itervalues())) 184 if numItems > 0: 185 self.depositBtn.Enable() 186 else: 187 self.depositBtn.Disable() 188 189 def Deposit(self, *args): 190 with locks.TempLock('ReagnetBayWnd_DepositItems_%s' % self.wnController.sovHubID): 191 sucessfulDeposit = False 192 try: 193 self.wnController.busyDepositingItems = True 194 self.wnController.depositBtnDelay = True 195 self.depositBtn.Disable() 196 self.depositBtn.busy = True 197 qtyByTypeID = self.GetTypeIDsAndQtyFromInputEntries() 198 if self.DepositConfirmed(qtyByTypeID): 199 failedToMove = self.wnController.DoDepositItems(qtyByTypeID) 200 sucessfulDeposit = not failedToMove 201 finally: 202 self.depositBtn.busy = False 203 self.wnController.busyDepositingItems = False 204 if sucessfulDeposit: 205 self.Close() 206 else: 207 uthread2.call_after_wallclocktime_delay(self.EnableBtnAfterDeposit, 1.0) 208 self.Refresh() 209 210 def EnableBtnAfterDeposit(self): 211 self.wnController.depositBtnDelay = False 212 self.UpdateBtn() 213 214 def GetTypeIDsAndQtyFromInputEntries(self): 215 qtyByTypeID = {} 216 for typeID, inputEntry in self.inputEntriesByTypeID.iteritems(): 217 inputQty = inputEntry.GetInputQty() 218 qtyByTypeID[typeID] = inputQty 219 220 return qtyByTypeID 221 222 def DepositConfirmed(self, qtyByTypeID): 223 if self.wnController.useResourceHold: 224 dialogKey = 'ConfirmReagentDepositFromReagentBay' 225 else: 226 dialogKey = 'ConfirmReagentDepositFromCargo' 227 depositTextList = [ u'\u2022 %s' % GetByLabel('UI/Common/QuantityAndItem', quantity=qty, item=typeID) for typeID, qty in qtyByTypeID.iteritems() if qty ] 228 depositText = '<br>'.join(depositTextList) 229 if prompt_player_fsd_dialog(dialogKey, {'itemList': depositText, 230 'rewardText': ''}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 231 return True 232 return False 233 234 def OnSessionChanged(self, isRemote, sess, change): 235 if 'shipid' in change: 236 self.LoadCombo() 237 self.Refresh() 238 239 def OnItemChange(self, item, change, location): 240 validFlags = {invConst.flagCargo, invConst.flagColonyResourcesHold} 241 if item.locationID == session.shipid and item.flagID in validFlags: 242 self.Refresh() 243 elif change.get(const.ixLocationID, None) == session.shipid and change.get(const.ixFlag, None) in validFlags: 244 self.Refresh() 245 246 def GetMenuMoreOptions(self): 247 menu_data = super(ReagnetBayWnd, self).GetMenuMoreOptions() 248 if session.role & ROLE_PROGRAMMER: 249 menu_data.AddEntry('QA Reload', self.DebugReload) 250 return menu_data 251 252 253 class ReagentBayInputItem(ContainerAutoSize): 254 default_align = carbonui.Align.TOTOP 255 default_minHeight = 88 256 default_alignMode = carbonui.Align.TOTOP 257 258 def ApplyAttributes(self, attributes): 259 super(ReagentBayInputItem, self).ApplyAttributes(attributes) 260 self.wndController = attributes.wndController 261 self.inputItemController = attributes.itemController 262 self.inputFieldChangedCallback = attributes.inputFieldChangedCallback 263 self.paddingValue = attributes.paddingValue or 0 264 qtyInCargo = attributes.qtyInCargo 265 self.ConstructTypeIcon() 266 self.ConstructInput(qtyInCargo) 267 self.ConstructLabels() 268 269 def ConstructTypeIcon(self): 270 iconSize = 64 271 gaugeSize = iconSize + 10 272 leftCont = Container(parent=self, name='leftCont', align=carbonui.Align.TOLEFT, width=gaugeSize, left=10) 273 self.iconGaugeCont = IconGaugeCont(parent=leftCont, align=carbonui.Align.CENTERLEFT, pos=(0, 274 0, 275 gaugeSize, 276 gaugeSize), gaugeSize=gaugeSize, iconSize=iconSize, typeID=self.inputItemController.typeID) 277 278 def ConstructInput(self, qtyInCargo): 279 rightPad = self.paddingValue + 10 280 rightCont = Container(parent=self, name='rightCont', align=carbonui.Align.TORIGHT, width=100, left=rightPad) 281 self.inputEdit = SingleLineEditInteger(parent=rightCont, width=100, OnChange=self.OnInputFieldChanged, setvalue=qtyInCargo, align=carbonui.Align.CENTERRIGHT) 282 283 def ConstructLabels(self): 284 textCont = ContainerAutoSize(parent=self, name='textCont', align=carbonui.Align.TOTOP, padLeft=12) 285 grid = LayoutGrid(parent=textCont, align=carbonui.Align.TOPLEFT, columns=2, cellSpacing=(10, 6), top=16) 286 carbonui.text.styles.TextBody(parent=grid, align=carbonui.Align.CENTERLEFT, text=evetypes.GetName(self.inputItemController.typeID)) 287 self.timeLeftLabel = carbonui.text.styles.TextDetail(parent=grid, align=carbonui.Align.CENTERLEFT, text='', color=TextColor.SECONDARY) 288 self.currentLabel = carbonui.text.styles.TextBody(text='', color=TextColor.SECONDARY) 289 grid.AddCell(self.currentLabel, colSpan=2) 290 self.burnRateLabel = carbonui.text.styles.TextBody(text='', color=TextColor.SECONDARY) 291 grid.AddCell(self.burnRateLabel, colSpan=2) 292 293 def RefreshNumbers(self): 294 maxToAdd = self.inputItemController.maxToAdd 295 self.inputEdit.SetMaxValue(maxToAdd) 296 self.currentLabel.text = GetByLabel('UI/Sovereignty/SovHub/ReagentBay/CurrentInHub', qtyInHub=FmtAmt(self.inputItemController.unitsInSovHub)) 297 rateText = GetByLabel('UI/Sovereignty/AmountPerHour', value=self.inputItemController.burnRate) 298 self.burnRateLabel.text = GetByLabel('UI/Sovereignty/SovHub/ReagentBay/FuelBurnRate', burnRate=rateText) 299 self.timeLeftLabel.text = self.inputItemController.GetTimesLeft(self.GetInputQty()) 300 self.inputEdit.Show() 301 value = self.GetInputQty() 302 self.inputItemController.currentValueIfSelected = min(value, maxToAdd) 303 if value > maxToAdd: 304 self.inputEdit.SetValue(maxToAdd, False) 305 self.UpdateGaugeProgress() 306 307 def UpdateGaugeProgress(self): 308 unitsInWnd = self.GetInputQty() 309 progressInHub, progressInWnd = self.inputItemController.GetProgress(unitsInWnd) 310 self.iconGaugeCont.SetProgress(progressInHub, mathext.clamp(progressInHub + progressInWnd, 0, 1)) 311 312 def GetInputQty(self): 313 return self.inputEdit.GetValue() 314 315 def OnInputFieldChanged(self, *args): 316 if self.inputFieldChangedCallback: 317 self.inputFieldChangedCallback(*args) 318 319 def UpdateEntry(self, unitsInSovHub, qtyInCargo, burnRate): 320 self.inputItemController.unitsInSovHub = unitsInSovHub 321 self.inputItemController.qtyInCargo = qtyInCargo 322 self.inputItemController.burnRate = burnRate 323 self.RefreshUI() 324 325 def RefreshUI(self): 326 self.RefreshNumbers() 327 self.UpdateEnabledLook() 328 329 def UpdateEnabledLook(self): 330 if self.inputItemController.qtyInCargo: 331 self.opacity = 1.0 332 else: 333 self.opacity = 0.25 334 self.UpdateInputHint() 335 336 def UpdateInputHint(self): 337 if self.inputItemController.qtyInCargo: 338 hintPath = self.wndController.GetQtyInCargoHintPath() 339 hint = GetByLabel(hintPath, qty=self.inputItemController.qtyInCargo) 340 else: 341 hint = GetByLabel(self.wndController.GetNoQtyInCargoHintPath()) 342 self.inputEdit.hint = hint 343 344 345 class IconGaugeCont(Container): 346 default_state = uiconst.UI_NORMAL 347 348 def ApplyAttributes(self, attributes): 349 super(IconGaugeCont, self).ApplyAttributes(attributes) 350 self.typeID = attributes.typeID 351 iconSize = attributes.iconSize 352 gaugeSize = attributes.gaugeSize 353 self.typeCont = Container(parent=self, name='typeCont', align=uiconst.CENTER, pos=(0, 354 0, 355 iconSize, 356 iconSize)) 357 typeIcon = Sprite(parent=self.typeCont, name='typeIcon', align=uiconst.CENTERRIGHT, state=uiconst.UI_DISABLED, pos=(0, 358 0, 359 iconSize, 360 iconSize)) 361 sm.GetService('photo').GetIconByType(typeIcon, self.typeID) 362 gaugeCont = Container(parent=self, name='gaugeCont', pos=(0, 363 0, 364 gaugeSize, 365 gaugeSize), align=uiconst.CENTERRIGHT) 366 self.gauge = GaugeCircular(parent=gaugeCont, colorStart=eveColor.CRYO_BLUE, colorEnd=eveColor.CRYO_BLUE, radius=gaugeSize / 2, align=uiconst.CENTER, state=uiconst.UI_DISABLED, colorBg=(0, 0, 0, 0), showMarker=False, startAngle=math.pi / 2) 367 self.inWndGauge = GaugeCircular(parent=gaugeCont, radius=gaugeSize / 2, colorStart=eveColor.SILVER_GREY, colorEnd=eveColor.SILVER_GREY, align=uiconst.CENTER, state=uiconst.UI_DISABLED, showMarker=False, startAngle=math.pi / 2) 368 369 def OnClick(self, *args): 370 return sm.GetService('info').ShowInfo(self.typeID) 371 372 def GetMenu(self): 373 return GetMenuService().GetMenuFromItemIDTypeID(None, self.typeID) 374 375 def SetProgress(self, unitsInContainerProgress, unitsInWndProgress): 376 self.gauge.SetValue(unitsInContainerProgress) 377 self.inWndGauge.SetValue(unitsInWndProgress)