new feature: two columns view in media library (albums and songs)
This commit is contained in:
@@ -232,6 +232,7 @@ void Help::GetKeybindings()
|
|||||||
|
|
||||||
|
|
||||||
*w << " " << fmtBold << "Keys - Media library\n -----------------------------------------\n" << fmtBoldEnd;
|
*w << " " << fmtBold << "Keys - Media library\n -----------------------------------------\n" << fmtBoldEnd;
|
||||||
|
*w << DisplayKeys(Key.MediaLibrary) << "Switch between two/three columns\n";
|
||||||
*w << DisplayKeys(&Key.VolumeDown[0], 1) << "Previous column\n";
|
*w << DisplayKeys(&Key.VolumeDown[0], 1) << "Previous column\n";
|
||||||
*w << DisplayKeys(&Key.VolumeUp[0], 1) << "Next column\n";
|
*w << DisplayKeys(&Key.VolumeUp[0], 1) << "Next column\n";
|
||||||
*w << DisplayKeys(Key.Enter) << "Add to playlist and play song/album/artist's songs\n";
|
*w << DisplayKeys(Key.Enter) << "Add to playlist and play song/album/artist's songs\n";
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ using std::string;
|
|||||||
|
|
||||||
MediaLibrary *myLibrary = new MediaLibrary;
|
MediaLibrary *myLibrary = new MediaLibrary;
|
||||||
|
|
||||||
|
bool MediaLibrary::hasTwoColumns;
|
||||||
size_t MediaLibrary::itsLeftColWidth;
|
size_t MediaLibrary::itsLeftColWidth;
|
||||||
size_t MediaLibrary::itsMiddleColWidth;
|
size_t MediaLibrary::itsMiddleColWidth;
|
||||||
size_t MediaLibrary::itsMiddleColStartX;
|
size_t MediaLibrary::itsMiddleColStartX;
|
||||||
@@ -43,6 +44,7 @@ size_t MediaLibrary::itsRightColStartX;
|
|||||||
|
|
||||||
void MediaLibrary::Init()
|
void MediaLibrary::Init()
|
||||||
{
|
{
|
||||||
|
hasTwoColumns = 0;
|
||||||
itsLeftColWidth = COLS/3-1;
|
itsLeftColWidth = COLS/3-1;
|
||||||
itsMiddleColWidth = COLS/3;
|
itsMiddleColWidth = COLS/3;
|
||||||
itsMiddleColStartX = itsLeftColWidth+1;
|
itsMiddleColStartX = itsLeftColWidth+1;
|
||||||
@@ -77,11 +79,21 @@ void MediaLibrary::Init()
|
|||||||
|
|
||||||
void MediaLibrary::Resize()
|
void MediaLibrary::Resize()
|
||||||
{
|
{
|
||||||
itsLeftColWidth = COLS/3-1;
|
if (!hasTwoColumns)
|
||||||
itsMiddleColStartX = itsLeftColWidth+1;
|
{
|
||||||
itsMiddleColWidth = COLS/3;
|
itsLeftColWidth = COLS/3-1;
|
||||||
itsRightColStartX = itsLeftColWidth+itsMiddleColWidth+2;
|
itsMiddleColStartX = itsLeftColWidth+1;
|
||||||
itsRightColWidth = COLS-COLS/3*2-1;
|
itsMiddleColWidth = COLS/3;
|
||||||
|
itsRightColStartX = itsLeftColWidth+itsMiddleColWidth+2;
|
||||||
|
itsRightColWidth = COLS-COLS/3*2-1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itsMiddleColStartX = 0;
|
||||||
|
itsMiddleColWidth = COLS/2;
|
||||||
|
itsRightColStartX = itsMiddleColWidth+1;
|
||||||
|
itsRightColWidth = COLS-itsMiddleColWidth-1;
|
||||||
|
}
|
||||||
|
|
||||||
Artists->Resize(itsLeftColWidth, MainHeight);
|
Artists->Resize(itsLeftColWidth, MainHeight);
|
||||||
Albums->Resize(itsMiddleColWidth, MainHeight);
|
Albums->Resize(itsMiddleColWidth, MainHeight);
|
||||||
@@ -110,7 +122,24 @@ void MediaLibrary::Refresh()
|
|||||||
void MediaLibrary::SwitchTo()
|
void MediaLibrary::SwitchTo()
|
||||||
{
|
{
|
||||||
if (myScreen == this)
|
if (myScreen == this)
|
||||||
return;
|
{
|
||||||
|
hasTwoColumns = !hasTwoColumns;
|
||||||
|
hasToBeResized = 1;
|
||||||
|
Artists->Clear(0);
|
||||||
|
Albums->Clear(0);
|
||||||
|
Albums->Reset();
|
||||||
|
Songs->Clear(0);
|
||||||
|
if (hasTwoColumns)
|
||||||
|
{
|
||||||
|
if (w == Artists)
|
||||||
|
NextColumn();
|
||||||
|
string item_type = IntoStr(Config.media_lib_primary_tag);
|
||||||
|
ToLower(item_type);
|
||||||
|
Albums->SetTitle("Albums (sorted by " + item_type + ")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Albums->SetTitle("Albums");
|
||||||
|
}
|
||||||
|
|
||||||
if (hasToBeResized)
|
if (hasToBeResized)
|
||||||
Resize();
|
Resize();
|
||||||
@@ -128,7 +157,7 @@ std::string MediaLibrary::Title()
|
|||||||
|
|
||||||
void MediaLibrary::Update()
|
void MediaLibrary::Update()
|
||||||
{
|
{
|
||||||
if (Artists->Empty())
|
if (!hasTwoColumns && Artists->Empty())
|
||||||
{
|
{
|
||||||
TagList list;
|
TagList list;
|
||||||
Albums->Clear(0);
|
Albums->Clear(0);
|
||||||
@@ -147,7 +176,7 @@ void MediaLibrary::Update()
|
|||||||
Artists->Refresh();
|
Artists->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Artists->Empty() && Albums->Empty() && Songs->Empty())
|
if (!hasTwoColumns && !Artists->Empty() && Albums->Empty() && Songs->Empty())
|
||||||
{
|
{
|
||||||
Albums->Reset();
|
Albums->Reset();
|
||||||
TagList list;
|
TagList list;
|
||||||
@@ -173,14 +202,13 @@ void MediaLibrary::Update()
|
|||||||
Albums->AddOption(std::make_pair("<no album>", SearchConstraints("", "")));
|
Albums->AddOption(std::make_pair("<no album>", SearchConstraints("", "")));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TagList::iterator it = list.begin(); it != list.end(); it++)
|
for (TagList::const_iterator it = list.begin(); it != list.end(); it++)
|
||||||
{
|
{
|
||||||
TagList l;
|
TagList l;
|
||||||
Mpd->StartFieldSearch(MPD_TAG_ITEM_DATE);
|
Mpd->StartFieldSearch(MPD_TAG_ITEM_DATE);
|
||||||
Mpd->AddSearch(Config.media_lib_primary_tag, Artists->Current());
|
Mpd->AddSearch(Config.media_lib_primary_tag, Artists->Current());
|
||||||
Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, *it);
|
Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, *it);
|
||||||
Mpd->CommitSearch(l);
|
Mpd->CommitSearch(l);
|
||||||
utf_to_locale(*it);
|
|
||||||
if (l.empty())
|
if (l.empty())
|
||||||
{
|
{
|
||||||
Albums->AddOption(std::make_pair(*it, SearchConstraints(*it, "")));
|
Albums->AddOption(std::make_pair(*it, SearchConstraints(*it, "")));
|
||||||
@@ -190,27 +218,69 @@ void MediaLibrary::Update()
|
|||||||
Albums->AddOption(std::make_pair("(" + *j + ") " + *it, SearchConstraints(*it, *j)));
|
Albums->AddOption(std::make_pair("(" + *j + ") " + *it, SearchConstraints(*it, *j)));
|
||||||
}
|
}
|
||||||
utf_to_locale(Artists->Current());
|
utf_to_locale(Artists->Current());
|
||||||
|
for (size_t i = 0; i < Albums->Size(); i++)
|
||||||
|
utf_to_locale((*Albums)[i].first);
|
||||||
if (!Albums->Empty())
|
if (!Albums->Empty())
|
||||||
Albums->Sort<CaseInsensitiveSorting>((*Albums)[0].first == "<no album>");
|
Albums->Sort<CaseInsensitiveSorting>((*Albums)[0].first == "<no album>");
|
||||||
Albums->Window::Clear();
|
Albums->Refresh();
|
||||||
|
}
|
||||||
|
else if (hasTwoColumns && Albums->Empty() && Songs->Empty())
|
||||||
|
{
|
||||||
|
TagList artists;
|
||||||
|
*Albums << XY(0, 0) << "Fetching albums' list...";
|
||||||
|
Albums->Window::Refresh();
|
||||||
|
Mpd->GetList(artists, Config.media_lib_primary_tag);
|
||||||
|
for (TagList::const_iterator i = artists.begin(); i != artists.end(); i++)
|
||||||
|
{
|
||||||
|
TagList albums;
|
||||||
|
Mpd->StartFieldSearch(MPD_TAG_ITEM_ALBUM);
|
||||||
|
Mpd->AddSearch(Config.media_lib_primary_tag, *i);
|
||||||
|
Mpd->CommitSearch(albums);
|
||||||
|
for (TagList::const_iterator j = albums.begin(); j != albums.end(); j++)
|
||||||
|
{
|
||||||
|
if (Config.media_lib_primary_tag != MPD_TAG_ITEM_DATE)
|
||||||
|
{
|
||||||
|
TagList years;
|
||||||
|
Mpd->StartFieldSearch(MPD_TAG_ITEM_DATE);
|
||||||
|
Mpd->AddSearch(Config.media_lib_primary_tag, *i);
|
||||||
|
Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, *j);
|
||||||
|
Mpd->CommitSearch(years);
|
||||||
|
if (!years.empty())
|
||||||
|
{
|
||||||
|
for (TagList::const_iterator k = years.begin(); k != years.end(); k++)
|
||||||
|
{
|
||||||
|
Albums->AddOption(std::make_pair(*i + " - (" + *k + ") " + *j, SearchConstraints(*i, *j, *k)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Albums->AddOption(std::make_pair(*i + " - " + *j, SearchConstraints(*i, *j, "")));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Albums->AddOption(std::make_pair(*i + " - " + *j, SearchConstraints(*i, *j, *i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < Albums->Size(); i++)
|
||||||
|
utf_to_locale((*Albums)[i].first);
|
||||||
|
if (!Albums->Empty())
|
||||||
|
Albums->Sort<CaseInsensitiveSorting>();
|
||||||
Albums->Refresh();
|
Albums->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Artists->Empty() && w == Albums && Albums->Empty())
|
if (!hasTwoColumns && !Artists->Empty() && w == Albums && Albums->Empty())
|
||||||
{
|
{
|
||||||
Albums->HighlightColor(Config.main_highlight_color);
|
Albums->HighlightColor(Config.main_highlight_color);
|
||||||
Artists->HighlightColor(Config.active_column_color);
|
Artists->HighlightColor(Config.active_column_color);
|
||||||
w = Artists;
|
w = Artists;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Artists->Empty() && Songs->Empty())
|
if ((hasTwoColumns || !Artists->Empty()) && Songs->Empty())
|
||||||
{
|
{
|
||||||
Songs->Reset();
|
Songs->Reset();
|
||||||
SongList list;
|
SongList list;
|
||||||
|
|
||||||
Songs->Clear(0);
|
Songs->Clear(0);
|
||||||
Mpd->StartSearch(1);
|
Mpd->StartSearch(1);
|
||||||
Mpd->AddSearch(Config.media_lib_primary_tag, locale_to_utf_cpy(Artists->Current()));
|
Mpd->AddSearch(Config.media_lib_primary_tag, hasTwoColumns ? Albums->Current().second.Artist : locale_to_utf_cpy(Artists->Current()));
|
||||||
if (Albums->Empty()) // left for compatibility with <mpd-0.14
|
if (Albums->Empty()) // left for compatibility with <mpd-0.14
|
||||||
{
|
{
|
||||||
*Albums << XY(0, 0) << "No albums found.";
|
*Albums << XY(0, 0) << "No albums found.";
|
||||||
@@ -218,9 +288,9 @@ void MediaLibrary::Update()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, locale_to_utf_cpy(Albums->Current().second.Album));
|
Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, Albums->Current().second.Album);
|
||||||
if (!Albums->Current().second.Album.empty()) // for <no album>
|
if (!Albums->Current().second.Album.empty()) // for <no album>
|
||||||
Mpd->AddSearch(MPD_TAG_ITEM_DATE, locale_to_utf_cpy(Albums->Current().second.Year));
|
Mpd->AddSearch(MPD_TAG_ITEM_DATE, Albums->Current().second.Year);
|
||||||
}
|
}
|
||||||
Mpd->CommitSearch(list);
|
Mpd->CommitSearch(list);
|
||||||
|
|
||||||
@@ -293,7 +363,7 @@ void MediaLibrary::NextColumn()
|
|||||||
{
|
{
|
||||||
if (w == Artists)
|
if (w == Artists)
|
||||||
{
|
{
|
||||||
if (Songs->Empty())
|
if (!hasTwoColumns && Songs->Empty())
|
||||||
return;
|
return;
|
||||||
Artists->HighlightColor(Config.main_highlight_color);
|
Artists->HighlightColor(Config.main_highlight_color);
|
||||||
w->Refresh();
|
w->Refresh();
|
||||||
@@ -322,7 +392,7 @@ void MediaLibrary::PrevColumn()
|
|||||||
if (!Albums->Empty())
|
if (!Albums->Empty())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (w == Albums)
|
if (w == Albums && !hasTwoColumns)
|
||||||
{
|
{
|
||||||
Albums->HighlightColor(Config.main_highlight_color);
|
Albums->HighlightColor(Config.main_highlight_color);
|
||||||
w->Refresh();
|
w->Refresh();
|
||||||
|
|||||||
@@ -28,8 +28,10 @@ class MediaLibrary : public Screen<Window>
|
|||||||
{
|
{
|
||||||
struct SearchConstraints
|
struct SearchConstraints
|
||||||
{
|
{
|
||||||
|
SearchConstraints(const std::string &artist, const std::string &album, const std::string &year) : Artist(artist), Album(album), Year(year) { }
|
||||||
SearchConstraints(const std::string &album, const std::string &year) : Album(album), Year(year) { }
|
SearchConstraints(const std::string &album, const std::string &year) : Album(album), Year(year) { }
|
||||||
|
|
||||||
|
std::string Artist;
|
||||||
std::string Album;
|
std::string Album;
|
||||||
std::string Year;
|
std::string Year;
|
||||||
};
|
};
|
||||||
@@ -57,6 +59,7 @@ class MediaLibrary : public Screen<Window>
|
|||||||
|
|
||||||
virtual List *GetList();
|
virtual List *GetList();
|
||||||
|
|
||||||
|
int Columns() { return hasTwoColumns ? 2 : 3; }
|
||||||
void NextColumn();
|
void NextColumn();
|
||||||
void PrevColumn();
|
void PrevColumn();
|
||||||
|
|
||||||
@@ -72,6 +75,7 @@ class MediaLibrary : public Screen<Window>
|
|||||||
static bool SortSongsByTrack(MPD::Song *, MPD::Song *);
|
static bool SortSongsByTrack(MPD::Song *, MPD::Song *);
|
||||||
static bool SortSongsByYear(MPD::Song *, MPD::Song *);
|
static bool SortSongsByYear(MPD::Song *, MPD::Song *);
|
||||||
|
|
||||||
|
static bool hasTwoColumns;
|
||||||
static size_t itsLeftColWidth;
|
static size_t itsLeftColWidth;
|
||||||
static size_t itsMiddleColWidth;
|
static size_t itsMiddleColWidth;
|
||||||
static size_t itsMiddleColStartX;
|
static size_t itsMiddleColStartX;
|
||||||
|
|||||||
@@ -1664,7 +1664,8 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
myBrowser->ChangeBrowseMode();
|
myBrowser->ChangeBrowseMode();
|
||||||
}
|
}
|
||||||
else if (myScreen->ActiveWindow() == myLibrary->Artists)
|
else if (myScreen->ActiveWindow() == myLibrary->Artists
|
||||||
|
|| (myLibrary->Columns() == 2 && myScreen->ActiveWindow() == myLibrary->Albums))
|
||||||
{
|
{
|
||||||
LockStatusbar();
|
LockStatusbar();
|
||||||
Statusbar() << "Tag type ? [" << fmtBold << 'a' << fmtBoldEnd << "rtist/" << fmtBold << 'y' << fmtBoldEnd << "ear/" << fmtBold << 'g' << fmtBoldEnd << "enre/" << fmtBold << 'c' << fmtBoldEnd << "omposer/" << fmtBold << 'p' << fmtBoldEnd << "erformer] ";
|
Statusbar() << "Tag type ? [" << fmtBold << 'a' << fmtBoldEnd << "rtist/" << fmtBold << 'y' << fmtBoldEnd << "ear/" << fmtBold << 'g' << fmtBoldEnd << "enre/" << fmtBold << 'c' << fmtBoldEnd << "omposer/" << fmtBold << 'p' << fmtBoldEnd << "erformer] ";
|
||||||
@@ -1685,9 +1686,20 @@ int main(int argc, char *argv[])
|
|||||||
string item_type = IntoStr(Config.media_lib_primary_tag);
|
string item_type = IntoStr(Config.media_lib_primary_tag);
|
||||||
myLibrary->Artists->SetTitle(item_type + "s");
|
myLibrary->Artists->SetTitle(item_type + "s");
|
||||||
myLibrary->Artists->Reset();
|
myLibrary->Artists->Reset();
|
||||||
myLibrary->Artists->Clear(0);
|
|
||||||
myLibrary->Artists->Display();
|
|
||||||
ToLower(item_type);
|
ToLower(item_type);
|
||||||
|
if (myLibrary->Columns() == 2)
|
||||||
|
{
|
||||||
|
myLibrary->Songs->Clear(0);
|
||||||
|
myLibrary->Albums->Reset();
|
||||||
|
myLibrary->Albums->Clear();
|
||||||
|
myLibrary->Albums->SetTitle("Albums (sorted by " + item_type + ")");
|
||||||
|
myLibrary->Albums->Display();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myLibrary->Artists->Clear(0);
|
||||||
|
myLibrary->Artists->Display();
|
||||||
|
}
|
||||||
ShowMessage("Switched to list of %s tag", item_type.c_str());
|
ShowMessage("Switched to list of %s tag", item_type.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -287,7 +287,13 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
|
|||||||
myTagEditor->Albums->Clear(0);
|
myTagEditor->Albums->Clear(0);
|
||||||
myTagEditor->Dirs->Clear(0);
|
myTagEditor->Dirs->Clear(0);
|
||||||
# endif // HAVE_TAGLIB_H
|
# endif // HAVE_TAGLIB_H
|
||||||
myLibrary->Artists->Clear(0);
|
if (myLibrary->Columns() == 2)
|
||||||
|
{
|
||||||
|
myLibrary->Albums->Clear();
|
||||||
|
myLibrary->Songs->Clear(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
myLibrary->Artists->Clear(0);
|
||||||
myPlaylistEditor->Content->Clear(0);
|
myPlaylistEditor->Content->Clear(0);
|
||||||
}
|
}
|
||||||
if (changed.PlayerState)
|
if (changed.PlayerState)
|
||||||
|
|||||||
Reference in New Issue
Block a user