The Big Commit (tm): Remove Cairo.Color and most of Gdk.Color usage from libprolooks
[libprolooks.git] / src / ThorwilKnobImageSource.vala
blob45957c6678fcba0cf8c6c7b9cefe08ee23d07b37
1 using Gtk;
2 using Cairo;
4 namespace Prolooks {
5 protected class ThorwilKnobImageSource : DrawingArea, IKnobImageSource {
6 public double knob_width { get; set; }
7 public double knob_height { get; set; }
9 private HSV lamp_hsv;
10 private Gdk.RGBA _lamp_color;
12 public Gdk.RGBA lamp_color {
13 get {
14 return _lamp_color;
17 set {
18 _lamp_color = value;
19 lamp_hsv = new HSV.for_rgba (value);
23 public double get_knob_width () {
24 return knob_width;
27 public double get_knob_height () {
28 return knob_height;
31 public double get_line_width () {
32 return 0.0;
35 public double get_radius () {
36 return knob_width / 2.0;
39 public string to_string () {
40 return "ThorwilKnobImageSource: Dimens: (%f, %f); radius: %f; lamp-hue: %f".printf (
41 get_knob_width (),
42 get_knob_height (),
43 get_radius (),
44 lamp_hsv.hue);
47 construct {
48 knob_width = 40;
49 knob_height = 40;
50 set_size_request ((int)(phases * knob_width), (int) (knob_height));
51 lamp_color = rgba_from_string ("#b9feff");
52 draw.connect(on_draw);
55 public bool on_draw (Cairo.Context cr) {
56 cr.set_source_rgba(0.75, 0.75, 0.75, 0);
58 cr.rectangle(0, 0, phases * knob_width, 4 * knob_height);
59 cr.fill();
61 for (int variant = 0; variant < 1; variant++) {
62 // x/y = the middle of the knob
63 var x = get_radius();
64 var y = knob_height * (variant + 0.5);
65 paint_knobs (cr, (KnobMode)variant, x, y);
68 return true;
71 public void paint_knob (Cairo.Context cr, KnobMode knob_mode, int phase, double lwidth, double radius, double x, double y) {
72 var width = 105.0;
73 var height = 105.0;
74 var xc = width / 2.0;
75 var yc = height / 2.0;
77 var start_angle = 0.0;
78 var end_angle = 0.0;
79 var value_angle = 0.0;
81 // Draw out the triangle using absolute coordinates
82 var value = phase * 1.0 / (phases - 1);
84 if (knob_mode != KnobMode.ENDLESS) {
85 start_angle = (180 - 45) * Math.PI / 180;
86 end_angle = (360 + 45) * Math.PI / 180;
87 } else {
88 start_angle = (270) * Math.PI / 180;
89 end_angle = (270 + 360) * Math.PI / 180;
92 value_angle = start_angle + value * (end_angle - start_angle);
94 var value_x = Math.cos(value_angle);
95 var value_y = Math.sin(value_angle);
96 var start_angle_x = Math.cos(start_angle);
97 var start_angle_y = Math.sin(start_angle);
98 var end_angle_x = Math.cos(end_angle);
99 var end_angle_y = Math.sin(end_angle);
101 cr.save ();
102 cr.translate (x, 0);
103 cr.scale (2.0 * radius / width, 2.0 * radius / height);
104 cr.translate (-xc, 0);
106 // KnobRim
107 cr.set_source (create_gradient_str (32, 16, 75, 16, "#d4c8b9", "#ae977b"));
108 cr.set_line_width (2.0);
109 cr.arc (xc, yc, 31.5, 0.0, 2 * Math.PI);
110 cr.stroke ();
112 var progress_width = 20.0;
113 var progress_radius = 40.0;
114 var progress_radius_inner = progress_radius - progress_width / 2.0;
115 var progress_radius_outer = progress_radius + progress_width / 2.0;
116 var knob_disc_radius = progress_radius_inner - 5.0;
118 // ProgressBackground
119 cr.set_source (create_gradient_str (20, 20, 89, 87, "#2f2f4c", "#090a0d"));
120 cr.set_line_width (progress_width);
121 cr.arc (xc, yc, progress_radius, start_angle, end_angle);
122 cr.stroke ();
124 // ProgressLamp
125 lamp_hsv.saturation = 0.27;
126 lamp_hsv.value = 1.0;
127 var lamp_bright = lamp_hsv.to_rgba ();
128 lamp_hsv.saturation = 0.66;
129 lamp_hsv.value = 0.67;
130 var lamp_dark = lamp_hsv.to_rgba ();
132 cr.set_source (create_gradient (20, 20, 89, 87, lamp_bright, lamp_dark));
133 cr.set_line_width (progress_width);
134 cr.arc (xc, yc, progress_radius, start_angle, value_angle);
135 cr.stroke ();
137 // ProgressShadow
138 // TODO (Performace ?)
140 cr.set_line_cap (LineCap.ROUND);
141 var progress_rim_width = 2.0;
142 cr.set_line_width (progress_rim_width);
144 // ProgressBeginRim
145 cr.set_source (create_gradient_str (18, 79, 35, 79, "#dfd5c9", "#dfd5c9", 1.0, 0.0));
146 cr.move_to (xc + progress_radius_outer * start_angle_x,
147 yc + progress_radius_outer * start_angle_y);
148 cr.line_to (xc + progress_radius_inner * start_angle_x,
149 yc + progress_radius_inner * start_angle_y);
150 cr.stroke ();
152 // ProgressEndRim
153 set_source_color_string (cr, "#b3a190");
154 cr.move_to (xc + progress_radius_outer * end_angle_x,
155 yc + progress_radius_outer * end_angle_y);
156 cr.line_to (xc + progress_radius_inner * end_angle_x,
157 yc + progress_radius_inner * end_angle_y);
158 cr.stroke ();
160 // ProgressRim
161 cr.set_source (create_gradient_str (95, 6, 5, 44, "#dfd5c9", "#b0a090"));
162 cr.arc (xc, yc, progress_radius_outer, start_angle, end_angle);
163 cr.stroke ();
165 cr.set_line_cap (LineCap.BUTT);
167 // ProgressLampReflection
168 // TODO?: blur 2.0
169 cr.set_source (create_gradient (20, 20, 89, 87, lamp_bright, lamp_dark, 0.25, 0.25));
170 cr.set_line_width (progress_width);
171 cr.arc (xc, yc, progress_radius, start_angle, value_angle + Math.PI / 180.0);
172 cr.stroke ();
174 // ProgressBackgroundShine
176 Cairo.Pattern progress_shine = create_gradient_str (89, 73, 34, 16, "#ffffff", "#ffffff", 0.3, 0.04);
177 progress_shine.add_color_stop_rgba (0.5, 1.0, 1.0, 1.0, 0.0);
178 progress_shine.add_color_stop_rgba (0.75, 1.0, 1.0, 1.0, 0.3);
180 cr.set_source (progress_shine);
181 cr.set_line_width (progress_width);
182 cr.arc (xc, yc, progress_radius, start_angle, end_angle);
183 cr.stroke ();
185 // KnobShadow
186 // TODO?: blur 2.0
188 cr.set_line_width (progress_rim_width);
189 cr.set_source (create_gradient_str (86, 77, 38, 25, "#151928", "#151928", 1.0, 0.5));
190 cr.arc (xc, yc, progress_radius_inner, 0, 2 * Math.PI);
191 cr.stroke ();
194 // KnobRimPlain
195 cr.set_line_width (1.0);
196 cr.set_source_rgb (0.0, 0.0, 0.0);
197 cr.arc (xc, yc, progress_radius_inner, 0, 2 * Math.PI);
198 cr.set_source (create_gradient_str (35, 31, 75, 72, "#68625c", "#44494b"));
199 cr.fill ();
200 cr.set_source_rgb (0, 0, 0);
201 cr.arc (xc, yc, progress_radius_inner, 0, 2 * Math.PI);
202 cr.stroke ();
204 // KnobDiscBackground
205 cr.set_source (create_gradient_str (42, 34, 68, 70, "#e7ecef", "#9cafb8"));
206 cr.arc (xc, yc, knob_disc_radius, 0, 2 * Math.PI);
207 cr.fill ();
208 cr.set_line_width (2.0);
210 double degrees = Math.PI / 180.0;
212 // KnobRimShadow
213 // TODO
215 // KnobShineBright
216 cr.set_source (create_gradient_str (38, 34, 70, 68, "#ffffff", "#caddf2", 0.2, 0.2));
217 cr.move_to (xc,yc);
218 cr.arc (xc, yc, knob_disc_radius - 1, -154 * degrees, -120 * degrees);
219 cr.move_to (xc,yc);
220 cr.arc (xc, yc, knob_disc_radius - 1, Math.PI / 2.0 - 60 * degrees, Math.PI / 2.0 - 29 * degrees);
221 cr.fill ();
223 // KnobShineDark
224 cr.set_source (create_gradient_str (50, 40, 62, 60, "#a1adb6", "#47535c", 0.07, 0.15));
225 cr.move_to (xc,yc);
226 cr.arc (xc, yc, knob_disc_radius - 1, - 67 * degrees, - 27 * degrees);
227 cr.move_to (xc,yc);
228 cr.arc (xc, yc, knob_disc_radius - 1, Math.PI - 67 * degrees, Math.PI- 27 * degrees);
229 cr.fill ();
231 // KnobShineRipples
232 Cairo.Pattern knob_ripples = new Cairo.Pattern.radial (xc, yc, 0, xc, yc, 4);
233 add_color_stop_str (knob_ripples, 0.0, "#e7ecef", 0.05);
234 add_color_stop_str (knob_ripples, 0.5, "#58717d", 0.05);
235 add_color_stop_str (knob_ripples, 0.75, "#d1d9de", 0.05);
236 add_color_stop_str (knob_ripples, 1.0, "#5d7682", 0.05);
237 knob_ripples.set_extend(Cairo.Extend.REPEAT);
239 cr.set_line_width (0.0);
240 cr.set_source (knob_ripples);
241 cr.arc (xc, yc, knob_disc_radius, 0, 2 * Math.PI);
242 cr.fill ();
244 cr.save();
246 cr.translate (xc + knob_disc_radius * value_x,
247 yc + knob_disc_radius * value_y);
249 cr.rotate (value_angle - Math.PI);
251 // KnobIndicatorBay
252 cr.set_source (create_gradient_str (16, -2, 9, 13, "#e7ecef", "#9cafb8", 0.8, 0.8));
253 cr.move_to (0, 4);
254 cr.line_to (17, 4);
255 cr.curve_to (19, 4, 21, 2, 21, 0);
256 cr.curve_to (21, -2, 19, -4, 17, -4);
257 cr.line_to (0, -4);
258 cr.close_path();
259 cr.fill();
261 // KnobIndicator
262 cr.set_source (create_gradient_str (9, -2, 9, 2, "#68625c", "#44494b"));
263 cr.move_to (0, 2);
264 cr.line_to (16, 2);
265 cr.curve_to (17, 2, 18, 1, 18, 0);
266 cr.curve_to (18, -1, 17, -2, 16, -2);
267 cr.line_to (0, -2);
268 cr.close_path();
269 cr.fill();
271 cr.restore ();
273 // KnobDiscRim
274 cr.set_line_width (2.0);
275 cr.set_source (create_gradient_str (38, 32, 70, 67, "#3d3d3d", "#000000"));
276 cr.arc (xc, yc, knob_disc_radius, 0, 2 * Math.PI);
277 cr.stroke ();
279 cr.restore ();
282 } // namespace Prolooks