diff options
-rw-r--r-- | callbacks.c | 1 | ||||
-rw-r--r-- | callbacks.h | 14 | ||||
-rw-r--r-- | cmp3.c | 5 | ||||
-rw-r--r-- | deadbeef.glade | 64 | ||||
-rw-r--r-- | gtkplaylist.c | 149 | ||||
-rw-r--r-- | interface.c | 24 |
6 files changed, 236 insertions, 21 deletions
diff --git a/callbacks.c b/callbacks.c index 78a7b9c1..d87a2896 100644 --- a/callbacks.c +++ b/callbacks.c @@ -524,3 +524,4 @@ on_voice5_clicked (GtkButton *button, codec_unlock (); } + diff --git a/callbacks.h b/callbacks.h index bd2800e6..1efce62e 100644 --- a/callbacks.h +++ b/callbacks.h @@ -204,3 +204,17 @@ void on_playlist_drag_data_delete (GtkWidget *widget, GdkDragContext *drag_context, gpointer user_data); + +gboolean +on_header_expose_event (GtkWidget *widget, + GdkEventExpose *event, + gpointer user_data); + +gboolean +on_header_configure_event (GtkWidget *widget, + GdkEventConfigure *event, + gpointer user_data); + +void +on_header_realize (GtkWidget *widget, + gpointer user_data); @@ -586,6 +586,7 @@ static const char * convstr (const char* str, int sz) { static char out[2048]; const char *enc = "iso8859-1"; + char *ret = out; // hack to add limited cp1251 recoding support @@ -624,8 +625,10 @@ convstr (const char* str, int sz) { memset (out, 0, sizeof (out)); size_t res = iconv (cd, &pin, &inbytesleft, &pout, &outbytesleft); iconv_close (cd); + ret = out + 3; } - return out; + //printf ("decoded %s\n", out+3); + return ret; } const char *convstr_id3v1 (const char* str, int sz) { diff --git a/deadbeef.glade b/deadbeef.glade index a30a7412..5299f80c 100644 --- a/deadbeef.glade +++ b/deadbeef.glade @@ -642,25 +642,53 @@ <property name="spacing">0</property> <child> - <widget class="GtkDrawingArea" id="playlist"> + <widget class="GtkVBox" id="vbox3"> <property name="visible">True</property> - <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK</property> - <signal name="configure_event" handler="on_playlist_configure_event" last_modification_time="Sat, 04 Jul 2009 00:03:23 GMT"/> - <signal name="expose_event" handler="on_playlist_expose_event" last_modification_time="Sat, 04 Jul 2009 00:03:29 GMT"/> - <signal name="realize" handler="on_playlist_realize" last_modification_time="Sat, 04 Jul 2009 00:03:36 GMT"/> - <signal name="button_press_event" handler="on_playlist_button_press_event" last_modification_time="Sat, 04 Jul 2009 00:41:38 GMT"/> - <signal name="scroll_event" handler="on_playlist_scroll_event" last_modification_time="Sat, 04 Jul 2009 17:16:21 GMT"/> - <signal name="drag_begin" handler="on_playlist_drag_begin" last_modification_time="Fri, 31 Jul 2009 10:36:23 GMT"/> - <signal name="drag_motion" handler="on_playlist_drag_motion" last_modification_time="Fri, 31 Jul 2009 10:36:30 GMT"/> - <signal name="drag_drop" handler="on_playlist_drag_drop" last_modification_time="Fri, 31 Jul 2009 10:36:39 GMT"/> - <signal name="drag_data_get" handler="on_playlist_drag_data_get" last_modification_time="Fri, 31 Jul 2009 10:36:43 GMT"/> - <signal name="drag_end" handler="on_playlist_drag_end" last_modification_time="Fri, 31 Jul 2009 11:41:00 GMT"/> - <signal name="drag_failed" handler="on_playlist_drag_failed" last_modification_time="Fri, 31 Jul 2009 11:41:05 GMT"/> - <signal name="drag_leave" handler="on_playlist_drag_leave" last_modification_time="Fri, 31 Jul 2009 11:41:11 GMT"/> - <signal name="button_release_event" handler="on_playlist_button_release_event" last_modification_time="Fri, 31 Jul 2009 12:20:56 GMT"/> - <signal name="motion_notify_event" handler="on_playlist_motion_notify_event" last_modification_time="Fri, 31 Jul 2009 12:23:49 GMT"/> - <signal name="drag_data_received" handler="on_playlist_drag_data_received" last_modification_time="Mon, 03 Aug 2009 12:07:39 GMT"/> - <signal name="drag_data_delete" handler="on_playlist_drag_data_delete" last_modification_time="Mon, 03 Aug 2009 12:35:47 GMT"/> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkDrawingArea" id="header"> + <property name="height_request">24</property> + <property name="visible">True</property> + <signal name="expose_event" handler="on_header_expose_event" last_modification_time="Thu, 06 Aug 2009 14:54:29 GMT"/> + <signal name="configure_event" handler="on_header_configure_event" last_modification_time="Thu, 06 Aug 2009 14:54:33 GMT"/> + <signal name="realize" handler="on_header_realize" last_modification_time="Thu, 06 Aug 2009 14:54:41 GMT"/> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkDrawingArea" id="playlist"> + <property name="visible">True</property> + <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK</property> + <signal name="configure_event" handler="on_playlist_configure_event" last_modification_time="Sat, 04 Jul 2009 00:03:23 GMT"/> + <signal name="expose_event" handler="on_playlist_expose_event" last_modification_time="Sat, 04 Jul 2009 00:03:29 GMT"/> + <signal name="realize" handler="on_playlist_realize" last_modification_time="Sat, 04 Jul 2009 00:03:36 GMT"/> + <signal name="button_press_event" handler="on_playlist_button_press_event" last_modification_time="Sat, 04 Jul 2009 00:41:38 GMT"/> + <signal name="scroll_event" handler="on_playlist_scroll_event" last_modification_time="Sat, 04 Jul 2009 17:16:21 GMT"/> + <signal name="drag_begin" handler="on_playlist_drag_begin" last_modification_time="Fri, 31 Jul 2009 10:36:23 GMT"/> + <signal name="drag_motion" handler="on_playlist_drag_motion" last_modification_time="Fri, 31 Jul 2009 10:36:30 GMT"/> + <signal name="drag_drop" handler="on_playlist_drag_drop" last_modification_time="Fri, 31 Jul 2009 10:36:39 GMT"/> + <signal name="drag_data_get" handler="on_playlist_drag_data_get" last_modification_time="Fri, 31 Jul 2009 10:36:43 GMT"/> + <signal name="drag_end" handler="on_playlist_drag_end" last_modification_time="Fri, 31 Jul 2009 11:41:00 GMT"/> + <signal name="drag_failed" handler="on_playlist_drag_failed" last_modification_time="Fri, 31 Jul 2009 11:41:05 GMT"/> + <signal name="drag_leave" handler="on_playlist_drag_leave" last_modification_time="Fri, 31 Jul 2009 11:41:11 GMT"/> + <signal name="button_release_event" handler="on_playlist_button_release_event" last_modification_time="Fri, 31 Jul 2009 12:20:56 GMT"/> + <signal name="motion_notify_event" handler="on_playlist_motion_notify_event" last_modification_time="Fri, 31 Jul 2009 12:23:49 GMT"/> + <signal name="drag_data_received" handler="on_playlist_drag_data_received" last_modification_time="Mon, 03 Aug 2009 12:07:39 GMT"/> + <signal name="drag_data_delete" handler="on_playlist_drag_data_delete" last_modification_time="Mon, 03 Aug 2009 12:35:47 GMT"/> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> </widget> <packing> <property name="padding">0</property> diff --git a/gtkplaylist.c b/gtkplaylist.c index 8971a4c8..8dbd44bc 100644 --- a/gtkplaylist.c +++ b/gtkplaylist.c @@ -30,6 +30,64 @@ static double playlist_clicktime = 0; static double ps_lastpos[2]; static int shift_sel_anchor = -1; +#define ncolumns 5 +#define colname_max 100 + +int refit_header = 1; + +const char *colnames[ncolumns] = { + "Playing Status", + "Album / Title", + "Track №", + "Title / Track Artist", + "Duration" +}; +char colnames_fitted[ncolumns][colname_max]; + +int colwidths[] = { + 50, 200, 50, 200, 50 +}; + +int +fit_text (cairo_t *cr, char *out, int len, const char *in, int width) { + int l = strlen (in); + len--; + l = min (len, l); + strncpy (out, in, l); + out[l] = 0; + int w = 0; + + char *p = &out[l-1]; + p = g_utf8_find_prev_char (out, p); + int processed = 0; + for (;;) { + cairo_text_extents_t e; + cairo_text_extents (cr, out, &e); + w = e.width;// + e.x_bearing + e.x_advance; + if (e.width <= width && (processed == 0 || processed >= 3)) { + break; + } + char *prev = g_utf8_find_prev_char (out, p); + + if (!prev) { + break; + } + int i; + for (i = 0; i < p-prev; i++) { + prev[i] = '.'; + } + processed += p-prev; + p = prev; + if (processed >= 3) { + for (int i = 0; i < 3; i++) { + p[i] = '.'; + } + p[3] = 0; + } + } + return w; +} + static void text_draw (cairo_t *cr, int x, int y, const char *text) { cairo_move_to (cr, x, y+rowheight-3); @@ -142,10 +200,37 @@ draw_ps_row (GdkDrawable *drawable, cairo_t *cr, int row, playItem_t *it) { else { cairo_set_source_rgb (cr, 0xf4/255.f, 0x7e/255.f, 0x46/255.f); } + cairo_set_font_size (cr, rowheight-4); + // draw as columns + const char *columns[ncolumns] = { + "", + ps_find_meta (it, "artist"), + ps_find_meta (it, "track"), + ps_find_meta (it, "title"), + "0:00" + }; + int x = 0; +#if 1 + for (int i = 0; i < ncolumns; i++) { + char str[512]; + if (i > 0) { + int w = fit_text (cr, str, 512, columns[i], colwidths[i]-6); +// printf ("draw %s -> %s\n", columns[i], str); + if (i == 2) { + text_draw (cr, x + colwidths[i] - w - 3, row * rowheight - scrollpos * rowheight, str); + } + else { + text_draw (cr, x + 3, row * rowheight - scrollpos * rowheight, str); + } + } + x += colwidths[i] + 2; + } +#endif +#if 0 char dname[512]; ps_format_item_display_name (it, dname, 512); - cairo_set_font_size (cr, rowheight-4); text_draw (cr, rowheight, row * rowheight - scrollpos * rowheight, dname); +#endif } @@ -995,3 +1080,65 @@ gtkps_handle_fm_drag_drop (int drop_y, void *ptr, int length) { draw_playlist (widget, 0, 0, widget->allocation.width, widget->allocation.height); gtkps_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height); } + +gboolean +on_header_expose_event (GtkWidget *widget, + GdkEventExpose *event, + gpointer user_data) +{ + int x = 0; + int w = 100; + int h = widget->allocation.height; + const char *detail = "toolbar"; + + for (int i = 0; i < ncolumns; i++) { + if (x >= widget->allocation.width) { + break; + } + w = colwidths[i]; + gtk_paint_box (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, NULL, detail, x, 0, w, h); + gtk_paint_vline (widget->style, widget->window, GTK_STATE_NORMAL, NULL, NULL, NULL, 0, h, x+w); + x += w + 2; + } + if (x < widget->allocation.width) { + gtk_paint_box (widget->style, widget->window, GTK_STATE_INSENSITIVE, GTK_SHADOW_OUT, NULL, NULL, detail, x, 0, widget->allocation.width-x, h); + } + cairo_t *cr; + cr = gdk_cairo_create (widget->window); + if (!cr) { + return FALSE; + } + x = 0; + for (int i = 0; i < ncolumns; i++) { + if (x >= widget->allocation.width) { + break; + } + w = colwidths[i]; + cairo_move_to (cr, x + 5, 15); + if (refit_header) { + fit_text (cr, colnames_fitted[i], colname_max, colnames[i], colwidths[i]-10); + } + cairo_show_text (cr, colnames_fitted[i]); + x += w + 2; + } + refit_header = 0; + cairo_destroy (cr); + return FALSE; +} + + +gboolean +on_header_configure_event (GtkWidget *widget, + GdkEventConfigure *event, + gpointer user_data) +{ + return FALSE; +} + + +void +on_header_realize (GtkWidget *widget, + gpointer user_data) +{ +} + diff --git a/interface.c b/interface.c index 58237b46..748d0007 100644 --- a/interface.c +++ b/interface.c @@ -84,6 +84,8 @@ create_mainwin (void) GtkWidget *handlebox4; GtkWidget *playpos; GtkWidget *_; + GtkWidget *vbox3; + GtkWidget *header; GtkWidget *playlist; GtkWidget *playscroll; GtkWidget *statusbar; @@ -343,9 +345,18 @@ create_mainwin (void) gtk_box_pack_start (GTK_BOX (vbox1), _, TRUE, TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (_), 3); + vbox3 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox3); + gtk_box_pack_start (GTK_BOX (_), vbox3, TRUE, TRUE, 0); + + header = gtk_drawing_area_new (); + gtk_widget_show (header); + gtk_box_pack_start (GTK_BOX (vbox3), header, FALSE, TRUE, 0); + gtk_widget_set_size_request (header, -1, 24); + playlist = gtk_drawing_area_new (); gtk_widget_show (playlist); - gtk_box_pack_start (GTK_BOX (_), playlist, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox3), playlist, TRUE, TRUE, 0); gtk_widget_set_events (playlist, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); playscroll = gtk_vscrollbar_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 1, 1, 0, 0))); @@ -431,6 +442,15 @@ create_mainwin (void) g_signal_connect ((gpointer) playpos, "value_changed", G_CALLBACK (on_playpos_value_changed), NULL); + g_signal_connect ((gpointer) header, "expose_event", + G_CALLBACK (on_header_expose_event), + NULL); + g_signal_connect ((gpointer) header, "configure_event", + G_CALLBACK (on_header_configure_event), + NULL); + g_signal_connect ((gpointer) header, "realize", + G_CALLBACK (on_header_realize), + NULL); g_signal_connect ((gpointer) playlist, "configure_event", G_CALLBACK (on_playlist_configure_event), NULL); @@ -539,6 +559,8 @@ create_mainwin (void) GLADE_HOOKUP_OBJECT (mainwin, handlebox4, "handlebox4"); GLADE_HOOKUP_OBJECT (mainwin, playpos, "playpos"); GLADE_HOOKUP_OBJECT (mainwin, _, "_"); + GLADE_HOOKUP_OBJECT (mainwin, vbox3, "vbox3"); + GLADE_HOOKUP_OBJECT (mainwin, header, "header"); GLADE_HOOKUP_OBJECT (mainwin, playlist, "playlist"); GLADE_HOOKUP_OBJECT (mainwin, playscroll, "playscroll"); GLADE_HOOKUP_OBJECT (mainwin, statusbar, "statusbar"); |