Knob: instantiate SimpleKnobImageSource by default
[libprolooks.git] / prolooks / VuMeter.vala
blobbaed2755080398ee95765c206ed1cd442aa17616
1 /*
2 Copyright 2009 by Hans Baier, Krzysztof Foltman
3 License: LGPLv2+
4 */
6 using Gtk;
8 namespace Prolooks {
10 public class VuMeter : DrawingArea {
12 public enum VuMeterMode {
13 VU_STANDARD,
14 VU_MONOCHROME,
15 VU_MONOCHROME_REVERSE
17 private Cairo.Surface? cache_surface = null;
18 private VuMeterMode _mode = VuMeterMode.VU_STANDARD;
19 private double _value = 0.5;
21 public double value {
22 set {
23 if (Math.fabs(_value - value) >= 0.0001)
24 queue_draw();
25 _value = value;
27 get {
28 return _value;
31 public VuMeterMode mode {
32 set {
33 if (mode != _mode) {
34 mode = _mode;
35 queue_draw();
38 get {
39 return _mode;
43 public VuMeter () {
45 // Set favored widget size
46 set_size_request (100, 14);
49 /* Widget is asked to draw itself */
50 public override bool expose_event (Gdk.EventExpose event) {
51 int ox = 1, oy = 1;
52 int sx = allocation.width - 2, sy = allocation.height - 2;
54 // Create a Cairo context
55 var cr = Gdk.cairo_create (this.window);
57 if (cache_surface == null)
59 int x;
60 // looks like its either first call or the widget has been resized.
61 // create the cache_surface.
62 cache_surface = new Cairo.Surface.similar (cr.get_target(),
63 Cairo.Content.COLOR,
64 allocation.width,
65 allocation.height );
67 // And render the meterstuff again.
69 Cairo.Context cache_cr = new Cairo.Context ( cache_surface );
70 cache_cr.set_source_rgba (0, 0, 0, 0);
71 cache_cr.rectangle (ox, oy, sx, sy);
72 cache_cr.fill ();
73 cache_cr.set_line_width (1);
75 for (x = ox; x <= ox + sx; x += 3)
77 double ts = (x - ox) * 1.0 / sx;
78 double r = 0, g = 0, b = 0;
79 switch(mode)
81 case VuMeterMode.VU_STANDARD:
82 default:
83 if (ts < 0.75) {
84 r = ts / 0.75;
85 g = 1;
86 b = 0;
88 else {
89 r = 1;
90 g = 1 - (ts - 0.75) / 0.25;
91 b = 0;
93 break;
94 case VuMeterMode.VU_MONOCHROME_REVERSE:
95 r = 1;
96 g = 1;
97 b = 0;
98 break;
99 case VuMeterMode.VU_MONOCHROME:
100 r = 1;
101 g = 1;
102 b = 0;
103 break;
105 cache_cr.set_source_rgb(r, g, b);
106 cache_cr.move_to (x, oy);
107 cache_cr.line_to (x, oy + sy + 1);
108 cache_cr.move_to (x, oy + sy);
109 cache_cr.line_to (x, oy );
110 cache_cr.stroke ();
114 // Set clipping area in order to avoid unnecessary drawing
115 cr.rectangle (event.area.x, event.area.y,
116 event.area.width, event.area.height);
117 cr.clip ();
119 cr.set_source_surface (cache_surface, 0, 0);
120 cr.paint ();
121 cr.set_source_rgba (0, 0, 0, 0.5);
123 if( mode == VuMeterMode.VU_MONOCHROME_REVERSE )
124 cr.rectangle (ox, oy, _value * (sx - ox) + 1, sy - oy + 1);
125 else
126 cr.rectangle (ox + _value * (sx - ox), oy, sx - ox + 1, sy - oy + 1);
128 cr.fill ();
130 return false;
134 } // namespace Prolooks