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

bargraph.py (11573B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\control\bargraph.py
      2 import math
      3 import blue
      4 import localization
      5 import uthread
      6 from carbon.common.script.util.format import FmtAmt
      7 from carbonui import uiconst
      8 from carbonui.primitives.container import Container
      9 from carbonui.primitives.fill import Fill
     10 from carbonui.primitives.frame import Frame
     11 from carbonui.primitives.line import Line
     12 from carbonui.primitives.sprite import Sprite
     13 from carbonui.uicore import uicore
     14 from carbonui.uianimations import animations
     15 from carbonui.util.color import Color
     16 from eve.client.script.ui.control import eveLabel
     17 COLOR_FRAME = (1.0,
     18  1.0,
     19  1.0,
     20  0.5)
     21 
     22 class BarGraph(Container):
     23     default_name = 'barGraph'
     24     default_maxValue = 1.0
     25     default_barUpdateDelayMs = 10
     26     default_backgroundColor = (0.0, 0.0, 0.0, 0.9)
     27     default_timeIndicatorColor = (1.0, 1.0, 1.0, 0.6)
     28     UPDATEINTERVAL_NORMAL = 100
     29     UPDATEINTERVAL_NEWBARS = 1500
     30 
     31     def ApplyAttributes(self, attributes):
     32         Container.ApplyAttributes(self, attributes)
     33         self.barUpdateDelayMs = attributes.get('barUpdateDelayMs', self.default_barUpdateDelayMs)
     34         backgroundColor = attributes.get('backgroundColor', self.default_backgroundColor)
     35         timeIndicatorColor = attributes.get('timeIndicatorColor', self.default_timeIndicatorColor)
     36         self.barHintFunc = attributes.get('barHintFunc', None)
     37         self.bars = []
     38         self.busy = None
     39         self.queuedValues = None
     40         self.numBars = None
     41         self.setValuesThread = None
     42         self.timeIndicatorValue = 0.0
     43         self.maxValue = None
     44         self.xLabels = None
     45         self.timeIndicatorThread = None
     46         self.barWidth = None
     47         XAXISHEIGHT = 15
     48         YAXISWIDTH = 40
     49         self.yAxisCont = Container(parent=self, name='yAxisCont', align=uiconst.TOLEFT, width=YAXISWIDTH, padBottom=XAXISHEIGHT + 1)
     50         self.xAxisCont = Container(parent=self, name='xAxisCont', align=uiconst.TOBOTTOM, height=XAXISHEIGHT)
     51         self.graphCont = Container(parent=self, name='graphCont', align=uiconst.TOALL)
     52         self.timeIndicator = Line(parent=self.graphCont, name='timeIndicator', state=uiconst.UI_HIDDEN, align=uiconst.TOPLEFT, color=timeIndicatorColor, padding=(0, 1, 0, 1), width=1)
     53         self.backgroundCont = Container(parent=self, name='backgroundCont', align=uiconst.TOALL, padding=(1, 2, 1, 1), clipChildren=True)
     54         Frame(parent=self, color=COLOR_FRAME)
     55         Sprite(parent=self.backgroundCont, name='backgroundStripes', align=uiconst.TOTOP, height=500, texturePath='res:/UI/Texture/Bargraph/background_stripes.dds', ignoreSize=True, color=backgroundColor)
     56         self.barCont = Container(parent=self.graphCont, name='barCont', align=uiconst.TOALL, padding=(2, 2, 1, 1), clipChildren=True)
     57 
     58     def _CreateBars(self, numBars):
     59         self.barCont.Flush()
     60         self.bars = []
     61         self.numBars = numBars
     62         l, t, w, h = self.barCont.GetAbsolute()
     63         self.barWidth = max(1, (w - 2) / self.numBars)
     64         for i in xrange(self.numBars):
     65             bar = Bar(parent=self.barCont, name='bar%s' % i, align=uiconst.TOLEFT, width=self.barWidth, height=h, barNum=i + 1)
     66             if self.barHintFunc:
     67                 bar._GetBarHint = self.barHintFunc
     68             self.bars.append(bar)
     69 
     70         self.xAxisCont.padRight = w - self.barWidth * self.numBars - 2
     71         if self.xLabels:
     72             self.SetXLabels(self.xLabels)
     73         self.ShowTimeIndicator(self.timeIndicatorValue)
     74 
     75     def SetXLabels(self, labels):
     76         self.xAxisCont.Flush()
     77         self.xLabels = labels
     78         for i, label in enumerate(labels):
     79             if i == len(labels) - 1:
     80                 align = uiconst.TOPRIGHT
     81             else:
     82                 align = uiconst.TOPLEFT
     83             XLabel(parent=self.xAxisCont, value=float(i) / (len(labels) - 1), text=label, align=align)
     84 
     85     def _CreateYAxis(self):
     86         self.yAxisCont.Flush()
     87         NUMYAXISLABELS = 5
     88         if self.maxValue == 0:
     89             return
     90         for i in xrange(NUMYAXISLABELS):
     91             value = float(i) / (NUMYAXISLABELS - 1)
     92             YLabel(parent=self.yAxisCont, width=self.yAxisCont.width, value=value, text=FmtAmt(value * self.maxValue))
     93 
     94         yAxisFill = Fill(parent=self.yAxisCont, color=Color.WHITE)
     95         animations.FadeTo(yAxisFill, startVal=0.2, endVal=0.0, duration=0.3)
     96 
     97     def SetValues(self, values):
     98         if self.busy:
     99             self.queuedValues = values
    100             return
    101         self.queuedValues = None
    102         self.busy = True
    103         updateInterval = self.UPDATEINTERVAL_NORMAL
    104         maxValue = max(values)
    105         lenValues = len(values)
    106         if self.numBars != lenValues:
    107             if self.setValuesThread:
    108                 self.setValuesThread.kill()
    109             self._CreateBars(lenValues)
    110             updateInterval = self.UPDATEINTERVAL_NEWBARS
    111         YAXISRESCALEVALUE = 1
    112         while YAXISRESCALEVALUE < maxValue:
    113             YAXISRESCALEVALUE *= 10
    114 
    115         YAXISRESCALEVALUE *= 0.1
    116         if maxValue > self.maxValue or maxValue < self.maxValue - 1.3 * YAXISRESCALEVALUE:
    117             self.maxValue = int(math.ceil(float(maxValue) / YAXISRESCALEVALUE)) * YAXISRESCALEVALUE
    118             self._CreateYAxis()
    119         self.setValuesThread = uthread.new(self._SetValues, values)
    120         uthread.new(self._EnforceUpdateInterval, updateInterval)
    121 
    122     def _EnforceUpdateInterval(self, updateInterval):
    123         blue.pyos.synchro.SleepWallclock(updateInterval)
    124         if not self or self.destroyed:
    125             return
    126         self.busy = False
    127         if self.queuedValues:
    128             self.SetValues(self.queuedValues)
    129 
    130     def _SetValues(self, values):
    131         for i, val in enumerate(values):
    132             if i >= self.numBars:
    133                 continue
    134             bar = self.bars[i]
    135             if self.maxValue == 0:
    136                 bar.SetValue(rawValue=0.0, maxRawValue=1.0)
    137             else:
    138                 bar.SetValue(rawValue=val, maxRawValue=self.maxValue)
    139             if self.barUpdateDelayMs:
    140                 blue.pyos.synchro.SleepWallclock(self.barUpdateDelayMs)
    141                 if not self or self.destroyed:
    142                     return
    143 
    144     def ShowTimeIndicator(self, value, animate = True):
    145         if value is None:
    146             return
    147         if self.barWidth is None:
    148             return
    149         self.timeIndicatorValue = value
    150         l, t, w, h = self.graphCont.GetAbsolute()
    151         self.timeIndicator.state = uiconst.UI_DISABLED
    152         self.timeIndicator.SetAlpha(1.0)
    153         p = self.barCont.padLeft
    154         self.timeIndicator.left = p + int(value * self.barWidth * self.numBars)
    155         self.timeIndicator.height = h
    156         if animate and self.timeIndicatorThread is None:
    157             self.timeIndicatorThread = uthread.new(self._AnimateTimeIndicator)
    158 
    159     def _AnimateTimeIndicator(self):
    160         x = 0.0
    161         CYCLETIME = 3.0
    162         k = 2 * math.pi / CYCLETIME
    163         while self and not self.destroyed:
    164             x = (x + 1.0 / blue.os.fps) % CYCLETIME
    165             self.timeIndicator.SetAlpha(0.3 * math.sin(k * x) + 0.7)
    166             blue.pyos.synchro.Yield()
    167 
    168     def HideTimeIndicator(self):
    169         self.timeIndicatorValue = None
    170         self.timeIndicator.state = uiconst.UI_HIDDEN
    171         if self.timeIndicatorThread is not None:
    172             self.timeIndicatorThread.kill()
    173             self.timeIndicatorThread = None
    174 
    175 
    176 class Bar(Container):
    177     default_frequency = 14.0
    178     default_dampRatio = 1.41
    179     default_color = COLOR_FRAME
    180     default_disturbance = 0.5
    181     default_state = uiconst.UI_NORMAL
    182     BARHEIGHT = 150
    183 
    184     def ApplyAttributes(self, attributes):
    185         Container.ApplyAttributes(self, attributes)
    186         self.frequency = attributes.Get('frequency', self.default_frequency)
    187         self.dampRatio = attributes.Get('dampRatio', self.default_dampRatio)
    188         self.color = attributes.Get('color', self.default_color)
    189         self.disturbance = attributes.Get('disturbance', self.default_disturbance)
    190         self.barNum = attributes.Get('barNum', 0)
    191         self.value = 0.0
    192         self.rawValue = 0.0
    193         self.maxRawValue = 1.0
    194         self.morphThread = None
    195         self.graphHeight = None
    196         self.backgroundFill = Fill(parent=self, color=Color.GetGrayRGBA(0.0, 0.5), state=uiconst.UI_HIDDEN)
    197         self.bar = Sprite(parent=self, align=uiconst.BOTTOMLEFT, color=self.color, texturePath='res:/UI/Texture/Bargraph/%s.dds' % self.BARHEIGHT, pos=(0,
    198          -self.BARHEIGHT,
    199          self.width,
    200          self.BARHEIGHT), state=uiconst.UI_DISABLED, padLeft=1)
    201 
    202     def SetValue(self, rawValue, maxRawValue, *args):
    203         if self.morphThread:
    204             self.morphThread.kill()
    205         initVal = self.value
    206         self.rawValue = rawValue
    207         self.maxRawValue = maxRawValue
    208         self.value = float(rawValue) / maxRawValue
    209         if not self.graphHeight:
    210             l, t, w, h = self.GetAbsolute()
    211             self.graphHeight = h
    212         diffInPixels = math.fabs(self.GetTopFromValue(initVal) - self.GetTopFromValue(self.value))
    213         if diffInPixels > 2:
    214             self.morphThread = uicore.effect.MorphUIMassSpringDamper(self.bar, newVal=self.value, initVal=initVal, newthread=1, float=1, minVal=-1.0, maxVal=1.0, dampRatio=self.dampRatio, frequency=self.frequency, maxTime=3.0, callback=self.OnValueChanged)
    215         else:
    216             self.OnValueChanged(self, self.value)
    217 
    218     def OnValueChanged(self, bar, value, *args):
    219         if not self or self.destroyed:
    220             return
    221         HUEMAX = 0.6
    222         hue = HUEMAX * max(0.0, 1.0 - value)
    223         color = Color().SetHSB(hue, 0.7, 0.8, 1.0).GetRGBA()
    224         self.bar.SetRGBA(*color)
    225         self.bar.top = self.GetTopFromValue(value)
    226         self.value = value
    227 
    228     def GetTopFromValue(self, value):
    229         top = int(value * self.graphHeight - self.BARHEIGHT)
    230         top -= top % 2
    231         return top
    232 
    233     def GetHint(self):
    234         return self._GetBarHint(self.barNum, self.rawValue, self.maxRawValue)
    235 
    236     def _GetBarHint(self, num, rawValue, maxRawValue):
    237         return localization.GetByLabel('UI/BarGraph/DefaultBarHint', num=num, rawValue=rawValue, maxRawValue=maxRawValue)
    238 
    239     def OnMouseEnter(self, *args):
    240         if hasattr(self, 'background'):
    241             self.backgroundFill.state = uiconst.UI_DISABLED
    242 
    243     def OnMouseExit(self, *args):
    244         if hasattr(self, 'background'):
    245             self.backgroundFill.state = uiconst.UI_HIDDEN
    246 
    247 
    248 class LabelText(eveLabel.EveLabelSmall):
    249     default_color = (1.0, 1.0, 1.0, 0.6)
    250 
    251 
    252 class YLabel(Container):
    253     default_align = uiconst.BOTTOMRIGHT
    254     default_height = 20
    255 
    256     def ApplyAttributes(self, attributes):
    257         Container.ApplyAttributes(self, attributes)
    258         value = attributes.Get('value')
    259         text = attributes.Get('text', '%s' % value)
    260         l, t, w, h = self.parent.GetAbsolute()
    261         self.top = int(h * value)
    262         LabelText(parent=self, text=text, align=uiconst.BOTTOMRIGHT, top=-5, left=5)
    263         Line(parent=self, color=COLOR_FRAME, align=uiconst.BOTTOMRIGHT, width=4, height=1, top=-1)
    264 
    265 
    266 class XLabel(Container):
    267     default_align = uiconst.TOPLEFT
    268     default_width = 100
    269     default_height = 20
    270 
    271     def ApplyAttributes(self, attributes):
    272         Container.ApplyAttributes(self, attributes)
    273         value = attributes.Get('value')
    274         text = attributes.Get('text', '%s' % value)
    275         l, t, w, h = self.parent.GetAbsolute()
    276         LabelText(parent=self, text=text, align=self.align, top=5)
    277         Line(parent=self, color=COLOR_FRAME, align=self.align, width=1, height=4)