summaryrefslogtreecommitdiff
path: root/plugins/gtkui
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-09-26 15:01:28 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-09-26 15:01:28 +0200
commit74ba92ebc78e60ad140198db9694777a17d4fa16 (patch)
treebfa406e184e70ac2292453c9b754eca1b5f6e6ce /plugins/gtkui
parent241c1d792750e8bbffd7e2ebcd200a4034115991 (diff)
fixed several hangs/slowdowns/bugs in playlist selection code
Diffstat (limited to 'plugins/gtkui')
-rw-r--r--plugins/gtkui/callbacks.c8
-rw-r--r--plugins/gtkui/ddblistview.c85
-rw-r--r--plugins/gtkui/ddblistview.h4
-rw-r--r--plugins/gtkui/mainplaylist.c7
-rw-r--r--plugins/gtkui/search.c7
5 files changed, 91 insertions, 20 deletions
diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c
index 433649d8..cd06eff3 100644
--- a/plugins/gtkui/callbacks.c
+++ b/plugins/gtkui/callbacks.c
@@ -249,6 +249,10 @@ on_select_all1_activate (GtkMenuItem *menuitem,
deadbeef->pl_select_all ();
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
ddb_listview_refresh (pl, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ pl = DDB_LISTVIEW (lookup_widget (searchwin, "searchlist"));
+ if (pl) {
+ ddb_listview_refresh (pl, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ }
}
@@ -932,6 +936,10 @@ on_deselect_all1_activate (GtkMenuItem *menuitem,
deadbeef->pl_unlock ();
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
ddb_listview_refresh (pl, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ pl = DDB_LISTVIEW (lookup_widget (searchwin, "searchlist"));
+ if (pl) {
+ ddb_listview_refresh (pl, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ }
}
diff --git a/plugins/gtkui/ddblistview.c b/plugins/gtkui/ddblistview.c
index d17ded26..1109e902 100644
--- a/plugins/gtkui/ddblistview.c
+++ b/plugins/gtkui/ddblistview.c
@@ -42,6 +42,7 @@
#define DEFAULT_GROUP_TITLE_HEIGHT 30
#define SCROLL_STEP 20
#define AUTOSCROLL_UPDATE_FREQ 0.01f
+#define NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW 10
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(fmt,...)
@@ -320,6 +321,9 @@ ddb_listview_init(DdbListview *listview)
listview->cursor_sz = NULL;
listview->cursor_drag = NULL;
+ listview->area_selection_start = 0;
+ listview->area_selection_end = 0;
+
GtkWidget *hbox;
GtkWidget *vbox;
@@ -1307,29 +1311,44 @@ ddb_listview_header_expose (DdbListview *ps, int x, int y, int w, int h) {
void
ddb_listview_select_single (DdbListview *ps, int sel) {
+ int nchanged = 0;
int idx=0;
DdbListviewIter it = ps->binding->head ();
for (; it; idx++) {
if (idx == sel) {
if (!ps->binding->is_selected (it)) {
ps->binding->select (it, 1);
- ddb_listview_draw_row (ps, idx, it);
- ps->binding->selection_changed (it, idx);
+ if (nchanged < NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
+ ddb_listview_draw_row (ps, idx, it);
+ ps->binding->selection_changed (it, idx);
+ }
+ nchanged++;
}
else if (ps->binding->cursor () == idx) {
- ddb_listview_draw_row (ps, idx, it);
+ if (nchanged < NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
+ ddb_listview_draw_row (ps, idx, it);
+ }
}
}
else if (ps->binding->is_selected (it)) {
ps->binding->select (it, 0);
- ddb_listview_draw_row (ps, idx, it);
- ps->binding->selection_changed (it, idx);
+ if (nchanged < NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
+ ddb_listview_draw_row (ps, idx, it);
+ ps->binding->selection_changed (it, idx);
+ }
+ nchanged++;
}
DdbListviewIter next = PL_NEXT (it);
UNREF (it);
it = next;
}
UNREF (it);
+ if (nchanged >= NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
+ ddb_listview_refresh (ps, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ps->binding->selection_changed (it, -1); // that means "selection changed a lot, redraw everything"
+ }
+ ps->area_selection_start = sel;
+ ps->area_selection_end = sel;
}
void
@@ -1722,26 +1741,45 @@ ddb_listview_list_mousemove (DdbListview *ps, GdkEventMotion *ev, int ex, int ey
int start = min (y, ps->shift_sel_anchor);
int end = max (y, ps->shift_sel_anchor);
- idx=0;
- DdbListviewIter it;
- for (it = ps->binding->head (); it; idx++) {
+ int nchanged = 0;
+
+ // don't touch anything in process_start/end range
+ int process_start = min (start, ps->area_selection_start);
+ int process_end = max (end, ps->area_selection_end);
+
+ idx=process_start;
+ DdbListviewIter it = ps->binding->get_for_idx (idx);
+ for (; it && idx <= process_end; idx++) {
+ int selected = ps->binding->is_selected (it);
if (idx >= start && idx <= end) {
- if (!ps->binding->is_selected (it)) {
+ if (!selected) {
ps->binding->select (it, 1);
- ddb_listview_draw_row (ps, idx, it);
- ps->binding->selection_changed (it, idx);
+ nchanged++;
+ if (nchanged < NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
+ ddb_listview_draw_row (ps, idx, it);
+ ps->binding->selection_changed (it, idx);
+ }
}
}
- else if (ps->binding->is_selected (it)) {
+ else if (selected) {
ps->binding->select (it, 0);
- ddb_listview_draw_row (ps, idx, it);
- ps->binding->selection_changed (it, idx);
+ nchanged++;
+ if (nchanged < NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
+ ddb_listview_draw_row (ps, idx, it);
+ ps->binding->selection_changed (it, idx);
+ }
}
DdbListviewIter next = PL_NEXT(it);
UNREF (it);
it = next;
}
UNREF (it);
+ if (nchanged >= NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
+ ddb_listview_refresh (ps, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ps->binding->selection_changed (it, -1); // that means "selection changed a lot, redraw everything"
+ }
+ ps->area_selection_start = start;
+ ps->area_selection_end = end;
}
if (sel != -1 && sel != prev) {
if (prev != -1) {
@@ -1903,25 +1941,36 @@ ddb_listview_handle_keypress (DdbListview *ps, int keyval, int state) {
// select all between shift_sel_anchor and deadbeef->pl_get_cursor (ps->iterator)
int start = min (cursor, ps->shift_sel_anchor);
int end = max (cursor, ps->shift_sel_anchor);
+
+ int nchanged = 0;
int idx=0;
+
DdbListviewIter it;
for (it = ps->binding->head (); it; idx++) {
if (idx >= start && idx <= end) {
ps->binding->select (it, 1);
- ddb_listview_draw_row (ps, idx, it);
- ps->binding->selection_changed (it, idx);
+ if (nchanged < NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
+ ddb_listview_draw_row (ps, idx, it);
+ ps->binding->selection_changed (it, idx);
+ }
}
else if (ps->binding->is_selected (it))
{
ps->binding->select (it, 0);
- ddb_listview_draw_row (ps, idx, it);
- ps->binding->selection_changed (it, idx);
+ if (nchanged < NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
+ ddb_listview_draw_row (ps, idx, it);
+ ps->binding->selection_changed (it, idx);
+ }
}
DdbListviewIter next = PL_NEXT(it);
UNREF (it);
it = next;
}
UNREF (it);
+ if (nchanged >= NUM_CHANGED_ROWS_BEFORE_FULL_REDRAW) {
+ ddb_listview_refresh (ps, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ ps->binding->selection_changed (it, -1); // that means "selection changed a lot, redraw everything"
+ }
}
}
else {
diff --git a/plugins/gtkui/ddblistview.h b/plugins/gtkui/ddblistview.h
index 9ffaa5d5..20b5f72c 100644
--- a/plugins/gtkui/ddblistview.h
+++ b/plugins/gtkui/ddblistview.h
@@ -145,6 +145,10 @@ struct _DdbListview {
int block_redraw_on_scroll;
int grouptitle_height;
+ // previous area selection range
+ int area_selection_start;
+ int area_selection_end;
+
GdkCursor *cursor_sz;
GdkCursor *cursor_drag;
};
diff --git a/plugins/gtkui/mainplaylist.c b/plugins/gtkui/mainplaylist.c
index 84e62951..2df3bd0e 100644
--- a/plugins/gtkui/mainplaylist.c
+++ b/plugins/gtkui/mainplaylist.c
@@ -148,7 +148,12 @@ void main_handle_doubleclick (DdbListview *listview, DdbListviewIter iter, int i
void main_selection_changed (DdbListviewIter it, int idx) {
DdbListview *search = DDB_LISTVIEW (lookup_widget (searchwin, "searchlist"));
- ddb_listview_draw_row (search, search_get_idx ((DB_playItem_t *)it), it);
+ if (idx == -1) {
+ ddb_listview_refresh (search, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ }
+ else {
+ ddb_listview_draw_row (search, search_get_idx ((DB_playItem_t *)it), it);
+ }
}
void main_draw_group_title (DdbListview *listview, GdkDrawable *drawable, DdbListviewIter it, int x, int y, int width, int height) {
diff --git a/plugins/gtkui/search.c b/plugins/gtkui/search.c
index 4d73f659..ee096930 100644
--- a/plugins/gtkui/search.c
+++ b/plugins/gtkui/search.c
@@ -369,7 +369,12 @@ void search_handle_doubleclick (DdbListview *listview, DdbListviewIter iter, int
void search_selection_changed (DdbListviewIter it, int idx) {
DdbListview *main = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
- ddb_listview_draw_row (main, main_get_idx ((DB_playItem_t *)it), it);
+ if (idx == -1) {
+ ddb_listview_refresh (main, DDB_REFRESH_LIST | DDB_EXPOSE_LIST);
+ }
+ else {
+ ddb_listview_draw_row (main, main_get_idx ((DB_playItem_t *)it), it);
+ }
}
void