1 /* Gnome Music Player Client (GMPC)
2 * Copyright (C) 2004-2012 Qball Cow <qball@gmpclient.org>
3 * Project homepage: http://gmpclient.org/
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 private const bool use_transition
= Gmpc
.use_transition
;
27 public class Gmpc
.Progress
: Gtk
.VBox
29 private uint total
= 0;
30 private uint current
= 0;
31 private bool do_countdown
= false;
32 public bool _hide_text
= false;
33 private Gtk
.Scale scale
= null;
34 private Gtk
.Label label
= null;
35 private ulong set_value_handler
= 0;
36 private Gtk
.Window tooltip
= null;
37 private Gtk
.Label tooltip_label
= null;
44 /* If there is a tooltip on destruction of slider, destroy it */
45 if(this
.tooltip
!= null)
47 this
.tooltip
.destroy();
52 /* Set/getter for enabling/disabling text label */
70 * Paint a nice box around it
72 private bool tooltip_expose_event_callback(Gtk
.Widget tooltip
, Cairo
.Context ctx
)
75 Gtk.render_frame(tooltip.get_style_context(),
76 Gdk.cairo_create(tooltip.get_window()),
78 tooltip.get_allocated_width(), tooltip.get_allocated_height());
83 private bool enter_notify_event_callback(Gtk
.Widget scale
, Gdk
.EventCrossing event
)
85 /* Create tooltip if mouse enters the event window */
86 if (event
.type
== Gdk
.EventType
.ENTER_NOTIFY
)
88 if ( tooltip
!= null ) tooltip
.destroy();
89 tooltip
= new Gtk
.Window(Gtk
.WindowType
.POPUP
);
90 tooltip_label
= new Gtk
.Label("test");
91 tooltip
.add(tooltip_label
);
92 tooltip
.border_width
= 4;
93 tooltip
.set_app_paintable(true);
94 tooltip
.draw
.connect(tooltip_expose_event_callback
);
96 /* Destroy tooltip if mouse leaves the event window */
97 if (event
.type
== Gdk
.EventType
.LEAVE_NOTIFY
)
107 private bool motion_notify_event_callback(Gtk
.Widget scale
, Gdk
.EventMotion event
)
109 if(event
.type
== Gdk
.EventType
.MOTION_NOTIFY
)
113 int e_hour
, e_minutes
, e_seconds
;
114 int t_hour
= (int) this
.total
/ 3600;
115 int t_minutes
= (int) this
.total
%3600/60;
116 int t_seconds
= (int) this
.total
%60;
118 uint p
= (uint)(this
.total
* (event
.x
/(double)(scale
.get_allocated_width()-scale
.style
.xthickness
)));
119 /* Don't show beyond end time */
120 p
= (p
> this
.total
)? this
.total
:p
;
121 if(this
.do_countdown
)
126 e_hour
= (int) p
/3600;
127 e_minutes
= (int) (p
%3600)/60;
128 e_seconds
= (int) (p
%60);
131 a
+= "%02i:".printf(e_hour
);
133 a
+= "%02i:%02i".printf(e_minutes
, e_seconds
);
139 a
+= "%02i:".printf(t_hour
);
141 a
+= "%02i:%02i".printf(t_minutes
,t_seconds
);
143 if(this
.do_countdown
)
144 this
.tooltip_label
.width_chars
= (int)a
.length
;
146 this
.tooltip_label
.width_chars
= (int)a
.length
+1;
147 this
.tooltip_label
.set_text(a
);
151 tooltip
.move((int)event
.x_root
-tooltip
.get_allocated_width()/2, (int)event
.y_root
+tooltip
.get_allocated_height());
157 /* Construct function */
161 this
.scale
= new Gtk
.HScale(null);
162 this
.scale
.set_range(0.0,1.0);
163 this
.scale
.draw_value
= false;
164 this
.set_value_handler
= GLib
.Signal
.connect_swapped(this
.scale
,"value_changed",(GLib
.Callback
)value_changed
,this
);
165 // this.scale.update_policy = Gtk.UpdateType.DISCONTINUOUS;//DELAYED;//DISCONTINUOUS;
166 this
.scale
.sensitive
= false;
168 this
.scale
.add_events((int)Gdk
.EventMask
.SCROLL_MASK
);
169 this
.scale
.add_events((int)Gdk
.EventMask
.POINTER_MOTION_MASK
);
170 this
.scale
.add_events((int)Gdk
.EventMask
.ENTER_NOTIFY_MASK
);
171 this
.scale
.add_events((int)Gdk
.EventMask
.LEAVE_NOTIFY_MASK
);
172 this
.scale
.scroll_event
.connect(scroll_event_callback
);
173 GLib
.Signal
.connect_object(this
.scale
, "button-press-event",
174 (GLib
.Callback
)button_press_event_callback
, this
, GLib
.ConnectFlags
.SWAPPED
|GLib
.ConnectFlags
.AFTER
);
175 this
.scale
.button_release_event
.connect(button_release_event_callback
);
176 this
.scale
.motion_notify_event
.connect(motion_notify_event_callback
);
177 this
.scale
.enter_notify_event
.connect(enter_notify_event_callback
);
178 this
.scale
.leave_notify_event
.connect(enter_notify_event_callback
);
180 this
.label
= new Gtk
.Label("");
181 this
.label
.set_alignment(0.5f
,0.5f
);
182 this
.label
.set_no_show_all(true);
184 this
.pack_start(this
.scale
, true,true,0);
185 this
.pack_end(this
.label
, false,false,0);
192 public signal void seek_event (uint seek_time
);
195 private void value_changed (Gtk
.Scale range
)
199 uint seconds
= (uint)(this
.total
*(range
.get_value()));
200 if(seconds
!= this
.current
)
204 private int press
= 0;
205 private bool button_release_event_callback (Gtk
.Widget scale
, Gdk
.EventButton event
)
210 private bool button_press_event_callback (Gdk
.EventButton event
, Gtk
.Scale scale
)
213 if(event
.type
== Gdk
.EventType
.BUTTON_PRESS
)
215 if(event
.button
== 3)
217 this
.do_countdown
= !this
.do_countdown
;
218 var cur
= this
.current
;
219 var tot
= this
.total
;
220 this
.total
=this
.current
= 0;
223 if(event
.button
== 2 || event
.button
== 1)
225 uint p
= (uint)(this
.total
* (event
.x
/(double)(scale
.get_allocated_width()-scale
.style
.xthickness
)));
226 p
= (p
> this
.total
)? this
.total
:p
;
231 else if (event
.type
== Gdk
.EventType
.2BUTTON_PRESS
)
233 if(event
.button
== 2 || event
.button
== 1)
235 uint p
= (uint)(this
.total
* (event
.x
/(double)(scale
.get_allocated_width()-scale
.style
.xthickness
)));
236 p
= (p
> this
.total
)? this
.total
:p
;
244 private bool scroll_event_callback (Gtk
.Widget scale
,Gdk
.EventScroll event
)
246 if(event
.direction
== Gdk
.ScrollDirection
.UP
)
248 seek_event(this
.current
+5);
250 else if (event
.direction
== Gdk
.ScrollDirection
.DOWN
)
252 seek_event(this
.current
-5);
257 public void set_time(uint total
, uint current
)
259 if(this
.press
> 0) return;
260 if(this
.total
!= total
)
262 this
.scale
.sensitive
= (total
> 0);
265 if(this
.total
!= total
|| this
.current
!= current
)
268 this
.current
= current
;
270 GLib
.SignalHandler
.block(this
.scale
, this
.set_value_handler
);
273 this
.scale
.set_value(this
.current
/(double)this
.total
);
277 this
.scale
.set_value(0.0);
280 GLib
.SignalHandler
.unblock(this
.scale
, this
.set_value_handler
);
282 if(this
.hide_text
== false)
284 int e_hour
, e_minutes
, e_seconds
;
285 int t_hour
= (int) this
.total
/ 3600;
286 int t_minutes
= (int) this
.total
%3600/60;
287 int t_seconds
= (int) this
.total
%60;
289 uint p
= this
.current
;
290 if(this
.do_countdown
)
292 p
= this
.total
-this
.current
;
295 e_hour
= (int) p
/3600;
296 e_minutes
= (int) (p
%3600)/60;
297 e_seconds
= (int) (p
%60);
300 a
+= "%02i:".printf(e_hour
);
302 a
+= "%02i:%02i".printf(e_minutes
, e_seconds
);
308 a
+= "%02i:".printf(t_hour
);
310 a
+= "%02i:%02i".printf(t_minutes
,t_seconds
);
312 if(this
.do_countdown
)
313 this
.label
.width_chars
= (int)a
.length
;
315 this
.label
.width_chars
= (int)a
.length
+1;
316 this
.label
.set_text(a
);
322 /* vim: set noexpandtab ts=4 sw=4 sts=4 tw=120: */