diff options
author | Alexey Yakovenko <wakeroid@gmail.com> | 2009-08-09 01:41:43 +0200 |
---|---|---|
committer | Alexey Yakovenko <wakeroid@gmail.com> | 2009-08-09 01:41:43 +0200 |
commit | 88c97a3029f9166178819af6de29c7dbf5482c45 (patch) | |
tree | 44731c8795bae8fb864b842d21794b65c23cfa6d | |
parent | 1a9a8db9af43097ae4eef4dc5e1e0b0e3a7713c1 (diff) |
first working search prototype
-rw-r--r-- | callbacks.c | 7 | ||||
-rw-r--r-- | callbacks.h | 1 | ||||
-rw-r--r-- | cflac.c | 4 | ||||
-rw-r--r-- | deadbeef.glade | 3 | ||||
-rw-r--r-- | gtkplaylist.c | 118 | ||||
-rw-r--r-- | gtkplaylist.h | 8 | ||||
-rw-r--r-- | interface.c | 5 | ||||
-rw-r--r-- | playlist.c | 72 | ||||
-rw-r--r-- | playlist.h | 12 | ||||
-rw-r--r-- | search.c | 43 | ||||
-rw-r--r-- | search.h | 1 |
11 files changed, 183 insertions, 91 deletions
diff --git a/callbacks.c b/callbacks.c index 1bd0eff4..b20acaa1 100644 --- a/callbacks.c +++ b/callbacks.c @@ -65,8 +65,10 @@ main_playlist_init (GtkWidget *widget) { main_playlist.scrollbar = lookup_widget (mainwin, "playscroll"); main_playlist.phead = &playlist_head; main_playlist.pcurr = &playlist_current_ptr; + main_playlist.count = &ps_count; main_playlist.update_statusbar = 1; main_playlist.has_dragndrop = 1; + search_playlist.iterator = PS_NEXT; main_playlist.scrollpos = 0; main_playlist.row = -1; main_playlist.clicktime = -1; @@ -95,8 +97,10 @@ search_playlist_init (GtkWidget *widget) { assert (search_playlist.scrollbar); search_playlist.phead = &search_head; // main_playlist.pcurr = &search_current; + search_playlist.count = &search_count; search_playlist.update_statusbar = 0; search_playlist.has_dragndrop = 0; + search_playlist.iterator = PS_SEARCH_NEXT; search_playlist.scrollpos = 0; search_playlist.row = -1; search_playlist.clicktime = -1; @@ -488,7 +492,7 @@ on_playlist_drag_data_get (GtkWidget *widget, uint32_t *ptr = malloc (nsel * sizeof (uint32_t)); int idx = 0; int i = 0; - for (playItem_t *it = playlist_head; it; it = it->next, idx++) { + for (playItem_t *it = playlist_head; it; it = it->next[PS_NEXT], idx++) { if (it->selected) { ptr[i] = idx; i++; @@ -689,3 +693,4 @@ on_searchlist_realize (GtkWidget *widget, } + diff --git a/callbacks.h b/callbacks.h index ba5d9dbb..f715f2d6 100644 --- a/callbacks.h +++ b/callbacks.h @@ -386,3 +386,4 @@ gboolean on_playlist_motion_notify_event (GtkWidget *widget, GdkEventMotion *event, gpointer user_data); + @@ -248,13 +248,13 @@ cflac_init_cue_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC_ else if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { playItem_t *it = NULL; if (cb->after) { - it = cb->after->next; + it = cb->after->next[PS_NEXT]; } else if (cb->last) { it = playlist_head; } if (it) { - for (; it != cb->last->next; it = it->next) { + for (; it != cb->last->next[PS_NEXT]; it = it->next[PS_NEXT]) { char str[10]; snprintf (str, 10, "%d", it->tracknum); ps_add_meta (it, "track", str); diff --git a/deadbeef.glade b/deadbeef.glade index 251b13db..484cb66f 100644 --- a/deadbeef.glade +++ b/deadbeef.glade @@ -1505,7 +1505,7 @@ Public License instead of this License. But first, please read <property name="events">GDK_KEY_PRESS_MASK</property> <property name="title" translatable="yes">Search</property> <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> + <property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property> <property name="modal">False</property> <property name="resizable">True</property> <property name="destroy_with_parent">False</property> @@ -1517,6 +1517,7 @@ Public License instead of this License. But first, please read <property name="focus_on_map">True</property> <property name="urgency_hint">False</property> <signal name="key_press_event" handler="on_searchwin_key_press_event" last_modification_time="Sat, 08 Aug 2009 18:19:17 GMT"/> + <signal name="delete_event" handler="gtk_widget_hide_on_delete" last_modification_time="Sat, 08 Aug 2009 23:03:33 GMT"/> <child> <widget class="GtkVBox" id="vbox4"> diff --git a/gtkplaylist.c b/gtkplaylist.c index b736dfb6..080c9071 100644 --- a/gtkplaylist.c +++ b/gtkplaylist.c @@ -133,7 +133,7 @@ void gtkps_setup_scrollbar (gtkplaylist_t *ps) { GtkWidget *playlist = ps->playlist; int h = playlist->allocation.height / rowheight; - int size = ps_getcount (); + int size = (*ps->count); if (h >= size) { size = 0; } @@ -159,7 +159,7 @@ gtkps_redraw_ps_row_novis (gtkplaylist_t *ps, int row) { // cairo_select_font_face (cr, "fixed", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); - playItem_t *it = ps_get_for_idx (row); + playItem_t *it = gtkps_get_for_idx (ps, row); // printf ("redraw row %d (selected = %d, cursor = %d)\n", row, it->selected, ps->row == row ? 1 : 0); if (it) { gtkps_draw_ps_row_back (ps, cr, row, it); @@ -317,24 +317,25 @@ gtkps_draw_playlist (gtkplaylist_t *ps, int x, int y, int w, int h) { int row1; int row2; int row2_full; + printf ("number of items in ps: %d\n", *ps->count); row1 = max (0, y / rowheight + ps->scrollpos); - row2 = min (ps_getcount (), (y+h) / rowheight + ps->scrollpos + 1); + row2 = min ((*ps->count), (y+h) / rowheight + ps->scrollpos + 1); row2_full = (y+h) / rowheight + ps->scrollpos + 1; //printf ("drawing row %d (nvis=%d)\n", row2_full, ps->nvisiblerows); // draw background - playItem_t *it = ps_get_for_idx (ps->scrollpos); + playItem_t *it = gtkps_get_for_idx (ps, ps->scrollpos); playItem_t *it_copy = it; for (row = row1; row < row2_full; row++) { gtkps_draw_ps_row_back (ps, cr, row, it); if (it) { - it = it->next; + it = it->next[ps->iterator]; } } it = it_copy; int idx = 0; for (row = row1; row < row2; row++, idx++) { gtkps_draw_ps_row (ps, cr, row, it); - it = it->next; + it = it->next[ps->iterator]; } cairo_destroy (cr); @@ -380,7 +381,7 @@ void gtkps_select_single (gtkplaylist_t *ps, int sel) { int idx=0; GtkWidget *widget = ps->playlist; - for (playItem_t *it = playlist_head; it; it = it->next, idx++) { + for (playItem_t *it = (*ps->phead); it; it = it->next[ps->iterator], idx++) { if (idx == sel) { if (!it->selected) { it->selected = 1; @@ -423,7 +424,7 @@ static int shift_sel_anchor = -1; void gtkps_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time) { // cursor must be set here, but selection must be handled in keyrelease - if (ps_getcount () == 0) { + if ((*ps->count) == 0) { return; } GtkWidget *widget = ps->playlist; @@ -432,7 +433,7 @@ gtkps_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time) ps->lastpos[1] = ey; // select item int y = ey/rowheight + ps->scrollpos; - if (y < 0 || y >= ps_getcount ()) { + if (y < 0 || y >= (*ps->count)) { y = -1; } @@ -454,7 +455,7 @@ gtkps_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time) int sel = y; if (y == -1) { - y = ps_getcount () - 1; + y = (*ps->count) - 1; } int prev = ps->row; ps->row = y; @@ -462,7 +463,7 @@ gtkps_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time) // handle selection if (!(state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK))) { - playItem_t *it = ps_get_for_idx (sel); + playItem_t *it = gtkps_get_for_idx (ps, sel); if (!it || !it->selected) { // reset selection, and set it to single item gtkps_select_single (ps, sel); @@ -482,7 +483,7 @@ gtkps_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time) else if (state & GDK_CONTROL_MASK) { // toggle selection if (y != -1) { - playItem_t *it = ps_get_for_idx (y); + playItem_t *it = gtkps_get_for_idx (ps, y); if (it) { it->selected = 1 - it->selected; gtkps_redraw_ps_row (ps, y); @@ -494,7 +495,7 @@ gtkps_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time) int start = min (prev, ps->row); int end = max (prev, ps->row); int idx = 0; - for (playItem_t *it = playlist_head; it; it = it->next, idx++) { + for (playItem_t *it = (*ps->phead); it; it = it->next[ps->iterator], idx++) { if (idx >= start && idx <= end) { if (!it->selected) { it->selected = 1; @@ -589,7 +590,7 @@ gtkps_mousemove (gtkplaylist_t *ps, GdkEventMotion *event) { int start = min (y, shift_sel_anchor); int end = max (y, shift_sel_anchor); int idx=0; - for (playItem_t *it = playlist_head; it; it = it->next, idx++) { + for (playItem_t *it = (*ps->phead); it; it = it->next[ps->iterator], idx++) { if (idx >= start && idx <= end) { it->selected = 1; gtkps_redraw_ps_row (ps, idx); @@ -611,7 +612,7 @@ gtkps_handle_scroll_event (gtkplaylist_t *ps, int direction) { GtkWidget *range = ps->scrollbar;; GtkWidget *playlist = ps->playlist; int h = playlist->allocation.height / rowheight; - int size = ps_getcount (); + int size = (*ps->count); if (h >= size) { size = 0; } @@ -685,10 +686,10 @@ gtkps_prevsong (void) { } if (playlist_current_ptr != prev) { if (prev) { - gtkps_redraw_ps_row (widget, ps_get_idx_of (prev)); + gtkps_redraw_ps_row (widget, gtkps_get_idx_of (ps, prev)); } if (playlist_current_ptr) { - gtkps_redraw_ps_row (widget, ps_get_idx_of (playlist_current_ptr)); + gtkps_redraw_ps_row (widget, gtkps_get_idx_of (ps, playlist_current_ptr)); } } } @@ -705,14 +706,14 @@ gtkps_playsongnum (int idx) { p_stop (); streamer_set_nextsong (idx, 1); #if 0 - playItem_t *it = ps_get_for_idx (ps->row); + playItem_t *it = gtkps_get_for_idx (ps, ps->row); if (it) { //if (it != playlist_current_ptr) { GtkWidget *widget = ps->playlist; int prev = -1; if (playlist_current_ptr) { - prev = ps_get_idx_of (playlist_current_ptr); + prev = gtkps_get_idx_of (ps, playlist_current_ptr); } ps_set_current (it); if (prev != -1) { @@ -748,7 +749,7 @@ gtkps_keypress (gtkplaylist_t *ps, int keyval, int state) { } else if ((keyval == GDK_A || keyval == GDK_a) && (state & GDK_CONTROL_MASK)) { // select all - for (playItem_t *it = playlist_head; it; it = it->next) { + for (playItem_t *it = (*ps->phead); it; it = it->next[ps->iterator]) { it->selected = 1; } gtkps_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height); @@ -761,15 +762,15 @@ gtkps_keypress (gtkplaylist_t *ps, int keyval, int state) { } else if (keyval == GDK_Delete) { ps_delete_selected (); - if (ps->row >= ps_getcount ()) { - ps->row = ps_getcount () - 1; + if (ps->row >= (*ps->count)) { + ps->row = (*ps->count) - 1; } gtkps_setup_scrollbar (ps); gtkps_draw_playlist (ps, 0, 0, widget->allocation.width, widget->allocation.height); gtkps_expose (ps, 0, 0, widget->allocation.width, widget->allocation.height); return; } - else if (keyval == GDK_Down && ps->row < ps_getcount () - 1) { + else if (keyval == GDK_Down && ps->row < (*ps->count) - 1) { ps->row++; if (ps->row > ps->scrollpos + widget->allocation.height / rowheight - 1) { newscroll = ps->row - widget->allocation.height / rowheight + 1; @@ -781,10 +782,10 @@ gtkps_keypress (gtkplaylist_t *ps, int keyval, int state) { newscroll = ps->row; } } - else if (keyval == GDK_Page_Down && ps->row < ps_getcount () - 1) { + else if (keyval == GDK_Page_Down && ps->row < (*ps->count) - 1) { ps->row += 10; - if (ps->row >= ps_getcount ()) { - ps->row = ps_getcount () - 1; + if (ps->row >= (*ps->count)) { + ps->row = (*ps->count) - 1; } if (ps->row > ps->scrollpos + widget->allocation.height / rowheight - 1) { newscroll = ps->row - widget->allocation.height / rowheight + 1; @@ -799,8 +800,8 @@ gtkps_keypress (gtkplaylist_t *ps, int keyval, int state) { newscroll = ps->row; } } - else if (keyval == GDK_End && ps->row != ps_getcount () - 1) { - ps->row = ps_getcount () - 1; + else if (keyval == GDK_End && ps->row != (*ps->count) - 1) { + ps->row = (*ps->count) - 1; if (ps->row > ps->scrollpos + widget->allocation.height / rowheight - 1) { newscroll = ps->row - widget->allocation.height / rowheight + 1; } @@ -817,7 +818,7 @@ gtkps_keypress (gtkplaylist_t *ps, int keyval, int state) { int start = min (ps->row, shift_sel_anchor); int end = max (ps->row, shift_sel_anchor); int idx=0; - for (playItem_t *it = playlist_head; it; it = it->next, idx++) { + for (playItem_t *it = (*ps->phead); it; it = it->next[ps->iterator], idx++) { if (idx >= start && idx <= end) { // if (!it->selected) { it->selected = 1; @@ -847,7 +848,7 @@ gtkps_keypress (gtkplaylist_t *ps, int keyval, int state) { if (prev != ps->row) { shift_sel_anchor = ps->row; int idx=0; - for (playItem_t *it = playlist_head; it; it = it->next, idx++) { + for (playItem_t *it = (*ps->phead); it; it = it->next[ps->iterator], idx++) { if (idx == ps->row) { if (!it->selected) { it->selected = 1; @@ -908,9 +909,9 @@ gtkps_track_dragdrop (gtkplaylist_t *ps, int y) { void gtkps_handle_drag_drop (gtkplaylist_t *ps, int drop_y, uint32_t *d, int length) { int drop_row = drop_y / rowheight + ps->scrollpos; - playItem_t *drop_before = ps_get_for_idx (drop_row); + playItem_t *drop_before = gtkps_get_for_idx (ps, drop_row); while (drop_before && drop_before->selected) { - drop_before = drop_before->next; + drop_before = drop_before->next[ps->iterator]; } // unlink items from playlist, and link together playItem_t *head = NULL; @@ -918,34 +919,32 @@ gtkps_handle_drag_drop (gtkplaylist_t *ps, int drop_y, uint32_t *d, int length) int processed = 0; int idx = 0; playItem_t *next = NULL; - for (playItem_t *it = playlist_head; it && processed < length; it = next, idx++) { + for (playItem_t *it = (*ps->phead); it && processed < length; it = next, idx++) { // printf ("idx: %d\n", d[i]); - next = it->next; + next = it->next[ps->iterator]; if (idx == d[processed]) { if (it->prev) { - it->prev->next = it->next; + it->prev->next[ps->iterator] = it->next[ps->iterator]; } else { - playlist_head = it->next; + (*ps->phead) = it->next[ps->iterator]; } - if (it->next) { - it->next->prev = it->prev; + if (it->next[ps->iterator]) { + it->next[ps->iterator]->prev = it->prev; } else { playlist_tail = it->prev; } if (tail) { - tail->next = it; + tail->next[ps->iterator] = it; it->prev = tail; tail = it; } else { head = tail = it; - it->prev = it->next = NULL; + it->prev = it->next[ps->iterator] = NULL; } processed++; - // extern int ps_count; - // ps_count--; } } // find insertion point @@ -959,12 +958,12 @@ gtkps_handle_drag_drop (gtkplaylist_t *ps, int drop_y, uint32_t *d, int length) // insert in between head->prev = drop_after; if (drop_after) { - drop_after->next = head; + drop_after->next[ps->iterator] = head; } else { - playlist_head = head; + (*ps->phead) = head; } - tail->next = drop_before; + tail->next[ps->iterator] = drop_before; if (drop_before) { drop_before->prev = tail; } @@ -1027,7 +1026,7 @@ gtkps_add_fm_dropped_files (gtkplaylist_t *ps, char *ptr, int length, int drop_y GDK_THREADS_LEAVE(); int drop_row = drop_y / rowheight + ps->scrollpos; - playItem_t *drop_before = ps_get_for_idx (drop_row); + playItem_t *drop_before = gtkps_get_for_idx (ps, drop_row); playItem_t *after = NULL; if (drop_before) { after = drop_before->prev; @@ -1346,7 +1345,7 @@ gtkps_playsong (gtkplaylist_t *ps) { else if (playlist_current_ptr) { p_stop (); printf ("restart\n"); - streamer_set_nextsong (ps_get_idx_of (playlist_current_ptr), 1); + streamer_set_nextsong (gtkps_get_idx_of (ps, playlist_current_ptr), 1); } else if (ps->row != -1) { printf ("start under cursor\n"); @@ -1357,3 +1356,28 @@ gtkps_playsong (gtkplaylist_t *ps) { streamer_set_nextsong (0, 1); } } + +int +gtkps_get_idx_of (gtkplaylist_t *ps, playItem_t *it) { + playItem_t *c = *ps->phead; + int idx = 0; + while (c && c != it) { + c = c->next[ps->iterator]; + idx++; + } + if (!c) { + return -1; + } + return idx; +} + +playItem_t * +gtkps_get_for_idx (gtkplaylist_t *ps, int idx) { + playItem_t *it = *ps->phead; + while (idx--) { + if (!it) + return NULL; + it = it->next[ps->iterator]; + } + return it; +} diff --git a/gtkplaylist.h b/gtkplaylist.h index 6fbe592d..9f600193 100644 --- a/gtkplaylist.h +++ b/gtkplaylist.h @@ -43,8 +43,10 @@ typedef struct { // parameters playItem_t **phead; // pointer to head of list to display playItem_t **pcurr; // pointer to current item + int *count; // pointer to count of items in list int update_statusbar; // whether it needs to update status bar in certain cases int has_dragndrop; // whether it has drag and drop capability + int iterator; // index into next array of playItem_t struct int lastpos[2]; // last mouse position (for playlist widget) // current state int scrollpos; @@ -129,6 +131,12 @@ gtkps_add_files (gtkplaylist_t *ps, GSList *lst); void gtkps_configure (gtkplaylist_t *ps); +int +gtkps_get_idx_of (gtkplaylist_t *ps, playItem_t *it); + +playItem_t * +gtkps_get_for_idx (gtkplaylist_t *ps, int idx); + // this functions take value from passed playlist, that's why it's here void gtkps_playsong (gtkplaylist_t *ps); diff --git a/interface.c b/interface.c index 04a47571..eb406dbf 100644 --- a/interface.c +++ b/interface.c @@ -692,7 +692,7 @@ create_searchwin (void) gtk_widget_set_size_request (searchwin, 300, 150); gtk_widget_set_events (searchwin, GDK_KEY_PRESS_MASK); gtk_window_set_title (GTK_WINDOW (searchwin), "Search"); - gtk_window_set_position (GTK_WINDOW (searchwin), GTK_WIN_POS_CENTER_ON_PARENT); + gtk_window_set_position (GTK_WINDOW (searchwin), GTK_WIN_POS_CENTER_ALWAYS); gtk_window_set_skip_taskbar_hint (GTK_WINDOW (searchwin), TRUE); gtk_window_set_skip_pager_hint (GTK_WINDOW (searchwin), TRUE); @@ -734,6 +734,9 @@ create_searchwin (void) g_signal_connect ((gpointer) searchwin, "key_press_event", G_CALLBACK (on_searchwin_key_press_event), NULL); + g_signal_connect ((gpointer) searchwin, "delete_event", + G_CALLBACK (gtk_widget_hide_on_delete), + NULL); g_signal_connect ((gpointer) searchentry, "changed", G_CALLBACK (on_searchentry_changed), NULL); @@ -45,7 +45,7 @@ playItem_t *playlist_tail; playItem_t *playlist_shuffle_head; playItem_t playlist_current; playItem_t *playlist_current_ptr; -static int ps_count = 0; +int ps_count = 0; static int ps_order = 0; // 0 = linear, 1 = shuffle, 2 = random static int ps_loop_mode = 0; // 0 = loop, 1 = don't loop, 2 = loop single @@ -433,11 +433,11 @@ ps_remove (playItem_t *it) { ps_count--; // remove from shuffle list - for (playItem_t *i = playlist_head; i; i = i->next) { - if (i->shufflenext == it) { - i->shufflenext = it->shufflenext; + for (playItem_t *i = playlist_head; i; i = i->next[PS_NEXT]) { + if (i->next[PS_SHUFFLE_NEXT] == it) { + i->next[PS_SHUFFLE_NEXT] = it->next[PS_SHUFFLE_NEXT]; if (it == playlist_shuffle_head) { - playlist_shuffle_head = it->shufflenext; + playlist_shuffle_head = it->next[PS_SHUFFLE_NEXT]; } break; } @@ -445,13 +445,13 @@ ps_remove (playItem_t *it) { // remove from linear list if (it->prev) { - it->prev->next = it->next; + it->prev->next[PS_NEXT] = it->next[PS_NEXT]; } else { - playlist_head = it->next; + playlist_head = it->next[PS_NEXT]; } - if (it->next) { - it->next->prev = it->prev; + if (it->next[PS_NEXT]) { + it->next[PS_NEXT]->prev = it->prev; } else { playlist_tail = it->prev; @@ -470,7 +470,7 @@ int ps_getselcount (void) { // FIXME: slow! int cnt = 0; - for (playItem_t *it = playlist_head; it; it = it->next) { + for (playItem_t *it = playlist_head; it; it = it->next[PS_NEXT]) { if (it->selected) { cnt++; } @@ -484,7 +484,7 @@ ps_get_for_idx (int idx) { while (idx--) { if (!it) return NULL; - it = it->next; + it = it->next[PS_NEXT]; } return it; } @@ -494,7 +494,7 @@ ps_get_idx_of (playItem_t *it) { playItem_t *c = playlist_head; int idx = 0; while (c && c != it) { - c = c->next; + c = c->next[PS_NEXT]; idx++; } if (!c) { @@ -509,7 +509,7 @@ ps_append_item (playItem_t *it) { playlist_tail = playlist_head = it; } else { - playlist_tail->next = it; + playlist_tail->next[PS_NEXT] = it; it->prev = playlist_tail; playlist_tail = it; } @@ -519,7 +519,7 @@ ps_append_item (playItem_t *it) { playItem_t * ps_insert_item (playItem_t *after, playItem_t *it) { if (!after) { - it->next = playlist_head; + it->next[PS_NEXT] = playlist_head; it->prev = NULL; if (playlist_head) { playlist_head->prev = it; @@ -531,11 +531,11 @@ ps_insert_item (playItem_t *after, playItem_t *it) { } else { it->prev= after; - it->next = after->next; - if (after->next) { - after->next->prev = it; + it->next[PS_NEXT] = after->next[PS_NEXT]; + if (after->next[PS_NEXT]) { + after->next[PS_NEXT]->prev = it; } - after->next = it; + after->next[PS_NEXT] = it; if (after == playlist_tail) { playlist_tail = it; } @@ -553,9 +553,9 @@ ps_item_copy (playItem_t *out, playItem_t *it) { out->timeend = it->timeend; out->duration = it->duration; out->filetype = it->filetype; - out->next = it->next; + out->next[PS_NEXT] = it->next[PS_NEXT]; out->prev = it->prev; - out->shufflenext = it->shufflenext; + out->next[PS_SHUFFLE_NEXT] = it->next[PS_SHUFFLE_NEXT]; // copy metainfo metaInfo_t *prev = NULL; metaInfo_t *meta = it->meta; @@ -640,8 +640,8 @@ ps_prevsong (void) { else { playItem_t *it = NULL; playItem_t *last = NULL; - for (it = playlist_shuffle_head; it; it = it->shufflenext) { - if (it->shufflenext == playlist_current_ptr) { + for (it = playlist_shuffle_head; it; it = it->next[PS_SHUFFLE_NEXT]) { + if (it->next[PS_SHUFFLE_NEXT] == playlist_current_ptr) { break; } last = it; @@ -701,7 +701,7 @@ ps_nextsong (int reason) { streamer_set_nextsong (r, 1); return 0; } - playItem_t *it = playlist_current_ptr->shufflenext; + playItem_t *it = playlist_current_ptr->next[PS_SHUFFLE_NEXT]; if (!it) { if (ps_loop_mode == 0) { // loop it = playlist_shuffle_head; @@ -726,7 +726,7 @@ ps_nextsong (int reason) { streamer_set_nextsong (r, 1); return 0; } - it = playlist_current_ptr->next; + it = playlist_current_ptr->next[PS_NEXT]; } if (!it) { if (ps_loop_mode == 0) { @@ -870,16 +870,16 @@ void ps_delete_selected (void) { playItem_t *next = NULL; for (playItem_t *it = playlist_head; it; it = next) { - next = it->next; + next = it->next[PS_NEXT]; if (it->selected) { if (it->prev) { - it->prev->next = it->next; + it->prev->next[PS_NEXT] = it->next[PS_NEXT]; } - if (it->next) { - it->next->prev = it->prev; + if (it->next[PS_NEXT]) { + it->next[PS_NEXT]->prev = it->prev; } if (playlist_head == it) { - playlist_head = it->next; + playlist_head = it->next[PS_NEXT]; } if (playlist_tail == it) { playlist_tail = it->prev; @@ -900,8 +900,8 @@ ps_shuffle (void) { playItem_t *tail = NULL; playItem_t *it; int cnt = 0; - for (it = playlist_head; it; it = it->next) { - it->shufflenext = head; + for (it = playlist_head; it; it = it->next[PS_NEXT]) { + it->next[PS_SHUFFLE_NEXT] = head; head = it; cnt++; } @@ -910,16 +910,16 @@ ps_shuffle (void) { int idx = (float)rand ()/RAND_MAX * cnt; int i = 0; playItem_t *prev = NULL; - for (it = head; it; it = it->shufflenext, i++) { + for (it = head; it; it = it->next[PS_SHUFFLE_NEXT], i++) { if (i == idx) { if (prev) { - prev->shufflenext = it->shufflenext; + prev->next[PS_SHUFFLE_NEXT] = it->next[PS_SHUFFLE_NEXT]; } else { - head = it->shufflenext; + head = it->next[PS_SHUFFLE_NEXT]; } // prepend to shuffled playlist - it->shufflenext = playlist_shuffle_head; + it->next[PS_SHUFFLE_NEXT] = playlist_shuffle_head; if (!playlist_shuffle_head) { tail = it; } @@ -933,7 +933,7 @@ ps_shuffle (void) { #if 0 // loop this list if (tail) { - tail->shufflenext = playlist_shuffle_head; + tail->next[PS_SHUFFLE_NEXT] = playlist_shuffle_head; } #endif } @@ -24,6 +24,11 @@ typedef struct metaInfo_s { struct metaInfo_s *next; } metaInfo_t; +#define PS_MAX_ITERATORS 3 +#define PS_NEXT 0 +#define PS_SEARCH_NEXT 1 +#define PS_SHUFFLE_NEXT 2 + typedef struct playItem_s { char *fname; // full pathname struct codec_s *codec; // codec to use with this file @@ -32,10 +37,10 @@ typedef struct playItem_s { float timeend; // end time of cue track, or -1 float duration; // in seconds const char *filetype; // e.g. MP3 or OGG - struct playItem_s *next; // next item in linked list + struct playItem_s *next[PS_MAX_ITERATORS]; // next item in linked list struct playItem_s *prev; // prev item in linked list - struct playItem_s *shufflenext; // next item in shuffle list - struct playItem_s *searchnext; // next in search results list +// struct playItem_s *shufflenext; // next item in shuffle list +// struct playItem_s *searchnext; // next in search results list struct metaInfo_s *meta; // linked list storing metainfo unsigned selected : 1; } playItem_t; @@ -45,6 +50,7 @@ extern playItem_t *playlist_tail; // tail of linked list extern playItem_t *playlist_shuffle_head; // head of shuffled playlist extern playItem_t *playlist_current_ptr; // pointer to a real current playlist item extern playItem_t playlist_current; // copy of playlist item being played (stays in memory even if removed from playlist) +extern int ps_count; int ps_add_dir (const char *dirname, int (*cb)(playItem_t *it, void *data), void *user_data); @@ -20,6 +20,7 @@ #endif #include <gtk/gtk.h> +#include <gdk/gdkkeysyms.h> #include <math.h> #include <stdlib.h> #include <string.h> @@ -34,11 +35,14 @@ GtkWidget *searchwin = NULL; struct playItem_s *search_head = NULL; struct playItem_s *search_current = NULL; +int search_count = 0; void search_start (void) { if (!searchwin) { searchwin = create_searchwin (); + extern GtkWidget *mainwin; + gtk_window_set_transient_for (GTK_WINDOW (searchwin), GTK_WINDOW (mainwin)); } gtk_widget_show (searchwin); gtk_window_present (GTK_WINDOW (searchwin)); @@ -51,6 +55,42 @@ on_searchentry_changed (GtkEditable *editable, // final implementation must work in separate thread, and catch up when // value was changed // but for alpha, let's do it in GTK thread + + // walk playlist starting with playlist_head, and populate list starting + // with search_head + + const gchar *text = gtk_entry_get_text (GTK_ENTRY (editable)); + printf ("%s\n", text); + + search_head = NULL; + playItem_t *tail = NULL; + search_count = 0; + if (*text) { + for (playItem_t *it = playlist_head; it; it = it->next[PS_NEXT]) { + for (metaInfo_t *m = it->meta; m; m = m->next) { + if (strcasestr (m->value, text)) { + // add to list + it->next[PS_SEARCH_NEXT] = NULL; + if (tail) { + tail->next[PS_SEARCH_NEXT] = it; + tail = it; + } + else { + search_head = tail = it; + } + printf ("found matching item: %s -> %s\n", text, m->value); + search_count++; + break; + } + } + } + } + + extern gtkplaylist_t search_playlist; + gtkplaylist_t *ps = &search_playlist; + memset (ps->fmtcache, 0, sizeof (int16_t) * 3 * ps_ncolumns * ps->nvisiblerows); + gtkps_draw_playlist (ps, 0, 0, ps->playlist->allocation.width, ps->playlist->allocation.height); + gtkps_expose (ps, 0, 0, ps->playlist->allocation.width, ps->playlist->allocation.height); } ///////// searchwin header handlers @@ -112,6 +152,9 @@ on_searchwin_key_press_event (GtkWidget *widget, gpointer user_data) { // that's for when user attempts to navigate list while entry has focus + if (event->keyval == GDK_Escape) { + gtk_widget_hide (widget); + } return FALSE; } @@ -20,6 +20,7 @@ extern struct playItem_s *search_head; extern struct playItem_s *search_current; +extern int search_count; void search_start (void); |