diff options
-rw-r--r-- | src/actions.cpp | 42 | ||||
-rw-r--r-- | src/ncmpcpp.cpp | 2 | ||||
-rw-r--r-- | src/search_engine.cpp | 2 | ||||
-rw-r--r-- | src/sel_items_adder.cpp | 2 | ||||
-rw-r--r-- | src/status.cpp | 4 | ||||
-rw-r--r-- | src/tag_editor.cpp | 8 | ||||
-rw-r--r-- | src/tiny_tag_editor.cpp | 4 | ||||
-rw-r--r-- | src/window.cpp | 33 | ||||
-rw-r--r-- | src/window.h | 70 |
9 files changed, 72 insertions, 95 deletions
diff --git a/src/actions.cpp b/src/actions.cpp index 351c4b7a..e2e6a322 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -779,7 +779,7 @@ void SavePlaylist::run() { Statusbar::ScopedLock lock; Statusbar::put() << "Save playlist as: "; - playlist_name = wFooter->getString(); + playlist_name = wFooter->prompt(); } if (playlist_name.find("/") != std::string::npos) { @@ -842,11 +842,11 @@ void ExecuteCommand::run() std::string cmd_name; { Statusbar::ScopedLock lock; - NC::Window::ScopedStringHelper helper(*wFooter, + NC::Window::ScopedPromptHook helper(*wFooter, Statusbar::Helpers::TryExecuteImmediateCommand() ); Statusbar::put() << NC::Format::Bold << ":" << NC::Format::NoBold; - cmd_name = wFooter->getString(); + cmd_name = wFooter->prompt(); } auto cmd = Bindings.findCommand(cmd_name); @@ -968,7 +968,7 @@ void Add::run() { Statusbar::ScopedLock lock; Statusbar::put() << (myScreen == myPlaylistEditor ? "Add to playlist: " : "Add: "); - path = wFooter->getString(); + path = wFooter->prompt(); } Statusbar::put() << "Adding..."; @@ -1275,7 +1275,7 @@ void SetCrossfade::run() Statusbar::ScopedLock lock; Statusbar::put() << "Set crossfade to: "; - auto crossfade = fromString<unsigned>(wFooter->getString()); + auto crossfade = fromString<unsigned>(wFooter->prompt()); lowerBoundCheck(crossfade, 0u); Config.crossfade_time = crossfade; Mpd.SetCrossfade(crossfade); @@ -1289,7 +1289,7 @@ void SetVolume::run() { Statusbar::ScopedLock lock; Statusbar::put() << "Set volume to: "; - volume = fromString<unsigned>(wFooter->getString()); + volume = fromString<unsigned>(wFooter->prompt()); boundsCheck(volume, 0u, 100u); Mpd.SetVolume(volume); } @@ -1335,7 +1335,7 @@ void EditLibraryTag::run() { Statusbar::ScopedLock lock; Statusbar::put() << NC::Format::Bold << tagTypeToString(Config.media_lib_primary_tag) << NC::Format::NoBold << ": "; - new_tag = wFooter->getString(myLibrary->Tags.current().value().tag()); + new_tag = wFooter->prompt(myLibrary->Tags.current().value().tag()); } if (!new_tag.empty() && new_tag != myLibrary->Tags.current().value().tag()) { @@ -1393,7 +1393,7 @@ void EditLibraryAlbum::run() { Statusbar::ScopedLock lock; Statusbar::put() << NC::Format::Bold << "Album: " << NC::Format::NoBold; - new_album = wFooter->getString(myLibrary->Albums.current().value().entry().album()); + new_album = wFooter->prompt(myLibrary->Albums.current().value().entry().album()); } if (!new_album.empty() && new_album != myLibrary->Albums.current().value().entry().album()) { @@ -1452,7 +1452,7 @@ void EditDirectoryName::run() { Statusbar::ScopedLock lock; Statusbar::put() << NC::Format::Bold << "Directory: " << NC::Format::NoBold; - new_dir = wFooter->getString(old_dir); + new_dir = wFooter->prompt(old_dir); } if (!new_dir.empty() && new_dir != old_dir) { @@ -1487,7 +1487,7 @@ void EditDirectoryName::run() { Statusbar::ScopedLock lock; Statusbar::put() << NC::Format::Bold << "Directory: " << NC::Format::NoBold; - new_dir = wFooter->getString(old_dir); + new_dir = wFooter->prompt(old_dir); } if (!new_dir.empty() && new_dir != old_dir) { @@ -1530,7 +1530,7 @@ void EditPlaylistName::run() { Statusbar::ScopedLock lock; Statusbar::put() << NC::Format::Bold << "Playlist: " << NC::Format::NoBold; - new_name = wFooter->getString(old_name); + new_name = wFooter->prompt(old_name); } if (!new_name.empty() && new_name != old_name) { @@ -1604,7 +1604,7 @@ void ToggleScreenLock::run() { Statusbar::ScopedLock lock; Statusbar::put() << "% of the locked screen's width to be reserved (20-80): "; - part = fromString<unsigned>(wFooter->getString(boost::lexical_cast<std::string>(part))); + part = fromString<unsigned>(wFooter->prompt(boost::lexical_cast<std::string>(part))); } boundsCheck(part, 20u, 80u); Config.locked_screen_width_part = part/100.0; @@ -1648,7 +1648,7 @@ void JumpToPositionInSong::run() { Statusbar::ScopedLock lock; Statusbar::put() << "Position to go (in %/m:ss/seconds(s)): "; - spos = wFooter->getString(); + spos = wFooter->prompt(); } boost::regex rx; @@ -1883,11 +1883,11 @@ void ApplyFilter::run() try { Statusbar::ScopedLock lock; - NC::Window::ScopedStringHelper helper(*wFooter, + NC::Window::ScopedPromptHook helper(*wFooter, Statusbar::Helpers::ApplyFilterImmediately(f, filter) ); Statusbar::put() << NC::Format::Bold << "Apply filter: " << NC::Format::NoBold; - wFooter->getString(filter); + wFooter->prompt(filter); } catch (NC::PromptAborted &) { @@ -1935,7 +1935,7 @@ void Find::run() { Statusbar::ScopedLock lock; Statusbar::put() << "Find: "; - token = wFooter->getString(); + token = wFooter->prompt(); } Statusbar::print("Searching..."); @@ -2110,7 +2110,7 @@ void AddRandomItems::run() { Statusbar::ScopedLock lock; Statusbar::put() << "Number of random " << tag_type_str << "s: "; - number = fromString<unsigned>(wFooter->getString()); + number = fromString<unsigned>(wFooter->prompt()); } if (number && (rnd_type == 's' ? Mpd.AddRandomSongs(number) : Mpd.AddRandomTag(tag_type, number))) { @@ -2247,7 +2247,7 @@ void SetSelectedItemsPriority::run() { Statusbar::ScopedLock lock; Statusbar::put() << "Set priority [0-255]: "; - prio = fromString<unsigned>(wFooter->getString()); + prio = fromString<unsigned>(wFooter->prompt()); boundsCheck(prio, 0u, 255u); } myPlaylist->SetSelectedItemsPriority(prio); @@ -2271,7 +2271,7 @@ void SetVisualizerSampleMultiplier::run() { Statusbar::ScopedLock lock; Statusbar::put() << "Set visualizer sample multiplier: "; - multiplier = fromString<double>(wFooter->getString()); + multiplier = fromString<double>(wFooter->prompt()); lowerBoundCheck(multiplier, 0.0); Config.visualizer_sample_multiplier = multiplier; } @@ -2292,7 +2292,7 @@ void FilterPlaylistOnPriorities::run() { Statusbar::ScopedLock lock; Statusbar::put() << "Show songs with priority higher than: "; - prio = fromString<unsigned>(wFooter->getString()); + prio = fromString<unsigned>(wFooter->prompt()); boundsCheck(prio, 0u, 255u); myPlaylist->main().filter(myPlaylist->main().begin(), myPlaylist->main().end(), [prio](const NC::Menu<MPD::Song>::Item &s) { @@ -2844,7 +2844,7 @@ void findItem(const Find direction) { Statusbar::ScopedLock lock; Statusbar::put() << "Find " << (direction == Find::Forward ? "forward" : "backward") << ": "; - token = wFooter->getString(); + token = wFooter->prompt(); } Statusbar::print("Searching..."); diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 1dfcea46..21ba4c3c 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -123,7 +123,7 @@ int main(int argc, char **argv) wHeader->display(); wFooter = new NC::Window(0, Actions::FooterStartY, COLS, Actions::FooterHeight, "", Config.statusbar_color, NC::Border::None); - wFooter->setGetStringHelper(Statusbar::Helpers::getString); + wFooter->setPromptHook(Statusbar::Helpers::getString); // initialize global timer Timer = boost::posix_time::microsec_clock::local_time(); diff --git a/src/search_engine.cpp b/src/search_engine.cpp index eb81e941..6c5b817b 100644 --- a/src/search_engine.cpp +++ b/src/search_engine.cpp @@ -158,7 +158,7 @@ void SearchEngine::enterPressed() Statusbar::ScopedLock lock; std::string constraint = ConstraintsNames[option]; Statusbar::put() << NC::Format::Bold << constraint << NC::Format::NoBold << ": "; - itsConstraints[option] = Global::wFooter->getString(itsConstraints[option]); + itsConstraints[option] = Global::wFooter->prompt(itsConstraints[option]); w.current().value().buffer().clear(); constraint.resize(13, ' '); w.current().value().buffer() << NC::Format::Bold << constraint << NC::Format::NoBold << ": "; diff --git a/src/sel_items_adder.cpp b/src/sel_items_adder.cpp index 8b143e69..db6d17df 100644 --- a/src/sel_items_adder.cpp +++ b/src/sel_items_adder.cpp @@ -227,7 +227,7 @@ void SelectedItemsAdder::addToNewPlaylist() const { Statusbar::ScopedLock lock; Statusbar::put() << "Save playlist as: "; - playlist = Global::wFooter->getString(); + playlist = Global::wFooter->prompt(); } addToExistingPlaylist(playlist); } diff --git a/src/status.cpp b/src/status.cpp index bb2e2656..b57f25f0 100644 --- a/src/status.cpp +++ b/src/status.cpp @@ -167,9 +167,9 @@ void Status::handleServerError(MPD::ServerError &e) Statusbar::printf("MPD: %1%", e.what()); if (e.code() == MPD_SERVER_ERROR_PERMISSION) { - NC::Window::ScopedStringHelper helper(*wFooter, nullptr); + NC::Window::ScopedPromptHook helper(*wFooter, nullptr); Statusbar::put() << "Password: "; - Mpd.SetPassword(wFooter->getString(0, true)); + Mpd.SetPassword(wFooter->prompt("", -1, true)); try { Mpd.SendPassword(); Statusbar::print("Password accepted"); diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp index 1a5a424b..79e0453a 100644 --- a/src/tag_editor.cpp +++ b/src/tag_editor.cpp @@ -360,7 +360,7 @@ void TagEditor::enterPressed() { Statusbar::ScopedLock lock; Statusbar::put() << "Pattern: "; - new_pattern = wFooter->getString(Config.pattern); + new_pattern = wFooter->prompt(Config.pattern); } Config.pattern = new_pattern; FParser->at(0).value() = "Pattern: "; @@ -494,7 +494,7 @@ void TagEditor::enterPressed() { Statusbar::ScopedLock lock; Statusbar::put() << NC::Format::Bold << TagTypes->current().value() << NC::Format::NoBold << ": "; - std::string new_tag = wFooter->getString(Tags->current().value().getTags(get, Config.tags_separator)); + std::string new_tag = wFooter->prompt(Tags->current().value().getTags(get, Config.tags_separator)); for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it) (*it)->setTags(set, new_tag, Config.tags_separator); } @@ -502,7 +502,7 @@ void TagEditor::enterPressed() { Statusbar::ScopedLock lock; Statusbar::put() << NC::Format::Bold << TagTypes->current().value() << NC::Format::NoBold << ": "; - std::string new_tag = wFooter->getString(Tags->current().value().getTags(get, Config.tags_separator)); + std::string new_tag = wFooter->prompt(Tags->current().value().getTags(get, Config.tags_separator)); if (new_tag != Tags->current().value().getTags(get, Config.tags_separator)) Tags->current().value().setTags(set, new_tag, Config.tags_separator); Tags->scroll(NC::Scroll::Down); @@ -526,7 +526,7 @@ void TagEditor::enterPressed() std::string extension = old_name.substr(last_dot); old_name = old_name.substr(0, last_dot); Statusbar::put() << NC::Format::Bold << "New filename: " << NC::Format::NoBold; - std::string new_name = wFooter->getString(old_name); + std::string new_name = wFooter->prompt(old_name); if (!new_name.empty()) s.setNewName(new_name + extension); Tags->scroll(NC::Scroll::Down); diff --git a/src/tiny_tag_editor.cpp b/src/tiny_tag_editor.cpp index 34cc23de..12281a26 100644 --- a/src/tiny_tag_editor.cpp +++ b/src/tiny_tag_editor.cpp @@ -106,7 +106,7 @@ void TinyTagEditor::enterPressed() Statusbar::ScopedLock lock; size_t pos = option-8; Statusbar::put() << NC::Format::Bold << SongInfo::Tags[pos].Name << ": " << NC::Format::NoBold; - itsEdited.setTags(SongInfo::Tags[pos].Set, Global::wFooter->getString( + itsEdited.setTags(SongInfo::Tags[pos].Set, Global::wFooter->prompt( itsEdited.getTags(SongInfo::Tags[pos].Get, Config.tags_separator)), Config.tags_separator); w.at(option).value().clear(); w.at(option).value() << NC::Format::Bold << SongInfo::Tags[pos].Name << ':' << NC::Format::NoBold << ' '; @@ -120,7 +120,7 @@ void TinyTagEditor::enterPressed() size_t dot = filename.rfind("."); std::string extension = filename.substr(dot); filename = filename.substr(0, dot); - std::string new_name = Global::wFooter->getString(filename); + std::string new_name = Global::wFooter->prompt(filename); if (!new_name.empty()) { itsEdited.setNewName(new_name + extension); diff --git a/src/window.cpp b/src/window.cpp index 9edc377d..511bdcd5 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -57,7 +57,7 @@ int read_key(FILE *) do { x = w->getX(); - if (w->runGetStringHelper(rl_line_buffer, &done)) + if (w->runPromptHook(rl_line_buffer, &done)) { if (done) { @@ -431,7 +431,7 @@ Window::Window(size_t startx, m_base_color(color), m_base_bg_color(Color::Default), m_border(border), - m_get_string_helper(0), + m_prompt_hook(0), m_title(title), m_bold_counter(0), m_underline_counter(0), @@ -479,7 +479,7 @@ Window::Window(const Window &rhs) , m_base_color(rhs.m_base_color) , m_base_bg_color(rhs.m_base_bg_color) , m_border(rhs.m_border) -, m_get_string_helper(rhs.m_get_string_helper) +, m_prompt_hook(rhs.m_prompt_hook) , m_title(rhs.m_title) , m_color_stack(rhs.m_color_stack) , m_input_queue(rhs.m_input_queue) @@ -504,7 +504,7 @@ Window::Window(Window &&rhs) , m_base_color(rhs.m_base_color) , m_base_bg_color(rhs.m_base_bg_color) , m_border(rhs.m_border) -, m_get_string_helper(rhs.m_get_string_helper) +, m_prompt_hook(rhs.m_prompt_hook) , m_title(std::move(rhs.m_title)) , m_color_stack(std::move(rhs.m_color_stack)) , m_input_queue(std::move(rhs.m_input_queue)) @@ -532,7 +532,7 @@ Window &Window::operator=(Window rhs) std::swap(m_base_color, rhs.m_base_color); std::swap(m_base_bg_color, rhs.m_base_bg_color); std::swap(m_border, rhs.m_border); - std::swap(m_get_string_helper, rhs.m_get_string_helper); + std::swap(m_prompt_hook, rhs.m_prompt_hook); std::swap(m_title, rhs.m_title); std::swap(m_color_stack, rhs.m_color_stack); std::swap(m_input_queue, rhs.m_input_queue); @@ -665,13 +665,10 @@ void Window::resize(size_t new_width, size_t new_height) recreate(m_width, m_height); } -void Window::showBorder() const +void Window::refreshBorder() const { if (m_border != Border::None) - { - ::refresh(); prefresh(m_border_window, 0, 0, getStarty(), getStartX(), m_start_y+m_height, m_start_x+m_width); - } if (!m_title.empty()) { if (m_border != Border::None) @@ -689,7 +686,7 @@ void Window::showBorder() const void Window::display() { - showBorder(); + refreshBorder(); refresh(); } @@ -806,21 +803,15 @@ void Window::pushChar(int ch) m_input_queue.push(ch); } -std::string Window::getString(const std::string &base, size_t width, bool encrypted) +std::string Window::prompt(const std::string &base, size_t width, bool encrypted) { rl::aborted = false; rl::w = this; getyx(m_window, rl::start_y, rl::start_x); - rl::width = width; + rl::width = std::min(m_width-rl::start_x-1, width-1); rl::encrypted = encrypted; rl::base = base.c_str(); - width--; - if (width == size_t(-1)) - rl::width = m_width-rl::start_x-1; - else - rl::width = width; - mmask_t oldmask; std::string result; @@ -878,11 +869,11 @@ bool Window::hasCoords(int &x, int &y) # endif } -bool Window::runGetStringHelper(const char *arg, bool *done) const +bool Window::runPromptHook(const char *arg, bool *done) const { - if (m_get_string_helper) + if (m_prompt_hook) { - bool continue_ = m_get_string_helper(arg); + bool continue_ = m_prompt_hook(arg); if (done != nullptr) *done = !continue_; return true; diff --git a/src/window.h b/src/window.h index 8d61e47e..ba40e09c 100644 --- a/src/window.h +++ b/src/window.h @@ -109,10 +109,10 @@ #endif /// NC namespace provides set of easy-to-use -/// wrappers over original curses library -namespace NC {// +/// wrappers over original curses library. +namespace NC { -/// Thrown if Ctrl-G is pressed during the call to Window::getString(). +/// Thrown if Ctrl-C or Ctrl-G is pressed during the call to Window::getString() /// @see Window::getString() struct PromptAborted : std::exception { @@ -154,11 +154,6 @@ enum class Scroll { Up, Down, PageUp, PageDown, Home, End }; std::ostream &operator<<(std::ostream &os, Scroll s); -/// Helper function that is invoked each time one will want -/// to obtain string from Window::getString() function -/// @see Window::getString() -typedef std::function<bool(const char *)> GetStringHelper; - /// Initializes curses screen and sets some additional attributes /// @param window_title title of the window (has an effect only if pdcurses lib is used) /// @param enable_colors enables colors @@ -188,21 +183,26 @@ struct XY /// Main class of NCurses namespace, used as base for other specialized windows struct Window { + /// Helper function that is periodically invoked + // inside Window::getString() function + /// @see Window::getString() + typedef std::function<bool(const char *)> PromptHook; + /// Sets helper to a specific value for the current scope - struct ScopedStringHelper + struct ScopedPromptHook { template <typename HelperT> - ScopedStringHelper(Window &w, HelperT &&helper) noexcept - : m_w(w), m_helper(std::move(w.m_get_string_helper)) { - m_w.m_get_string_helper = std::forward<HelperT>(helper); + ScopedPromptHook(Window &w, HelperT &&helper) noexcept + : m_w(w), m_hook(std::move(w.m_prompt_hook)) { + m_w.m_prompt_hook = std::forward<HelperT>(helper); } - ~ScopedStringHelper() noexcept { - m_w.m_get_string_helper = std::move(m_helper); + ~ScopedPromptHook() noexcept { + m_w.m_prompt_hook = std::move(m_hook); } private: Window &m_w; - GetStringHelper m_helper; + PromptHook m_hook; }; Window() : m_window(0), m_border_window(0) { } @@ -253,14 +253,9 @@ struct Window /// @return current window's timeout int getTimeout() const; - /// Reads the string from standard input. Note that this is much more complex - /// function than getstr() from curses library. It allows for moving through - /// letters with arrows, supports scrolling if string's length is bigger than - /// given area, supports history of previous strings and each time it receives - /// an input from the keyboard or the timeout is reached, it calls helper function - /// (if it's set) that takes as an argument currently edited string. + /// Reads the string from standard input using readline library. /// @param base base string that has to be edited - /// @param length max length of string, unlimited by default + /// @param length max length of the string, unlimited by default /// @param width width of area that entry field can take. if it's reached, string /// will be scrolled. if value is 0, field will be from cursor position to the end /// of current line wide. @@ -268,17 +263,9 @@ struct Window /// actual text. /// @return edited string /// - /// @see setGetStringHelper() + /// @see setPromptHook() /// @see SetTimeout() - /// @see CreateHistory() - std::string getString(const std::string &base, size_t width = 0, bool encrypted = false); - - /// Wrapper for above function that doesn't take base string (it will be empty). - /// Taken parameters are the same as for above. - std::string getString(size_t width = 0, bool encrypted = false) - { - return getString("", width, encrypted); - } + std::string prompt(const std::string &base = "", size_t width = -1, bool encrypted = false); /// Moves cursor to given coordinates /// @param x given X position @@ -299,19 +286,18 @@ struct Window /// @return true if it transformed variables, false otherwise bool hasCoords(int &x, int &y); - /// Sets helper function used in getString() - /// @param helper pointer to function that matches getStringHelper prototype + /// Sets hook used in getString() + /// @param hook pointer to function that matches getStringHelper prototype /// @see getString() - template <typename HelperT> - void setGetStringHelper(HelperT &&helper) - { - m_get_string_helper = std::forward<HelperT>(helper); + template <typename HookT> + void setPromptHook(HookT &&hook) { + m_prompt_hook = std::forward<HookT>(hook); } /// Run current GetString helper function (if defined). /// @see getString() /// @return true if helper was run, false otherwise - bool runGetStringHelper(const char *arg, bool *done) const; + bool runPromptHook(const char *arg, bool *done) const; /// Sets window's base color /// @param fg foregound base color @@ -352,7 +338,7 @@ struct Window virtual void clear(); /// Adds given file descriptor to the list that will be polled in - /// ReadKey() along with stdin and callback that will be invoked + /// readKey() along with stdin and callback that will be invoked /// when there is data waiting for reading in it /// @param fd file descriptor /// @param callback callback @@ -466,7 +452,7 @@ protected: /// Refreshes window's border /// - void showBorder() const; + void refreshBorder() const; /// Changes dimensions of window, called from resize() /// @param width new window's width @@ -533,7 +519,7 @@ private: /// pointer to helper function used by getString() /// @see getString() /// - GetStringHelper m_get_string_helper; + PromptHook m_prompt_hook; /// window title std::string m_title; |