summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-08-09 01:41:43 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-08-09 01:41:43 +0200
commit88c97a3029f9166178819af6de29c7dbf5482c45 (patch)
tree44731c8795bae8fb864b842d21794b65c23cfa6d
parent1a9a8db9af43097ae4eef4dc5e1e0b0e3a7713c1 (diff)
first working search prototype
-rw-r--r--callbacks.c7
-rw-r--r--callbacks.h1
-rw-r--r--cflac.c4
-rw-r--r--deadbeef.glade3
-rw-r--r--gtkplaylist.c118
-rw-r--r--gtkplaylist.h8
-rw-r--r--interface.c5
-rw-r--r--playlist.c72
-rw-r--r--playlist.h12
-rw-r--r--search.c43
-rw-r--r--search.h1
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);
+
diff --git a/cflac.c b/cflac.c
index c8fe2eb3..18f61660 100644
--- a/cflac.c
+++ b/cflac.c
@@ -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);
diff --git a/playlist.c b/playlist.c
index 3c5b6351..57858ae1 100644
--- a/playlist.c
+++ b/playlist.c
@@ -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
}
diff --git a/playlist.h b/playlist.h
index 8e33c53e..13ede684 100644
--- a/playlist.h
+++ b/playlist.h
@@ -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);
diff --git a/search.c b/search.c
index 3944eafd..a90a4bd7 100644
--- a/search.c
+++ b/search.c
@@ -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;
}
diff --git a/search.h b/search.h
index 33d5f8c0..43b0057f 100644
--- a/search.h
+++ b/search.h
@@ -20,6 +20,7 @@
extern struct playItem_s *search_head;
extern struct playItem_s *search_current;
+extern int search_count;
void
search_start (void);