1 /***************************************************************************
2 * Copyright (C) 2008-2013 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
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. *
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. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
24 #include "statusbar.h"
27 #include "utility/wide_string.h"
29 using Global::wFooter
;
33 timeval statusbarLockTime
;
34 int statusbarLockDelay
= -1;
36 bool statusbarBlockUpdate
= false;
37 bool progressbarBlockUpdate
= false;
38 bool statusbarAllowUnlock
= true;
40 void showMessage(int time
, const char *format
, va_list list
)
42 if (statusbarAllowUnlock
)
44 statusbarLockTime
= Global::Timer
;
45 statusbarLockDelay
= time
;
46 if (Config
.statusbar_visibility
)
47 statusbarBlockUpdate
= true;
49 progressbarBlockUpdate
= true;
50 wFooter
->goToXY(0, Config
.statusbar_visibility
);
51 *wFooter
<< NC::Format::NoBold
;
52 wmove(wFooter
->raw(), Config
.statusbar_visibility
, 0);
53 vw_printw(wFooter
->raw(), format
, list
);
54 wclrtoeol(wFooter
->raw());
61 void Progressbar::lock()
63 progressbarBlockUpdate
= true;
66 void Progressbar::unlock()
68 progressbarBlockUpdate
= false;
71 bool Progressbar::isUnlocked()
73 return !progressbarBlockUpdate
;
76 void Progressbar::draw(unsigned int elapsed
, unsigned int time
)
78 unsigned pb_width
= wFooter
->getWidth();
79 unsigned howlong
= time
? pb_width
*elapsed
/time
: 0;
80 if (Config
.progressbar_boldness
)
81 *wFooter
<< NC::Format::Bold
;
82 *wFooter
<< Config
.progressbar_color
;
83 if (Config
.progressbar
[2] != '\0')
85 wFooter
->goToXY(0, 0);
86 for (unsigned i
= 0; i
< pb_width
; ++i
)
87 *wFooter
<< Config
.progressbar
[2];
88 wFooter
->goToXY(0, 0);
91 mvwhline(wFooter
->raw(), 0, 0, 0, pb_width
);
94 *wFooter
<< Config
.progressbar_elapsed_color
;
95 pb_width
= std::min(size_t(howlong
), wFooter
->getWidth());
96 for (unsigned i
= 0; i
< pb_width
; ++i
)
97 *wFooter
<< Config
.progressbar
[0];
98 if (howlong
< wFooter
->getWidth())
99 *wFooter
<< Config
.progressbar
[1];
100 *wFooter
<< NC::Color::End
;
102 *wFooter
<< NC::Color::End
;
103 if (Config
.progressbar_boldness
)
104 *wFooter
<< NC::Format::NoBold
;
107 void Statusbar::lock()
109 if (Config
.statusbar_visibility
)
110 statusbarBlockUpdate
= true;
112 progressbarBlockUpdate
= true;
113 statusbarAllowUnlock
= false;
116 void Statusbar::unlock()
118 statusbarAllowUnlock
= true;
119 if (statusbarLockDelay
< 0)
121 if (Config
.statusbar_visibility
)
122 statusbarBlockUpdate
= false;
124 progressbarBlockUpdate
= false;
126 if (Status::State::player() == MPD::psStop
)
128 if (Config
.new_design
)
129 Progressbar::draw(Status::State::elapsedTime(), myPlaylist
->currentSongLength());
136 bool Statusbar::isUnlocked()
138 return !statusbarBlockUpdate
;
141 void Statusbar::tryRedraw()
144 if (statusbarLockDelay
> 0
145 && Timer
.tv_sec
>= statusbarLockTime
.tv_sec
+statusbarLockDelay
)
147 statusbarLockDelay
= -1;
149 if (Config
.statusbar_visibility
)
150 statusbarBlockUpdate
= !statusbarAllowUnlock
;
152 progressbarBlockUpdate
= !statusbarAllowUnlock
;
154 if (Status::State::player() != MPD::psStop
&& !statusbarBlockUpdate
&& !progressbarBlockUpdate
)
156 if (Config
.new_design
)
157 Progressbar::draw(Status::State::elapsedTime(), myPlaylist
->currentSongLength());
159 Status::Changes::elapsedTime(false);
165 NC::Window
&Statusbar::put()
167 *wFooter
<< NC::XY(0, Config
.statusbar_visibility
? 1 : 0) << wclrtoeol
;
171 void Statusbar::msg(const char *format
, ...)
174 va_start(list
, format
);
175 showMessage(Config
.message_delay_time
, format
, list
);
179 void Statusbar::msg(int time
, const char *format
, ...)
182 va_start(list
, format
);
183 showMessage(time
, format
, list
);
187 void Statusbar::Helpers::mpd()
189 Status::update(Mpd
.noidle());
192 bool Statusbar::Helpers::getString(const char *)
198 bool Statusbar::Helpers::ApplyFilterImmediately::operator()(const char *s
)
200 using Global::myScreen
;
201 // if input queue is not empty, we don't want to update filter since next
202 // character will be taken from queue immediately, trigering this function
203 // again and thus making it inefficient, so let's apply filter only if
204 // "real" user input arrived. however, we want to apply filter if ENTER
205 // is next in queue, so its effects will be seen.
206 if (wFooter
->inputQueue().empty() || wFooter
->inputQueue().front() == KEY_ENTER
)
211 m_f
->applyFilter(m_s
);
212 myScreen
->refreshWindow();
219 bool Statusbar::Helpers::TryExecuteImmediateCommand::operator()(const char *s
)
221 bool continue_
= true;
225 auto cmd
= Bindings
.findCommand(m_s
);
226 if (cmd
&& cmd
->immediate())