4e0320639c733f368d5862890e1af331dc9ce314
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 #ifndef NCMPC_MINI
35 static gboolean
36 scroll_timer_callback(gpointer data)
37 {
38 struct status_bar *p = data;
40 p->scroll_source_id = 0;
42 hscroll_step(&p->hscroll);
43 status_bar_paint(p, p->prev_status, p->prev_song);
44 doupdate();
45 return false;
46 }
47 #endif
49 static gboolean
50 status_bar_clear_message(gpointer data)
51 {
52 struct status_bar *p = data;
53 WINDOW *w = p->window.w;
55 assert(p != NULL);
56 assert(p->message_source_id != 0);
58 p->message_source_id = 0;
60 wmove(w, 0, 0);
61 wclrtoeol(w);
62 wrefresh(w);
64 return false;
65 }
67 void
68 status_bar_paint(struct status_bar *p, const struct mpd_status *status,
69 const struct mpd_song *song)
70 {
71 WINDOW *w = p->window.w;
72 enum mpd_state state;
73 int elapsedTime = 0;
74 #ifdef NCMPC_MINI
75 static char bitrate[1];
76 #else
77 char bitrate[16];
78 #endif
79 const char *str = NULL;
80 int x = 0;
81 char buffer[p->window.cols * 4 + 1];
83 #ifndef NCMPC_MINI
84 p->prev_status = status;
85 p->prev_song = song;
86 #endif
88 if (p->message_source_id != 0)
89 return;
91 wmove(w, 0, 0);
92 wclrtoeol(w);
93 colors_use(w, COLOR_STATUS_BOLD);
95 state = status == NULL ? MPD_STATE_UNKNOWN
96 : mpd_status_get_state(status);
98 switch (state) {
99 case MPD_STATE_PLAY:
100 str = _("Playing:");
101 break;
102 case MPD_STATE_PAUSE:
103 str = _("[Paused]");
104 break;
105 case MPD_STATE_STOP:
106 default:
107 break;
108 }
110 if (str) {
111 waddstr(w, str);
112 x += utf8_width(str) + 1;
113 }
115 /* create time string */
116 if (state == MPD_STATE_PLAY || state == MPD_STATE_PAUSE) {
117 int total_time = mpd_status_get_total_time(status);
118 if (total_time > 0) {
119 char elapsed_string[32], duration_string[32];
121 /*checks the conf to see whether to display elapsed or remaining time */
122 if(!strcmp(options.timedisplay_type,"elapsed"))
123 elapsedTime = mpd_status_get_elapsed_time(status);
124 else if(!strcmp(options.timedisplay_type,"remaining"))
125 elapsedTime = total_time -
126 mpd_status_get_elapsed_time(status);
128 if (song != NULL &&
129 seek_id == (int)mpd_song_get_id(song))
130 elapsedTime = seek_target_time;
132 /* display bitrate if visible-bitrate is true */
133 #ifndef NCMPC_MINI
134 if (options.visible_bitrate) {
135 g_snprintf(bitrate, 16,
136 " [%d kbps]",
137 mpd_status_get_kbit_rate(status));
138 } else {
139 bitrate[0] = '\0';
140 }
141 #endif
143 /* write out the time */
144 format_duration_short(elapsed_string,
145 sizeof(elapsed_string),
146 elapsedTime);
147 format_duration_short(duration_string,
148 sizeof(duration_string),
149 total_time);
151 g_snprintf(buffer, sizeof(buffer), "%s [%s/%s]",
152 bitrate, elapsed_string, duration_string);
153 #ifndef NCMPC_MINI
154 } else if (options.visible_bitrate) {
155 g_snprintf(buffer, sizeof(buffer),
156 " [%d kbps]",
157 mpd_status_get_kbit_rate(status));
158 #endif
159 } else {
160 buffer[0] = 0;
161 }
162 } else {
163 #ifndef NCMPC_MINI
164 if (options.display_time) {
165 time_t timep;
167 time(&timep);
168 strftime(buffer, sizeof(buffer), "%X ",localtime(&timep));
169 } else
170 #endif
171 buffer[0] = 0;
172 }
174 /* display song */
175 if (state == MPD_STATE_PLAY || state == MPD_STATE_PAUSE) {
176 char songname[p->window.cols * 4 + 1];
177 #ifndef NCMPC_MINI
178 int width = COLS - x - utf8_width(buffer);
179 #endif
181 if (song)
182 strfsong(songname, sizeof(songname),
183 options.status_format, song);
184 else
185 songname[0] = '\0';
187 colors_use(w, COLOR_STATUS);
188 /* scroll if the song name is to long */
189 #ifndef NCMPC_MINI
190 if (options.scroll && utf8_width(songname) > (unsigned)width) {
191 char *tmp = strscroll(&p->hscroll, songname,
192 options.scroll_sep, width);
194 g_strlcpy(songname, tmp, sizeof(songname));
195 g_free(tmp);
197 if (p->scroll_source_id == 0)
198 p->scroll_source_id =
199 g_timeout_add(1000,
200 scroll_timer_callback,
201 p);
202 } else if (p->scroll_source_id != 0) {
203 g_source_remove(p->scroll_source_id);
204 p->scroll_source_id = 0;
205 }
206 #endif
207 //mvwaddnstr(w, 0, x, songname, width);
208 mvwaddstr(w, 0, x, songname);
209 #ifndef NCMPC_MINI
210 } else if (p->scroll_source_id != 0) {
211 g_source_remove(p->scroll_source_id);
212 p->scroll_source_id = 0;
213 #endif
214 }
216 /* display time string */
217 if (buffer[0] != 0) {
218 x = p->window.cols - strlen(buffer);
219 colors_use(w, COLOR_STATUS_TIME);
220 mvwaddstr(w, 0, x, buffer);
221 }
223 wnoutrefresh(w);
224 }
226 void
227 status_bar_resize(struct status_bar *p, unsigned width, int y, int x)
228 {
229 p->window.cols = width;
230 wresize(p->window.w, 1, width);
231 mvwin(p->window.w, y, x);
232 }
234 void
235 status_bar_message(struct status_bar *p, const char *msg)
236 {
237 WINDOW *w = p->window.w;
239 wmove(w, 0, 0);
240 wclrtoeol(w);
241 colors_use(w, COLOR_STATUS_ALERT);
242 waddstr(w, msg);
243 wnoutrefresh(w);
245 if (p->message_source_id != 0)
246 g_source_remove(p->message_source_id);
247 p->message_source_id = g_timeout_add(options.status_message_time * 1000,
248 status_bar_clear_message, p);
249 }