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