NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

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)