mirror of
https://github.com/clangen/musikcube.git
synced 2025-02-19 15:40:50 +00:00
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:
parent
32965dd2af
commit
8b14ddb5e8
@ -75,7 +75,6 @@ namespace musik { namespace core { namespace audio {
|
|||||||
BufferPtr GetEmptyBuffer();
|
BufferPtr GetEmptyBuffer();
|
||||||
void LoadDecoderPlugins();
|
void LoadDecoderPlugins();
|
||||||
|
|
||||||
private:
|
|
||||||
typedef std::list<BufferPtr> BufferList;
|
typedef std::list<BufferPtr> BufferList;
|
||||||
typedef std::shared_ptr<IDecoderFactory> DecoderFactoryPtr;
|
typedef std::shared_ptr<IDecoderFactory> DecoderFactoryPtr;
|
||||||
typedef std::vector<DecoderFactoryPtr> DecoderFactoryList;
|
typedef std::vector<DecoderFactoryPtr> DecoderFactoryList;
|
||||||
|
@ -17,7 +17,7 @@ using namespace musik::core::library::constants;
|
|||||||
#define TRANSPORT_HEIGHT 2
|
#define TRANSPORT_HEIGHT 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_CATEGORY constants::Track::ALBUM_ID
|
#define DEFAULT_CATEGORY constants::Track::ARTIST_ID
|
||||||
|
|
||||||
using namespace musik::core;
|
using namespace musik::core;
|
||||||
using namespace musik::core::audio;
|
using namespace musik::core::audio;
|
||||||
|
24
src/musikbox/app/query/TrackListQueryBase.h
Executable file
24
src/musikbox/app/query/TrackListQueryBase.h
Executable 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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,9 @@ TrackListViewQuery::TrackListViewQuery(LibraryPtr library, const std::string& co
|
|||||||
this->id = id;
|
this->id = id;
|
||||||
this->result.reset(new std::vector<TrackPtr>());
|
this->result.reset(new std::vector<TrackPtr>());
|
||||||
this->headers.reset(new std::set<size_t>());
|
this->headers.reset(new std::set<size_t>());
|
||||||
|
this->hash = 0;
|
||||||
|
|
||||||
|
this->GetQueryHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackListViewQuery::~TrackListViewQuery() {
|
TrackListViewQuery::~TrackListViewQuery() {
|
||||||
@ -35,13 +38,24 @@ TrackListViewQuery::Headers TrackListViewQuery::GetHeaders() {
|
|||||||
return this->headers;
|
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) {
|
bool TrackListViewQuery::OnRun(Connection& db) {
|
||||||
if (result) {
|
if (result) {
|
||||||
result.reset(new std::vector<TrackPtr>());
|
result.reset(new std::vector<TrackPtr>());
|
||||||
headers.reset(new std::set<size_t>());
|
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 " \
|
"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 " \
|
"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 "
|
"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;
|
std::string lastAlbum;
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
|
|
||||||
Statement trackQuery(query.c_str(), db);
|
Statement trackQuery(this->query.c_str(), db);
|
||||||
|
|
||||||
trackQuery.BindInt(0, this->id);
|
trackQuery.BindInt(0, this->id);
|
||||||
while (trackQuery.Step() == Row) {
|
while (trackQuery.Step() == Row) {
|
||||||
|
@ -3,38 +3,37 @@
|
|||||||
#include <core/library/query/QueryBase.h>
|
#include <core/library/query/QueryBase.h>
|
||||||
#include <core/db/Connection.h>
|
#include <core/db/Connection.h>
|
||||||
#include <core/library/track/Track.h>
|
#include <core/library/track/Track.h>
|
||||||
#include "CategoryListViewQuery.h"
|
|
||||||
|
#include "TrackListQueryBase.h"
|
||||||
|
|
||||||
namespace musik {
|
namespace musik {
|
||||||
namespace box {
|
namespace box {
|
||||||
class TrackListViewQuery : public musik::core::query::QueryBase {
|
class TrackListViewQuery : public TrackListQueryBase {
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<
|
|
||||||
std::vector<musik::core::TrackPtr> > Result;
|
|
||||||
|
|
||||||
typedef std::shared_ptr<std::set<size_t> > Headers;
|
|
||||||
|
|
||||||
TrackListViewQuery(
|
TrackListViewQuery(
|
||||||
musik::core::LibraryPtr library,
|
musik::core::LibraryPtr library,
|
||||||
const std::string& column, DBID id);
|
const std::string& column,
|
||||||
|
DBID id);
|
||||||
|
|
||||||
virtual ~TrackListViewQuery();
|
virtual ~TrackListViewQuery();
|
||||||
|
|
||||||
std::string Name() { return "TrackListViewQuery"; }
|
virtual std::string Name() { return "TrackListViewQuery"; }
|
||||||
|
|
||||||
virtual Result GetResult();
|
virtual Result GetResult();
|
||||||
virtual Headers GetHeaders();
|
virtual Headers GetHeaders();
|
||||||
|
virtual size_t GetQueryHash();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool OnRun(musik::core::db::Connection &db);
|
virtual bool OnRun(musik::core::db::Connection &db);
|
||||||
|
|
||||||
Result result;
|
|
||||||
Headers headers;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
musik::core::LibraryPtr library;
|
musik::core::LibraryPtr library;
|
||||||
|
Result result;
|
||||||
|
Headers headers;
|
||||||
std::string column;
|
std::string column;
|
||||||
DBID id;
|
DBID id;
|
||||||
|
std::string query;
|
||||||
|
size_t hash;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,16 +140,18 @@ void CommandWindow::Help() {
|
|||||||
this->output->WriteLine(" <F1> console view", s);
|
this->output->WriteLine(" <F1> console view", s);
|
||||||
this->output->WriteLine(" <F2> library view", s);
|
this->output->WriteLine(" <F2> library view", s);
|
||||||
this->output->WriteLine("\n", 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(" 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(" volume: <0 - 100>: set % volume", s);
|
||||||
this->output->WriteLine(" clear: clear the log window", s);
|
this->output->WriteLine(" clear: clear the log window", s);
|
||||||
this->output->WriteLine(" seek <seconds>: seek to <seconds> into track", 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("\n", 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(" plugins: list loaded plugins", s);
|
this->output->WriteLine(" plugins: list loaded plugins", s);
|
||||||
this->output->WriteLine("\n <ctrl+d>: quit\n", s);
|
this->output->WriteLine("\n <ctrl+d>: quit\n", s);
|
||||||
}
|
}
|
||||||
@ -254,10 +256,9 @@ void CommandWindow::ListPlugins() const {
|
|||||||
PluginList::iterator it = plugins.begin();
|
PluginList::iterator it = plugins.begin();
|
||||||
for (; it != plugins.end(); it++) {
|
for (; it != plugins.end(); it++) {
|
||||||
std::string format =
|
std::string format =
|
||||||
"plugin:\n"
|
" " + std::string((*it)->Name()) + " "
|
||||||
" name: " + std::string((*it)->Name()) + " "
|
|
||||||
"v" + std::string((*it)->Version()) + "\n"
|
"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);
|
this->output->WriteLine(format, BOX_COLOR_RED_ON_BLUE);
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ TrackListView::TrackListView(PlaybackService& playback, LibraryPtr library)
|
|||||||
this->library->QueryCompleted.connect(this, &TrackListView::OnQueryCompleted);
|
this->library->QueryCompleted.connect(this, &TrackListView::OnQueryCompleted);
|
||||||
this->playback.TrackChanged.connect(this, &TrackListView::OnTrackChanged);
|
this->playback.TrackChanged.connect(this, &TrackListView::OnTrackChanged);
|
||||||
this->adapter = new Adapter(*this);
|
this->adapter = new Adapter(*this);
|
||||||
|
this->lastQueryHash = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackListView::~TrackListView() {
|
TrackListView::~TrackListView() {
|
||||||
@ -71,8 +72,16 @@ void TrackListView::ProcessMessage(IMessage &message) {
|
|||||||
if (this->query && this->query->GetStatus() == IQuery::Finished) {
|
if (this->query && this->query->GetStatus() == IQuery::Finished) {
|
||||||
this->metadata = this->query->GetResult();
|
this->metadata = this->query->GetResult();
|
||||||
this->headers = this->query->GetHeaders();
|
this->headers = this->query->GetHeaders();
|
||||||
this->query.reset();
|
|
||||||
|
/* 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->SetSelectedIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->lastQueryHash = this->query->GetQueryHash();
|
||||||
|
this->query.reset();
|
||||||
|
|
||||||
this->OnAdapterChanged();
|
this->OnAdapterChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,8 @@ namespace musik {
|
|||||||
PlaybackService& playback;
|
PlaybackService& playback;
|
||||||
musik::core::TrackPtr playing;
|
musik::core::TrackPtr playing;
|
||||||
musik::core::LibraryPtr library;
|
musik::core::LibraryPtr library;
|
||||||
|
|
||||||
|
size_t lastQueryHash;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,6 +152,15 @@ void ListWindow::OnAdapterChanged() {
|
|||||||
this->Repaint();
|
this->Repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ListWindow::OnSizeChanged() {
|
||||||
|
ScrollableWindow::OnSizeChanged();
|
||||||
|
|
||||||
|
this->GetScrollAdapter().DrawPage(
|
||||||
|
this->GetContent(),
|
||||||
|
this->selectedIndex,
|
||||||
|
&this->GetScrollPosition());
|
||||||
|
}
|
||||||
|
|
||||||
IScrollAdapter::ScrollPosition& ListWindow::GetScrollPosition() {
|
IScrollAdapter::ScrollPosition& ListWindow::GetScrollPosition() {
|
||||||
return this->scrollPosition;
|
return this->scrollPosition;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ namespace cursespp {
|
|||||||
virtual void OnAdapterChanged();
|
virtual void OnAdapterChanged();
|
||||||
virtual void OnSelectionChanged(size_t newIndex, size_t oldIndex);
|
virtual void OnSelectionChanged(size_t newIndex, size_t oldIndex);
|
||||||
virtual void OnInvalidated();
|
virtual void OnInvalidated();
|
||||||
|
virtual void OnSizeChanged();
|
||||||
|
|
||||||
virtual IScrollAdapter::ScrollPosition& GetScrollPosition();
|
virtual IScrollAdapter::ScrollPosition& GetScrollPosition();
|
||||||
|
|
||||||
|
@ -29,7 +29,13 @@ ScrollableWindow::~ScrollableWindow() {
|
|||||||
|
|
||||||
void ScrollableWindow::OnSizeChanged() {
|
void ScrollableWindow::OnSizeChanged() {
|
||||||
Window::OnSizeChanged();
|
Window::OnSizeChanged();
|
||||||
GetScrollAdapter().SetDisplaySize(GetContentWidth(), GetContentHeight());
|
|
||||||
|
IScrollAdapter& adapter = this->GetScrollAdapter();
|
||||||
|
ScrollPos& pos = this->GetScrollPosition();
|
||||||
|
|
||||||
|
adapter.SetDisplaySize(
|
||||||
|
this->GetContentWidth(),
|
||||||
|
this->GetContentHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollPos& ScrollableWindow::GetScrollPosition() {
|
ScrollPos& ScrollableWindow::GetScrollPosition() {
|
||||||
|
@ -156,6 +156,7 @@
|
|||||||
<ClInclude Include="app\layout\LibraryLayout.h" />
|
<ClInclude Include="app\layout\LibraryLayout.h" />
|
||||||
<ClInclude Include="app\layout\MainLayout.h" />
|
<ClInclude Include="app\layout\MainLayout.h" />
|
||||||
<ClInclude Include="app\query\CategoryListViewQuery.h" />
|
<ClInclude Include="app\query\CategoryListViewQuery.h" />
|
||||||
|
<ClInclude Include="app\query\TrackListQueryBase.h" />
|
||||||
<ClInclude Include="app\query\SingleTrackQuery.h" />
|
<ClInclude Include="app\query\SingleTrackQuery.h" />
|
||||||
<ClInclude Include="app\query\TrackListViewQuery.h" />
|
<ClInclude Include="app\query\TrackListViewQuery.h" />
|
||||||
<ClInclude Include="app\service\PlaybackService.h" />
|
<ClInclude Include="app\service\PlaybackService.h" />
|
||||||
|
@ -231,6 +231,9 @@
|
|||||||
<ClInclude Include="app\window\EntryWithHeader.h">
|
<ClInclude Include="app\window\EntryWithHeader.h">
|
||||||
<Filter>app\window</Filter>
|
<Filter>app\window</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="app\query\TrackListQueryBase.h">
|
||||||
|
<Filter>app\query</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="cursespp">
|
<Filter Include="cursespp">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user