diff --git a/src/Makefile.am b/src/Makefile.am index 46caf2d7..526b267c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/actions.cpp b/src/actions.cpp index 596474e3..453ad362 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -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 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(a)) { if (songpos < Mpd.GetTotalTime()) diff --git a/src/actions.h b/src/actions.h index 724866ef..34b21cda 100644 --- a/src/actions.h +++ b/src/actions.h @@ -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; diff --git a/src/help.cpp b/src/help.cpp index 249e5d5d..a97f97ee 100644 --- a/src/help.cpp +++ b/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::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::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 += " "; diff --git a/src/keys.cpp b/src/keys.cpp new file mode 100644 index 00000000..79ee7a60 --- /dev/null +++ b/src/keys.cpp @@ -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; +} diff --git a/src/keys.h b/src/keys.h new file mode 100644 index 00000000..ed61d362 --- /dev/null +++ b/src/keys.h @@ -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 +#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 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 Bindings; + +private: + template 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 diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 68b6e7ee..d533e6aa 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -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; diff --git a/src/settings.cpp b/src/settings.cpp index ee56b1b4..7f529db3 100644 --- a/src/settings.cpp +++ b/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"; diff --git a/src/settings.h b/src/settings.h index 30302f75..a9084c55 100644 --- a/src/settings.h +++ b/src/settings.h @@ -45,43 +45,6 @@ struct Column bool display_empty_tag; }; -struct Bind -{ - typedef std::vector 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::iterator - , std::multimap::iterator - > Binding; - - void GenerateBindings(); - - std::multimap Bindings; - - private: - template 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);