From c9630312efe18caf713c1fa63fa0bda07209f634 Mon Sep 17 00:00:00 2001 From: casey Date: Tue, 31 May 2016 21:27:24 -0700 Subject: [PATCH] Added album separators in TrackListView, and cleaned up IScrollAdapter::IEntry interface in the process. --- src/musikbox/app/query/TrackListViewQuery.cpp | 18 +++++++- src/musikbox/app/query/TrackListViewQuery.h | 4 ++ src/musikbox/app/window/CategoryListView.cpp | 2 +- src/musikbox/app/window/EntryWithHeader.cpp | 44 +++++++++++++++++++ src/musikbox/app/window/EntryWithHeader.h | 25 +++++++++++ src/musikbox/app/window/TrackListView.cpp | 18 +++++--- src/musikbox/app/window/TrackListView.h | 1 + src/musikbox/cursespp/IScrollAdapter.h | 4 +- src/musikbox/cursespp/MultiLineEntry.cpp | 18 +------- src/musikbox/cursespp/MultiLineEntry.h | 14 +++--- src/musikbox/cursespp/ScrollAdapterBase.cpp | 19 ++++---- src/musikbox/cursespp/SingleLineEntry.cpp | 14 +----- src/musikbox/cursespp/SingleLineEntry.h | 18 ++++---- src/musikbox/musikbox.vcxproj | 6 ++- src/musikbox/musikbox.vcxproj.filters | 6 +++ 15 files changed, 142 insertions(+), 69 deletions(-) create mode 100755 src/musikbox/app/window/EntryWithHeader.cpp create mode 100755 src/musikbox/app/window/EntryWithHeader.h diff --git a/src/musikbox/app/query/TrackListViewQuery.cpp b/src/musikbox/app/query/TrackListViewQuery.cpp index 595af18fc..b1e58eeb6 100755 --- a/src/musikbox/app/query/TrackListViewQuery.cpp +++ b/src/musikbox/app/query/TrackListViewQuery.cpp @@ -20,6 +20,7 @@ TrackListViewQuery::TrackListViewQuery(LibraryPtr library, const std::string& co this->column = column; this->id = id; this->result.reset(new std::vector()); + this->headers.reset(new std::set()); } TrackListViewQuery::~TrackListViewQuery() { @@ -30,9 +31,14 @@ TrackListViewQuery::Result TrackListViewQuery::GetResult() { return this->result; } +TrackListViewQuery::Headers TrackListViewQuery::GetHeaders() { + return this->headers; +} + bool TrackListViewQuery::OnRun(Connection& db) { if (result) { result.reset(new std::vector()); + headers.reset(new std::set()); } std::string query = boost::str(boost::format( @@ -41,11 +47,20 @@ bool TrackListViewQuery::OnRun(Connection& db) { "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); + std::string lastAlbum; + size_t index = 0; + Statement trackQuery(query.c_str(), db); trackQuery.BindInt(0, this->id); while (trackQuery.Step() == Row) { TrackPtr track = TrackPtr(new LibraryTrack(this->id, this->library)); + std::string album = trackQuery.ColumnText(8); + + if (album != lastAlbum) { + headers->insert(index); + lastAlbum = album; + } track->SetValue(Track::TRACK_NUM, trackQuery.ColumnText(0)); track->SetValue(Track::BPM, trackQuery.ColumnText(1)); @@ -55,12 +70,13 @@ bool TrackListViewQuery::OnRun(Connection& db) { track->SetValue(Track::TITLE, trackQuery.ColumnText(5)); 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::ALBUM_ID, album.c_str()); 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); + ++index; } return true; diff --git a/src/musikbox/app/query/TrackListViewQuery.h b/src/musikbox/app/query/TrackListViewQuery.h index 3d683e13b..ed18cae3d 100755 --- a/src/musikbox/app/query/TrackListViewQuery.h +++ b/src/musikbox/app/query/TrackListViewQuery.h @@ -12,6 +12,8 @@ namespace musik { typedef std::shared_ptr< std::vector > Result; + typedef std::shared_ptr > Headers; + TrackListViewQuery( musik::core::LibraryPtr library, const std::string& column, DBID id); @@ -21,11 +23,13 @@ namespace musik { std::string Name() { return "TrackListViewQuery"; } virtual Result GetResult(); + virtual Headers GetHeaders(); protected: virtual bool OnRun(musik::core::db::Connection &db); Result result; + Headers headers; private: musik::core::LibraryPtr library; diff --git a/src/musikbox/app/window/CategoryListView.cpp b/src/musikbox/app/window/CategoryListView.cpp index 557fa2179..08a08e742 100755 --- a/src/musikbox/app/window/CategoryListView.cpp +++ b/src/musikbox/app/window/CategoryListView.cpp @@ -100,7 +100,7 @@ IScrollAdapter::EntryPtr CategoryListView::Adapter::GetEntry(size_t index) { text::Ellipsize(value, this->GetWidth()); int64 attrs = (index == parent.GetSelectedIndex()) ? COLOR_PAIR(BOX_COLOR_BLACK_ON_GREEN) : -1; - IScrollAdapter::EntryPtr entry(new SingleLineEntry(value)); + std::shared_ptr entry(new SingleLineEntry(value)); entry->SetAttrs(attrs); return entry; } diff --git a/src/musikbox/app/window/EntryWithHeader.cpp b/src/musikbox/app/window/EntryWithHeader.cpp new file mode 100755 index 000000000..e88d2222f --- /dev/null +++ b/src/musikbox/app/window/EntryWithHeader.cpp @@ -0,0 +1,44 @@ +#include +#include "EntryWithHeader.h" +#include +#include + +using namespace musik::box; + +EntryWithHeader::EntryWithHeader( + const std::string& header, const std::string& value) +{ + this->header = header; + this->value = value; + this->attrs = -1; +} + +void EntryWithHeader::SetWidth(size_t width) { + this->width = width; +} + +int64 EntryWithHeader::GetAttrs(size_t line) { + return (line == 0) ? this->headerAttrs : this->attrs; +} + +void EntryWithHeader::SetAttrs(int64 headerAttrs, int64 attrs) { + this->headerAttrs = headerAttrs; + this->attrs = attrs; +} + +size_t EntryWithHeader::GetLineCount() { + return 2; +} + +#define TRUNCATE(value, width) \ + u8substr(value, 0, width > 0 ? width : 0) + +std::string EntryWithHeader::GetLine(size_t line) { + if (line == 0) { + std::string ellipsized = this->header; + musik::box::text::Ellipsize(ellipsized, this->width); + return ellipsized; + } + + return TRUNCATE(this->value, this->width); +} diff --git a/src/musikbox/app/window/EntryWithHeader.h b/src/musikbox/app/window/EntryWithHeader.h new file mode 100755 index 000000000..0d4161e8b --- /dev/null +++ b/src/musikbox/app/window/EntryWithHeader.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +namespace musik { + namespace box { + class EntryWithHeader : public cursespp::IScrollAdapter::IEntry { + public: + EntryWithHeader(const std::string& header, const std::string& value); + virtual ~EntryWithHeader() { } + + virtual void SetWidth(size_t width); + virtual int64 GetAttrs(size_t line); + virtual size_t GetLineCount(); + virtual std::string GetLine(size_t line); + + void SetAttrs(int64 headerAttrs, int64 attrs); + + private: + size_t width; + std::string header, value; + int64 headerAttrs, attrs; + }; + } +} \ No newline at end of file diff --git a/src/musikbox/app/window/TrackListView.cpp b/src/musikbox/app/window/TrackListView.cpp index 87d1ae4c9..14be19ad6 100755 --- a/src/musikbox/app/window/TrackListView.cpp +++ b/src/musikbox/app/window/TrackListView.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -68,6 +69,7 @@ void TrackListView::ProcessMessage(IMessage &message) { if (message.Type() == WINDOW_MESSAGE_QUERY_COMPLETED) { if (this->query && this->query->GetStatus() == IQuery::Finished) { this->metadata = this->query->GetResult(); + this->headers = this->query->GetHeaders(); this->query.reset(); this->SetSelectedIndex(0); this->OnAdapterChanged(); @@ -137,9 +139,15 @@ IScrollAdapter::EntryPtr TrackListView::Adapter::GetEntry(size_t index) { % group(setw(column3Width), setiosflags(std::ios::left), setfill(' '), artist) % group(setw(column4Width), setiosflags(std::ios::left), setfill(' '), album)); - IScrollAdapter::EntryPtr entry(new SingleLineEntry(text)); - - entry->SetAttrs(attrs); - - return entry; + if (this->parent.headers->find(index) != this->parent.headers->end()) { + std::string album = track->GetValue(constants::Track::ALBUM_ID); + std::shared_ptr entry(new EntryWithHeader(album, text)); + entry->SetAttrs(COLOR_PAIR(BOX_COLOR_GREEN_ON_BLACK), attrs); + return entry; + } + else { + std::shared_ptr entry(new SingleLineEntry(text)); + entry->SetAttrs(attrs); + return entry; + } } diff --git a/src/musikbox/app/window/TrackListView.h b/src/musikbox/app/window/TrackListView.h index ae6ff97f9..c29bfe5e2 100755 --- a/src/musikbox/app/window/TrackListView.h +++ b/src/musikbox/app/window/TrackListView.h @@ -51,6 +51,7 @@ namespace musik { private: std::shared_ptr query; std::shared_ptr > metadata; + std::shared_ptr > headers; Adapter* adapter; PlaybackService& playback; musik::core::LibraryPtr library; diff --git a/src/musikbox/cursespp/IScrollAdapter.h b/src/musikbox/cursespp/IScrollAdapter.h index e154a672b..c877e6160 100755 --- a/src/musikbox/cursespp/IScrollAdapter.h +++ b/src/musikbox/cursespp/IScrollAdapter.h @@ -28,10 +28,8 @@ namespace cursespp { virtual ~IEntry() { } virtual size_t GetLineCount() = 0; virtual std::string GetLine(size_t line) = 0; - virtual std::string GetValue() = 0; virtual void SetWidth(size_t width) = 0; - virtual void SetAttrs(int64 attrs) = 0; - virtual int64 GetAttrs() = 0; + virtual int64 GetAttrs(size_t line) = 0; }; typedef std::shared_ptr EntryPtr; diff --git a/src/musikbox/cursespp/MultiLineEntry.cpp b/src/musikbox/cursespp/MultiLineEntry.cpp index 1cd483e14..ceda5fe09 100755 --- a/src/musikbox/cursespp/MultiLineEntry.cpp +++ b/src/musikbox/cursespp/MultiLineEntry.cpp @@ -21,26 +21,10 @@ std::string MultiLineEntry::GetLine(size_t n) { return this->lines.at(n); } -std::string MultiLineEntry::GetValue() { - return value; -} - -size_t MultiLineEntry::GetIndex() { - return this->index; -} - -void MultiLineEntry::SetIndex(size_t index) { - this->index = index; -} - -int64 MultiLineEntry::GetAttrs() { +int64 MultiLineEntry::GetAttrs(size_t line) { return this->attrs; } -void MultiLineEntry::SetAttrs(int64 attrs) { - this->attrs = attrs; -} - inline static void breakIntoSubLines( std::string& line, size_t width, diff --git a/src/musikbox/cursespp/MultiLineEntry.h b/src/musikbox/cursespp/MultiLineEntry.h index 4c78df33e..a7aaa87b8 100755 --- a/src/musikbox/cursespp/MultiLineEntry.h +++ b/src/musikbox/cursespp/MultiLineEntry.h @@ -6,18 +6,16 @@ namespace cursespp { class MultiLineEntry : public IScrollAdapter::IEntry { public: MultiLineEntry(const std::string& value, int64 attrs = -1); + virtual ~MultiLineEntry() { } + + virtual size_t GetLineCount(); + virtual std::string GetLine(size_t line); + virtual void SetWidth(size_t width); + virtual int64 GetAttrs(size_t line); - size_t GetIndex(); - void SetIndex(size_t index); - size_t GetLineCount(); - std::string GetLine(size_t line); - std::string GetValue(); - void SetWidth(size_t width); void SetAttrs(int64 attrs); - int64 GetAttrs(); private: - size_t index; std::string value; std::vector lines; size_t charCount; diff --git a/src/musikbox/cursespp/ScrollAdapterBase.cpp b/src/musikbox/cursespp/ScrollAdapterBase.cpp index 4cfaea2a8..a4807442e 100755 --- a/src/musikbox/cursespp/ScrollAdapterBase.cpp +++ b/src/musikbox/cursespp/ScrollAdapterBase.cpp @@ -101,13 +101,14 @@ void ScrollAdapterBase::DrawPage(WINDOW* window, size_t index, ScrollPosition *r for (size_t e = 0; e < visible.size(); e++) { EntryPtr entry = visible.at(e); size_t count = entry->GetLineCount(); - int64 attrs = entry->GetAttrs(); - - if (attrs != -1) { - wattron(window, attrs); - } for (size_t i = 0; i < count && drawnLines < this->height; i++) { + int64 attrs = entry->GetAttrs(i); + + if (attrs != -1) { + wattron(window, attrs); + } + std::string line = entry->GetLine(i); size_t len = u8len(line); @@ -123,11 +124,11 @@ void ScrollAdapterBase::DrawPage(WINDOW* window, size_t index, ScrollPosition *r wprintw(window, "%s", line.c_str()); - ++drawnLines; - } + if (attrs != -1) { + wattroff(window, attrs); + } - if (attrs != -1) { - wattroff(window, attrs); + ++drawnLines; } } diff --git a/src/musikbox/cursespp/SingleLineEntry.cpp b/src/musikbox/cursespp/SingleLineEntry.cpp index f6b01d838..14c7f4849 100755 --- a/src/musikbox/cursespp/SingleLineEntry.cpp +++ b/src/musikbox/cursespp/SingleLineEntry.cpp @@ -9,19 +9,11 @@ SingleLineEntry::SingleLineEntry(const std::string& value) { this->attrs = -1; } -size_t SingleLineEntry::GetIndex() { - return this->index; -} - void SingleLineEntry::SetWidth(size_t width) { this->width = width; } -void SingleLineEntry::SetIndex(size_t index) { - this->index = index; -} - -int64 SingleLineEntry::GetAttrs() { +int64 SingleLineEntry::GetAttrs(size_t line) { return this->attrs; } @@ -35,8 +27,4 @@ size_t SingleLineEntry::GetLineCount() { std::string SingleLineEntry::GetLine(size_t line) { return u8substr(this->value, 0, this->width > 0 ? this->width : 0); -} - -std::string SingleLineEntry::GetValue() { - return this->value; } \ No newline at end of file diff --git a/src/musikbox/cursespp/SingleLineEntry.h b/src/musikbox/cursespp/SingleLineEntry.h index d3cdc3a5d..97de8d60d 100755 --- a/src/musikbox/cursespp/SingleLineEntry.h +++ b/src/musikbox/cursespp/SingleLineEntry.h @@ -6,19 +6,17 @@ namespace cursespp { class SingleLineEntry : public IScrollAdapter::IEntry { public: SingleLineEntry(const std::string& value); + virtual ~SingleLineEntry() { } + + virtual void SetWidth(size_t width); + virtual int64 GetAttrs(size_t line); + virtual size_t GetLineCount(); + virtual std::string GetLine(size_t line); - size_t GetIndex(); - void SetIndex(size_t index); - void SetWidth(size_t width); void SetAttrs(int64 attrs); - int64 GetAttrs(); - - size_t GetLineCount(); - std::string GetLine(size_t line); - std::string GetValue(); - + private: - size_t index, width; + size_t width; std::string value; int64 attrs; }; diff --git a/src/musikbox/musikbox.vcxproj b/src/musikbox/musikbox.vcxproj index 1688de794..9d8f8b50d 100755 --- a/src/musikbox/musikbox.vcxproj +++ b/src/musikbox/musikbox.vcxproj @@ -60,7 +60,7 @@ Disabled ./;../;../3rdparty/include;../3rdparty/win32_include;../../../boost_1_60_0;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebug @@ -89,7 +89,7 @@ ./;../;../3rdparty/include;../3rdparty/win32_include;../../../boost_1_60_0;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;NDEBUG;_CONSOLE;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreaded Use Level3 @@ -126,6 +126,7 @@ + @@ -163,6 +164,7 @@ + diff --git a/src/musikbox/musikbox.vcxproj.filters b/src/musikbox/musikbox.vcxproj.filters index 5929a7fe4..e537b1190 100755 --- a/src/musikbox/musikbox.vcxproj.filters +++ b/src/musikbox/musikbox.vcxproj.filters @@ -93,6 +93,9 @@ app + + app\window + @@ -225,6 +228,9 @@ cursespp + + app\window +