*ThorwilKnob: KnobRim done
[libprolooks.git] / prolooks / ThorwilKnobImageSource.vala
blob652eacde156875795f6f8c697c60f7f8ebca1543
1 using Gtk;
2 using Cairo;
4 namespace Prolooks {
5 class ThorwilKnobImageSource : DrawingArea, IKnobImageSource {
6 public double knob_width { get; set; }
7 public double knob_height { get; set; }
8 public double x { get; set; }
9 public double y { get; set; }
10 public Gdk.Color lamp_color { get; set; }
12 public double get_knob_width () {
13 return knob_width;
16 public double get_knob_height () {
17 return knob_height;
20 public double get_line_width () {
21 return knob_width / 10;
24 public double get_radius () {
25 return knob_width / 2;
28 public string to_string () {
29 return "SimpleKnobImageSource: Dimens: (%f, %f); linewidth: %f; radius: %f; led-color: %s".printf (
30 get_knob_width (),
31 get_knob_height (),
32 get_line_width (),
33 get_radius (),
34 Prolooks.color_to_string(lamp_color));
37 private double scale_factor = 4.0;
39 construct {
40 knob_width = 105;
41 knob_height = 105;
42 x = knob_width / 2;
43 y = knob_height / 2;
44 set_size_request ((int)(scale_factor * knob_width), (int) (scale_factor * knob_height));
45 //set_size_request (phases * (int)knob_width, variants * (int)knob_height);
46 lamp_color = color_from_string ("#ff7f00");
49 public override bool expose_event (Gdk.EventExpose event) {
50 var cr = Gdk.cairo_create (this.window);
51 // Set clipping area in order to avoid unnecessary drawing
52 Gdk.cairo_rectangle (cr, event.area);
53 cr.clip ();
55 cr.scale (scale_factor, scale_factor);
57 cr.set_source_rgba(0.75, 0.75, 0.75, 0);
58 debug ("expose!\n");
60 cr.rectangle(0, 0, knob_width, knob_height);
61 cr.fill ();
64 cr.rectangle(0, 0, phases * knob_width, 4 * knob_height);
65 cr.fill();
67 for (int variant = 0; variant <= variants; variant++) {
68 // x/y = the middle of the knob
69 var x = knob_width / 2;
70 var y = knob_height * (variant + 0.5);
71 paint_knobs (cr, (KnobMode)variant, x, y);
75 paint_knob (cr, KnobMode.POSITIVE, 25, 20, 50, x, y);
77 return true;
80 public void paint_knob (Cairo.Context cr, KnobMode knob_mode, int phase, double lwidth, double radius, double x, double y) {
81 var radiusminus2 = radius - lwidth;
82 var radiusminus3 = radius - lwidth * 3 / 2;
84 var knob_rim_radius = 31.5;
86 var start_angle = 0.0;
87 var end_angle = 0.0;
88 var value_angle = 0.0;
90 // Draw out the triangle using absolute coordinates
91 var value = phase * 1.0 / (phases - 1);
93 if (knob_mode != KnobMode.ENDLESS) {
94 start_angle = (180 - 45) * Math.PI / 180;
95 end_angle = (360 + 45) * Math.PI / 180;
96 } else {
97 start_angle = (270) * Math.PI / 180;
98 end_angle = (270 + 360) * Math.PI / 180;
101 value_angle = start_angle + value * (end_angle - start_angle);
102 var cos_value = Math.cos(value_angle);
103 var sin_value = Math.sin(value_angle);
104 var cos_start_angle = Math.cos(start_angle);
105 var sin_start_angle = Math.sin(start_angle);
106 var cos_end_angle = Math.cos(end_angle);
107 var sin_end_angle = Math.sin(end_angle);
109 // KnobRim
110 cr.set_source (create_gradient_str (32, 16, 75, 16, "#d4c8b9", "#ae977b"));
111 cr.set_line_width (2.0);
112 cr.arc (x, y, 31.5, 0.0, 2 * Math.PI);
113 cr.stroke ();
115 var process_width = 20.0;
116 var process_radius = 40.0;
117 var process_radius_inner = process_radius - process_width / 2.0;
118 var process_radius_outer = process_radius + process_width / 2.0;
120 // ProgressBackground
121 cr.set_source (create_gradient_str (20, 20, 89, 87, "#2f2f4c", "#090a0d"));
122 cr.set_line_width (process_width);
123 cr.arc (x, y, process_radius, start_angle, end_angle);
124 cr.stroke ();
126 // ProgressLamp
127 cr.set_source (create_gradient_str (20, 20, 89, 87, "#b9feff", "#3aacaa"));
128 cr.set_line_width (process_width);
129 cr.arc (x, y, process_radius, start_angle, value_angle);
130 cr.stroke ();
132 // ProgressShadow
133 // TODO (Performace ?)
135 cr.set_line_cap (LineCap.ROUND);
136 var progress_rim_width = 2.0;
137 cr.set_line_width (progress_rim_width);
139 // ProgressBeginRim
140 cr.set_source (create_gradient_str (18, 79, 35, 79, "#dfd5c9", "#dfd5c9", 1.0, 0.0));
141 cr.move_to (x + process_radius_outer * cos_start_angle,
142 y + process_radius_outer * sin_start_angle);
143 cr.line_to (x + process_radius_inner * cos_start_angle,
144 y + process_radius_inner * sin_start_angle);
145 cr.stroke ();
147 // ProgressEndRim
148 set_source_color_string (cr, "#b3a190");
149 cr.move_to (x + process_radius_outer * cos_end_angle,
150 y + process_radius_outer * sin_end_angle);
151 cr.line_to (x + process_radius_inner * cos_end_angle,
152 y + process_radius_inner * sin_end_angle);
153 cr.stroke ();
155 // ProgressRim
156 cr.set_source (create_gradient_str (95, 6, 5, 44, "#dfd5c9", "#b0a090"));
157 cr.arc (x, y, process_radius_outer, start_angle, end_angle);
158 cr.stroke ();
160 cr.set_line_cap (LineCap.BUTT);
162 // ProgressLampReflection
163 // TODO?: blur 2.0
164 cr.set_source (create_gradient_str (20, 20, 89, 87, "#b9feff", "#3aacaa", 0.25, 0.25));
165 cr.set_line_width (process_width);
166 cr.arc (x, y, process_radius, start_angle, value_angle + Math.PI / 180.0);
167 cr.stroke ();
169 // ProgressBackgroundShine
171 Cairo.Pattern progress_shine = create_gradient_str (89, 73, 34, 16, "#ffffff", "#ffffff", 0.3, 0.04);
172 progress_shine.add_color_stop_rgba (0.5, 1.0, 1.0, 1.0, 0.0);
173 progress_shine.add_color_stop_rgba (0.75, 1.0, 1.0, 1.0, 0.3);
175 cr.set_source (progress_shine);
176 cr.set_line_width (process_width);
177 cr.arc (x, y, process_radius, start_angle, end_angle);
178 cr.stroke ();
180 // KnobShadow
181 // TODO?: blur 2.0
182 cr.set_line_width (progress_rim_width);
183 cr.set_source (create_gradient_str (86, 77, 38, 25, "#151928", "#151928", 1.0, 0.5));
184 cr.arc (x, y, process_radius_inner, 0, 2 * Math.PI);
185 cr.stroke ();
187 // KnobRimPlain
188 // TODO?: blur 2.0
189 cr.set_line_width (1.0);
190 cr.set_source_rgb (0.0, 0.0, 0.0);
191 cr.arc (x, y, process_radius_inner, 0, 2 * Math.PI);
192 cr.stroke ();
196 } // namespace Prolooks