poll both stdin and mpd using one select()
this allows for immediate reading mpd events
This commit is contained in:
@@ -53,7 +53,6 @@ void Browser::Init()
|
|||||||
{
|
{
|
||||||
w = new Menu<Item>(0, MainStartY, COLS, MainHeight, Config.columns_in_browser ? Display::Columns() : "", Config.main_color, brNone);
|
w = new Menu<Item>(0, MainStartY, COLS, MainHeight, Config.columns_in_browser ? Display::Columns() : "", Config.main_color, brNone);
|
||||||
w->HighlightColor(Config.main_highlight_color);
|
w->HighlightColor(Config.main_highlight_color);
|
||||||
w->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
w->CyclicScrolling(Config.use_cyclic_scrolling);
|
w->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
w->SetSelectPrefix(&Config.selected_item_prefix);
|
w->SetSelectPrefix(&Config.selected_item_prefix);
|
||||||
w->SetSelectSuffix(&Config.selected_item_suffix);
|
w->SetSelectSuffix(&Config.selected_item_suffix);
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ void Clock::Init()
|
|||||||
Width = Config.clock_display_seconds ? 60 : 40;
|
Width = Config.clock_display_seconds ? 60 : 40;
|
||||||
|
|
||||||
w = new Window((COLS-Width)/2, (MainHeight-Height)/2+MainStartY, Width, Height-1, "", Config.main_color, Border(Config.main_color));
|
w = new Window((COLS-Width)/2, (MainHeight-Height)/2+MainStartY, Width, Height-1, "", Config.main_color, Border(Config.main_color));
|
||||||
w->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
isInitialized = 1;
|
isInitialized = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ Help *myHelp = new Help;
|
|||||||
void Help::Init()
|
void Help::Init()
|
||||||
{
|
{
|
||||||
w = new Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
w = new Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
||||||
w->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
GetKeybindings();
|
GetKeybindings();
|
||||||
w->Flush();
|
w->Flush();
|
||||||
isInitialized = 1;
|
isInitialized = 1;
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ const Info::Metadata Info::Tags[] =
|
|||||||
void Info::Init()
|
void Info::Init()
|
||||||
{
|
{
|
||||||
w = new Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
w = new Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
||||||
w->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
isInitialized = 1;
|
isInitialized = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ Lyrics *myLyrics = new Lyrics;
|
|||||||
void Lyrics::Init()
|
void Lyrics::Init()
|
||||||
{
|
{
|
||||||
w = new Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
w = new Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
||||||
w->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
isInitialized = 1;
|
isInitialized = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,20 +52,17 @@ void MediaLibrary::Init()
|
|||||||
|
|
||||||
Artists = new Menu<std::string>(0, MainStartY, itsLeftColWidth, MainHeight, IntoStr(Config.media_lib_primary_tag) + "s", Config.main_color, brNone);
|
Artists = new Menu<std::string>(0, MainStartY, itsLeftColWidth, MainHeight, IntoStr(Config.media_lib_primary_tag) + "s", Config.main_color, brNone);
|
||||||
Artists->HighlightColor(Config.active_column_color);
|
Artists->HighlightColor(Config.active_column_color);
|
||||||
Artists->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
Artists->CyclicScrolling(Config.use_cyclic_scrolling);
|
Artists->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
Artists->SetItemDisplayer(Display::Generic);
|
Artists->SetItemDisplayer(Display::Generic);
|
||||||
|
|
||||||
Albums = new Menu< std::pair<std::string, SearchConstraints> >(itsMiddleColStartX, MainStartY, itsMiddleColWidth, MainHeight, "Albums", Config.main_color, brNone);
|
Albums = new Menu< std::pair<std::string, SearchConstraints> >(itsMiddleColStartX, MainStartY, itsMiddleColWidth, MainHeight, "Albums", Config.main_color, brNone);
|
||||||
Albums->HighlightColor(Config.main_highlight_color);
|
Albums->HighlightColor(Config.main_highlight_color);
|
||||||
Albums->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
Albums->CyclicScrolling(Config.use_cyclic_scrolling);
|
Albums->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
Albums->SetItemDisplayer(Display::Pairs);
|
Albums->SetItemDisplayer(Display::Pairs);
|
||||||
Albums->SetGetStringFunction(StringPairToString);
|
Albums->SetGetStringFunction(StringPairToString);
|
||||||
|
|
||||||
Songs = new Menu<Song>(itsRightColStartX, MainStartY, itsRightColWidth, MainHeight, "Songs", Config.main_color, brNone);
|
Songs = new Menu<Song>(itsRightColStartX, MainStartY, itsRightColWidth, MainHeight, "Songs", Config.main_color, brNone);
|
||||||
Songs->HighlightColor(Config.main_highlight_color);
|
Songs->HighlightColor(Config.main_highlight_color);
|
||||||
Songs->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
Songs->CyclicScrolling(Config.use_cyclic_scrolling);
|
Songs->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
Songs->SetSelectPrefix(&Config.selected_item_prefix);
|
Songs->SetSelectPrefix(&Config.selected_item_prefix);
|
||||||
Songs->SetSelectSuffix(&Config.selected_item_suffix);
|
Songs->SetSelectSuffix(&Config.selected_item_suffix);
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ void SelectedItemsAdder::Init()
|
|||||||
{
|
{
|
||||||
SetDimensions();
|
SetDimensions();
|
||||||
w = new Menu<std::string>((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY, itsWidth, itsHeight, "Add selected items to...", Config.main_color, Config.window_border);
|
w = new Menu<std::string>((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY, itsWidth, itsHeight, "Add selected items to...", Config.main_color, Config.window_border);
|
||||||
w->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
w->CyclicScrolling(Config.use_cyclic_scrolling);
|
w->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
w->HighlightColor(Config.main_highlight_color);
|
w->HighlightColor(Config.main_highlight_color);
|
||||||
w->SetItemDisplayer(Display::Generic);
|
w->SetItemDisplayer(Display::Generic);
|
||||||
|
|||||||
@@ -151,14 +151,14 @@ void Connection::GoIdle()
|
|||||||
isIdle = 1;
|
isIdle = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpd_idle Connection::GoBusy()
|
int Connection::GoBusy()
|
||||||
{
|
{
|
||||||
if (isIdle && mpd_send_noidle(itsConnection))
|
if (isIdle && mpd_send_noidle(itsConnection))
|
||||||
{
|
{
|
||||||
isIdle = 0;
|
isIdle = 0;
|
||||||
return mpd_recv_idle(itsConnection, 1);
|
return mpd_recv_idle(itsConnection, 1);
|
||||||
}
|
}
|
||||||
return mpd_idle(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::UpdateStatus()
|
void Connection::UpdateStatus()
|
||||||
@@ -166,13 +166,14 @@ void Connection::UpdateStatus()
|
|||||||
if (!itsConnection)
|
if (!itsConnection)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
int idle_mask = 0;
|
||||||
if (isIdle)
|
if (isIdle)
|
||||||
{
|
{
|
||||||
FD_ZERO(&itsPoll);
|
if (hasData)
|
||||||
FD_SET(itsFD, &itsPoll);
|
{
|
||||||
timeval timeout = { 0, 0 };
|
idle_mask = GoBusy();
|
||||||
if (select(itsFD+1, &itsPoll, 0, 0, &timeout) == 1)
|
hasData = 0;
|
||||||
GoBusy();
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// count local elapsed time as we don't receive
|
// count local elapsed time as we don't receive
|
||||||
@@ -217,14 +218,6 @@ void Connection::UpdateStatus()
|
|||||||
{
|
{
|
||||||
// sync local elapsed time counter with mpd
|
// sync local elapsed time counter with mpd
|
||||||
itsElapsed = mpd_status_get_elapsed_time(itsCurrentStatus);
|
itsElapsed = mpd_status_get_elapsed_time(itsCurrentStatus);
|
||||||
// little hack as it seems mpd doesn't always return elapsed
|
|
||||||
// time equal to 0 even if song has changed, it sometimes
|
|
||||||
// returns the last second, so we need to bypass it by zeroing
|
|
||||||
// it in this case.
|
|
||||||
// NOTICE: it seems polling with select() instead of poll()
|
|
||||||
// fixes this, but that can just be more randomness.
|
|
||||||
//if (itsElapsed == mpd_status_get_total_time(itsCurrentStatus))
|
|
||||||
// itsElapsed = 0;
|
|
||||||
time(&itsElapsedTimer[0]);
|
time(&itsElapsedTimer[0]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -274,7 +267,12 @@ void Connection::UpdateStatus()
|
|||||||
itsChanges.StatusFlags = itsChanges.Repeat || itsChanges.Random || itsChanges.Single || itsChanges.Consume || itsChanges.Crossfade || itsChanges.DBUpdating;
|
itsChanges.StatusFlags = itsChanges.Repeat || itsChanges.Random || itsChanges.Single || itsChanges.Consume || itsChanges.Crossfade || itsChanges.DBUpdating;
|
||||||
}
|
}
|
||||||
itsUpdater(this, itsChanges, itsErrorHandlerUserdata);
|
itsUpdater(this, itsChanges, itsErrorHandlerUserdata);
|
||||||
GoIdle();
|
// below conditionals are a hack to workaround mpd bug 2608/2612
|
||||||
|
// by fetching another status with correct values after a while
|
||||||
|
if (!((idle_mask & MPD_IDLE_PLAYER) && !itsChanges.PlayerState))
|
||||||
|
GoIdle();
|
||||||
|
else if (supportsIdle && !isIdle)
|
||||||
|
OrderDataFetching();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
13
src/mpdpp.h
13
src/mpdpp.h
@@ -21,12 +21,6 @@
|
|||||||
#ifndef _MPDPP_H
|
#ifndef _MPDPP_H
|
||||||
#define _MPDPP_H
|
#define _MPDPP_H
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
# include <winsock.h>
|
|
||||||
#else
|
|
||||||
# include <sys/select.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <mpd/client.h>
|
#include <mpd/client.h>
|
||||||
@@ -98,7 +92,10 @@ namespace MPD
|
|||||||
int GetPort() { return itsPort; }
|
int GetPort() { return itsPort; }
|
||||||
|
|
||||||
float Version() const;
|
float Version() const;
|
||||||
|
|
||||||
bool SupportsIdle() const { return supportsIdle; }
|
bool SupportsIdle() const { return supportsIdle; }
|
||||||
|
void OrderDataFetching() { hasData = 1; }
|
||||||
|
int GetFD() const { return itsFD; }
|
||||||
|
|
||||||
void SetHostname(const std::string &);
|
void SetHostname(const std::string &);
|
||||||
void SetPort(int port) { itsPort = port; }
|
void SetPort(int port) { itsPort = port; }
|
||||||
@@ -213,7 +210,7 @@ namespace MPD
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void GoIdle();
|
void GoIdle();
|
||||||
mpd_idle GoBusy();
|
int GoBusy();
|
||||||
|
|
||||||
int CheckForErrors();
|
int CheckForErrors();
|
||||||
|
|
||||||
@@ -224,10 +221,10 @@ namespace MPD
|
|||||||
int itsErrorCode;
|
int itsErrorCode;
|
||||||
size_t itsMaxPlaylistLength;
|
size_t itsMaxPlaylistLength;
|
||||||
|
|
||||||
fd_set itsPoll;
|
|
||||||
int itsFD;
|
int itsFD;
|
||||||
bool isIdle;
|
bool isIdle;
|
||||||
bool supportsIdle;
|
bool supportsIdle;
|
||||||
|
bool hasData;
|
||||||
|
|
||||||
std::string itsHost;
|
std::string itsHost;
|
||||||
int itsPort;
|
int itsPort;
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ int main(int argc, char *argv[])
|
|||||||
wFooter = new Window(0, footer_start_y, COLS, footer_height, "", Config.statusbar_color, brNone);
|
wFooter = new Window(0, footer_start_y, COLS, footer_height, "", Config.statusbar_color, brNone);
|
||||||
wFooter->SetTimeout(ncmpcpp_window_timeout);
|
wFooter->SetTimeout(ncmpcpp_window_timeout);
|
||||||
wFooter->SetGetStringHelper(StatusbarGetStringHelper);
|
wFooter->SetGetStringHelper(StatusbarGetStringHelper);
|
||||||
|
wFooter->AddFDCallback(Mpd.GetFD(), StatusbarMPDCallback);
|
||||||
wFooter->CreateHistory();
|
wFooter->CreateHistory();
|
||||||
|
|
||||||
myPlaylist->SwitchTo();
|
myPlaylist->SwitchTo();
|
||||||
@@ -201,10 +202,13 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
if (!Mpd.Connected())
|
if (!Mpd.Connected())
|
||||||
{
|
{
|
||||||
|
if (!wFooter->FDCallbacksListEmpty())
|
||||||
|
wFooter->ClearFDCallbacksList();
|
||||||
ShowMessage("Attempting to reconnect...");
|
ShowMessage("Attempting to reconnect...");
|
||||||
if (Mpd.Connect())
|
if (Mpd.Connect())
|
||||||
{
|
{
|
||||||
ShowMessage("Connected to %s!", Mpd.GetHostname().c_str());
|
ShowMessage("Connected to %s!", Mpd.GetHostname().c_str());
|
||||||
|
wFooter->AddFDCallback(Mpd.GetFD(), StatusbarMPDCallback);
|
||||||
MessagesAllowed = 0;
|
MessagesAllowed = 0;
|
||||||
UpdateStatusImmediately = 1;
|
UpdateStatusImmediately = 1;
|
||||||
# ifdef ENABLE_OUTPUTS
|
# ifdef ENABLE_OUTPUTS
|
||||||
@@ -289,7 +293,7 @@ int main(int argc, char *argv[])
|
|||||||
myScreen->Update();
|
myScreen->Update();
|
||||||
if (input != ERR)
|
if (input != ERR)
|
||||||
myScreen->RefreshWindow();
|
myScreen->RefreshWindow();
|
||||||
myScreen->ReadKey(input);
|
wFooter->ReadKey(input);
|
||||||
|
|
||||||
if (input == ERR)
|
if (input == ERR)
|
||||||
continue;
|
continue;
|
||||||
@@ -567,7 +571,7 @@ int main(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Playlist::BlockNowPlayingUpdate = 1;
|
Playlist::BlockNowPlayingUpdate = 1;
|
||||||
myPlaylist->Items->SetTimeout(50);
|
wFooter->SetTimeout(50);
|
||||||
int del_counter = 0;
|
int del_counter = 0;
|
||||||
while (!myPlaylist->Items->Empty() && Keypressed(input, Key.Delete))
|
while (!myPlaylist->Items->Empty() && Keypressed(input, Key.Delete))
|
||||||
{
|
{
|
||||||
@@ -581,11 +585,11 @@ int main(int argc, char *argv[])
|
|||||||
Mpd.DeleteID(myPlaylist->CurrentSong()->GetID());
|
Mpd.DeleteID(myPlaylist->CurrentSong()->GetID());
|
||||||
myPlaylist->Items->DeleteOption(id);
|
myPlaylist->Items->DeleteOption(id);
|
||||||
myPlaylist->Items->Refresh();
|
myPlaylist->Items->Refresh();
|
||||||
myPlaylist->Items->ReadKey(input);
|
wFooter->ReadKey(input);
|
||||||
++del_counter;
|
++del_counter;
|
||||||
}
|
}
|
||||||
myPlaylist->FixPositions(myPlaylist->Items->Choice());
|
myPlaylist->FixPositions(myPlaylist->Items->Choice());
|
||||||
myPlaylist->Items->SetTimeout(ncmpcpp_window_timeout);
|
wFooter->SetTimeout(ncmpcpp_window_timeout);
|
||||||
Playlist::BlockNowPlayingUpdate = 0;
|
Playlist::BlockNowPlayingUpdate = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -703,7 +707,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myPlaylistEditor->Content->SetTimeout(50);
|
wFooter->SetTimeout(50);
|
||||||
locale_to_utf(myPlaylistEditor->Playlists->Current());
|
locale_to_utf(myPlaylistEditor->Playlists->Current());
|
||||||
while (!myPlaylistEditor->Content->Empty() && Keypressed(input, Key.Delete))
|
while (!myPlaylistEditor->Content->Empty() && Keypressed(input, Key.Delete))
|
||||||
{
|
{
|
||||||
@@ -712,10 +716,10 @@ int main(int argc, char *argv[])
|
|||||||
Mpd.Delete(myPlaylistEditor->Playlists->Current(), myPlaylistEditor->Content->Choice());
|
Mpd.Delete(myPlaylistEditor->Playlists->Current(), myPlaylistEditor->Content->Choice());
|
||||||
myPlaylistEditor->Content->DeleteOption(myPlaylistEditor->Content->Choice());
|
myPlaylistEditor->Content->DeleteOption(myPlaylistEditor->Content->Choice());
|
||||||
myPlaylistEditor->Content->Refresh();
|
myPlaylistEditor->Content->Refresh();
|
||||||
myPlaylistEditor->Content->ReadKey(input);
|
wFooter->ReadKey(input);
|
||||||
}
|
}
|
||||||
utf_to_locale(myPlaylistEditor->Playlists->Current());
|
utf_to_locale(myPlaylistEditor->Playlists->Current());
|
||||||
myPlaylistEditor->Content->SetTimeout(ncmpcpp_window_timeout);
|
wFooter->SetTimeout(ncmpcpp_window_timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -808,7 +812,7 @@ int main(int argc, char *argv[])
|
|||||||
else if (myScreen == myPlaylist && !myPlaylist->Items->Empty())
|
else if (myScreen == myPlaylist && !myPlaylist->Items->Empty())
|
||||||
{
|
{
|
||||||
CHECK_PLAYLIST_FOR_FILTERING;
|
CHECK_PLAYLIST_FOR_FILTERING;
|
||||||
myPlaylist->Items->SetTimeout(50);
|
wFooter->SetTimeout(50);
|
||||||
if (myPlaylist->Items->hasSelected())
|
if (myPlaylist->Items->hasSelected())
|
||||||
{
|
{
|
||||||
std::vector<size_t> list;
|
std::vector<size_t> list;
|
||||||
@@ -848,7 +852,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
myPlaylist->Items->Highlight(list[(list.size()-1)/2]);
|
myPlaylist->Items->Highlight(list[(list.size()-1)/2]);
|
||||||
myPlaylist->Items->Refresh();
|
myPlaylist->Items->Refresh();
|
||||||
myPlaylist->Items->ReadKey(input);
|
wFooter->ReadKey(input);
|
||||||
}
|
}
|
||||||
Playlist::BlockNowPlayingUpdate = 0;
|
Playlist::BlockNowPlayingUpdate = 0;
|
||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
@@ -876,17 +880,17 @@ int main(int argc, char *argv[])
|
|||||||
myPlaylist->Items->Swap(to, to+1);
|
myPlaylist->Items->Swap(to, to+1);
|
||||||
myPlaylist->Items->Scroll(wUp);
|
myPlaylist->Items->Scroll(wUp);
|
||||||
myPlaylist->Items->Refresh();
|
myPlaylist->Items->Refresh();
|
||||||
myPlaylist->Items->ReadKey(input);
|
wFooter->ReadKey(input);
|
||||||
}
|
}
|
||||||
Mpd.Move(from, to);
|
Mpd.Move(from, to);
|
||||||
Playlist::BlockNowPlayingUpdate = 0;
|
Playlist::BlockNowPlayingUpdate = 0;
|
||||||
UpdateStatusImmediately = 1;
|
UpdateStatusImmediately = 1;
|
||||||
}
|
}
|
||||||
myPlaylist->Items->SetTimeout(ncmpcpp_window_timeout);
|
wFooter->SetTimeout(ncmpcpp_window_timeout);
|
||||||
}
|
}
|
||||||
else if (myScreen->ActiveWindow() == myPlaylistEditor->Content && !myPlaylistEditor->Content->Empty())
|
else if (myScreen->ActiveWindow() == myPlaylistEditor->Content && !myPlaylistEditor->Content->Empty())
|
||||||
{
|
{
|
||||||
myPlaylistEditor->Content->SetTimeout(50);
|
wFooter->SetTimeout(50);
|
||||||
if (myPlaylistEditor->Content->hasSelected())
|
if (myPlaylistEditor->Content->hasSelected())
|
||||||
{
|
{
|
||||||
std::vector<size_t> list;
|
std::vector<size_t> list;
|
||||||
@@ -905,7 +909,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
myPlaylistEditor->Content->Highlight(list[(list.size()-1)/2]);
|
myPlaylistEditor->Content->Highlight(list[(list.size()-1)/2]);
|
||||||
myPlaylistEditor->Content->Refresh();
|
myPlaylistEditor->Content->Refresh();
|
||||||
myPlaylistEditor->Content->ReadKey(input);
|
wFooter->ReadKey(input);
|
||||||
}
|
}
|
||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
for (size_t i = 0; i < list.size(); ++i)
|
for (size_t i = 0; i < list.size(); ++i)
|
||||||
@@ -925,12 +929,12 @@ int main(int argc, char *argv[])
|
|||||||
myPlaylistEditor->Content->Swap(to, to+1);
|
myPlaylistEditor->Content->Swap(to, to+1);
|
||||||
myPlaylistEditor->Content->Scroll(wUp);
|
myPlaylistEditor->Content->Scroll(wUp);
|
||||||
myPlaylistEditor->Content->Refresh();
|
myPlaylistEditor->Content->Refresh();
|
||||||
myPlaylistEditor->Content->ReadKey(input);
|
wFooter->ReadKey(input);
|
||||||
}
|
}
|
||||||
if (from != to)
|
if (from != to)
|
||||||
Mpd.Move(myPlaylistEditor->Playlists->Current(), from, to);
|
Mpd.Move(myPlaylistEditor->Playlists->Current(), from, to);
|
||||||
}
|
}
|
||||||
myPlaylistEditor->Content->SetTimeout(ncmpcpp_window_timeout);
|
wFooter->SetTimeout(ncmpcpp_window_timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Keypressed(input, Key.MvSongDown))
|
else if (Keypressed(input, Key.MvSongDown))
|
||||||
@@ -940,7 +944,7 @@ int main(int argc, char *argv[])
|
|||||||
else if (myScreen == myPlaylist && !myPlaylist->Items->Empty())
|
else if (myScreen == myPlaylist && !myPlaylist->Items->Empty())
|
||||||
{
|
{
|
||||||
CHECK_PLAYLIST_FOR_FILTERING;
|
CHECK_PLAYLIST_FOR_FILTERING;
|
||||||
myPlaylist->Items->SetTimeout(50);
|
wFooter->SetTimeout(50);
|
||||||
if (myPlaylist->Items->hasSelected())
|
if (myPlaylist->Items->hasSelected())
|
||||||
{
|
{
|
||||||
std::vector<size_t> list;
|
std::vector<size_t> list;
|
||||||
@@ -974,7 +978,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
myPlaylist->Items->Highlight(list[(list.size()-1)/2]);
|
myPlaylist->Items->Highlight(list[(list.size()-1)/2]);
|
||||||
myPlaylist->Items->Refresh();
|
myPlaylist->Items->Refresh();
|
||||||
myPlaylist->Items->ReadKey(input);
|
wFooter->ReadKey(input);
|
||||||
}
|
}
|
||||||
Playlist::BlockNowPlayingUpdate = 0;
|
Playlist::BlockNowPlayingUpdate = 0;
|
||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
@@ -1002,18 +1006,18 @@ int main(int argc, char *argv[])
|
|||||||
myPlaylist->Items->Swap(to, to-1);
|
myPlaylist->Items->Swap(to, to-1);
|
||||||
myPlaylist->Items->Scroll(wDown);
|
myPlaylist->Items->Scroll(wDown);
|
||||||
myPlaylist->Items->Refresh();
|
myPlaylist->Items->Refresh();
|
||||||
myPlaylist->Items->ReadKey(input);
|
wFooter->ReadKey(input);
|
||||||
}
|
}
|
||||||
Mpd.Move(from, to);
|
Mpd.Move(from, to);
|
||||||
Playlist::BlockNowPlayingUpdate = 0;
|
Playlist::BlockNowPlayingUpdate = 0;
|
||||||
UpdateStatusImmediately = 1;
|
UpdateStatusImmediately = 1;
|
||||||
}
|
}
|
||||||
myPlaylist->Items->SetTimeout(ncmpcpp_window_timeout);
|
wFooter->SetTimeout(ncmpcpp_window_timeout);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (myScreen->ActiveWindow() == myPlaylistEditor->Content && !myPlaylistEditor->Content->Empty())
|
else if (myScreen->ActiveWindow() == myPlaylistEditor->Content && !myPlaylistEditor->Content->Empty())
|
||||||
{
|
{
|
||||||
myPlaylistEditor->Content->SetTimeout(50);
|
wFooter->SetTimeout(50);
|
||||||
if (myPlaylistEditor->Content->hasSelected())
|
if (myPlaylistEditor->Content->hasSelected())
|
||||||
{
|
{
|
||||||
std::vector<size_t> list;
|
std::vector<size_t> list;
|
||||||
@@ -1032,7 +1036,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
myPlaylistEditor->Content->Highlight(list[(list.size()-1)/2]);
|
myPlaylistEditor->Content->Highlight(list[(list.size()-1)/2]);
|
||||||
myPlaylistEditor->Content->Refresh();
|
myPlaylistEditor->Content->Refresh();
|
||||||
myPlaylistEditor->Content->ReadKey(input);
|
wFooter->ReadKey(input);
|
||||||
}
|
}
|
||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
for (int i = list.size()-1; i >= 0; --i)
|
for (int i = list.size()-1; i >= 0; --i)
|
||||||
@@ -1052,12 +1056,12 @@ int main(int argc, char *argv[])
|
|||||||
myPlaylistEditor->Content->Swap(to, to-1);
|
myPlaylistEditor->Content->Swap(to, to-1);
|
||||||
myPlaylistEditor->Content->Scroll(wDown);
|
myPlaylistEditor->Content->Scroll(wDown);
|
||||||
myPlaylistEditor->Content->Refresh();
|
myPlaylistEditor->Content->Refresh();
|
||||||
myPlaylistEditor->Content->ReadKey(input);
|
wFooter->ReadKey(input);
|
||||||
}
|
}
|
||||||
if (from != to)
|
if (from != to)
|
||||||
Mpd.Move(myPlaylistEditor->Playlists->Current(), from, to);
|
Mpd.Move(myPlaylistEditor->Playlists->Current(), from, to);
|
||||||
}
|
}
|
||||||
myPlaylistEditor->Content->SetTimeout(ncmpcpp_window_timeout);
|
wFooter->SetTimeout(ncmpcpp_window_timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Keypressed(input, Key.MoveTo) && myScreen == myPlaylist)
|
else if (Keypressed(input, Key.MoveTo) && myScreen == myPlaylist)
|
||||||
@@ -1148,7 +1152,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
TraceMpdStatus();
|
TraceMpdStatus();
|
||||||
myPlaylist->UpdateTimer();
|
myPlaylist->UpdateTimer();
|
||||||
myPlaylist->Items->ReadKey(input);
|
wFooter->ReadKey(input);
|
||||||
|
|
||||||
int howmuch = Config.incremental_seeking ? (myPlaylist->Timer()-t)/2+Config.seek_time : Config.seek_time;
|
int howmuch = Config.incremental_seeking ? (myPlaylist->Timer()-t)/2+Config.seek_time : Config.seek_time;
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ using namespace NCurses;
|
|||||||
|
|
||||||
typedef std::pair<std::string, std::string> string_pair;
|
typedef std::pair<std::string, std::string> string_pair;
|
||||||
|
|
||||||
const int ncmpcpp_window_timeout = 100;
|
const int ncmpcpp_window_timeout = 500;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ Outputs *myOutputs = new Outputs;
|
|||||||
void Outputs::Init()
|
void Outputs::Init()
|
||||||
{
|
{
|
||||||
w = new Menu<MPD::Output>(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
w = new Menu<MPD::Output>(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
||||||
w->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
w->CyclicScrolling(Config.use_cyclic_scrolling);
|
w->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
w->HighlightColor(Config.main_highlight_color);
|
w->HighlightColor(Config.main_highlight_color);
|
||||||
w->SetItemDisplayer(Display::Pairs);
|
w->SetItemDisplayer(Display::Pairs);
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ Menu< std::pair<std::string, MPD::Song::GetFunction> > *Playlist::SortDialog = 0
|
|||||||
void Playlist::Init()
|
void Playlist::Init()
|
||||||
{
|
{
|
||||||
Items = new Menu<MPD::Song>(0, MainStartY, COLS, MainHeight, Config.columns_in_playlist ? Display::Columns() : "", Config.main_color, brNone);
|
Items = new Menu<MPD::Song>(0, MainStartY, COLS, MainHeight, Config.columns_in_playlist ? Display::Columns() : "", Config.main_color, brNone);
|
||||||
Items->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
Items->CyclicScrolling(Config.use_cyclic_scrolling);
|
Items->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
Items->HighlightColor(Config.main_highlight_color);
|
Items->HighlightColor(Config.main_highlight_color);
|
||||||
Items->SetSelectPrefix(&Config.selected_item_prefix);
|
Items->SetSelectPrefix(&Config.selected_item_prefix);
|
||||||
@@ -62,7 +61,6 @@ void Playlist::Init()
|
|||||||
SortDialogHeight = std::min(int(MainHeight), 18);
|
SortDialogHeight = std::min(int(MainHeight), 18);
|
||||||
|
|
||||||
SortDialog = new Menu< std::pair<std::string, MPD::Song::GetFunction> >((COLS-SortDialogWidth)/2, (MainHeight-SortDialogHeight)/2+MainStartY, SortDialogWidth, SortDialogHeight, "Sort songs by...", Config.main_color, Config.window_border);
|
SortDialog = new Menu< std::pair<std::string, MPD::Song::GetFunction> >((COLS-SortDialogWidth)/2, (MainHeight-SortDialogHeight)/2+MainStartY, SortDialogWidth, SortDialogHeight, "Sort songs by...", Config.main_color, Config.window_border);
|
||||||
SortDialog->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
SortDialog->CyclicScrolling(Config.use_cyclic_scrolling);
|
SortDialog->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
SortDialog->SetItemDisplayer(Display::Pairs);
|
SortDialog->SetItemDisplayer(Display::Pairs);
|
||||||
|
|
||||||
|
|||||||
@@ -47,13 +47,11 @@ void PlaylistEditor::Init()
|
|||||||
|
|
||||||
Playlists = new Menu<std::string>(0, MainStartY, LeftColumnWidth, MainHeight, "Playlists", Config.main_color, brNone);
|
Playlists = new Menu<std::string>(0, MainStartY, LeftColumnWidth, MainHeight, "Playlists", Config.main_color, brNone);
|
||||||
Playlists->HighlightColor(Config.active_column_color);
|
Playlists->HighlightColor(Config.active_column_color);
|
||||||
Playlists->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
Playlists->CyclicScrolling(Config.use_cyclic_scrolling);
|
Playlists->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
Playlists->SetItemDisplayer(Display::Generic);
|
Playlists->SetItemDisplayer(Display::Generic);
|
||||||
|
|
||||||
Content = new Menu<Song>(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, "Playlist's content", Config.main_color, brNone);
|
Content = new Menu<Song>(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, "Playlist's content", Config.main_color, brNone);
|
||||||
Content->HighlightColor(Config.main_highlight_color);
|
Content->HighlightColor(Config.main_highlight_color);
|
||||||
Content->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
Content->CyclicScrolling(Config.use_cyclic_scrolling);
|
Content->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
Content->SetSelectPrefix(&Config.selected_item_prefix);
|
Content->SetSelectPrefix(&Config.selected_item_prefix);
|
||||||
Content->SetSelectSuffix(&Config.selected_item_suffix);
|
Content->SetSelectSuffix(&Config.selected_item_suffix);
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ void SearchEngine::Init()
|
|||||||
{
|
{
|
||||||
w = new Menu< std::pair<Buffer *, Song *> >(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
w = new Menu< std::pair<Buffer *, Song *> >(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
||||||
w->HighlightColor(Config.main_highlight_color);
|
w->HighlightColor(Config.main_highlight_color);
|
||||||
w->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
w->CyclicScrolling(Config.use_cyclic_scrolling);
|
w->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
w->SetItemDisplayer(Display::SearchEngine);
|
w->SetItemDisplayer(Display::SearchEngine);
|
||||||
w->SetSelectPrefix(&Config.selected_item_prefix);
|
w->SetSelectPrefix(&Config.selected_item_prefix);
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ void ServerInfo::Init()
|
|||||||
{
|
{
|
||||||
SetDimensions();
|
SetDimensions();
|
||||||
w = new Scrollpad((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY, itsWidth, itsHeight, "MPD server info", Config.main_color, Config.window_border);
|
w = new Scrollpad((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY, itsWidth, itsHeight, "MPD server info", Config.main_color, Config.window_border);
|
||||||
w->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
|
|
||||||
Mpd.GetURLHandlers(itsURLHandlers);
|
Mpd.GetURLHandlers(itsURLHandlers);
|
||||||
Mpd.GetTagTypes(itsTagTypes);
|
Mpd.GetTagTypes(itsTagTypes);
|
||||||
|
|||||||
@@ -63,6 +63,11 @@ void WindowTitle(const std::string &status)
|
|||||||
}
|
}
|
||||||
#endif // !USE_PDCURSES
|
#endif // !USE_PDCURSES
|
||||||
|
|
||||||
|
void StatusbarMPDCallback()
|
||||||
|
{
|
||||||
|
Mpd.OrderDataFetching();
|
||||||
|
}
|
||||||
|
|
||||||
void StatusbarGetStringHelper(const std::wstring &)
|
void StatusbarGetStringHelper(const std::wstring &)
|
||||||
{
|
{
|
||||||
TraceMpdStatus();
|
TraceMpdStatus();
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ Window &Statusbar();
|
|||||||
void DrawProgressbar(unsigned elapsed, unsigned time);
|
void DrawProgressbar(unsigned elapsed, unsigned time);
|
||||||
void ShowMessage(const char *, ...) GNUC_PRINTF(1, 2);
|
void ShowMessage(const char *, ...) GNUC_PRINTF(1, 2);
|
||||||
|
|
||||||
|
void StatusbarMPDCallback();
|
||||||
void StatusbarGetStringHelper(const std::wstring &);
|
void StatusbarGetStringHelper(const std::wstring &);
|
||||||
void StatusbarApplyFilterImmediately(const std::wstring &);
|
void StatusbarApplyFilterImmediately(const std::wstring &);
|
||||||
|
|
||||||
|
|||||||
@@ -68,14 +68,12 @@ void TagEditor::Init()
|
|||||||
|
|
||||||
Albums = new Menu<string_pair>(0, MainStartY, LeftColumnWidth, MainHeight, "Albums", Config.main_color, brNone);
|
Albums = new Menu<string_pair>(0, MainStartY, LeftColumnWidth, MainHeight, "Albums", Config.main_color, brNone);
|
||||||
Albums->HighlightColor(Config.active_column_color);
|
Albums->HighlightColor(Config.active_column_color);
|
||||||
Albums->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
Albums->CyclicScrolling(Config.use_cyclic_scrolling);
|
Albums->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
Albums->SetItemDisplayer(Display::Pairs);
|
Albums->SetItemDisplayer(Display::Pairs);
|
||||||
Albums->SetGetStringFunction(StringPairToString);
|
Albums->SetGetStringFunction(StringPairToString);
|
||||||
|
|
||||||
Dirs = new Menu<string_pair>(0, MainStartY, LeftColumnWidth, MainHeight, "Directories", Config.main_color, brNone);
|
Dirs = new Menu<string_pair>(0, MainStartY, LeftColumnWidth, MainHeight, "Directories", Config.main_color, brNone);
|
||||||
Dirs->HighlightColor(Config.active_column_color);
|
Dirs->HighlightColor(Config.active_column_color);
|
||||||
Dirs->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
Dirs->CyclicScrolling(Config.use_cyclic_scrolling);
|
Dirs->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
Dirs->SetItemDisplayer(Display::Pairs);
|
Dirs->SetItemDisplayer(Display::Pairs);
|
||||||
Dirs->SetGetStringFunction(StringPairToString);
|
Dirs->SetGetStringFunction(StringPairToString);
|
||||||
@@ -84,7 +82,6 @@ void TagEditor::Init()
|
|||||||
|
|
||||||
TagTypes = new Menu<std::string>(MiddleColumnStartX, MainStartY, MiddleColumnWidth, MainHeight, "Tag types", Config.main_color, brNone);
|
TagTypes = new Menu<std::string>(MiddleColumnStartX, MainStartY, MiddleColumnWidth, MainHeight, "Tag types", Config.main_color, brNone);
|
||||||
TagTypes->HighlightColor(Config.main_highlight_color);
|
TagTypes->HighlightColor(Config.main_highlight_color);
|
||||||
TagTypes->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
TagTypes->CyclicScrolling(Config.use_cyclic_scrolling);
|
TagTypes->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
TagTypes->SetItemDisplayer(Display::Generic);
|
TagTypes->SetItemDisplayer(Display::Generic);
|
||||||
|
|
||||||
@@ -111,7 +108,6 @@ void TagEditor::Init()
|
|||||||
|
|
||||||
Tags = new Menu<MPD::Song>(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, "Tags", Config.main_color, brNone);
|
Tags = new Menu<MPD::Song>(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, "Tags", Config.main_color, brNone);
|
||||||
Tags->HighlightColor(Config.main_highlight_color);
|
Tags->HighlightColor(Config.main_highlight_color);
|
||||||
Tags->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
Tags->CyclicScrolling(Config.use_cyclic_scrolling);
|
Tags->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
Tags->SetSelectPrefix(&Config.selected_item_prefix);
|
Tags->SetSelectPrefix(&Config.selected_item_prefix);
|
||||||
Tags->SetSelectSuffix(&Config.selected_item_suffix);
|
Tags->SetSelectSuffix(&Config.selected_item_suffix);
|
||||||
@@ -121,7 +117,6 @@ void TagEditor::Init()
|
|||||||
Tags->SetGetStringFunctionUserData(TagTypes);
|
Tags->SetGetStringFunctionUserData(TagTypes);
|
||||||
|
|
||||||
FParserDialog = new Menu<std::string>((COLS-FParserDialogWidth)/2, (MainHeight-FParserDialogHeight)/2+MainStartY, FParserDialogWidth, FParserDialogHeight, "", Config.main_color, Config.window_border);
|
FParserDialog = new Menu<std::string>((COLS-FParserDialogWidth)/2, (MainHeight-FParserDialogHeight)/2+MainStartY, FParserDialogWidth, FParserDialogHeight, "", Config.main_color, Config.window_border);
|
||||||
FParserDialog->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
FParserDialog->CyclicScrolling(Config.use_cyclic_scrolling);
|
FParserDialog->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
FParserDialog->SetItemDisplayer(Display::Generic);
|
FParserDialog->SetItemDisplayer(Display::Generic);
|
||||||
FParserDialog->AddOption("Get tags from filename");
|
FParserDialog->AddOption("Get tags from filename");
|
||||||
@@ -130,15 +125,12 @@ void TagEditor::Init()
|
|||||||
FParserDialog->AddOption("Cancel");
|
FParserDialog->AddOption("Cancel");
|
||||||
|
|
||||||
FParser = new Menu<std::string>((COLS-FParserWidth)/2, (MainHeight-FParserHeight)/2+MainStartY, FParserWidthOne, FParserHeight, "_", Config.main_color, Config.active_window_border);
|
FParser = new Menu<std::string>((COLS-FParserWidth)/2, (MainHeight-FParserHeight)/2+MainStartY, FParserWidthOne, FParserHeight, "_", Config.main_color, Config.active_window_border);
|
||||||
FParser->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
FParser->CyclicScrolling(Config.use_cyclic_scrolling);
|
FParser->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
FParser->SetItemDisplayer(Display::Generic);
|
FParser->SetItemDisplayer(Display::Generic);
|
||||||
|
|
||||||
FParserLegend = new Scrollpad((COLS-FParserWidth)/2+FParserWidthOne, (MainHeight-FParserHeight)/2+MainStartY, FParserWidthTwo, FParserHeight, "Legend", Config.main_color, Config.window_border);
|
FParserLegend = new Scrollpad((COLS-FParserWidth)/2+FParserWidthOne, (MainHeight-FParserHeight)/2+MainStartY, FParserWidthTwo, FParserHeight, "Legend", Config.main_color, Config.window_border);
|
||||||
FParserLegend->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
|
|
||||||
FParserPreview = new Scrollpad((COLS-FParserWidth)/2+FParserWidthOne, (MainHeight-FParserHeight)/2+MainStartY, FParserWidthTwo, FParserHeight, "Preview", Config.main_color, Config.window_border);
|
FParserPreview = new Scrollpad((COLS-FParserWidth)/2+FParserWidthOne, (MainHeight-FParserHeight)/2+MainStartY, FParserWidthTwo, FParserHeight, "Preview", Config.main_color, Config.window_border);
|
||||||
FParserPreview->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
|
|
||||||
w = LeftColumn;
|
w = LeftColumn;
|
||||||
isInitialized = 1;
|
isInitialized = 1;
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ void TinyTagEditor::Init()
|
|||||||
{
|
{
|
||||||
w = new Menu<Buffer>(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
w = new Menu<Buffer>(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
||||||
w->HighlightColor(Config.main_highlight_color);
|
w->HighlightColor(Config.main_highlight_color);
|
||||||
w->SetTimeout(ncmpcpp_window_timeout);
|
|
||||||
w->CyclicScrolling(Config.use_cyclic_scrolling);
|
w->CyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
w->SetItemDisplayer(Display::Generic);
|
w->SetItemDisplayer(Display::Generic);
|
||||||
isInitialized = 1;
|
isInitialized = 1;
|
||||||
|
|||||||
@@ -21,6 +21,12 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
# include <winsock.h>
|
||||||
|
#else
|
||||||
|
# include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
@@ -352,9 +358,63 @@ void Window::SetTimeout(int timeout)
|
|||||||
wtimeout(itsWindow, timeout);
|
wtimeout(itsWindow, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::AddFDCallback(int fd, void (*callback)())
|
||||||
|
{
|
||||||
|
itsFDs.push_back(std::make_pair(fd, callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::ClearFDCallbacksList()
|
||||||
|
{
|
||||||
|
itsFDs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::FDCallbacksListEmpty() const
|
||||||
|
{
|
||||||
|
return itsFDs.empty();
|
||||||
|
}
|
||||||
|
|
||||||
void Window::ReadKey(int &read_key) const
|
void Window::ReadKey(int &read_key) const
|
||||||
{
|
{
|
||||||
|
// 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
|
||||||
|
// other file descriptors and then wait for stdin input with
|
||||||
|
// the given timeout. unfortunately, this results in delays
|
||||||
|
// since ncmpcpp doesn't see that data arrived while waiting
|
||||||
|
// for input from stdin, but it seems there is no better option.
|
||||||
|
|
||||||
|
fd_set fdset;
|
||||||
|
FD_ZERO(&fdset);
|
||||||
|
# if !defined(USE_PDCURSES)
|
||||||
|
FD_SET(STDIN_FILENO, &fdset);
|
||||||
|
timeval timeout = { itsWindowTimeout/1000, (itsWindowTimeout%1000)*1000 };
|
||||||
|
# else
|
||||||
|
timeval timeout = { 0, 0 };
|
||||||
|
# endif
|
||||||
|
|
||||||
|
int fd_max = STDIN_FILENO;
|
||||||
|
for (FDCallbacks::const_iterator it = itsFDs.begin(); it != itsFDs.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->first > fd_max)
|
||||||
|
fd_max = it->first;
|
||||||
|
FD_SET(it->first, &fdset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (select(fd_max+1, &fdset, 0, 0, &timeout) > 0)
|
||||||
|
{
|
||||||
|
# if !defined(USE_PDCURSES)
|
||||||
|
read_key = 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))
|
||||||
|
it->second();
|
||||||
|
}
|
||||||
|
# if !defined(USE_PDCURSES)
|
||||||
|
else
|
||||||
|
read_key = ERR;
|
||||||
|
# else
|
||||||
read_key = wgetch(itsWindow);
|
read_key = wgetch(itsWindow);
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::ReadKey() const
|
void Window::ReadKey() const
|
||||||
@@ -437,7 +497,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);
|
||||||
input = wgetch(itsWindow);
|
ReadKey(input);
|
||||||
|
|
||||||
// these key codes are special and should be ignored
|
// these key codes are special and should be ignored
|
||||||
if ((input < 10 || (input > 10 && input != 21 && input < 32))
|
if ((input < 10 || (input > 10 && input != 21 && input < 32))
|
||||||
|
|||||||
23
src/window.h
23
src/window.h
@@ -343,6 +343,23 @@ namespace NCurses
|
|||||||
///
|
///
|
||||||
virtual void Clear(bool refresh = 1);
|
virtual void Clear(bool refresh = 1);
|
||||||
|
|
||||||
|
/// Adds given file descriptor to the list that will be polled in
|
||||||
|
/// ReadKey() along with stdin and callback that will be invoked
|
||||||
|
/// when there is data waiting for reading in it
|
||||||
|
/// @param fd file descriptor
|
||||||
|
/// @param callback callback
|
||||||
|
///
|
||||||
|
void AddFDCallback(int fd, void (*callback)());
|
||||||
|
|
||||||
|
/// Clears list of file descriptors and their callbacks
|
||||||
|
///
|
||||||
|
void ClearFDCallbacksList();
|
||||||
|
|
||||||
|
/// Checks if list of file descriptors is empty
|
||||||
|
/// @return true if list is empty, false otherwise
|
||||||
|
///
|
||||||
|
bool FDCallbacksListEmpty() const;
|
||||||
|
|
||||||
/// Reads key from standard input and writes it into read_key variable
|
/// Reads key from standard input and writes it into read_key variable
|
||||||
/// @param read_key variable for read key to be written into it
|
/// @param read_key variable for read key to be written into it
|
||||||
///
|
///
|
||||||
@@ -553,6 +570,12 @@ namespace NCurses
|
|||||||
/// stack of colors
|
/// stack of colors
|
||||||
std::stack<Colors> itsColors;
|
std::stack<Colors> itsColors;
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
typedef std::vector< std::pair<int, void (*)()> > FDCallbacks;
|
||||||
|
FDCallbacks itsFDs;
|
||||||
|
|
||||||
/// pointer to container used as history
|
/// pointer to container used as history
|
||||||
std::deque<std::wstring> *itsHistory;
|
std::deque<std::wstring> *itsHistory;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user