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

eveSpinWheelPicker.py (10721B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\control\eveSpinWheelPicker.py
      2 import math
      3 import uthread
      4 import blue
      5 from carbon.common.script.util import timerstuff
      6 from carbonui import uiconst
      7 from carbonui.primitives.container import Container
      8 from carbonui.primitives.fill import Fill
      9 from carbonui.primitives.sprite import Sprite
     10 from carbonui.primitives.transform import Transform
     11 from carbonui.uicore import uicore
     12 
     13 class SpinWheelPicker(Container):
     14     default_align = uiconst.CENTER
     15     default_left = 0
     16     default_top = 0
     17     default_width = 256
     18     default_height = 256
     19     default_name = 'SpinWheel'
     20     default_state = uiconst.UI_NORMAL
     21     default_pickRadius = 66
     22     TEXTURESIZE = 162
     23     MARKERTFSIZE = 98
     24     SPINRATIO = 1.0
     25 
     26     def ApplyAttributes(self, attributes):
     27         Container.ApplyAttributes(self, attributes)
     28         self._spinning = False
     29         self._lastAngle = 0.0
     30         self._tickGap = 0.0
     31         self._options = None
     32         self._value = None
     33         self._lastRotationDelta = None
     34         self._didSpin = False
     35         self._wheelbuffer = 0
     36         self._wheeling = False
     37         for each in uicore.layer.main.children[:]:
     38             if each.name == self.default_name:
     39                 each.Close()
     40 
     41         if attributes.parent is None:
     42             uicore.layer.main.children.append(self)
     43         transform = Transform(parent=self, pos=(0,
     44          0,
     45          self.TEXTURESIZE,
     46          self.TEXTURESIZE), align=uiconst.CENTER, state=uiconst.UI_DISABLED, name='mainTransform')
     47         self.sr.mainTransform = transform
     48         sprite = Sprite(parent=transform, align=uiconst.TOALL, texturePath='res:/UI/Texture/spinWheelPicker_main.dds')
     49         self.sr.mainTransform = transform
     50         self.sr.marker = Fill(parent=self, align=uiconst.CENTER, pos=(0, -64, 2, 16), color=(1.0, 1.0, 1.0, 1.0), idx=0)
     51         options = attributes.Get('options', [(True, None)] + [ (False, i) for i in xrange(60) ])
     52         activeOptionIndex = attributes.Get('activeOptionIndex', 4)
     53         self.LoadOptions(options, activeOptionIndex)
     54         setvalueCallback = attributes.Get('OnSetValue', None)
     55         if setvalueCallback:
     56             self.OnSetValue = setvalueCallback
     57 
     58     def LoadOptions(self, options, activeOptionIndex = 0):
     59         for each in self.sr.mainTransform.children[:]:
     60             if each.name == 'tick':
     61                 each.Close()
     62 
     63         self._options = options
     64         step = math.pi * 2 / len(self._options)
     65         self._tickGap = step
     66         angle = 0.0
     67         activeRotation = 0.0
     68         for i, each in enumerate(self._options):
     69             isZero, args = each
     70             markerTransform = Transform(parent=self.sr.mainTransform, pos=(0,
     71              0,
     72              self.MARKERTFSIZE,
     73              self.MARKERTFSIZE), align=uiconst.CENTER, state=uiconst.UI_DISABLED, name='tick', rotation=angle + math.pi * 0.25, idx=0)
     74             sprite = Sprite(parent=markerTransform, align=uiconst.TOPRIGHT, pos=(0, 0, 16, 16), color=(0.0, 0.0, 0.0, 1.0), texturePath='res:/UI/Texture/spinWheelPicker_marker2.dds')
     75             if i == activeOptionIndex:
     76                 activeRotation = angle
     77             angle += step
     78             if isZero:
     79                 sprite.texture.resPath = 'res:/UI/Texture/CharacterCreation/ovalSlider_Filler.dds'
     80                 sprite.SetRGB(1.0, 0.0, 0.0)
     81                 sprite.top = 2
     82                 sprite.left = 2
     83 
     84         if activeRotation:
     85 
     86             def UpdateMarker(_None, newAngle):
     87                 self.sr.mainTransform.SetRotation(newAngle)
     88 
     89             currentAngle = self.sr.mainTransform.GetRotation()
     90             uicore.effect.MorphUIMassSpringDamper(None, None, activeRotation, newthread=False, frequency=15.0, dampRatio=0.5, callback=UpdateMarker, initVal=currentAngle)
     91         self.SettleOnTick()
     92 
     93     def SettleOnTick(self):
     94         sm.StartService('audio').SendUIEvent(unicode('ui_icc_circular_slider_item_selected_play'))
     95         currentAngle = self.sr.mainTransform.GetRotation()
     96 
     97         def UpdateMarker(_None, newAngle):
     98             if self.destroyed:
     99                 return
    100             self.sr.mainTransform.SetRotation(newAngle)
    101 
    102         step = self._tickGap
    103         angle = 0.0
    104         value = None
    105         for isZero, value in self._options:
    106             if angle - step / 2 < 0.0 and angle - step / 2 + math.pi * 2 <= currentAngle <= angle + step / 2 + math.pi * 2:
    107                 break
    108             if angle - step / 2 <= currentAngle <= angle + step / 2:
    109                 break
    110             angle += step
    111 
    112         if abs(angle - currentAngle) > step:
    113             angle += math.pi * 2
    114         uicore.effect.MorphUIMassSpringDamper(None, None, angle, frequency=15.0, dampRatio=0.5, callback=UpdateMarker, initVal=currentAngle)
    115         self.SetValue(value)
    116 
    117     def GetValue(self):
    118         return self._value
    119 
    120     def SetValue(self, value):
    121         self._value = value
    122         self.OnSetValue(self, value)
    123 
    124     def OnSetValue(self, control, value):
    125         pass
    126 
    127     def RotationTick(self, *args):
    128         if self._spinning:
    129             newAngle = self.GetRotationAngleFromCenter()
    130             delta = self._lastAngle - newAngle
    131             if delta:
    132                 self._didSpin = True
    133                 if abs(delta) > math.pi:
    134                     if delta < 0.0:
    135                         delta += math.pi * 2
    136                     else:
    137                         delta -= math.pi * 2
    138             self.sr.mainTransform.Rotate(delta * self.SPINRATIO)
    139             self._lastRotationDelta = delta * self.SPINRATIO
    140             self._lastAngle = newAngle
    141         else:
    142             self.sr._rotationTimer = None
    143 
    144     def OnClick(self, *args):
    145         if self._didSpin:
    146             return
    147         mouseAngle = self.GetRotationAngleFromCenter()
    148         currentAngle = self.sr.mainTransform.GetRotation()
    149         newAngle = mouseAngle + currentAngle - math.pi * 0.5
    150         newAngle = self.sr.mainTransform.ClampRotation(newAngle)
    151         self.sr.mainTransform.SetRotation(newAngle)
    152 
    153         def UpdateMarker(_None, _newAngle):
    154             self.sr.mainTransform.SetRotation(_newAngle)
    155 
    156         step = self._tickGap
    157         angle = 0.0
    158         value = None
    159         for isZero, value in self._options:
    160             if angle - step / 2 < 0.0 and angle - step / 2 + math.pi * 2 <= newAngle <= angle + step / 2 + math.pi * 2:
    161                 break
    162             if angle - step / 2 <= newAngle <= angle + step / 2:
    163                 break
    164             angle += step
    165 
    166         diff = abs(angle - currentAngle)
    167         if diff > math.pi:
    168             if angle > currentAngle:
    169                 angle -= math.pi * 2
    170             else:
    171                 angle += math.pi * 2
    172         uicore.effect.MorphUIMassSpringDamper(None, None, angle, frequency=15.0, dampRatio=0.5, callback=UpdateMarker, initVal=currentAngle)
    173         self.SetValue(value)
    174 
    175     def OnMouseWheel(self, *args):
    176         if getattr(self, '_wheeling', False):
    177             self._wheelbuffer += uicore.uilib.dz
    178         else:
    179             uthread.new(self.MouseWheelThread, uicore.uilib.dz)
    180 
    181     def MouseWheelThread(self, delta):
    182         self._wheeling = True
    183         blue.pyos.synchro.SleepWallclock(100)
    184         if self._wheelbuffer:
    185             delta += self._wheelbuffer
    186             self._wheelbuffer = 0
    187         sm.StartService('audio').SendUIEvent(unicode('ui_icc_circular_slider_item_selected_play'))
    188         currentAngle = self.sr.mainTransform.GetRotation()
    189 
    190         def UpdateMarker(_None, newAngle):
    191             self.sr.mainTransform.SetRotation(newAngle)
    192 
    193         steps = abs(delta / 120)
    194         if delta > 0:
    195             newAngle = currentAngle + self._tickGap * steps
    196         else:
    197             newAngle = currentAngle - self._tickGap * steps
    198         if newAngle < 0.0:
    199             newAngle += math.pi * 2
    200         elif newAngle > math.pi * 2:
    201             newAngle -= math.pi * 2
    202         step = self._tickGap
    203         angle = 0.0
    204         value = None
    205         for isZero, value in self._options:
    206             if angle - step / 2 < 0.0 and angle - step / 2 + math.pi * 2 <= newAngle <= angle + step / 2 + math.pi * 2:
    207                 break
    208             if angle - step / 2 <= newAngle <= angle + step / 2:
    209                 break
    210             angle += step
    211 
    212         diff = abs(angle - currentAngle)
    213         if diff > math.pi:
    214             if angle > currentAngle:
    215                 angle -= math.pi * 2
    216             else:
    217                 angle += math.pi * 2
    218         uicore.effect.MorphUIMassSpringDamper(None, None, angle, newthread=0, frequency=15.0, dampRatio=0.5, callback=UpdateMarker, initVal=currentAngle)
    219         self._wheeling = False
    220         if self._wheelbuffer:
    221             buff = self._wheelbuffer
    222             self._wheelbuffer = 0
    223             return self.MouseWheelThread(buff)
    224         self.SetValue(value)
    225 
    226     def OnMouseDown(self, button, *args):
    227         if button == uiconst.MOUSELEFT:
    228             sm.StartService('audio').SendUIEvent(unicode('ui_icc_inventory_item_mouse_over_loop_play'))
    229             self._lastAngle = self.GetRotationAngleFromCenter()
    230             self._spinning = True
    231             self._didSpin = False
    232             self.sr._rotationTimer = timerstuff.AutoTimer(10, self.RotationTick)
    233 
    234     def OnMouseUp(self, button, *args):
    235         if button == uiconst.MOUSELEFT:
    236             sm.StartService('audio').SendUIEvent(unicode('ui_icc_inventory_item_mouse_over_loop_stop'))
    237             self._spinning = False
    238             if self._didSpin:
    239                 uthread.new(self.Throw)
    240 
    241     def Throw(self, *args):
    242         newAngle = self.GetRotationAngleFromCenter()
    243         delta = self._lastRotationDelta
    244         lenOptions = len(self._options)
    245         if delta:
    246             distance = delta
    247             steps = 20
    248             maxExp = math.exp(steps / 10.0)
    249             for i in xrange(1, steps + 1):
    250                 iExp = math.exp(i / 10.0)
    251                 _delta = distance - distance * (iExp / maxExp)
    252                 self.sr.mainTransform.Rotate(_delta)
    253                 blue.pyos.synchro.SleepWallclock(10)
    254                 if self.destroyed or self._spinning:
    255                     return
    256 
    257         self.SettleOnTick()
    258 
    259     def GetRotationAngleFromCenter(self):
    260         x, y = uicore.uilib.x, uicore.uilib.y
    261         l, t, w, h = self.GetAbsolute()
    262         px, py = l + w / 2, t + h / 2
    263         tn = (abs(x - px) or 1e-07) / float(abs(y - py) or 1e-07)
    264         if y < py:
    265             if x > px:
    266                 rot = math.pi * 0.5 + math.atan(tn)
    267             else:
    268                 rot = math.pi * 0.5 - math.atan(tn)
    269         elif x > px:
    270             rot = math.pi * 1.5 - math.atan(tn)
    271         else:
    272             rot = math.pi * 1.5 + math.atan(tn)
    273         return self.sr.mainTransform.ClampRotation(rot)