implement input character queue and add PushCharacters macro utility
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
51
src/macro_utilities.h
Normal 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;
|
||||||
|
};
|
||||||
@@ -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))
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|
||||||
|
|||||||
14
src/screen.h
14
src/screen.h
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
23
src/window.h
23
src/window.h
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user