From 1d2541e10083a520b2cfb86b04cbecdae6c3122e Mon Sep 17 00:00:00 2001 From: casey Date: Wed, 18 May 2016 02:29:11 -0700 Subject: [PATCH] Much improved console UI with global hotkeys and some column formatting --- src/core/library/LocalLibrary.cpp | 18 ++++-- src/core/library/LocalLibraryConstants.h | 4 +- src/core/playback/Transport.cpp | 35 +++++++++++- src/core/playback/Transport.h | 36 +++++++----- src/musikbox/Main.cpp | 37 ++++++------ src/musikbox/app/layout/LibraryLayout.cpp | 27 +++++---- src/musikbox/app/layout/LibraryLayout.h | 3 +- .../app/query/CategoryListViewQuery.cpp | 56 ++++++++++++++++--- .../app/query/CategoryListViewQuery.h | 9 ++- src/musikbox/app/query/SingleTrackQuery.h | 2 +- src/musikbox/app/query/TrackListViewQuery.cpp | 9 +-- src/musikbox/app/query/TrackListViewQuery.h | 7 +-- src/musikbox/app/util/GlobalHotkeys.cpp | 35 ++++++++++++ src/musikbox/app/util/GlobalHotkeys.h | 18 ++++++ src/musikbox/app/window/CategoryListView.cpp | 38 ++++++++++++- src/musikbox/app/window/CategoryListView.h | 8 ++- src/musikbox/app/window/TrackListView.cpp | 22 +++++++- src/musikbox/cursespp/MultiLineEntry.cpp | 3 +- src/musikbox/cursespp/Window.cpp | 3 +- src/musikbox/musikbox.vcxproj | 2 + src/musikbox/musikbox.vcxproj.filters | 6 ++ 21 files changed, 293 insertions(+), 85 deletions(-) create mode 100755 src/musikbox/app/util/GlobalHotkeys.cpp create mode 100755 src/musikbox/app/util/GlobalHotkeys.h diff --git a/src/core/library/LocalLibrary.cpp b/src/core/library/LocalLibrary.cpp index 43aca76aa..8b350f433 100644 --- a/src/core/library/LocalLibrary.cpp +++ b/src/core/library/LocalLibrary.cpp @@ -49,6 +49,8 @@ static const std::string TAG = "LocalLibrary"; using namespace musik::core; using namespace musik::core::library; +#define VERBOSE_LOGGING 0 + LibraryPtr LocalLibrary::Create(std::string name, int id) { LibraryPtr lib(new LocalLibrary(name, id)); return lib; @@ -140,7 +142,9 @@ int LocalLibrary::Enqueue(QueryPtr query, unsigned int options) { queryQueue.push_back(query); queueCondition.notify_all(); - musik::debug::info(TAG, "query '" + query->Name() + "' enqueued"); + if (VERBOSE_LOGGING) { + musik::debug::info(TAG, "query '" + query->Name() + "' enqueued"); + } return query->GetId(); } @@ -185,13 +189,19 @@ void LocalLibrary::ThreadProc() { } if (query) { - musik::debug::info(TAG, "query '" + query->Name() + "' running"); + if (VERBOSE_LOGGING) { + musik::debug::info(TAG, "query '" + query->Name() + "' running"); + } query->Run(this->db); this->QueryCompleted(query); - musik::debug::info(TAG, boost::str(boost::format( - "query '%1%' finished with status=%2%") % query->Name() % query->GetStatus())); + if (VERBOSE_LOGGING) { + musik::debug::info(TAG, boost::str(boost::format( + "query '%1%' finished with status=%2%") + % query->Name() + % query->GetStatus())); + } query.reset(); } diff --git a/src/core/library/LocalLibraryConstants.h b/src/core/library/LocalLibraryConstants.h index fa9de06c3..8b80e056f 100755 --- a/src/core/library/LocalLibraryConstants.h +++ b/src/core/library/LocalLibraryConstants.h @@ -46,8 +46,8 @@ namespace musik { namespace core { namespace library { namespace constants { static const char* DURATION = "duration"; static const char* FILESIZE = "filesize"; static const char* YEAR = "year"; - static const char* DISPLAY_GENRE_ID = "visual_genre_id"; - static const char* DISPLAY_ARTIST_ID = "visual_artist_id"; + static const char* GENRE_ID = "visual_genre_id"; + static const char* ARTIST_ID = "visual_artist_id"; static const char* ALBUM_ID = "album_id"; static const char* PATH_ID = "path_id"; static const char* TITLE = "title"; diff --git a/src/core/playback/Transport.cpp b/src/core/playback/Transport.cpp index 0889ef7d7..f392b4cfe 100644 --- a/src/core/playback/Transport.cpp +++ b/src/core/playback/Transport.cpp @@ -41,7 +41,8 @@ using namespace musik::core::audio; static std::string TAG = "Transport"; Transport::Transport() -: volume(1.0) { +: volume(1.0) +, state(StateStopped) { } Transport::~Transport() { @@ -49,6 +50,11 @@ Transport::~Transport() { this->currentPlayer.reset(); } +Transport::PlaybackState Transport::GetPlaybackState() { + boost::mutex::scoped_lock lock(this->stateMutex); + return this->state; +} + void Transport::PrepareNextTrack(std::string trackUrl) { PlayerPtr player = Player::Create(trackUrl); @@ -61,6 +67,12 @@ void Transport::PrepareNextTrack(std::string trackUrl) { void Transport::Start(std::string url) { musik::debug::info(TAG, "we were asked to start the track at " + url); + /* TODO FIXME: hack; the player is reference counted, we don't want the count + to reach zero within the critical section, because its background thread may + raise an event and cause a deadlock. do we really need shared_ptrs for these + Player instances? */ + PlayerPtr current; + PlayerPtr player; { @@ -77,6 +89,7 @@ void Transport::Start(std::string url) { musik::debug::info(TAG, "Player created successfully"); } + current = this->currentPlayer; /* see hack note above. */ this->currentPlayer = newPlayer; this->currentPlayer->PlaybackStarted.connect(this, &Transport::OnPlaybackStarted); @@ -85,7 +98,7 @@ void Transport::Start(std::string url) { this->currentPlayer->PlaybackError.connect(this, &Transport::OnPlaybackError); musik::debug::info(TAG, "play()"); - this->currentPlayer->Play(); + this->currentPlayer->Play(); /* non-blocking */ player = this->currentPlayer; } @@ -272,6 +285,24 @@ void Transport::OnPlaybackError(Player *player) { } void Transport::RaisePlaybackEvent(int type, PlayerPtr player) { + /* TODO FIXME: should be either decoupled or merged with the playback + event enum. */ + switch (type) { + case EventStarted: + case EventResumed: + this->state = StatePlaying; + break; + + case EventFinished: + case EventError: + this->state = StateStopped; + break; + + case EventPaused: + this->state = StatePaused; + break; + } + std::string uri = player ? player->GetUrl() : ""; this->PlaybackEvent(type, uri); } \ No newline at end of file diff --git a/src/core/playback/Transport.h b/src/core/playback/Transport.h index 2308637e6..78692f764 100644 --- a/src/core/playback/Transport.h +++ b/src/core/playback/Transport.h @@ -37,12 +37,31 @@ #include #include #include -#include +#include namespace musik { namespace core { namespace audio { class Transport : public sigslot::has_slots<> { public: + sigslot::signal2 PlaybackEvent; + sigslot::signal0<> VolumeChanged; + + typedef enum { + StateStopped, + StatePaused, + StatePlaying + } PlaybackState; + + typedef enum { + EventScheduled = 0, + EventStarted = 1, + EventPaused = 2, + EventResumed = 3, + EventAlmostDone = 4, + EventFinished = 5, + EventError = -1 + } PlaybackEventType; + Transport(); ~Transport(); @@ -58,19 +77,7 @@ namespace musik { namespace core { namespace audio { double Volume(); void SetVolume(double volume); - public: - typedef enum { - EventScheduled = 0, - EventStarted = 1, - EventPaused = 2, - EventResumed = 3, - EventAlmostDone = 4, - EventFinished = 5, - EventError = -1 - } PlaybackEventType; - - sigslot::signal2 PlaybackEvent; - sigslot::signal0<> VolumeChanged; + PlaybackState GetPlaybackState(); private: void RaisePlaybackEvent(int type, PlayerPtr player); @@ -82,6 +89,7 @@ namespace musik { namespace core { namespace audio { private: double volume; + PlaybackState state; boost::mutex stateMutex; PlayerPtr currentPlayer; diff --git a/src/musikbox/Main.cpp b/src/musikbox/Main.cpp index 9fc94dc33..ab23b16d2 100644 --- a/src/musikbox/Main.cpp +++ b/src/musikbox/Main.cpp @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -163,6 +164,8 @@ int main(int argc, char* argv[]) using musik::core::LibraryFactory; LibraryPtr library = LibraryFactory::Libraries().at(0); + GlobalHotkeys globalHotkeys(tp); + LibraryLayout libraryLayout(tp, library); MainLayout mainLayout(tp, library); @@ -186,33 +189,29 @@ int main(int argc, char* argv[]) } if (ch != -1) { /* -1 = idle timeout */ - std::string kn = keyname(ch); + std::string kn = keyname((int) ch); if (ch == '\t') { /* tab */ focusNextInLayout(state); } - else if (kn == "^D") { + else if (kn == "^D") { /* ctrl+d quits */ quit = true; } - else if (kn == "ALT_K") { - tp.SetVolume(tp.Volume() + 0.05); /* 5% */ - } - else if (kn == "ALT_J") { - tp.SetVolume(tp.Volume() - 0.05); - } - else if (ch >= KEY_F(0) && ch <= KEY_F(12)) { - if (ch == KEY_F(1)) { - changeLayout(state, &mainLayout); + else if (!globalHotkeys.Handle(ch)) { + if (ch >= KEY_F(0) && ch <= KEY_F(12)) { + if (ch == KEY_F(1)) { + changeLayout(state, &mainLayout); + } + else if (ch == KEY_F(2)) { + changeLayout(state, &libraryLayout); + } } - else if (ch == KEY_F(2)) { - changeLayout(state, &libraryLayout); + else if (state.input) { + state.input->WriteChar(ch); + } + else if (state.keyHandler) { + state.keyHandler->KeyPress(ch); } - } - else if (state.input) { - state.input->WriteChar(ch); - } - else if (state.keyHandler) { - state.keyHandler->KeyPress(ch); } } diff --git a/src/musikbox/app/layout/LibraryLayout.cpp b/src/musikbox/app/layout/LibraryLayout.cpp index e7206fbef..464792c92 100755 --- a/src/musikbox/app/layout/LibraryLayout.cpp +++ b/src/musikbox/app/layout/LibraryLayout.cpp @@ -1,10 +1,17 @@ #include "stdafx.h" + #include #include + +#include + #include "LibraryLayout.h" +using namespace musik::core::library::constants; + #define CATEGORY_WIDTH 25 #define TRANSPORT_HEIGHT 3 +#define DEFAULT_CATEGORY Track::ALBUM_ID LibraryLayout::LibraryLayout(Transport& transport, LibraryPtr library) : LayoutBase() @@ -21,9 +28,9 @@ void LibraryLayout::Layout() { this->SetSize(Screen::GetWidth(), Screen::GetHeight()); this->SetPosition(0, 0); - this->albumList->SetPosition(0, 0); - this->albumList->SetSize(CATEGORY_WIDTH, this->GetHeight() - TRANSPORT_HEIGHT); - this->albumList->SetFocusOrder(0); + this->categoryList->SetPosition(0, 0); + this->categoryList->SetSize(CATEGORY_WIDTH, this->GetHeight() - TRANSPORT_HEIGHT); + this->categoryList->SetFocusOrder(0); this->trackList->SetPosition(CATEGORY_WIDTH, 0); this->trackList->SetSize(this->GetWidth() - CATEGORY_WIDTH, this->GetHeight() - TRANSPORT_HEIGHT); @@ -35,15 +42,15 @@ void LibraryLayout::Layout() { } void LibraryLayout::InitializeWindows() { - this->albumList.reset(new CategoryListView(this->library)); + this->categoryList.reset(new CategoryListView(this->library, DEFAULT_CATEGORY)); this->trackList.reset(new TrackListView(this->transport, this->library)); this->transportView.reset(new TransportWindow(this->library, this->transport)); - this->AddWindow(this->albumList); + this->AddWindow(this->categoryList); this->AddWindow(this->trackList); this->AddWindow(this->transportView); - this->albumList->SelectionChanged.connect( + this->categoryList->SelectionChanged.connect( this, &LibraryLayout::OnCategoryViewSelectionChanged); this->Layout(); @@ -51,15 +58,15 @@ void LibraryLayout::InitializeWindows() { void LibraryLayout::Show() { LayoutBase::Show(); - this->albumList->Requery(); + this->categoryList->Requery(); } void LibraryLayout::OnCategoryViewSelectionChanged( ListWindow *view, size_t newIndex, size_t oldIndex) { - if (view == this->albumList.get()) { - DBID id = this->albumList->GetSelectedId(); + if (view == this->categoryList.get()) { + DBID id = this->categoryList->GetSelectedId(); if (id != -1) { - this->trackList->Requery("album_id", id); + this->trackList->Requery(this->categoryList->GetFieldName(), id); } } } \ No newline at end of file diff --git a/src/musikbox/app/layout/LibraryLayout.h b/src/musikbox/app/layout/LibraryLayout.h index 2a69e5ecc..c698f5a97 100755 --- a/src/musikbox/app/layout/LibraryLayout.h +++ b/src/musikbox/app/layout/LibraryLayout.h @@ -30,8 +30,7 @@ class LibraryLayout : public LayoutBase, public sigslot::has_slots<> { Transport& transport; LibraryPtr library; - std::shared_ptr albumList; + std::shared_ptr categoryList; std::shared_ptr trackList; std::shared_ptr transportView; - }; \ No newline at end of file diff --git a/src/musikbox/app/query/CategoryListViewQuery.cpp b/src/musikbox/app/query/CategoryListViewQuery.cpp index f75faaa2a..f5e06b3d0 100755 --- a/src/musikbox/app/query/CategoryListViewQuery.cpp +++ b/src/musikbox/app/query/CategoryListViewQuery.cpp @@ -3,15 +3,62 @@ #include "stdafx.h" #include "CategoryListViewQuery.h" +#include #include +#include + +#include + using musik::core::db::Statement; using musik::core::db::Row; +using namespace musik::core::library::constants; #define reset(x) x.reset(new std::vector>); -CategoryListViewQuery::CategoryListViewQuery() { +static const std::string ALBUM_QUERY = + "SELECT DISTINCT albums.id, albums.name " + "FROM albums, tracks " + "WHERE albums.id = tracks.album_id " + "ORDER BY albums.sort_order;"; + +static const std::string ARTIST_QUERY = + "SELECT DISTINCT artists.id, artists.name " + "FROM artists, tracks " + "WHERE artists.id = tracks.visual_artist_id " + "ORDER BY artists.sort_order;"; + +static const std::string GENRE_QUERY = + "SELECT DISTINCT genres.id, genres.name " + "FROM genres, tracks " + "WHERE genres.id = tracks.visual_genre_id " + "ORDER BY genres.sort_order;"; + +static boost::mutex QUERY_MAP_MUTEX; +static std::map FIELD_TO_QUERY_MAP; + +static void initFieldToQueryMap() { + FIELD_TO_QUERY_MAP.emplace(Track::ALBUM_ID, ALBUM_QUERY); + FIELD_TO_QUERY_MAP.emplace(Track::ARTIST_ID, ARTIST_QUERY); + FIELD_TO_QUERY_MAP.emplace(Track::GENRE_ID, GENRE_QUERY); +} + +CategoryListViewQuery::CategoryListViewQuery(const std::string& trackField) { + this->trackField = trackField; + reset(result); + + { + boost::mutex::scoped_lock lock(QUERY_MAP_MUTEX); + + if (!FIELD_TO_QUERY_MAP.size()) { + initFieldToQueryMap(); + } + } + + if (FIELD_TO_QUERY_MAP.find(trackField) == FIELD_TO_QUERY_MAP.end()) { + throw "invalid field for CategoryListView specified"; + } } CategoryListViewQuery::~CategoryListViewQuery() { @@ -25,12 +72,7 @@ CategoryListViewQuery::ResultList CategoryListViewQuery::GetResult() { bool CategoryListViewQuery::OnRun(Connection& db) { reset(result); - std::string query = - "SELECT DISTINCT albums.id, albums.name " - "FROM albums, tracks " - "WHERE albums.id = tracks.album_id " - "ORDER BY albums.sort_order;"; - + std::string query = FIELD_TO_QUERY_MAP[this->trackField]; Statement stmt(query.c_str(), db); while (stmt.Step() == Row) { diff --git a/src/musikbox/app/query/CategoryListViewQuery.h b/src/musikbox/app/query/CategoryListViewQuery.h index ade970b85..a4a37f40e 100755 --- a/src/musikbox/app/query/CategoryListViewQuery.h +++ b/src/musikbox/app/query/CategoryListViewQuery.h @@ -17,17 +17,16 @@ class CategoryListViewQuery : public QueryBase { typedef std::shared_ptr>> ResultList; - CategoryListViewQuery(); - ~CategoryListViewQuery(); + CategoryListViewQuery(const std::string& trackField); + virtual ~CategoryListViewQuery(); - std::string Name() { - return "CategoryListViewQuery"; - } + std::string Name() { return "CategoryListViewQuery"; } virtual ResultList GetResult(); protected: virtual bool OnRun(Connection &db); + std::string trackField; ResultList result; }; \ No newline at end of file diff --git a/src/musikbox/app/query/SingleTrackQuery.h b/src/musikbox/app/query/SingleTrackQuery.h index 3439e367a..56e123499 100755 --- a/src/musikbox/app/query/SingleTrackQuery.h +++ b/src/musikbox/app/query/SingleTrackQuery.h @@ -13,7 +13,7 @@ using musik::core::LibraryPtr; class SingleTrackQuery : public QueryBase { public: SingleTrackQuery(const std::string& path); - ~SingleTrackQuery(); + virtual ~SingleTrackQuery(); virtual std::string Name() { return "SingleTrackQuery"; } virtual TrackPtr GetResult(); diff --git a/src/musikbox/app/query/TrackListViewQuery.cpp b/src/musikbox/app/query/TrackListViewQuery.cpp index 822f2918f..50b0e3484 100755 --- a/src/musikbox/app/query/TrackListViewQuery.cpp +++ b/src/musikbox/app/query/TrackListViewQuery.cpp @@ -36,8 +36,9 @@ bool TrackListViewQuery::OnRun(Connection& db) { std::string query = boost::str(boost::format( "SELECT DISTINCT t.track, t.bpm, t.duration, t.filesize, t.year, t.title, t.filename, t.thumbnail_id, al.name AS album, gn.name AS genre, ar.name AS artist, t.filetime " \ "FROM tracks t, paths p, albums al, artists ar, genres gn " \ - "WHERE t.%s=? AND t.album_id=al.id AND t.visual_genre_id=gn.id AND t.visual_artist_id=ar.id") % this->column); - + "WHERE t.%s=? AND t.album_id=al.id AND t.visual_genre_id=gn.id AND t.visual_artist_id=ar.id " + "ORDER BY album, track, artist") % this->column); + Statement trackQuery(query.c_str(), db); trackQuery.BindInt(0, this->id); @@ -53,8 +54,8 @@ bool TrackListViewQuery::OnRun(Connection& db) { track->SetValue(Track::FILENAME, trackQuery.ColumnText(6)); track->SetValue(Track::THUMBNAIL_ID, trackQuery.ColumnText(7)); track->SetValue(Track::ALBUM_ID, trackQuery.ColumnText(8)); - track->SetValue(Track::DISPLAY_GENRE_ID, trackQuery.ColumnText(9)); - track->SetValue(Track::DISPLAY_ARTIST_ID, trackQuery.ColumnText(10)); + track->SetValue(Track::GENRE_ID, trackQuery.ColumnText(9)); + track->SetValue(Track::ARTIST_ID, trackQuery.ColumnText(10)); track->SetValue(Track::FILETIME, trackQuery.ColumnText(11)); result->push_back(track); diff --git a/src/musikbox/app/query/TrackListViewQuery.h b/src/musikbox/app/query/TrackListViewQuery.h index bbddb839e..7dba6f32b 100755 --- a/src/musikbox/app/query/TrackListViewQuery.h +++ b/src/musikbox/app/query/TrackListViewQuery.h @@ -15,10 +15,9 @@ class TrackListViewQuery : public QueryBase { typedef std::shared_ptr> Result; TrackListViewQuery(LibraryPtr library, const std::string& column, DBID id); - ~TrackListViewQuery(); - std::string Name() { - return "TrackListViewQuery"; - } + virtual ~TrackListViewQuery(); + + std::string Name() { return "TrackListViewQuery"; } virtual Result GetResult(); diff --git a/src/musikbox/app/util/GlobalHotkeys.cpp b/src/musikbox/app/util/GlobalHotkeys.cpp new file mode 100755 index 000000000..7bcae0ada --- /dev/null +++ b/src/musikbox/app/util/GlobalHotkeys.cpp @@ -0,0 +1,35 @@ +#include "stdafx.h" +#include "GlobalHotkeys.h" + +GlobalHotkeys::GlobalHotkeys(Transport& transport) +: transport(transport) { + +} + +GlobalHotkeys::~GlobalHotkeys() { + +} + +bool GlobalHotkeys::Handle(int64 ch) { + std::string kn = keyname((int) ch); + + if (kn == "ALT_K") { + int state = this->transport.GetPlaybackState(); + if (state == Transport::StatePaused) { + this->transport.Resume(); + } + else if (state == Transport::StatePlaying) { + this->transport.Pause(); + } + } + if (kn == "ALT_L") { + this->transport.SetVolume(this->transport.Volume() + 0.05); /* 5% */ + return true; + } + else if (kn == "ALT_J") { + this->transport.SetVolume(this->transport.Volume() - 0.05); + return true; + } + + return false; +} \ No newline at end of file diff --git a/src/musikbox/app/util/GlobalHotkeys.h b/src/musikbox/app/util/GlobalHotkeys.h new file mode 100755 index 000000000..c59816a30 --- /dev/null +++ b/src/musikbox/app/util/GlobalHotkeys.h @@ -0,0 +1,18 @@ +#pragma once + +#include "stdafx.h" + +#include + +using musik::core::audio::Transport; + +class GlobalHotkeys { + public: + GlobalHotkeys(Transport& transport); + ~GlobalHotkeys(); /* non-virtual; do not use as a base class */ + + bool Handle(int64 ch); + + private: + Transport& transport; +}; \ No newline at end of file diff --git a/src/musikbox/app/window/CategoryListView.cpp b/src/musikbox/app/window/CategoryListView.cpp index 4757584ea..18759c756 100755 --- a/src/musikbox/app/window/CategoryListView.cpp +++ b/src/musikbox/app/window/CategoryListView.cpp @@ -7,20 +7,24 @@ #include #include +#include + #include #include "CategoryListView.h" using musik::core::LibraryPtr; using musik::core::IQuery; +using namespace musik::core::library::constants; #define WINDOW_MESSAGE_QUERY_COMPLETED 1002 -CategoryListView::CategoryListView(LibraryPtr library, IWindow *parent) -: ListWindow(parent) { +CategoryListView::CategoryListView(LibraryPtr library, const std::string& fieldName) +: ListWindow(NULL) { this->SetContentColor(BOX_COLOR_WHITE_ON_BLACK); this->library = library; this->library->QueryCompleted.connect(this, &CategoryListView::OnQueryCompleted); + this->fieldName = fieldName; this->adapter = new Adapter(*this); } @@ -28,8 +32,25 @@ CategoryListView::~CategoryListView() { delete adapter; } +void CategoryListView::KeyPress(int64 ch) { + std::string kn = keyname((int) ch); + + if (kn == "ALT_1") { + this->SetFieldName(Track::ARTIST_ID); + } + else if (kn == "ALT_2") { + this->SetFieldName(Track::ALBUM_ID); + } + else if (kn == "ALT_3") { + this->SetFieldName(Track::GENRE_ID); + } + else { + ListWindow::KeyPress(ch); + } +} + void CategoryListView::Requery() { - this->activeQuery.reset(new CategoryListViewQuery()); + this->activeQuery.reset(new CategoryListViewQuery(this->fieldName)); this->library->Enqueue(activeQuery); } @@ -41,6 +62,17 @@ DBID CategoryListView::GetSelectedId() { return -1; } +std::string CategoryListView::GetFieldName() { + return this->fieldName; +} + +void CategoryListView::SetFieldName(const std::string& fieldName) { + if (this->fieldName != fieldName) { + this->fieldName = fieldName; + this->Requery(); + } +} + void CategoryListView::OnQueryCompleted(QueryPtr query) { if (query == this->activeQuery) { Post(WINDOW_MESSAGE_QUERY_COMPLETED); diff --git a/src/musikbox/app/window/CategoryListView.h b/src/musikbox/app/window/CategoryListView.h index 657678745..569354e5f 100755 --- a/src/musikbox/app/window/CategoryListView.h +++ b/src/musikbox/app/window/CategoryListView.h @@ -15,12 +15,17 @@ using musik::core::LibraryPtr; class CategoryListView : public ListWindow, public sigslot::has_slots<> { public: - CategoryListView(LibraryPtr library, IWindow *parent = NULL); + CategoryListView(LibraryPtr library, const std::string& fieldName); virtual ~CategoryListView(); void Requery(); + virtual void ProcessMessage(IWindowMessage &message); + virtual void KeyPress(int64 ch); + DBID GetSelectedId(); + std::string GetFieldName(); + void SetFieldName(const std::string& fieldName); protected: virtual IScrollAdapter& GetScrollAdapter(); @@ -42,6 +47,7 @@ class CategoryListView : public ListWindow, public sigslot::has_slots<> { LibraryPtr library; Adapter *adapter; + std::string fieldName; std::shared_ptr activeQuery; CategoryListViewQuery::ResultList metadata; }; \ No newline at end of file diff --git a/src/musikbox/app/window/TrackListView.cpp b/src/musikbox/app/window/TrackListView.cpp index 0f4c35d99..5de0f31b6 100755 --- a/src/musikbox/app/window/TrackListView.cpp +++ b/src/musikbox/app/window/TrackListView.cpp @@ -82,16 +82,32 @@ size_t TrackListView::Adapter::GetEntryCount() { return parent.metadata ? parent.metadata->size() : 0; } +static inline void trunc(std::string& s, int max) { + if (s.size() > max) { + s = s.substr(0, max); + } +} + +#define MAX_ARTIST 12 +#define MAX_ALBUM 12 + IScrollAdapter::EntryPtr TrackListView::Adapter::GetEntry(size_t index) { int64 attrs = (index == parent.GetSelectedIndex()) ? COLOR_PAIR(BOX_COLOR_BLACK_ON_GREEN) : -1; TrackPtr track = parent.metadata->at(index); - std::string trackNum = track->GetValue("track"); - std::string title = track->GetValue("title"); + std::string trackNum = track->GetValue(Track::TRACK_NUM); + std::string artist = track->GetValue(Track::ARTIST_ID); + std::string album = track->GetValue(Track::ALBUM_ID); + std::string title = track->GetValue(Track::TITLE); + + trunc(artist, MAX_ARTIST); + trunc(album, MAX_ALBUM); std::string text = boost::str( - boost::format("%s %s") + boost::format("%s %s %s %s") % boost::io::group(std::setw(3), std::setfill(' '), trackNum) + % boost::io::group(std::setw(MAX_ARTIST), std::setiosflags(std::ios::left), std::setfill(' '), artist) + % boost::io::group(std::setw(MAX_ALBUM), std::setiosflags(std::ios::left), std::setfill(' '), album) % title); IScrollAdapter::EntryPtr entry(new SingleLineEntry(text)); diff --git a/src/musikbox/cursespp/MultiLineEntry.cpp b/src/musikbox/cursespp/MultiLineEntry.cpp index 64562e681..befcb5703 100755 --- a/src/musikbox/cursespp/MultiLineEntry.cpp +++ b/src/musikbox/cursespp/MultiLineEntry.cpp @@ -117,8 +117,7 @@ inline static void breakIntoSubLines( size_t wordLength = u8len(word); size_t extra = (i != 0); - /* we have enough space for this new word. accumulate it. the - +1 here is to take the space into account */ + /* we have enough space for this new word. accumulate it. */ if (accumLength + extra + wordLength < width) { if (extra) { diff --git a/src/musikbox/cursespp/Window.cpp b/src/musikbox/cursespp/Window.cpp index 230c9d354..556948a17 100755 --- a/src/musikbox/cursespp/Window.cpp +++ b/src/musikbox/cursespp/Window.cpp @@ -213,9 +213,8 @@ void Window::Show() { } } - this->Repaint(); - this->isVisible = true; + this->Repaint(); } void Window::Hide() { diff --git a/src/musikbox/musikbox.vcxproj b/src/musikbox/musikbox.vcxproj index d0e75a1d6..bfb97b262 100755 --- a/src/musikbox/musikbox.vcxproj +++ b/src/musikbox/musikbox.vcxproj @@ -120,6 +120,7 @@ + @@ -152,6 +153,7 @@ + diff --git a/src/musikbox/musikbox.vcxproj.filters b/src/musikbox/musikbox.vcxproj.filters index 2db1745e6..918d56ec1 100755 --- a/src/musikbox/musikbox.vcxproj.filters +++ b/src/musikbox/musikbox.vcxproj.filters @@ -78,6 +78,9 @@ app\query + + app\util + @@ -186,6 +189,9 @@ app\query + + app\util +