1 /*
2 * Copyright (c) 2011 Tim van der Molen <tim@kariliq.nl>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include <stdlib.h>
18
19 #include "siren.h"
20
21 struct view_entry {
22 enum view_id id;
23 enum bind_scope bind_scope;
24 void (*print)(void);
25 void (*activate_entry)(void);
26 void (*copy_entry)(enum view_id);
27 void (*delete_all_entries)(void);
28 void (*delete_entry)(void);
29 void (*move_entry_down)(void);
30 void (*move_entry_up)(void);
31 void (*search_next)(const char *);
32 void (*search_prev)(const char *);
33 void (*select_active_entry)(void);
34 void (*select_prev_entry)(void);
35 void (*select_next_entry)(void);
36 void (*select_first_entry)(void);
37 void (*select_last_entry)(void);
38 void (*scroll_down)(enum menu_scroll);
39 void (*scroll_up)(enum menu_scroll);
40 };
41
42 static struct view_entry view_list[] = {
43 {
44 VIEW_ID_LIBRARY,
45 BIND_SCOPE_LIBRARY,
46 library_print,
47 library_activate_entry,
48 library_copy_entry,
49 library_delete_all_entries,
50 library_delete_entry,
51 NULL,
52 NULL,
53 library_search_next,
54 library_search_prev,
55 library_select_active_entry,
56 library_select_prev_entry,
57 library_select_next_entry,
58 library_select_first_entry,
59 library_select_last_entry,
60 library_scroll_down,
61 library_scroll_up
62 },
63 {
64 VIEW_ID_PLAYLIST,
65 BIND_SCOPE_PLAYLIST,
66 playlist_print,
67 playlist_activate_entry,
68 playlist_copy_entry,
69 NULL,
70 NULL,
71 NULL,
72 NULL,
73 playlist_search_next,
74 playlist_search_prev,
75 playlist_select_active_entry,
76 playlist_select_prev_entry,
77 playlist_select_next_entry,
78 playlist_select_first_entry,
79 playlist_select_last_entry,
80 playlist_scroll_down,
81 playlist_scroll_up
82 },
83 {
84 VIEW_ID_QUEUE,
85 BIND_SCOPE_QUEUE,
86 queue_print,
87 queue_activate_entry,
88 queue_copy_entry,
89 queue_delete_all_entries,
90 queue_delete_entry,
91 queue_move_entry_down,
92 queue_move_entry_up,
93 queue_search_next,
94 queue_search_prev,
95 NULL,
96 queue_select_prev_entry,
97 queue_select_next_entry,
98 queue_select_first_entry,
99 queue_select_last_entry,
100 queue_scroll_down,
101 queue_scroll_up
102 },
103 {
104 VIEW_ID_BROWSER,
105 BIND_SCOPE_BROWSER,
106 browser_print,
107 browser_activate_entry,
108 browser_copy_entry,
109 NULL,
110 NULL,
111 NULL,
112 NULL,
113 browser_search_next,
114 browser_search_prev,
115 browser_select_active_entry,
116 browser_select_prev_entry,
117 browser_select_next_entry,
118 browser_select_first_entry,
119 browser_select_last_entry,
120 browser_scroll_down,
121 browser_scroll_up
122 }
123 };
124
125 static int view_sel;
126 static char *view_search = NULL;
127
128 void
view_activate_entry(void)129 view_activate_entry(void)
130 {
131 view_list[view_sel].activate_entry();
132 }
133
134 void
view_add_dir(enum view_id view,const char * path)135 view_add_dir(enum view_id view, const char *path)
136 {
137 switch (view) {
138 case VIEW_ID_LIBRARY:
139 library_add_dir(path);
140 break;
141 case VIEW_ID_QUEUE:
142 queue_add_dir(path);
143 break;
144 default:
145 msg_errx("Cannot add tracks to this view");
146 break;
147 }
148 }
149
150 void
view_add_track(enum view_id view,struct track * t)151 view_add_track(enum view_id view, struct track *t)
152 {
153 switch (view) {
154 case VIEW_ID_LIBRARY:
155 library_add_track(t);
156 break;
157 case VIEW_ID_QUEUE:
158 queue_add_track(t);
159 break;
160 default:
161 msg_errx("Cannot add tracks to this view");
162 break;
163 }
164 }
165
166 void
view_copy_entry(enum view_id view)167 view_copy_entry(enum view_id view)
168 {
169 view_list[view_sel].copy_entry(view);
170 }
171
172 void
view_delete_all_entries(void)173 view_delete_all_entries(void)
174 {
175 if (view_list[view_sel].delete_all_entries == NULL)
176 msg_errx("Cannot delete entries in this view");
177 else
178 view_list[view_sel].delete_all_entries();
179 }
180
181 void
view_delete_entry(void)182 view_delete_entry(void)
183 {
184 if (view_list[view_sel].delete_entry == NULL)
185 msg_errx("Cannot delete entries in this view");
186 else
187 view_list[view_sel].delete_entry();
188 }
189
190 enum view_id
view_get_id(void)191 view_get_id(void)
192 {
193 return view_list[view_sel].id;
194 }
195
196 void
view_handle_key(int key)197 view_handle_key(int key)
198 {
199 msg_clear();
200
201 if (bind_execute(view_list[view_sel].bind_scope, key) == 0)
202 return;
203 if (bind_execute(BIND_SCOPE_COMMON, key) == 0)
204 return;
205
206 msg_errx("Key not bound");
207 }
208
209 void
view_move_entry_down(void)210 view_move_entry_down(void)
211 {
212 if (view_list[view_sel].move_entry_down == NULL)
213 msg_errx("Cannot move entries in this view");
214 else
215 view_list[view_sel].move_entry_down();
216 }
217
218 void
view_move_entry_up(void)219 view_move_entry_up(void)
220 {
221 if (view_list[view_sel].move_entry_up == NULL)
222 msg_errx("Cannot move entries in this view");
223 else
224 view_list[view_sel].move_entry_up();
225 }
226
227 void
view_print(void)228 view_print(void)
229 {
230 view_list[view_sel].print();
231 }
232
233 void
view_scroll_down(enum menu_scroll scroll)234 view_scroll_down(enum menu_scroll scroll)
235 {
236 view_list[view_sel].scroll_down(scroll);
237 }
238
239 void
view_scroll_up(enum menu_scroll scroll)240 view_scroll_up(enum menu_scroll scroll)
241 {
242 view_list[view_sel].scroll_up(scroll);
243 }
244
245 void
view_search_next(const char * search)246 view_search_next(const char *search)
247 {
248 if (search != NULL) {
249 free(view_search);
250 view_search = xstrdup(search);
251 } else if (view_search == NULL) {
252 msg_errx("No previous search");
253 return;
254 }
255
256 view_list[view_sel].search_next(view_search);
257 }
258
259 void
view_search_prev(const char * search)260 view_search_prev(const char *search)
261 {
262 if (search != NULL) {
263 free(view_search);
264 view_search = xstrdup(search);
265 } else if (view_search == NULL) {
266 msg_errx("No previous search");
267 return;
268 }
269
270 view_list[view_sel].search_prev(view_search);
271 }
272
273 void
view_select_active_entry(void)274 view_select_active_entry(void)
275 {
276 if (view_list[view_sel].select_active_entry != NULL)
277 view_list[view_sel].select_active_entry();
278 }
279
280 void
view_select_first_entry(void)281 view_select_first_entry(void)
282 {
283 view_list[view_sel].select_first_entry();
284 }
285
286 void
view_select_last_entry(void)287 view_select_last_entry(void)
288 {
289 view_list[view_sel].select_last_entry();
290 }
291
292 void
view_select_next_entry(void)293 view_select_next_entry(void)
294 {
295 view_list[view_sel].select_next_entry();
296 }
297
298 void
view_select_prev_entry(void)299 view_select_prev_entry(void)
300 {
301 view_list[view_sel].select_prev_entry();
302 }
303
304 void
view_select_view(enum view_id id)305 view_select_view(enum view_id id)
306 {
307 size_t i;
308
309 if (view_list[view_sel].id != id)
310 for (i = 0; i < NELEMENTS(view_list); i++)
311 if (view_list[i].id == id) {
312 view_sel = i;
313 view_print();
314 break;
315 }
316 }
317