Exemple #1
0
 def process(self, dc, values):
     from math import radians, sqrt
     #Save bmp and rescale it as the dice arry
     bmp = dc.GetAsBitmap()
     w, h = bmp.GetSize()
     size_length = w / (2 * sqrt(2))
     img = wx.ImageFromBitmap(bmp)
     img.Rescale(size_length, size_length)
     #Paste the rotated bmp
     dc.Clear()
     #Draw the necessary lines
     dc.Pen = wx.Pen('black')
     b = size_length
     c = float(b) * sqrt(2) / 2
     #Partial diagonal lines
     dc.DrawLine(0, c, 2 * c, 3 * c)
     dc.DrawLine(c, 4 * c, 3 * c, 2 * c)
     dc.DrawLine(4 * c, 3 * c, 2 * c, c)
     dc.DrawLine(3 * c, 0, c, 2 * c)
     #Straing lines
     dc.DrawLine(0, c, 2 * c, c)
     dc.DrawLine(2 * c, 3 * c, 4 * c, 3 * c)
     #And now the picture
     gc = wx.GraphicsContext_Create(dc)
     gc.Translate(2 * c, c)
     gc.Rotate(radians(45))
     gc.DrawBitmap(wx.BitmapFromImage(img), 0, 0, b, b)
    def OnMouseMove(self, evt):
        if not self.HasCapture():
            return
        rect = wx.RectPP(self.startPos, evt.GetPosition())
        # Draw the rubber-band rectangle using an overlay so it
        # will manage keeping the rectangle and the former window
        # contents separate.
        dc = wx.ClientDC(self)
        odc = wx.DCOverlay(self.overlay, dc)
        odc.Clear()

        pen = wx.Pen("black", 2)
        brush = wx.Brush(wx.Color(192, 192, 192, 128))
        if "wxMac" in wx.PlatformInfo:
            dc.SetPen(pen)
            dc.SetBrush(brush)
            dc.DrawRectangleRect(rect)
        else:
            # use a GC on Windows (and GTK?)
            # this crashed on the Mac
            ctx = wx.GraphicsContext_Create(dc)
            ctx.SetPen(pen)
            ctx.SetBrush(brush)
            ctx.DrawRectangle(*rect)

        del odc  # work around a bug in the Python wrappers to make
    def OnPaint(self, evt):
        dc = self.dcref(self)
        gc = wx.GraphicsContext_Create(dc)

        if self.onMotion or self.needBitmap:
            self.drawBackBitmap()
        dc.DrawBitmap(self.backBitmap,0,0)

        activeTrajs = [t for t in self.getActiveTrajectories() if len(t.getPoints()) > 1 and t.circlePos]
        self.parent.sg_audio.setMixerChannelAmps(activeTrajs, self.fxballValues)

        if not self.useMario:
            for t in activeTrajs:
                if t.circlePos != None:
                    gc.SetPen(t.getPen())
                    gc.SetBrush(t.getBrush())
                    gc.DrawEllipse(t.circlePos[0]-5, t.circlePos[1]-5, 10, 10)
                    gc.SetPen(t.getBorderPen())
                    gc.SetBrush(t.getBorderBrush())
                    gc.DrawEllipse(t.circlePos[0]-2, t.circlePos[1]-2, 4, 4)
        else:
            for t in activeTrajs:
                if t.lastCirclePos[0] < t.circlePos[0]: marioff = 0
                else: marioff = 4
                bitmario = self.marios[t.mario + marioff]
                dc.DrawBitmap(bitmario, t.circlePos[0]-8, t.circlePos[1]-8, True)

        if self.pointerPos != None:
            w,h = self.GetSize()
            dc.SetTextForeground("#FFFFFF")
            dc.SetFont(self.font_pos)
            xvalue = self.pointerPos[0] / float(w) * self.parent.controls.sndDur
            yvalue = (h - self.pointerPos[1]) / float(h)
            dc.DrawText("X: %.3f  Y: %.3f" % (xvalue, yvalue), w-110, h-13)
Exemple #4
0
    def drawlayer(self, image):
        try:
            dc = wx.MemoryDC()
            dc.SelectObject(self.bitmap)
            dc.SetBackground(wx.Brush("black"))
            dc.Clear()
            dc.SetPen(self.pen)
            dc.SetBrush(self.brush)

            if self.slicer == 'Skeinforge':
                for i in image:
                    #print i
                    points = [
                        wx.Point(
                            *map(lambda x: int(round(float(x) * self.scale)),
                                 j.strip().split()))
                        for j in i.strip().split("M")[1].split("L")
                    ]
                    dc.DrawPolygon(points, self.size[0] / 2, self.size[1] / 2)
            elif self.slicer == 'Slic3r':
                gc = wx.GraphicsContext_Create(dc)
                gc.Translate(*self.offset)
                gc.Scale(self.scale, self.scale)
                wxpsvgdocument.SVGDocument(image).render(gc)
            elif self.slicer == 'bitmap':
                dc.DrawBitmap(image, self.offset[0], -self.offset[1], True)
            else:
                raise Exception(self.slicer + " is an unknown method.")
            self.pic.SetBitmap(self.bitmap)
            self.pic.Show()
            self.Refresh()

        except:
            raise
            pass
Exemple #5
0
    def draw(self, dc):
        gc = wx.GraphicsContext_Create(dc)
        dc.SetTextForeground("#000000")
        dc.SetFont(self.font)
        if not self.sndBitmap:
            w, h = self.GetSize()
            dc.SetBrush(wx.Brush(self.backgroundcolor, wx.SOLID))
            dc.Clear()
            dc.SetPen(wx.Pen(self.outlinecolor, width=1, style=wx.SOLID))
            dc.DrawRectangle(0, 0, w, h)
        else:
            dc.DrawBitmap(self.sndBitmap, 0, 0)

        [
            dc.DrawBitmap(fx.bit, fx.pos[0], fx.pos[1], True)
            for fx in self.fxballValues
        ]

        selectedTraj = self.parent.controls.getSelected()
        activeTrajs = [
            t for t in self.getActiveTrajectories() if len(t.getPoints()) > 1
        ]
        for t in activeTrajs:
            recsize = 14
            s2 = recsize / 2
            gc.SetBrush(t.getBrush(trans=True))
            gc.SetPen(t.getPen(big=True))
            if len(t.getPoints()) >= 2:
                gc.DrawLines(t.getPoints())
            if t.getId() == selectedTraj:
                recsize = 14
                s2 = recsize / 2
                self.selected = t
                gc.SetPen(wx.Pen("#EEEEEE", width=2, style=wx.SOLID))
            if t.getFirstPoint() != None:
                # With midi triggering, it's possible to delete a trajectory in the
                # middle of this block. That raises an error: NoneType (t.circlePos)
                # object is not subscriptable.
                try:
                    gc.SetBrush(t.getBrush())
                    gc.DrawRoundedRectangle(t.getFirstPoint()[0] - s2,
                                            t.getFirstPoint()[1] - s2, recsize,
                                            recsize, 2)
                    dc.DrawLabel(
                        str(t.getLabel()),
                        wx.Rect(t.getFirstPoint()[0] - s2,
                                t.getFirstPoint()[1] - s2, recsize, recsize),
                        wx.ALIGN_CENTER)
                    if t.getType() in ['circle', 'oscil']:
                        gc.SetBrush(self.losaBrush)
                        gc.SetPen(self.losaPen)
                        gc.DrawRoundedRectangle(t.getLosangePoint()[0] - 5,
                                                t.getLosangePoint()[1] - 5, 10,
                                                10, 2)
                except:
                    pass
    def OnMotion(self, evt):
        if not self.HasCapture():
            return

        dc = wx.ClientDC(self)
        odc = wx.DCOverlay(self.overlay, dc)
        odc.Clear()
        ctx = wx.GraphicsContext_Create(dc)
        ctx.SetPen(wx.GREY_PEN)
        ctx.SetBrush(wx.Brush(wx.Color(192, 192, 192, 128)))
        ctx.DrawRectangle(*wx.RectPP(self.selectionStart, evt.Position))
        del odc
Exemple #7
0
    def OnPaint(self, evt):
        dc = wx.BufferedPaintDC(self)
        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        dc.Clear()
        dc.SetFont(wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT))

        gc = wx.GraphicsContext_Create(dc)

        if self.toggle_state and self.button.factory.toggle and \
                not self.button.factory.toggle_filename:
            self._draw_toggle(gc)

        # Put the icon in the middle of the alotted space. If the text is wider
        # than the icon, then the best_size will be wider, in which case we
        # want to put the icon in a little bit more towards the center,
        # otherwise, the icon will be drawn starting after the left padding.

        best_size = self.DoGetBestSize()
        x_offset = (best_size.width - self.button.factory.width) / 2.0
        y_offset = self.padding[1] / 2.0
        gc.Translate(x_offset, y_offset)
        gc.Scale(float(self.zoom_x) / 100, float(self.zoom_y) / 100)

        if self.toggle_state and self.button.factory.toggle and \
                self.button.factory.toggle_filename:
            self.toggle_document.render(gc)
            label_text = self.button.factory.toggle_label
        else:
            self.document.render(gc)
            label_text = self.button.factory.label

        # Reset the translation and zoom, then draw the text at an offset
        # based on the text width. There is a minor gotcha for supporting
        # multiple platforms here, Translate and DrawText behave differently
        # on different platforms.
        # It would be nice is a cross platform library actually worked the
        # same across platforms...

        text_width = dc.GetTextExtent(label_text)[0]
        text_x = (best_size.width - text_width) / 2.0
        text_y = self.button.factory.height
        gc.Scale(100 / float(self.zoom_x), 100 / float(self.zoom_y))

        if sys.platform == 'darwin':
            gc.Translate(-x_offset + text_x, -y_offset + text_y)
            dc.DrawText(label_text, 0, 0)
        else:
            gc.Translate(-x_offset, -y_offset)
            dc.DrawText(label_text, text_x, text_y)

        if not self.button.enabled:
            self._draw_disable_mask(gc)
Exemple #8
0
 def createKnobBitmap(self):
     b = wx.EmptyBitmap(10, self.knobSize)
     dc = wx.MemoryDC(b)
     gc = wx.GraphicsContext_Create(dc)
     dc.SetBackground(wx.Brush(self.backgroundColour))
     dc.Clear()
     gc.SetPen(wx.Pen("#444444"))
     gc.SetBrush(self.greybrush)
     p1 = (1, 1)
     p2 = (1, self.knobSize-1)
     p3 = (9, self.knobHalfSize)
     gc.DrawLines([p1,p2,p3])
     dc.SelectObject(wx.NullBitmap)
     self.knobBitmap = b
