1 /***************************************************************************
2 * Copyright (C) 2008-2014 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 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 if (Config
.progressbar_boldness
)
63 *wFooter
<< NC::Format::Bold
;
64 *wFooter
<< Config
.progressbar_color
;
65 if (Config
.progressbar
[2] != '\0')
67 wFooter
->goToXY(0, 0);
68 for (unsigned i
= 0; i
< pb_width
; ++i
)
69 *wFooter
<< Config
.progressbar
[2];
70 wFooter
->goToXY(0, 0);
73 mvwhline(wFooter
->raw(), 0, 0, 0, pb_width
);
76 *wFooter
<< Config
.progressbar_elapsed_color
;
77 pb_width
= std::min(size_t(howlong
), wFooter
->getWidth());
78 for (unsigned i
= 0; i
< pb_width
; ++i
)
79 *wFooter
<< Config
.progressbar
[0];
80 if (howlong
< wFooter
->getWidth())
81 *wFooter
<< Config
.progressbar
[1];
82 *wFooter
<< NC::Color::End
;
84 *wFooter
<< NC::Color::End
;
85 if (Config
.progressbar_boldness
)
86 *wFooter
<< NC::Format::NoBold
;
89 Statusbar::ScopedLock::ScopedLock() noexcept
92 if (Config
.statusbar_visibility
)
93 statusbar_block_update
= true;
95 progressbar_block_update
= true;
96 statusbar_allow_unlock
= false;
99 Statusbar::ScopedLock::~ScopedLock() noexcept
102 statusbar_allow_unlock
= true;
103 if (statusbar_lock_delay
.is_negative())
105 if (Config
.statusbar_visibility
)
106 statusbar_block_update
= false;
108 progressbar_block_update
= false;
110 if (Status::State::player() == MPD::psStop
)
112 switch (Config
.design
)
114 case Design::Classic
:
115 put(); // clear statusbar
117 case Design::Alternative
:
118 Progressbar::draw(Status::State::elapsedTime(), Status::State::totalTime());
125 bool Statusbar::isUnlocked()
127 return !statusbar_block_update
;
130 void Statusbar::tryRedraw()
133 if (statusbar_lock_delay
> boost::posix_time::seconds(0)
134 && Timer
- statusbar_lock_time
> statusbar_lock_delay
)
136 statusbar_lock_delay
= boost::posix_time::seconds(-1);
138 if (Config
.statusbar_visibility
)
139 statusbar_block_update
= !statusbar_allow_unlock
;
141 progressbar_block_update
= !statusbar_allow_unlock
;
143 if (!statusbar_block_update
&& !progressbar_block_update
)
145 switch (Config
.design
)
147 case Design::Classic
:
148 switch (Status::State::player())
152 put(); // clear statusbar
156 Status::Changes::elapsedTime(false);
160 case Design::Alternative
:
161 Progressbar::draw(Status::State::elapsedTime(), Status::State::totalTime());
169 NC::Window
&Statusbar::put()
171 *wFooter
<< NC::XY(0, Config
.statusbar_visibility
? 1 : 0) << NC::TermManip::ClearToEOL
;
175 void Statusbar::print(int delay
, const std::string
&message
)
177 if (statusbar_allow_unlock
)
179 statusbar_lock_time
= Global::Timer
;
180 statusbar_lock_delay
= boost::posix_time::seconds(delay
);
181 if (Config
.statusbar_visibility
)
182 statusbar_block_update
= true;
184 progressbar_block_update
= true;
185 wFooter
->goToXY(0, Config
.statusbar_visibility
);
186 *wFooter
<< message
<< NC::TermManip::ClearToEOL
;
191 void Statusbar::Helpers::mpd()
193 Status::update(Mpd
.noidle());
196 bool Statusbar::Helpers::mainHook(const char *)
202 std::string
Statusbar::Helpers::promptReturnOneOf(std::vector
<std::string
> values
)
204 Statusbar::Helpers::ImmediatelyReturnOneOf
prompt_hook(std::move(values
));
205 NC::Window::ScopedPromptHook
hook(*wFooter
, prompt_hook
);
206 int x
= wFooter
->getX(), y
= wFooter
->getY();
210 wFooter
->goToXY(x
, y
);
211 result
= wFooter
->prompt();
213 while (!prompt_hook
.isOneOf(result
));
217 bool Statusbar::Helpers::ImmediatelyReturnOneOf::operator()(const char *s
) const
223 bool Statusbar::Helpers::ApplyFilterImmediately::operator()(const char *s
)
225 using Global::myScreen
;
228 if (m_w
->allowsFiltering() && m_w
->currentFilter() != s
)
231 if (myScreen
== myPlaylist
)
232 myPlaylist
->enableHighlighting();
233 myScreen
->refreshWindow();
235 } catch (boost::bad_expression
&) { }
239 bool Statusbar::Helpers::FindImmediately::operator()(const char *s
)
241 using Global::myScreen
;
244 if (m_w
->allowsSearching() && m_w
->searchConstraint() != s
)
246 m_w
->setSearchConstraint(s
);
247 m_w
->search(m_direction
, Config
.wrapped_search
, false);
248 if (myScreen
== myPlaylist
)
249 myPlaylist
->enableHighlighting();
250 myScreen
->refreshWindow();
252 } catch (boost::bad_expression
&) { }
256 bool Statusbar::Helpers::TryExecuteImmediateCommand::operator()(const char *s
)
258 bool continue_
= true;
262 auto cmd
= Bindings
.findCommand(m_s
);
263 if (cmd
&& cmd
->immediate())