1 /***************************************************************************
2 * Copyright (C) 2008-2017 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"
26 #include "screens/playlist.h"
27 #include "utility/wide_string.h"
29 using Global::wFooter
;
33 bool progressbar_block_update
= false;
35 boost::posix_time::ptime statusbar_lock_time
;
36 boost::posix_time::seconds
statusbar_lock_delay(-1);
38 bool statusbar_block_update
= false;
39 bool statusbar_allow_unlock
= true;
43 Progressbar::ScopedLock::ScopedLock() noexcept
45 progressbar_block_update
= true;
48 Progressbar::ScopedLock::~ScopedLock() noexcept
50 progressbar_block_update
= false;
53 bool Progressbar::isUnlocked()
55 return !progressbar_block_update
;
58 void Progressbar::draw(unsigned int elapsed
, unsigned int time
)
60 unsigned pb_width
= wFooter
->getWidth();
61 unsigned howlong
= time
? pb_width
*elapsed
/time
: 0;
62 *wFooter
<< Config
.progressbar_color
;
63 if (Config
.progressbar
[2] != '\0')
65 wFooter
->goToXY(0, 0);
66 for (unsigned i
= 0; i
< pb_width
; ++i
)
67 *wFooter
<< Config
.progressbar
[2];
68 wFooter
->goToXY(0, 0);
71 mvwhline(wFooter
->raw(), 0, 0, 0, pb_width
);
72 *wFooter
<< NC::FormattedColor::End
<>(Config
.progressbar_color
);
75 *wFooter
<< Config
.progressbar_elapsed_color
;
76 pb_width
= std::min(size_t(howlong
), wFooter
->getWidth());
77 for (unsigned i
= 0; i
< pb_width
; ++i
)
78 *wFooter
<< Config
.progressbar
[0];
79 if (howlong
< wFooter
->getWidth())
80 *wFooter
<< Config
.progressbar
[1];
81 *wFooter
<< NC::FormattedColor::End
<>(Config
.progressbar_elapsed_color
);
85 Statusbar::ScopedLock::ScopedLock() noexcept
88 if (Config
.statusbar_visibility
)
89 statusbar_block_update
= true;
91 progressbar_block_update
= true;
92 statusbar_allow_unlock
= false;
95 Statusbar::ScopedLock::~ScopedLock() noexcept
98 statusbar_allow_unlock
= true;
99 if (statusbar_lock_delay
.is_negative())
101 if (Config
.statusbar_visibility
)
102 statusbar_block_update
= false;
104 progressbar_block_update
= false;
106 if (Status::State::player() == MPD::psStop
)
108 switch (Config
.design
)
110 case Design::Classic
:
111 put(); // clear statusbar
113 case Design::Alternative
:
114 Progressbar::draw(Status::State::elapsedTime(), Status::State::totalTime());
121 bool Statusbar::isUnlocked()
123 return !statusbar_block_update
;
126 void Statusbar::tryRedraw()
129 if (statusbar_lock_delay
> boost::posix_time::seconds(0)
130 && Timer
- statusbar_lock_time
> statusbar_lock_delay
)
132 statusbar_lock_delay
= boost::posix_time::seconds(-1);
134 if (Config
.statusbar_visibility
)
135 statusbar_block_update
= !statusbar_allow_unlock
;
137 progressbar_block_update
= !statusbar_allow_unlock
;
139 if (!statusbar_block_update
&& !progressbar_block_update
)
141 switch (Config
.design
)
143 case Design::Classic
:
144 switch (Status::State::player())
148 put(); // clear statusbar
152 Status::Changes::elapsedTime(false);
156 case Design::Alternative
:
157 Progressbar::draw(Status::State::elapsedTime(), Status::State::totalTime());
165 NC::Window
&Statusbar::put()
167 *wFooter
<< NC::XY(0, Config
.statusbar_visibility
? 1 : 0) << NC::TermManip::ClearToEOL
;
171 void Statusbar::print(int delay
, const std::string
&message
)
173 if (statusbar_allow_unlock
)
175 statusbar_lock_time
= Global::Timer
;
176 statusbar_lock_delay
= boost::posix_time::seconds(delay
);
177 if (Config
.statusbar_visibility
)
178 statusbar_block_update
= true;
180 progressbar_block_update
= true;
181 wFooter
->goToXY(0, Config
.statusbar_visibility
);
182 *wFooter
<< message
<< NC::TermManip::ClearToEOL
;
187 void Statusbar::Helpers::mpd()
189 Status::update(Mpd
.noidle());
192 bool Statusbar::Helpers::mainHook(const char *)
198 char Statusbar::Helpers::promptReturnOneOf(const std::vector
<char> &values
)
201 throw std::logic_error("empty vector of acceptable input");
202 NC::Key::Type result
;
206 result
= wFooter
->readKey();
207 if (result
== NC::Key::Ctrl_C
|| result
== NC::Key::Ctrl_G
)
208 throw NC::PromptAborted();
210 while (std::find(values
.begin(), values
.end(), result
) == values
.end());
214 bool Statusbar::Helpers::ImmediatelyReturnOneOf::operator()(const char *s
) const
220 bool Statusbar::Helpers::ApplyFilterImmediately::operator()(const char *s
)
222 using Global::myScreen
;
225 if (m_w
->allowsFiltering() && m_w
->currentFilter() != s
)
228 if (myScreen
== myPlaylist
)
229 myPlaylist
->enableHighlighting();
230 myScreen
->refreshWindow();
232 } catch (boost::bad_expression
&) { }
236 bool Statusbar::Helpers::FindImmediately::operator()(const char *s
)
238 using Global::myScreen
;
241 if (m_w
->allowsSearching() && m_w
->searchConstraint() != s
)
243 m_w
->setSearchConstraint(s
);
244 m_w
->search(m_direction
, Config
.wrapped_search
, false);
245 if (myScreen
== myPlaylist
)
246 myPlaylist
->enableHighlighting();
247 myScreen
->refreshWindow();
249 } catch (boost::bad_expression
&) { }
253 bool Statusbar::Helpers::TryExecuteImmediateCommand::operator()(const char *s
)
255 bool continue_
= true;
259 auto cmd
= Bindings
.findCommand(m_s
);
260 if (cmd
&& cmd
->immediate())