Exemple #9
0
    def onPaint(self, dc, buttonBitmap, disableButtonBitmap, selectedTrack,
                trackPosition):
        gc = wx.GraphicsContext_Create(dc)

        dc.SetFont(self.font)

        self.trackPosition = trackPosition

        # grid
        dc.SetPen(wx.Pen("#3F3F3F", 1))
        for i in range(1, self.rows + 1):
            y = TRACK_ROW_SIZE * i + self.trackPosition
            dc.DrawLine(27, y, 124, y)
            dc.DrawLine(127, y, MAX_WIDTH - 127, y)
        for i in range(1, MAX_WIDTH / (TRACK_COL_SIZE - 1)):
            x = i * TRACK_COL_SIZE + INPUTS_LINE_POS
            end = self.trackPosition + self.trackHeight
            dc.DrawLine(x, self.trackPosition, x, end)

        if self.id == selectedTrack:
            r = wx.Rect(1, self.trackPosition + 1, MAX_WIDTH - 2,
                        self.trackHeight - 2)
            gc.SetPen(wx.Pen("#BBBBBB", 1.5))
            gc.SetBrush(wx.Brush(TRACKS_BACKGROUND_COLOUR, wx.TRANSPARENT))
            gc.DrawRoundedRectangle(r[0], r[1], r[2], r[3], 3)

        dc.SetTextForeground("#FFFFFF")
        rect = wx.Rect(0, self.trackPosition, SELECTION_LINE_POS,
                       self.trackHeight)
        dc.DrawLabel(str(self.id), rect, wx.ALIGN_CENTER)

        dc.SetTextForeground(FXBOX_FOREGROUND_COLOUR)
        for i, inputBut in enumerate(self.buttonsInputs):
            rect = inputBut.getRect()
            gc.DrawBitmap(buttonBitmap, rect[0], rect[1], rect[2], rect[3])
            dc.DrawLabel(inputBut.name, rect, wx.ALIGN_CENTER)

        for i, button in enumerate(self.buttonsFxs):
            r = button.getRect()
            if button.getEnable():
                gc.DrawBitmap(buttonBitmap, r[0], r[1], r[2], r[3])
            else:
                gc.DrawBitmap(disableButtonBitmap, r[0], r[1], r[2], r[3])
            dc.DrawLabel(button.name, r, wx.ALIGN_CENTER)

        dc.SetPen(wx.Pen("#222222", 1))
        y = self.trackPosition + self.trackHeight
        dc.DrawLine(0, y, MAX_WIDTH, y)

        return self.trackHeight + self.trackPosition
Exemple #10
0
    def OnPaint(self, evt):
        start = time.time()
        dc = wx.BufferedPaintDC(self)
        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        dc.Clear()
        if not self.document:
            dc.DrawText("No Document", 20, 20)
            return
        gc = wx.GraphicsContext_Create(dc)

        gc.Translate(*self.offset)
        gc.Scale(float(self.zoom_x) / 100, float(self.zoom_y) / 100)

        self.document.render(gc)
        self.lastRender = time.time() - start
 def create_bitmap(self):
     size = tuple(self.GetSize())
     self.sndBitmap = wx.EmptyBitmap(size[0], size[1])
     memory = wx.MemoryDC()
     memory.SelectObject(self.sndBitmap)
     gc = wx.GraphicsContext_Create(memory)
     gc.SetPen(wx.Pen("#3F3F44"))
     gc.SetBrush(wx.Brush("#3F3F44", style=wx.TRANSPARENT))
     memory.SetBrush(wx.Brush(self.backgroundcolor))
     memory.DrawRectangle(0,0,size[0],size[1])
     for samples in self.list:
         if len(samples):
             gc.DrawLines(samples)
     memory.SelectObject(wx.NullBitmap)
     self.needBitmap = True
     self.Refresh()
    def OnMotion(self, evt):
        if not self.HasCapture():
            return

        dc = wx.ClientDC(self)
        odc = wx.DCOverlay(self.overlay, dc)
        odc.Clear()
        if 'phoenix' in wx.version():
            ctx = wx.GraphicsContext.Create(dc)
        else:
            ctx = wx.GraphicsContext_Create(dc)
        ctx.SetPen(wx.GREY_PEN)
        ctx.SetBrush(wx.Brush(wx.Colour(192, 192, 192, 128)))
        if 'phoenix' in wx.version():
            ctx.DrawRectangle(self.selectionStart[0], self.selectionStart[0],
                              evt.Position[0], evt.Position[1])
        else:
            ctx.DrawRectangle(*wx.RectPP(self.selectionStart, evt.Position))
        del odc
Exemple #13
0
 def createButtonBitmap(self, enable=True):
     w, h = BUTTON_WIDTH, BUTTON_HEIGHT
     b = wx.EmptyBitmap(w, h)
     dc = wx.MemoryDC(b)
     dc.SetPen(wx.Pen(TRACKS_BACKGROUND_COLOUR, 1))
     dc.SetBrush(wx.Brush(TRACKS_BACKGROUND_COLOUR))
     dc.DrawRectangle(0, 0, w, h)
     gc = wx.GraphicsContext_Create(dc)
     gc.SetPen(wx.Pen(FXBOX_OUTLINE_COLOUR, 1, wx.SOLID))
     if enable:
         gc.SetBrush(wx.Brush(FXBOX_ENABLE_BACKGROUND_COLOUR, wx.SOLID))
     else:
         gc.SetBrush(wx.Brush(FXBOX_DISABLE_BACKGROUND_COLOUR, wx.SOLID))
     rect = wx.Rect(0, 0, w, h)
     gc.DrawRoundedRectangle(rect[0], rect[1], rect[2], rect[3], 2)
     dc.SelectObject(wx.NullBitmap)
     if enable:
         self.buttonBitmap = b
     else:
         self.disableButtonBitmap = b
Exemple #14
0
 def CreateContext(self, target):
     ctx = wx.GraphicsContext_Create(target)
     ctx.SetPen(wx.BLACK_PEN)
     ctx.SetBrush(wx.RED_BRUSH)
     self.locals["context"] = ctx
     return ctx
