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

buySellMultiBase.py (14776B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\market\buySellMultiBase.py
      2 import math
      3 import eveformat
      4 import evelink.client
      5 from carbon.common.script.util.format import FmtAmt
      6 from carbonui import TextColor, uiconst
      7 from carbonui.control.scrollContainer import ScrollContainer
      8 from carbonui.primitives.container import Container
      9 from carbonui.primitives.sprite import Sprite
     10 from carbonui.button.group import ButtonGroup
     11 from carbonui.control.checkbox import Checkbox
     12 from eve.client.script.ui.control.eveIcon import Icon
     13 from eve.client.script.ui.control.eveLabel import EveCaptionSmall
     14 from carbonui.control.window import Window
     15 from eve.client.script.ui.control.utilMenu import UtilMenu
     16 from eve.client.script.ui.shared.market.accessControl import MarketAccessControl
     17 from eve.client.script.ui.shared.pointerTool.pointerToolConst import UNIQUE_NAME_MARKET_ORDER_DURATION
     18 from eve.common.lib.appConst import corpRoleAccountant, corpRoleTrader
     19 import evetypes
     20 from inventorycommon.const import typePlex
     21 from localization import GetByLabel
     22 import uthread
     23 from carbonui.uicore import uicore
     24 from eve.client.script.ui.tooltips.tooltipUtil import SetTooltipHeaderAndDescription
     25 from eveprefs import boot
     26 from marketutil.feature_flags.client import is_global_plex_market_experiment_enabled
     27 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     28 COL_GREEN = (0.3, 0.9, 0.1)
     29 COL_RED = (1.0, 0.275, 0.0)
     30 COL_WHITE = (1.0, 1.0, 1.0)
     31 
     32 class SellBuyItemsWindow(Window):
     33     __notifyevents__ = ['OnSessionChanged']
     34     default_width = 520
     35     default_height = 390
     36     default_minSize = (default_width, default_height)
     37     default_windowID = 'SellBuyItemsWindow'
     38     captionTextPath = 'UI/Inventory/ItemActions/MultiBuy'
     39     scrollId = 'MultiBuyScroll'
     40     tradeForCorpSettingConfig = 'buyUseCorp'
     41     tradeTextPath = 'UI/Market/MarketQuote/CommandSell'
     42     orderCap = 'MultiSellOrderCap'
     43     tradeOnConfirm = True
     44     corpCheckboxTop = 38
     45     numbersGridTop = 6
     46     dropLabelPath = 'UI/Market/Marketbase/DropItemsToAdd'
     47     cannotBeTradeLabelPath = 'UI/Market/MarketQuote/CannotBeSold'
     48     badDeltaWarningPath = 'UI/Market/MarketQuote/MultiBuyTypesAboveAverage'
     49     salesTaxToolTipHeaderLabelPath = 'UI/Market/MarketQuote/SalesTaxTooltipHeader'
     50     salesTaxToolTipDescriptionLabelPath = 'UI/Market/MarketQuote/SalesTaxTooltipDescription'
     51     brokersFeeTooltipHeaderLabelPath = 'UI/Market/MarketQuote/BrokersFeeTooltipHeader'
     52     brokersFeeTooltipDescriptionLabelPath = 'UI/Market/MarketQuote/BrokersFeeTooltipDescription'
     53     importHintLabelPath = ''
     54     exportHintLabelPath = ''
     55 
     56     def ApplyAttributes(self, attributes):
     57         Window.ApplyAttributes(self, attributes)
     58         self.isReadOnly = MarketAccessControl().is_sell_items_read_only
     59         self.marketQuoteSvc = sm.GetService('marketQuote')
     60         self.InitializeVariables(attributes)
     61         self.SetCaption(GetByLabel(self.captionTextPath))
     62         self.scope = uiconst.SCOPE_INGAME
     63         self.mainCont = mainCont = Container(parent=self.sr.main, name='mainCont')
     64         self.infoCont = Container(parent=mainCont, name='infoCont', align=uiconst.TOBOTTOM, height=92)
     65         self.bottomLeft = Container(parent=self.infoCont, name='bottomLeft', align=uiconst.TOLEFT, width=250, state=uiconst.UI_PICKCHILDREN, uniqueUiName=UNIQUE_NAME_MARKET_ORDER_DURATION)
     66         self.bottomRight = Container(parent=self.infoCont, name='bottomRight', align=uiconst.TORIGHT, width=250)
     67         self.AddImportExportButtons()
     68         self.dropCont = Container(name='dropCont', parent=mainCont, align=uiconst.TOTOP, state=uiconst.UI_NORMAL, height=32, padding=(32, 0, 32, 0))
     69         self.dropLabel = EveCaptionSmall(parent=self.dropCont, align=uiconst.CENTER, text=GetByLabel(self.dropLabelPath), color=TextColor.SECONDARY)
     70         self.fakeItemsCont = Container(parent=self.dropCont, align=uiconst.TOALL, clipChildren=True)
     71         self.locationCont = Container(parent=mainCont, name='locationCont', align=uiconst.TOTOP)
     72         self.scrollCont = Container(parent=mainCont, name='scrollCont', padding=(0, 8, 0, 8))
     73         self.itemsScroll = ScrollContainer(parent=self.scrollCont, id=self.scrollId)
     74         self.btnGroup = ButtonGroup(parent=self.sr.main, idx=0, line=False)
     75         self.tradeButton = self.btnGroup.AddButton(GetByLabel(self.tradeTextPath), self.PerformTrade, isDefault=self.tradeOnConfirm, uiName='confirm_sell_button')
     76         self.btnGroup.AddButton(GetByLabel('UI/Generic/Cancel'), self.Cancel, uiName='cancel_sell_button')
     77         self.DrawNumbers()
     78         corpAcctName = self._CanTradeForCorp()
     79         if corpAcctName is not None:
     80             self.DrawCheckBox(corpAcctName)
     81         self.globalDragHover = uicore.event.RegisterForTriuiEvents(uiconst.UI_MOUSEHOVER, self.OnGlobalMouseHover)
     82 
     83     def StartAddItemsThread(self):
     84         if len(self.preItems):
     85             self.addItemsThread = uthread.new(self.AddPreItems, self.preItems)
     86 
     87     def InitializeVariables(self, attributes):
     88         self.globalDragHover = None
     89         self.cannotTradeItemList = []
     90         self.itemList = []
     91         self.preItems = attributes.preItems or []
     92         self.useCorp = None
     93         self.hasDrawn = False
     94         self.addItemsThread = None
     95         self.baseStationID = None
     96 
     97     def DrawNumbers(self):
     98         pass
     99 
    100     def SetupBrokersFeeTooltips(self):
    101         SetTooltipHeaderAndDescription(self.brokersFee, GetByLabel(self.brokersFeeTooltipHeaderLabelPath), GetByLabel(self.brokersFeeTooltipDescriptionLabelPath))
    102         SetTooltipHeaderAndDescription(self.brokersFeeAmt, GetByLabel(self.brokersFeeTooltipHeaderLabelPath), GetByLabel(self.brokersFeeTooltipDescriptionLabelPath))
    103 
    104     def SetupSalesTaxTooltips(self):
    105         SetTooltipHeaderAndDescription(self.salesTax, GetByLabel(self.salesTaxToolTipHeaderLabelPath), GetByLabel(self.salesTaxToolTipDescriptionLabelPath))
    106         SetTooltipHeaderAndDescription(self.salesTaxAmt, GetByLabel(self.salesTaxToolTipHeaderLabelPath), GetByLabel(self.salesTaxToolTipDescriptionLabelPath))
    107 
    108     def DrawCheckBox(self, corpAcctName):
    109         useCorpWallet = settings.user.ui.Get(self.tradeForCorpSettingConfig, False)
    110         top = self.corpCheckboxTop
    111         self.useCorp = Checkbox(text=GetByLabel('UI/Market/MarketQuote/UseCorpAccount', accountName=corpAcctName), parent=self.bottomLeft, settingsKey='usecorp', checked=useCorpWallet, callback=self.OnUseCorp, pos=(0,
    112          top,
    113          350,
    114          0), align=uiconst.TOPLEFT)
    115 
    116     def AddImportExportButtons(self):
    117         self._AddImportButton()
    118         self._AddExportButton()
    119 
    120     def _AddImportButton(self):
    121         importMenu = UtilMenu(name='importMenu', menuAlign=uiconst.TOPLEFT, parent=self.mainCont, align=uiconst.TOPLEFT, pos=(0, 0, 32, 32), GetUtilMenu=self.GetImportMenu, texturePath='res:/UI/Texture/Shared/pasteFrom.png', iconSize=28, hint=GetByLabel(self.importHintLabelPath))
    122 
    123     def _AddExportButton(self):
    124         exportMenu = UtilMenu(name='exportMenu', menuAlign=uiconst.TOPLEFT, parent=self.mainCont, align=uiconst.TOPRIGHT, pos=(4, 0, 28, 28), GetUtilMenu=self.GetExportMenu, texturePath='res:/UI/Texture/Shared/copyTo.png', iconSize=28, hint=GetByLabel(self.exportHintLabelPath))
    125 
    126     def _CanTradeForCorp(self):
    127         if session.corprole & (corpRoleAccountant | corpRoleTrader):
    128             corpAcctName = sm.GetService('corp').GetMyCorpAccountName()
    129             if corpAcctName is not None:
    130                 return corpAcctName
    131 
    132     def OnUseCorp(self, *args):
    133         if self.useCorp.checked:
    134             newValue = True
    135         else:
    136             newValue = False
    137         settings.user.ui.Set(self.tradeForCorpSettingConfig, newValue)
    138         self.UpdateNumbers()
    139 
    140     def TradingForCorp(self):
    141         if self.useCorp:
    142             useCorp = self.useCorp.checked
    143         else:
    144             useCorp = False
    145         return useCorp
    146 
    147     def GetImportMenu(self, menuParent):
    148         pass
    149 
    150     def GetExportMenu(self, menuParent):
    151         pass
    152 
    153     def DropItems(self, dragObj, nodes):
    154         pass
    155 
    156     def PerformTrade(self, *args):
    157         pass
    158 
    159     def UpdateNumbers(self):
    160         pass
    161 
    162     def GetItems(self):
    163         return self.itemList
    164 
    165     def AddPreItems(self, preItems):
    166         pass
    167 
    168     def IsAllowedDragData(self, dragData):
    169         return True
    170 
    171     def DrawDraggedItems(self, dragData):
    172         if not self.IsAllowedDragData(dragData):
    173             return
    174         self.hasDrawn = True
    175         uicore.animations.FadeOut(self.dropLabel, duration=0.15)
    176         noOfItems = len(dragData)
    177         noOfAvailable = math.floor((self.width - 16 - self.dropCont.padLeft - self.dropCont.padRight) / 28)
    178         for i, dragItem in enumerate(dragData):
    179             c = Container(parent=self.fakeItemsCont, align=uiconst.TOLEFT, padding=2, width=24)
    180             if noOfItems > noOfAvailable and i == noOfAvailable - 1:
    181                 icon = Sprite(parent=c, texturePath='res:/UI/Texture/classes/MultiSell/DotDotDot.png', state=uiconst.UI_DISABLED, width=24, height=24, align=uiconst.CENTER)
    182                 icon.SetAlpha(0.6)
    183                 return
    184             typeID = self.GetTypeIDFromDragItem(dragItem)
    185             icon = Icon(parent=c, typeID=typeID, state=uiconst.UI_DISABLED)
    186             icon.SetSize(24, 24)
    187 
    188     def GetTypeIDFromDragItem(self, dragItem):
    189         getTypeID = dragItem.item.typeID
    190         return getTypeID
    191 
    192     def OnDropData(self, dragSource, dragData):
    193         self.ClearDragData()
    194 
    195     def ClearDragData(self):
    196         self.fakeItemsCont.Flush()
    197         uicore.animations.FadeIn(self.dropLabel, 0.6, duration=0.3)
    198         self.hasDrawn = False
    199 
    200     def OnGlobalMouseHover(self, *args, **kw):
    201         shouldClearDragData = True
    202         if uicore.IsDragging() and uicore.dragObject:
    203             mo = uicore.uilib.mouseOver
    204             if mo == self or mo.IsUnder(self):
    205                 shouldClearDragData = False
    206                 if not self.hasDrawn:
    207                     self.DrawDraggedItems(uicore.dragObject.dragData)
    208         if shouldClearDragData:
    209             self.ClearDragData()
    210         return True
    211 
    212     def Cancel(self, *args):
    213         self.Close()
    214 
    215     def Close(self, *args, **kwds):
    216         Window.Close(self, *args, **kwds)
    217         if self.addItemsThread:
    218             self.addItemsThread.kill()
    219         uicore.event.UnregisterForTriuiEvents(self.globalDragHover)
    220 
    221     def CheckOrderAvailability(self, preItems):
    222         availableOrders = int(sm.GetService('machoNet').GetGlobalConfig().get(self.orderCap, 100)) - len(self.itemList)
    223         if len(preItems) > availableOrders:
    224             prompt_player_fsd_dialog('CustomNotify', {'notify': GetByLabel('UI/Market/MarketQuote/TooManyItemsForOrder')})
    225             return preItems[:availableOrders]
    226         return preItems
    227 
    228     def RemoveItem(self, itemEntry):
    229         self.itemsScroll._RemoveChild(itemEntry)
    230         self.itemList.remove(itemEntry)
    231         self.RemoveItemFromCollection(itemEntry)
    232         self.UpdateNumbers()
    233         self.UpdateHeaderCount()
    234 
    235     def RemoveItemFromCollection(self, itemEntry):
    236         pass
    237 
    238     def DoAddItem(self, item):
    239         itemEntry = self.GetItemEntry(item)
    240         self.AddItemToCollection(item, itemEntry)
    241         itemEntry.state = uiconst.UI_NORMAL
    242         self.itemsScroll._InsertChild(0, itemEntry)
    243         self.itemList.append(itemEntry)
    244         self.UpdateNumbers()
    245         self.UpdateHeaderCount()
    246         return itemEntry
    247 
    248     def UpdateHeaderCount(self):
    249         if is_global_plex_market_experiment_enabled() and any((x.typeID == typePlex for x in self.itemList)):
    250             self.SetCaption('%s (%i)' % (GetByLabel(self.captionTextPath), len(self.itemList)))
    251         else:
    252             self.SetCaption('%s (%i) - %s' % (GetByLabel(self.captionTextPath), len(self.itemList), self.GetStationLocationText()))
    253 
    254     def GetStationLocationText(self):
    255         if self.baseStationID is None:
    256             return ''
    257         stationLocation = cfg.evelocations.Get(self.baseStationID).locationName
    258         return stationLocation
    259 
    260     def DisplayErrorHints(self):
    261         hintTextList = self.GetErrorHints()
    262         if hintTextList:
    263             hintText = '<br>'.join(hintTextList)
    264             prompt_player_fsd_dialog('CustomNotify', {'notify': hintText})
    265 
    266     def GetErrorHints(self):
    267         hintTextList = self.BuildHintTextList(self.cannotTradeItemList, self.cannotBeTradeLabelPath)
    268         return hintTextList
    269 
    270     def BuildHintTextList(self, itemList, labelPath):
    271         hintTextList = []
    272         if len(itemList):
    273             hintTextList.append(eveformat.bold(GetByLabel(labelPath)))
    274             for item in itemList:
    275                 hintTextList.append(evelink.type_link(type_id=item.typeID))
    276 
    277         return hintTextList
    278 
    279     def ClearErrorLists(self):
    280         self.cannotTradeItemList = []
    281 
    282     def GetValidatedItem(self, item):
    283         return None
    284 
    285     def GetItemsIterator(self, onlyValid = False):
    286         for item in self.GetItems():
    287             if not item:
    288                 continue
    289             if onlyValid and not self.GetValidatedItem(item):
    290                 continue
    291             yield item
    292 
    293     def GetOrderDeltaTextForWarning(self):
    294         return ''
    295 
    296     def GetItemsWithBadDelta(self, args):
    297         return []
    298 
    299     def ContinueAfterWarning(self, buyItemList):
    300         highItems = self.GetItemsWithBadDelta(buyItemList)
    301         orderText = self.GetOrderDeltaTextForWarning()
    302         hightText = ''
    303         if highItems:
    304             highTextList = [GetByLabel(self.badDeltaWarningPath)]
    305             highItems.sort(key=lambda x: x[0], reverse=True)
    306             for perc, item in highItems:
    307                 percText = GetByLabel('UI/Common/Percentage', percentage=FmtAmt(perc * 100, showFraction=0))
    308                 highTextList.append('- %s (%s)' % (evetypes.GetName(item.typeID), percText))
    309 
    310             hightText = '<br>'.join(highTextList)
    311         if orderText or hightText:
    312             warningTextList = []
    313             if orderText:
    314                 warningTextList.append(orderText)
    315                 warningTextList.append('')
    316             if hightText:
    317                 warningTextList.append(hightText)
    318                 warningTextList.append('')
    319             warningTextList.append(GetByLabel('UI/Market/MarketQuote/MultiBuyAboveAverageConfirmation'))
    320             warningText = '<br>'.join(warningTextList)
    321             headerLabel = GetByLabel('UI/Generic/Warning')
    322             ret = prompt_player_fsd_dialog('CustomQuestion', {'header': headerLabel,
    323              'question': warningText}, uiconst.YESNO, default=uiconst.ID_NO)
    324             if ret != uiconst.ID_YES:
    325                 return False
    326         return True
    327 
    328     def AreExtraExportOptionsAvailable(self):
    329         extraOptions = boot.region != 'optic' and session.languageID != 'EN'
    330         return extraOptions