2 Copyright 2009 by Hans Baier, Krzysztof Foltman
10 public class VUMeter
: DrawingArea
{
12 public enum VUMeterMode
{
17 private Cairo
.Surface? cache_surface
= null;
18 private VUMeterMode _mode
= VUMeterMode
.VU_STANDARD
;
19 private double _value
= 0.5;
23 if (Math
.fabs(_value
- value
) >= 0.0001)
31 public VUMeterMode mode
{
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
) {
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)
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(),
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
);
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;
81 case VUMeterMode
.VU_STANDARD
:
90 g
= 1 - (ts
- 0.75) / 0.25;
94 case VUMeterMode
.VU_MONOCHROME_REVERSE
:
99 case VUMeterMode
.VU_MONOCHROME
:
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
);
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
);
119 cr
.set_source_surface (cache_surface
, 0, 0);
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);
126 cr
.rectangle (ox
+ _value
* (sx
- ox
), oy
, sx
- ox
+ 1, sy
- oy
+ 1);
134 } // namespace Prolooks