1 /* ncmpc (Ncurses MPD Client)
2 * (c) 2004-2009 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 "status_bar.h"
21 #include "options.h"
22 #include "colors.h"
23 #include "i18n.h"
24 #include "charset.h"
25 #include "strfsong.h"
26 #include "player_command.h"
27 #include "utils.h"
29 #include <mpd/client.h>
31 #include <assert.h>
32 #include <string.h>
34 void
35 status_bar_init(struct status_bar *p, unsigned width, int y, int x)
36 {
37 window_init(&p->window, 1, width, y, x);
39 leaveok(p->window.w, false);
40 keypad(p->window.w, true);
42 p->message_source_id = 0;
44 #ifndef NCMPC_MINI
45 if (options.scroll)
46 hscroll_init(&p->hscroll, p->window.w, options.scroll_sep);
48 p->prev_status = NULL;
49 p->prev_song = NULL;
50 #endif
51 }
53 void
54 status_bar_deinit(struct status_bar *p)
55 {
56 delwin(p->window.w);
58 #ifndef NCMPC_MINI
59 if (options.scroll)
60 hscroll_clear(&p->hscroll);
61 #endif
62 }
64 static gboolean
65 status_bar_clear_message(gpointer data)
66 {
67 struct status_bar *p = data;
68 WINDOW *w = p->window.w;
70 assert(p != NULL);
71 assert(p->message_source_id != 0);
73 p->message_source_id = 0;
75 wmove(w, 0, 0);
76 wclrtoeol(w);
77 wrefresh(w);
79 return false;
80 }
82 void
83 status_bar_paint(struct status_bar *p, const struct mpd_status *status,
84 const struct mpd_song *song)
85 {
86 WINDOW *w = p->window.w;
87 enum mpd_state state;
88 int elapsedTime = 0;
89 #ifdef NCMPC_MINI
90 static char bitrate[1];
91 #else
92 char bitrate[16];
93 #endif
94 const char *str = NULL;
95 int x = 0;
96 char buffer[p->window.cols * 4 + 1];
98 #ifndef NCMPC_MINI
99 p->prev_status = status;
100 p->prev_song = song;
101 #endif
103 if (p->message_source_id != 0)
104 return;
106 wmove(w, 0, 0);
107 wclrtoeol(w);
108 colors_use(w, COLOR_STATUS_BOLD);
110 state = status == NULL ? MPD_STATE_UNKNOWN
111 : mpd_status_get_state(status);
113 switch (state) {
114 case MPD_STATE_PLAY:
115 str = _("Playing:");
116 break;
117 case MPD_STATE_PAUSE:
118 str = _("[Paused]");
119 break;
120 case MPD_STATE_STOP:
121 default:
122 break;
123 }
125 if (str) {
126 waddstr(w, str);
127 x += utf8_width(str) + 1;
128 }
130 /* create time string */
131 if (state == MPD_STATE_PLAY || state == MPD_STATE_PAUSE) {
132 int total_time = mpd_status_get_total_time(status);
133 if (total_time > 0) {
134 char elapsed_string[32], duration_string[32];
136 /*checks the conf to see whether to display elapsed or remaining time */
137 if (seek_id >= 0 &&
138 seek_id == mpd_status_get_song_id(status))
139 elapsedTime = seek_target_time;
140 else if (options.display_remaining_time)
141 elapsedTime = total_time -
142 mpd_status_get_elapsed_time(status);
143 else
144 elapsedTime = mpd_status_get_elapsed_time(status);
146 /* display bitrate if visible-bitrate is true */
147 #ifndef NCMPC_MINI
148 if (options.visible_bitrate) {
149 g_snprintf(bitrate, 16,
150 " [%d kbps]",
151 mpd_status_get_kbit_rate(status));
152 } else {
153 bitrate[0] = '\0';
154 }
155 #endif
157 /* write out the time */
158 format_duration_short(elapsed_string,
159 sizeof(elapsed_string),
160 elapsedTime);
161 format_duration_short(duration_string,
162 sizeof(duration_string),
163 total_time);
165 g_snprintf(buffer, sizeof(buffer), "%s [%s/%s]",
166 bitrate, elapsed_string, duration_string);
167 #ifndef NCMPC_MINI
168 } else if (options.visible_bitrate) {
169 g_snprintf(buffer, sizeof(buffer),
170 " [%d kbps]",
171 mpd_status_get_kbit_rate(status));
172 #endif
173 } else {
174 buffer[0] = 0;
175 }
176 } else {
177 #ifndef NCMPC_MINI
178 if (options.display_time) {
179 time_t timep;
181 time(&timep);
182 strftime(buffer, sizeof(buffer), "%X ",localtime(&timep));
183 } else
184 #endif
185 buffer[0] = 0;
186 }
188 /* display song */
189 if (state == MPD_STATE_PLAY || state == MPD_STATE_PAUSE) {
190 char songname[p->window.cols * 4 + 1];
191 #ifndef NCMPC_MINI
192 int width = COLS - x - utf8_width(buffer);
193 #endif
195 if (song)
196 strfsong(songname, sizeof(songname),
197 options.status_format, song);
198 else
199 songname[0] = '\0';
201 colors_use(w, COLOR_STATUS);
202 /* scroll if the song name is to long */
203 #ifndef NCMPC_MINI
204 if (options.scroll && utf8_width(songname) > (unsigned)width) {
205 hscroll_set(&p->hscroll, x, 0, width, songname);
206 hscroll_draw(&p->hscroll);
207 } else {
208 if (options.scroll)
209 hscroll_clear(&p->hscroll);
210 mvwaddstr(w, 0, x, songname);
211 }
212 #else
213 mvwaddstr(w, 0, x, songname);
214 #endif
215 #ifndef NCMPC_MINI
216 } else if (options.scroll) {
217 hscroll_clear(&p->hscroll);
218 #endif
219 }
221 /* display time string */
222 if (buffer[0] != 0) {
223 x = p->window.cols - strlen(buffer);
224 colors_use(w, COLOR_STATUS_TIME);
225 mvwaddstr(w, 0, x, buffer);
226 }
228 wnoutrefresh(w);
229 }
231 void
232 status_bar_resize(struct status_bar *p, unsigned width, int y, int x)
233 {
234 p->window.cols = width;
235 wresize(p->window.w, 1, width);
236 mvwin(p->window.w, y, x);
237 }
239 void
240 status_bar_message(struct status_bar *p, const char *msg)
241 {
242 WINDOW *w = p->window.w;
244 #ifndef NCMPC_MINI
245 if (options.scroll)
246 hscroll_clear(&p->hscroll);
247 #endif
249 wmove(w, 0, 0);
250 wclrtoeol(w);
251 colors_use(w, COLOR_STATUS_ALERT);
252 waddstr(w, msg);
253 wnoutrefresh(w);
255 if (p->message_source_id != 0)
256 g_source_remove(p->message_source_id);
257 p->message_source_id = g_timeout_add(options.status_message_time * 1000,
258 status_bar_clear_message, p);
259 }