Beispiel #1
0
 def SetValue(self, value, animate=True):
     if value > 1.0:
         uicore.animations.FadeTo(self,
                                  0.25,
                                  1.0,
                                  duration=0.5,
                                  loops=uiconst.ANIM_REPEAT)
     else:
         uicore.animations.FadeIn(self, duration=0.5)
     value = min(1.0, max(0.0, value))
     self.currentValue = 100 * value
     value *= self.gaugeRange / 360.0
     GaugeCircular.SetValue(self, value)
Beispiel #2
0
 def SetValue(self, value, *args):
     GaugeCircular.SetValue(self, value, *args)
     sm.GetService('audio').SetGlobalRTPC('ind_circleValue', 100 * value)
Beispiel #3
0
class Timer(uiprimitives.Container):
    __guid__ = 'crimewatchTimers.Timer'
    default_width = 46
    default_align = uiconst.TOLEFT
    default_hintClass = TimerHint

    def ApplyAttributes(self, attributes):
        uiprimitives.Container.ApplyAttributes(self, attributes)
        self.hintClass = attributes.get('hintClass', self.default_hintClass)
        self.state = uiconst.UI_PICKCHILDREN
        self.timerHint = None
        self.showHint = False
        self.expiryTime = None
        self.iconBlink = None
        self.rewind = False
        self.ratio = 0.0
        self.counterText = None
        self.animationThread = None
        self.timerType = attributes.Get('timerType')
        self.timerData = attributes.get('timerData', CRIMEWATCH_TIMER_DATA[attributes.Get('timerType')])
        self.GetTime = self.timerData.timerFunc
        self.activeAnimationCurves = None
        self.callback = attributes.get('callback', None)
        self.content = uiprimitives.Transform(parent=self, name='content', align=uiconst.TOPLEFT, pos=(0, 0, 32, 32), state=uiconst.UI_NORMAL)
        self.content.OnMouseEnter = self.OnMouseEnter
        self.iconTransform = uiprimitives.Transform(parent=self.content, name='iconTransform', align=uiconst.CENTER, width=16, height=16, state=uiconst.UI_DISABLED)
        self.icon = uiprimitives.Sprite(name='icon', parent=self.iconTransform, pos=(0, 0, 16, 16), texturePath=self.timerData.icon, color=self.timerData.color, state=uiconst.UI_DISABLED, align=uiconst.CENTER)
        self.gaugeCircular = GaugeCircular(parent=self.content, radius=16, align=uiconst.CENTER, colorStart=self.timerData.color, colorEnd=self.timerData.color, colorBg=Color(*self.timerData.color).SetAlpha(ALPHA_EMPTY).GetRGBA(), lineWidth=2.5, clockwise=False, showMarker=False, state=uiconst.UI_DISABLED)
        self.pointerContainer = uiprimitives.Transform(name='pointer_container', parent=self.content, width=32, height=32, idx=0)
        self.pointerClipper = uiprimitives.Container(parent=self.pointerContainer, pos=(9, -10, 15, 13), clipChildren=True, align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED)
        self.pointerSprite = uiprimitives.Sprite(name='cycle_pointer', parent=self.pointerClipper, pos=(0, 0, 15, 19), texturePath='res:/UI/Texture/Crimewatch/Crimewatch_TimerPoint_WithShadow.png', color=self.timerData.color, align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED)
        self.iconTransform.scalingCenter = (0.5, 0.5)
        uicore.animations.Tr2DScaleTo(self.iconTransform, startScale=(0.8, 0.8), endScale=(1.0, 1.0), duration=0.75, curveType=uiconst.ANIM_OVERSHOT)

    def SetTimerType(self, timerType):
        self.timerData = CRIMEWATCH_TIMER_DATA[timerType]
        r, g, b, a = self.timerData.color
        self.icon.color.SetRGB(r, g, b, a)
        self.pointerSprite.color.SetRGB(r, g, b, a)
        self.gaugeCircular.SetColor(self.timerData.color, self.timerData.color)

    def SetRatio(self, ratio):
        self.ratio = min(1.0, max(0.0, ratio))
        rotation = min(pi * 2, 2 * pi * self.ratio)
        self.pointerContainer.rotation = rotation
        self.gaugeCircular.SetValue(ratio, animate=False)

    def SetExpiryTime(self, expiryTime, doAlert, maxDuration = None):
        self.Reset(expiryTime, doAlert, maxDuration=maxDuration)
        self.expiryTime = expiryTime
        if expiryTime is None:
            self.PlayActiveAnimation()
        else:
            self.animationThread = uthread.new(self.Animate_Thread)

    def Reset(self, resetTo, doAlert, maxDuration = None):
        if self.animationThread is not None:
            self.animationThread.kill()
        if maxDuration and maxDuration != self.timerData.maxTimeout:
            self.timerData = self.timerData._replace(maxTimeout=maxDuration)
        uthread.new(self.Rewind_Thread, resetTo, doAlert)

    def Rewind_Thread(self, resetTo, doAlert):
        if self.rewind:
            return
        if doAlert and self.timerData.resetAudioEvent is not None:
            sm.GetService('audio').SendUIEvent(self.timerData.resetAudioEvent)
        self.rewind = True
        ratio = self.ratio
        startTime = self.GetTime()
        distance = 1 - ratio
        cycleSpeed = float(distance * 500)
        while not self.destroyed and self.ratio < (self.GetRatio(resetTo - self.GetTime()) if resetTo is not None else 1.0):
            elapsedTime = blue.os.TimeDiffInMs(startTime, self.GetTime())
            toAdd = elapsedTime / cycleSpeed
            self.SetRatio(ratio + toAdd)
            blue.pyos.synchro.SleepWallclock(25)

        self.rewind = False

    def FlipFlop(self, sprite, duration = 1.0, startValue = 0.0, endValue = 1.0, loops = 5):
        curve = trinity.Tr2ScalarCurve()
        curve.length = duration
        curve.interpolation = trinity.TR2CURVE_LINEAR
        curve.startValue = startValue
        curve.AddKey(0.01 * duration, endValue)
        curve.AddKey(0.5 * duration, endValue)
        curve.AddKey(0.51 * duration, startValue)
        curve.endValue = startValue
        return uicore.animations.Play(curve, sprite, 'opacity', loops, None, False)

    def GetRatio(self, timeLeft):
        ratio = timeLeft / float(self.timerData.maxTimeout)
        ratio = min(1.0, max(0.0, ratio))
        return ratio

    def Animate_Thread(self):
        self.StopActiveAnimation()
        while not self.destroyed and self.expiryTime is not None:
            if not self.rewind:
                if self.ratio <= 0.0:
                    break
                timeLeft = self.expiryTime - self.GetTime()
                ratio = self.GetRatio(timeLeft)
                self.SetRatio(ratio)
                if timeLeft < BLINK_BEFORE_DONE_TIME:
                    self.PlayIconBlink()
                else:
                    self.StopIconBlink()
            blue.pyos.synchro.SleepWallclock(50)

        if self.callback:
            self.callback(self)

    def PlayIconBlink(self):
        if self.iconBlink is None:
            self.iconBlink = self.FlipFlop(self.icon, startValue=1.0, endValue=0.0)
            if self.timerData.endingAudioEvent:
                sm.GetService('audio').SendUIEvent(self.timerData.endingAudioEvent)

    def StopIconBlink(self):
        if self.iconBlink is not None:
            self.iconBlink.Stop()
            self.iconBlink = None
            self.icon.opacity = 1.0

    def EndAnimation(self):
        self.SetRatio(0.0)
        uicore.animations.MoveOutBottom(self.pointerSprite, amount=9, duration=0.3, sleep=False)
        self.content.scalingCenter = (0.5, 0.5)
        uicore.animations.Tr2DScaleTo(self.content, startScale=(1.0, 1.0), endScale=(0.8, 0.8), duration=0.4, sleep=True)

    def OnMouseEnter(self, *args):
        uthread.new(self.ShowHide)

    def ShowHide(self):
        blue.pyos.synchro.SleepWallclock(250)
        if uicore.uilib.mouseOver is self.content:
            self.showHint = True
            if self.timerHint is None:
                left, top, width, height = self.content.GetAbsolute()
                self.timerHint = self.hintClass(parent=uicore.layer.abovemain, left=left + 16, top=top + 16, timerData=self.timerData, parentTimer=self)

    def ShiftLeft(self):
        uicore.animations.MoveInFromRight(self, self.width, duration=0.5)

    def SetCounter(self, count):
        if count is None or count <= 1:
            if self.counterText is not None:
                self.counterText.Close()
                self.counterText = None
        else:
            if self.counterText is None:
                self.counterText = uicontrols.EveHeaderLarge(parent=self.content, name='counter', left=34, top=-2, bold=True, color=self.timerData.color)
            text = str(count) if count < 10 else '9+'
            self.counterText.text = text

    def PlayActiveAnimation(self):
        self.activeAnimationCurves = ((self.pointerSprite, self.FlipFlop(self.pointerSprite, startValue=1.0, endValue=0.75, duration=1.0, loops=uiconst.ANIM_REPEAT)), (self.gaugeCircular, self.FlipFlop(self.gaugeCircular, startValue=1.0, endValue=0.75, duration=1.0, loops=uiconst.ANIM_REPEAT)))

    def StopActiveAnimation(self):
        if self.activeAnimationCurves is not None:
            for sprite, animCurve in self.activeAnimationCurves:
                animCurve.Stop()
                sprite.opacity = 1.0

            self.activeAnimationCurves = None