7 public class Display
: DisplayBase
{
19 private string _time_alt
;
20 public string time_alt
{
21 get { return _time_alt
; }
23 if (_time_alt
!= value
) {
30 private double realtime_x
;
31 private double realtime_y
;
32 private double realtime_w
;
33 private double realtime_h
;
35 public signal void toggle_realtime_requested (bool new_state
);
36 public bool realtime
{ get; set; }
39 private double xruns_x
;
40 private double xruns_y
;
41 private double xruns_w
;
42 private double xruns_h
;
43 private uint32 _xruns
;
45 public signal void reset_xruns_requested ();
51 if (_xruns
!= value
) {
58 static jack_nframes_t
[] sample_rates
= { 22050, 32000, 44100, 48000, 96000, 192000 };
59 private jack_nframes_t _sample_rate
;
60 public jack_nframes_t sample_rate
{
65 if (_sample_rate
!= value
) {
71 public signal void sample_rate_changed (jack_nframes_t new_sample_rate
);
72 private double sample_rate_x
;
73 private double sample_rate_y
;
74 private double sample_rate_w
;
75 private double sample_rate_h
;
76 private Menu sample_rate_menu
;
78 private jack_nframes_t _buffer_size
;
79 public jack_nframes_t buffer_size
{
84 if (_buffer_size
!= value
) {
91 static uint[] buffer_sizes
= { 16, 32, 64, 128, 256, 512, 1024, 2048 };
92 public signal void buffer_size_changed (jack_nframes_t new_buffer_size
);
93 private double buffer_size_x
;
94 private double buffer_size_y
;
95 private double buffer_size_w
;
96 private double buffer_size_h
;
97 private Menu buffer_size_menu
;
104 set_size_request (width
, height
);
108 private double popup_triangle_width () { return 7.0; }
110 public void draw_popup_triangle (Cairo
.Context cr
, double x
, double y
) {
112 set_source_from_color_string (cr
, "#b3b6af");
115 cr
.line_to (x
+ popup_triangle_width (), y
);
116 cr
.line_to (x
+ popup_triangle_width () / 2.0, y
+ 4);
122 protected override bool draw_contents (Cairo
.Context cr
, Gdk
.EventExpose event
) {
124 double font_size
= 16;
125 double smaller_font_size
= font_size
- 4;
127 double y
= font_size
;
129 ///////////////////////////// ABOVE
131 text (cr
, time
, padding
+ x
, y
, font_size
);
133 Cairo
.TextExtents ext
= Cairo
.TextExtents();
134 cr
.text_extents (time_alt
, ref ext
);
136 // show alt text right justified
137 text (cr
, time_alt
, inner_width
- ext
.x_advance
- ext
.x_bearing
- padding
, y
, font_size
);
139 ////////////////////////////// LINES
142 Color
.parse (text_color_default
, out line_color
);
143 set_source_from_color (cr
, line_color
, 0.5);
145 /* shows text boundaries for visual debugging: left bound
146 cr.move_to (x, y + ext.y_bearing);
147 cr.rel_line_to (0, ext.height);
151 cr
.text_extents (time
, ref ext
);
152 // clock time separator line
153 var vline_x
= padding
+ x
+ ext
.x_advance
+ ext
.x_bearing
+ padding
+ 1;
155 cr
.move_to (vline_x
, padding
);
156 cr
.rel_line_to (0, inner_height
- 2 * padding
+ 1);
159 var hline_y
= padding
+ ext
.height
+ padding
+ 2;
161 // vertical separator line
162 cr
.move_to (padding
, hline_y
);
163 cr
.rel_line_to (width
- 20, 0);
166 ////////////////////////////// BELOW
167 var y_text_below
= 0.5 + hline_y
+ smaller_font_size
;
171 cr
.text_extents (rt
, ref ext
);
173 text (cr
, rt
, padding
, y_text_below
, smaller_font_size
);
176 realtime_x
= padding
;
177 realtime_y
= y_text_below
- ext
.height
;
178 realtime_w
= ext
.x_advance
;
179 realtime_h
= ext
.height
+ ext
.y_bearing
;
182 var x_after_rt
= padding
+ ext
.x_advance
;
185 string xruns_str
= "X: %u".printf (xruns
);
186 cr
.text_extents (xruns_str
, ref ext
);
188 text (cr
, xruns_str
, x_after_rt
, y_text_below
, smaller_font_size
);
190 text (cr
, xruns_str
, x_after_rt
, y_text_below
, smaller_font_size
, "#ff0000");
193 xruns_x
= x_after_rt
;
194 xruns_y
= y_text_below
- ext
.height
;
195 xruns_w
= vline_x
- x_after_rt
;
196 xruns_h
= ext
.height
;
199 set_source_from_color_string (cr, "#ff0000");
200 cr.rectangle (xruns_x, xruns_y, xruns_w, xruns_h);
205 string buffer_size_str
= "%2.1fms".printf (buffer_size
*1000.0/(double)sample_rate
);
207 cr
.text_extents (buffer_size_str
, ref ext
);
208 var y_popup_triangle
= y_text_below
- ext
.height
+ 1.0;
210 buffer_size_x
= vline_x
+ padding
;
211 buffer_size_y
= y_popup_triangle
;
212 buffer_size_w
= ext
.x_advance
+ ext
.x_bearing
+ popup_triangle_width ();
213 buffer_size_h
= ext
.height
;
214 text (cr
, buffer_size_str
, buffer_size_x
, y_text_below
, smaller_font_size
);
215 draw_popup_triangle (cr
, buffer_size_x
+ ext
.x_advance
+ ext
.x_bearing
+ 1.0, y_popup_triangle
);
218 string sample_rate_str
= "%u".printf (sample_rate
);
219 cr
.text_extents (sample_rate_str
, ref ext
);
221 sample_rate_x
= inner_width
- ext
.x_advance
- ext
.x_bearing
- padding
- 1 - popup_triangle_width ();
222 sample_rate_y
= y_popup_triangle
;
223 sample_rate_w
= ext
.x_advance
+ ext
.x_bearing
+ popup_triangle_width ();
224 sample_rate_h
= ext
.height
;
225 text (cr
, sample_rate_str
, sample_rate_x
, y_text_below
, smaller_font_size
);
226 draw_popup_triangle (cr
, inner_width
- popup_triangle_width () - padding
, y_popup_triangle
);
231 private bool is_in_rect (double x
, double y
, double r_x
, double r_y
, double r_w
, double r_h
) {
234 return (r_x
<= x
) && (x
<= r_x
+ r_w
)
235 && (r_y
<= y
) && (y
<= r_y
+ r_h
);
238 public override bool button_press_event (Gdk
.EventButton event
) {
239 if (event
.type
== EventType
.BUTTON_PRESS
) {
240 if (is_in_rect (event
.x
, event
.y
, sample_rate_x
, sample_rate_y
, sample_rate_w
, sample_rate_h
)) {
241 sample_rate_menu
= new
Menu();
242 for (int i
= 0; i
< sample_rates
.length
; i
++) {
243 var item
= new MenuItem
.with_label ("%u".printf (sample_rates
[i
]));
244 item
.activate
+= (item
) => {
245 string rate_str
= ((Gtk
.Label
)((Gtk
.Item
)item
).get_child ()).get_text();
246 var new_rate
= (jack_nframes_t
) rate_str
.to_ulong ();
247 if (new_rate
!= sample_rate
) {
248 sample_rate_changed (new_rate
);
251 sample_rate_menu
.append (item
);
254 sample_rate_menu
.popup (null, null, null, 3, event
.time
);
255 sample_rate_menu
.show_all();
258 if (is_in_rect (event
.x
, event
.y
, buffer_size_x
, buffer_size_y
, buffer_size_w
, buffer_size_h
)) {
259 buffer_size_menu
= new
Menu ();
260 for (int i
= 0; i
< buffer_sizes
.length
; i
++) {
261 var item
= new MenuItem
.with_label ("%2.1fms".printf (buffer_sizes
[i
]*1000.0/(double)sample_rate
));
262 item
.user_data
= &buffer_sizes
[i
];
263 item
.activate
+= (item
) => {
264 buffer_size_changed (*((jack_nframes_t
*)item
.user_data
));
266 buffer_size_menu
.append (item
);
269 buffer_size_menu
.popup (null, null, null, 3, event
.time
);
270 buffer_size_menu
.show_all();
275 if (event
.type
== EventType
.BUTTON_PRESS
&& event
.button
== 1) {
276 if (is_in_rect (event
.x
, event
.y
, realtime_x
, realtime_y
, realtime_w
, realtime_h
)) {
277 toggle_realtime_requested (!realtime
);
280 if (is_in_rect (event
.x
, event
.y
, xruns_x
, xruns_y
, xruns_w
, xruns_h
)) {
281 reset_xruns_requested ();
287 private bool was_in_realtime_rect
;
289 /* Mouse pointer moved over widget */
290 public override bool motion_notify_event (Gdk
.EventMotion event
) {
292 var cr = Gdk.cairo_create (this.window);
294 if (is_in_rect (event.x, event.y, realtime_x, realtime_y, realtime_w, realtime_h)) {
295 was_in_realtime_rect = true;
296 set_source_from_color_string (cr, text_color_default, 0.1);
297 cr.rectangle (realtime_x, realtime_y, realtime_w, realtime_h);
300 if (was_in_realtime_rect) {
310 } //namespace Jackpanel