implement input character queue and add PushCharacters macro utility

This commit is contained in:
Andrzej Rybczak
2012-08-25 06:50:27 +02:00
parent 55ae5b1816
commit f6cae753e2
9 changed files with 94 additions and 45 deletions

View File

@@ -14,6 +14,7 @@ INCLUDES= $(all_includes)
ncmpcpp_LDFLAGS = $(all_libraries) ncmpcpp_LDFLAGS = $(all_libraries)
noinst_HEADERS = browser.h charset.h clock.h conv.h curl_handle.h display.h \ noinst_HEADERS = browser.h charset.h clock.h conv.h curl_handle.h display.h \
error.h global.h help.h helpers.h lastfm.h lastfm_service.h lyrics.h \ error.h global.h help.h helpers.h lastfm.h lastfm_service.h lyrics.h \
lyrics_fetcher.h media_library.h menu.h mpdpp.h outputs.h playlist_editor.h screen.h \ lyrics_fetcher.h macro_utilities.h media_library.h menu.h mpdpp.h outputs.h \
scrollpad.h search_engine.h sel_items_adder.h server_info.h settings.h song.h \ playlist_editor.h screen.h scrollpad.h search_engine.h sel_items_adder.h server_info.h \
song_info.h tag_editor.h tiny_tag_editor.h tolower.h visualizer.h window.h settings.h song.h song_info.h tag_editor.h tiny_tag_editor.h tolower.h \
visualizer.h window.h

View File

