move keys related functions/classes to separate file
This commit is contained in:
@@ -14,6 +14,7 @@ ncmpcpp_SOURCES = \
|
||||
global.cpp \
|
||||
help.cpp \
|
||||
helpers.cpp \
|
||||
keys.cpp \
|
||||
lastfm.cpp \
|
||||
lastfm_service.cpp \
|
||||
lyrics.cpp \
|
||||
@@ -61,6 +62,7 @@ noinst_HEADERS = \
|
||||
help.h \
|
||||
helpers.h \
|
||||
interfaces.h \
|
||||
keys.h \
|
||||
lastfm.h \
|
||||
lastfm_service.h \
|
||||
lyrics.h \
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "browser.h"
|
||||
#include "clock.h"
|
||||
#include "help.h"
|
||||
#include "keys.h"
|
||||
#include "media_library.h"
|
||||
#include "lastfm.h"
|
||||
#include "lyrics.h"
|
||||
@@ -69,35 +70,6 @@ size_t Action::FooterHeight;
|
||||
size_t Action::FooterStartY;
|
||||
|
||||
std::map<ActionType, Action *> Action::Actions;
|
||||
Action::Key Action::NoOp = Action::Key(ERR, ctNCurses);
|
||||
|
||||
Action::Key Action::ReadKey(NC::Window &w)
|
||||
{
|
||||
std::string tmp;
|
||||
int input;
|
||||
while (true)
|
||||
{
|
||||
input = w.readKey();
|
||||
if (input == ERR)
|
||||
return NoOp;
|
||||
if (input > 255)
|
||||
return Key(input, ctNCurses);
|
||||
else
|
||||
{
|
||||
wchar_t wc;
|
||||
tmp += input;
|
||||
size_t conv_res = mbrtowc(&wc, tmp.c_str(), MB_CUR_MAX, 0);
|
||||
if (conv_res == size_t(-1)) // incomplete multibyte character
|
||||
continue;
|
||||
else if (conv_res == size_t(-2)) // garbage character sequence
|
||||
return NoOp;
|
||||
else // character complete
|
||||
return Key(wc, ctStandard);
|
||||
}
|
||||
}
|
||||
// not reachable
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void Action::ValidateScreenSize()
|
||||
{
|
||||
@@ -269,12 +241,11 @@ void Action::Seek()
|
||||
|
||||
int howmuch = Config.incremental_seeking ? (myPlaylist->Timer()-t)/2+Config.seek_time : Config.seek_time;
|
||||
|
||||
Key input = ReadKey(*wFooter);
|
||||
KeyConfiguration::Binding k = Keys.Bindings.equal_range(input);
|
||||
// no action?
|
||||
if (k.first == k.second || !k.first->second.isSingle())
|
||||
Key input = Key::read(*wFooter);
|
||||
auto k = Keys.Bindings.equal_range(input);
|
||||
if (k.first == k.second || !k.first->second.isSingle()) // no single action?
|
||||
break;
|
||||
Action *a = k.first->second.getAction();
|
||||
Action *a = k.first->second.action();
|
||||
if (dynamic_cast<SeekForward *>(a))
|
||||
{
|
||||
if (songpos < Mpd.GetTotalTime())
|
||||
|
||||
@@ -50,41 +50,8 @@ enum ActionType
|
||||
aShowVisualizer, aShowClock, aShowServerInfo
|
||||
};
|
||||
|
||||
enum CharType { ctStandard, ctNCurses };
|
||||
|
||||
struct Action
|
||||
{
|
||||
/// Key for binding actions to it. Supports non-ascii characters.
|
||||
struct Key
|
||||
{
|
||||
Key(wchar_t ch, CharType ct) : Char(ch), Type(ct) { }
|
||||
|
||||
wchar_t getChar() const { return Char; }
|
||||
CharType getType() const { return Type; }
|
||||
|
||||
# define INEQUALITY_OPERATOR(CMP) \
|
||||
bool operator CMP (const Key &k) const \
|
||||
{ \
|
||||
if (Char CMP k.Char) \
|
||||
return true; \
|
||||
if (Char != k.Char) \
|
||||
return false; \
|
||||
return Type CMP k.Type; \
|
||||
}
|
||||
INEQUALITY_OPERATOR(<);
|
||||
INEQUALITY_OPERATOR(<=);
|
||||
INEQUALITY_OPERATOR(>);
|
||||
INEQUALITY_OPERATOR(>=);
|
||||
# undef INEQUALITY_OPERATOR
|
||||
|
||||
bool operator==(const Key &k) const { return Char == k.Char && Type == k.Type; }
|
||||
bool operator!=(const Key &k) const { return !(*this == k); }
|
||||
|
||||
private:
|
||||
wchar_t Char;
|
||||
CharType Type;
|
||||
};
|
||||
|
||||
enum FindDirection { fdForward, fdBackward };
|
||||
|
||||
Action(ActionType type, const char *name) : itsType(type), itsName(name) { }
|
||||
@@ -102,8 +69,6 @@ struct Action
|
||||
return false;
|
||||
}
|
||||
|
||||
static Key ReadKey(NC::Window &w);
|
||||
|
||||
static void ValidateScreenSize();
|
||||
static void SetResizeFlags();
|
||||
static void ResizeScreen();
|
||||
@@ -124,8 +89,6 @@ struct Action
|
||||
static size_t FooterHeight;
|
||||
static size_t FooterStartY;
|
||||
|
||||
static Key NoOp;
|
||||
|
||||
protected:
|
||||
virtual bool canBeRun() const { return true; }
|
||||
virtual void Run() = 0;
|
||||
|
||||
40
src/help.cpp
40
src/help.cpp
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "global.h"
|
||||
#include "help.h"
|
||||
#include "scrollpad.h"
|
||||
#include "keys.h"
|
||||
#include "settings.h"
|
||||
|
||||
using Global::MainHeight;
|
||||
@@ -32,46 +32,46 @@ Help *myHelp = new Help;
|
||||
|
||||
namespace {//
|
||||
|
||||
std::string keyToString(const Action::Key &key, bool *print_backspace)
|
||||
std::string keyToString(const Key &key, bool *print_backspace)
|
||||
{
|
||||
std::string result;
|
||||
if (key == Action::Key(KEY_UP, ctNCurses))
|
||||
if (key == Key(KEY_UP, Key::NCurses))
|
||||
result += "Up";
|
||||
else if (key == Action::Key(KEY_DOWN, ctNCurses))
|
||||
else if (key == Key(KEY_DOWN, Key::NCurses))
|
||||
result += "Down";
|
||||
else if (key == Action::Key(KEY_PPAGE, ctNCurses))
|
||||
else if (key == Key(KEY_PPAGE, Key::NCurses))
|
||||
result += "PageUp";
|
||||
else if (key == Action::Key(KEY_NPAGE, ctNCurses))
|
||||
else if (key == Key(KEY_NPAGE, Key::NCurses))
|
||||
result += "PageDown";
|
||||
else if (key == Action::Key(KEY_HOME, ctNCurses))
|
||||
else if (key == Key(KEY_HOME, Key::NCurses))
|
||||
result += "Home";
|
||||
else if (key == Action::Key(KEY_END, ctNCurses))
|
||||
else if (key == Key(KEY_END, Key::NCurses))
|
||||
result += "End";
|
||||
else if (key == Action::Key(KEY_SPACE, ctStandard))
|
||||
else if (key == Key(KEY_SPACE, Key::Standard))
|
||||
result += "Space";
|
||||
else if (key == Action::Key(KEY_ENTER, ctStandard))
|
||||
else if (key == Key(KEY_ENTER, Key::Standard))
|
||||
result += "Enter";
|
||||
else if (key == Action::Key(KEY_DC, ctNCurses))
|
||||
else if (key == Key(KEY_DC, Key::NCurses))
|
||||
result += "Delete";
|
||||
else if (key == Action::Key(KEY_RIGHT, ctNCurses))
|
||||
else if (key == Key(KEY_RIGHT, Key::NCurses))
|
||||
result += "Right";
|
||||
else if (key == Action::Key(KEY_LEFT, ctNCurses))
|
||||
else if (key == Key(KEY_LEFT, Key::NCurses))
|
||||
result += "Left";
|
||||
else if (key == Action::Key(KEY_TAB, ctStandard))
|
||||
else if (key == Key(KEY_TAB, Key::Standard))
|
||||
result += "Tab";
|
||||
else if (key == Action::Key(KEY_SHIFT_TAB, ctNCurses))
|
||||
else if (key == Key(KEY_SHIFT_TAB, Key::NCurses))
|
||||
result += "Shift-Tab";
|
||||
else if (key >= Action::Key(KEY_CTRL_A, ctStandard) && key <= Action::Key(KEY_CTRL_Z, ctStandard))
|
||||
else if (key >= Key(KEY_CTRL_A, Key::Standard) && key <= Key(KEY_CTRL_Z, Key::Standard))
|
||||
{
|
||||
result += "Ctrl-";
|
||||
result += key.getChar()+64;
|
||||
}
|
||||
else if (key >= Action::Key(KEY_F1, ctNCurses) && key <= Action::Key(KEY_F12, ctNCurses))
|
||||
else if (key >= Key(KEY_F1, Key::NCurses) && key <= Key(KEY_F12, Key::NCurses))
|
||||
{
|
||||
result += "F";
|
||||
result += intTo<std::string>::apply(key.getChar()-264);
|
||||
}
|
||||
else if ((key == Action::Key(KEY_BACKSPACE, ctNCurses) || key == Action::Key(KEY_BACKSPACE_2, ctStandard)))
|
||||
else if ((key == Key(KEY_BACKSPACE, Key::NCurses) || key == Key(KEY_BACKSPACE_2, Key::Standard)))
|
||||
{
|
||||
// since some terminals interpret KEY_BACKSPACE as backspace and other need KEY_BACKSPACE_2,
|
||||
// actions have to be bound to either of them, but we want to display "Backspace" only once,
|
||||
@@ -142,9 +142,9 @@ std::string Help::DisplayKeys(const ActionType at)
|
||||
{
|
||||
bool print_backspace = true;
|
||||
std::string result;
|
||||
for (std::multimap<Action::Key, Bind>::const_iterator it = Keys.Bindings.begin(); it != Keys.Bindings.end(); ++it)
|
||||
for (auto it = Keys.Bindings.begin(); it != Keys.Bindings.end(); ++it)
|
||||
{
|
||||
if (it->second.isSingle() && it->second.getAction()->Type() == at)
|
||||
if (it->second.isSingle() && it->second.action()->Type() == at)
|
||||
{
|
||||
result += keyToString(it->first, &print_backspace);
|
||||
result += " ";
|
||||
|
||||
195
src/keys.cpp
Normal file
195
src/keys.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
/***************************************************************************
|
||||
* 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 "keys.h"
|
||||
|
||||
KeyConfiguration Keys;
|
||||
|
||||
Key Key::noOp = Key(ERR, NCurses);
|
||||
|
||||
void KeyConfiguration::generateBindings()
|
||||
{
|
||||
bind_(KEY_MOUSE, Key::NCurses, aMouseEvent);
|
||||
bind_(KEY_UP, Key::NCurses, aScrollUp);
|
||||
bind_(KEY_DOWN, Key::NCurses, aScrollDown);
|
||||
bind_('[', Key::Standard, aScrollUpAlbum);
|
||||
bind_(']', Key::Standard, aScrollDownAlbum);
|
||||
bind_('{', Key::Standard, aScrollUpArtist);
|
||||
bind_('}', Key::Standard, aScrollDownArtist);
|
||||
bind_(KEY_PPAGE, Key::NCurses, aPageUp);
|
||||
bind_(KEY_NPAGE, Key::NCurses, aPageDown);
|
||||
bind_(KEY_HOME, Key::NCurses, aMoveHome);
|
||||
bind_(KEY_END, Key::NCurses, aMoveEnd);
|
||||
bind_(KEY_SPACE, Key::Standard, aPressSpace);
|
||||
bind_(KEY_ENTER, Key::Standard, aPressEnter);
|
||||
bind_(KEY_DC, Key::NCurses, aDelete);
|
||||
bind_(KEY_RIGHT, Key::NCurses, aNextColumn);
|
||||
bind_(KEY_RIGHT, Key::NCurses, aSlaveScreen);
|
||||
bind_(KEY_RIGHT, Key::NCurses, aVolumeUp);
|
||||
bind_(KEY_LEFT, Key::NCurses, aPreviousColumn);
|
||||
bind_(KEY_LEFT, Key::NCurses, aMasterScreen);
|
||||
bind_(KEY_LEFT, Key::NCurses, aVolumeDown);
|
||||
bind_(KEY_TAB, Key::Standard, aNextScreen);
|
||||
bind_(KEY_SHIFT_TAB, Key::NCurses, aPreviousScreen);
|
||||
bind_('1', Key::Standard, aShowHelp);
|
||||
bind_('2', Key::Standard, aShowPlaylist);
|
||||
bind_('3', Key::Standard, aShowBrowser);
|
||||
bind_('4', Key::Standard, aShowSearchEngine);
|
||||
bind_('5', Key::Standard, aShowMediaLibrary);
|
||||
bind_('6', Key::Standard, aShowPlaylistEditor);
|
||||
bind_('7', Key::Standard, aShowTagEditor);
|
||||
bind_('8', Key::Standard, aShowOutputs);
|
||||
bind_('9', Key::Standard, aShowVisualizer);
|
||||
bind_('0', Key::Standard, aShowClock);
|
||||
bind_('@', Key::Standard, aShowServerInfo);
|
||||
bind_('s', Key::Standard, aStop);
|
||||
bind_('P', Key::Standard, aPause);
|
||||
bind_('>', Key::Standard, aNextSong);
|
||||
bind_('<', Key::Standard, aPreviousSong);
|
||||
bind_(KEY_CTRL_H, Key::Standard, aJumpToParentDir);
|
||||
bind_(KEY_CTRL_H, Key::Standard, aReplaySong);
|
||||
bind_(KEY_BACKSPACE, Key::NCurses, aJumpToParentDir);
|
||||
bind_(KEY_BACKSPACE, Key::NCurses, aReplaySong);
|
||||
bind_(KEY_BACKSPACE_2, Key::Standard, aJumpToParentDir);
|
||||
bind_(KEY_BACKSPACE_2, Key::Standard, aReplaySong);
|
||||
bind_('f', Key::Standard, aSeekForward);
|
||||
bind_('b', Key::Standard, aSeekBackward);
|
||||
bind_('r', Key::Standard, aToggleRepeat);
|
||||
bind_('z', Key::Standard, aToggleRandom);
|
||||
bind_('y', Key::Standard, aSaveTagChanges);
|
||||
bind_('y', Key::Standard, aStartSearching);
|
||||
bind_('y', Key::Standard, aToggleSingle);
|
||||
bind_('R', Key::Standard, aToggleConsume);
|
||||
bind_('Y', Key::Standard, aToggleReplayGainMode);
|
||||
bind_('t', Key::Standard, aToggleSpaceMode);
|
||||
bind_('T', Key::Standard, aToggleAddMode);
|
||||
bind_('|', Key::Standard, aToggleMouse);
|
||||
bind_('#', Key::Standard, aToggleBitrateVisibility);
|
||||
bind_('Z', Key::Standard, aShuffle);
|
||||
bind_('x', Key::Standard, aToggleCrossfade);
|
||||
bind_('X', Key::Standard, aSetCrossfade);
|
||||
bind_('u', Key::Standard, aUpdateDatabase);
|
||||
bind_(KEY_CTRL_V, Key::Standard, aSortPlaylist);
|
||||
bind_(KEY_CTRL_R, Key::Standard, aReversePlaylist);
|
||||
bind_(KEY_CTRL_F, Key::Standard, aApplyFilter);
|
||||
bind_(KEY_CTRL_G, Key::Standard, aDisableFilter);
|
||||
bind_('/', Key::Standard, aFind);
|
||||
bind_('/', Key::Standard, aFindItemForward);
|
||||
bind_('?', Key::Standard, aFind);
|
||||
bind_('?', Key::Standard, aFindItemBackward);
|
||||
bind_('.', Key::Standard, aNextFoundItem);
|
||||
bind_(',', Key::Standard, aPreviousFoundItem);
|
||||
bind_('w', Key::Standard, aToggleFindMode);
|
||||
bind_('e', Key::Standard, aEditSong);
|
||||
bind_('e', Key::Standard, aEditLibraryTag);
|
||||
bind_('e', Key::Standard, aEditLibraryAlbum);
|
||||
bind_('e', Key::Standard, aEditDirectoryName);
|
||||
bind_('e', Key::Standard, aEditPlaylistName);
|
||||
bind_('e', Key::Standard, aEditLyrics);
|
||||
bind_('i', Key::Standard, aShowSongInfo);
|
||||
bind_('I', Key::Standard, aShowArtistInfo);
|
||||
bind_('g', Key::Standard, aJumpToPositionInSong);
|
||||
bind_('l', Key::Standard, aShowLyrics);
|
||||
bind_('v', Key::Standard, aReverseSelection);
|
||||
bind_('V', Key::Standard, aDeselectItems);
|
||||
bind_('B', Key::Standard, aSelectAlbum);
|
||||
bind_('a', Key::Standard, aAddSelectedItems);
|
||||
bind_('c', Key::Standard, aClearPlaylist);
|
||||
bind_('c', Key::Standard, aClearMainPlaylist);
|
||||
bind_('C', Key::Standard, aCropPlaylist);
|
||||
bind_('C', Key::Standard, aCropMainPlaylist);
|
||||
bind_('m', Key::Standard, aMoveSortOrderUp);
|
||||
bind_('m', Key::Standard, aMoveSelectedItemsUp);
|
||||
bind_('n', Key::Standard, aMoveSortOrderDown);
|
||||
bind_('n', Key::Standard, aMoveSelectedItemsDown);
|
||||
bind_('M', Key::Standard, aMoveSelectedItemsTo);
|
||||
bind_('A', Key::Standard, aAdd);
|
||||
bind_('S', Key::Standard, aSavePlaylist);
|
||||
bind_('o', Key::Standard, aJumpToPlayingSong);
|
||||
bind_('G', Key::Standard, aJumpToBrowser);
|
||||
bind_('G', Key::Standard, aJumpToPlaylistEditor);
|
||||
bind_('~', Key::Standard, aJumpToMediaLibrary);
|
||||
bind_('E', Key::Standard, aJumpToTagEditor);
|
||||
bind_('U', Key::Standard, aToggleAutoCenter);
|
||||
bind_('p', Key::Standard, aToggleDisplayMode);
|
||||
bind_('\\', Key::Standard, aToggleInterface);
|
||||
bind_('!', Key::Standard, aToggleSeparatorsInPlaylist);
|
||||
bind_('L', Key::Standard, aToggleLyricsFetcher);
|
||||
bind_('F', Key::Standard, aToggleFetchingLyricsInBackground);
|
||||
bind_(KEY_CTRL_L, Key::Standard, aToggleScreenLock);
|
||||
bind_('`', Key::Standard, aToggleBrowserSortMode);
|
||||
bind_('`', Key::Standard, aToggleLibraryTagType);
|
||||
bind_('`', Key::Standard, aRefetchLyrics);
|
||||
bind_('`', Key::Standard, aRefetchArtistInfo);
|
||||
bind_('`', Key::Standard, aAddRandomItems);
|
||||
bind_(KEY_CTRL_P, Key::Standard, aSetSelectedItemsPriority);
|
||||
bind_('q', Key::Standard, aQuit);
|
||||
|
||||
bind_('k', Key::Standard, aScrollUp);
|
||||
bind_('j', Key::Standard, aScrollDown);
|
||||
bind_('d', Key::Standard, aDelete);
|
||||
bind_('+', Key::Standard, aVolumeUp);
|
||||
bind_('-', Key::Standard, aVolumeDown);
|
||||
bind_(KEY_F1, Key::NCurses, aShowHelp);
|
||||
bind_(KEY_F2, Key::NCurses, aShowPlaylist);
|
||||
bind_(KEY_F3, Key::NCurses, aShowBrowser);
|
||||
bind_(KEY_F4, Key::NCurses, aShowSearchEngine);
|
||||
bind_(KEY_F5, Key::NCurses, aShowMediaLibrary);
|
||||
bind_(KEY_F6, Key::NCurses, aShowPlaylistEditor);
|
||||
bind_(KEY_F7, Key::NCurses, aShowTagEditor);
|
||||
bind_(KEY_F8, Key::NCurses, aShowOutputs);
|
||||
bind_(KEY_F9, Key::NCurses, aShowVisualizer);
|
||||
bind_(KEY_F10, Key::NCurses, aShowClock);
|
||||
bind_('Q', Key::Standard, aQuit);
|
||||
}
|
||||
|
||||
Key Key::read(NC::Window &w)
|
||||
{
|
||||
Key result = noOp;
|
||||
std::string tmp;
|
||||
int input;
|
||||
while (true)
|
||||
{
|
||||
input = w.readKey();
|
||||
if (input == ERR)
|
||||
break;
|
||||
if (input > 255)
|
||||
{
|
||||
result = Key(input, NCurses);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t wc;
|
||||
tmp += input;
|
||||
size_t conv_res = mbrtowc(&wc, tmp.c_str(), MB_CUR_MAX, 0);
|
||||
if (conv_res == size_t(-1)) // incomplete multibyte character
|
||||
continue;
|
||||
else if (conv_res == size_t(-2)) // garbage character sequence
|
||||
break;
|
||||
else // character complete
|
||||
{
|
||||
result = Key(wc, Standard);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
98
src/keys.h
Normal file
98
src/keys.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/***************************************************************************
|
||||
* 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. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _KEYS_H
|
||||
#define _KEYS_H
|
||||
|
||||
#include <cassert>
|
||||
#include "actions.h"
|
||||
|
||||
/// Key for binding actions to it. Supports non-ascii characters.
|
||||
struct Key
|
||||
{
|
||||
enum Type { Standard, NCurses };
|
||||
|
||||
Key(wchar_t ch, Type ct) : m_char(ch), m_type(ct) { }
|
||||
|
||||
wchar_t getChar() const { return m_char; }
|
||||
Type getType() const { return m_type; }
|
||||
|
||||
# define KEYS_DEFINE_OPERATOR(CMP) \
|
||||
bool operator CMP (const Key &k) const \
|
||||
{ \
|
||||
if (m_char CMP k.m_char) \
|
||||
return true; \
|
||||
if (m_char != k.m_char) \
|
||||
return false; \
|
||||
return m_type CMP k.m_type; \
|
||||
}
|
||||
KEYS_DEFINE_OPERATOR(<);
|
||||
KEYS_DEFINE_OPERATOR(<=);
|
||||
KEYS_DEFINE_OPERATOR(>);
|
||||
KEYS_DEFINE_OPERATOR(>=);
|
||||
# undef KEYS_DEFINE_OPERATOR
|
||||
|
||||
bool operator==(const Key &k) const { return m_char == k.m_char && m_type == k.m_type; }
|
||||
bool operator!=(const Key &k) const { return !(*this == k); }
|
||||
|
||||
static Key read(NC::Window &w);
|
||||
static Key noOp;
|
||||
|
||||
private:
|
||||
wchar_t m_char;
|
||||
Type m_type;
|
||||
};
|
||||
|
||||
/// Represents either single action or chain of actions bound to a certain key
|
||||
struct Binding
|
||||
{
|
||||
typedef std::vector<Action *> ActionChain;
|
||||
|
||||
Binding(ActionType at) : m_is_single(true), m_action(Action::Get(at)) { }
|
||||
Binding(ActionChain *chain_) : m_is_single(false), m_chain(chain_) { }
|
||||
|
||||
bool isSingle() const { return m_is_single; }
|
||||
ActionChain *chain() const { assert(!m_is_single); return m_chain; }
|
||||
Action *action() const { assert(m_is_single); return m_action; }
|
||||
|
||||
private:
|
||||
bool m_is_single;
|
||||
union {
|
||||
Action *m_action;
|
||||
ActionChain *m_chain;
|
||||
};
|
||||
};
|
||||
|
||||
/// Key configuration
|
||||
struct KeyConfiguration
|
||||
{
|
||||
void generateBindings();
|
||||
|
||||
std::multimap<Key, Binding> Bindings;
|
||||
|
||||
private:
|
||||
template <typename T> void bind_(wchar_t c, Key::Type ct, T t) {
|
||||
Bindings.insert(std::make_pair(Key(c, ct), Binding(t)));
|
||||
}
|
||||
};
|
||||
|
||||
extern KeyConfiguration Keys;
|
||||
|
||||
#endif // _KEYS_H
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "browser.h"
|
||||
#include "global.h"
|
||||
#include "helpers.h"
|
||||
#include "keys.h"
|
||||
#include "lyrics.h"
|
||||
#include "playlist.h"
|
||||
#include "settings.h"
|
||||
@@ -97,7 +98,7 @@ int main(int argc, char **argv)
|
||||
Config.Read();
|
||||
|
||||
Config.GenerateColumns();
|
||||
Keys.GenerateBindings();
|
||||
Keys.generateBindings();
|
||||
|
||||
if (getenv("MPD_HOST"))
|
||||
Mpd.SetHostname(getenv("MPD_HOST"));
|
||||
@@ -175,7 +176,7 @@ int main(int argc, char **argv)
|
||||
Mpd.SetErrorHandler(NcmpcppErrorCallback, 0);
|
||||
|
||||
// local variables
|
||||
Action::Key input(0, ctStandard);
|
||||
Key input(0, Key::Standard);
|
||||
timeval past = { 0, 0 };
|
||||
// local variables end
|
||||
|
||||
@@ -262,26 +263,26 @@ int main(int argc, char **argv)
|
||||
}
|
||||
// header stuff end
|
||||
|
||||
if (input != Action::NoOp)
|
||||
if (input != Key::noOp)
|
||||
myScreen->RefreshWindow();
|
||||
input = Action::ReadKey(*wFooter);
|
||||
input = Key::read(*wFooter);
|
||||
|
||||
if (input == Action::NoOp)
|
||||
if (input == Key::noOp)
|
||||
continue;
|
||||
|
||||
KeyConfiguration::Binding k = Keys.Bindings.equal_range(input);
|
||||
auto k = Keys.Bindings.equal_range(input);
|
||||
for (; k.first != k.second; ++k.first)
|
||||
{
|
||||
Bind &b = k.first->second;
|
||||
Binding &b = k.first->second;
|
||||
if (b.isSingle())
|
||||
{
|
||||
if (b.getAction()->Execute())
|
||||
if (b.action()->Execute())
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Bind::ActionChain *chain = b.getChain();
|
||||
for (Bind::ActionChain::iterator it = chain->begin(); it != chain->end(); ++it)
|
||||
auto chain = b.chain();
|
||||
for (auto it = chain->begin(); it != chain->end(); ++it)
|
||||
if (!(*it)->Execute())
|
||||
break;
|
||||
break;
|
||||
|
||||
137
src/settings.cpp
137
src/settings.cpp
@@ -55,7 +55,6 @@
|
||||
#endif
|
||||
|
||||
Configuration Config;
|
||||
KeyConfiguration Keys;
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -158,142 +157,6 @@ void CreateDir(const std::string &dir)
|
||||
);
|
||||
}
|
||||
|
||||
void KeyConfiguration::GenerateBindings()
|
||||
{
|
||||
Bind_(KEY_MOUSE, ctNCurses, aMouseEvent);
|
||||
Bind_(KEY_UP, ctNCurses, aScrollUp);
|
||||
Bind_(KEY_DOWN, ctNCurses, aScrollDown);
|
||||
Bind_('[', ctStandard, aScrollUpAlbum);
|
||||
Bind_(']', ctStandard, aScrollDownAlbum);
|
||||
Bind_('{', ctStandard, aScrollUpArtist);
|
||||
Bind_('}', ctStandard, aScrollDownArtist);
|
||||
Bind_(KEY_PPAGE, ctNCurses, aPageUp);
|
||||
Bind_(KEY_NPAGE, ctNCurses, aPageDown);
|
||||
Bind_(KEY_HOME, ctNCurses, aMoveHome);
|
||||
Bind_(KEY_END, ctNCurses, aMoveEnd);
|
||||
Bind_(KEY_SPACE, ctStandard, aPressSpace);
|
||||
Bind_(KEY_ENTER, ctStandard, aPressEnter);
|
||||
Bind_(KEY_DC, ctNCurses, aDelete);
|
||||
Bind_(KEY_RIGHT, ctNCurses, aNextColumn);
|
||||
Bind_(KEY_RIGHT, ctNCurses, aSlaveScreen);
|
||||
Bind_(KEY_RIGHT, ctNCurses, aVolumeUp);
|
||||
Bind_(KEY_LEFT, ctNCurses, aPreviousColumn);
|
||||
Bind_(KEY_LEFT, ctNCurses, aMasterScreen);
|
||||
Bind_(KEY_LEFT, ctNCurses, aVolumeDown);
|
||||
Bind_(KEY_TAB, ctStandard, aNextScreen);
|
||||
Bind_(KEY_SHIFT_TAB, ctNCurses, aPreviousScreen);
|
||||
Bind_('1', ctStandard, aShowHelp);
|
||||
Bind_('2', ctStandard, aShowPlaylist);
|
||||
Bind_('3', ctStandard, aShowBrowser);
|
||||
Bind_('4', ctStandard, aShowSearchEngine);
|
||||
Bind_('5', ctStandard, aShowMediaLibrary);
|
||||
Bind_('6', ctStandard, aShowPlaylistEditor);
|
||||
Bind_('7', ctStandard, aShowTagEditor);
|
||||
Bind_('8', ctStandard, aShowOutputs);
|
||||
Bind_('9', ctStandard, aShowVisualizer);
|
||||
Bind_('0', ctStandard, aShowClock);
|
||||
Bind_('@', ctStandard, aShowServerInfo);
|
||||
Bind_('s', ctStandard, aStop);
|
||||
Bind_('P', ctStandard, aPause);
|
||||
Bind_('>', ctStandard, aNextSong);
|
||||
Bind_('<', ctStandard, aPreviousSong);
|
||||
Bind_(KEY_CTRL_H, ctStandard, aJumpToParentDir);
|
||||
Bind_(KEY_CTRL_H, ctStandard, aReplaySong);
|
||||
Bind_(KEY_BACKSPACE, ctNCurses, aJumpToParentDir);
|
||||
Bind_(KEY_BACKSPACE, ctNCurses, aReplaySong);
|
||||
Bind_(KEY_BACKSPACE_2, ctStandard, aJumpToParentDir);
|
||||
Bind_(KEY_BACKSPACE_2, ctStandard, aReplaySong);
|
||||
Bind_('f', ctStandard, aSeekForward);
|
||||
Bind_('b', ctStandard, aSeekBackward);
|
||||
Bind_('r', ctStandard, aToggleRepeat);
|
||||
Bind_('z', ctStandard, aToggleRandom);
|
||||
Bind_('y', ctStandard, aSaveTagChanges);
|
||||
Bind_('y', ctStandard, aStartSearching);
|
||||
Bind_('y', ctStandard, aToggleSingle);
|
||||
Bind_('R', ctStandard, aToggleConsume);
|
||||
Bind_('Y', ctStandard, aToggleReplayGainMode);
|
||||
Bind_('t', ctStandard, aToggleSpaceMode);
|
||||
Bind_('T', ctStandard, aToggleAddMode);
|
||||
Bind_('|', ctStandard, aToggleMouse);
|
||||
Bind_('#', ctStandard, aToggleBitrateVisibility);
|
||||
Bind_('Z', ctStandard, aShuffle);
|
||||
Bind_('x', ctStandard, aToggleCrossfade);
|
||||
Bind_('X', ctStandard, aSetCrossfade);
|
||||
Bind_('u', ctStandard, aUpdateDatabase);
|
||||
Bind_(KEY_CTRL_V, ctStandard, aSortPlaylist);
|
||||
Bind_(KEY_CTRL_R, ctStandard, aReversePlaylist);
|
||||
Bind_(KEY_CTRL_F, ctStandard, aApplyFilter);
|
||||
Bind_(KEY_CTRL_G, ctStandard, aDisableFilter);
|
||||
Bind_('/', ctStandard, aFind);
|
||||
Bind_('/', ctStandard, aFindItemForward);
|
||||
Bind_('?', ctStandard, aFind);
|
||||
Bind_('?', ctStandard, aFindItemBackward);
|
||||
Bind_('.', ctStandard, aNextFoundItem);
|
||||
Bind_(',', ctStandard, aPreviousFoundItem);
|
||||
Bind_('w', ctStandard, aToggleFindMode);
|
||||
Bind_('e', ctStandard, aEditSong);
|
||||
Bind_('e', ctStandard, aEditLibraryTag);
|
||||
Bind_('e', ctStandard, aEditLibraryAlbum);
|
||||
Bind_('e', ctStandard, aEditDirectoryName);
|
||||
Bind_('e', ctStandard, aEditPlaylistName);
|
||||
Bind_('e', ctStandard, aEditLyrics);
|
||||
Bind_('i', ctStandard, aShowSongInfo);
|
||||
Bind_('I', ctStandard, aShowArtistInfo);
|
||||
Bind_('g', ctStandard, aJumpToPositionInSong);
|
||||
Bind_('l', ctStandard, aShowLyrics);
|
||||
Bind_('v', ctStandard, aReverseSelection);
|
||||
Bind_('V', ctStandard, aDeselectItems);
|
||||
Bind_('B', ctStandard, aSelectAlbum);
|
||||
Bind_('a', ctStandard, aAddSelectedItems);
|
||||
Bind_('c', ctStandard, aClearPlaylist);
|
||||
Bind_('c', ctStandard, aClearMainPlaylist);
|
||||
Bind_('C', ctStandard, aCropPlaylist);
|
||||
Bind_('C', ctStandard, aCropMainPlaylist);
|
||||
Bind_('m', ctStandard, aMoveSortOrderUp);
|
||||
Bind_('m', ctStandard, aMoveSelectedItemsUp);
|
||||
Bind_('n', ctStandard, aMoveSortOrderDown);
|
||||
Bind_('n', ctStandard, aMoveSelectedItemsDown);
|
||||
Bind_('M', ctStandard, aMoveSelectedItemsTo);
|
||||
Bind_('A', ctStandard, aAdd);
|
||||
Bind_('S', ctStandard, aSavePlaylist);
|
||||
Bind_('o', ctStandard, aJumpToPlayingSong);
|
||||
Bind_('G', ctStandard, aJumpToBrowser);
|
||||
Bind_('G', ctStandard, aJumpToPlaylistEditor);
|
||||
Bind_('~', ctStandard, aJumpToMediaLibrary);
|
||||
Bind_('E', ctStandard, aJumpToTagEditor);
|
||||
Bind_('U', ctStandard, aToggleAutoCenter);
|
||||
Bind_('p', ctStandard, aToggleDisplayMode);
|
||||
Bind_('\\', ctStandard, aToggleInterface);
|
||||
Bind_('!', ctStandard, aToggleSeparatorsInPlaylist);
|
||||
Bind_('L', ctStandard, aToggleLyricsFetcher);
|
||||
Bind_('F', ctStandard, aToggleFetchingLyricsInBackground);
|
||||
Bind_(KEY_CTRL_L, ctStandard, aToggleScreenLock);
|
||||
Bind_('`', ctStandard, aToggleBrowserSortMode);
|
||||
Bind_('`', ctStandard, aToggleLibraryTagType);
|
||||
Bind_('`', ctStandard, aRefetchLyrics);
|
||||
Bind_('`', ctStandard, aRefetchArtistInfo);
|
||||
Bind_('`', ctStandard, aAddRandomItems);
|
||||
Bind_(KEY_CTRL_P, ctStandard, aSetSelectedItemsPriority);
|
||||
Bind_('q', ctStandard, aQuit);
|
||||
|
||||
Bind_('k', ctStandard, aScrollUp);
|
||||
Bind_('j', ctStandard, aScrollDown);
|
||||
Bind_('d', ctStandard, aDelete);
|
||||
Bind_('+', ctStandard, aVolumeUp);
|
||||
Bind_('-', ctStandard, aVolumeDown);
|
||||
Bind_(KEY_F1, ctNCurses, aShowHelp);
|
||||
Bind_(KEY_F2, ctNCurses, aShowPlaylist);
|
||||
Bind_(KEY_F3, ctNCurses, aShowBrowser);
|
||||
Bind_(KEY_F4, ctNCurses, aShowSearchEngine);
|
||||
Bind_(KEY_F5, ctNCurses, aShowMediaLibrary);
|
||||
Bind_(KEY_F6, ctNCurses, aShowPlaylistEditor);
|
||||
Bind_(KEY_F7, ctNCurses, aShowTagEditor);
|
||||
Bind_(KEY_F8, ctNCurses, aShowOutputs);
|
||||
Bind_(KEY_F9, ctNCurses, aShowVisualizer);
|
||||
Bind_(KEY_F10, ctNCurses, aShowClock);
|
||||
Bind_('Q', ctStandard, aQuit);
|
||||
}
|
||||
|
||||
void Configuration::SetDefaults()
|
||||
{
|
||||
mpd_host = "localhost";
|
||||
|
||||
@@ -45,43 +45,6 @@ struct Column
|
||||
bool display_empty_tag;
|
||||
};
|
||||
|
||||
struct Bind
|
||||
{
|
||||
typedef std::vector<Action *> ActionChain;
|
||||
|
||||
Bind(ActionType at) : isThisSingle(true), itsAction(Action::Get(at)) { }
|
||||
Bind(ActionChain *chain) : isThisSingle(false), itsChain(chain) { }
|
||||
|
||||
bool isSingle() const { return isThisSingle; }
|
||||
ActionChain *getChain() const { assert(!isThisSingle); return itsChain; }
|
||||
Action *getAction() const { assert(isThisSingle); return itsAction; }
|
||||
|
||||
private:
|
||||
bool isThisSingle;
|
||||
union {
|
||||
Action *itsAction;
|
||||
ActionChain *itsChain;
|
||||
};
|
||||
};
|
||||
|
||||
struct KeyConfiguration
|
||||
{
|
||||
typedef std::pair<
|
||||
std::multimap<Action::Key, Bind>::iterator
|
||||
, std::multimap<Action::Key, Bind>::iterator
|
||||
> Binding;
|
||||
|
||||
void GenerateBindings();
|
||||
|
||||
std::multimap<Action::Key, Bind> Bindings;
|
||||
|
||||
private:
|
||||
template <typename T> void Bind_(wchar_t c, CharType ct, T t)
|
||||
{
|
||||
Bindings.insert(std::make_pair(Action::Key(c, ct), Bind(t)));
|
||||
}
|
||||
};
|
||||
|
||||
struct Configuration
|
||||
{
|
||||
Configuration();
|
||||
@@ -234,7 +197,6 @@ struct Configuration
|
||||
std::string config_file_path;
|
||||
};
|
||||
|
||||
extern KeyConfiguration Keys;
|
||||
extern Configuration Config;
|
||||
|
||||
void CreateDir(const std::string &dir);
|
||||
|
||||
Reference in New Issue
Block a user