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

careerNode.py (17868B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\careerPortal\circleView\careerNode.py
      2 import math
      3 import carbonui.const as uiconst
      4 import trinity
      5 from carbon.client.script.environment.AudioUtil import PlaySound
      6 from carbon.common.script.sys.serviceConst import ROLE_GML
      7 from carbonui.control.button import Button
      8 from carbonui import ButtonFrameType, ButtonVariant, Density
      9 from carbonui.primitives.container import Container
     10 from carbonui.primitives.containerAutoSize import ContainerAutoSize
     11 from carbonui.primitives.sprite import Sprite
     12 from carbonui.primitives.transform import Transform
     13 from carbonui.uianimations import animations
     14 from carbonui.util.color import Color
     15 from careergoals.client.career_goal_svc import get_career_goals_svc
     16 from characterdata import careerpath, careerpathconst
     17 from eve.client.script.ui import eveColor
     18 from eve.client.script.ui.control.donutSegment import DonutSegment
     19 from eve.client.script.ui.control.eveLabel import EveCaptionLarge
     20 from eve.client.script.ui.control.gaugeCircular import GaugeCircular
     21 from eve.client.script.ui.control.infoIcon import InfoGlyphIcon
     22 from eve.client.script.ui.shared.careerPortal import cpSignals, careerConst
     23 from eve.client.script.ui.shared.careerPortal.careerConst import LEVEL_ANIMATION_DURATION
     24 from eve.client.script.ui.shared.careerPortal.careerControllerUI import get_career_portal_controller_svc
     25 from eve.client.script.ui.shared.careerPortal.careerPointsLabel import CareerPointsLabel
     26 from eve.client.script.ui.shared.careerPortal.circleView.circleNode import CircleNode
     27 from eve.client.script.ui.shared.careerPortal.link.dragData import NodeDragData
     28 from eve.client.script.ui.util.uix import GetTextWidth, GetTextHeight, QtyPopup
     29 from localization import GetByMessageID, GetByLabel
     30 LABEL_CONTAINER_HEIGHT = 30
     31 TEXT_CONT_TOP = 4
     32 GLYPH_ICON_SIZE = 16
     33 ICON_SIZE = 128
     34 BG_PADDING = 180
     35 NODE_MAX_SIZE = 180
     36 ANIM_DURATION = 0.4
     37 
     38 class CareerNode(CircleNode):
     39     default_name = 'CareerNode'
     40     default_state = uiconst.UI_NORMAL
     41     default_align = uiconst.CENTER
     42     isInCenter = False
     43 
     44     def GetMenu(self):
     45         if session and session.role & ROLE_GML:
     46             menu = [['QA: Complete', self._Debug_CompleteGoal], ['QA: Progress', self._Debug_ProgressGoal]]
     47             return menu
     48 
     49     def _Debug_CompleteGoal(self):
     50         get_career_goals_svc().get_goal_data_controller().admin_complete_goal(self.nodeObject.goal.goal_id)
     51 
     52     def _Debug_ProgressGoal(self):
     53         ret = QtyPopup(minvalue=0, setvalue=1, maxvalue=self.nodeObject.goal.definition.target_value)
     54         if ret and 'qty' in ret:
     55             get_career_goals_svc().get_goal_data_controller().admin_progress_goal(self.nodeObject.goal.goal_id, ret['qty'])
     56 
     57     def ApplyAttributes(self, attributes):
     58         self.nodeObject = attributes.nodeObject
     59         self.prevPos = None
     60         super(CareerNode, self).ApplyAttributes(attributes)
     61         progress, target = self.nodeObject.GetCareerPathProgress()
     62         self.iconGauge.SetGaugeValue(progress, target)
     63         self.iconGauge.UpdateGaugeColor(progress >= target)
     64         self.OnCareerWindowStateChanged(attributes.initialState)
     65 
     66     def GetSignals(self):
     67         signals = super(CareerNode, self).GetSignals()
     68         signals.extend([(cpSignals.on_career_node_hover_on, self.OnCareerNodeHoveredOn), (cpSignals.on_career_node_hover_off, self.OnCareerNodeHoveredOff)])
     69         return signals
     70 
     71     def PrepareUI(self):
     72         self.iconGauge = IconWithGauge(parent=self, align=uiconst.CENTERTOP, nodeObject=self.nodeObject)
     73         self.textCont = CardTextCont(name='textCont', parent=self, nodeObject=self.nodeObject)
     74 
     75     def OnGoalUpdated(self, goalID, value):
     76         if goalID != self.nodeObject.goal.goal_id:
     77             return
     78         if careerConst.CAREER_WINDOW_STATE_SETTING.get() != careerConst.CareerWindowState.CAREERS_VIEW and careerConst.SELECTED_CAREER_PATH_SETTING.get() != self.nodeObject.careerPathID:
     79             self.FadeIn(callback=lambda : self.FadeOut(timeOffset=1.5))
     80         progress, target = self.nodeObject.GetCareerPathProgress()
     81         self.iconGauge.SetGaugeValue(progress, target)
     82 
     83     def ResizeComponents(self, nodeSize, left, top, angle, animate = False):
     84         self.iconGauge.ResizeComponents(nodeSize, animate)
     85         self.textCont.top = self.iconGauge.height + TEXT_CONT_TOP
     86         newWidth = max(self.textCont.GetWidth(), self.iconGauge.gauge.width)
     87         textContHeight = self.textCont.GetHeight()
     88         newHeight = textContHeight + self.iconGauge.gauge.height + TEXT_CONT_TOP
     89         newAnchorY = newAnchorX = nodeSize / 2
     90         top += textContHeight / 2
     91         if self.IsSelected():
     92             self._GoToCenter()
     93         if animate:
     94             animations.MorphScalar(self, 'width', self.width, newWidth, duration=LEVEL_ANIMATION_DURATION)
     95             animations.MorphScalar(self, 'height', self.width, newHeight, duration=LEVEL_ANIMATION_DURATION)
     96             animations.MorphScalar(self, 'left', startVal=self.left, endVal=left, duration=careerConst.LEVEL_ANIMATION_DURATION)
     97             animations.MorphScalar(self, 'top', startVal=self.top, endVal=top, duration=careerConst.LEVEL_ANIMATION_DURATION)
     98             animations.MorphScalar(self, 'anchorPointX', self.anchorPointX, newAnchorX, duration=LEVEL_ANIMATION_DURATION)
     99             animations.MorphScalar(self, 'anchorPointY', self.anchorPointY, newAnchorY, duration=LEVEL_ANIMATION_DURATION)
    100         else:
    101             self.top = top
    102             self.left = left
    103             self.width = newWidth
    104             self.height = newHeight
    105             self.prevPos = (left,
    106              top,
    107              newWidth,
    108              newHeight)
    109             self.anchorPointY = newAnchorY
    110             self.anchorPointX = newAnchorY
    111 
    112     def IsSelected(self):
    113         careerID = careerConst.SELECTED_CAREER_PATH_SETTING.get()
    114         return careerID == self.nodeObject.careerPathID
    115 
    116     def OnCareerWindowStateChanged(self, state):
    117         careerID = careerConst.SELECTED_CAREER_PATH_SETTING.get()
    118         if state == careerConst.CareerWindowState.CAREERS_VIEW:
    119             self.Show()
    120             animations.FadeIn(self, duration=ANIM_DURATION)
    121             animations.Tr2DRotateTo(self, startAngle=self.rotation, endAngle=0)
    122             self.textCont.Show()
    123             animations.FadeIn(self.textCont, duration=ANIM_DURATION, callback=self.textCont.careerPointsLabel.Reset)
    124             if careerID == self.nodeObject.careerPathID:
    125                 self._GoToCircle()
    126             else:
    127                 self.Enable()
    128             animations.Tr2DScaleTo(self.iconGauge, startScale=self.iconGauge.scale, endScale=(1.0, 1.0))
    129         if state in (careerConst.CareerWindowState.ACTIVITIES_VIEW, careerConst.CareerWindowState.GOALS_VIEW):
    130             animations.Tr2DRotateTo(self, startAngle=self.rotation, endAngle=math.radians(-careerConst.CIRCLE_ROTATION_BY_CAREER[careerID]))
    131             animations.FadeOut(self.textCont, duration=0.2)
    132             if self.nodeObject.careerPathID == careerID:
    133                 self._GoToCenter()
    134             else:
    135                 self.Disable()
    136                 animations.FadeOut(self, duration=ANIM_DURATION, callback=self.Hide)
    137                 animations.Tr2DScaleTo(self.iconGauge, self.iconGauge.scale, (0.8, 0.8))
    138 
    139     def _GoToCircle(self):
    140         animations.MoveTo(self, self.pos, self.prevPos)
    141         textContHeight = self.textCont.GetHeight()
    142         newHeight = textContHeight + self.iconGauge.gauge.height + TEXT_CONT_TOP
    143         animations.MorphScalar(self, 'height', self.height, newHeight, duration=0.2)
    144         careerConst.SELECTED_CAREER_PATH_SETTING.set(careerpathconst.career_path_none)
    145         self.isInCenter = False
    146 
    147     def _GoToCenter(self):
    148         animations.MoveTo(self, startPos=self.pos, endPos=(0, 0))
    149         newHeight = self.iconGauge.width or 172
    150         animations.MorphScalar(self, 'height', self.height, newHeight, duration=0.2)
    151         animations.Tr2DScaleTo(self.iconGauge, startScale=self.iconGauge.scale, endScale=(1.5, 1.5))
    152         self.isInCenter = True
    153 
    154     def OnClick(self, *args):
    155         PlaySound('career_portal_select_profession_play')
    156         if careerConst.SELECTED_CAREER_PATH_SETTING.get() == self.nodeObject.careerPathID:
    157             currentState = careerConst.CAREER_WINDOW_STATE_SETTING.get()
    158             if currentState == careerConst.CareerWindowState.GOALS_VIEW:
    159                 newState = careerConst.CareerWindowState.ACTIVITIES_VIEW
    160             else:
    161                 newState = careerConst.CareerWindowState.CAREERS_VIEW
    162             careerConst.CAREER_WINDOW_STATE_SETTING.set(newState)
    163         else:
    164             get_career_portal_controller_svc().select_career(self.nodeObject.careerPathID, self.nodeObject.goal.goal_id)
    165 
    166     def OnMouseEnter(self, *args):
    167         self.iconGauge.OnMouseEnter(*args)
    168         if self.IsAnimating():
    169             return
    170         PlaySound('career_portal_hover_profession_play')
    171         cpSignals.on_career_node_hover_on(self.nodeObject.careerPathID)
    172 
    173     def OnMouseExit(self, *args):
    174         self.iconGauge.OnMouseExit(*args)
    175         cpSignals.on_career_node_hover_off(self.nodeObject.careerPathID)
    176 
    177     def IsAnimating(self):
    178         return self.HasAnimation('left') or self.HasAnimation('top')
    179 
    180     def OnCareerNodeHoveredOn(self, careerPathID):
    181         currentState = careerConst.CAREER_WINDOW_STATE_SETTING.get()
    182         if currentState != careerConst.CareerWindowState.ACTIVITIES_VIEW:
    183             return
    184         if careerPathID != self.nodeObject.careerPathID:
    185             self.Show()
    186             animations.FadeIn(self, duration=0.2)
    187 
    188     def OnCareerNodeHoveredOff(self, careerPathID):
    189         currentState = careerConst.CAREER_WINDOW_STATE_SETTING.get()
    190         if currentState != careerConst.CareerWindowState.ACTIVITIES_VIEW:
    191             return
    192         if careerPathID != self.nodeObject.careerPathID:
    193             animations.FadeOut(self, duration=0.2, callback=self.Hide)
    194 
    195     def FadeIn(self, callback = None):
    196         animations.FadeIn(self, duration=ANIM_DURATION, callback=callback)
    197 
    198     def FadeOut(self, timeOffset = 0.0):
    199         animations.FadeOut(self, duration=ANIM_DURATION, timeOffset=timeOffset)
    200 
    201     def GetDragData(self):
    202         if self.nodeObject:
    203             return NodeDragData(self.nodeObject.careerPathID, None, None, self.nodeObject.careerPathName)
    204 
    205 
    206 class CardTextCont(ContainerAutoSize):
    207     default_alignMode = uiconst.TOTOP
    208     default_align = uiconst.CENTERTOP
    209 
    210     def ApplyAttributes(self, attributes):
    211         super(CardTextCont, self).ApplyAttributes(attributes)
    212         self.nodeObject = attributes.nodeObject
    213         self.careerInfoContainer = ContainerAutoSize(name='careerInfoContainer', parent=self, align=uiconst.TOTOP)
    214         nameLabelAndInfoContainer = Container(name='nameLabelAndInfoContainer', parent=self.careerInfoContainer, align=uiconst.TOTOP, height=LABEL_CONTAINER_HEIGHT)
    215         self.careerPathLabel = EveCaptionLarge(parent=nameLabelAndInfoContainer, name='careerPathLabel', align=uiconst.CENTER, state=uiconst.UI_DISABLED, bold=True, singleline=True, text=self.nodeObject.careerPathName)
    216         self.infoGlyphIcon = InfoGlyphIcon(parent=nameLabelAndInfoContainer, align=uiconst.CENTER)
    217         pointsContainer = Container(name='pointsContainer', parent=self.careerInfoContainer, align=uiconst.TOTOP, height=20)
    218         self.careerPointsLabel = CareerPointsLabel(parent=pointsContainer, careerNode=self.nodeObject)
    219         self.videoButton = Button(parent=Container(name='playButtonContainer', parent=self, align=uiconst.TOTOP, height=24, top=4), name='videoButton', align=uiconst.CENTER, label=GetByLabel('UI/CareerPortal/PlayVideo'), texturePath='res:/UI/Texture/classes/careerPortal/playVideo.png', func=self.PlayVideo, iconSize=GLYPH_ICON_SIZE, density=Density.COMPACT, variant=ButtonVariant.GHOST, frame_type=ButtonFrameType.CUT_BOTTOM_LEFT_RIGHT)
    220         self.UpdateLabels()
    221         self.width = self.GetWidth()
    222 
    223     def UpdateLabels(self):
    224         self.infoGlyphIcon.left = self.careerPathLabel.width / 2 + GLYPH_ICON_SIZE
    225         self.infoGlyphIcon.hint = GetByLabel(careerConst.CAREER_DESCRIPTIONS.get(self.nodeObject.careerPathID, ''))
    226 
    227     def PlayVideo(self, *args):
    228         videoPath = careerConst.CAREER_VIDEOS.get(self.nodeObject.careerPathID, None)
    229         get_career_portal_controller_svc().play_video(videoPath)
    230 
    231     def GetWidth(self):
    232         careerLabelWidth = GetTextWidth(self.nodeObject.careerPathName, fontsize=self.careerPathLabel.fontsize, bold=True)
    233         return careerLabelWidth + self.infoGlyphIcon.width + GLYPH_ICON_SIZE + 4
    234 
    235     def GetHeight(self):
    236         careerLabelHeight = GetTextHeight(self.nodeObject.careerPathName, fontsize=self.careerPathLabel.fontsize, bold=True)
    237         pointsLabelHeight = GetTextHeight(self.nodeObject.GetCareerPathPointsText())
    238         totalHeight = careerLabelHeight + pointsLabelHeight + self.videoButton.parent.height + self.videoButton.parent.top * 2
    239         return totalHeight
    240 
    241 
    242 class IconWithGauge(Transform):
    243     default_align = uiconst.CENTERTOP
    244     default_state = uiconst.UI_DISABLED
    245     default_bgGaugeOpacity = 0.15
    246     default_rotationCenter = (0.5, 0.5)
    247     default_scalingCenter = (0.5, 0.5)
    248 
    249     def ApplyAttributes(self, attributes):
    250         super(IconWithGauge, self).ApplyAttributes(attributes)
    251         self.nodeObject = attributes.nodeObject
    252         texturePath = self.nodeObject.iconTexturePath
    253         self.isSelected = False
    254         self.gauge = GaugeCircular(parent=self, name='gauge', align=uiconst.CENTER, lineWidth=4, clockwise=True, showMarker=False, glow=True, glowBrightness=0.5, bgPortion=0.997, idx=0, colorBg=Color(eveColor.CRYO_BLUE).SetBrightness(0.2).GetRGBA(), useMiddleGauge=True)
    255         self.icon = Sprite(parent=self, name='icon', align=uiconst.CENTER, texturePath=texturePath, state=uiconst.UI_DISABLED, width=ICON_SIZE, height=ICON_SIZE, outputMode=uiconst.OUTPUT_COLOR_AND_GLOW, glowBrightness=0.3, idx=1)
    256 
    257     def _SetupBackground(self):
    258         self.bgCont = Container(name='backgroundContainer', parent=self, align=uiconst.CENTER, bgTexturePath='res:/UI/Texture/classes/careerPortal/careerNodeHoverOff.png', bgOutputMode=uiconst.OUTPUT_COLOR_AND_GLOW, bgSpriteEffect=trinity.TR2_SFX_SOFTLIGHT, opacity=0.5)
    259         self.bgCont._bgSprite.glowBrightness = 0.3
    260 
    261     def ConstructLine(self, radius, lineWidth):
    262         return DonutSegment(parent=self, align=uiconst.CENTER, lineWidth=lineWidth, radius=radius, isClockwise=True)
    263 
    264     def ResizeComponents(self, nodeSize, animate):
    265         if animate:
    266             self._AnimateToNewSize(nodeSize)
    267         else:
    268             iconSize = nodeSize / 1.2
    269             bgSizeWithPadding = nodeSize * 2.2
    270             self.icon.SetSize(iconSize, iconSize)
    271             self.bgCont.SetSize(bgSizeWithPadding, bgSizeWithPadding)
    272             self.height = self.width = nodeSize
    273         radius = nodeSize / 2
    274         self.gauge.SetRadius(radius)
    275 
    276     def _AnimateToNewSize(self, nodeSize):
    277         animations.MorphScalar(self, 'height', self.height, nodeSize, duration=LEVEL_ANIMATION_DURATION)
    278         animations.MorphScalar(self, 'width', self.width, nodeSize, duration=LEVEL_ANIMATION_DURATION)
    279         iconSize = nodeSize / 1.2
    280         bgSizeWithPadding = nodeSize * 2.2
    281         animations.MorphScalar(self.icon, 'height', self.icon.height, iconSize, duration=LEVEL_ANIMATION_DURATION)
    282         animations.MorphScalar(self.icon, 'width', self.icon.width, iconSize, duration=LEVEL_ANIMATION_DURATION)
    283         animations.MorphScalar(self.bgCont, 'height', self.bgCont.height, bgSizeWithPadding, duration=LEVEL_ANIMATION_DURATION)
    284         animations.MorphScalar(self.bgCont, 'width', self.bgCont, bgSizeWithPadding, duration=LEVEL_ANIMATION_DURATION)
    285 
    286     def SetGaugeValue(self, value, maxValue):
    287         isGaugeFull = value >= maxValue
    288         self.gauge.SetValueWithMiddleGauge(float(value) / float(maxValue), lingerDurationSeconds=1.0, callback=lambda : self.UpdateGaugeColor(isGaugeFull))
    289 
    290     def UpdateGaugeColor(self, full):
    291         if full:
    292             animations.MorphScalar(self.gauge.gauge, 'glowBrightness', startVal=self.gauge.glowBrightness, endVal=1.0, curveType=uiconst.ANIM_OVERSHOT5)
    293             self.gauge.SetColor(eveColor.LEAFY_GREEN, eveColor.LEAFY_GREEN)
    294         else:
    295             self.gauge.SetColor(eveColor.CRYO_BLUE, eveColor.CRYO_BLUE)
    296 
    297     def OnMouseEnter(self, *args):
    298         animations.FadeTo(self.icon, self.icon.opacity, 1.4, duration=careerConst.HOVER_ANIMATION_DURATION)
    299         animations.FadeIn(self.bgCont, endVal=1.0, duration=careerConst.HOVER_ANIMATION_DURATION)
    300 
    301     def OnMouseExit(self, *args):
    302         animations.FadeTo(self.icon, self.icon.opacity, 1.0, duration=careerConst.HOVER_ANIMATION_DURATION)
    303         animations.FadeTo(self.bgCont, startVal=self.bgCont.opacity, endVal=0.5, duration=careerConst.HOVER_ANIMATION_DURATION)
    304 
    305 
    306 class CareerNodeObject(object):
    307 
    308     def __init__(self, careerPathID):
    309         self.careerPathID = careerPathID
    310         self._careerPathName = None
    311         self.goal = get_career_goals_svc().get_goal_data_controller().get_career_path_goal(self.careerPathID)
    312 
    313     @property
    314     def iconTexturePath(self):
    315         return careerConst.ICON_BY_CAREER_ID.get(self.careerPathID, '')
    316 
    317     @property
    318     def careerPathName(self):
    319         if self._careerPathName is None:
    320             careerInfo = careerpath.get_career_path(self.careerPathID)
    321             self._careerPathName = GetByMessageID(careerInfo.nameID)
    322         return self._careerPathName
    323 
    324     def GetCareerPathPointsText(self):
    325         currentPoints = self.goal.progress
    326         maxPoints = self.goal.definition.target_value
    327         return GetByLabel('UI/CareerPortal/CareerPointsNumFull', currentPoints=currentPoints, totalPoints=maxPoints)
    328 
    329     def GetCareerPathProgress(self):
    330         return (self.goal.progress, self.goal.definition.target_value)