summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--callbacks.c157
-rw-r--r--callbacks.h25
-rw-r--r--deadbeef.glade17
-rw-r--r--interface.c32
-rw-r--r--main.c23
5 files changed, 222 insertions, 32 deletions
diff --git a/callbacks.c b/callbacks.c
index 0e8520c9..f96aaff0 100644
--- a/callbacks.c
+++ b/callbacks.c
@@ -776,3 +776,160 @@ on_playlist_save_as_activate (GtkMenuItem *menuitem,
save_playlist_as ();
}
+
+gboolean
+on_seekbar_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data)
+{
+
+ return FALSE;
+}
+
+enum
+{
+ CORNER_NONE = 0,
+ CORNER_TOPLEFT = 1,
+ CORNER_TOPRIGHT = 2,
+ CORNER_BOTTOMLEFT = 4,
+ CORNER_BOTTOMRIGHT = 8,
+ CORNER_ALL = 15
+};
+
+static void
+clearlooks_rounded_rectangle (cairo_t * cr,
+ double x, double y, double w, double h,
+ double radius, uint8_t corners)
+{
+ if (radius < 0.01 || (corners == CORNER_NONE)) {
+ cairo_rectangle (cr, x, y, w, h);
+ return;
+ }
+
+ if (corners & CORNER_TOPLEFT)
+ cairo_move_to (cr, x + radius, y);
+ else
+ cairo_move_to (cr, x, y);
+
+ if (corners & CORNER_TOPRIGHT)
+ cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 2);
+ else
+ cairo_line_to (cr, x + w, y);
+
+ if (corners & CORNER_BOTTOMRIGHT)
+ cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, M_PI * 0.5);
+ else
+ cairo_line_to (cr, x + w, y + h);
+
+ if (corners & CORNER_BOTTOMLEFT)
+ cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.5, M_PI);
+ else
+ cairo_line_to (cr, x, y + h);
+
+ if (corners & CORNER_TOPLEFT)
+ cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5);
+ else
+ cairo_line_to (cr, x, y);
+
+}
+
+int seekbar_moving = 0;
+int seekbar_move_x = 0;
+
+void
+seekbar_draw (GtkWidget *widget) {
+ if (!widget) {
+ return;
+ }
+ cairo_t *cr;
+ cr = gdk_cairo_create (widget->window);
+ if (!cr) {
+ return;
+ }
+ float pos = 0;
+ if (playlist_current.codec && playlist_current.duration > 0) {
+ pos = playlist_current.codec->info.position / playlist_current.duration;
+ pos *= widget->allocation.width;
+ }
+ // left
+ cairo_set_source_rgb (cr, 0xf4/255.f, 0x7e/255.f, 0x46/255.f);
+ cairo_rectangle (cr, 0, widget->allocation.height/2-4, pos, 8);
+ cairo_clip (cr);
+ clearlooks_rounded_rectangle (cr, 0, widget->allocation.height/2-4, widget->allocation.width, 8, 4, 0xff);
+ cairo_fill (cr);
+ cairo_reset_clip (cr);
+
+ // right
+ cairo_rectangle (cr, pos, widget->allocation.height/2-4, widget->allocation.width-pos, 8);
+ cairo_clip (cr);
+ cairo_set_source_rgb (cr, 0x21/255.f, 0x23/255.f, 0x1f/255.f);
+ clearlooks_rounded_rectangle (cr, 0, widget->allocation.height/2-4, widget->allocation.width, 8, 4, 0xff);
+ cairo_fill (cr);
+ cairo_reset_clip (cr);
+
+ if (seekbar_moving) {
+ cairo_set_source_rgb (cr, 1,1,1);
+ int x = seekbar_move_x;
+ if (x < 0) {
+ x = 0;
+ }
+ if (x > widget->allocation.width-8) {
+ x = widget->allocation.width-8;
+ }
+ clearlooks_rounded_rectangle (cr, x, widget->allocation.height/2-4, 8, 8, 4, 0xff);
+ cairo_fill (cr);
+ }
+
+ cairo_destroy (cr);
+}
+
+gboolean
+on_seekbar_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data)
+{
+ seekbar_draw (widget);
+ return FALSE;
+}
+
+
+gboolean
+on_seekbar_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data)
+{
+ if (seekbar_moving) {
+ seekbar_move_x = event->x;
+ seekbar_draw (widget);
+ }
+ return FALSE;
+}
+
+gboolean
+on_seekbar_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ seekbar_moving = 1;
+ seekbar_move_x = event->x;
+ seekbar_draw (widget);
+ return FALSE;
+}
+
+
+gboolean
+on_seekbar_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ seekbar_moving = 0;
+ seekbar_draw (widget);
+ float time = event->x * playlist_current.duration / (widget->allocation.width-8);
+ if (time < 0) {
+ time = 0;
+ }
+ messagepump_push (M_SONGSEEK, 0, time * 1000, 0);
+ return FALSE;
+}
+
+
diff --git a/callbacks.h b/callbacks.h
index 1daf45ed..476cb800 100644
--- a/callbacks.h
+++ b/callbacks.h
@@ -403,3 +403,28 @@ on_playlist_save_activate (GtkMenuItem *menuitem,
void
on_playlist_save_as_activate (GtkMenuItem *menuitem,
gpointer user_data);
+
+gboolean
+on_seekbar_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_seekbar_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data);
+
+gboolean
+on_seekbar_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer user_data);
+
+gboolean
+on_seekbar_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data);
+
+gboolean
+on_seekbar_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data);
diff --git a/deadbeef.glade b/deadbeef.glade
index 14c1bee2..60502f6a 100644
--- a/deadbeef.glade
+++ b/deadbeef.glade
@@ -525,19 +525,18 @@
</child>
<child>
- <widget class="GtkHScale" id="playpos">
+ <widget class="GtkDrawingArea" id="seekbar">
<property name="width_request">200</property>
<property name="visible">True</property>
- <property name="draw_value">False</property>
- <property name="value_pos">GTK_POS_TOP</property>
- <property name="digits">1</property>
- <property name="update_policy">GTK_UPDATE_DISCONTINUOUS</property>
- <property name="inverted">False</property>
- <property name="adjustment">0 0 1000 0 0 0</property>
- <signal name="value_changed" handler="on_playpos_value_changed" last_modification_time="Fri, 03 Jul 2009 23:43:55 GMT"/>
+ <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <signal name="button_press_event" handler="on_seekbar_button_press_event" last_modification_time="Tue, 11 Aug 2009 17:47:59 GMT"/>
+ <signal name="button_release_event" handler="on_seekbar_button_release_event" last_modification_time="Tue, 11 Aug 2009 17:48:02 GMT"/>
+ <signal name="configure_event" handler="on_seekbar_configure_event" last_modification_time="Tue, 11 Aug 2009 17:48:06 GMT"/>
+ <signal name="expose_event" handler="on_seekbar_expose_event" last_modification_time="Tue, 11 Aug 2009 17:48:11 GMT"/>
+ <signal name="motion_notify_event" handler="on_seekbar_motion_notify_event" last_modification_time="Tue, 11 Aug 2009 17:48:18 GMT"/>
</widget>
<packing>
- <property name="padding">0</property>
+ <property name="padding">2</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
diff --git a/interface.c b/interface.c
index 0f06bf18..db273a02 100644
--- a/interface.c
+++ b/interface.c
@@ -86,7 +86,7 @@ create_mainwin (void)
GtkWidget *image6;
GtkWidget *vbox2;
GtkWidget *volume;
- GtkWidget *playpos;
+ GtkWidget *seekbar;
GtkWidget *_;
GtkWidget *vbox3;
GtkWidget *header;
@@ -338,13 +338,11 @@ create_mainwin (void)
GTK_WIDGET_UNSET_FLAGS (volume, GTK_CAN_FOCUS);
gtk_scale_set_draw_value (GTK_SCALE (volume), FALSE);
- playpos = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 1000, 0, 0, 0)));
- gtk_widget_show (playpos);
- gtk_box_pack_start (GTK_BOX (hbox2), playpos, FALSE, TRUE, 0);
- gtk_widget_set_size_request (playpos, 200, -1);
- GTK_WIDGET_UNSET_FLAGS (playpos, GTK_CAN_FOCUS);
- gtk_scale_set_draw_value (GTK_SCALE (playpos), FALSE);
- gtk_range_set_update_policy (GTK_RANGE (playpos), GTK_UPDATE_DISCONTINUOUS);
+ seekbar = gtk_drawing_area_new ();
+ gtk_widget_show (seekbar);
+ gtk_box_pack_start (GTK_BOX (hbox2), seekbar, FALSE, TRUE, 2);
+ gtk_widget_set_size_request (seekbar, 200, -1);
+ gtk_widget_set_events (seekbar, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
_ = gtk_hbox_new (FALSE, 0);
gtk_widget_show (_);
@@ -455,8 +453,20 @@ create_mainwin (void)
g_signal_connect ((gpointer) volume, "value_changed",
G_CALLBACK (on_volume_value_changed),
NULL);
- g_signal_connect ((gpointer) playpos, "value_changed",
- G_CALLBACK (on_playpos_value_changed),
+ g_signal_connect ((gpointer) seekbar, "button_press_event",
+ G_CALLBACK (on_seekbar_button_press_event),
+ NULL);
+ g_signal_connect ((gpointer) seekbar, "button_release_event",
+ G_CALLBACK (on_seekbar_button_release_event),
+ NULL);
+ g_signal_connect ((gpointer) seekbar, "configure_event",
+ G_CALLBACK (on_seekbar_configure_event),
+ NULL);
+ g_signal_connect ((gpointer) seekbar, "expose_event",
+ G_CALLBACK (on_seekbar_expose_event),
+ NULL);
+ g_signal_connect ((gpointer) seekbar, "motion_notify_event",
+ G_CALLBACK (on_seekbar_motion_notify_event),
NULL);
g_signal_connect ((gpointer) header, "expose_event",
G_CALLBACK (on_header_expose_event),
@@ -583,7 +593,7 @@ create_mainwin (void)
GLADE_HOOKUP_OBJECT (mainwin, image6, "image6");
GLADE_HOOKUP_OBJECT (mainwin, vbox2, "vbox2");
GLADE_HOOKUP_OBJECT (mainwin, volume, "volume");
- GLADE_HOOKUP_OBJECT (mainwin, playpos, "playpos");
+ GLADE_HOOKUP_OBJECT (mainwin, seekbar, "seekbar");
GLADE_HOOKUP_OBJECT (mainwin, _, "_");
GLADE_HOOKUP_OBJECT (mainwin, vbox3, "vbox3");
GLADE_HOOKUP_OBJECT (mainwin, header, "header");
diff --git a/main.c b/main.c
index f4320ea8..dbd0dd65 100644
--- a/main.c
+++ b/main.c
@@ -43,7 +43,7 @@ int psdl_terminate = 0;
// update status bar and window title
static int sb_context_id = -1;
static char sb_text[512];
-static int last_songpos = -1;
+static float last_songpos = -1;
void
update_songinfo (void) {
@@ -51,10 +51,9 @@ update_songinfo (void) {
return;
}
char sbtext_new[512] = "-";
- int songpos = 0;
+ float songpos = last_songpos;
if (p_ispaused ()) {
strcpy (sbtext_new, "Paused");
- songpos = 0;
}
else if (p_isstopped ()) {
strcpy (sbtext_new, "Stopped");
@@ -69,9 +68,7 @@ update_songinfo (void) {
const char *mode = c->info.channels == 1 ? "Mono" : "Stereo";
int samplerate = c->info.samplesPerSecond;
int bitspersample = c->info.bitsPerSample;
- float pos = c->info.position;
- int dur = playlist_current.duration;
- songpos = pos * 1000 / dur;
+ songpos = c->info.position;
codec_unlock ();
snprintf (sbtext_new, 512, "[%s] %dHz | %d bit | %s | %d:%02d / %d:%02d | %d songs total", playlist_current.filetype ? playlist_current.filetype:"-", samplerate, bitspersample, mode, minpos, secpos, mindur, secdur, pl_getcount ());
@@ -95,12 +92,13 @@ update_songinfo (void) {
}
if (songpos != last_songpos) {
- last_songpos = songpos;
- extern int g_disable_seekbar_handler;
- g_disable_seekbar_handler = 1;
- GtkRange *seekbar = GTK_RANGE (lookup_widget (mainwin, "playpos"));
- gtk_range_set_value (seekbar, songpos);
- g_disable_seekbar_handler = 0;
+ void seekbar_draw (GtkWidget *widget);
+ if (mainwin) {
+ GDK_THREADS_ENTER();
+ seekbar_draw (lookup_widget (mainwin, "seekbar"));
+ GDK_THREADS_LEAVE();
+ last_songpos = songpos;
+ }
}
}
@@ -240,6 +238,7 @@ main (int argc, char *argv[]) {
mainwin = create_mainwin ();
gtk_widget_show (mainwin);
gtk_main ();
+ mainwin = NULL;
gdk_threads_leave ();
messagepump_free ();
psdl_terminate = 1;