1 /* 2 DeaDBeeF -- the music player 3 Copyright (C) 2009-2015 Alexey Yakovenko and other contributors 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 18 2. Altered source versions must be plainly marked as such, and must not be 19 misrepresented as being the original software. 20 21 3. This notice may not be removed or altered from any source distribution. 22 */ 23 24 #ifndef __DDBLISTVIEW_H 25 #define __DDBLISTVIEW_H 26 27 #include <gtk/gtk.h> 28 #include <sys/time.h> 29 #include <stdint.h> 30 #include "drawing.h" 31 #include "../../deadbeef.h" 32 33 // drag and drop targets 34 #define TARGET_PLAYITEMS "DDB_PLAYITEM_LIST" 35 enum { 36 TARGET_URILIST, 37 TARGET_SAMEWIDGET, 38 }; 39 40 G_BEGIN_DECLS 41 42 #define DDB_TYPE_LISTVIEW (ddb_listview_get_type ()) 43 #define DDB_LISTVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), DDB_TYPE_LISTVIEW, DdbListview)) 44 #define DDB_LISTVIEW_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST((obj), DDB_TYPE_LISTVIEW, DdbListviewClass)) 45 #define DDB_IS_LISTVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DDB_TYPE_LISTVIEW)) 46 #define DDB_IS_LISTVIEW_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), DDB_TYPE_LISTVIEW)) 47 #define DDB_LISTVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DDB_TYPE_LISTVIEW, DdbListviewClass)) 48 49 typedef struct { 50 int id; // predefined col type 51 char *format; 52 char *bytecode; 53 } col_info_t; 54 55 typedef struct _DdbListview DdbListview; 56 typedef struct _DdbListviewClass DdbListviewClass; 57 58 typedef void * DdbListviewIter; 59 typedef void * DdbPlaylistHandle; 60 61 struct _DdbListviewGroup { 62 DdbListviewIter head; 63 int32_t height; 64 int32_t min_height; 65 int32_t num_items; 66 int pinned; 67 struct _DdbListviewGroup *next; 68 }; 69 70 typedef struct _DdbListviewGroup DdbListviewGroup; 71 //typedef void * DdbListviewColIter; 72 73 typedef struct { 74 // rows 75 int (*count) (void); 76 int (*sel_count) (void); 77 78 int (*cursor) (void); 79 void (*set_cursor) (int cursor); 80 81 DdbListviewIter (*head) (void); 82 DdbListviewIter (*tail) (void); 83 DdbListviewIter (*next) (DdbListviewIter); 84 DdbListviewIter (*prev) (DdbListviewIter); 85 86 DdbListviewIter (*get_for_idx) (int idx); 87 int (*get_idx) (DdbListviewIter); 88 89 void (*ref) (DdbListviewIter); 90 void (*unref) (DdbListviewIter); 91 92 void (*select) (DdbListviewIter, int sel); 93 int (*is_selected) (DdbListviewIter); 94 95 int (*get_group) (DdbListview *listview, DdbListviewIter it, char *str, int size); 96 97 // drag-n-drop 98 void (*drag_n_drop) (DdbListviewIter before, DdbPlaylistHandle playlist_from, uint32_t *indices, int length, int copy); 99 void (*external_drag_n_drop) (DdbListviewIter before, char *mem, int length); 100 101 // callbacks 102 void (*draw_group_title) (DdbListview *listview, cairo_t *drawable, DdbListviewIter iter, int pl_iter, int x, int y, int width, int height); 103 void (*draw_album_art) (DdbListview *listview, cairo_t *drawable, DdbListviewIter group_iter, int column, int group_pinned, int grp_next_y, int x, int y, int width, int height); 104 void (*draw_column_data) (DdbListview *listview, cairo_t *drawable, DdbListviewIter iter, int idx, int column, int pl_iter, int x, int y, int width, int height); 105 void (*list_context_menu) (DdbListview *listview, DdbListviewIter iter, int idx); 106 void (*header_context_menu) (DdbListview *listview, int col); 107 void (*handle_doubleclick) (DdbListview *listview, DdbListviewIter iter, int idx); 108 void (*selection_changed) (DdbListview *listview, DdbListviewIter it, int idx); 109 void (*delete_selected) (void); 110 void (*groups_changed) (DdbListview *listview, const char *format); 111 void (*columns_changed) (DdbListview *listview); 112 void (*col_sort) (int col, int sort_order, void *user_data); 113 void (*col_free_user_data) (void *user_data); 114 void (*vscroll_changed) (int pos); 115 void (*cursor_changed) (int pos); 116 int (*modification_idx) (void); 117 } DdbListviewBinding; 118 119 struct _DdbListviewColumn; 120 struct _DdbListviewGroup; 121 122 struct _DdbListview { 123 GtkTable parent; 124 125 // interaction with client 126 DdbListviewBinding *binding; 127 128 // cached gtk/gdk object pointers 129 GtkWidget *list; 130 GtkWidget *header; 131 GtkWidget *scrollbar; 132 GtkWidget *hscrollbar; 133 134 int totalwidth; // width of listview, including invisible (scrollable) part 135 const char *title; // unique id, used for config writing, etc 136 int lastpos[2]; // last mouse position (for list widget) 137 // current state 138 int scrollpos; 139 int hscrollpos; 140 int rowheight; 141 142 int col_movepos; 143 144 int drag_motion_y; 145 146 int ref_point; // idx of anchor when columns are resized 147 int ref_point_offset; // y pixel-coordinate of anchor relative to view 148 149 // scrolling 150 int scroll_mode; // 0=select, 1=dragndrop 151 int scroll_pointer_y; 152 float scroll_direction; 153 int scroll_active; 154 struct timeval tm_prevscroll; 155 float scroll_sleep_time; 156 157 // selection 158 int areaselect; // boolean, whether area selection is active (1), or not (0) 159 int areaselect_y; // pixel-coordinate of anchor click relative to playlist origin 160 int dragwait; // set to 1 when mouse was pressed down on already selected track, but not moved since (so we're waiting for dnd to begin) 161 int drag_source_playlist; 162 int shift_sel_anchor; 163 164 // header 165 int header_dragging; 166 int header_sizing; 167 int header_dragpt[2]; 168 float last_header_motion_ev; //is it subject to remove? 169 int prev_header_x; 170 int header_prepare; 171 int header_width; // previous width before resize 172 int col_autoresize; 173 174 struct _DdbListviewColumn *columns; 175 gboolean lock_columns; 176 177 ddb_playlist_t *plt; // current playlist (refcounted), must be unreffed with the group 178 struct _DdbListviewGroup *groups; 179 int groups_build_idx; // must be the same as playlist modification idx 180 int fullheight; 181 int block_redraw_on_scroll; 182 int grouptitle_height; 183 int calculated_grouptitle_height; 184 185 // previous area selection range 186 int area_selection_start; 187 int area_selection_end; 188 189 GdkCursor *cursor_sz; 190 GdkCursor *cursor_drag; 191 192 // drawing contexts 193 drawctx_t listctx; 194 drawctx_t grpctx; 195 drawctx_t hdrctx; 196 197 // cover art size 198 int cover_size; 199 int new_cover_size; 200 guint cover_refresh_timeout_id; 201 202 // group format string that's supposed to get parsed by tf 203 char *group_format; 204 // tf bytecode for group title 205 char *group_title_bytecode; 206 207 guint tf_redraw_timeout_id; 208 int tf_redraw_track_idx; 209 DdbListviewIter tf_redraw_track; 210 }; 211 212 struct _DdbListviewClass { 213 GtkTableClass parent_class; 214 }; 215 216 GType ddb_listview_get_type(void); 217 218 GtkWidget * ddb_listview_new(); 219 220 void 221 ddb_listview_set_binding (DdbListview *listview, DdbListviewBinding *binding); 222 void 223 ddb_listview_draw_row (DdbListview *listview, int idx, DdbListviewIter iter); 224 int 225 ddb_listview_get_vscroll_pos (DdbListview *listview); 226 int 227 ddb_listview_get_hscroll_pos (DdbListview *listview); 228 DdbListviewIter 229 ddb_listview_get_iter_from_coord (DdbListview *listview, int x, int y); 230 int 231 ddb_listview_handle_keypress (DdbListview *ps, int keyval, int state); 232 void 233 ddb_listview_set_cursor (DdbListview *pl, int cursor); 234 void 235 ddb_listview_set_cursor_noscroll (DdbListview *pl, int cursor); 236 void 237 ddb_listview_scroll_to (DdbListview *listview, int rowpos); 238 void 239 ddb_listview_set_vscroll (DdbListview *listview, int scroll); 240 int 241 ddb_listview_is_scrolling (DdbListview *listview); 242 int 243 ddb_listview_column_get_count (DdbListview *listview); 244 void 245 ddb_listview_column_append (DdbListview *listview, const char *title, int width, int align_right, int minheight, int color_override, GdkColor color, void *user_data); 246 void 247 ddb_listview_column_insert (DdbListview *listview, int before, const char *title, int width, int align_right, int minheight, int color_override, GdkColor color, void *user_data); 248 void 249 ddb_listview_column_remove (DdbListview *listview, int idx); 250 int 251 ddb_listview_column_get_info (DdbListview *listview, int col, const char **title, int *width, int *align_right, int *minheight, int *color_override, GdkColor *color, void **user_data); 252 int 253 ddb_listview_column_set_info (DdbListview *listview, int col, const char *title, int width, int align_right, int minheight, int color_override, GdkColor color, void *user_data); 254 void 255 ddb_listview_show_header (DdbListview *listview, int show); 256 void 257 ddb_listview_init_autoresize (DdbListview *ps, int totalwidth); 258 259 enum { 260 DDB_REFRESH_COLUMNS = 1, 261 DDB_REFRESH_HSCROLL = 2, 262 DDB_REFRESH_VSCROLL = 4, 263 DDB_REFRESH_LIST = 8, 264 DDB_LIST_CHANGED = 16, 265 }; 266 267 void ddb_listview_refresh (DdbListview *listview, uint32_t flags); 268 269 gboolean 270 ddb_listview_list_drag_drop (GtkWidget *widget, 271 GdkDragContext *drag_context, 272 gint x, 273 gint y, 274 guint time, 275 gpointer user_data); 276 277 void 278 ddb_listview_list_drag_data_get (GtkWidget *widget, 279 GdkDragContext *drag_context, 280 GtkSelectionData *data, 281 guint info, 282 guint time, 283 gpointer user_data); 284 285 void 286 ddb_listview_list_drag_end (GtkWidget *widget, 287 GdkDragContext *drag_context, 288 gpointer user_data); 289 290 void 291 ddb_listview_list_drag_data_received (GtkWidget *widget, 292 GdkDragContext *drag_context, 293 gint x, 294 gint y, 295 GtkSelectionData *data, 296 guint target_type, 297 guint time, 298 gpointer user_data); 299 300 void 301 ddb_listview_list_drag_leave (GtkWidget *widget, 302 GdkDragContext *drag_context, 303 guint time, 304 gpointer user_data); 305 306 void 307 ddb_listview_list_drag_end (GtkWidget *widget, 308 GdkDragContext *drag_context, 309 gpointer user_data); 310 311 void 312 ddb_listview_clear_sort (DdbListview *listview); 313 314 void 315 ddb_listview_lock_columns (DdbListview *lv, gboolean lock); 316 317 int 318 ddb_listview_get_row_pos (DdbListview *listview, int row_idx); 319 320 void 321 ddb_listview_groupcheck (DdbListview *listview); 322 323 int 324 ddb_listview_is_album_art_column (DdbListview *listview, int x); 325 326 int 327 ddb_listview_is_album_art_column_idx (DdbListview *listview, int cidx); 328 329 void 330 ddb_listview_update_fonts (DdbListview *ps); 331 332 void 333 ddb_listview_header_update_fonts (DdbListview *ps); 334 335 void 336 ddb_listview_cancel_autoredraw (DdbListview *listview); 337 338 G_END_DECLS 339 340 #endif // __DDBLISTVIEW_H 341