From 5a2853b36ae08249260e2e0e91e45dc044dca965 Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Tue, 26 May 2009 22:07:08 +0200 Subject: [PATCH] new feature: outputs screen --- configure.in | 5 +++ doc/keys | 2 + src/Makefile.am | 6 +-- src/help.cpp | 9 ++++ src/mpdpp.cpp | 31 +++++++++++++ src/mpdpp.h | 7 +++ src/ncmpcpp.cpp | 14 +++++- src/outputs.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++++++ src/outputs.h | 59 +++++++++++++++++++++++++ src/settings.cpp | 4 ++ src/settings.h | 1 + 11 files changed, 245 insertions(+), 4 deletions(-) create mode 100644 src/outputs.cpp create mode 100644 src/outputs.h diff --git a/configure.in b/configure.in index b91f03e3..623e336f 100644 --- a/configure.in +++ b/configure.in @@ -9,6 +9,7 @@ AC_LANG_CPLUSPLUS AC_PROG_CXX AM_PROG_LIBTOOL +AC_ARG_ENABLE(outputs, AS_HELP_STRING([--enable-outputs], [Enable outputs screen @<:@default=no@:>@]), [outputs=$enableval], [outputs=no]) AC_ARG_ENABLE(clock, AS_HELP_STRING([--enable-clock], [Enable clock screen @<:@default=no@:>@]), [clock=$enableval], [clock=no]) AC_ARG_ENABLE(unicode, AS_HELP_STRING([--enable-unicode], [Enable utf8 support @<:@default=yes@:>@]), [unicode=$enableval], [unicode=yes]) AC_ARG_WITH(curl, AS_HELP_STRING([--with-curl], [Enable fetching lyrics from the Internet @<:@default=auto@:>@]), [curl=$withval], [curl=auto]) @@ -17,6 +18,10 @@ AC_ARG_WITH(pdcurses, AS_HELP_STRING([--with-pdcurses[=LIBNAME]], [Link against AC_ARG_WITH(threads, AS_HELP_STRING([--with-threads], [Enable threading support using posix threads @<:@default=auto@:>@]), [threads=$withval], [threads=auto]) AC_ARG_WITH(taglib, AS_HELP_STRING([--with-taglib], [Enable tag editor @<:@default=auto@:>@]), [taglib=$withval], [taglib=auto]) +if test "$outputs" = "yes"; then + AC_DEFINE([ENABLE_OUTPUTS], [1], [enables outputs screen]) +fi + if test "$clock" = "yes"; then AC_DEFINE([ENABLE_CLOCK], [1], [enables clock screen]) fi diff --git a/doc/keys b/doc/keys index bdd19f44..e879e637 100644 --- a/doc/keys +++ b/doc/keys @@ -54,6 +54,8 @@ # #key_tag_editor = '7' 271 # +#key_outputs = '8' 272 +# #key_clock = '0' 274 # #key_stop = 's' diff --git a/src/Makefile.am b/src/Makefile.am index a0ac0b99..e329b887 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ bin_PROGRAMS = ncmpcpp ncmpcpp_SOURCES = browser.cpp charset.cpp clock.cpp display.cpp help.cpp \ helpers.cpp info.cpp libmpdclient.c lyrics.cpp media_library.cpp menu.cpp misc.cpp \ - mpdpp.cpp ncmpcpp.cpp playlist.cpp playlist_editor.cpp scrollpad.cpp \ + mpdpp.cpp ncmpcpp.cpp outputs.cpp playlist.cpp playlist_editor.cpp scrollpad.cpp \ search_engine.cpp settings.cpp song.cpp status.cpp str_pool.c tag_editor.cpp window.cpp # set the include path found by configure @@ -10,5 +10,5 @@ INCLUDES= $(all_includes) # the library search path. ncmpcpp_LDFLAGS = $(all_libraries) noinst_HEADERS = browser.h charset.h clock.h display.h global.h help.h \ - helpers.h home.h info.h lyrics.h media_library.h menu.h mpdpp.h playlist_editor.h \ - screen.h scrollpad.h search_engine.h settings.h song.h tag_editor.h window.h + helpers.h home.h info.h lyrics.h media_library.h menu.h mpdpp.h outputs.h \ + playlist_editor.h screen.h scrollpad.h search_engine.h settings.h song.h tag_editor.h window.h diff --git a/src/help.cpp b/src/help.cpp index af4fd319..70fa7858 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -139,6 +139,9 @@ void Help::GetKeybindings() # ifdef HAVE_TAGLIB_H *w << DisplayKeys(Key.TagEditor) << "Tag editor\n"; # endif // HAVE_TAGLIB_H +# ifdef ENABLE_OUTPUTS + *w << DisplayKeys(Key.Outputs) << "Outputs\n"; +# endif // ENABLE_OUTPUTS # ifdef ENABLE_CLOCK *w << DisplayKeys(Key.Clock) << "Clock screen\n"; # endif // ENABLE_CLOCK @@ -273,5 +276,11 @@ void Help::GetKeybindings() *w << DisplayKeys(&Key.VolumeDown[0], 1) << "Previous column\n"; *w << DisplayKeys(&Key.VolumeUp[0], 1) << "Next column\n"; # endif // HAVE_TAGLIB_H + + +# ifdef ENABLE_OUTPUTS + *w << "\n\n " << fmtBold << "Keys - Outputs\n -----------------------------------------\n" << fmtBoldEnd; + *w << DisplayKeys(Key.Enter) << "Enable/disable output\n"; +# endif // ENABLE_OUTPUTS } diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp index 0f5e229f..6301f2ba 100644 --- a/src/mpdpp.cpp +++ b/src/mpdpp.cpp @@ -867,6 +867,37 @@ void Connection::GetDirectories(const string &path, TagList &v) const } } +void Connection::GetOutputs(OutputList &v) const +{ + if (!isConnected) + return; + mpd_sendOutputsCommand(itsConnection); + while (mpd_OutputEntity *output = mpd_getNextOutput(itsConnection)) + { + v.push_back(std::make_pair(output->name, output->enabled)); + mpd_freeOutputElement(output); + } + mpd_finishCommand(itsConnection); +} + +bool Connection::EnableOutput(int id) +{ + if (!isConnected) + return false; + mpd_sendEnableOutputCommand(itsConnection, id); + mpd_finishCommand(itsConnection); + return !CheckForErrors(); +} + +bool Connection::DisableOutput(int id) +{ + if (!isConnected) + return false; + mpd_sendDisableOutputCommand(itsConnection, id); + mpd_finishCommand(itsConnection); + return !CheckForErrors(); +} + int Connection::CheckForErrors() { itsErrorCode = 0; diff --git a/src/mpdpp.h b/src/mpdpp.h index b4cb374e..aaf77aac 100644 --- a/src/mpdpp.h +++ b/src/mpdpp.h @@ -64,9 +64,12 @@ namespace MPD bool StatusFlags:1; }; + typedef std::pair Output; + typedef std::vector ItemList; typedef std::vector SongList; typedef std::vector TagList; + typedef std::vector OutputList; void FreeSongList(SongList &); void FreeItemList(ItemList &); @@ -177,6 +180,10 @@ namespace MPD void GetSongs(const std::string &, SongList &) const; void GetDirectories(const std::string &, TagList &) const; + void GetOutputs(OutputList &) const; + bool EnableOutput(int); + bool DisableOutput(int); + private: int CheckForErrors(); diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 42ae247e..878770bd 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -45,6 +45,7 @@ #include "settings.h" #include "song.h" #include "info.h" +#include "outputs.h" #include "status.h" #include "tag_editor.h" @@ -142,7 +143,9 @@ int main(int argc, char *argv[]) myTinyTagEditor->Init(); myTagEditor->Init(); # endif // HAVE_TAGLIB_H - +# ifdef ENABLE_OUTPUTS + myOutputs->Init(); +# endif // ENABLE_OUTPUTS # ifdef ENABLE_CLOCK myClock->Init(); # endif // ENABLE_CLOCK @@ -207,6 +210,9 @@ int main(int argc, char *argv[]) ShowMessage("Connected to %s!", Mpd->GetHostname().c_str()); MessagesAllowed = 0; UpdateStatusImmediately = 1; +# ifdef ENABLE_OUTPUTS + myOutputs->FetchList(); +# endif // ENABLE_OUTPUTS } } @@ -1881,6 +1887,12 @@ int main(int argc, char *argv[]) myTagEditor->SwitchTo(); } # endif // HAVE_TAGLIB_H +# ifdef ENABLE_OUTPUTS + else if (Keypressed(input, Key.Outputs)) + { + myOutputs->SwitchTo(); + } +# endif // ENABLE_OUTPUTS # ifdef ENABLE_CLOCK else if (Keypressed(input, Key.Clock)) { diff --git a/src/outputs.cpp b/src/outputs.cpp new file mode 100644 index 00000000..e832088d --- /dev/null +++ b/src/outputs.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** + * Copyright (C) 2008-2009 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 "outputs.h" + +#ifdef ENABLE_OUTPUTS + +#include "display.h" +#include "global.h" + +using namespace Global; + +Outputs *myOutputs = new Outputs; + +void Outputs::Init() +{ + w = new Menu(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone); + w->SetTimeout(ncmpcpp_window_timeout); + w->CyclicScrolling(Config.use_cyclic_scrolling); + w->HighlightColor(Config.main_highlight_color); + w->SetItemDisplayer(Display::Pairs); + + FetchList(); +} + +void Outputs::SwitchTo() +{ + if (myScreen == this) + return; + + if (hasToBeResized) + Resize(); + + myScreen = this; + w->Window::Clear(); + + RedrawHeader = 1; +} + +void Outputs::Resize() +{ + w->Resize(COLS, MainHeight); + hasToBeResized = 0; +} + +std::string Outputs::Title() +{ + return "Outputs"; +} + +void Outputs::EnterPressed() +{ + if (w->Current().second) + { + if (Mpd->DisableOutput(w->GetPosition())) + ShowMessage("Output \"%s\" disabled", w->Current().first.c_str()); + w->Current().second = 0; + w->BoldOption(w->Choice(), 0); + } + else + { + if (Mpd->EnableOutput(w->GetPosition())) + ShowMessage("Output \"%s\" enabled", w->Current().first.c_str()); + w->Current().second = 1; + w->BoldOption(w->Choice(), 1); + } + +} + +void Outputs::MouseButtonPressed(MEVENT me) +{ + if (w->Empty() || !w->hasCoords(me.x, me.y) || size_t(me.y) >= w->Size()) + return; + if (me.bstate & BUTTON1_PRESSED || me.bstate & BUTTON3_PRESSED) + { + w->Goto(me.y); + if (me.bstate & BUTTON3_PRESSED) + EnterPressed(); + } + else + Screen< Menu >::MouseButtonPressed(me); +} + +void Outputs::FetchList() +{ + MPD::OutputList ol; + Mpd->GetOutputs(ol); + w->Clear(); + for (MPD::OutputList::const_iterator it = ol.begin(); it != ol.end(); it++) + w->AddOption(*it, it->second); +} + +#endif // ENABLE_OUTPUTS + diff --git a/src/outputs.h b/src/outputs.h new file mode 100644 index 00000000..eaf50b5f --- /dev/null +++ b/src/outputs.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2008-2009 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 _OUTPUTS_H +#define _OUTPUTS_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef ENABLE_OUTPUTS + +#include "menu.h" +#include "mpdpp.h" +#include "screen.h" + +class Outputs : public Screen< Menu > +{ + public: + virtual void Init(); + virtual void SwitchTo(); + virtual void Resize(); + + virtual std::string Title(); + + virtual void EnterPressed(); + virtual void SpacePressed() { } + virtual void MouseButtonPressed(MEVENT); + + virtual bool allowsSelection() { return false; } + + virtual List *GetList() { return w; } + + void FetchList(); +}; + +extern Outputs *myOutputs; + +#endif // ENABLE_OUTPUTS + +#endif + diff --git a/src/settings.cpp b/src/settings.cpp index ad0e7844..fe91ac22 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -109,6 +109,7 @@ void DefaultKeys(ncmpcpp_keys &keys) keys.MediaLibrary[0] = '5'; keys.PlaylistEditor[0] = '6'; keys.TagEditor[0] = '7'; + keys.Outputs[0] = '8'; keys.Clock[0] = '0'; keys.Stop[0] = 's'; keys.Pause[0] = 'P'; @@ -176,6 +177,7 @@ void DefaultKeys(ncmpcpp_keys &keys) keys.MediaLibrary[1] = 269; keys.PlaylistEditor[1] = 270; keys.TagEditor[1] = 271; + keys.Outputs[1] = 272; keys.Clock[1] = 274; keys.Stop[1] = null_key; keys.Pause[1] = null_key; @@ -343,6 +345,8 @@ void ReadKeys(ncmpcpp_keys &keys) GetKeys(key, keys.PlaylistEditor); else if (key.find("key_tag_editor ") != string::npos) GetKeys(key, keys.TagEditor); + else if (key.find("key_outputs ") != string::npos) + GetKeys(key, keys.Outputs); else if (key.find("key_clock ") != string::npos) GetKeys(key, keys.Clock); else if (key.find("key_stop ") != string::npos) diff --git a/src/settings.h b/src/settings.h index f22f22be..dc6d279e 100644 --- a/src/settings.h +++ b/src/settings.h @@ -57,6 +57,7 @@ struct ncmpcpp_keys int MediaLibrary[2]; int PlaylistEditor[2]; int TagEditor[2]; + int Outputs[2]; int Clock[2]; int Stop[2]; int Pause[2];