Code

screen_interface: add method mouse(), replacing CMD_MOUSE_EVENT
[ncmpc.git] / src / screen.c
1 /* ncmpc (Ncurses MPD Client)
2  * (c) 2004-2017 The Music Player Daemon Project
3  * Project homepage: http://musicpd.org
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
20 #include "screen.h"
21 #include "screen_interface.h"
22 #include "screen_list.h"
23 #include "screen_status.h"
24 #include "config.h"
25 #include "i18n.h"
26 #include "charset.h"
27 #include "mpdclient.h"
28 #include "options.h"
29 #include "player_command.h"
30 #include "screen_help.h"
31 #include "screen_queue.h"
32 #include "screen_file.h"
33 #include "screen_artist.h"
34 #include "screen_search.h"
35 #include "screen_song.h"
36 #include "screen_keydef.h"
37 #include "screen_lyrics.h"
38 #include "screen_outputs.h"
39 #include "screen_chat.h"
41 #include <mpd/client.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45 #include <string.h>
46 #include <time.h>
48 /* screens */
50 struct screen screen = {
51         .current_page = &screen_queue,
52 };
54 static const struct screen_functions *mode_fn_prev = &screen_queue;
56 void
57 screen_switch(const struct screen_functions *sf, struct mpdclient *c)
58 {
59         assert(sf != NULL);
61         if (sf == screen.current_page)
62                 return;
64         mode_fn_prev = screen.current_page;
66         /* close the old mode */
67         if (screen.current_page->close != NULL)
68                 screen.current_page->close();
70         /* get functions for the new mode */
71         screen.current_page = sf;
73         /* open the new mode */
74         if (sf->open != NULL)
75                 sf->open(c);
77         screen_paint(c, true);
78 }
80 void
81 screen_swap(struct mpdclient *c, const struct mpd_song *song)
82 {
83         if (song != NULL)
84         {
85                 if (false)
86                         { /* just a hack to make the ifdefs less ugly */ }
87 #ifdef ENABLE_SONG_SCREEN
88                 if (mode_fn_prev == &screen_song)
89                         screen_song_switch(c, song);
90 #endif
91 #ifdef ENABLE_LYRICS_SCREEN
92                 else if (mode_fn_prev == &screen_lyrics)
93                         screen_lyrics_switch(c, song, true);
94 #endif
95                 else
96                         screen_switch(mode_fn_prev, c);
97         }
98         else
99                 screen_switch(mode_fn_prev, c);
102 static int
103 find_configured_screen(const char *name)
105         unsigned i;
107         for (i = 0; options.screen_list[i] != NULL; ++i)
108                 if (strcmp(options.screen_list[i], name) == 0)
109                         return i;
111         return -1;
114 static void
115 screen_next_mode(struct mpdclient *c, int offset)
117         int max = g_strv_length(options.screen_list);
119         /* find current screen */
120         int current = find_configured_screen(screen_get_name(screen.current_page));
121         int next = current + offset;
122         if (next<0)
123                 next = max-1;
124         else if (next>=max)
125                 next = 0;
127         const struct screen_functions *sf =
128                 screen_lookup_name(options.screen_list[next]);
129         if (sf != NULL)
130                 screen_switch(sf, c);
133 void
134 screen_update(struct mpdclient *c)
136 #ifndef NCMPC_MINI
137         static bool was_connected;
138         static bool initialized = false;
139         static bool repeat;
140         static bool random_enabled;
141         static bool single;
142         static bool consume;
143         static unsigned crossfade;
145         /* print a message if mpd status has changed */
146         if ((c->events & MPD_IDLE_OPTIONS) && c->status != NULL) {
147                 if (!initialized) {
148                         repeat = mpd_status_get_repeat(c->status);
149                         random_enabled = mpd_status_get_random(c->status);
150                         single = mpd_status_get_single(c->status);
151                         consume = mpd_status_get_consume(c->status);
152                         crossfade = mpd_status_get_crossfade(c->status);
153                         initialized = true;
154                 }
156                 if (repeat != mpd_status_get_repeat(c->status))
157                         screen_status_printf(mpd_status_get_repeat(c->status) ?
158                                              _("Repeat mode is on") :
159                                              _("Repeat mode is off"));
161                 if (random_enabled != mpd_status_get_random(c->status))
162                         screen_status_printf(mpd_status_get_random(c->status) ?
163                                              _("Random mode is on") :
164                                              _("Random mode is off"));
166                 if (single != mpd_status_get_single(c->status))
167                         screen_status_printf(mpd_status_get_single(c->status) ?
168                                              /* "single" mode means
169                                                 that MPD will
170                                                 automatically stop
171                                                 after playing one
172                                                 single song */
173                                              _("Single mode is on") :
174                                              _("Single mode is off"));
176                 if (consume != mpd_status_get_consume(c->status))
177                         screen_status_printf(mpd_status_get_consume(c->status) ?
178                                              /* "consume" mode means
179                                                 that MPD removes each
180                                                 song which has
181                                                 finished playing */
182                                              _("Consume mode is on") :
183                                              _("Consume mode is off"));
185                 if (crossfade != mpd_status_get_crossfade(c->status))
186                         screen_status_printf(_("Crossfade %d seconds"),
187                                              mpd_status_get_crossfade(c->status));
189                 repeat = mpd_status_get_repeat(c->status);
190                 random_enabled = mpd_status_get_random(c->status);
191                 single = mpd_status_get_single(c->status);
192                 consume = mpd_status_get_consume(c->status);
193                 crossfade = mpd_status_get_crossfade(c->status);
194         }
196         if ((c->events & MPD_IDLE_DATABASE) != 0 && was_connected &&
197             mpdclient_is_connected(c))
198                 screen_status_printf(_("Database updated"));
199         was_connected = mpdclient_is_connected(c);
200 #endif
202         /* update the main window */
203         if (screen.current_page->update != NULL)
204                 screen.current_page->update(c);
206         screen_paint(c, false);
209 void
210 screen_cmd(struct mpdclient *c, command_t cmd)
212 #ifndef NCMPC_MINI
213         if (screen.welcome_source_id != 0) {
214                 g_source_remove(screen.welcome_source_id);
215                 screen.welcome_source_id = 0;
216         }
217 #endif
219         if (screen.current_page->cmd != NULL &&
220             screen.current_page->cmd(c, cmd))
221                 return;
223         if (handle_player_command(c, cmd))
224                 return;
226         switch(cmd) {
227         case CMD_TOGGLE_FIND_WRAP:
228                 options.find_wrap = !options.find_wrap;
229                 screen_status_printf(options.find_wrap ?
230                                      _("Find mode: Wrapped") :
231                                      _("Find mode: Normal"));
232                 break;
233         case CMD_TOGGLE_AUTOCENTER:
234                 options.auto_center = !options.auto_center;
235                 screen_status_printf(options.auto_center ?
236                                      _("Auto center mode: On") :
237                                      _("Auto center mode: Off"));
238                 break;
239         case CMD_SCREEN_UPDATE:
240                 screen_paint(c, true);
241                 break;
242         case CMD_SCREEN_PREVIOUS:
243                 screen_next_mode(c, -1);
244                 break;
245         case CMD_SCREEN_NEXT:
246                 screen_next_mode(c, 1);
247                 break;
248         case CMD_SCREEN_PLAY:
249                 screen_switch(&screen_queue, c);
250                 break;
251         case CMD_SCREEN_FILE:
252                 screen_switch(&screen_browse, c);
253                 break;
254 #ifdef ENABLE_HELP_SCREEN
255         case CMD_SCREEN_HELP:
256                 screen_switch(&screen_help, c);
257                 break;
258 #endif
259 #ifdef ENABLE_SEARCH_SCREEN
260         case CMD_SCREEN_SEARCH:
261                 screen_switch(&screen_search, c);
262                 break;
263 #endif
264 #ifdef ENABLE_ARTIST_SCREEN
265         case CMD_SCREEN_ARTIST:
266                 screen_switch(&screen_artist, c);
267                 break;
268 #endif
269 #ifdef ENABLE_SONG_SCREEN
270         case CMD_SCREEN_SONG:
271                 screen_switch(&screen_song, c);
272                 break;
273 #endif
274 #ifdef ENABLE_KEYDEF_SCREEN
275         case CMD_SCREEN_KEYDEF:
276                 screen_switch(&screen_keydef, c);
277                 break;
278 #endif
279 #ifdef ENABLE_LYRICS_SCREEN
280         case CMD_SCREEN_LYRICS:
281                 screen_switch(&screen_lyrics, c);
282                 break;
283 #endif
284 #ifdef ENABLE_OUTPUTS_SCREEN
285         case CMD_SCREEN_OUTPUTS:
286                 screen_switch(&screen_outputs, c);
287                 break;
288 #endif
289 #ifdef ENABLE_CHAT_SCREEN
290         case CMD_SCREEN_CHAT:
291                 screen_switch(&screen_chat, c);
292                 break;
293 #endif
294         case CMD_SCREEN_SWAP:
295                 screen_swap(c, NULL);
296                 break;
298         default:
299                 break;
300         }
303 #ifdef HAVE_GETMOUSE
305 static bool
306 screen_current_page_mouse(struct mpdclient *c, int x, int y, mmask_t bstate)
308         if (screen.current_page->mouse == NULL)
309                 return false;
311         y -= screen.title_bar.window.rows;
312         return screen.current_page->mouse(c, x, y, bstate);
315 bool
316 screen_mouse(struct mpdclient *c, int x, int y, mmask_t bstate)
318         if (screen_current_page_mouse(c, x, y, bstate))
319                 return true;
321         /* if button 2 was pressed switch screen */
322         if (bstate & BUTTON2_CLICKED) {
323                 screen_cmd(c, CMD_SCREEN_NEXT);
324                 return true;
325         }
327         return false;
330 #endif