7 class SimpleKnobImageSource : DrawingArea implements IKnobImageSource
8 prop knob_width: double
9 prop knob_height: double
12 prop led_color: Gdk.Color
14 def get_knob_width () : double
17 def get_knob_height () : double
20 def get_line_width () : double
21 return knob_width / 10
23 def get_radius () : double
24 return knob_width / 2 - get_line_width ()
31 set_size_request (phases * (int)knob_width, variants * (int)knob_height);
32 led_color = color_from_string ("#ff7f00")
34 def override expose_event (event: Gdk.EventExpose) : bool
35 var cr = Gdk.cairo_create (this.window);
36 // Set clipping area in order to avoid unnecessary drawing
37 Gdk.cairo_rectangle (cr, event.area);
40 cr.set_source_rgba(0.75, 0.75, 0.75, 0)
41 cr.rectangle(0, 0, phases * knob_width, 4 * knob_height)
44 for var variant = 0 to variants
45 var x = knob_width / 2
46 var y = knob_height * (variant + 0.5)
47 paint_knobs (cr, variant, x, y)
51 def paint_knob (cr: Context, knob_mode: KnobMode, phase: int, lwidth: double, radius: double, x: double, y: double)
52 var radiusplus = radius + lwidth / 2
53 var radiusminus = radius - lwidth / 2
54 var radiusminus2 = radius - lwidth
55 var radiusminus3 = radius - lwidth * 3 / 2
56 var radiusint = (radius - lwidth / 2) * 0.25
58 var arrow = knob_width / 10.0
65 // Draw out the triangle using absolute coordinates
66 value = phase * 1.0 / (phases - 1)
67 if knob_mode != KnobMode.ENDLESS
68 sangle = (180 - 45) * PI / 180
69 eangle = (360 + 45) * PI / 180
72 sangle = (270) * PI / 180
73 eangle = (270 + 360) * PI / 180
75 vangle = sangle + value * (eangle - sangle)
79 var midled = (nleds - 1) / 2
80 var midphase = (phases - 1) / 2
81 var thresholdP = midled + 1 + ((phase - midphase - 1) * 1.0 * (nleds - midled - 2) / (phases - midphase - 2))
82 var thresholdN = midled - 1 - ((midphase - 1 - phase) * 1.0 * (nleds - midled - 2) / (midphase - 1))
84 var spacing = PI / nleds
85 for var led = 0 to (nleds - 1)
87 if knob_mode == KnobMode.ENDLESS
88 adelta = (eangle - sangle) / (nleds)
90 adelta = (eangle - sangle - spacing) / (nleds - 1)
95 var lvalue = led * 1.0 / (nleds - 1)
96 var pvalue = phase * 1.0 / (phases - 1)
97 if knob_mode == KnobMode.ENDLESS
98 // XXXKF works only for phases = 2 * leds
99 var exled = phase / 2.0
100 lit = (led == exled) or (phase == (phases - 1) and led == 0)
101 glowlit = led == (exled + 0.5) or led == (exled - 0.5)
103 hilite = (phase % ((phases - 1) / 4)) == 0
104 if knob_mode == KnobMode.POSITIVE
105 lit = (pvalue == 1.0) or pvalue > lvalue
106 if knob_mode == KnobMode.BIPOLAR
108 lit = (phase == midphase)
109 //glowlit = (phase < midphase and thresholdN >= midled - 1) or (phase > midphase and thresholdP <= midled + 1)
112 else if led > midled and phase > midphase
113 // led = [midled + 1, nleds - 1]
114 // phase = [midphase + 1, phases - 1]
115 lit = led <= thresholdP
116 glowlit = led <= thresholdP + 1
118 else if led < midled and phase < midphase
119 lit = led >= thresholdN
120 glowlit = led >= thresholdN - 1
124 if knob_mode == KnobMode.NEGATIVE
125 lit = pvalue == 0 or pvalue < lvalue
128 cr.set_source_rgb(0, 0, 0)
130 set_source_color(cr, shade_color (led_color, glowval))
133 cr.set_source_rgb(1, 1, 0)
135 set_source_color(cr, led_color)
137 cr.arc(x, y, radius, sangle + adelta * led, sangle + adelta * led + spacing)
140 var grad = new Cairo.Pattern.linear(x - radius / 2, y - radius / 2, x + radius / 2, y + radius / 2)
141 grad.add_color_stop_rgb(0.0, 0.5, 0.5, 0.5)
142 grad.add_color_stop_rgb(1.0, 0.8, 0.8, 0.8)
145 cr.arc(x, y, radiusminus2, 0, 2 * PI)
148 grad = new Cairo.Pattern.linear(x - radius / 2, y - radius / 2, x + radius / 2, y + radius / 2)
149 grad.add_color_stop_rgb(0.0, 0.8, 0.8, 0.8)
150 grad.add_color_stop_rgb(1.0, 0.5, 0.5, 0.5)
152 cr.arc(x, y, radiusminus3, 0, 2 * PI)
154 cr.set_source_rgb(0, 0, 0)
156 cr.arc(x, y, radiusminus2, 0, 2 * PI)
159 cr.set_source_rgba(0, 0, 0, 0.5)
161 var mtx = Matrix (0,0,0,0,0,0)
162 cr.get_matrix(out mtx)
163 cr.translate(x + radiusminus2 * c, y + radiusminus2 * s)
166 cr.line_to(-radius/2, 0)