A couple small but important fixes:

- Don't adjust scroll position in TrackListView after a requery if the
  query contents haven't actually changed
- Ensure resizing doesn't lose the selected item in ListWindow
- Added the concept of query hashes and generalized TrackListQueryBase
  so different types of queries can be supplied to a TrackListView.
This commit is contained in:
casey 2016-06-02 18:45:16 -07:00
parent 32965dd2af
commit 8b14ddb5e8
13 changed files with 95 additions and 27 deletions

View File

@ -75,7 +75,6 @@ namespace musik { namespace core { namespace audio {
BufferPtr GetEmptyBuffer();
void LoadDecoderPlugins();
private:
typedef std::list<BufferPtr> BufferList;
typedef std::shared_ptr<IDecoderFactory> DecoderFactoryPtr;
typedef std::vector<DecoderFactoryPtr> DecoderFactoryList;

View File

@ -17,7 +17,7 @@ using namespace musik::core::library::constants;
#define TRANSPORT_HEIGHT 2
#endif
#define DEFAULT_CATEGORY constants::Track::ALBUM_ID
#define DEFAULT_CATEGORY constants::Track::ARTIST_ID
using namespace musik::core;
using namespace musik::core::audio;

View File

@ -0,0 +1,24 @@
#pragma once
#include <core/library/query/QueryBase.h>
#include <core/db/Connection.h>
#include <core/library/track/Track.h>
#include "CategoryListViewQuery.h"
namespace musik {
namespace box {
class TrackListQueryBase : public musik::core::query::QueryBase {
public:
typedef std::shared_ptr<
std::vector<musik::core::TrackPtr> > Result;
typedef std::shared_ptr<std::set<size_t> > Headers;
virtual ~TrackListQueryBase() { };
virtual std::string Name() = 0;
virtual Result GetResult() = 0;
virtual Headers GetHeaders() = 0;
virtual size_t GetQueryHash() = 0;
};
}
}

View File

@ -21,6 +21,9 @@ TrackListViewQuery::TrackListViewQuery(LibraryPtr library, const std::string& co
this->id = id;
this->result.reset(new std::vector<TrackPtr>());
this->headers.reset(new std::set<size_t>());
this->hash = 0;
this->GetQueryHash();
}
TrackListViewQuery::~TrackListViewQuery() {
@ -35,13 +38,24 @@ TrackListViewQuery::Headers TrackListViewQuery::GetHeaders() {
return this->headers;
}
size_t TrackListViewQuery::GetQueryHash() {
if (this->hash == 0) {
std::string parts = boost::str(
boost::format("%s-%s") % this->column % this->id);
this->hash = std::hash<std::string>()(parts);
}
return this->hash;
}
bool TrackListViewQuery::OnRun(Connection& db) {
if (result) {
result.reset(new std::vector<TrackPtr>());
headers.reset(new std::set<size_t>());
}
std::string query = boost::str(boost::format(
this->query = boost::str(boost::format(
"SELECT DISTINCT t.id, 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 "
@ -50,7 +64,7 @@ bool TrackListViewQuery::OnRun(Connection& db) {
std::string lastAlbum;
size_t index = 0;
Statement trackQuery(query.c_str(), db);
Statement trackQuery(this->query.c_str(), db);
trackQuery.BindInt(0, this->id);
while (trackQuery.Step() == Row) {

View File

@ -3,38 +3,37 @@
#include <core/library/query/QueryBase.h>
#include <core/db/Connection.h>
#include <core/library/track/Track.h>
#include "CategoryListViewQuery.h"
#include "TrackListQueryBase.h"
namespace musik {
namespace box {
class TrackListViewQuery : public musik::core::query::QueryBase {
class TrackListViewQuery : public TrackListQueryBase {
public:
typedef std::shared_ptr<
std::vector<musik::core::TrackPtr> > Result;
typedef std::shared_ptr<std::set<size_t> > Headers;
TrackListViewQuery(
musik::core::LibraryPtr library,
const std::string& column, DBID id);
const std::string& column,
DBID id);
virtual ~TrackListViewQuery();
std::string Name() { return "TrackListViewQuery"; }
virtual std::string Name() { return "TrackListViewQuery"; }
virtual Result GetResult();
virtual Headers GetHeaders();
virtual size_t GetQueryHash();
protected:
virtual bool OnRun(musik::core::db::Connection &db);
Result result;
Headers headers;
private:
musik::core::LibraryPtr library;
Result result;
Headers headers;
std::string column;
DBID id;
std::string query;
size_t hash;
};
}
}

View File

@ -140,16 +140,18 @@ void CommandWindow::Help() {
this->output->WriteLine(" <F1> console view", s);
this->output->WriteLine(" <F2> library view", s);
this->output->WriteLine("\n", s);
this->output->WriteLine(" play <uri>: play audio at location", s);
this->output->WriteLine(" addir <dir>: add a music directory", s);
this->output->WriteLine(" rmdir <dir>: remove a music directory", s);
this->output->WriteLine(" lsdirs: list scanned directories", s);
this->output->WriteLine(" rescan: rescan paths for new metadata", s);
this->output->WriteLine("\n", s);
this->output->WriteLine(" play <uri>: play audio at <uri>", s);
this->output->WriteLine(" pause: pause/resume", s);
this->output->WriteLine(" stop: stop all playback", s);
this->output->WriteLine(" stop: stop and clean up everything", s);
this->output->WriteLine(" volume: <0 - 100>: set % volume", s);
this->output->WriteLine(" clear: clear the log window", s);
this->output->WriteLine(" seek <seconds>: seek to <seconds> into track", s);
this->output->WriteLine(" addir <dir>: add a directory to be indexed", s);
this->output->WriteLine(" rmdir <dir>: remove indexed directory path", s);
this->output->WriteLine(" lsdirs: list scanned directories", s);
this->output->WriteLine(" rescan: rescan paths for new metadata", s);
this->output->WriteLine("\n", s);
this->output->WriteLine(" plugins: list loaded plugins", s);
this->output->WriteLine("\n <ctrl+d>: quit\n", s);
}
@ -254,10 +256,9 @@ void CommandWindow::ListPlugins() const {
PluginList::iterator it = plugins.begin();
for (; it != plugins.end(); it++) {
std::string format =
"plugin:\n"
" name: " + std::string((*it)->Name()) + " "
" " + std::string((*it)->Name()) + " "
"v" + std::string((*it)->Version()) + "\n"
" author: " + std::string((*it)->Author()) + "\n";
" by " + std::string((*it)->Author()) + "\n";
this->output->WriteLine(format, BOX_COLOR_RED_ON_BLUE);
}

View File

@ -37,6 +37,7 @@ TrackListView::TrackListView(PlaybackService& playback, LibraryPtr library)
this->library->QueryCompleted.connect(this, &TrackListView::OnQueryCompleted);
this->playback.TrackChanged.connect(this, &TrackListView::OnTrackChanged);
this->adapter = new Adapter(*this);
this->lastQueryHash = 0;
}
TrackListView::~TrackListView() {
@ -71,8 +72,16 @@ void TrackListView::ProcessMessage(IMessage &message) {
if (this->query && this->query->GetStatus() == IQuery::Finished) {
this->metadata = this->query->GetResult();
this->headers = this->query->GetHeaders();
/* if the query was functionally the same as the last query, don't
mess with the selected index */
if (this->lastQueryHash != query->GetQueryHash()) {
this->SetSelectedIndex(0);
}
this->lastQueryHash = this->query->GetQueryHash();
this->query.reset();
this->SetSelectedIndex(0);
this->OnAdapterChanged();
}
}

View File

@ -58,6 +58,8 @@ namespace musik {
PlaybackService& playback;
musik::core::TrackPtr playing;
musik::core::LibraryPtr library;
size_t lastQueryHash;
};
}
}

View File

@ -152,6 +152,15 @@ void ListWindow::OnAdapterChanged() {
this->Repaint();
}
void ListWindow::OnSizeChanged() {
ScrollableWindow::OnSizeChanged();
this->GetScrollAdapter().DrawPage(
this->GetContent(),
this->selectedIndex,
&this->GetScrollPosition());
}
IScrollAdapter::ScrollPosition& ListWindow::GetScrollPosition() {
return this->scrollPosition;
}

View File

@ -30,6 +30,7 @@ namespace cursespp {
virtual void OnAdapterChanged();
virtual void OnSelectionChanged(size_t newIndex, size_t oldIndex);
virtual void OnInvalidated();
virtual void OnSizeChanged();
virtual IScrollAdapter::ScrollPosition& GetScrollPosition();

View File

@ -29,7 +29,13 @@ ScrollableWindow::~ScrollableWindow() {
void ScrollableWindow::OnSizeChanged() {
Window::OnSizeChanged();
GetScrollAdapter().SetDisplaySize(GetContentWidth(), GetContentHeight());
IScrollAdapter& adapter = this->GetScrollAdapter();
ScrollPos& pos = this->GetScrollPosition();
adapter.SetDisplaySize(
this->GetContentWidth(),
this->GetContentHeight());
}
ScrollPos& ScrollableWindow::GetScrollPosition() {

View File

@ -156,6 +156,7 @@
<ClInclude Include="app\layout\LibraryLayout.h" />
<ClInclude Include="app\layout\MainLayout.h" />
<ClInclude Include="app\query\CategoryListViewQuery.h" />
<ClInclude Include="app\query\TrackListQueryBase.h" />
<ClInclude Include="app\query\SingleTrackQuery.h" />
<ClInclude Include="app\query\TrackListViewQuery.h" />
<ClInclude Include="app\service\PlaybackService.h" />

View File

@ -231,6 +231,9 @@
<ClInclude Include="app\window\EntryWithHeader.h">
<Filter>app\window</Filter>
</ClInclude>
<ClInclude Include="app\query\TrackListQueryBase.h">
<Filter>app\query</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="cursespp">