summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--callbacks.c1
-rw-r--r--callbacks.h14
-rw-r--r--cmp3.c5
-rw-r--r--deadbeef.glade64
-rw-r--r--gtkplaylist.c149
-rw-r--r--interface.c24
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);
diff --git a/cmp3.c b/cmp3.c
index 87cc2be9..ad031349 100644
--- a/cmp3.c
+++ b/cmp3.c
@@ -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");