diff options
-rw-r--r-- | plugins/gtkui/ddblistview.c | 78 | ||||
-rw-r--r-- | plugins/gtkui/ddblistview.h | 4 | ||||
-rw-r--r-- | plugins/gtkui/mainplaylist.c | 4 |
3 files changed, 85 insertions, 1 deletions
diff --git a/plugins/gtkui/ddblistview.c b/plugins/gtkui/ddblistview.c index 5294b290..465117ff 100644 --- a/plugins/gtkui/ddblistview.c +++ b/plugins/gtkui/ddblistview.c @@ -79,6 +79,8 @@ static void ddb_listview_destroy(GObject *object); void ddb_listview_build_groups (DdbListview *listview); +static void +ddb_listview_resize_groups (DdbListview *listview); // fwd decls void ddb_listview_free_groups (DdbListview *listview); @@ -291,6 +293,9 @@ ddb_listview_init(DdbListview *listview) listview->col_movepos = -1; listview->drag_motion_y = -1; + listview->ref_point = -1; + listview->ref_point_offset = -1; + listview->scroll_mode = 0; listview->scroll_pointer_y = -1; listview->scroll_direction = 0; @@ -2561,7 +2566,7 @@ ddb_listview_header_motion_notify_event (GtkWidget *widget, c->fwidth = (float)c->width / ps->header_width; } if (c->minheight) { - ddb_listview_build_groups (ps); + ddb_listview_resize_groups (ps); } ps->block_redraw_on_scroll = 1; ddb_listview_list_setup_vscroll (ps); @@ -2618,6 +2623,45 @@ ddb_listview_header_button_press_event (GtkWidget *widget, DdbListview *ps = DDB_LISTVIEW (g_object_get_data (G_OBJECT (widget), "owner")); // ps->active_column = ddb_listview_header_get_column_for_coord (ps, event->x); if (TEST_LEFT_CLICK (event)) { + + ddb_listview_groupcheck (ps); + DdbListviewGroup *grp = ps->groups; + DdbListviewGroup *grp_next; + + if (grp && ps->scrollpos > 0) { + int abs_idx = 0; + int grp_y = 0; + + GtkAllocation a; + gtk_widget_get_allocation (ps->list, &a); + int cursor_pos = ddb_listview_get_row_pos (ps, ps->binding->cursor ()); + ps->ref_point = 0; + ps->ref_point_offset = 0; + + // find 1st group + while (grp && grp_y + grp->height < ps->scrollpos) { + grp_y += grp->height; + abs_idx += grp->num_items; + grp = grp->next; + } + // choose cursor_pos as anchor + if (ps->scrollpos < cursor_pos && cursor_pos < ps->scrollpos + a.height && cursor_pos < ps->fullheight) { + ps->ref_point = ps->binding->cursor (); + ps->ref_point_offset = cursor_pos - ps->scrollpos; + } + // choose first group as anchor + else if (ps->scrollpos < grp_y + ps-> grouptitle_height + (grp->num_items * ps->rowheight) && grp_y + ps-> grouptitle_height + (grp->num_items * ps->rowheight) < ps->scrollpos + a.height) { + ps->ref_point = abs_idx; + ps->ref_point_offset = (grp_y + ps->grouptitle_height) - ps->scrollpos; + } + // choose next group as anchor + else { + grp_y += grp->height; + abs_idx += grp->num_items; + ps->ref_point = abs_idx; + ps->ref_point_offset = (grp_y + ps->grouptitle_height) - ps->scrollpos; + } + } // start sizing/dragging ps->header_dragging = -1; ps->header_sizing = -1; @@ -3205,6 +3249,38 @@ ddb_listview_build_groups (DdbListview *listview) { } void +ddb_listview_resize_groups (DdbListview *listview) { + deadbeef->pl_lock (); + int old_height = listview->fullheight; + int grp_height_old = 0; + listview->fullheight = 0; + + int min_height= 0; + DdbListviewColumn *c; + for (c = listview->columns; c; c = c->next) { + if (c->minheight && c->width > min_height) { + min_height = c->width; + } + } + + DdbListviewGroup *grp = listview->groups; + while (grp) { + grp->height = listview->grouptitle_height + grp->num_items * listview->rowheight; + if (grp->height - listview->grouptitle_height < min_height) { + grp_height_old = grp->height; + grp->height = min_height + listview->grouptitle_height; + } + listview->fullheight += grp->height; + grp = grp->next; + } + + deadbeef->pl_unlock (); + if (old_height != listview->fullheight) { + ddb_listview_refresh (listview, DDB_REFRESH_VSCROLL); + } +} + +void ddb_listview_set_vscroll (DdbListview *listview, int scroll) { GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (listview->scrollbar)); gtk_range_set_value (GTK_RANGE (listview->scrollbar), scroll); diff --git a/plugins/gtkui/ddblistview.h b/plugins/gtkui/ddblistview.h index 53db2a60..372bcb3c 100644 --- a/plugins/gtkui/ddblistview.h +++ b/plugins/gtkui/ddblistview.h @@ -52,6 +52,7 @@ typedef void * DdbPlaylistHandle; struct _DdbListviewGroup { DdbListviewIter head; int32_t height; + int32_t min_height; int32_t num_items; int pinned; struct _DdbListviewGroup *next; @@ -132,6 +133,9 @@ struct _DdbListview { int drag_motion_y; + int ref_point; // idx of anchor when columns are resized + int ref_point_offset; // y pixel-coordinate of anchor relative to view + // scrolling int scroll_mode; // 0=select, 1=dragndrop int scroll_pointer_y; diff --git a/plugins/gtkui/mainplaylist.c b/plugins/gtkui/mainplaylist.c index ae828a30..fc781a39 100644 --- a/plugins/gtkui/mainplaylist.c +++ b/plugins/gtkui/mainplaylist.c @@ -250,6 +250,10 @@ main_column_size_changed (DdbListview *listview, int col) { return; } if (inf->id == DB_COLUMN_ALBUM_ART) { + if (listview->scrollpos > 0) { + int pos = ddb_listview_get_row_pos (listview, listview->ref_point); + gtk_range_set_value (GTK_RANGE (listview->scrollbar), pos - listview->ref_point_offset); + } coverart_reset_queue (); ddb_playlist_t *plt = deadbeef->plt_get_curr (); if (plt) { |