+ Vintage Delay: make bpm spin button use 2 decimal places
[calf.git] / knobs / knob2.py
blob20870d3c4b99f229d62a1e1f5ea78e13744ef720
1 #!/usr/bin/env python
3 import cairo
4 from math import pi, cos, sin
6 WIDTH, HEIGHT = 40, 40
7 x, y = WIDTH / 2, HEIGHT / 2
8 lwidth = WIDTH / 10
9 radius = WIDTH / 2 - lwidth
10 radiusplus = radius + lwidth / 2
11 radiusminus = radius - lwidth / 2
12 radiusminus2 = radius - lwidth
13 radiusminus3 = radius - lwidth * 3 / 2
14 radiusint = (radius - lwidth / 2) * 0.25
15 value = 0.7
16 arrow = WIDTH / 10
17 phases = 65
19 # Setup Cairo
20 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, phases * WIDTH, HEIGHT * 4)
21 ctx = cairo.Context(surface)
22 ctx.set_source_rgba(0.75, 0.75, 0.75, 0)
23 ctx.rectangle(0, 0, phases * WIDTH, 4 * HEIGHT)
24 ctx.fill()
26 for variant in range(0, 4):
27 x = WIDTH / 2
28 y = HEIGHT * (variant + 0.5)
29 for phase in range(0, phases):
30 # Draw out the triangle using absolute coordinates
31 value = phase * 1.0 / (phases - 1)
32 if variant != 3:
33 sangle = (180 - 45)*pi/180
34 eangle = (360 + 45)*pi/180
35 nleds = 31
36 else:
37 sangle = (270)*pi/180
38 eangle = (270 + 360)*pi/180
39 nleds = 32
40 vangle = sangle + value * (eangle - sangle)
41 c, s = cos(vangle), sin(vangle)
43 midled = (nleds - 1) / 2
44 midphase = (phases - 1) / 2
45 thresholdP = midled + 1 + ((phase - midphase - 1) * 1.0 * (nleds - midled - 2) / (phases - midphase - 2))
46 thresholdN = midled - 1 - ((midphase - 1 - phase) * 1.0 * (nleds - midled - 2) / (midphase - 1))
48 spacing = pi / nleds
49 for led in range(0, nleds):
50 if variant == 3:
51 adelta = (eangle - sangle) / (nleds)
52 else:
53 adelta = (eangle - sangle - spacing) / (nleds - 1)
54 lit = False
55 glowlit = False
56 glowval = 0.5
57 hilite = False
58 lvalue = led * 1.0 / (nleds - 1)
59 pvalue = phase * 1.0 / (phases - 1)
60 if variant == 3:
61 # XXXKF works only for phases = 2 * leds
62 exled = phase / 2.0
63 lit = led == exled or (phase == phases - 1 and led == 0)
64 glowlit = led == (exled + 0.5) or led == (exled - 0.5)
65 glowval = 0.8
66 hilite = (phase % ((phases - 1) / 4)) == 0
67 if variant == 0: lit = (pvalue == 1.0) or pvalue > lvalue
68 if variant == 1:
69 if led == midled:
70 lit = (phase == midphase)
71 #glowlit = (phase < midphase and thresholdN >= midled - 1) or (phase > midphase and thresholdP <= midled + 1)
72 glowlit = False
73 hilite = True
74 elif led > midled and phase > midphase:
75 # led = [midled + 1, nleds - 1]
76 # phase = [midphase + 1, phases - 1]
77 lit = led <= thresholdP
78 glowlit = led <= thresholdP + 1
79 glowval = 0.4
80 elif led < midled and phase < midphase:
81 lit = led >= thresholdN
82 glowlit = led >= thresholdN - 1
83 glowval = 0.4
84 else:
85 lit = False
86 if variant == 2: lit = pvalue == 0 or pvalue < lvalue
87 if not lit:
88 if not glowlit:
89 ctx.set_source_rgb(0, 0, 0)
90 else:
91 ctx.set_source_rgb(1 * glowval, 0.5 * glowval, 0)
92 else:
93 if hilite:
94 ctx.set_source_rgb(1, 1, 0)
95 else:
96 ctx.set_source_rgb(1, 0.5, 0)
97 ctx.set_line_width(3)
98 if hilite:
99 ctx.set_line_width(4)
100 ctx.arc(x, y, radius, sangle + adelta * led, sangle + adelta * led + spacing)
101 ctx.stroke()
103 #ctx.set_line_width(lwidth)
104 #ctx.set_source_rgb(1, 0.5, 0)
105 #ctx.arc(x, y, radius, sangle, vangle)
106 #ctx.line_to(x + radiusint * c, y + radiusint * s)
107 #ctx.stroke()
109 grad = cairo.LinearGradient(x - radius / 2, y - radius / 2, x + radius / 2, y + radius / 2)
110 #grad.add_color_stop_rgb(0.0, 0.5, 0.5, 0.5)
111 #grad.add_color_stop_rgb(1.0, 0.8, 0.8, 0.8)
112 grad.add_color_stop_rgb(0.0, 0.5, 0.5, 0.5)
113 grad.add_color_stop_rgb(1.0, 0.8, 0.8, 0.8)
114 ctx.set_source(grad)
115 # ctx.set_source_rgb(0.8, 0.8, 0.8)
116 ctx.set_line_width(2)
117 ctx.arc(x, y, radiusminus2, 0, 2 * pi)
118 ctx.fill()
120 grad = cairo.LinearGradient(x - radius / 2, y - radius / 2, x + radius / 2, y + radius / 2)
121 grad.add_color_stop_rgb(0.0, 0.8, 0.8, 0.8)
122 grad.add_color_stop_rgb(1.0, 0.5, 0.5, 0.5)
123 ctx.set_source(grad)
124 ctx.arc(x, y, radiusminus3, 0, 2 * pi)
125 ctx.fill()
126 ctx.set_source_rgb(0, 0, 0)
127 ctx.set_line_width(2)
128 ctx.arc(x, y, radiusminus2, 0, 2 * pi)
129 ctx.stroke()
131 ctx.set_source_rgba(0, 0, 0, 0.5)
132 ctx.set_line_width(1)
133 mtx = ctx.get_matrix()
134 ctx.translate(x + radiusminus2 * c, y + radiusminus2 * s)
135 ctx.rotate(vangle)
136 ctx.move_to(0, 0)
137 ctx.line_to(-radius/2, 0)
138 ctx.stroke()
139 ctx.set_matrix(mtx)
140 x += WIDTH
142 #ctx.set_source_rgb(1, 0.5, 0)
143 #ctx.line_to(x + radiusplus * c, y + radiusplus * s)
144 #ctx.stroke()
146 # Output a PNG file
147 surface.write_to_png("knob.png")