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

uiComponents.py (7942B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\util\uiComponents.py
      2 import functools
      3 import math
      4 import signals
      5 import carbonui.const as uiconst
      6 from carbonui.primitives.fill import Fill
      7 from carbonui.primitives.gradientSprite import GradientSprite
      8 import logging
      9 import uthread
     10 from carbonui.uicore import uicore
     11 from carbonui.util.various_unsorted import GetWindowAbove
     12 logger = logging.getLogger(__name__)
     13 
     14 def Component(component):
     15 
     16     def AttachComponent(cls):
     17         if not hasattr(cls, '_attached_ui_components'):
     18             setattr(cls, '_attached_ui_components', [])
     19         cls._attached_ui_components.append(component)
     20         for methodName in component.__observed_methods__:
     21             method = getattr(cls, methodName, None)
     22             if method is None:
     23                 continue
     24             signal = getattr(method, '_component_method_observers', None)
     25             if signal is None:
     26                 signal = signals.Signal()
     27 
     28                 def GetWrapper(_method, _signal):
     29 
     30                     @functools.wraps(method)
     31                     def Wrapper(*args, **kwargs):
     32                         try:
     33                             result = _method(*args, **kwargs)
     34                         except:
     35                             logger.exception('Method %s raised an exception before signal could emit', methodName)
     36                             raise
     37 
     38                         try:
     39                             _signal(*args, **kwargs)
     40                         except Exception:
     41                             logger.exception('Failed while notifying observers for method %s', methodName)
     42 
     43                         return result
     44 
     45                     return Wrapper
     46 
     47                 wrapper = GetWrapper(method, signal)
     48                 setattr(wrapper, '_component_method_observers', signal)
     49                 setattr(cls, methodName, wrapper)
     50             signal.connect(getattr(component, methodName))
     51 
     52         return cls
     53 
     54     return AttachComponent
     55 
     56 
     57 THREADS_BY_KEY = {}
     58 
     59 def RunThreadOnce(threadKey):
     60 
     61     def Wrapper(func):
     62 
     63         @functools.wraps(func)
     64         def RunThread(*args, **kwargs):
     65             if threadKey not in THREADS_BY_KEY:
     66                 THREADS_BY_KEY[threadKey] = uthread.new(ExecuteAndRelease, func, *args, **kwargs)
     67 
     68         return RunThread
     69 
     70     def ExecuteAndRelease(func, *args, **kwargs):
     71         try:
     72             func(*args, **kwargs)
     73         finally:
     74             del THREADS_BY_KEY[threadKey]
     75 
     76     return Wrapper
     77 
     78 
     79 class ButtonEffect:
     80     __observed_methods__ = ['ApplyAttributes',
     81      'OnMouseEnter',
     82      'OnMouseExit',
     83      'OnMouseUp',
     84      'OnMouseDown',
     85      'OnClick']
     86     isToggleButton = False
     87     isRadioButton = False
     88 
     89     def __init__(self, opacityIdle = 0.0, opacityHover = 0.5, opacityMouseDown = 0.85, idx = 0, bgElementFunc = None, audioOnEntry = None, audioOnClick = None, exitDuration = 0.3):
     90         self.opacityIdle = opacityIdle
     91         self.opacityHover = opacityHover
     92         self.opacityMouseDown = opacityMouseDown
     93         self.bgElementFunc = bgElementFunc
     94         self.audioOnEntry = audioOnEntry
     95         self.audioOnClick = audioOnClick
     96         self.idx = idx
     97         self.exitDuration = exitDuration
     98 
     99     def ApplyAttributes(self, _self, attributes, *args):
    100         if self.bgElementFunc:
    101             _self._buttonEffect_bgElement = self.bgElementFunc(_self, attributes)
    102         else:
    103             _self._buttonEffect_bgElement = GradientSprite(name='hoverGradient', bgParent=_self, rotation=-math.pi / 2, rgbData=[(0, (1.0, 1.0, 1.0))], alphaData=[(0, 0.5), (0.3, 0.2), (0.6, 0.08)], idx=self.idx)
    104         _self._buttonEffect_bgElement.opacity = self.opacityIdle
    105         if not hasattr(_self, 'disabled'):
    106             setattr(_self, 'disabled', attributes.disabled or False)
    107         if self.isToggleButton:
    108             setattr(_self, 'isActive', attributes.isActive or False)
    109             if _self.isActive:
    110                 _self._buttonEffect_bgElement.opacity = self.opacityMouseDown
    111 
    112             def SetActive(isActive):
    113                 _self.isActive = isActive
    114                 if _self.isActive:
    115                     uicore.animations.FadeTo(_self._buttonEffect_bgElement, _self._buttonEffect_bgElement.opacity, self.opacityMouseDown, duration=0.1)
    116                 else:
    117                     uicore.animations.FadeTo(_self._buttonEffect_bgElement, _self._buttonEffect_bgElement.opacity, self.opacityIdle, duration=self.exitDuration)
    118                 onActiveStateChange = getattr(_self, 'OnActiveStateChange', None)
    119                 if onActiveStateChange is not None:
    120                     onActiveStateChange()
    121 
    122             _self.SetActive = SetActive
    123 
    124     def OnMouseEnter(self, _self, *args):
    125         if _self.disabled:
    126             return
    127         if not self.IsActiveToggle(_self):
    128             uicore.animations.FadeTo(_self._buttonEffect_bgElement, _self._buttonEffect_bgElement.opacity, self.opacityHover, duration=0.1)
    129         if self.audioOnEntry:
    130             sm.GetService('audio').SendUIEvent(self.audioOnEntry)
    131 
    132     def OnMouseExit(self, _self, *args):
    133         if not (self.isToggleButton and _self.isActive):
    134             uicore.animations.FadeTo(_self._buttonEffect_bgElement, _self._buttonEffect_bgElement.opacity, self.opacityIdle, duration=0.3)
    135 
    136     def OnMouseDown(self, _self, *args):
    137         if _self.disabled:
    138             return
    139         if self.IsActiveToggle(_self):
    140             uicore.animations.FadeTo(_self._buttonEffect_bgElement, _self._buttonEffect_bgElement.opacity, self.opacityMouseDown, duration=0.1)
    141 
    142     def OnMouseUp(self, _self, *args):
    143         if _self.disabled:
    144             return
    145         if self.IsActiveToggle(_self):
    146             return
    147         uicore.animations.FadeTo(_self._buttonEffect_bgElement, _self._buttonEffect_bgElement.opacity, self.opacityHover, duration=0.2)
    148 
    149     def OnClick(self, _self, *args):
    150         if _self.disabled:
    151             return
    152         self.Toggle(_self)
    153         if not self.IsActiveToggle(_self):
    154             uicore.animations.FadeTo(_self._buttonEffect_bgElement, _self._buttonEffect_bgElement.opacity, self.opacityMouseDown, duration=self.exitDuration)
    155         if self.audioOnClick:
    156             sm.GetService('audio').SendUIEvent(self.audioOnClick)
    157 
    158     def IsActiveToggle(self, _self):
    159         return self.isToggleButton and _self.isActive
    160 
    161     def Toggle(self, _self):
    162         if self.isRadioButton:
    163             _self.SetActive(True)
    164         elif self.isToggleButton:
    165             _self.SetActive(not _self.isActive)
    166 
    167 
    168 class ToggleButtonEffect(ButtonEffect):
    169     isToggleButton = True
    170 
    171 
    172 class RadioButtonEffect(ButtonEffect):
    173     isToggleButton = True
    174     isRadioButton = True
    175 
    176 
    177 class HoverEffect:
    178     __observed_methods__ = ['ApplyAttributes',
    179      'OnMouseEnter',
    180      'OnMouseExit',
    181      'OnClick']
    182 
    183     def __init__(self, padding = (1, 1, 1, 1), color = (1.0, 1.0, 1.0, 0.25), audioOnEntry = None, audioOnClick = None, bgElementFunc = None):
    184         self.padding = padding
    185         self.color = color
    186         self.audioOnEntry = audioOnEntry
    187         self.audioOnClick = audioOnClick
    188         self.bgElementFunc = bgElementFunc
    189 
    190     def _GetHoverElement(self, _self):
    191         return getattr(_self, '_hoverEffect_bgFill', None)
    192 
    193     def ApplyAttributes(self, _self, *args):
    194         setattr(_self, '_hoverEffect_bgFill', Fill(bgParent=_self, padding=self.padding, color=self.color, state=uiconst.UI_HIDDEN))
    195 
    196     def OnMouseEnter(self, _self, *args):
    197         fill = self._GetHoverElement(_self)
    198         if fill is None:
    199             return
    200         fill.state = uiconst.UI_NORMAL
    201         if self.audioOnEntry:
    202             sm.GetService('audio').SendUIEvent(self.audioOnEntry)
    203 
    204     def OnMouseExit(self, _self, *args):
    205         fill = self._GetHoverElement(_self)
    206         if fill:
    207             fill.state = uiconst.UI_HIDDEN
    208 
    209     def OnClick(self, _self, *args):
    210         if self.audioOnClick:
    211             sm.GetService('audio').SendUIEvent(self.audioOnClick)