made prolooks more glade-friendly + assorted bugfixes
[libprolooks.git] / prolooks / VuMeter.vala
blobe7e241fedde7cdf4d1793ddc57ad900810aa4c76
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 Mode {
13 STANDARD,
14 MONOCHROME,
15 MONOCHROME_REVERSE
18 private Cairo.Surface? cache_surface = null;
19 private Mode _mode = Mode.STANDARD; 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;
32 public Mode mode {
33 set {
34 if (value != _mode) {
35 _mode = value;
36 cache_surface = null;
37 queue_draw();
40 get {
41 return _mode;
45 public VuMeter () {
47 // Set favored widget size
48 set_size_request (100, 14);
51 /* Widget is asked to draw itself */
52 public override bool expose_event (Gdk.EventExpose event) {
53 int ox = 1, oy = 1;
54 int sx = allocation.width - 2, sy = allocation.height - 2;
56 // Create a Cairo context
57 var cr = Gdk.cairo_create (this.window);
59 if (cache_surface == null)
61 int x;
62 // looks like its either first call or the widget has been resized.
63 // create the cache_surface.
64 cache_surface = new Cairo.Surface.similar (cr.get_target(),
65 Cairo.Content.COLOR,
66 allocation.width,
67 allocation.height );
69 // And render the meterstuff again.
71 Cairo.Context cache_cr = new Cairo.Context ( cache_surface );
72 cache_cr.set_source_rgba (0, 0, 0, 0);
73 cache_cr.rectangle (ox, oy, sx, sy);
74 cache_cr.fill ();
75 cache_cr.set_line_width (1);
77 for (x = ox; x <= ox + sx; x += 3)
79 double ts = (x - ox) * 1.0 / sx;
80 double r = 0, g = 0, b = 0;
81 switch(mode)
83 case Mode.STANDARD:
84 default:
85 if (ts < 0.75) {
86 r = ts / 0.75;
87 g = 1;
88 b = 0;
90 else {
91 r = 1;
92 g = 1 - (ts - 0.75) / 0.25;
93 b = 0;
95 break;
96 case Mode.MONOCHROME_REVERSE:
97 r = 1;
98 g = 1;
99 b = 0;
100 break;
101 case Mode.MONOCHROME:
102 r = 1;
103 g = 1;
104 b = 0;
105 break;
107 cache_cr.set_source_rgb(r, g, b);
108 cache_cr.move_to (x, oy);
109 cache_cr.line_to (x, oy + sy + 1);
110 cache_cr.move_to (x, oy + sy);
111 cache_cr.line_to (x, oy );
112 cache_cr.stroke ();
116 // Set clipping area in order to avoid unnecessary drawing
117 cr.rectangle (event.area.x, event.area.y,
118 event.area.width, event.area.height);
119 cr.clip ();
121 cr.set_source_surface (cache_surface, 0, 0);
122 cr.paint ();
123 cr.set_source_rgba (0, 0, 0, 0.5);
125 if( mode == Mode.MONOCHROME_REVERSE )
126 cr.rectangle (ox, oy, _value * (sx - ox) + 1, sy - oy + 1);
127 else
128 cr.rectangle (ox + _value * (sx - ox), oy, sx - ox + 1, sy - oy + 1);
130 cr.fill ();
132 return false;
136 } // namespace Prolooks