diff options
-rw-r--r-- | callbacks.c | 157 | ||||
-rw-r--r-- | callbacks.h | 25 | ||||
-rw-r--r-- | deadbeef.glade | 17 | ||||
-rw-r--r-- | interface.c | 32 | ||||
-rw-r--r-- | main.c | 23 |
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"); @@ -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; |