mirror of
https://github.com/clangen/musikcube.git
synced 2025-02-14 18:40:48 +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();
|
||||
void LoadDecoderPlugins();
|
||||
|
||||
private:
|
||||
typedef std::list<BufferPtr> BufferList;
|
||||
typedef std::shared_ptr<IDecoderFactory> DecoderFactoryPtr;
|
||||
typedef std::vector<DecoderFactoryPtr> DecoderFactoryList;
|
||||
|
@ -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;
|
||||
|
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->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) {
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,8 @@ namespace musik {
|
||||
PlaybackService& playback;
|
||||
musik::core::TrackPtr playing;
|
||||
musik::core::LibraryPtr library;
|
||||
|
||||
size_t lastQueryHash;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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" />
|
||||
|
@ -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">
|
||||
|
Loading…
x
Reference in New Issue
Block a user