'repeat one song' mode added + memleak fix and some code clean-ups
This commit is contained in:
@@ -61,6 +61,8 @@
|
|||||||
#
|
#
|
||||||
#key_toggle_repeat = 'r'
|
#key_toggle_repeat = 'r'
|
||||||
#
|
#
|
||||||
|
#key_toggle_repeat_one = 'R'
|
||||||
|
#
|
||||||
#key_toggle_random = 'z'
|
#key_toggle_random = 'z'
|
||||||
#
|
#
|
||||||
#key_shuffle = 'Z'
|
#key_shuffle = 'Z'
|
||||||
|
|||||||
@@ -74,6 +74,8 @@
|
|||||||
#
|
#
|
||||||
#autocenter_mode = "no"
|
#autocenter_mode = "no"
|
||||||
#
|
#
|
||||||
|
#repeat_one_mode = "no"
|
||||||
|
#
|
||||||
#header_visibility = "yes"
|
#header_visibility = "yes"
|
||||||
#
|
#
|
||||||
#statusbar_visibility = "yes"
|
#statusbar_visibility = "yes"
|
||||||
|
|||||||
@@ -563,7 +563,7 @@ bool Menu::IsStatic(int option)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu Menu::EmptyClone()
|
Window * Menu::EmptyClone()
|
||||||
{
|
{
|
||||||
return Menu(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder);
|
return new Menu(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,8 +77,7 @@ class Menu : public Window
|
|||||||
|
|
||||||
bool Empty() { return itsOptions.empty(); }
|
bool Empty() { return itsOptions.empty(); }
|
||||||
bool IsStatic(int);
|
bool IsStatic(int);
|
||||||
Menu EmptyClone();
|
virtual Window * EmptyClone();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
vector<Option *> itsOptions;
|
vector<Option *> itsOptions;
|
||||||
vector<int> NeedsRedraw;
|
vector<int> NeedsRedraw;
|
||||||
|
|||||||
@@ -190,9 +190,9 @@ int main(int argc, char *argv[])
|
|||||||
main_height++;
|
main_height++;
|
||||||
|
|
||||||
mPlaylist = new Menu(0, main_start_y, COLS, main_height, "", Config.main_color, brNone);
|
mPlaylist = new Menu(0, main_start_y, COLS, main_height, "", Config.main_color, brNone);
|
||||||
mBrowser = new Menu(mPlaylist->EmptyClone());
|
mBrowser = static_cast<Menu *>(mPlaylist->EmptyClone());
|
||||||
mTagEditor = new Menu(mPlaylist->EmptyClone());
|
mTagEditor = static_cast<Menu *>(mPlaylist->EmptyClone());
|
||||||
mSearcher = new Menu(mPlaylist->EmptyClone());
|
mSearcher = static_cast<Menu *>(mPlaylist->EmptyClone());
|
||||||
|
|
||||||
int lib_artist_width = COLS/3-1;
|
int lib_artist_width = COLS/3-1;
|
||||||
int lib_albums_width = COLS/3;
|
int lib_albums_width = COLS/3;
|
||||||
@@ -205,7 +205,7 @@ int main(int argc, char *argv[])
|
|||||||
mLibSongs = new Menu(lib_songs_start_x, main_start_y, lib_songs_width, main_height, "Songs", Config.main_color, brNone);
|
mLibSongs = new Menu(lib_songs_start_x, main_start_y, lib_songs_width, main_height, "Songs", Config.main_color, brNone);
|
||||||
|
|
||||||
sHelp = new Scrollpad(0, main_start_y, COLS, main_height, "", Config.main_color, brNone);
|
sHelp = new Scrollpad(0, main_start_y, COLS, main_height, "", Config.main_color, brNone);
|
||||||
sLyrics = new Scrollpad(sHelp->EmptyClone());
|
sLyrics = static_cast<Scrollpad *>(sHelp->EmptyClone());
|
||||||
|
|
||||||
sHelp->Add(" [b]Keys - Movement\n -----------------------------------------[/b]\n");
|
sHelp->Add(" [b]Keys - Movement\n -----------------------------------------[/b]\n");
|
||||||
sHelp->Add(DisplayKeys(Key.Up) + "Move Cursor up\n");
|
sHelp->Add(DisplayKeys(Key.Up) + "Move Cursor up\n");
|
||||||
@@ -233,6 +233,7 @@ int main(int argc, char *argv[])
|
|||||||
sHelp->Add(DisplayKeys(Key.VolumeUp) + "Increase volume\n\n");
|
sHelp->Add(DisplayKeys(Key.VolumeUp) + "Increase volume\n\n");
|
||||||
|
|
||||||
sHelp->Add(DisplayKeys(Key.ToggleRepeat) + "Toggle repeat mode\n");
|
sHelp->Add(DisplayKeys(Key.ToggleRepeat) + "Toggle repeat mode\n");
|
||||||
|
sHelp->Add(DisplayKeys(Key.ToggleRepeatOne) + "Toggle \"repeat one\" mode\n");
|
||||||
sHelp->Add(DisplayKeys(Key.ToggleRandom) + "Toggle random mode\n");
|
sHelp->Add(DisplayKeys(Key.ToggleRandom) + "Toggle random mode\n");
|
||||||
sHelp->Add(DisplayKeys(Key.Shuffle) + "Shuffle playlist\n");
|
sHelp->Add(DisplayKeys(Key.Shuffle) + "Shuffle playlist\n");
|
||||||
sHelp->Add(DisplayKeys(Key.ToggleCrossfade) + "Toggle crossfade mode\n");
|
sHelp->Add(DisplayKeys(Key.ToggleCrossfade) + "Toggle crossfade mode\n");
|
||||||
@@ -431,21 +432,21 @@ int main(int argc, char *argv[])
|
|||||||
mLibAlbums->Clear();
|
mLibAlbums->Clear();
|
||||||
Mpd->GetAlbums(mLibArtists->GetCurrentOption(), list);
|
Mpd->GetAlbums(mLibArtists->GetCurrentOption(), list);
|
||||||
for (TagList::const_iterator it = list.begin(); it != list.end(); it++)
|
for (TagList::const_iterator it = list.begin(); it != list.end(); it++)
|
||||||
mLibAlbums->AddOption(*it);
|
mLibAlbums->AddOption(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreeSongList(vSongs);
|
||||||
|
|
||||||
if (mLibAlbums->Empty())
|
if (mLibAlbums->Empty())
|
||||||
{
|
{
|
||||||
mLibAlbums->WriteXY(0, 0, "No albums found.");
|
mLibAlbums->WriteXY(0, 0, "No albums found.");
|
||||||
mLibSongs->Clear(0);
|
mLibSongs->Clear(0);
|
||||||
FreeSongList(vSongs);
|
|
||||||
Mpd->StartSearch(1);
|
Mpd->StartSearch(1);
|
||||||
Mpd->AddSearch(MPD_TAG_ITEM_ARTIST, mLibArtists->GetCurrentOption());
|
Mpd->AddSearch(MPD_TAG_ITEM_ARTIST, mLibArtists->GetCurrentOption());
|
||||||
Mpd->CommitSearch(vSongs);
|
Mpd->CommitSearch(vSongs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FreeSongList(vSongs);
|
|
||||||
mLibSongs->Clear(0);
|
mLibSongs->Clear(0);
|
||||||
Mpd->StartSearch(1);
|
Mpd->StartSearch(1);
|
||||||
Mpd->AddSearch(MPD_TAG_ITEM_ARTIST, mLibArtists->GetCurrentOption());
|
Mpd->AddSearch(MPD_TAG_ITEM_ARTIST, mLibArtists->GetCurrentOption());
|
||||||
@@ -974,7 +975,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
found_pos = 0;
|
found_pos = 0;
|
||||||
vFoundPositions.clear();
|
vFoundPositions.clear();
|
||||||
vSearched.clear();
|
FreeSongList(vSearched);
|
||||||
PrepareSearchEngine(searched_song);
|
PrepareSearchEngine(searched_song);
|
||||||
ShowMessage("Search state reset");
|
ShowMessage("Search state reset");
|
||||||
break;
|
break;
|
||||||
@@ -1323,25 +1324,25 @@ int main(int argc, char *argv[])
|
|||||||
wFooter->WriteXY(0, Config.statusbar_visibility, "Add: ", 1);
|
wFooter->WriteXY(0, Config.statusbar_visibility, "Add: ", 1);
|
||||||
string path = wFooter->GetString("");
|
string path = wFooter->GetString("");
|
||||||
UNLOCK_STATUSBAR;
|
UNLOCK_STATUSBAR;
|
||||||
SongList list;
|
if (!path.empty())
|
||||||
Mpd->GetDirectoryRecursive(path, list);
|
|
||||||
if (!list.empty())
|
|
||||||
{
|
{
|
||||||
for (SongList::const_iterator it = list.begin(); it != list.end(); it++)
|
SongList list;
|
||||||
Mpd->QueueAddSong(**it);
|
Mpd->GetDirectoryRecursive(path, list);
|
||||||
if (Mpd->CommitQueue())
|
if (!list.empty())
|
||||||
{
|
{
|
||||||
Song *s = vPlaylist[vPlaylist.size()-list.size()];
|
for (SongList::const_iterator it = list.begin(); it != list.end(); it++)
|
||||||
if (s->GetHash() != list[0]->GetHash())
|
Mpd->QueueAddSong(**it);
|
||||||
ShowMessage(message_part_of_songs_added);
|
if (Mpd->CommitQueue())
|
||||||
|
{
|
||||||
|
Song *s = vPlaylist[vPlaylist.size()-list.size()];
|
||||||
|
if (s->GetHash() != list[0]->GetHash())
|
||||||
|
ShowMessage(message_part_of_songs_added);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!path.empty())
|
|
||||||
Mpd->AddSong(path);
|
Mpd->AddSong(path);
|
||||||
|
FreeSongList(list);
|
||||||
}
|
}
|
||||||
FreeSongList(list);
|
|
||||||
}
|
}
|
||||||
else if (Keypressed(input, Key.SeekForward) || Keypressed(input, Key.SeekBackward))
|
else if (Keypressed(input, Key.SeekForward) || Keypressed(input, Key.SeekBackward))
|
||||||
{
|
{
|
||||||
@@ -1413,6 +1414,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else if (Keypressed(input, Key.ToggleRepeat))
|
else if (Keypressed(input, Key.ToggleRepeat))
|
||||||
Mpd->SetRepeat(!Mpd->GetRepeat());
|
Mpd->SetRepeat(!Mpd->GetRepeat());
|
||||||
|
else if (Keypressed(input, Key.ToggleRepeatOne))
|
||||||
|
{
|
||||||
|
Config.repeat_one_mode = !Config.repeat_one_mode;
|
||||||
|
ShowMessage("'Repeat one' mode: " + string(Config.repeat_one_mode ? "On" : "Off"));
|
||||||
|
}
|
||||||
else if (Keypressed(input, Key.Shuffle))
|
else if (Keypressed(input, Key.Shuffle))
|
||||||
Mpd->Shuffle();
|
Mpd->Shuffle();
|
||||||
else if (Keypressed(input, Key.ToggleRandom))
|
else if (Keypressed(input, Key.ToggleRandom))
|
||||||
|
|||||||
@@ -215,9 +215,9 @@ void Scrollpad::Clear()
|
|||||||
Window::Clear();
|
Window::Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Scrollpad Scrollpad::EmptyClone()
|
Window * Scrollpad::EmptyClone()
|
||||||
{
|
{
|
||||||
return Scrollpad(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder);
|
return new Scrollpad(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scrollpad & Scrollpad::operator=(const Scrollpad &base)
|
Scrollpad & Scrollpad::operator=(const Scrollpad &base)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class Scrollpad: public Window
|
|||||||
virtual void SetBorder(BORDER);
|
virtual void SetBorder(BORDER);
|
||||||
virtual void SetTitle(string);
|
virtual void SetTitle(string);
|
||||||
virtual void Clear();
|
virtual void Clear();
|
||||||
Scrollpad EmptyClone();
|
virtual Window * EmptyClone();
|
||||||
Scrollpad & operator=(const Scrollpad &);
|
Scrollpad & operator=(const Scrollpad &);
|
||||||
protected:
|
protected:
|
||||||
void print_content();
|
void print_content();
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ void DefaultKeys(ncmpcpp_keys &keys)
|
|||||||
keys.SeekForward[0] = 'f';
|
keys.SeekForward[0] = 'f';
|
||||||
keys.SeekBackward[0] = 'b';
|
keys.SeekBackward[0] = 'b';
|
||||||
keys.ToggleRepeat[0] = 'r';
|
keys.ToggleRepeat[0] = 'r';
|
||||||
|
keys.ToggleRepeatOne[0] = 'R';
|
||||||
keys.ToggleRandom[0] = 'z';
|
keys.ToggleRandom[0] = 'z';
|
||||||
keys.Shuffle[0] = 'Z';
|
keys.Shuffle[0] = 'Z';
|
||||||
keys.ToggleCrossfade[0] = 'x';
|
keys.ToggleCrossfade[0] = 'x';
|
||||||
@@ -98,6 +99,7 @@ void DefaultKeys(ncmpcpp_keys &keys)
|
|||||||
keys.SeekForward[1] = null_key;
|
keys.SeekForward[1] = null_key;
|
||||||
keys.SeekBackward[1] = null_key;
|
keys.SeekBackward[1] = null_key;
|
||||||
keys.ToggleRepeat[1] = null_key;
|
keys.ToggleRepeat[1] = null_key;
|
||||||
|
keys.ToggleRepeatOne[1] = null_key;
|
||||||
keys.ToggleRandom[1] = null_key;
|
keys.ToggleRandom[1] = null_key;
|
||||||
keys.Shuffle[1] = null_key;
|
keys.Shuffle[1] = null_key;
|
||||||
keys.ToggleCrossfade[1] = null_key;
|
keys.ToggleCrossfade[1] = null_key;
|
||||||
@@ -144,6 +146,7 @@ void DefaultConfiguration(ncmpcpp_config &conf)
|
|||||||
conf.header_visibility = true;
|
conf.header_visibility = true;
|
||||||
conf.statusbar_visibility = true;
|
conf.statusbar_visibility = true;
|
||||||
conf.autocenter_mode = false;
|
conf.autocenter_mode = false;
|
||||||
|
conf.repeat_one_mode = false;
|
||||||
conf.set_window_title = true;
|
conf.set_window_title = true;
|
||||||
conf.mpd_connection_timeout = 15;
|
conf.mpd_connection_timeout = 15;
|
||||||
conf.crossfade_time = 5;
|
conf.crossfade_time = 5;
|
||||||
@@ -307,6 +310,8 @@ void ReadKeys(ncmpcpp_keys &keys)
|
|||||||
GetKeys(*it, keys.SeekBackward);
|
GetKeys(*it, keys.SeekBackward);
|
||||||
else if (it->find("key_toggle_repeat ") != string::npos)
|
else if (it->find("key_toggle_repeat ") != string::npos)
|
||||||
GetKeys(*it, keys.ToggleRepeat);
|
GetKeys(*it, keys.ToggleRepeat);
|
||||||
|
else if (it->find("key_toggle_repeat_one ") != string::npos)
|
||||||
|
GetKeys(*it, keys.ToggleRepeatOne);
|
||||||
else if (it->find("key_toggle_random ") != string::npos)
|
else if (it->find("key_toggle_random ") != string::npos)
|
||||||
GetKeys(*it, keys.ToggleRandom);
|
GetKeys(*it, keys.ToggleRandom);
|
||||||
else if (it->find("key_shuffle ") != string::npos)
|
else if (it->find("key_shuffle ") != string::npos)
|
||||||
@@ -423,6 +428,9 @@ void ReadConfiguration(ncmpcpp_config &conf)
|
|||||||
if (it->find("autocenter_mode") != string::npos)
|
if (it->find("autocenter_mode") != string::npos)
|
||||||
conf.autocenter_mode = v == "yes";
|
conf.autocenter_mode = v == "yes";
|
||||||
|
|
||||||
|
if (it->find("repeat_one_mode") != string::npos)
|
||||||
|
conf.repeat_one_mode = v == "yes";
|
||||||
|
|
||||||
if (it->find("enable_window_title") != string::npos)
|
if (it->find("enable_window_title") != string::npos)
|
||||||
conf.set_window_title = v == "yes";
|
conf.set_window_title = v == "yes";
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ struct ncmpcpp_keys
|
|||||||
int SeekForward[2];
|
int SeekForward[2];
|
||||||
int SeekBackward[2];
|
int SeekBackward[2];
|
||||||
int ToggleRepeat[2];
|
int ToggleRepeat[2];
|
||||||
|
int ToggleRepeatOne[2];
|
||||||
int ToggleRandom[2];
|
int ToggleRandom[2];
|
||||||
int Shuffle[2];
|
int Shuffle[2];
|
||||||
int ToggleCrossfade[2];
|
int ToggleCrossfade[2];
|
||||||
@@ -102,6 +103,7 @@ struct ncmpcpp_config
|
|||||||
bool header_visibility;
|
bool header_visibility;
|
||||||
bool statusbar_visibility;
|
bool statusbar_visibility;
|
||||||
bool autocenter_mode;
|
bool autocenter_mode;
|
||||||
|
bool repeat_one_mode;
|
||||||
|
|
||||||
int mpd_connection_timeout;
|
int mpd_connection_timeout;
|
||||||
int crossfade_time;
|
int crossfade_time;
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ extern bool block_library_update;
|
|||||||
|
|
||||||
extern bool redraw_me;
|
extern bool redraw_me;
|
||||||
|
|
||||||
|
bool repeat_one_allowed = 0;
|
||||||
|
|
||||||
long long playlist_old_id = -1;
|
long long playlist_old_id = -1;
|
||||||
|
|
||||||
int old_playing;
|
int old_playing;
|
||||||
@@ -325,11 +327,17 @@ void NcmpcppStatusChanged(MPDConnection *Mpd, MPDStatusChanges changed, void *da
|
|||||||
{
|
{
|
||||||
if (!mPlaylist->Empty())
|
if (!mPlaylist->Empty())
|
||||||
{
|
{
|
||||||
|
if (Config.repeat_one_mode && repeat_one_allowed && old_playing+1 == now_playing)
|
||||||
|
{
|
||||||
|
std::swap<int>(now_playing,old_playing);
|
||||||
|
Mpd->Play(now_playing);
|
||||||
|
}
|
||||||
if (old_playing >= 0)
|
if (old_playing >= 0)
|
||||||
mPlaylist->BoldOption(old_playing+1, 0);
|
mPlaylist->BoldOption(old_playing+1, 0);
|
||||||
mPlaylist->BoldOption(now_playing+1, 1);
|
mPlaylist->BoldOption(now_playing+1, 1);
|
||||||
if (Config.autocenter_mode)
|
if (Config.autocenter_mode)
|
||||||
mPlaylist->Highlight(now_playing+1);
|
mPlaylist->Highlight(now_playing+1);
|
||||||
|
repeat_one_allowed = 0;
|
||||||
}
|
}
|
||||||
if (!Mpd->GetElapsedTime())
|
if (!Mpd->GetElapsedTime())
|
||||||
mvwhline(wFooter->RawWin(), 0, 0, 0, wFooter->GetWidth());
|
mvwhline(wFooter->RawWin(), 0, 0, 0, wFooter->GetWidth());
|
||||||
@@ -348,6 +356,10 @@ void NcmpcppStatusChanged(MPDConnection *Mpd, MPDStatusChanges changed, void *da
|
|||||||
|
|
||||||
int elapsed = Mpd->GetElapsedTime();
|
int elapsed = Mpd->GetElapsedTime();
|
||||||
|
|
||||||
|
// 'repeat one' mode check - be sure that we deal with item with known length
|
||||||
|
if (Mpd->GetCurrentSong().GetTotalLength() && elapsed == Mpd->GetCurrentSong().GetTotalLength())
|
||||||
|
repeat_one_allowed = 1;
|
||||||
|
|
||||||
if (!block_statusbar_update && Config.statusbar_visibility)
|
if (!block_statusbar_update && Config.statusbar_visibility)
|
||||||
{
|
{
|
||||||
string tracklength;
|
string tracklength;
|
||||||
|
|||||||
@@ -586,6 +586,11 @@ void EnableColors()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window * Window::EmptyClone()
|
||||||
|
{
|
||||||
|
return new Window(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder);
|
||||||
|
}
|
||||||
|
|
||||||
char * ToString(const wchar_t *ws)
|
char * ToString(const wchar_t *ws)
|
||||||
{
|
{
|
||||||
string s;
|
string s;
|
||||||
|
|||||||
@@ -106,6 +106,8 @@ class Window
|
|||||||
virtual COLOR GetColor() const;
|
virtual COLOR GetColor() const;
|
||||||
virtual BORDER GetBorder() const;
|
virtual BORDER GetBorder() const;
|
||||||
|
|
||||||
|
virtual Window * EmptyClone();
|
||||||
|
|
||||||
virtual void Go(WHERE) { } // for Menu and Scrollpad class
|
virtual void Go(WHERE) { } // for Menu and Scrollpad class
|
||||||
virtual int GetChoice() const { return -1; } // for Menu class
|
virtual int GetChoice() const { return -1; } // for Menu class
|
||||||
virtual void Add(string str) { Write(str); } // for Scrollpad class
|
virtual void Add(string str) { Write(str); } // for Scrollpad class
|
||||||
|
|||||||
Reference in New Issue
Block a user