From d7644e273f412f9e6fa5dff8d39daba1e8be5228 Mon Sep 17 00:00:00 2001 From: Alexey Yakovenko Date: Sun, 7 Feb 2010 22:20:19 +0100 Subject: tabs for multiple playlists WIP --- plugins/gtkui/Makefile.am | 3 +- plugins/gtkui/callbacks.c | 4 - plugins/gtkui/callbacks.h | 25 +++++++ plugins/gtkui/deadbeef.glade | 53 +++++++++----- plugins/gtkui/gdkdrawing.c | 13 +++- plugins/gtkui/interface.c | 44 ++++++++--- plugins/gtkui/tabs.c | 169 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 273 insertions(+), 38 deletions(-) create mode 100644 plugins/gtkui/tabs.c (limited to 'plugins') diff --git a/plugins/gtkui/Makefile.am b/plugins/gtkui/Makefile.am index 146e76db..3ef740f5 100644 --- a/plugins/gtkui/Makefile.am +++ b/plugins/gtkui/Makefile.am @@ -9,7 +9,8 @@ gtkui_la_SOURCES = gtkui.c gtkui.h\ search.c search.h\ fileman.c\ pluginconf.c\ - parser.c parser.h + parser.c parser.h\ + tabs.c gtkui_la_LDFLAGS = -module diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c index 737fcaa3..e031f909 100644 --- a/plugins/gtkui/callbacks.c +++ b/plugins/gtkui/callbacks.c @@ -2301,7 +2301,3 @@ on_trackproperties_delete_event (GtkWidget *widget, trackproperties = NULL; return FALSE; } - - - - diff --git a/plugins/gtkui/callbacks.h b/plugins/gtkui/callbacks.h index 40c0048c..5070d73e 100644 --- a/plugins/gtkui/callbacks.h +++ b/plugins/gtkui/callbacks.h @@ -811,3 +811,28 @@ on_pref_dynsamplerate_clicked (GtkButton *button, void on_pref_close_clicked (GtkButton *button, gpointer user_data); + +gboolean +on_tabbar_button_press_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + +gboolean +on_tabbar_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); + +gboolean +on_tabbar_configure_event (GtkWidget *widget, + GdkEventConfigure *event, + gpointer user_data); + +gboolean +on_tabbar_expose_event (GtkWidget *widget, + GdkEventExpose *event, + gpointer user_data); + +gboolean +on_tabbar_motion_notify_event (GtkWidget *widget, + GdkEventMotion *event, + gpointer user_data); diff --git a/plugins/gtkui/deadbeef.glade b/plugins/gtkui/deadbeef.glade index 239398b9..34ea1a3f 100644 --- a/plugins/gtkui/deadbeef.glade +++ b/plugins/gtkui/deadbeef.glade @@ -793,6 +793,23 @@ + + + 24 + True + + + + + + + + 0 + False + True + + + 1 @@ -810,6 +827,24 @@ 0 0 + + + True + GTK_UPDATE_CONTINUOUS + False + 0 0 1 1 0 0 + + + + 1 + 2 + 0 + 1 + fill + fill + + + True @@ -884,24 +919,6 @@ - - - True - GTK_UPDATE_CONTINUOUS - False - 0 0 1 1 0 0 - - - - 1 - 2 - 0 - 1 - fill - fill - - - True diff --git a/plugins/gtkui/gdkdrawing.c b/plugins/gtkui/gdkdrawing.c index b2fe9710..29238689 100644 --- a/plugins/gtkui/gdkdrawing.c +++ b/plugins/gtkui/gdkdrawing.c @@ -142,9 +142,14 @@ draw_text_with_colors (float x, float y, int width, int align, const char *text) void draw_get_text_extents (const char *text, int len, int *w, int *h) { draw_init_font (); + pango_layout_set_width (pangolayout, 1000 * PANGO_SCALE); + pango_layout_set_alignment (pangolayout, PANGO_ALIGN_LEFT); pango_layout_set_text (pangolayout, text, len); - PangoRectangle ext; - pango_layout_get_pixel_extents (pangolayout, &ext, NULL); - *w = ext.width; - *h = ext.height; + PangoRectangle ink; + PangoRectangle log; + pango_layout_get_pixel_extents (pangolayout, &ink, &log); + *w = ink.width; + *h = ink.height; + printf ("ink: %d %d %d %d\n", ink.x, ink.y, ink.width, ink.height); + printf ("log: %d %d %d %d\n", log.x, log.y, log.width, log.height); } diff --git a/plugins/gtkui/interface.c b/plugins/gtkui/interface.c index 797186a7..c0897f13 100644 --- a/plugins/gtkui/interface.c +++ b/plugins/gtkui/interface.c @@ -110,13 +110,14 @@ create_mainwin (void) GtkWidget *image5; GtkWidget *seekbar; GtkWidget *volumebar; + GtkWidget *tabbar; GtkWidget *frame1; GtkWidget *table1; + GtkWidget *playscroll; GtkWidget *_; GtkWidget *vbox3; GtkWidget *header; GtkWidget *playlist; - GtkWidget *playscroll; GtkWidget *playhscroll; GtkWidget *statusbar; GtkAccelGroup *accel_group; @@ -501,6 +502,11 @@ create_mainwin (void) gtk_widget_set_size_request (volumebar, 70, -1); gtk_widget_set_events (volumebar, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); + tabbar = gtk_drawing_area_new (); + gtk_widget_show (tabbar); + gtk_box_pack_start (GTK_BOX (vbox1), tabbar, FALSE, TRUE, 0); + gtk_widget_set_size_request (tabbar, -1, 24); + frame1 = gtk_frame_new (NULL); gtk_widget_show (frame1); gtk_box_pack_start (GTK_BOX (vbox1), frame1, TRUE, TRUE, 0); @@ -510,6 +516,12 @@ create_mainwin (void) gtk_widget_show (table1); gtk_container_add (GTK_CONTAINER (frame1), table1); + playscroll = gtk_vscrollbar_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 1, 1, 0, 0))); + gtk_widget_show (playscroll); + gtk_table_attach (GTK_TABLE (table1), playscroll, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + _ = gtk_hbox_new (FALSE, 0); gtk_widget_show (_); gtk_table_attach (GTK_TABLE (table1), _, 0, 1, 0, 1, @@ -531,12 +543,6 @@ create_mainwin (void) 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))); - gtk_widget_show (playscroll); - gtk_table_attach (GTK_TABLE (table1), playscroll, 1, 2, 0, 1, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - playhscroll = gtk_hscrollbar_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 0, 0, 0, 0))); gtk_widget_show (playhscroll); gtk_table_attach (GTK_TABLE (table1), playhscroll, 0, 1, 1, 2, @@ -700,6 +706,24 @@ create_mainwin (void) g_signal_connect ((gpointer) volumebar, "scroll_event", G_CALLBACK (on_volumebar_scroll_event), NULL); + g_signal_connect ((gpointer) tabbar, "button_press_event", + G_CALLBACK (on_tabbar_button_press_event), + NULL); + g_signal_connect ((gpointer) tabbar, "button_release_event", + G_CALLBACK (on_tabbar_button_release_event), + NULL); + g_signal_connect ((gpointer) tabbar, "configure_event", + G_CALLBACK (on_tabbar_configure_event), + NULL); + g_signal_connect ((gpointer) tabbar, "expose_event", + G_CALLBACK (on_tabbar_expose_event), + NULL); + g_signal_connect ((gpointer) tabbar, "motion_notify_event", + G_CALLBACK (on_tabbar_motion_notify_event), + NULL); + g_signal_connect ((gpointer) playscroll, "value_changed", + G_CALLBACK (on_playscroll_value_changed), + NULL); g_signal_connect ((gpointer) header, "expose_event", G_CALLBACK (on_header_expose_event), NULL); @@ -766,9 +790,6 @@ create_mainwin (void) g_signal_connect ((gpointer) playlist, "drag_data_delete", G_CALLBACK (on_playlist_drag_data_delete), NULL); - g_signal_connect ((gpointer) playscroll, "value_changed", - G_CALLBACK (on_playscroll_value_changed), - NULL); g_signal_connect ((gpointer) playhscroll, "value_changed", G_CALLBACK (on_playhscroll_value_changed), NULL); @@ -853,13 +874,14 @@ create_mainwin (void) GLADE_HOOKUP_OBJECT (mainwin, image5, "image5"); GLADE_HOOKUP_OBJECT (mainwin, seekbar, "seekbar"); GLADE_HOOKUP_OBJECT (mainwin, volumebar, "volumebar"); + GLADE_HOOKUP_OBJECT (mainwin, tabbar, "tabbar"); GLADE_HOOKUP_OBJECT (mainwin, frame1, "frame1"); GLADE_HOOKUP_OBJECT (mainwin, table1, "table1"); + GLADE_HOOKUP_OBJECT (mainwin, playscroll, "playscroll"); 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, playhscroll, "playhscroll"); GLADE_HOOKUP_OBJECT (mainwin, statusbar, "statusbar"); diff --git a/plugins/gtkui/tabs.c b/plugins/gtkui/tabs.c new file mode 100644 index 00000000..43810498 --- /dev/null +++ b/plugins/gtkui/tabs.c @@ -0,0 +1,169 @@ +/* + DeaDBeeF - ultimate music player for GNU/Linux systems with X11 + Copyright (C) 2009-2010 Alexey Yakovenko + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#include "../../deadbeef.h" +#include +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif +#include +#include "gtkui.h" +#include "interface.h" +#include "support.h" +#include "drawing.h" + +static int tab_dragging = -1; +static int tab_movepos; + +gboolean +on_tabbar_button_press_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + + return FALSE; +} + + +gboolean +on_tabbar_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + + return FALSE; +} + + +gboolean +on_tabbar_configure_event (GtkWidget *widget, + GdkEventConfigure *event, + gpointer user_data) +{ + + return FALSE; +} + + +gboolean +on_tabbar_expose_event (GtkWidget *widget, + GdkEventExpose *event, + gpointer user_data) +{ + GdkDrawable *backbuf = widget->window; + int hscrollpos = 0; + int x = -hscrollpos; + int w = 0; + int h = widget->allocation.height; + const char *detail = "button"; + int cnt = deadbeef->plt_get_count (); + int tab_selected = deadbeef->plt_get_curr (); + + // fill background + gdk_draw_rectangle (backbuf, widget->style->bg_gc[GTK_STATE_NORMAL], TRUE, 0, 0, widget->allocation.width, widget->allocation.height); + draw_begin ((uintptr_t)backbuf); + int need_draw_moving = 0; + int idx; + int widths[cnt]; + int fullwidth = 0; + for (idx = 0; idx < cnt; idx++) { + const char *title = deadbeef->plt_get_title (idx); + widths[idx] = 0; + int h = 0; + draw_get_text_extents (title, strlen (title), &widths[idx], &h); + widths[idx] += 10; + printf ("width %s %d %d\n", title, strlen (title), widths[idx]); + fullwidth += widths[idx]; + printf ("fullwidth %d\n", fullwidth); + } + x = -hscrollpos + fullwidth/* - widths[cnt-1]*/; + for (idx = cnt-1; idx >= 0; idx--) { + w = widths[idx]; + x -= w; + GdkRectangle area; + area.x = x; + area.y = 0; + area.width = w+5; + area.height = 24; + if (idx != tab_selected) { + gtk_paint_box (widget->style, widget->window, idx == tab_selected ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL, GTK_SHADOW_OUT, &area, widget, "button", x, idx == tab_selected ? 0 : 1, w+5, 32); + GdkColor *gdkfg = &widget->style->fg[0]; + float fg[3] = {(float)gdkfg->red/0xffff, (float)gdkfg->green/0xffff, (float)gdkfg->blue/0xffff}; + draw_set_fg_color (fg); + const char *tab_title = deadbeef->plt_get_title (idx); + draw_text (x + 10, h/2-draw_get_font_size()/2, w, 0, tab_title); + } + } + gdk_draw_line (backbuf, widget->style->dark_gc[GTK_STATE_NORMAL], 0, widget->allocation.height-1, widget->allocation.width, widget->allocation.height-1); + // draw selected + { + idx = tab_selected; + w = widths[idx]; + x = -hscrollpos + fullwidth - w; + GdkRectangle area; + area.x = x; + area.y = 0; + area.width = w+5; + area.height = 24; + gtk_paint_box (widget->style, widget->window, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, &area, widget, "button", x, idx == tab_selected ? 0 : 1, w+5, 32); + GdkColor *gdkfg = &widget->style->fg[0]; + float fg[3] = {(float)gdkfg->red/0xffff, (float)gdkfg->green/0xffff, (float)gdkfg->blue/0xffff}; + draw_set_fg_color (fg); + const char *tab_title = deadbeef->plt_get_title (idx); + draw_text (x + 10, h/2-draw_get_font_size()/2, w, 0, tab_title); + } + + if (need_draw_moving) { + x = -hscrollpos; + for (idx = 0; idx < 10; idx++) { + w = widths[idx]; + if (idx == tab_dragging) { + // draw empty slot + if (x < widget->allocation.width) { + gtk_paint_box (widget->style, backbuf, GTK_STATE_ACTIVE, GTK_SHADOW_ETCHED_IN, NULL, widget, "button", x, 0, w, h); + } + x = tab_movepos; + if (x >= widget->allocation.width) { + break; + } + if (w > 0) { + gtk_paint_box (widget->style, backbuf, GTK_STATE_SELECTED, GTK_SHADOW_OUT, NULL, widget, "button", x, 0, w, h); + GdkColor *gdkfg = &widget->style->fg[GTK_STATE_SELECTED]; + float fg[3] = {(float)gdkfg->red/0xffff, (float)gdkfg->green/0xffff, (float)gdkfg->blue/0xffff}; + draw_set_fg_color (fg); + //draw_text (x + 5, h/2-draw_get_font_size()/2, tab_width-10, 0, tab_title); + } + break; + } + x += w; + } + } + draw_end (); + return FALSE; +} + + +gboolean +on_tabbar_motion_notify_event (GtkWidget *widget, + GdkEventMotion *event, + gpointer user_data) +{ + + return FALSE; +} + -- cgit v1.2.3