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"
28 #ifndef NCMPC_MINI
29 #include "hscroll.h"
30 #endif
32 #include <mpd/client.h>
34 #include <assert.h>
35 #include <string.h>
37 static gboolean
38 status_bar_clear_message(gpointer data)
39 {
40 struct status_bar *p = data;
41 WINDOW *w = p->window.w;
43 assert(p != NULL);
44 assert(p->message_source_id != 0);
46 p->message_source_id = 0;
48 wmove(w, 0, 0);
49 wclrtoeol(w);
50 wrefresh(w);
52 return false;
53 }
55 void
56 status_bar_paint(const struct status_bar *p, const struct mpd_status *status,
57 const struct mpd_song *song)
58 {
59 WINDOW *w = p->window.w;
60 enum mpd_state state;
61 int elapsedTime = 0;
62 #ifdef NCMPC_MINI
63 static char bitrate[1];
64 #else
65 char bitrate[16];
66 #endif
67 const char *str = NULL;
68 int x = 0;
69 char buffer[p->window.cols * 4 + 1];
71 if (p->message_source_id != 0)
72 return;
74 wmove(w, 0, 0);
75 wclrtoeol(w);
76 colors_use(w, COLOR_STATUS_BOLD);
78 state = status == NULL ? MPD_STATE_UNKNOWN
79 : mpd_status_get_state(status);
81 switch (state) {
82 case MPD_STATE_PLAY:
83 str = _("Playing:");
84 break;
85 case MPD_STATE_PAUSE:
86 str = _("[Paused]");
87 break;
88 case MPD_STATE_STOP:
89 default:
90 break;
91 }
93 if (str) {
94 waddstr(w, str);
95 x += utf8_width(str) + 1;
96 }
98 /* create time string */
99 if (state == MPD_STATE_PLAY || state == MPD_STATE_PAUSE) {
100 int total_time = mpd_status_get_total_time(status);
101 if (total_time > 0) {
102 /*checks the conf to see whether to display elapsed or remaining time */
103 if(!strcmp(options.timedisplay_type,"elapsed"))
104 elapsedTime = mpd_status_get_elapsed_time(status);
105 else if(!strcmp(options.timedisplay_type,"remaining"))
106 elapsedTime = total_time -
107 mpd_status_get_elapsed_time(status);
109 if (song != NULL &&
110 seek_id == (int)mpd_song_get_id(song))
111 elapsedTime = seek_target_time;
113 /* display bitrate if visible-bitrate is true */
114 #ifndef NCMPC_MINI
115 if (options.visible_bitrate) {
116 g_snprintf(bitrate, 16,
117 " [%d kbps]",
118 mpd_status_get_kbit_rate(status));
119 } else {
120 bitrate[0] = '\0';
121 }
122 #endif
124 /*write out the time, using hours if time over 60 minutes*/
125 if (total_time > 3600) {
126 g_snprintf(buffer, sizeof(buffer),
127 "%s [%i:%02i:%02i/%i:%02i:%02i]",
128 bitrate, elapsedTime/3600, (elapsedTime%3600)/60, elapsedTime%60,
129 total_time / 3600,
130 (total_time % 3600)/60,
131 total_time % 60);
132 } else {
133 g_snprintf(buffer, sizeof(buffer),
134 "%s [%i:%02i/%i:%02i]",
135 bitrate, elapsedTime/60, elapsedTime%60,
136 total_time / 60, total_time % 60);
137 }
138 #ifndef NCMPC_MINI
139 } else {
140 g_snprintf(buffer, sizeof(buffer),
141 " [%d kbps]",
142 mpd_status_get_kbit_rate(status));
143 #endif
144 }
145 #ifndef NCMPC_MINI
146 } else {
147 if (options.display_time) {
148 time_t timep;
150 time(&timep);
151 strftime(buffer, sizeof(buffer), "%X ",localtime(&timep));
152 } else
153 #endif
154 buffer[0] = 0;
155 }
157 /* display song */
158 if (state == MPD_STATE_PLAY || state == MPD_STATE_PAUSE) {
159 char songname[p->window.cols * 4 + 1];
160 #ifndef NCMPC_MINI
161 int width = COLS - x - utf8_width(buffer);
162 #endif
164 if (song)
165 strfsong(songname, sizeof(songname),
166 options.status_format, song);
167 else
168 songname[0] = '\0';
170 colors_use(w, COLOR_STATUS);
171 /* scroll if the song name is to long */
172 #ifndef NCMPC_MINI
173 if (options.scroll && utf8_width(songname) > (unsigned)width) {
174 static scroll_state_t st = { 0, 0 };
175 char *tmp = strscroll(songname, options.scroll_sep, width, &st);
177 g_strlcpy(songname, tmp, sizeof(songname));
178 g_free(tmp);
179 }
180 #endif
181 //mvwaddnstr(w, 0, x, songname, width);
182 mvwaddstr(w, 0, x, songname);
183 }
185 /* display time string */
186 if (buffer[0] != 0) {
187 x = p->window.cols - strlen(buffer);
188 colors_use(w, COLOR_STATUS_TIME);
189 mvwaddstr(w, 0, x, buffer);
190 }
192 wnoutrefresh(w);
193 }
195 void
196 status_bar_resize(struct status_bar *p, unsigned width, int y, int x)
197 {
198 p->window.cols = width;
199 wresize(p->window.w, 1, width);
200 mvwin(p->window.w, y, x);
201 }
203 void
204 status_bar_message(struct status_bar *p, const char *msg)
205 {
206 WINDOW *w = p->window.w;
208 wmove(w, 0, 0);
209 wclrtoeol(w);
210 colors_use(w, COLOR_STATUS_ALERT);
211 waddstr(w, msg);
212 wnoutrefresh(w);
214 if (p->message_source_id != 0)
215 g_source_remove(p->message_source_id);
216 p->message_source_id = g_timeout_add(options.status_message_time * 1000,
217 status_bar_clear_message, p);
218 }