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

shipTreeContainer.py (14091B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\shipTree\shipTreeContainer.py
      2 import evetypes
      3 import geo2
      4 import inventorycommon.typeHelpers
      5 import trinity
      6 from carbonui import uiconst
      7 from carbonui.primitives.container import Container
      8 from carbonui.primitives.containerAutoSize import ContainerAutoSize
      9 from carbonui.primitives.sprite import Sprite
     10 from carbonui.primitives.stretchspritehorizontal import StretchSpriteHorizontal
     11 from carbonui.primitives.vectorlinetrace import VectorLineTrace
     12 from carbonui.uicore import uicore
     13 from characterdata.factions import get_faction_name
     14 from eve.client.script.ui.shared.cloneGrade import ORIGIN_SHIPTREE
     15 from eve.client.script.ui.shared.cloneGrade.omegaCloneIcon import OmegaCloneIcon
     16 from eve.client.script.ui.shared.shipTree.shipTreeShipGroup import ShipTreeShipGroup
     17 from eve.client.script.ui.shared.shipTree import shipTreeConst
     18 from eve.client.script.ui.shared.shipTree.shipTreeConst import TREE_SCALE, NODETYPE_GROUP, NODETYPE_OTHERFACTIONGROUP, COLOR_BG, NODETYPE_ROOT, BG_BY_FACTIONID, COLOR_MASTERED
     19 from carbonui.control.buttonIcon import ButtonIcon
     20 from eve.client.script.ui.control.eveLabel import Label
     21 from eve.common.script.net.eveMachoNetVersion import machoVersion
     22 from eve.common.lib import appConst as const
     23 from inventorycommon.const import typeCapsule
     24 from localization import GetByMessageID, GetByLabel
     25 from omega.client.clone_grade_svc import get_clone_grade_svc
     26 X_OFFSET = 22
     27 Y_OFFSET = 40
     28 COLOR_FONT = (0.667,
     29  0.796,
     30  0.906,
     31  1.0)
     32 COLOR_LINE_TO = (1.0,
     33  1.0,
     34  1.0,
     35  1.0)
     36 COLOR_LINE_OMEGA = (1.0,
     37  0.8,
     38  0.0,
     39  1.0)
     40 
     41 class ShipTreeContainer(ContainerAutoSize):
     42     default_name = 'ShipTreeContainer'
     43 
     44     def ApplyAttributes(self, attributes):
     45         ContainerAutoSize.ApplyAttributes(self, attributes)
     46         self.factionID = attributes.factionID
     47         self._offset = None
     48         self._leftFloat = 0.0
     49         self._topFloat = 0.0
     50         self.rootNode = None
     51         self.shipGroups = {}
     52         self.lineCont = Container(name='lineCont', parent=self)
     53         self.ConstructTree()
     54         self.bgCont = Container(name='bgContainer', align=uiconst.CENTER, state=uiconst.UI_DISABLED, parent=self, padding=-100)
     55         self.topFrame = TopFrame(parent=self.bgCont, align=uiconst.TOTOP)
     56         self.bottomFrame = BottomFrame(parent=self.bgCont, align=uiconst.TOBOTTOM)
     57         Sprite(name='grid', bgParent=self.bgCont, state=uiconst.UI_DISABLED, align=uiconst.CENTER, texturePath='res:/UI/Texture/Classes/ShipTree/grid.png', color=(0.43, 0.727, 1.0, 0.2), idx=0, tileX=True, tileY=True)
     58         texturePath = BG_BY_FACTIONID.get(self.factionID)
     59         w, h = self.rootNode.GetDimensions()
     60         h = max(w, h) / 2
     61         height = 3.2 * h * TREE_SCALE
     62         width = 1.6 / 1.8 * height
     63         self.factionBG = Sprite(name='factionBG', parent=self.bgCont, align=uiconst.CENTER, texturePath=texturePath, width=width, height=height, opacity=0.18, idx=0)
     64 
     65     def ConstructTree(self):
     66         self.rootNode = sm.GetService('shipTree').GetRootNode(self.factionID)
     67         self._offset, _ = self.rootNode.GetBoundingBox()
     68         self.ConstructNodes()
     69         self.ConstructLines()
     70 
     71     def ConstructNodes(self):
     72         self.shipGroups = {}
     73         self._ConstructNodes(self.rootNode)
     74 
     75     def _ConstructNodes(self, node, i = 0, line = None):
     76         nodeType = node.GetNodeType()
     77         if nodeType == NODETYPE_GROUP:
     78             self.RenderShipGroup(node, i)
     79         elif nodeType == NODETYPE_OTHERFACTIONGROUP:
     80             self.RenderNodeOtherFactionGroup(node)
     81         elif nodeType == NODETYPE_ROOT:
     82             self.RenderRootNode(node)
     83         for childNode in node.children:
     84             self._ConstructNodes(childNode, i + 1, line)
     85 
     86     def ConstructLines(self, animate = True):
     87         self.lineCont.Flush()
     88         self._ConstructLines(self.rootNode, animate=animate)
     89 
     90     def _ConstructLines(self, node, i = 0, line = None, animate = True):
     91         if node.nodeType == NODETYPE_GROUP:
     92             line = None
     93         for childNode in node.children:
     94             line = self.RenderLine(node, childNode, i, line, animate=animate)
     95             self._ConstructLines(childNode, i + 1, line, animate)
     96             line = None
     97 
     98     def GetGroupNodeByID(self, shipGroupID):
     99         return self.rootNode.GetChildByID(shipGroupID)
    100 
    101     def GetGroupByID(self, shipGroupID):
    102         if not self.shipGroups:
    103             return None
    104         return self.shipGroups[shipGroupID]
    105 
    106     def RenderShipGroup(self, node, i):
    107         if node.parent and node.parent.nodeType == NODETYPE_OTHERFACTIONGROUP:
    108             return
    109         x, y = self._GetNodePosition(node)
    110         group = ShipTreeShipGroup(parent=self, node=node, alignMode=uiconst.TOPLEFT, left=x, top=y, idx=0, nodeNum=i)
    111         self.shipGroups[node.shipGroupID] = group
    112 
    113     def RenderNodeOtherFactionGroup(self, node):
    114         left, top = self._GetNodePosition(node)
    115         opacity = 0.2 if node.IsLocked() else 1.0
    116         texturePath = shipTreeConst.ICON_BY_FACTIONID.get(node.factionID)
    117         size = 64
    118         shipGroupData = cfg.infoBubbleGroups[node.shipGroupID]
    119         shipGroupName = GetByMessageID(shipGroupData['nameID'])
    120         ButtonIcon(parent=self, texturePath=texturePath, pos=(left - size / 2 + X_OFFSET,
    121          top - size / 2 + Y_OFFSET,
    122          size,
    123          size), iconSize=65, idx=0, func=self.OnOtherFactionClicked, args=(node,), opacity=opacity, hint='<b>%s</b>\n%s' % (get_faction_name(node.factionID), shipGroupName))
    124 
    125     def RenderOmegaIcon(self, node):
    126         left, top = self.GetOmegaIconPosition(node, node.GetParent())
    127         if self.IsOmega():
    128             tooltipText = GetByLabel('UI/CloneState/ShipTreeTooltipOmega')
    129             size = 32
    130             opacity = 0.5
    131         else:
    132             tooltipText = GetByLabel('UI/CloneState/ShipTreeTooltipAlpha')
    133             size = 64
    134             opacity = 1.0
    135         OmegaCloneIcon(parent=self.lineCont, pos=(left - size / 2,
    136          top - size / 2,
    137          size,
    138          size), idx=0, tooltipText=tooltipText, opacity=opacity, origin=ORIGIN_SHIPTREE)
    139 
    140     def GetOmegaIconPosition(self, node, parent):
    141         parentPosition = self._GetNodePosition(parent)
    142         childPosition = self._GetNodePosition(node)
    143         if childPosition[1] == parentPosition[1]:
    144             try:
    145                 offset = parent.GetGroupWidth()
    146                 s = offset / geo2.Vec2Length(geo2.Vec2Subtract(childPosition, parentPosition))
    147                 parentPosition = geo2.Vec2Lerp(parentPosition, childPosition, s)
    148             except AttributeError:
    149                 pass
    150 
    151         position = geo2.Vec2Lerp(parentPosition, childPosition, 0.5)
    152         position = geo2.Vec2Add(position, (X_OFFSET, Y_OFFSET))
    153         return position
    154 
    155     def RenderRootNode(self, node):
    156         texturePath = inventorycommon.typeHelpers.GetHoloIconPath(typeCapsule)
    157         size = 32
    158         left, top = self._GetNodePosition(node)
    159         if self.IsInGoldenPod():
    160             color = COLOR_MASTERED
    161             typeID = const.typeCapsuleGolden
    162         else:
    163             color = (1, 1, 1, 1)
    164             typeID = const.typeCapsule
    165         btn = RootNode(parent=self, pos=(left - size / 2 + X_OFFSET - 6,
    166          top - size / 2 - 2 + Y_OFFSET,
    167          size,
    168          size), func=sm.GetService('info').ShowInfo, iconSize=size, args=(typeID,), texturePath=texturePath, hint=evetypes.GetName(typeID), iconColor=color)
    169         btn.icon.blendMode = trinity.TR2_SBM_ADD
    170 
    171     def RenderLine(self, nodeFrom, nodeTo, i, line, animate = True):
    172         if nodeTo.nodeType == NODETYPE_OTHERFACTIONGROUP:
    173             return None
    174         if nodeTo.IsRestricted() and not self.IsOmega():
    175             colorTo = COLOR_LINE_OMEGA
    176         else:
    177             colorTo = COLOR_LINE_TO
    178         lineTexturePath = self.GetLineTexturePath(nodeTo)
    179         if not line or line.texturePath != lineTexturePath:
    180             line = VectorLineTraceShipTree(parent=self.lineCont, nodeFrom=nodeFrom, nodeTo=nodeTo, texturePath=lineTexturePath)
    181             pos = self.GetNewLineStartPos(nodeFrom, nodeTo)
    182             if i == 0 or nodeFrom.nodeType == NODETYPE_OTHERFACTIONGROUP:
    183                 colorFrom = (1.0, 1.0, 1.0, -0.05)
    184             elif nodeFrom.IsRestricted() and not self.IsOmega():
    185                 colorFrom = COLOR_LINE_OMEGA
    186             else:
    187                 colorFrom = COLOR_LINE_TO
    188             line.AddPoint(pos, colorFrom)
    189         posTo = self._GetLinePosition(nodeTo)
    190         line.AddPoint(posTo, colorTo)
    191         opacity = 0.7 if nodeTo.IsLocked() else 1.0
    192         if animate:
    193             uicore.animations.FadeIn(line, opacity, timeOffset=0.05 * i + 0.2, duration=0.3)
    194         else:
    195             line.opacity = opacity
    196         if nodeTo.IsRestricted() and not nodeFrom.IsRestricted() and not nodeFrom.nodeType == NODETYPE_OTHERFACTIONGROUP:
    197             self.RenderOmegaIcon(nodeTo)
    198         return line
    199 
    200     def IsInGoldenPod(self):
    201         implants = sm.GetService('godma').GetItem(session.charid).implants
    202         if implants is None:
    203             return False
    204         for implant in implants:
    205             if implant.typeID == const.typeGoldenCapsuleImplant:
    206                 return True
    207 
    208         return False
    209 
    210     def IsOmega(self):
    211         return get_clone_grade_svc().is_omega_with_grace_period()
    212 
    213     def GetLineTexturePath(self, nodeTo):
    214         if nodeTo.IsPathToElite():
    215             return 'res:/UI/Texture/classes/shipTree/lines/elite.png'
    216         if nodeTo.IsLocked():
    217             return 'res:/UI/Texture/classes/shipTree/lines/locked.png'
    218         return 'res:/UI/Texture/classes/shipTree/lines/unlocked.png'
    219 
    220     def GetNewLineStartPos(self, node, childNode):
    221         pos = self._GetLinePosition(node)
    222         childPos = self._GetLinePosition(childNode)
    223         if node.nodeType == NODETYPE_GROUP:
    224             if childPos[1] == pos[1]:
    225                 offset = node.GetGroupWidth() + 24
    226                 s = offset / geo2.Vec2Length(geo2.Vec2Subtract(childPos, pos))
    227                 pos = geo2.Vec2Lerp(pos, childPos, s)
    228         return (int(pos[0]), int(pos[1]))
    229 
    230     def _GetNodePosition(self, node):
    231         vec = geo2.Vec2Subtract(node.GetPosition(), self._offset)
    232         return geo2.Vec2Scale(vec, TREE_SCALE)
    233 
    234     def _GetLinePosition(self, node):
    235         vec = self._GetNodePosition(node)
    236         vec = geo2.Vec2Add(vec, (X_OFFSET, Y_OFFSET))
    237         return (int(vec[0]), int(vec[1]))
    238 
    239     def GetLeftFloat(self):
    240         return self._leftFloat
    241 
    242     def SetLeftFloat(self, value):
    243         self._leftFloat = value
    244         self.left = value
    245 
    246     leftFloat = property(GetLeftFloat, SetLeftFloat)
    247 
    248     def GetTopFloat(self):
    249         return self._topFloat
    250 
    251     def SetTopFloat(self, value):
    252         self._topFloat = value
    253         self.top = value
    254 
    255     topFloat = property(GetTopFloat, SetTopFloat)
    256 
    257     def OnOtherFactionClicked(self, node):
    258         sm.GetService('shipTreeUI').OpenAndShowShipGroup(node.factionID, node.shipGroupID)
    259 
    260     def UpdateTreeSkills(self):
    261         self.rootNode.FlushCache()
    262         self.ConstructLines(animate=False)
    263 
    264 
    265 class RootNode(ButtonIcon):
    266     isDragObject = True
    267 
    268     def GetDragData(self):
    269         import eveui
    270         return [eveui.dragdata.ItemType(type_id=typeCapsule)]
    271 
    272     def OnEndDrag(self, *args):
    273         ButtonIcon.OnEndDrag(self, *args)
    274         self.OnMouseExit()
    275 
    276 
    277 class VectorLineTraceShipTree(VectorLineTrace):
    278     default_spriteEffect = trinity.TR2_SFX_COPY
    279     default_lineWidth = 10.0
    280     default_textureWidth = 10.0
    281     default_opacity = 0.0
    282     default_idx = -1
    283     default_state = uiconst.UI_DISABLED
    284 
    285 
    286 class TopFrame(Container):
    287     default_name = 'topFrame'
    288     default_height = 26
    289 
    290     def ApplyAttributes(self, attributes):
    291         Container.ApplyAttributes(self, attributes)
    292         Sprite(parent=self, align=uiconst.TOLEFT, width=126, texturePath='res:/UI/Texture/classes/shipTree/frame/topLeft.png')
    293         cont = ContainerAutoSize(parent=self, align=uiconst.TOLEFT, alignMode=uiconst.TOPLEFT, bgTexturePath='res:/UI/Texture/classes/shipTree/frame/topMiddle.png')
    294         Label(parent=cont, text=GetByLabel('UI/ShipTree/InterbusShipIdentificationSystem'), color=COLOR_BG, top=3, fontsize=12, uppercase=True, bold=True, padRight=4)
    295         StretchSpriteHorizontal(parent=Container(parent=self), align=uiconst.TOTOP, texturePath='res:/UI/Texture/classes/ShipTree/frame/topRight.png', leftEdgeSize=40, rightEdgeSize=5, height=26)
    296 
    297 
    298 class BottomFrame(Container):
    299     default_name = 'bottomFrame'
    300     default_height = 59
    301 
    302     def ApplyAttributes(self, attributes):
    303         Container.ApplyAttributes(self, attributes)
    304         Sprite(parent=self, align=uiconst.TOLEFT, width=259, texturePath='res:/UI/Texture/classes/shipTree/frame/bottomLeft.png')
    305         cont = ContainerAutoSize(parent=self, align=uiconst.TOLEFT, padLeft=4)
    306         Label(parent=cont, align=uiconst.TOPLEFT, text=GetByLabel('UI/ShipTree/Showing'), uppercase=True, top=38, fontsize=9, color=COLOR_FONT)
    307         Label(parent=self, text='V1.%s.%s' % (len(evetypes.GetTypeIDsByCategory(const.categoryShip)), machoVersion), uppercase=True, top=43, left=82, fontsize=10, color=COLOR_FONT)
    308         Label(parent=cont, align=uiconst.TOPLEFT, text=GetByLabel('UI/ShipTree/MilitaryAndIndustrialVessels'), uppercase=True, top=49, fontsize=9, color=COLOR_FONT)
    309         self.AddSeperator(uiconst.TOLEFT)
    310         self.AddSeperator(uiconst.TORIGHT)
    311         Label(parent=ContainerAutoSize(align=uiconst.TORIGHT, parent=self, padLeft=4), align=uiconst.TOPLEFT, text=GetByLabel('UI/ShipTree/CourtesyLabel'), uppercase=True, top=49, fontsize=9, color=COLOR_FONT)
    312         self.AddSeperator(uiconst.TORIGHT)
    313         StretchSpriteHorizontal(parent=Container(parent=self, padding=(4, 0, 4, 0)), align=uiconst.TOBOTTOM, texturePath='res:/UI/Texture/classes/ShipTree/frame/bottomLine.png', leftEdgeSize=20, rightEdgeSize=20, height=2)
    314 
    315     def AddSeperator(self, align):
    316         Sprite(parent=Container(align=align, parent=self, width=40, padLeft=4), texturePath='res:/UI/Texture/classes/shipTree/frame/bottomSeperator.png', align=uiconst.TOBOTTOM, height=8)