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)
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 \
lyrics_fetcher.h media_library.h menu.h mpdpp.h outputs.h playlist_editor.h screen.h \
scrollpad.h search_engine.h sel_items_adder.h server_info.h settings.h song.h \
song_info.h tag_editor.h tiny_tag_editor.h tolower.h visualizer.h window.h
lyrics_fetcher.h macro_utilities.h media_library.h menu.h mpdpp.h outputs.h \
playlist_editor.h screen.h scrollpad.h search_engine.h sel_items_adder.h server_info.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;
while (true)
{
w.ReadKey(input);
input = w.ReadKey();
if (input == ERR)
return NoOp;
if (input > 255)
@@ -407,7 +407,7 @@ bool Action::AskYesNoQuestion(const std::string &question, void (*callback)())
{
if (callback)
callback();
wFooter->ReadKey(answer);
answer = wFooter->ReadKey();
}
while (answer != 'y' && answer != 'n');
UnlockStatusbar();
@@ -2103,7 +2103,7 @@ void ToggleReplayGainMode::Run()
do
{
TraceMpdStatus();
wFooter->ReadKey(answer);
answer = wFooter->ReadKey();
}
while (answer != 'o' && answer != 't' && answer != 'a');
UnlockStatusbar();
@@ -2147,7 +2147,7 @@ void AddRandomItems::Run()
do
{
TraceMpdStatus();
wFooter->ReadKey(answer);
answer = wFooter->ReadKey();
}
while (answer != 's' && answer != 'a' && answer != 'b');
UnlockStatusbar();
@@ -2210,7 +2210,7 @@ void ToggleLibraryTagType::Run()
do
{
TraceMpdStatus();
wFooter->ReadKey(answer);
answer = wFooter->ReadKey();
}
while (answer != 'a' && answer != 'A' && answer != 'y' && answer != 'g' && answer != 'c' && answer != 'p');
UnlockStatusbar();

View File

@@ -27,6 +27,7 @@
enum ActionType
{
aMacroUtility,
aMouseEvent, aScrollUp, aScrollDown, aScrollUpArtist, aScrollUpAlbum, aScrollDownArtist,
aScrollDownAlbum, aPageUp, aPageDown, aMoveHome, aMoveEnd, aToggleInterface, aJumpToParentDir,
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)
{
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 SpacePressed();
virtual void ReadKey(int &);
virtual void MouseButtonPressed(MEVENT);
virtual bool isTabbable() { return true; }

View File

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

View File

@@ -371,8 +371,17 @@ bool Window::FDCallbacksListEmpty() const
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
// both stdin and other file descriptors in one select. the
// 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 !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
for (FDCallbacks::const_iterator it = itsFDs.begin(); it != itsFDs.end(); ++it)
if (FD_ISSET(it->first, &fdset))
@@ -409,18 +418,19 @@ void Window::ReadKey(int &read_key) const
}
# if !defined(USE_PDCURSES)
else
read_key = ERR;
result = ERR;
# else
read_key = wgetch(itsWindow);
result = wgetch(itsWindow);
# 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;
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);
prefresh(itsWindow, 0, 0, itsStartY, itsStartX, itsStartY+itsHeight-1, itsStartX+itsWidth-1);
ReadKey(input);
input = ReadKey();
switch (input)
{

View File

@@ -36,6 +36,7 @@
#include <stack>
#include <vector>
#include <string>
#include <queue>
// define some Ctrl-? keys
#define KEY_CTRL_A 1
@@ -275,12 +276,12 @@ namespace NCurses
/// @see CreateHistory()
///
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).
/// 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);
}
@@ -407,14 +408,13 @@ namespace NCurses
///
bool FDCallbacksListEmpty() const;
/// Reads key from standard input and writes it into read_key variable
/// @param read_key variable for read key to be written into it
/// Reads key from standard input (or takes it from input queue)
/// and writes it into read_key variable
///
void ReadKey(int &read_key) const;
int ReadKey();
/// Waits until user press a key.
///
void ReadKey() const;
/// Push single character into input queue, so it can get consumed by ReadKey
void PushChar(int ch);
/// Scrolls the window by amount of lines given in its parameter
/// @param where indicates how many lines it has to scroll
@@ -611,12 +611,17 @@ namespace NCurses
int itsX;
int itsY;
/// window's title
/// window title
std::string itsTitle;
/// stack of colors
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
/// to be polled in ReadKey() and correspondent callbacks that
/// are invoked if there is data available in them