Fully redesigned
[calf.git] / knobs / knob3.py
bloba55af0e4b494c372c08bd0e3012c94d40288ac5f
1 #!/usr/bin/env python
3 import cairo
4 from math import pi, cos, sin
6 WIDTH, HEIGHT = 60, 60
7 background = "knob3_bg.png"
8 output = "knob3.png"
9 x, y = WIDTH / 2, HEIGHT / 2
10 lwidth = WIDTH / 12
11 radius = WIDTH / 2 - lwidth
12 radiusplus = radius + lwidth / 2
13 radiusminus = radius - lwidth / 2
14 radiusminus2 = radius - lwidth
15 radiusminus3 = radius - lwidth * 3 / 2
16 radiusint = (radius - lwidth / 2) * 0.25
17 value = 0.7
18 arrow = WIDTH / 10
19 phases = 65
21 # Setup Cairo
22 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, phases * WIDTH, HEIGHT * 4)
23 ctx = cairo.Context(surface)
24 ctx.set_source_rgba(0.75, 0.75, 0.75, 0)
25 ctx.rectangle(0, 0, phases * WIDTH, 4 * HEIGHT)
26 ctx.fill()
28 for variant in range(0, 4):
29 x = WIDTH / 2
30 y = HEIGHT * (variant + 0.5)
31 for phase in range(0, phases):
32 # Draw background image
33 bgimage = cairo.ImageSurface.create_from_png(background)
34 ctx.set_source_surface(bgimage, x - WIDTH / 2, y - HEIGHT / 2);
35 ctx.rectangle(phase * WIDTH, variant * HEIGHT, WIDTH, HEIGHT)
36 ctx.fill ();
38 # Draw out the triangle using absolute coordinates
39 value = phase * 1.0 / (phases - 1)
40 if variant != 3:
41 sangle = (180 - 45)*pi/180
42 eangle = (360 + 45)*pi/180
43 nleds = 31
44 else:
45 sangle = (270)*pi/180
46 eangle = (270 + 360)*pi/180
47 nleds = 32
48 vangle = sangle + value * (eangle - sangle)
49 c, s = cos(vangle), sin(vangle)
51 midled = (nleds - 1) / 2
52 midphase = (phases - 1) / 2
53 thresholdP = midled + 1 + ((phase - midphase - 1) * 1.0 * (nleds - midled - 2) / (phases - midphase - 2))
54 thresholdN = midled - 1 - ((midphase - 1 - phase) * 1.0 * (nleds - midled - 2) / (midphase - 1))
56 spacing = pi / nleds
57 for led in range(0, nleds):
58 if variant == 3:
59 adelta = (eangle - sangle) / (nleds)
60 else:
61 adelta = (eangle - sangle - spacing) / (nleds - 1)
62 lit = False
63 glowlit = False
64 glowval = 0.5
65 hilite = False
66 lvalue = led * 1.0 / (nleds - 1)
67 pvalue = phase * 1.0 / (phases - 1)
68 if variant == 3:
69 # XXXKF works only for phases = 2 * leds
70 exled = phase / 2.0
71 lit = led == exled or (phase == phases - 1 and led == 0)
72 glowlit = led == (exled + 0.5) or led == (exled - 0.5)
73 glowval = 0.8
74 hilite = (phase % ((phases - 1) / 4)) == 0
75 if variant == 0: lit = (pvalue == 1.0) or pvalue > lvalue
76 if variant == 1:
77 if led == midled:
78 lit = (phase == midphase)
79 #glowlit = (phase < midphase and thresholdN >= midled - 1) or (phase > midphase and thresholdP <= midled + 1)
80 glowlit = False
81 hilite = True
82 elif led > midled and phase > midphase:
83 # led = [midled + 1, nleds - 1]
84 # phase = [midphase + 1, phases - 1]
85 lit = led <= thresholdP
86 glowlit = led <= thresholdP + 1
87 glowval = 0.4
88 elif led < midled and phase < midphase:
89 lit = led >= thresholdN
90 glowlit = led >= thresholdN - 1
91 glowval = 0.4
92 else:
93 lit = False
94 if variant == 2: lit = pvalue == 0 or pvalue < lvalue
95 if not lit:
96 if not glowlit:
97 ctx.set_source_rgb(0.0, 0.1, 0.1)
98 else:
99 ctx.set_source_rgb(0.0 * glowval, 0.75 * glowval, 1.0 * glowval)
100 else:
101 if hilite:
102 ctx.set_source_rgb(0.3, 1.0, 1.0)
103 else:
104 ctx.set_source_rgb(0.0, 0.75, 1.0)
105 ctx.set_line_width(3)
106 if hilite:
107 ctx.set_line_width(4)
108 ctx.arc(x, y, radius, sangle + adelta * led, sangle + adelta * led + spacing)
109 ctx.stroke()
111 ctx.set_source_rgba(1, 1, 1, 1)
112 ctx.set_line_width(2)
113 mtx = ctx.get_matrix()
114 ctx.translate(x + radiusminus2 * c, y + radiusminus2 * s)
115 ctx.rotate(vangle)
116 ctx.move_to(0, 0)
117 ctx.line_to(-radius/5, 0)
118 ctx.stroke()
119 ctx.set_matrix(mtx)
120 x += WIDTH
122 # Output a PNG file
123 surface.write_to_png(output)