@@ -66,7 +66,7 @@ Action::Key Action::ReadKey(Window &w)
int input; int input;
while (true) while (true)
{ {
w.ReadKey(input); input = w.ReadKey();
if (input == ERR) if (input == ERR)
return NoOp; return NoOp;
if (input > 255) if (input > 255)
@@ -407,7 +407,7 @@ bool Action::AskYesNoQuestion(const std::string &question, void (*callback)())
{ {
if (callback) if (callback)
callback(); callback();
wFooter->ReadKey(answer); answer = wFooter->ReadKey();
} }
while (answer != 'y' && answer != 'n'); while (answer != 'y' && answer != 'n');
UnlockStatusbar(); UnlockStatusbar();
@@ -2103,7 +2103,7 @@ void ToggleReplayGainMode::Run()
do do
{ {
TraceMpdStatus(); TraceMpdStatus();
wFooter->ReadKey(answer); answer = wFooter->ReadKey();
} }
while (answer != 'o' && answer != 't' && answer != 'a'); while (answer != 'o' && answer != 't' && answer != 'a');
UnlockStatusbar(); UnlockStatusbar();
@@ -2147,7 +2147,7 @@ void AddRandomItems::Run()
do do
{ {
TraceMpdStatus(); TraceMpdStatus();
wFooter->ReadKey(answer); answer = wFooter->ReadKey();
} }
while (answer != 's' && answer != 'a' && answer != 'b'); while (answer != 's' && answer != 'a' && answer != 'b');
UnlockStatusbar(); UnlockStatusbar();
@@ -2210,7 +2210,7 @@ void ToggleLibraryTagType::Run()
do do
{ {
TraceMpdStatus(); TraceMpdStatus();
wFooter->ReadKey(answer); answer = wFooter->ReadKey();
} }
while (answer != 'a' && answer != 'A' && answer != 'y' && answer != 'g' && answer != 'c' && answer != 'p'); while (answer != 'a' && answer != 'A' && answer != 'y' && answer != 'g' && answer != 'c' && answer != 'p');
UnlockStatusbar(); UnlockStatusbar();

View File

@@ -27,6 +27,7 @@
enum ActionType enum ActionType
{ {
aMacroUtility,
aMouseEvent, aScrollUp, aScrollDown, aScrollUpArtist, aScrollUpAlbum, aScrollDownArtist, aMouseEvent, aScrollUp, aScrollDown, aScrollUpArtist, aScrollUpAlbum, aScrollDownArtist,
aScrollDownAlbum, aPageUp, aPageDown, aMoveHome, aMoveEnd, aToggleInterface, aJumpToParentDir, aScrollDownAlbum, aPageUp, aPageDown, aMoveHome, aMoveEnd, aToggleInterface, aJumpToParentDir,
aPressEnter, aPressSpace, aPreviousColumn, aNextColumn, aMasterScreen, aSlaveScreen, aVolumeUp, aPressEnter, aPressSpace, aPreviousColumn, aNextColumn, aMasterScreen, aSlaveScreen, aVolumeUp,

51
src/macro_utilities.h Normal file
View File

@@ -0,0 +1,51 @@
/***************************************************************************
* Copyright (C) 2008-2012 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "actions.h"
struct PushCharacters : public Action
{
template <typename Iterator> PushCharacters(Window **w, Iterator first, Iterator last) : Action(aMacroUtility, "")
{
construct(w, first, last);
}
PushCharacters(Window **w, const std::initializer_list<int> &v) : Action(aMacroUtility, "")
{
construct(w, v.begin(), v.end());
}
virtual void Run()
{
for (auto it = itsQueue.begin(); it != itsQueue.end(); ++it)
(*itsWindow)->PushChar(*it);
}
private:
template <typename Iterator> void construct(Window **w, Iterator first, Iterator last)
{
itsWindow = w;
for (; first != last; ++first)
itsQueue.push_back(*first);
}
Window **itsWindow;
std::vector<int> itsQueue;
};

View File

@@ -205,12 +205,6 @@ void Playlist::SpacePressed()
} }
} }
void Playlist::ReadKey(int &key)
{
w->ReadKey(key);
UpdateTimer();
}
void Playlist::MouseButtonPressed(MEVENT me) void Playlist::MouseButtonPressed(MEVENT me)
{ {
if (w == Items && !Items->Empty() && Items->hasCoords(me.x, me.y)) if (w == Items && !Items->Empty() && Items->hasCoords(me.x, me.y))

View File

@@ -42,7 +42,6 @@ class Playlist : public Screen<Window>
virtual void EnterPressed(); virtual void EnterPressed();
virtual void SpacePressed(); virtual void SpacePressed();
virtual void ReadKey(int &);
virtual void MouseButtonPressed(MEVENT); virtual void MouseButtonPressed(MEVENT);
virtual bool isTabbable() { return true; } virtual bool isTabbable() { return true; }

View File

@@ -75,10 +75,6 @@ class BasicScreen
/// ///
virtual void RefreshWindow() = 0; virtual void RefreshWindow() = 0;
/// see Screen::ReadKey()
///
virtual void ReadKey(int &key) = 0;
/// @see Screen::Scroll() /// @see Screen::Scroll()
/// ///
virtual void Scroll(Where where) = 0; virtual void Scroll(Where where) = 0;
@@ -204,10 +200,7 @@ template <typename WindowType> class Screen : public BasicScreen
/// ///
virtual void RefreshWindow(); virtual void RefreshWindow();
/// Reads a key from the screen
///
virtual void ReadKey(int &key);
/// Scrolls the screen by given amount of lines and /// Scrolls the screen by given amount of lines and
/// if fancy scrolling feature is disabled, enters the /// if fancy scrolling feature is disabled, enters the
/// loop that holds main loop until user releases the key /// loop that holds main loop until user releases the key
@@ -250,11 +243,6 @@ template <typename WindowType> void Screen<WindowType>::RefreshWindow()
w->Display(); w->Display();
} }
template <typename WindowType> void Screen<WindowType>::ReadKey(int &key)
{
w->ReadKey(key);
}
template <typename WindowType> void Screen<WindowType>::Scroll(Where where) template <typename WindowType> void Screen<WindowType>::Scroll(Where where)
{ {
w->Scroll(where); w->Scroll(where);

View File

@@ -371,8 +371,17 @@ bool Window::FDCallbacksListEmpty() const
return itsFDs.empty(); return itsFDs.empty();
} }
void Window::ReadKey(int &read_key) const int Window::ReadKey()
{ {
int result;
// if there are characters in input queue, get them and
// return immediately.
if (!itsInputQueue.empty())
{
result = itsInputQueue.front();
itsInputQueue.pop();
return result;
}
// in pdcurses polling stdin doesn't work, so we can't poll // in pdcurses polling stdin doesn't work, so we can't poll
// both stdin and other file descriptors in one select. the // both stdin and other file descriptors in one select. the
// workaround is to set the timeout of select to 0, poll // workaround is to set the timeout of select to 0, poll
@@ -401,7 +410,7 @@ void Window::ReadKey(int &read_key) const
if (select(fd_max+1, &fdset, 0, 0, itsWindowTimeout < 0 ? 0 : &timeout) > 0) if (select(fd_max+1, &fdset, 0, 0, itsWindowTimeout < 0 ? 0 : &timeout) > 0)
{ {
# if !defined(USE_PDCURSES) # if !defined(USE_PDCURSES)
read_key = FD_ISSET(STDIN_FILENO, &fdset) ? wgetch(itsWindow) : ERR; result = FD_ISSET(STDIN_FILENO, &fdset) ? wgetch(itsWindow) : ERR;
# endif // !USE_PDCURSES # endif // !USE_PDCURSES
for (FDCallbacks::const_iterator it = itsFDs.begin(); it != itsFDs.end(); ++it) for (FDCallbacks::const_iterator it = itsFDs.begin(); it != itsFDs.end(); ++it)
if (FD_ISSET(it->first, &fdset)) if (FD_ISSET(it->first, &fdset))
@@ -409,18 +418,19 @@ void Window::ReadKey(int &read_key) const
} }
# if !defined(USE_PDCURSES) # if !defined(USE_PDCURSES)
else else
read_key = ERR; result = ERR;
# else # else
read_key = wgetch(itsWindow); result = wgetch(itsWindow);
# endif # endif
return result;
} }
void Window::ReadKey() const void Window::PushChar(int ch)
{ {
wgetch(itsWindow); itsInputQueue.push(ch);
} }
std::string Window::GetString(const std::string &base, size_t length, size_t width, bool encrypted) const std::string Window::GetString(const std::string &base, size_t length, size_t width, bool encrypted)
{ {
int input; int input;
size_t beginning, maxbeginning, minx, x, real_x, y, maxx, real_maxx; size_t beginning, maxbeginning, minx, x, real_x, y, maxx, real_maxx;
@@ -495,7 +505,7 @@ std::string Window::GetString(const std::string &base, size_t length, size_t wid
wmove(itsWindow, y, x); wmove(itsWindow, y, x);
prefresh(itsWindow, 0, 0, itsStartY, itsStartX, itsStartY+itsHeight-1, itsStartX+itsWidth-1); prefresh(itsWindow, 0, 0, itsStartY, itsStartX, itsStartY+itsHeight-1, itsStartX+itsWidth-1);
ReadKey(input); input = ReadKey();
switch (input) switch (input)
{ {

View File

@@ -36,6 +36,7 @@
#include <stack> #include <stack>
#include <vector> #include <vector>
#include <string> #include <string>
#include <queue>
// define some Ctrl-? keys // define some Ctrl-? keys
#define KEY_CTRL_A 1 #define KEY_CTRL_A 1
@@ -275,12 +276,12 @@ namespace NCurses
/// @see CreateHistory() /// @see CreateHistory()
/// ///
std::string GetString(const std::string &base, size_t length = -1, std::string GetString(const std::string &base, size_t length = -1,
size_t width = 0, bool encrypted = 0) const; size_t width = 0, bool encrypted = 0);
/// Wrapper for above function that doesn't take base string (it will be empty). /// Wrapper for above function that doesn't take base string (it will be empty).
/// Taken parameters are the same as for above. /// Taken parameters are the same as for above.
/// ///
std::string GetString(size_t length = -1, size_t width = 0, bool encrypted = 0) const std::string GetString(size_t length = -1, size_t width = 0, bool encrypted = 0)
{ {
return GetString("", length, width, encrypted); return GetString("", length, width, encrypted);
} }
@@ -407,14 +408,13 @@ namespace NCurses
/// ///
bool FDCallbacksListEmpty() const; bool FDCallbacksListEmpty() const;
/// Reads key from standard input and writes it into read_key variable /// Reads key from standard input (or takes it from input queue)
/// @param read_key variable for read key to be written into it /// and writes it into read_key variable
/// ///
void ReadKey(int &read_key) const; int ReadKey();
/// Waits until user press a key. /// Push single character into input queue, so it can get consumed by ReadKey
/// void PushChar(int ch);
void ReadKey() const;
/// Scrolls the window by amount of lines given in its parameter /// Scrolls the window by amount of lines given in its parameter
/// @param where indicates how many lines it has to scroll /// @param where indicates how many lines it has to scroll
@@ -611,12 +611,17 @@ namespace NCurses
int itsX; int itsX;
int itsY; int itsY;
/// window's title /// window title
std::string itsTitle; std::string itsTitle;
/// stack of colors /// stack of colors
std::stack<Colors> itsColors; std::stack<Colors> itsColors;
/// input queue of a window. you can put characters there using
/// PushChar and they will be immediately consumed and
/// returned by ReadKey
std::queue<int> itsInputQueue;
/// containter used for additional file descriptors that have /// containter used for additional file descriptors that have
/// to be polled in ReadKey() and correspondent callbacks that /// to be polled in ReadKey() and correspondent callbacks that
/// are invoked if there is data available in them /// are invoked if there is data available in them