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

radialMenuActions.py (14409B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\radialMenu\radialMenuActions.py
      2 import math
      3 import types
      4 from carbonui.primitives.sprite import Sprite
      5 from eve.client.script.ui.control.glowSprite import GlowSprite
      6 from eve.client.script.ui.control.themeColored import SpriteThemeColored
      7 import carbonui.const as uiconst
      8 import localization
      9 from carbonui.primitives.transform import Transform
     10 import telemetry
     11 from carbonui.uicore import uicore
     12 from eve.client.script.ui.shared.radialMenu import BROADCAST_RADIAL_MENU
     13 from eve.client.script.ui.shared.radialMenu.broadcastRadialMenuFunctions import GetBroadcastMenuColor
     14 
     15 class RadialMenuActionBase(Transform):
     16     default_left = 0
     17     default_top = 0
     18     default_align = uiconst.CENTERTOP
     19     default_state = uiconst.UI_NORMAL
     20     moveOverSliceBasePath = 'res:/UI/Texture/classes/RadialMenu/mouseOver_%s.png'
     21     selelectedBasePath = 'res:/UI/Texture/classes/RadialMenu/selected_%s.png'
     22     emptySliceBasePath = 'res:/UI/Texture/classes/RadialMenu/emptySlice_%s.png'
     23     sliceBasePath = 'res:/UI/Texture/classes/RadialMenu/slice_%s.png'
     24     default_width = 100
     25     default_height = 70
     26     default_fullWidth = default_width
     27     default_fullHeight = default_height
     28 
     29     def ApplyAttributes(self, attributes):
     30         Transform.ApplyAttributes(self, attributes)
     31         self.degree = attributes.get('degree', 0)
     32         self.func = None
     33         self.funcArgs = None
     34         self.itemID = attributes.itemID
     35         self.isDisabled = False
     36         self.degreeWidth = attributes.degreeWidth
     37         self.labelPath = ''
     38         self.labelText = ''
     39         self.isEmpty = attributes.get('isEmpty', False)
     40         self.commandName = None
     41         self.isHilighted = False
     42         self.fullWidth = attributes.sizeInfo.buttonWidth
     43         self.fullHeight = attributes.sizeInfo.buttonHeight
     44         iconPar = Transform(parent=self, name='iconPar', pos=(0, 3, 32, 32), state=uiconst.UI_DISABLED, align=uiconst.CENTER)
     45         iconPar.rotation = math.radians(self.degree)
     46         self.icon = GlowSprite(parent=iconPar, name='icon', pos=(0, 0, 32, 32), state=uiconst.UI_DISABLED, align=uiconst.CENTER)
     47         if attributes.menuType == BROADCAST_RADIAL_MENU:
     48             color = GetBroadcastMenuColor()
     49         else:
     50             color = SpriteThemeColored.default_fixedColor
     51         selectionSlice = SpriteThemeColored(parent=self, name='selectionSlice', state=uiconst.UI_DISABLED, texturePath=self.selelectedBasePath % self.degreeWidth, align=uiconst.TOALL, opacity=0.9, color=color)
     52         selectionSlice.display = False
     53         self.selectionSlice = selectionSlice
     54         if self.isEmpty:
     55             sliceTexturePath = self.emptySliceBasePath % self.degreeWidth
     56         else:
     57             sliceTexturePath = self.sliceBasePath % self.degreeWidth
     58         self.hilite = SpriteThemeColored(parent=self, name='hilite', state=uiconst.UI_DISABLED, texturePath=self.selelectedBasePath % self.degreeWidth, align=uiconst.TOALL, colorType=uiconst.COLORTYPE_UIHILIGHTGLOW, opacity=0.0)
     59         self.availableSlice = SpriteThemeColored(parent=self, name='availableSlice', state=uiconst.UI_DISABLED, texturePath=sliceTexturePath, align=uiconst.TOALL, opacity=attributes.get('buttonBackgroundOpacity', 0.8), color=color)
     60         self.unavailableSlice = SpriteThemeColored(parent=self, name='unavailableSlice', state=uiconst.UI_DISABLED, texturePath=sliceTexturePath, align=uiconst.TOALL, colorType=uiconst.COLORTYPE_UIBASE, opacity=0.85)
     61         self.unavailableSlice.display = False
     62         self.sliceInUse = self.availableSlice
     63 
     64     def SetButtonInfo(self, labelPath, labelArgs, buttonInfo = None, isEnabled = True, iconTexturePath = None):
     65         self.labelPath = labelPath
     66         if isEnabled:
     67             self.labelText = localization.GetByLabel(labelPath, **labelArgs)
     68         else:
     69             self.labelText = ''
     70         self.name = 'actionButton_%s' % labelPath.split('/')[-1]
     71         if isEnabled:
     72             self.SetEnabled()
     73         else:
     74             self.SetDisabled()
     75         if iconTexturePath is not None:
     76             self.SetIcon(iconTexturePath)
     77         if buttonInfo is None:
     78             return
     79         buttonFunc = buttonInfo.func
     80         buttonFuncArgs = buttonInfo.funcArgs
     81         if not isinstance(buttonFunc, (types.MethodType, types.LambdaType)):
     82             return
     83         self.func = buttonFunc
     84         self.funcArgs = buttonFuncArgs
     85         self.commandName = getattr(buttonInfo, 'commandName', None)
     86 
     87     @telemetry.ZONE_METHOD
     88     def ShowButtonHilite(self):
     89         if self.isHilighted:
     90             return
     91         uicore.animations.FadeTo(self.hilite, self.hilite.opacity, 0.15, duration=uiconst.TIME_ENTRY)
     92         self.isHilighted = True
     93         sm.GetService('audio').SendUIEvent('ui_radial_mouseover_play')
     94         self.icon.OnMouseEnter()
     95 
     96     @telemetry.ZONE_METHOD
     97     def HideButtonHilite(self):
     98         if not self.isHilighted:
     99             return
    100         uicore.animations.FadeTo(self.hilite, self.hilite.opacity, 0.0, duration=uiconst.TIME_EXIT)
    101         self.isHilighted = False
    102         self.sliceInUse.Show()
    103         if self.isDisabled:
    104             self.icon.opacity = 0.4
    105         else:
    106             self.icon.opacity = 1.0
    107         self.icon.OnMouseExit()
    108 
    109     def ShowSelectionSlice(self):
    110         self.availableSlice.display = False
    111         self.unavailableSlice.display = False
    112         self.selectionSlice.display = True
    113 
    114     def SetIcon(self, texturePath):
    115         self.icon.SetTexturePath(texturePath)
    116 
    117     def SetDisabled(self):
    118         if self.sliceInUse != self.unavailableSlice:
    119             self.sliceInUse = self.unavailableSlice
    120             self.availableSlice.display = False
    121             self.unavailableSlice.display = True
    122         self.isDisabled = True
    123         self.icon.opacity = 0.4
    124 
    125     def SetEnabled(self):
    126         if self.sliceInUse != self.availableSlice:
    127             self.sliceInUse = self.availableSlice
    128             self.unavailableSlice.display = False
    129             self.availableSlice.display = True
    130         self.isDisabled = False
    131         self.icon.opacity = 1.0
    132 
    133     def AnimateSize(self, sizeRatio = 0.5, duration = 0.5, grow = True):
    134         if grow:
    135             startHeight = sizeRatio * self.fullHeight
    136             startWidth = sizeRatio * self.fullWidth
    137             endHeight = self.fullHeight
    138             endWidth = self.fullWidth
    139         else:
    140             startHeight = self.height
    141             startWidth = self.width
    142             endHeight = sizeRatio * self.fullHeight
    143             endWidth = sizeRatio * self.fullWidth
    144         uicore.animations.MorphScalar(self, 'height', startVal=startHeight, endVal=endHeight, duration=duration)
    145         uicore.animations.MorphScalar(self, 'width', startVal=startWidth, endVal=endWidth, duration=duration)
    146 
    147     def SelectButtonSlice(self, duration = 0.5):
    148         self.ShowSelectionSlice()
    149         curvePoints = ([0.0, 0], [0.5, -10], [1, -10])
    150         uicore.animations.MorphScalar(self, 'top', duration=duration, curveType=curvePoints, sleep=False)
    151         curvePoints = ([0.0, self.selectionSlice.opacity],
    152          [0.5, self.selectionSlice.opacity],
    153          [0.6, 1.5],
    154          [0.7, 0.5],
    155          [0.8, 1.5],
    156          [1, 0])
    157         uicore.animations.MorphScalar(self, 'opacity', duration=duration, curveType=curvePoints, sleep=True)
    158 
    159 
    160 class RadialMenuAction(RadialMenuActionBase):
    161 
    162     def OnButtonClick(self):
    163         if self.func:
    164             if self.funcArgs and isinstance(self.funcArgs[0], tuple) and isinstance(self.funcArgs[0][0], (types.MethodType, types.LambdaType)):
    165                 self.func(*self.funcArgs[0])
    166             else:
    167                 self.func(*(self.funcArgs or []))
    168             return True
    169         return False
    170 
    171 
    172 class RadialMenuRangeAction(RadialMenuActionBase):
    173 
    174     def ApplyAttributes(self, attributes):
    175         RadialMenuActionBase.ApplyAttributes(self, attributes)
    176         self.rangeList = attributes.rangeList
    177         self.defaultRange = attributes.defaultRange
    178         self.percOfAllRange = None
    179         self.currentRange = self.defaultRange
    180         self.minRangeDistance = attributes.sizeInfo.actionDistance
    181         self.actionButtonTopPadding = attributes.get('actionButtonTopPadding', 0)
    182         self.usePreciseRanges = attributes.get('usePreciseRanges', True)
    183         self.maxRangeDistance = 300
    184         self.lastLength = None
    185         self.rangeArrow = Sprite(parent=self, name='rangeArrow', pos=(0,
    186          self.actionButtonTopPadding + 1,
    187          18,
    188          12), state=uiconst.UI_DISABLED, align=uiconst.CENTERTOP, texturePath='res:/UI/Texture/classes/RadialMenu/rangeArrow.png', idx=0)
    189 
    190     def SetEnabled(self):
    191         RadialMenuActionBase.SetEnabled(self)
    192         self.rangeArrow.opacity = 1.0
    193 
    194     def SetDisabled(self):
    195         RadialMenuActionBase.SetDisabled(self)
    196         self.rangeArrow.opacity = 0.4
    197 
    198     def MoveMouse(self, length, currentDegree):
    199         if self.isDisabled:
    200             self.currentRange = None
    201             self.percOfAllRange = None
    202             return (self.currentRange, self.percOfAllRange)
    203         if length < self.minRangeDistance - self.actionButtonTopPadding:
    204             self.currentRange = self.defaultRange
    205             self.percOfAllRange = None
    206             return (self.currentRange, self.percOfAllRange)
    207         numRangeOptions = len(self.rangeList)
    208         lengthInEachStep = float((self.maxRangeDistance - self.minRangeDistance) / numRangeOptions)
    209         lengthInRangeMeasurer = length - self.minRangeDistance
    210         lengthInRangeMeasurer = self.FindLengthToUse(lengthInRangeMeasurer, currentDegree)
    211         for i, eachRange in enumerate(self.rangeList):
    212             lengthForThisStep = i * lengthInEachStep
    213             if lengthInRangeMeasurer > lengthForThisStep:
    214                 continue
    215             if i == 0:
    216                 self.currentRange = eachRange
    217                 self.percOfAllRange = 0
    218                 return (self.currentRange, self.percOfAllRange)
    219             lengthForPreviousStep = lengthInEachStep * (i - 1)
    220             previousStepDistance = self.rangeList[i - 1]
    221             lengthInThisStep = lengthInRangeMeasurer - lengthForPreviousStep
    222             percOfStep = float(lengthInThisStep) / lengthInEachStep
    223             if self.usePreciseRanges:
    224                 currentRange = percOfStep * (eachRange - previousStepDistance) + previousStepDistance
    225             else:
    226                 currentRange = previousStepDistance
    227             percOfEachStep = 1.0 / (numRangeOptions - 1)
    228             percOfAllRange = (i - 1 + percOfStep) * percOfEachStep
    229             self.currentRange = currentRange
    230             self.percOfAllRange = percOfAllRange
    231             return (currentRange, self.percOfAllRange)
    232         else:
    233             self.currentRange = self.rangeList[-1]
    234             return (self.currentRange, 1)
    235 
    236     def FindLengthToUse(self, length, currentDegree):
    237         if self.lastLength is None:
    238             self.lastLength = length
    239         halfDegreeWidth = self.degreeWidth / 2.0
    240         if not self.degree - halfDegreeWidth < currentDegree < self.degree + halfDegreeWidth:
    241             dx, dy = uicore.uilib.dx, uicore.uilib.dy
    242             if 90 < self.degree < 270:
    243                 length = self.lastLength + dy
    244             else:
    245                 length = self.lastLength - dy
    246         length = max(0, length)
    247         self.lastLength = length
    248         return length
    249 
    250     def OnButtonClick(self):
    251         if self.func and self.currentRange is not None:
    252             self.func(self.funcArgs, self.currentRange, self.percOfAllRange)
    253 
    254 
    255 class RadialMenuActioSecondLevel(RadialMenuActionBase):
    256 
    257     def ApplyAttributes(self, attributes):
    258         RadialMenuActionBase.ApplyAttributes(self, attributes)
    259         self.icon.SetTexturePath(attributes.texturePath)
    260         self.hasExtraOptions = attributes.hasExtraOptions
    261         self.levelType = attributes.levelType
    262 
    263     def MoveMouse(self, length, currentDegree):
    264         return True
    265 
    266 
    267 class ActionParent(Transform):
    268     default_align = uiconst.CENTER
    269     default_name = 'radialmenuActionParent'
    270 
    271     def ApplyAttributes(self, attributes):
    272         Transform.ApplyAttributes(self, attributes)
    273         degree = attributes.degree
    274         radians = math.radians(degree)
    275         self.rotation = -radians
    276         self.actionDistance = attributes.sizeInfo.actionDistance
    277         self.degree = degree
    278 
    279     def SetButtonInfo(self, menuOptions, buttonInfo, isEnabled, iconTexturePath):
    280         activeOption = menuOptions.activeOption
    281         labelArgs = getattr(menuOptions, 'labelArgs', {})
    282         self.actionButton.SetButtonInfo(activeOption, labelArgs, buttonInfo, isEnabled=isEnabled, iconTexturePath=iconTexturePath)
    283 
    284     def SetDisabledIcon(self, texturePath):
    285         self.actionButton.SetIcon(texturePath=texturePath)
    286         self.actionButton.SetDisabled()
    287 
    288     def SetIconOffset(self, iconOffset):
    289         self.actionButton.icon.parent.top = iconOffset
    290 
    291 
    292 class ActionButtonParent(ActionParent):
    293 
    294     def ApplyAttributes(self, attributes):
    295         ActionParent.ApplyAttributes(self, attributes)
    296         actionButton = RadialMenuAction(parent=self, name='actionButton', sizeInfo=attributes.sizeInfo, degree=attributes.degree, isEmpty=attributes.isEmpty, buttonBackgroundOpacity=attributes.buttonBackgroundOpacity, menuType=attributes.menuType, **attributes.actionKeywords)
    297         self.actionButton = actionButton
    298 
    299 
    300 class RangeActionButtonParent(ActionParent):
    301 
    302     def ApplyAttributes(self, attributes):
    303         ActionParent.ApplyAttributes(self, attributes)
    304         actionButton = RadialMenuRangeAction(parent=self, name='rangeButton', sizeInfo=attributes.sizeInfo, degree=attributes.degree, actionButtonTopPadding=attributes.sizeInfo.buttonPaddingTop, usePreciseRanges=attributes.usePreciseRanges, buttonBackgroundOpacity=attributes.buttonBackgroundOpacity, **attributes.actionKeywords)
    305         self.actionButton = actionButton
    306 
    307 
    308 class SecondLevelButtonParent(ActionParent):
    309     default_name = 'secondLevelButtonParent'
    310 
    311     def ApplyAttributes(self, attributes):
    312         ActionParent.ApplyAttributes(self, attributes)
    313         self.levelType = attributes.actionKeywords['levelType']
    314         actionButton = RadialMenuActioSecondLevel(parent=self, name='secondLevelButton', sizeInfo=attributes.sizeInfo, degree=attributes.degree, buttonBackgroundOpacity=attributes.buttonBackgroundOpacity, **attributes.actionKeywords)
    315         self.actionButton = actionButton