Exemple #15
0
	def Draw(self, dc):
		size = self.GetClientSize()
		width = size.width
		height = size.height
		middle = min(width, height) // 2
		radius = middle * 0.9
		xCenter, yCenter = width//2, height//2
		
		backColour = self.GetBackgroundColour()
		backBrush = wx.Brush(backColour, wx.SOLID)
		dc.SetBackground(backBrush)
		dc.Clear()
		
		ctx = wx.GraphicsContext_Create(dc)
		
		rOutside = radius * 0.98
		rOutTicks = rOutside
		rInMinuteTicks = rOutTicks * 0.95
		rInHourTicks = rOutTicks * 0.9
		rHour = radius * 0.6
		rMinute = (rInMinuteTicks + rInHourTicks) / 2
		rSecond = rMinute
		rBack = -radius * 0.1
		rDot = rSecond * 0.85
		dotSize = rDot * 0.08

		wMinuteTicks = radius * 0.03
		wHourTicks = wMinuteTicks * 2.0
		
		wHourHand = wHourTicks * 1.5
		wMinuteHand = wHourTicks
		wSecondHand = wMinuteHand / 2.0
		
		tCos60Local = tCos60
		tSin60Local = tSin60
		penSecond = ctx.CreatePen( GetPen(width=wMinuteTicks, cap=wx.wx.CAP_BUTT) )
		penHour = ctx.CreatePen( GetPen(width=wHourTicks, cap=wx.wx.CAP_BUTT) )
		
		#-----------------------------------------------------------------------------
		# Draw the metal ring
		#
		r = radius * 1.0/0.9
		def drawCircle( x, y, r ):
			ctx.DrawEllipse( x - r, y - r, r * 2, r * 2 )
		
		ctx.SetBrush( ctx.CreateRadialGradientBrush(
						xCenter, yCenter - r,
						xCenter, yCenter - r,
						r * 2,
						wx.WHITE, wx.Colour(33,33,33) ) )
		drawCircle( xCenter, yCenter, r )
		
		rSmaller = r * 0.90
		ctx.SetBrush( ctx.CreateRadialGradientBrush(
						xCenter, yCenter + rSmaller,
						xCenter, yCenter + rSmaller,
						rSmaller * 2,
						wx.WHITE, wx.Colour(33,33,33) ) )
		drawCircle( xCenter, yCenter, rSmaller )
		
		#-----------------------------------------------------------------------------
		# Draw the CountdownClock face.
		#
		ctx.SetPen( penSecond )
		ctx.SetBrush( ctx.CreateRadialGradientBrush(
			xCenter, yCenter-radius*0.6, xCenter, yCenter, rOutside,
			wx.Colour(252,252,252), wx.Colour(220,220,220) ) )
		ctx.DrawEllipse( xCenter - rOutside, yCenter - rOutside, rOutside*2, rOutside*2 )

		penCur = None
		for i in xrange(60):
			if i % 5 == 0:
				rIn = rInHourTicks
				pen = penHour
			else:
				rIn = rInMinuteTicks
				pen = penSecond
			if pen is not penCur:
				penCur = pen
				ctx.SetPen( pen )
			ctx.StrokeLine(
				xCenter + rIn * tCos60Local[i], yCenter + rIn * tSin60Local[i],
				xCenter + rOutTicks * tCos60Local[i], yCenter + rOutTicks * tSin60Local[i]
			)
			
		
		if self.tFuture is None:
			return
			
		dt = self.tFuture - self.tCur
		dSeconds = dt.total_seconds()

		#-----------------------------------------------------------------------------
		# Draw the digital CountdownClock.
		#
		tt = int(max(dSeconds,0.0) + 0.999)
		hour = tt // 3600
		minute = (tt // 60) % 60
		second = tt % 60
		
		ctx.SetFont( ctx.CreateFont(
			wx.FontFromPixelSize(
				(0,radius*0.37),
				wx.FONTFAMILY_SWISS,
				wx.FONTSTYLE_NORMAL,
				wx.FONTWEIGHT_NORMAL,
			),
			wx.Colour(100,100,100)) )
		tStr = u'{}:{:02d}:{:02d}'.format( hour, minute, second )
		w, h = ctx.GetTextExtent(u'00:00:00'[:len(tStr)])
		ctx.DrawText( tStr, xCenter-w/2, yCenter+radius/2-h )
		
		#-----------------------------------------------------------------------------
		# Draw the hands.
		#
		tt = int(max(dSeconds,0.0))
		hour = tt // 3600
		minute = (tt // 60) % 60
		second = tt % 60
		secondPos = (second  + math.modf(dSeconds)[0]) / 60.0
		minutePos = (minute + secondPos) / 60.0
		hourPos = (hour % 12 + minutePos) / 12.0
		
		if hour > 1.0:
			ctx.SetPen( ctx.CreatePen( GetPen(colour=wx.Colour(0,0,180,128), width=wHourHand) ) )
			cosCur = GetCos(hourPos)
			sinCur = GetSin(hourPos)
			ctx.StrokeLine(
				xCenter + rBack * cosCur, yCenter + rBack * sinCur,
				xCenter + rHour * cosCur, yCenter + rHour * sinCur
			)
		ctx.SetPen( ctx.CreatePen( GetPen(colour=wx.Colour(0,150,0,128), width=wMinuteHand) ) )
		cosCur = GetCos(minutePos)
		sinCur = GetSin(minutePos)
		ctx.StrokeLine(
			xCenter + rBack * cosCur,   yCenter + rBack * sinCur,
			xCenter + rMinute * cosCur, yCenter + rMinute * sinCur
		)
		ctx.SetPen( ctx.CreatePen( GetPen(colour=wx.RED,width=wSecondHand) ) )
		ctx.SetBrush( ctx.CreateBrush(wx.Brush(wx.RED)) )
		cosCur = GetCos(secondPos)
		sinCur = GetSin(secondPos)
		ctx.StrokeLine(
			xCenter + rDot * cosCur,    yCenter + rDot * sinCur,
			xCenter + rMinute * cosCur, yCenter + rMinute * sinCur
		)
		xDot = xCenter + rDot * cosCur
		yDot = yCenter + rDot * sinCur
		ctx.DrawEllipse( xDot - dotSize, yDot - dotSize, dotSize*2, dotSize*2 )
Exemple #16
0
    def OnPaint(self, evt):
        w,h = self.GetSize()
        dc = self.dcref(self)
        gc = wx.GraphicsContext_Create(dc)

        dc.Clear()
        gc.SetBrush(wx.Brush(self.backColour, wx.SOLID))

        # Draw background
        gc.SetPen(wx.Pen("#777777", width=self.borderWidth, style=wx.SOLID))
        gc.DrawRoundedRectangle(0, 0, w-1, h-1, 3)

        dc.SetFont(wx.Font(8, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL,
                           wx.FONTWEIGHT_NORMAL))
        dc.SetTextForeground(CONTROLSLIDER_TEXT_COLOUR)

        # Draw text label
        reclab = wx.Rect(0, 1, w, 9)
        dc.DrawLabel(self.label, reclab, wx.ALIGN_CENTER_HORIZONTAL)

        # Draw knob handle
        val = tFromValue(self.value, self.minvalue, self.maxvalue) * 0.8
        ph = val * 6.2831853072 - 4.2839899822 # (3 * math.pi / 2.2)
        X = math.cos(ph) * 14.23025 # math.sqrt(.1) * 45
        Y = math.sin(ph) * 14.23025
        gc.SetBrush(wx.Brush(self.knobColour, wx.SOLID))
        gc.SetPen(wx.Pen(self.colours[self.mode], width=2, style=wx.SOLID))
        self.knobPointPos = (X+25, Y+35)
        R = math.sqrt(X*X + Y*Y)
        gc.DrawEllipse(25-R, 35-R, R*2, R*2)
        gc.StrokeLine(25, 35, X+25, Y+35)

        dc.SetFont(wx.Font(CONTROLSLIDER_FONT, wx.FONTFAMILY_SWISS,
                           wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))

        # Highlight text for keyboard input
        if self.selected:
            gc.SetBrush(wx.Brush(CONTROLSLIDER_SELECTED_COLOUR, wx.SOLID))
            gc.SetPen(wx.Pen(CONTROLSLIDER_SELECTED_COLOUR, self.borderWidth))
            gc.DrawRoundedRectangle(2, 55, w-4, 12, 2)

        # Draw text value
        if self.selected and self.new:
            val = self.new
        else:
            if self.integer:
                val = '%d' % self.GetValue()
            else:
                val = self.floatPrecision % self.GetValue()
        dc.SetTextForeground(CONTROLSLIDER_TEXT_COLOUR)
        dc.DrawLabel(val, wx.Rect(0, 55, w, 14), wx.ALIGN_CENTER)

        # Midi ctl and automation window handle
        if self.drawBottomPart:
            dc.SetFont(wx.Font(CONTROLSLIDER_FONT, wx.FONTFAMILY_SWISS,
                               wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
            if self.midictl is not None:
                dc.DrawLabel("M : %d" % self.midictl, wx.Rect(5, 72, 41, 11),
                             wx.ALIGN_CENTER_VERTICAL)
            else:
                dc.DrawLabel("M :...", wx.Rect(5, 72, 41, 11),
                             wx.ALIGN_CENTER_VERTICAL)

            if self.autoPlay:
                gc.SetBrush(wx.Brush("#55DD55"))
            else:
                gc.SetBrush(wx.Brush("#333333", wx.TRANSPARENT))
            if self.showEdit:
                tri = [(w-14,72), (w-6,72), (w-10,80), (w-14,72)]
            else:
                tri = [(w-14,72), (w-14,80), (w-6,76), (w-14, 72)]
            gc.SetPen(wx.Pen("#333333", 1.5))
            gc.DrawLines(tri)

        evt.Skip()
Exemple #17
0
    def Draw(self, dc):
        size = self.GetClientSize()
        width = size.width
        height = size.height

        backColour = self.GetBackgroundColour()
        backBrush = wx.Brush(backColour, wx.SOLID)
        dc.SetBackground(backBrush)
        dc.Clear()

        if not self.data or width < 50 or height < 50:
            return

        ctx = wx.GraphicsContext_Create(dc)

        textWidth, textHeight = dc.GetTextExtent('00:00' if self.dataMax < 60 *
                                                 60 else '00:00:00')

        if len(self.data) == 1:
            colours = [wx.Colour(0, 0, 255, 1.0)]
        else:
            colours = [
                wx.Colour(255, 0, 0),
                wx.Colour(0, 255, 0),
                wx.Colour(0, 0, 255),
                wx.Colour(255, 255, 0),
                wx.Colour(255, 0, 255),
                wx.Colour(0, 255, 255),
                wx.Colour(0, 0, 0)
            ]
            if len(self.data) < len(colours):
                colours = colours[:len(self.data)]
            colours.reverse()

        drawLabels = False
        legendLength = 30  # Length of the legend lines
        legendSep = 10  # Separations between legend entries
        legendLabelSep = 4  # Separation between legend line and label
        if self.labels:
            labelsWidth = sum(legendLength + legendSep + legendLabelSep +
                              dc.GetTextExtent(lab)[0] for lab in self.labels)
            if labelsWidth <= width - 8:
                drawLabels = True

        xLeft = textWidth + 4
        xRight = width - 8
        yBottom = height - (textHeight + 8) * (2 if drawLabels else 1)
        yTop = textHeight + 8

        thick = int((xRight - xLeft) / float(max(1, self.seriesMax - 1)))
        dataMaxRange = self.dataMax * 1.05
        dataMinRange = 0 if self.startAtZero else self.dataMin * 0.95
        dFactor = float(yBottom - yTop) / (dataMaxRange - dataMinRange)

        # Draw the legend.
        if drawLabels:
            x, y = xRight, height - textHeight - 4
            for i, lab in enumerate(self.labels):
                pen = wx.Pen(colours[i % len(colours)], 6)
                pen.SetCap(wx.CAP_BUTT)
                dc.SetPen(pen)
                w, h = dc.GetTextExtent(lab)
                x -= w
                dc.DrawText(lab, x, y)
                x -= legendLength + legendLabelSep
                dc.DrawLine(x, y + textHeight / 2, x + legendLength,
                            y + textHeight / 2)
                x -= legendSep

        # Draw the lap labels and vertical lines.
        dc.SetPen(wx.Pen('light gray', 1))
        # Find some reasonable tickmarks.
        numLabels = float(xRight - xLeft) / (
            dc.GetTextExtent('{}'.format(self.seriesMax))[0] * 1.5)
        d = self.seriesMax / numLabels
        intervals = [1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500]
        d = intervals[bisect.bisect_left(intervals, d, 0, len(intervals) - 1)]
        for i in xrange(d - 1, self.seriesMax, d):
            x = xLeft + i * thick
            dc.DrawLine(x, yBottom + 2, x, yTop)
            s = '{}'.format(i + 1)
            w, h = dc.GetTextExtent(s)
            dc.DrawText(s, x - w / 2, yBottom + 4)
            dc.DrawText(s, x - w / 2, 0 + 4)

        # Draw the horizontal lines.
        # Find some reasonable tickmarks.
        dc.SetPen(wx.Pen('light gray', 1))
        numLabels = max(float(yBottom - yTop) / (textHeight * 3), 1)
        d = (dataMaxRange - dataMinRange) / numLabels
        intervals = [
            1, 2, 5, 10, 15, 30, 1 * 60, 2 * 60, 5 * 60, 10 * 60, 15 * 60,
            20 * 60, 30 * 60, 1 * 60 * 60, 2 * 60 * 60, 4 * 60 * 60,
            8 * 60 * 60, 24 * 60 * 60
        ]
        d = intervals[bisect.bisect_left(intervals, d, 0, len(intervals) - 1)]

        for t in xrange(
                int(dataMinRange) - int(dataMinRange % d),
                int(dataMaxRange * 2), d):
            y = yBottom - (t - dataMinRange) * dFactor
            if y > yBottom:
                continue
            if y < yTop:
                break
            if t < 60 * 60:
                s = '%d:%02d' % ((t / 60), t % 60)
            else:
                s = '%d:%02d:%02d' % (t / (60 * 60), (t / 60) % 60, t % 60)
            w, h = dc.GetTextExtent(s)
            dc.DrawText(s, textWidth - w, y - textHeight / 2 - 2)
            dc.DrawLine(xLeft - 3, y, xRight, y)

        # Draw the baseline
        dc.SetPen(wx.Pen('black', 2))
        dc.DrawLine(xLeft, yBottom, xRight, yBottom)
        dc.DrawLine(xLeft, yBottom, xLeft, yTop)

        # Define a path for the indicator about the origin.
        radius = 12
        ctx.SetPen(wx.Pen(wx.Colour(128, 128, 128), 1))
        ctx.SetBrush(
            ctx.CreateRadialGradientBrush(0, -radius * 0.50, 0, 0, radius + 1,
                                          wx.WHITE, wx.Colour(220, 220, 0)))
        path = ctx.CreatePath()
        path.MoveToPoint(0, -radius)
        path.AddLineToPoint(-radius, 0)
        path.AddLineToPoint(0, radius)
        path.AddLineToPoint(radius, 0)
        path.AddLineToPoint(0, -radius)

        # Draw the data lines.
        for i, s in enumerate(self.data):
            pen = wx.Pen(colours[i % len(colours)], 6)
            pen.SetCap(wx.CAP_ROUND)
            dc.SetPen(pen)
            points = []
            x = xLeft
            for d in s:
                y = yBottom - (d - dataMinRange) * dFactor
                points.append(wx.Point(x, y))
                x += thick
            if points:
                dc.DrawLines(points)

            # Draw indicators for interpolated values.
            ctx.SetPen(wx.Pen(wx.Colour(128, 128, 128), 1))
            for j, p in enumerate(points):
                if self.interpolated[i][j]:
                    ctx.PushState()
                    ctx.Translate(*p)
                    ctx.DrawPath(path)
                    ctx.PopState()
Exemple #18
0
    def Draw(self, dc):
        size = self.GetClientSize()
        width = size.width
        height = size.height

        backColour = self.GetBackgroundColour()
        backBrush = wx.Brush(backColour, wx.SOLID)
        backPen = wx.Pen(backColour, 0)
        dc.SetBackground(backBrush)
        dc.Clear()

        render = wx.RendererNative.Get()

        tooSmall = (width < 50 or height < 24)

        def drawTooSmall():
            dc.SetPen(wx.BLACK_DASHED_PEN)
            dc.DrawLine(0, height // 2, width, height // 2)

        if not self.raceTimes or not self.raceTimes[0] or len(
                self.raceTimes[0]) < 4 or tooSmall:
            self.empty = True
            if tooSmall:
                drawTooSmall()
            self.resetDimensions()
            return
        self.empty = False

        hudHeight = self.hudHeight = min(height / len(self.raceTimes), 80)

        legendHeight = max(hudHeight / 4, 10)
        fontLegend = wx.FontFromPixelSize(wx.Size(0, legendHeight),
                                          wx.FONTFAMILY_SWISS,
                                          wx.FONTSTYLE_NORMAL,
                                          wx.FONTWEIGHT_NORMAL)
        dc.SetFont(fontLegend)
        textWidth, textHeight = dc.GetTextExtent(u'1:00:00')
        broomTimeWidth = textWidth

        tickHeight = (hudHeight - textHeight * 2) / 2
        if tickHeight < 2:
            self.empty = True
            drawTooSmall()
            return

        raceTimeHeight = tickHeight * 2 * 0.6
        fontRaceTime = wx.FontFromPixelSize(wx.Size(0, raceTimeHeight),
                                            wx.FONTFAMILY_SWISS,
                                            wx.FONTSTYLE_NORMAL,
                                            wx.FONTWEIGHT_NORMAL)
        dc.SetFont(fontRaceTime)
        textWidth, textHeight = dc.GetTextExtent(u'0')
        zeroCharWidth = textWidth
        textWidth = max(
            dc.GetTextExtent(u'{}'.format(ldr))[0] for ldr in self.leader)
        textWidth = max(textWidth, int(self.checkeredFlag.GetWidth() * 1.2))
        textWidth += dc.GetTextExtent(u'  ')[0]

        dy = int(tickHeight * 2 * 0.75)

        labelsWidth = textWidth
        xLeft = self.xLeft = labelsWidth
        xRight = self.xRight = width - max(self.broom.GetWidth(),
                                           broomTimeWidth)
        if xRight - xLeft < 16:
            self.empty = True
            drawTooSmall()
            return

        xMult = self.xMult = (xRight - xLeft) / float(
            max(rt[-1] if rt else 0 for rt in self.raceTimes))

        yTop = 0
        for iRaceTimes, (leader, raceTimes) in enumerate(
                zip(self.leader, self.raceTimes)):
            if not raceTimes:
                continue

            nowTime = min((self.nowTime or raceTimes[-1]), raceTimes[-1])

            # Draw the legend.
            dc.SetFont(fontLegend)
            textWidth, textHeight = dc.GetTextExtent(u'0:00:00')
            hMiddle = textHeight + tickHeight
            dc.DrawLine(xLeft, yTop + hMiddle, xLeft + raceTimes[-1] * xMult,
                        yTop + hMiddle)
            dc.DrawLine(xLeft, yTop + hMiddle - tickHeight, xLeft,
                        yTop + hMiddle + tickHeight)

            lapMax = len(raceTimes) - 2
            xTextRight = 10000000
            for i in xrange(len(raceTimes) - 1, -1, -1):
                t = raceTimes[i]
                x = xLeft + int(t * xMult)
                dc.DrawLine(x, yTop + hMiddle - tickHeight, x,
                            yTop + hMiddle + tickHeight)
                if t != raceTimes[-1]:
                    n = '{}'.format(lapMax - i)
                    textWidth, textHeight = dc.GetTextExtent(n)
                    xTextNew = x - textWidth // 2
                    if xTextNew + textWidth <= xTextRight:
                        dc.DrawText(n, xTextNew, yTop + hMiddle + tickHeight)
                        xTextRight = xTextNew - zeroCharWidth // 3

            # Draw the progress bar.
            transparentBrush = wx.Brush(wx.WHITE, style=wx.TRANSPARENT)
            ctx = wx.GraphicsContext_Create(dc)
            ctx.SetPen(wx.Pen(wx.WHITE, 1, style=wx.TRANSPARENT))
            dd = int(dy * 0.3)

            yCur = int(hMiddle - dy / 2)
            xCur = (nowTime - raceTimes[0]) * xMult
            xStart = raceTimes[0] * xMult + xLeft
            b1 = ctx.CreateLinearGradientBrush(0, yTop + yCur, 0,
                                               yTop + yCur + dd + 1,
                                               self.colour, self.lighterColour)
            b2 = ctx.CreateLinearGradientBrush(0, yTop + yCur + dd, 0,
                                               yTop + yCur + dy,
                                               self.lighterColour, self.colour)
            ctx.SetBrush(b1)
            ctx.DrawRectangle(xStart, yTop + yCur, xCur, dd + 1)

            ctx.SetBrush(b2)
            ctx.DrawRectangle(xStart, yTop + yCur + dd, xCur, dy - dd)

            # Draw an outline around the progress bar.
            ctx.SetPen(wx.Pen(wx.Colour(128, 128, 128)))
            ctx.SetBrush(wx.TRANSPARENT_BRUSH)
            ctx.DrawRectangle(xStart, yTop + hMiddle - dy / 2, xCur, dy)

            # Draw checkered flag
            dc.SetFont(fontLegend)
            t = raceTimes[-2]
            tCur = Utils.formatTime(t)
            textWidth, textHeight = dc.GetTextExtent(tCur)
            x = xLeft + int(t * xMult)
            dc.DrawBitmap(self.checkeredFlag,
                          x - self.checkeredFlag.GetWidth() - 1,
                          yTop + hMiddle - self.checkeredFlag.GetHeight() // 2,
                          False)
            dc.DrawText(tCur, x - textWidth - textHeight / 8,
                        yTop + hMiddle - tickHeight - textHeight)

            # Draw broom.
            t = raceTimes[-1]
            tCur = Utils.formatTime(t)
            textWidth, textHeight = dc.GetTextExtent(tCur)
            x = xLeft + int(t * xMult)
            dc.DrawBitmap(self.broom, x + 3,
                          yTop + hMiddle - self.broom.GetHeight() // 2, False)
            dc.DrawText(tCur, x + textHeight / 8,
                        yTop + hMiddle - tickHeight - textHeight)

            # Draw indicator for the finish time.
            iRadius = dy / 3
            x = xLeft + int(raceTimes[-2] * xMult)
            ctx.SetBrush(wx.Brush(wx.Colour(0, 255, 0)))
            ctx.DrawEllipse(x - iRadius / 2,
                            yTop + hMiddle - tickHeight - iRadius / 4, iRadius,
                            iRadius)

            # Draw indicator for the last rider on course.
            x = xLeft + int(raceTimes[-1] * xMult)
            ctx.SetBrush(wx.Brush(wx.Colour(255, 0, 0)))
            ctx.DrawEllipse(x - iRadius / 2,
                            yTop + hMiddle - tickHeight - iRadius / 4, iRadius,
                            iRadius)

            ctx.SetPen(wx.BLACK_PEN)

            # Draw the time to the leader's next lap (or the broom if the race is over).
            dc.SetFont(fontRaceTime)
            nextLap = bisect.bisect_left(raceTimes, nowTime)
            if nextLap < len(raceTimes):
                t = raceTimes[nextLap] - nowTime
                tToLeader = t
                tCur = Utils.formatTime(t)
                if tCur[0] == '0':
                    tCur = tCur[1:]
                textWidth, textHeight = dc.GetTextExtent(tCur)
                t = nowTime
                x = xLeft + int(t * xMult)
                x = max(x - textWidth - textHeight / 8, xLeft + 2)
                dc.DrawText(tCur, x, yTop + hMiddle - textHeight / 2)

                if (nextLap == len(raceTimes)-2 and tToLeader > 15) or \
                 (nextLap == len(raceTimes)-3 and tToLeader < 15):
                    x -= self.bell.GetWidth() + textHeight / 8
                    if x >= xLeft:
                        dc.DrawBitmap(
                            self.bell, x,
                            yTop + hMiddle - self.bell.GetHeight() / 2)

            # Draw the leader.
            if leader is not None:
                leaderText = '{}'.format(leader)
                dc.SetFont(fontLegend
                           if legendHeight > raceTimeHeight else fontRaceTime)
                textWidth, textHeight = dc.GetTextExtent(leaderText)
                dc.DrawText(leaderText, xLeft - textWidth - textHeight / 8,
                            yTop + hMiddle - textHeight / 2)

            yTop += hudHeight

        if self.iRaceTimesHover is not None and self.lapInfoFunc:
            yTop = 0
            for iRaceTimes, (leader, raceTimes) in enumerate(
                    zip(self.leader, self.raceTimes)):
                if not raceTimes:
                    continue
                if iRaceTimes == self.iRaceTimesHover:
                    tCur, tNext = raceTimes[self.iLapHover - 1:self.iLapHover +
                                            1]
                    info = self.lapInfoFunc(self.iLapHover,
                                            len(raceTimes) - 2, tCur, tNext,
                                            leader)
                    hoverLineHeight = min(20, max(16, hudHeight // len(info)))
                    fontHover = wx.FontFromPixelSize(
                        wx.Size(0, int(hoverLineHeight * 0.85)),
                        wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL,
                        wx.FONTWEIGHT_NORMAL)
                    dc.SetFont(fontHover)
                    labelHoverWidth = max(
                        dc.GetTextExtent(label)[0] for label, value in info)
                    valueHoverWidth = max(
                        dc.GetTextExtent(value)[0] for label, value in info)
                    hoverBorderHeight = dc.GetTextExtent(u'  ')[1] // 3
                    hoverBorderWidth = dc.GetTextExtent(u'  ')[0]
                    hoverWidth = labelHoverWidth + valueHoverWidth + dc.GetTextExtent(
                        u' ')[0]
                    hoverHeight = hoverLineHeight * len(info)
                    xHover = xLeft + int(tCur * xMult) - hoverWidth
                    if xHover < 0:
                        xHover = 0
                    yHover = yTop + (hudHeight -
                                     hoverHeight) // 2 - hoverBorderHeight
                    if yHover < 0:
                        yHover = 0
                    elif yHover + hoverHeight + hoverBorderHeight * 2 > height:
                        yHover = height - hoverHeight + hoverBorderHeight * 2
                    dc.SetBrush(wx.WHITE_BRUSH)
                    render.DrawPushButton(
                        self, dc,
                        (xHover - hoverBorderWidth, yHover - hoverBorderHeight,
                         hoverWidth + hoverBorderWidth * 2,
                         hoverHeight + hoverBorderHeight * 2),
                        wx.CONTROL_ISDEFAULT)
                    for label, value in info:
                        dc.DrawText(
                            label, xHover + labelHoverWidth -
                            dc.GetTextExtent(label)[0], yHover)
                        dc.DrawText(value,
                                    xHover + hoverWidth - valueHoverWidth,
                                    yHover)
                        yHover += hoverLineHeight
                yTop += hudHeight
Exemple #19
0
    def Draw(self, dc):
        size = self.GetClientSize()
        width = size.width
        height = size.height

        backColour = self.GetBackgroundColour()
        backBrush = wx.Brush(backColour, wx.SOLID)
        backPen = wx.Pen(backColour, 0)
        dc.SetBackground(backBrush)
        dc.Clear()

        if not self.data or self.dataMax == 0 or width < 50 or height < 50:
            self.empty = True
            return

        self.empty = False

        barHeight = int(float(height) / float(len(self.data) + 2))
        if barHeight < 4:
            self.empty = True
            return
        barHeight = min(barHeight, 40)

        font = wx.FontFromPixelSize(wx.Size(0, barHeight - 1),
                                    wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL,
                                    wx.FONTWEIGHT_NORMAL)
        dc.SetFont(font)
        textWidthLeftMax, textHeightMax = dc.GetTextExtent('0000')
        if not self.showLabels:
            textWidthLeftMax /= 2
        textWidthRightMax = textWidthLeftMax
        if self.showLabels:
            for label in self.labels:
                textWidthLeftMax = max(textWidthLeftMax,
                                       dc.GetTextExtent(label)[0])
                textWidthRightMax = max(
                    textWidthRightMax,
                    dc.GetTextExtent('{}'.format(numFromLabel(label)))[0])

        if self.showLabels:
            legendSep = 4  # Separations between legend entries and the Gantt bars.
        else:
            legendSep = 0
        labelsWidthLeft = textWidthLeftMax + legendSep
        labelsWidthRight = textWidthRightMax + legendSep
        drawLabels = self.showLabels

        if labelsWidthLeft > width / 2:
            labelsWidthLeft = 0
            labelsWidthRight = 0
            drawLabels = False

        xLeft = labelsWidthLeft
        xRight = width - labelsWidthRight
        yBottom = barHeight * (len(self.data) + 1)
        yTop = barHeight

        fontLegend = wx.FontFromPixelSize(wx.Size(0, barHeight * .75),
                                          wx.FONTFAMILY_SWISS,
                                          wx.FONTSTYLE_NORMAL,
                                          wx.FONTWEIGHT_NORMAL)
        dc.SetFont(fontLegend)
        textWidth, textHeight = dc.GetTextExtent('00:00' if self.dataMax < 60 *
                                                 60 else '00:00:00')

        # Draw the horizontal labels.
        # Find some reasonable tickmarks for the x axis.
        numLabels = (xRight - xLeft) / (textWidth * 1.5)
        d = self.dataMax / float(numLabels)
        intervals = [
            1, 2, 5, 10, 15, 20, 30, 1 * 60, 2 * 60, 5 * 60, 10 * 60, 15 * 60,
            20 * 60, 30 * 60, 1 * 60 * 60, 2 * 60 * 60, 4 * 60 * 60,
            8 * 60 * 60, 12 * 60 * 60, 24 * 60 * 60
        ]
        d = intervals[bisect.bisect_left(intervals, d, 0, len(intervals) - 1)]
        dFactor = (xRight - xLeft) / float(self.dataMax)
        dc.SetPen(wx.Pen(wx.BLACK, 1))
        for t in xrange(0, int(self.dataMax), d):
            x = xLeft + t * dFactor
            if t < 60 * 60:
                s = '%d:%02d' % ((t / 60), t % 60)
            else:
                s = '%d:%02d:%02d' % (t / (60 * 60), (t / 60) % 60, t % 60)
            w, h = dc.GetTextExtent(s)
            dc.DrawText(s, x - w / 2, 0 + 4)
            if not self.minimizeLabels:
                dc.DrawText(s, x - w / 2, yBottom + 4)
            dc.DrawLine(x, yBottom + 3, x, yTop - 3)

        # Draw the Gantt chart.
        dc.SetFont(font)
        textWidth, textHeight = dc.GetTextExtent('0000')

        penBar = wx.Pen(wx.Colour(128, 128, 128), 1)
        penBar.SetCap(wx.CAP_BUTT)
        penBar.SetJoin(wx.JOIN_MITER)
        dc.SetPen(penBar)

        brushBar = wx.Brush(wx.BLACK)
        transparentBrush = wx.Brush(wx.WHITE, style=wx.TRANSPARENT)

        ctx = wx.GraphicsContext_Create(dc)
        ctx.SetPen(wx.Pen(wx.BLACK, 1))

        xyInterp = []
        xyDuplicate = []

        xFactor = float(width - labelsWidthLeft - labelsWidthRight) / float(
            self.dataMax)
        yLast = barHeight
        yHighlight = None
        for i, s in enumerate(self.data):
            yCur = yLast + barHeight
            xLast = labelsWidthLeft
            xCur = xLast
            tTooShort = (s[-1] / len(s)) / 10.0 if s else 0.0
            tLast = None
            for j, t in enumerate(s):
                xCur = int(labelsWidthLeft + t * xFactor)
                if j == 0:
                    brushBar.SetColour(wx.WHITE)
                    dc.SetBrush(brushBar)
                    dc.DrawRectangle(xLast, yLast, xCur - xLast + 1,
                                     yCur - yLast + 1)
                else:
                    ctx.SetPen(wx.Pen(wx.WHITE, 1, style=wx.TRANSPARENT))
                    dy = yCur - yLast + 1
                    dd = int(dy * 0.3)
                    ic = j % len(self.colours)

                    b1 = ctx.CreateLinearGradientBrush(0, yLast, 0,
                                                       yLast + dd + 1,
                                                       self.colours[ic],
                                                       self.lighterColours[ic])
                    ctx.SetBrush(b1)
                    ctx.DrawRectangle(xLast, yLast, xCur - xLast + 1, dd + 1)

                    b2 = ctx.CreateLinearGradientBrush(0, yLast + dd, 0,
                                                       yLast + dy,
                                                       self.lighterColours[ic],
                                                       self.colours[ic])
                    ctx.SetBrush(b2)
                    ctx.DrawRectangle(xLast, yLast + dd, xCur - xLast + 1,
                                      dy - dd)

                    dc.SetBrush(transparentBrush)
                    dc.SetPen(penBar)
                    dc.DrawRectangle(xLast, yLast, xCur - xLast + 1, dy)

                    try:
                        if self.interp[i][j]:
                            xyInterp.append((xCur, yLast))
                    except (TypeError, IndexError):
                        pass
                    if t - tLast < tTooShort:
                        xyDuplicate.append((xCur, yLast))

                xLast = xCur
                tLast = t

            # Draw the last empty bar.
            xCur = int(labelsWidthLeft + self.dataMax * xFactor)
            dc.SetPen(penBar)
            brushBar.SetColour(wx.WHITE)
            dc.SetBrush(brushBar)
            dc.DrawRectangle(xLast, yLast, xCur - xLast + 1, yCur - yLast + 1)

            # Draw the label on both ends.
            if self.showLabels:
                labelWidth = dc.GetTextExtent(self.labels[i])[0]
                dc.DrawText(self.labels[i], textWidthLeftMax - labelWidth,
                            yLast)
                if not self.minimizeLabels:
                    label = self.labels[i]
                    lastSpace = label.rfind(' ')
                    if lastSpace > 0:
                        label = label[lastSpace + 1:]
                    dc.DrawText(label, width - labelsWidthRight + legendSep,
                                yLast)

            if u'{}'.format(self.numSelect) == u'{}'.format(
                    numFromLabel(self.labels[i])):
                yHighlight = yCur

            yLast = yCur

        if yHighlight is not None and len(self.data) > 1:
            dc.SetPen(wx.Pen(wx.BLACK, 2))
            dc.SetBrush(wx.TRANSPARENT_BRUSH)
            dc.DrawLine(0, yHighlight, width, yHighlight)
            yHighlight -= barHeight
            dc.DrawLine(0, yHighlight, width, yHighlight)

        # Draw indicators for interpolated values.
        radius = (dy / 2) * 0.9

        if xyInterp:
            # Define a path for the indicator about the origin.
            ctx.SetPen(penBar)
            ctx.SetBrush(
                ctx.CreateRadialGradientBrush(0, -radius * 0.50, 0, 0,
                                              radius + 1, wx.WHITE,
                                              wx.Colour(220, 220, 0)))
            path = ctx.CreatePath()
            path.MoveToPoint(0, -radius)
            path.AddLineToPoint(-radius, 0)
            path.AddLineToPoint(0, radius)
            path.AddLineToPoint(radius, 0)
            path.AddLineToPoint(0, -radius)

            # Draw the interp indicators.
            for xCur, yCur in xyInterp:
                ctx.PushState()
                ctx.Translate(xCur, yCur + dy / 2.0 - (dy / 2.0 - radius) / 4)
                ctx.DrawPath(path)
                ctx.PopState()

        if xyDuplicate:
            # Draw the duplicate indicators.
            radius *= 1.3
            ctx.SetPen(wx.Pen(wx.RED, 3))
            ctx.SetBrush(wx.TRANSPARENT_BRUSH)
            for xCur, yCur in xyDuplicate:
                ctx.DrawEllipse(xCur - radius, yCur + dy / 2.0 - radius,
                                radius * 2, radius * 2)

        # Draw the now timeline.
        if self.nowTime and self.nowTime < self.dataMax:
            nowTimeStr = Utils.formatTime(self.nowTime)
            labelWidth, labelHeight = dc.GetTextExtent(nowTimeStr)
            x = int(labelsWidthLeft + self.nowTime * xFactor)

            ntColour = '#339966'
            dc.SetPen(wx.Pen(ntColour, 6))
            dc.DrawLine(x, barHeight - 4, x, yLast + 4)
            dc.SetPen(wx.Pen(wx.WHITE, 2))
            dc.DrawLine(x, barHeight - 4, x, yLast + 4)

            dc.SetBrush(wx.Brush(ntColour))
            dc.SetPen(wx.Pen(ntColour, 1))
            rect = wx.Rect(x - labelWidth / 2 - 2, 0, labelWidth + 4,
                           labelHeight)
            dc.DrawRectangleRect(rect)
            if not self.minimizeLabels:
                rect.SetY(yLast + 2)
                dc.DrawRectangleRect(rect)

            dc.SetTextForeground(wx.WHITE)
            dc.DrawText(nowTimeStr, x - labelWidth / 2, 0)
            if not self.minimizeLabels:
                dc.DrawText(nowTimeStr, x - labelWidth / 2, yLast + 2)

        self.xFactor = xFactor
        self.barHeight = barHeight
        self.labelsWidthLeft = labelsWidthLeft
Exemple #20
0
    def OnPaint(self, evt):
        # TODO: Drawing of the controlKnob must really be optimized
        w,h = self.GetSize()
        dc = self.dcref(self)
        gc = wx.GraphicsContext_Create(dc)

        if self._enable:
            backColour = self.backColour
            knobColour = CONTROLSLIDER_KNOB_COLOUR
        else:
            backColour = CONTROLSLIDER_DISABLE_BACK_COLOUR
            knobColour = CONTROLSLIDER_DISABLE_KNOB_COLOUR

        dc.Clear()
        gc.SetBrush(wx.Brush(backColour, wx.SOLID))

        # Draw background
        gc.SetPen(wx.Pen("#777777", width=self.borderWidth, style=wx.SOLID))
        gc.DrawRoundedRectangle(0, 0, w-1, h-1, 3)

        dc.SetFont(wx.Font(9, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                           wx.FONTWEIGHT_NORMAL, face=FONT_FACE))
        dc.SetTextForeground(CONTROLSLIDER_TEXT_COLOUR)

        # Draw text label
        reclab = wx.Rect(0, 1, w, 9)
        dc.DrawLabel(self.label, reclab, wx.ALIGN_CENTER_HORIZONTAL)

        recval = wx.Rect(0, 55, w, 14)

        if self.selected:
            gc.SetBrush(wx.Brush(CONTROLSLIDER_SELECTED_COLOUR, wx.SOLID))
            gc.SetPen(wx.Pen(CONTROLSLIDER_SELECTED_COLOUR, self.borderWidth))
            gc.DrawRoundedRectangle(2, 55, w-4, 12, 2)

        r = math.sqrt(.1)
        val = tFromValue(self.value, self.minvalue, self.maxvalue) * 0.8
        ph = val * math.pi * 2 - (3 * math.pi / 2.2)
        X = r * math.cos(ph)*45
        Y = r * math.sin(ph)*45
        gc.SetBrush(wx.Brush(knobColour, wx.SOLID))
        gc.SetPen(wx.Pen(self.colours[self.mode], width=2, style=wx.SOLID))
        self.knobPointPos = (X+25, Y+35)
        R = math.sqrt(X*X + Y*Y)
        gc.DrawEllipse(25-R, 35-R, R*2, R*2)
        gc.StrokeLine(25, 35, X+25, Y+35)

        dc.SetFont(wx.Font(CONTROLSLIDER_FONT, wx.FONTFAMILY_DEFAULT,
                           wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL,
                           face=FONT_FACE))
        # Draw text value
        if self.selected and self.new:
            val = self.new
        else:
            if self.integer:
                val = '%d' % self.GetValue()
            else:
                val = self.floatPrecision % self.GetValue()
        if PLATFORM == 'linux2':
            width = len(val) * (dc.GetCharWidth() - 3)
        else:
            width = len(val) * dc.GetCharWidth()
        dc.SetTextForeground(CONTROLSLIDER_TEXT_COLOUR)
        dc.DrawLabel(val, recval, wx.ALIGN_CENTER)

        if self.drawBottomPart:

            dc.SetFont(wx.Font(CONTROLSLIDER_FONT, wx.FONTFAMILY_DEFAULT,
                               wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL,
                               face=FONT_FACE))
            if self.midiLearn:
                gc.SetPen(wx.Pen(MIDILEARN_COLOUR, 1))
                gc.SetBrush(wx.Brush(MIDILEARN_COLOUR))
                gc.DrawRoundedRectangle(3, 70, 43, 11, 2)
            if self.midictl is not None:
                dc.DrawLabel("M : %d" % self.midictl, wx.Rect(5, 72, 41, 11),
                             wx.ALIGN_CENTER_VERTICAL)
            else:
                dc.DrawLabel("M : ?", wx.Rect(5, 72, 41, 11), wx.ALIGN_CENTER_VERTICAL)

            if self.autoPlay:
                gc.SetBrush(wx.Brush("#55DD55"))
            else:
                gc.SetBrush(wx.Brush("#333333", wx.TRANSPARENT))
            if self.showEdit:
                tri = [(w-14,72), (w-6,72), (w-10,80), (w-14,72)]
            else:
                tri = [(w-14,72), (w-14,80), (w-6,76), (w-14, 72)]
            gc.SetPen(wx.Pen("#333333", 1.5))
            gc.DrawLines(tri)

        evt.Skip()
Exemple #21
0
    def Draw(self, dc):
        # Get the actual client size of ourselves
        width, height = self.GetClientSize()

        if not width or not height:
            return

        # Initialize the wx.BufferedPaintDC, assigning a background
        # colour and a foreground colour (to draw the text)
        backColour = self.GetBackgroundColour()
        backBrush = wx.Brush(backColour, wx.SOLID)
        dc.SetBackground(backBrush)
        dc.Clear()

        value = self._value
        range = self._range

        value = max(value, 0)
        range = max(range, 1)
        value = min(value, range)

        dc.SetFont(self.GetFont())

        if self.textWidth is None:
            self.textWidth, self.textHeight = dc.GetTextExtent('00:00')

        if self._range != 0 and value == 0:
            # Draw the Do Not Enter sign.
            radius = min(width, height) / 2 - 1
            xCenter, yCenter = width / 2, radius
            lineHeight = 2 * int(radius * 0.25)
            lineWidth = 2 * int(radius * 0.70)
            sep = 4
            ctx = wx.GraphicsContext_Create(dc)
            ctx.SetPen(wx.GREY_PEN)
            ctx.SetBrush(wx.GREY_BRUSH)
            ctx.DrawEllipse(xCenter + 2 - radius, yCenter + 2 - radius,
                            radius * 2, radius * 2)
            ctx.SetPen(wx.BLACK_PEN)
            ctx.SetBrush(wx.RED_BRUSH)
            ctx.DrawEllipse(xCenter - radius, yCenter - radius, radius * 2,
                            radius * 2)
            ctx.SetPen(wx.WHITE_PEN)
            ctx.SetBrush(wx.WHITE_BRUSH)
            ctx.DrawRectangle(xCenter - lineWidth / 2,
                              yCenter - lineHeight / 2, lineWidth, lineHeight)
        elif value != 0:
            # Draw the status bar.
            x, y = 0, 0
            border = 0
            if width > border * 4:
                x += border
                width -= 2 * border
            if height > border * 4:
                y += border
                height -= 2 * border

            dc.SetPen(wx.TRANSPARENT_PEN)
            dc.SetBrush(wx.WHITE_BRUSH)
            dc.DrawRectangle(x, y, width, height)

            #---------------------------------------------------------------------
            ctx = wx.GraphicsContext_Create(dc)
            ctx.SetPen(wx.Pen(wx.WHITE, 1, style=wx.TRANSPARENT))

            colour = self._green if value > range / 4 else self._orange

            w = int(float(width) * float(value) / float(range))
            dd = int(height * 0.3)
            b1 = ctx.CreateLinearGradientBrush(x, y, x, y + dd + 1, colour,
                                               lighterColour(colour))
            ctx.SetBrush(b1)
            ctx.DrawRectangle(x, y, x + w, dd + 1)

            b2 = ctx.CreateLinearGradientBrush(x, y + dd, x, height,
                                               lighterColour(colour), colour)
            ctx.SetBrush(b2)
            ctx.DrawRectangle(x, y + dd, x + w, height - dd)

            # dc.SetBrush( wx.GREEN_BRUSH if value > range/4 else self._orangeBrush )
            # dc.DrawRectangle(x, y, int(float(width) * float(value) / float(range)), height)

            s = Utils.SecondsToMMSS(value)
            if s[0] == '0':
                s = s[1:]
            dc.DrawText(s, (width - self.textWidth) / 2, 0)

            dc.SetPen(wx.BLACK_PEN)
            dc.SetBrush(wx.TRANSPARENT_BRUSH)
            dc.DrawRectangle(x, y, width, height)
Exemple #22
0
    def Draw(self, dc):
        size = self.GetClientSize()
        width = size.width
        height = size.height

        maxBib = unicode(999999)

        minBarWidth = 48
        minBarHeight = 18
        maxBarHeight = 28

        backColour = self.GetBackgroundColour()
        backBrush = wx.Brush(backColour, wx.SOLID)
        greyBrush = wx.Brush(wx.Colour(196, 196, 196), wx.SOLID)
        lightGreyBrush = wx.Brush(wx.Colour(220, 220, 220), wx.SOLID)
        backPen = wx.Pen(backColour, 0)
        dc.SetBackground(backBrush)
        dc.Clear()

        tooSmall = (width < 50 or height < 24)

        if not self.data or self.dataMax == 0 or tooSmall:
            self.empty = True
            self.verticalSB.Show(False)
            self.horizontalSB.Show(False)
            if tooSmall:
                dc.SetPen(wx.BLACK_DASHED_PEN)
                dc.DrawLine(0, height // 2, width, height // 2)
            return

        self.empty = False

        barHeight = int(float(height) / float(len(self.data) + 2))
        barHeight = max(barHeight, minBarHeight)
        barHeight = min(barHeight, maxBarHeight)
        fontBarLabel = wx.FontFromPixelSize(
            wx.Size(0, int(min(barHeight - 2, barHeight * 0.9))),
            wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        dc.SetFont(fontBarLabel)
        textWidthLeftMax, textHeightMax = dc.GetTextExtent(maxBib)

        statusTextSpace = dc.GetTextExtent(' ')[0]
        if self.status:
            statusTextWidth = max(dc.GetTextExtent(s)[0] for s in self.status)
            if statusTextWidth:
                statusTextWidth += statusTextSpace
        else:
            statusTextWidth = 0
            self.status = [''] * len(self.data)

        textWidthLeftMax += statusTextWidth

        maxBibWidth = textWidthLeftMax
        textWidthRightMax = 0
        for label in self.labels:
            if label not in self.headerSet:
                textWidthLeftMax = max(
                    textWidthLeftMax,
                    dc.GetTextExtent(label)[0] + statusTextWidth)
                num = numFromLabel(label)
                if num is not None:
                    textWidthRightMax = max(
                        textWidthRightMax,
                        dc.GetTextExtent('{}'.format(num))[0])
        textWidthRightMax += statusTextWidth

        if textWidthLeftMax + textWidthRightMax > width:
            self.horizontalSB.Show(False)
            self.verticalSB.Show(False)
            self.empty = True
            return

        maxLaps = max(len(d) for d in self.data)
        if maxLaps and (width - textWidthLeftMax -
                        textWidthRightMax) / maxLaps < minBarWidth:
            self.horizontalSB.Show(True)
        else:
            self.horizontalSB.Show(False)

        if self.horizontalSB.IsShown():
            height -= self.scrollbarWidth

        barHeight = int(float(height) / float(len(self.data) + 2))
        barHeight = max(barHeight, minBarHeight)
        barHeight = min(barHeight, maxBarHeight)
        drawHeight = height - 2 * barHeight
        if barHeight * len(self.data) > drawHeight:
            self.verticalSB.Show(True)
            self.verticalSB.SetPosition(
                (width - self.scrollbarWidth, barHeight))
            self.verticalSB.SetSize((self.scrollbarWidth, drawHeight))
            pageSize = int(drawHeight / barHeight)
            SetScrollbarParameters(self.verticalSB, pageSize - 1,
                                   len(self.data) - 1, pageSize)
        else:
            self.verticalSB.Show(False)

        if self.verticalSB.IsShown():
            width -= self.scrollbarWidth

        iDataShowStart = self.verticalSB.GetThumbPosition(
        ) if self.verticalSB.IsShown() else 0
        iDataShowEnd = iDataShowStart + self.verticalSB.GetThumbSize(
        ) + 1 if self.verticalSB.IsShown() else len(self.data)
        tShowStart = self.horizontalSB.GetThumbPosition(
        ) if self.horizontalSB.IsShown() else 0

        dc.SetFont(fontBarLabel)

        textWidthLeftMax, textHeightMax = dc.GetTextExtent(maxBib)
        textWidthRightMax = 0
        for label in self.labels:
            if label not in self.headerSet:
                textWidthLeftMax = max(
                    textWidthLeftMax,
                    dc.GetTextExtent(label)[0] + statusTextWidth)
                num = numFromLabel(label)
                if num is not None:
                    textWidthRightMax = max(
                        textWidthRightMax,
                        dc.GetTextExtent('{}'.format(num))[0])
        textWidthRightMax += statusTextWidth

        if textWidthLeftMax + textWidthRightMax > width:
            self.horizontalSB.Show(False)
            self.verticalSB.Show(False)
            self.empty = True
            return

        legendSep = 4  # Separations between legend entries and the Gantt bars.
        labelsWidthLeft = textWidthLeftMax + legendSep
        labelsWidthRight = textWidthRightMax + legendSep
        '''
		if labelsWidthLeft > width / 2:
			labelsWidthLeft = 0
			labelsWidthRight = 0
			drawLabels = False
		'''

        xLeft = labelsWidthLeft
        xRight = width - labelsWidthRight
        yBottom = min(barHeight * (len(self.data) + 1), barHeight + drawHeight)
        yTop = barHeight

        if self.horizontalSB.IsShown():
            viewWidth = minBarWidth * maxLaps
            ratio = float(xRight - xLeft) / float(viewWidth)
            sbMax = int(self.dataMax) + 1
            pageSize = int(sbMax * ratio)
            SetScrollbarParameters(self.horizontalSB, pageSize - 1, sbMax,
                                   pageSize)
            self.horizontalSB.SetPosition((labelsWidthLeft, height))
            self.horizontalSB.SetSize((xRight - xLeft, self.scrollbarWidth))

        fontLegend = wx.FontFromPixelSize(wx.Size(0, barHeight * .75),
                                          wx.FONTFAMILY_SWISS,
                                          wx.FONTSTYLE_NORMAL,
                                          wx.FONTWEIGHT_NORMAL)
        fontNote = wx.FontFromPixelSize(wx.Size(0, barHeight * .8),
                                        wx.FONTFAMILY_SWISS,
                                        wx.FONTSTYLE_NORMAL,
                                        wx.FONTWEIGHT_NORMAL)

        dc.SetFont(fontLegend)
        textWidth, textHeight = dc.GetTextExtent('00:00' if self.dataMax < 60 *
                                                 60 else '00:00:00')

        # Draw the horizontal labels.
        # Find some reasonable tickmarks for the x axis.
        numLabels = (xRight - xLeft) / (textWidth * 1.5)
        tView = self.dataMax if not self.horizontalSB.IsShown(
        ) else self.horizontalSB.GetThumbSize()
        d = tView / max(1.0, float(numLabels))
        intervals = [
            1, 2, 5, 10, 15, 20, 30, 1 * 60, 2 * 60, 5 * 60, 10 * 60, 15 * 60,
            20 * 60, 30 * 60, 1 * 60 * 60, 2 * 60 * 60, 4 * 60 * 60,
            8 * 60 * 60, 12 * 60 * 60, 24 * 60 * 60
        ]
        d = intervals[bisect.bisect_left(intervals, d, 0, len(intervals) - 1)]
        if self.horizontalSB.IsShown():
            tAdjust = self.horizontalSB.GetThumbPosition()
            viewWidth = minBarWidth * maxLaps
            dFactor = float(viewWidth) / float(self.dataMax)
        else:
            tAdjust = 0
            dFactor = (xRight - xLeft) / float(self.dataMax)
        dc.SetPen(wx.Pen(wx.BLACK, 1))

        for t in xrange(0, int(self.dataMax), d):
            x = xLeft + (t - tAdjust) * dFactor
            if x < xLeft:
                continue
            if x > xRight:
                break
            if t < 60 * 60:
                s = '{}:{:02d}'.format((t / 60), t % 60)
            else:
                s = '{}:{:02d}:{:02d}'.format(t / (60 * 60), (t / 60) % 60,
                                              t % 60)
            w, h = dc.GetTextExtent(s)
            xText = x - w / 2
            #xText = x
            dc.DrawText(s, xText, 0 + 4)
            dc.DrawText(s, xText, yBottom + 4)
            dc.DrawLine(x, yBottom + 3, x, yTop - 3)

        # Draw the Gantt chart.
        dc.SetFont(fontBarLabel)
        textWidth, textHeight = dc.GetTextExtent(maxBib)

        penBar = wx.Pen(wx.Colour(128, 128, 128), 1)
        penBar.SetCap(wx.CAP_BUTT)
        penBar.SetJoin(wx.JOIN_MITER)
        dc.SetPen(penBar)

        brushBar = wx.Brush(wx.BLACK)
        transparentBrush = wx.Brush(wx.WHITE, style=wx.TRANSPARENT)

        ctx = wx.GraphicsContext_Create(dc)
        ctx.SetPen(wx.Pen(wx.BLACK, 1))

        xyInterp = []
        xyNumTimeInfo = []
        xyDuplicate = []

        xFactor = dFactor
        yLast = barHeight
        yHighlight = None

        tLeaderLast = None
        dy = 0
        for i, s in enumerate(self.data):
            # Record the leader's last x position.
            if tLeaderLast is None:
                tLeaderLast = s[-1] if s else 0.0
            if not (iDataShowStart <= i < iDataShowEnd):
                continue

            try:
                num = numFromLabel(self.labels[i])
            except (TypeError, IndexError):
                num = -1

            yCur = yLast + barHeight
            xLast = labelsWidthLeft
            xCur = xLast
            tTooShort = 9.0  # If a lap is shorter than 9 seconds, consider it a duplicate entry.
            for j, t in enumerate(s):
                if xLast >= xRight:
                    break
                xCur = xOriginal = int(labelsWidthLeft +
                                       (t - tAdjust) * xFactor)
                if xCur < labelsWidthLeft:
                    continue
                if xCur > xRight:
                    xCur = xRight
                if j == 0:
                    brushBar.SetColour(wx.WHITE)
                    dc.SetBrush(brushBar)
                    dc.DrawRectangle(xLast, yLast, xCur - xLast + 1,
                                     yCur - yLast + 1)
                else:
                    ctx.SetPen(wx.Pen(wx.WHITE, 1, style=wx.TRANSPARENT))
                    dy = yCur - yLast + 1
                    dd = int(dy * 0.3)
                    ic = j % len(self.colours)

                    b1 = ctx.CreateLinearGradientBrush(0, yLast, 0,
                                                       yLast + dd + 1,
                                                       self.colours[ic],
                                                       self.lighterColours[ic])
                    ctx.SetBrush(b1)
                    ctx.DrawRectangle(xLast, yLast, xCur - xLast + 1, dd + 1)

                    b2 = ctx.CreateLinearGradientBrush(0, yLast + dd, 0,
                                                       yLast + dy,
                                                       self.lighterColours[ic],
                                                       self.colours[ic])
                    ctx.SetBrush(b2)
                    ctx.DrawRectangle(xLast, yLast + dd, xCur - xLast + 1,
                                      dy - dd)

                    dc.SetBrush(transparentBrush)
                    dc.SetPen(penBar)
                    dc.DrawRectangle(xLast, yLast, xCur - xLast + 1, dy)

                    if self.lapNote:
                        note = self.lapNote.get((num, j), None)
                        if note:
                            dc.SetFont(fontNote)
                            noteWidth, noteHeight = dc.GetTextExtent(note)
                            noteBorderWidth = int(
                                dc.GetTextExtent('   ')[0] / 2)
                            noteBarWidth = xCur - xLast - noteBorderWidth * 2
                            if noteBarWidth <= 0:
                                noteBarWidth = xCur - xLast
                                noteBorderWidth = 0
                                note = '...'
                                noteWidth, noteHeight = dc.GetTextExtent(note)
                            elif noteWidth > noteBarWidth:
                                lenLeft, lenRight = 1, len(note)
                                while lenRight - lenLeft > 1:
                                    lenMid = (lenRight + lenLeft) // 2
                                    noteWidth, noteHeight = dc.GetTextExtent(
                                        note[:lenMid].strip() + '...')
                                    if noteWidth < noteBarWidth:
                                        lenLeft = lenMid
                                    else:
                                        lenRight = lenMid
                                note = note[:lenLeft].strip() + '...'
                                noteWidth, noteHeight = dc.GetTextExtent(note)
                            dc.DrawText(note, xLast + noteBorderWidth,
                                        yLast + (dy - noteHeight) / 2)
                            dc.SetFont(fontBarLabel)

                    if j == self.moveLap and self.moveIRider == i:
                        if hasPhoto(num, t):
                            # Draw a little camera icon.
                            cameraHeight = int(dy * 0.75)
                            cameraWidth = int(cameraHeight * 1.5)
                            dc.SetBrush(wx.BLACK_BRUSH)
                            dc.DrawRoundedRectangle(
                                xCur - 2 - cameraWidth,
                                yLast + (dy - cameraHeight) / 2, cameraWidth,
                                cameraHeight, cameraHeight / 5)
                            dc.SetPen(wx.WHITE_PEN)
                            dc.SetBrush(transparentBrush)
                            dc.DrawCircle(xCur - 2 - cameraWidth / 2,
                                          yLast + dy / 2,
                                          cameraHeight * (0.6 / 2))

                    if xOriginal <= xRight:
                        try:
                            if self.interp[i][j]:
                                xyInterp.append((xOriginal, yLast))
                        except (TypeError, ValueError, IndexError):
                            pass
                        if self.numTimeInfo and self.numTimeInfo.getInfo(
                                num, t) is not None:
                            xyNumTimeInfo.append((xOriginal, yLast))
                        if t - s[j - 1] < tTooShort:
                            xyDuplicate.append((xOriginal, yLast))

                xLast = xCur

            # Draw the last empty bar.
            xCur = int(labelsWidthLeft + self.dataMax * xFactor)
            if xCur > xRight:
                xCur = xRight
            dc.SetPen(penBar)
            brushBar.SetColour(wx.WHITE)
            dc.SetBrush(brushBar)
            dc.DrawRectangle(xLast, yLast, xCur - xLast + 1, yCur - yLast + 1)

            # Draw the label on both ends.
            if self.greyOutSet and i in self.greyOutSet:
                dc.SetPen(wx.TRANSPARENT_PEN)
                dc.SetBrush(greyBrush)
                dc.DrawRectangle(0, yLast, textWidthLeftMax, yCur - yLast + 1)
                dc.SetBrush(backBrush)
            if self.status[i] == _('PUL'):
                dc.SetPen(wx.TRANSPARENT_PEN)
                dc.SetBrush(lightGreyBrush)
                dc.DrawRectangle(0, yLast, textWidthLeftMax, yCur - yLast + 1)
                dc.SetBrush(backBrush)
            if self.labels[i] in self.headerSet:
                dc.DrawText(self.labels[i], labelsWidthLeft + 4,
                            yLast)  # This is a Category Label.
            else:
                labelWidth = dc.GetTextExtent(self.labels[i])[0]
                dc.DrawText(self.labels[i],
                            textWidthLeftMax - labelWidth - statusTextWidth,
                            yLast)
                if statusTextWidth and self.status[i]:
                    dc.DrawText(
                        self.status[i],
                        textWidthLeftMax - statusTextWidth + statusTextSpace,
                        yLast)
                if not self.minimizeLabels:
                    label = self.labels[i]
                    lastSpace = label.rfind(' ')
                    if lastSpace > 0:
                        label = label[lastSpace + 1:]
                    labelWidth = dc.GetTextExtent(label)[0]
                    dc.DrawText(label, width - labelsWidthRight + legendSep,
                                yLast)
                    if statusTextWidth and self.status[i]:
                        dc.DrawText(self.status[i],
                                    width - statusTextWidth + statusTextSpace,
                                    yLast)

            if u'{}'.format(self.numSelect) == u'{}'.format(
                    numFromLabel(self.labels[i])):
                yHighlight = yCur

            yLast = yCur

        if yHighlight is not None and len(self.data) > 1:
            dc.SetPen(wx.Pen(wx.BLACK, 2))
            dc.SetBrush(wx.TRANSPARENT_BRUSH)
            dc.DrawLine(0, yHighlight, width, yHighlight)
            yHighlight -= barHeight
            dc.DrawLine(0, yHighlight, width, yHighlight)

        # Draw indicators for interpolated values.
        radius = (dy / 2) * 0.9

        # Define a path for the interp indicator about the origin.
        diamondPath = ctx.CreatePath()
        diamondPath.MoveToPoint(0, -radius)
        diamondPath.AddLineToPoint(-radius, 0)
        diamondPath.AddLineToPoint(0, radius)
        diamondPath.AddLineToPoint(radius, 0)
        diamondPath.AddLineToPoint(0, -radius)

        def getStarPath(ctx, numPoints, radius, radiusInner):
            path = ctx.CreatePath()
            angle = (math.pi * 2.0) / numPoints
            angle2 = angle / 2.0
            path.MoveToPoint(0, -radius)
            for p in xrange(numPoints):
                a = p * angle + angle2 + math.pi / 2.0
                path.AddLineToPoint(
                    math.cos(a) * radiusInner, -math.sin(a) * radiusInner)
                a = (p + 1) * angle + math.pi / 2.0
                path.AddLineToPoint(
                    math.cos(a) * radius, -math.sin(a) * radius)
            path.AddLineToPoint(0, -radius)
            return path

        starPath = getStarPath(ctx, 5, radius, radius / 2)

        # Draw the interp indicators.
        ctx.SetPen(penBar)
        ctx.SetBrush(
            ctx.CreateRadialGradientBrush(0, -radius * 0.50, 0, 0, radius + 1,
                                          wx.WHITE, self.yellowColour))
        for xCur, yCur in xyInterp:
            ctx.PushState()
            ctx.Translate(xCur, yCur + dy / 2.0 - (dy / 2.0 - radius) / 4)
            ctx.DrawPath(diamondPath)
            ctx.PopState()

        # Draw the edit indictors.
        ctx.SetPen(penBar)
        ctx.SetBrush(
            ctx.CreateRadialGradientBrush(0, -radius * 0.50, 0, 0, radius + 1,
                                          wx.WHITE, self.orangeColour))
        for xCur, yCur in xyNumTimeInfo:
            ctx.PushState()
            ctx.Translate(xCur, yCur + dy / 2.0 - (dy / 2.0 - radius) / 4)
            ctx.DrawPath(starPath)
            ctx.PopState()

        # Draw the duplicate indicators.
        radius = int(radius * 1.5)
        ctx.SetPen(wx.Pen(wx.RED, 3))
        ctx.SetBrush(wx.TRANSPARENT_BRUSH)
        for xCur, yCur in xyDuplicate:
            ctx.DrawEllipse(xCur - radius, yCur + dy / 2.0 - radius,
                            radius * 2, radius * 2)

        # Draw the now timeline.
        timeLineTime = self.nowTime if self.nowTime and self.nowTime < self.dataMax else tLeaderLast
        nowTimeStr = Utils.formatTime(timeLineTime)
        labelWidth, labelHeight = dc.GetTextExtent(nowTimeStr)
        x = int(labelsWidthLeft + (timeLineTime - tAdjust) * xFactor)

        ntColour = '#339966'
        dc.SetPen(wx.Pen(ntColour, 3))
        dc.DrawLine(x, barHeight - 4, x, yLast + 4)
        dc.SetPen(wx.Pen(wx.WHITE, 1))
        dc.DrawLine(x, barHeight - 4, x, yLast + 4)

        dc.SetBrush(wx.Brush(ntColour))
        dc.SetPen(wx.Pen(ntColour, 1))
        rect = wx.Rect(x - labelWidth / 2 - 2, 0, labelWidth + 4, labelHeight)
        dc.DrawRectangleRect(rect)
        if not self.minimizeLabels:
            rect.SetY(yLast + 2)
            dc.DrawRectangleRect(rect)

        dc.SetTextForeground(wx.WHITE)
        dc.DrawText(nowTimeStr, x - labelWidth / 2, 0)
        if not self.minimizeLabels:
            dc.DrawText(nowTimeStr, x - labelWidth / 2, yLast + 2)

        # Store the drawing scale parameters.
        self.xFactor = xFactor
        self.barHeight = barHeight
        self.labelsWidthLeft = labelsWidthLeft