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

fittingMgmtCont.py (17070B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\fitting\fittingMgmtCont.py
      2 from collections import Counter
      3 import blue
      4 import evetypes
      5 from carbon.common.script.util.linkUtil import GetShowInfoLink
      6 from carbonui import ButtonStyle, uiconst
      7 from carbonui.control.button import Button
      8 from carbonui.control.contextMenu.menuEntryData import MenuEntryData
      9 from carbonui.control.singlelineedits.singleLineEditText import SingleLineEditText
     10 from carbonui.primitives.container import Container
     11 from carbonui.primitives.containerAutoSize import ContainerAutoSize
     12 from carbonui.primitives.sprite import Sprite
     13 from carbonui.uicore import uicore
     14 from carbonui.button.group import ButtonGroup, ButtonSizeMode
     15 from eve.client.script.ui.control.eveEditPlainText import EditPlainText
     16 from eve.client.script.ui.control.eveLabel import EveLabelMedium
     17 from eve.client.script.ui.control.eveScroll import Scroll
     18 from eve.client.script.ui.control.infoIcon import InfoIcon
     19 from eve.client.script.ui.control.itemIcon import ItemIcon
     20 from carbonui.control.tabGroup import TabGroup
     21 from eve.client.script.ui.control.utilMenu import UtilMenu
     22 from eve.client.script.ui.shared.fittingScreen.missingItemsPopup import OpenBuyAllBox
     23 from eve.common.lib.appConst import corpRoleFittingManager, maxLengthFittingDescription
     24 from eveexceptions import UserError
     25 from inventorycommon.const import categoryStructure, numVisibleSubsystems
     26 from inventorycommon.util import IsModularShip, IsSubsystemFlag
     27 from localization import GetByLabel
     28 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     29 from shipfitting.exportFittingUtil import AreModulesTranslated
     30 from utillib import KeyVal
     31 
     32 class FittingMgmtCont(Container):
     33     default_align = uiconst.TOALL
     34     default_clipChildren = True
     35 
     36     def ApplyAttributes(self, attributes):
     37         Container.ApplyAttributes(self, attributes)
     38         self.saveCallback = attributes.get('saveCallback', None)
     39         self.fittingSvc = sm.GetService('fittingSvc')
     40         self.saveDeleteButtonsCont = ButtonGroup(name='buttonParent', parent=self, align=uiconst.TOBOTTOM, padTop=8, button_size_mode=ButtonSizeMode.STRETCH)
     41         self.mainPanel = Container(name='rightMainPanel', parent=self, align=uiconst.TOALL)
     42         topParent = Container(name='topParent', parent=self.mainPanel, align=uiconst.TOTOP, height=64)
     43         self.topLeftParent = Container(name='topLeftParent', parent=topParent, align=uiconst.TOLEFT, width=64, padRight=8)
     44         self.topRightParent = Container(name='topRightParent', parent=topParent, align=uiconst.TOALL)
     45         self.bottomParent = Container(name='bottomParent', parent=self.mainPanel)
     46         self.AddTypeIcons()
     47         self.AddFittingNameElements()
     48         self.AddDescriptionField()
     49         self.AddButtons()
     50 
     51     def AddTypeIcons(self):
     52         self.shipIcon = FittingDraggableIcon2(name='shipIcon', parent=self.topLeftParent, state=uiconst.UI_NORMAL, pos=(0, 0, 64, 64))
     53         self.shipIcon.fitting = {}
     54         self.shipIcon.hint = GetByLabel('UI/Fitting/FittingWindow/FittingManagement/FittingIconHint')
     55         self.shipIcon.OnClick = self.ClickDragIcon
     56 
     57     def AddFittingNameElements(self):
     58         shipInfoCont = Container(name='shipInfoCont', parent=self.topRightParent, align=uiconst.TOTOP, height=SingleLineEditText.default_height, padTop=12)
     59         iconCont = ContainerAutoSize(name='iconCont', align=uiconst.TORIGHT, parent=shipInfoCont)
     60         self.infoicon = InfoIcon(parent=iconCont, state=uiconst.UI_HIDDEN, align=uiconst.CENTERRIGHT)
     61         UtilMenu(menuAlign=uiconst.TOPRIGHT, parent=iconCont, align=uiconst.CENTERRIGHT, pos=(20, 0, 16, 16), GetUtilMenu=self.SettingMenu, texturePath='res:/UI/Texture/SettingsCogwheel.png', hint=GetByLabel('UI/Common/Settings'), iconSize=18)
     62         self.fittingTypeIcon = Sprite(parent=ContainerAutoSize(parent=shipInfoCont, align=uiconst.TOLEFT), pos=(0, 0, 20, 20), texturePath='res:/UI/Texture/WindowIcons/member.png', align=uiconst.CENTERLEFT)
     63         self.fittingName = SingleLineEditText(name='fittingName', parent=shipInfoCont, align=uiconst.TOTOP, padding=(4, 0, 4, 0), maxLength=40, label=GetByLabel('UI/Fitting/FittingWindow/FittingManagement/FittingName'), fontsize=12, configName='edit_fittingName', maxWidth=120, OnFocusLost=self.OnEditFieldLostFocus, OnSetFocus=self.OnEditFieldSetFocus)
     64         self.OnEditFieldLostFocus()
     65         truncatedText = GetByLabel('UI/Fitting/FittingWindow/FittingManagement/Truncated')
     66         self.truncatedLabel = EveLabelMedium(text=truncatedText, parent=self.topRightParent, pos=(0, 3, 60, 20), state=uiconst.UI_NORMAL, align=uiconst.TOTOP)
     67         self.truncatedLabel.display = True
     68 
     69     def OnEditFieldLostFocus(self, *args):
     70         self.fittingName.opacity = 0.5
     71         self.fittingName.textLabel.opacity = 2.0
     72 
     73     def OnEditFieldSetFocus(self, *args):
     74         self.fittingName.opacity = 1.0
     75         self.fittingName.textLabel.opacity = 1.0
     76 
     77     def AddDescriptionField(self):
     78         self.fittingDescription = EditPlainText(setvalue=None, parent=self.bottomParent, align=uiconst.TOALL, maxLength=maxLengthFittingDescription)
     79         self.fittingInfo = Scroll(name='fittingInfoScroll', parent=self.bottomParent)
     80         tabs = [[GetByLabel('UI/Fitting/FittingWindow/FittingManagement/Fittings'),
     81           self.fittingInfo,
     82           self,
     83           None,
     84           self.fittingInfo], [GetByLabel('UI/Common/Description'),
     85           self.fittingDescription,
     86           self,
     87           None,
     88           self.fittingDescription]]
     89         self.fittingInfoTab = TabGroup(name='tabparent', parent=self.bottomParent, idx=0)
     90         self.fittingInfoTab.Startup(tabs, 'fittingInfoTab')
     91         self.fittingInfo.Startup()
     92 
     93     def AddButtons(self):
     94         pass
     95 
     96     def AddFitSaveBtns(self):
     97         self.fitBtn = Button(parent=self.saveDeleteButtonsCont, label=GetByLabel('UI/Fitting/FittingWindow/FittingManagement/Fit'), func=self.Fit)
     98         self.saveBtn = Button(parent=self.saveDeleteButtonsCont, label=GetByLabel('UI/Common/Buttons/Save'), func=self.Save, get_menu_entry_data_func=self._get_save_sub_menu_data)
     99         self.saveBtn.LoadTooltipPanel = self.LoadSaveBtnTooltipPanel
    100 
    101     def _get_save_sub_menu_data(self):
    102         sub_menu = []
    103         if session.allianceid:
    104             alliance = sm.GetService('alliance').GetAlliance(session.allianceid)
    105             if alliance.executorCorpID == session.corpid:
    106                 sub_menu.append(MenuEntryData(text=GetByLabel('UI/Fitting/FittingWindow/SaveForAlliance'), func=lambda : self.SaveForOwner(session.allianceid)))
    107         sub_menu.append(MenuEntryData(text=GetByLabel('UI/Fitting/FittingWindow/SaveForCorp'), func=lambda : self.SaveForOwner(session.corpid)))
    108         sub_menu.append(MenuEntryData(text=GetByLabel('UI/Fitting/FittingWindow/SaveForCharacter', charID=session.charid), func=lambda : self.SaveForOwner(session.charid)))
    109         return MenuEntryData(text=GetByLabel('UI/Common/Buttons/Save'), func=self.Save, subMenuData=sub_menu)
    110 
    111     def AddDeleteBtn(self):
    112         self.deleteBtn = Button(parent=self.saveDeleteButtonsCont, label=GetByLabel('UI/Common/Buttons/Delete'), func=self.Delete, style=ButtonStyle.DANGER)
    113 
    114     def TryAddSimulationBtn(self):
    115         self.simulateButton = Button(parent=self.saveDeleteButtonsCont, label=GetByLabel('UI/Fitting/FittingWindow/Simulate'), func=self.SimulateFitting)
    116 
    117     def AddExportBtn(self):
    118         self.exportBtn = Button(parent=self.saveDeleteButtonsCont, label=GetByLabel('UI/Fitting/FittingWindow/FittingManagement/ExportToClipboard'), func=self.ExportFittingToClipboard, hint=GetByLabel('UI/Fitting/FittingWindow/FittingManagement/ExportToClipboardHint'))
    119         if AreModulesTranslated(session):
    120             self.exportBtn.LoadTooltipPanel = self.LoadExportTooltipPanel
    121 
    122     def AddMultiBuyBtn(self):
    123         import shipfitting.multiBuyUtil as multiBuyUtil
    124         multiBuyUtil.AddBuyButton(parent=self.saveDeleteButtonsCont, fittingMgmtWnd=self)
    125 
    126     def SettingMenu(self, menuParent):
    127         nameCbChecked = settings.user.ui.Get('useFittingNameForShips', 0)
    128         menuParent.AddCheckBox(text=GetByLabel('UI/Fitting/FittingWindow/FittingManagement/UseFittingNameForShip'), checked=bool(nameCbChecked), callback=(settings.user.ui.Set, 'useFittingNameForShips', not nameCbChecked))
    129 
    130     def LoadSaveBtnTooltipPanel(self, tooltipPanel, *args):
    131         hasCorpRoles = bool(session.corprole & corpRoleFittingManager)
    132         if not hasCorpRoles:
    133             return
    134         tooltipPanel.LoadGeneric1ColumnTemplate()
    135         tooltipPanel.state = uiconst.UI_NORMAL
    136         tooltipPanel.columns = 1
    137         tooltipPanel.margin = (12, 12, 12, 12)
    138         tooltipPanel.cellPadding = 0
    139         tooltipPanel.cellSpacing = 10
    140         saveAllianceBtn = None
    141         if session.allianceid and sm.GetService('alliance').GetAlliance(session.allianceid).executorCorpID == session.corpid:
    142             saveAllianceBtn = Button(parent=tooltipPanel, label=GetByLabel('UI/Fitting/FittingWindow/SaveForAlliance'), func=self.SaveForOwner, args=(session.allianceid,), align=uiconst.CENTER)
    143         saveCorpBtn = Button(parent=tooltipPanel, label=GetByLabel('UI/Fitting/FittingWindow/SaveForCorp'), func=self.SaveForOwner, args=(session.corpid,), align=uiconst.CENTER)
    144         savePersonalBtn = Button(parent=tooltipPanel, label=GetByLabel('UI/Fitting/FittingWindow/SaveForCharacter', charID=session.charid), func=self.SaveForOwner, args=(session.charid,), align=uiconst.CENTER)
    145         maxWidth = max(saveCorpBtn.width, savePersonalBtn.width)
    146         if saveAllianceBtn:
    147             maxWidth = max(maxWidth, saveAllianceBtn.width)
    148         saveCorpBtn.width = savePersonalBtn.width = maxWidth
    149         if saveAllianceBtn:
    150             saveAllianceBtn.width = maxWidth
    151 
    152     def LoadExportTooltipPanel(self, tooltipPanel, *args):
    153         tooltipPanel.LoadGeneric1ColumnTemplate()
    154         tooltipPanel.state = uiconst.UI_NORMAL
    155         tooltipPanel.columns = 1
    156         tooltipPanel.margin = (12, 12, 12, 12)
    157         tooltipPanel.cellPadding = 0
    158         tooltipPanel.cellSpacing = 10
    159         exportBtn = Button(parent=tooltipPanel, label=GetByLabel('UI/Fitting/FittingWindow/FittingManagement/ExportToClipboardLocalized'), func=self._ExportFittingToClipboard, args=(True,), align=uiconst.CENTER)
    160         exportEnglishBtn = Button(parent=tooltipPanel, label=GetByLabel('UI/Fitting/FittingWindow/FittingManagement/ExportToClipboard'), func=self._ExportFittingToClipboard, args=(False,), align=uiconst.CENTER)
    161         maxWidth = max(exportEnglishBtn.width, exportBtn.width)
    162         exportEnglishBtn.width = exportBtn.width = maxWidth
    163 
    164     def SetFittingTypeIcon(self, fittingOwner):
    165         if fittingOwner == session.charid:
    166             texturePath = 'res:/UI/Texture/WindowIcons/member.png'
    167             text = GetByLabel('UI/Fitting/FittingWindow/FittingManagement/PersonalFitting')
    168         elif fittingOwner == session.corpid:
    169             texturePath = 'res:/UI/Texture/WindowIcons/corporation.png'
    170             text = GetByLabel('UI/Fitting/FittingWindow/FittingManagement/CorporationFitting')
    171         else:
    172             self.fittingTypeIcon.display = False
    173             return
    174         self.fittingTypeIcon.display = True
    175         self.fittingTypeIcon.hint = text
    176         self.fittingTypeIcon.texturePath = texturePath
    177 
    178     def LoadNewFitting(self, fitting, isTruncated = False):
    179         self.ShowPanel()
    180         self.fitting = fitting
    181         self.fittingName.SetValue(fitting.name)
    182         self.fittingDescription.SetText(fitting.description)
    183         self.fittingDescription.SetText(fitting.description)
    184         shipName = GetShowInfoLink(fitting.shipTypeID, evetypes.GetName(fitting.shipTypeID))
    185         self.shipIcon.SetTypeID(fitting.shipTypeID)
    186         self.shipIcon.fitting = fitting
    187         self.infoicon.Show()
    188         self.infoicon.SetTypeID(fitting.shipTypeID)
    189         if isTruncated:
    190             self.truncatedLabel.display = True
    191         else:
    192             self.truncatedLabel.display = False
    193         fittingOwner = fitting.ownerID
    194         self.SetFittingTypeIcon(fittingOwner)
    195         scrolllist = self.fittingSvc.GetFittingInfoScrollList(fitting)
    196         self.fittingInfo.Load(contentList=scrolllist)
    197         if evetypes.GetCategoryID(fitting.shipTypeID) == categoryStructure:
    198             self.fitBtn.Disable()
    199         else:
    200             self.fitBtn.Enable()
    201 
    202     def HidePanel(self):
    203         self.display = False
    204         self.fitting = None
    205 
    206     def ShowPanel(self):
    207         self.display = True
    208 
    209     def GetSelectedFitting(self):
    210         return self.fitting
    211 
    212     def ClickDragIcon(self, *args):
    213         subsystems = {}
    214         if IsModularShip(self.fitting.shipTypeID):
    215             for typeID, flag, qty in self.fitting.fitData:
    216                 if IsSubsystemFlag(flag):
    217                     subsystems[evetypes.GetGroupID(typeID)] = typeID
    218 
    219             if len(subsystems) != numVisibleSubsystems:
    220                 raise UserError('NotEnoughSubSystemsNotify', {})
    221         sm.GetService('preview').PreviewType(self.fitting.shipTypeID, subsystems)
    222 
    223     def ShowInfo(self, *args):
    224         if self.fitting is not None:
    225             sm.GetService('info').ShowInfo(self.fitting.shipTypeID, None)
    226 
    227     def Fit(self, *args):
    228         fitting = self.fitting
    229         failedToLoad = self.fittingSvc.LoadFitting(fitting, getFailedDict=True)
    230         failedToLoadCounter = Counter({x[0]:x[1] for x in failedToLoad})
    231         if failedToLoadCounter:
    232             OpenBuyAllBox(failedToLoadCounter, fitting)
    233         else:
    234             from eve.client.script.ui.shared.fittingScreen.fittingWnd import FittingWindow
    235             wnd = FittingWindow.GetIfOpen()
    236             if wnd:
    237                 sm.GetService('ghostFittingSvc').TryExitSimulation(askQuestion=True)
    238 
    239     def Save(self, *args):
    240         if self.fitting.ownerID == session.corpid and bool(session.corprole & corpRoleFittingManager):
    241             return self.SaveForOwner(session.corpid)
    242         else:
    243             return self.SaveForOwner(session.charid)
    244 
    245     def SaveForOwner(self, ownerID):
    246         if self.fitting.ownerID:
    247             self.SaveExistingFitting(ownerID)
    248         else:
    249             self.SaveNewFitting(ownerID)
    250 
    251     def Delete(self, *args):
    252         pass
    253 
    254     def SimulateFitting(self, *args):
    255         SimulateFitting(self.fitting)
    256 
    257     def ExportFittingToClipboard(self, *args):
    258         self._ExportFittingToClipboard()
    259 
    260     def _ExportFittingToClipboard(self, isLocalized = False):
    261         sm.GetService('fittingSvc').ExportFittingToClipboard(self.fitting, isLocalized)
    262 
    263     def SaveExistingFitting(self, newOwnerID):
    264         if self.fitting is None:
    265             return
    266         newFitting = None
    267         if newOwnerID != self.fitting.ownerID:
    268             return self.SaveNewFitting(newOwnerID)
    269         if newFitting is not None:
    270             fitting = newFitting
    271         else:
    272             fitting = self.fitting
    273         newName = self.fittingName.GetValue()
    274         newDescription = self.fittingDescription.GetValue()
    275         blue.synchro.Yield()
    276         self.fittingSvc.ChangeNameAndDescription(fitting.fittingID, fitting.ownerID, newName, newDescription)
    277         sm.ScatterEvent('OnRedrawFittingMgmt')
    278         sm.ScatterEvent('OnFittingsUpdated', self.fitting)
    279         if self.saveCallback:
    280             self.saveCallback()
    281 
    282     def SaveNewFitting(self, ownerID):
    283         name = self.fittingName.GetValue()
    284         description = self.fittingDescription.GetValue()
    285         fittingID = self.fittingSvc.PersistFitting(ownerID, name, description, fit=(self.fitting.shipTypeID, self.fitting.fitData))
    286         if fittingID > 0 and self.saveCallback:
    287             self.saveCallback()
    288 
    289 
    290 class FittingMgmtContInWnd(FittingMgmtCont):
    291 
    292     def Delete(self, *args):
    293         if prompt_player_fsd_dialog('DeleteFitting', {}, uiconst.YESNO, suppress=uiconst.ID_YES) != uiconst.ID_YES:
    294             return
    295         if not self.fitting:
    296             return
    297         ownerID = self.fitting.ownerID
    298         fittingID = self.fitting.fittingID
    299         self.fittingSvc.DeleteFitting(ownerID, fittingID)
    300         self.HidePanel()
    301 
    302     def AddButtons(self):
    303         self.AddFitSaveBtns()
    304         self.AddMultiBuyBtn()
    305         self.TryAddSimulationBtn()
    306         self.AddExportBtn()
    307         self.AddDeleteBtn()
    308 
    309 
    310 class FittingMgmtContInStandalone(FittingMgmtCont):
    311 
    312     def AddButtons(self):
    313         self.AddFitSaveBtns()
    314         self.AddMultiBuyBtn()
    315         self.TryAddSimulationBtn()
    316 
    317 
    318 class FittingDraggableIcon2(ItemIcon):
    319     __guid__ = 'xtriui.FittingDraggableIcon2'
    320     isDragObject = True
    321 
    322     def Startup(self, fitting):
    323         self.fitting = fitting
    324 
    325     def GetDragData(self, *args):
    326         entry = KeyVal()
    327         entry.fitting = self.fitting
    328         entry.__guid__ = 'listentry.FittingEntry'
    329         return [entry]
    330 
    331 
    332 def SimulateFitting(fitting):
    333     from eve.client.script.ui.shared.fittingScreen.fittingWnd import FittingWindow
    334     wnd = FittingWindow.GetIfOpen()
    335     if wnd:
    336         wnd.Maximize()
    337     else:
    338         uicore.cmd.OpenFitting()
    339     sm.GetService('ghostFittingSvc').SimulateFitting(fitting)