- Renamed MainLayout -> ConsoleLayout

- Refactored TrackListView to not deal with PlaybackService directly.
  This is the job of the "Controller" which doesn't exist yet.
- Tweaked LibraryLayout to act more like a Controller, and start
  playback when the user presses enter.
- Added a hacked up NowPlaying layout.
This commit is contained in:
casey 2016-06-02 21:45:44 -07:00
parent 8b14ddb5e8
commit 535367d705
17 changed files with 298 additions and 79 deletions

View File

@ -1,11 +1,13 @@
set (BOX_SRCS
./Main.cpp
./stdafx.cpp
./app/layout/ConsoleLayout.cpp
./app/layout/LibraryLayout.cpp
./app/layout/MainLayout.cpp
./app/layout/NowPlayingLayout.cpp
./app/query/CategoryListViewQuery.cpp
./app/query/SingleTrackQuery.cpp
./app/query/TrackListViewQuery.cpp
./app/query/CategoryTrackListQuery.cpp
./app/query/NowPlayingTrackListQuery.cpp
./app/service/PlaybackService.cpp
./app/util/GlobalHotkeys.cpp
./app/util/SystemInfo.cpp

View File

@ -40,9 +40,9 @@
#include <cursespp/LayoutStack.h>
#include <cursespp/WindowLayout.h>
#include <app/layout/MainLayout.h>
#include <app/layout/ConsoleLayout.h>
#include <app/layout/LibraryLayout.h>
#include <app/window/OutputWindow.h>
#include <app/layout/NowPlayingLayout.h>
#include <app/util/GlobalHotkeys.h>
#include <app/service/PlaybackService.h>
@ -238,7 +238,8 @@ int main(int argc, char* argv[])
GlobalHotkeys globalHotkeys(playback, library);
ILayoutPtr libraryLayout((ILayout *) new LibraryLayout(playback, library));
ILayoutPtr consoleLayout((ILayout *) new MainLayout(tp, library));
ILayoutPtr nowPlayingLayout((ILayout *) new NowPlayingLayout(playback, library));
ILayoutPtr consoleLayout((ILayout *) new ConsoleLayout(tp, library));
int64 ch;
timeout(IDLE_TIMEOUT_MS);
@ -281,11 +282,14 @@ int main(int argc, char* argv[])
else if (kn == "KEY_RESIZE") {
resizeAt = now() + REDRAW_DEBOUNCE_MS;
}
else if (ch == KEY_F(1)) {
changeLayout(state, consoleLayout);
}
else if (ch == KEY_F(2)) {
changeLayout(state, libraryLayout);
}
else if (ch == KEY_F(1)) {
changeLayout(state, consoleLayout);
else if (ch == KEY_F(3)) {
changeLayout(state, nowPlayingLayout);
}
else if (!globalHotkeys.Handle(kn)) {
if (state.input) {

View File

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "MainLayout.h"
#include "ConsoleLayout.h"
#include <cursespp/Screen.h>
#include <cursespp/IMessage.h>
@ -11,7 +11,7 @@ using namespace musik::core::audio;
using namespace musik::box;
using namespace cursespp;
MainLayout::MainLayout(Transport& transport, LibraryPtr library)
ConsoleLayout::ConsoleLayout(Transport& transport, LibraryPtr library)
: LayoutBase() {
this->logs.reset(new LogWindow(this));
this->output.reset(new OutputWindow(this));
@ -32,11 +32,11 @@ MainLayout::MainLayout(Transport& transport, LibraryPtr library)
this->PostMessage(MESSAGE_TYPE_UPDATE, 0, 0, UPDATE_INTERVAL_MS);
}
MainLayout::~MainLayout() {
ConsoleLayout::~ConsoleLayout() {
}
void MainLayout::Layout() {
void ConsoleLayout::Layout() {
/* this layout */
this->MoveAndResize(
0,
@ -81,19 +81,19 @@ void MainLayout::Layout() {
3);
}
void MainLayout::Show() {
void ConsoleLayout::Show() {
LayoutBase::Show();
this->UpdateWindows();
}
void MainLayout::ProcessMessage(IMessage &message) {
void ConsoleLayout::ProcessMessage(IMessage &message) {
if (message.Type() == MESSAGE_TYPE_UPDATE) {
this->UpdateWindows();
this->PostMessage(MESSAGE_TYPE_UPDATE, 0, 0, UPDATE_INTERVAL_MS);
}
}
void MainLayout::UpdateWindows() {
void ConsoleLayout::UpdateWindows() {
this->logs->Update();
this->resources->Update();
}

View File

@ -15,13 +15,13 @@
namespace musik {
namespace box {
class MainLayout : public cursespp::LayoutBase {
class ConsoleLayout : public cursespp::LayoutBase {
public:
MainLayout(
ConsoleLayout(
musik::core::audio::Transport& transport,
musik::core::LibraryPtr library);
~MainLayout();
~ConsoleLayout();
virtual void Layout();
virtual void Show();

View File

@ -5,6 +5,8 @@
#include <core/library/LocalLibraryConstants.h>
#include <app/query/CategoryTrackListQuery.h>
#include "LibraryLayout.h"
using namespace musik::core::library::constants;
@ -95,9 +97,13 @@ void LibraryLayout::Show() {
void LibraryLayout::RequeryTrackList(ListWindow *view) {
if (view == this->categoryList.get()) {
DBID id = this->categoryList->GetSelectedId();
if (id != -1) {
this->trackList->Requery(this->categoryList->GetFieldName(), id);
DBID selectedId = this->categoryList->GetSelectedId();
if (selectedId != -1) {
this->trackList->Requery(std::shared_ptr<TrackListQueryBase>(
new CategoryTrackListQuery(
this->library,
this->categoryList->GetFieldName(),
selectedId)));
}
}
}
@ -113,7 +119,16 @@ void LibraryLayout::OnCategoryViewInvalidated(
}
bool LibraryLayout::KeyPress(const std::string& key) {
if (key == "ALT_1" || key == "M-1") {
if (key == "^M") { /* enter. play the selection */
auto tracks = this->trackList->GetTrackList();
auto focus = this->GetFocus();
size_t index = (focus == this->trackList)
? this->trackList->GetSelectedIndex() : 0;
this->playback.Play(*tracks, index);
}
else if (key == "ALT_1" || key == "M-1") {
this->categoryList->SetFieldName(constants::Track::ARTIST_ID);
return true;
}
@ -129,16 +144,6 @@ bool LibraryLayout::KeyPress(const std::string& key) {
this->categoryList->Requery();
return true;
}
else if (key == "CTL_DOWN") {
this->focused = this->transportView;
this->transportView->Focus();
}
else if (key == "CTL_UP") {
if (this->focused) {
this->focused->Blur();
this->focused.reset();
}
}
else if (key == " ") {
/* copied from GlobalHotkeys. should probably be generalized
at some point. */

View File

@ -0,0 +1,64 @@
#include "stdafx.h"
#include <cursespp/Colors.h>
#include <cursespp/Screen.h>
#include <core/library/LocalLibraryConstants.h>
#include <app/query/NowPlayingTrackListQuery.h>
#include "NowPlayingLayout.h"
using namespace musik::core::library::constants;
using namespace musik::core;
using namespace musik::core::audio;
using namespace musik::core::library;
using namespace musik::box;
using namespace cursespp;
NowPlayingLayout::NowPlayingLayout(
PlaybackService& playback,
musik::core::LibraryPtr library)
: LayoutBase()
, playback(playback)
, library(library) {
this->InitializeWindows();
}
NowPlayingLayout::~NowPlayingLayout() {
}
void NowPlayingLayout::Layout() {
this->SetSize(Screen::GetWidth(), Screen::GetHeight());
this->SetPosition(0, 0);
this->trackList->MoveAndResize(
0,
0,
this->GetWidth(),
this->GetHeight());
this->trackList->SetFocusOrder(1);
}
void NowPlayingLayout::InitializeWindows() {
this->trackList.reset(new TrackListView(this->playback, this->library));
this->AddWindow(this->trackList);
this->Layout();
}
IWindowPtr NowPlayingLayout::GetFocus() {
return this->trackList;
}
void NowPlayingLayout::Show() {
LayoutBase::Show();
this->RequeryTrackList();
}
void NowPlayingLayout::RequeryTrackList() {
this->trackList->Requery(std::shared_ptr<TrackListQueryBase>(
new NowPlayingTrackListQuery(this->playback)));
}

View File

@ -0,0 +1,38 @@
#pragma once
#include <cursespp/LayoutBase.h>
#include <app/window/CategoryListView.h>
#include <app/window/TrackListView.h>
#include <app/window/TransportWindow.h>
#include <app/service/PlaybackService.h>
#include <core/playback/Transport.h>
#include <core/library/ILibrary.h>
#include <sigslot/sigslot.h>
namespace musik {
namespace box {
class NowPlayingLayout : public cursespp::LayoutBase, public sigslot::has_slots<> {
public:
NowPlayingLayout(
PlaybackService& playback,
musik::core::LibraryPtr library);
virtual ~NowPlayingLayout();
virtual void Layout();
virtual void Show();
virtual cursespp::IWindowPtr GetFocus();
private:
void InitializeWindows();
void RequeryTrackList();
PlaybackService& playback;
musik::core::LibraryPtr library;
std::shared_ptr<TrackListView> trackList;
};
}
}

View File

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "TrackListViewQuery.h"
#include "CategoryTrackListQuery.h"
#include <core/library/track/LibraryTrack.h>
#include <core/library/LocalLibraryConstants.h>
@ -15,7 +15,7 @@ using namespace musik::core::db;
using namespace musik::core::library::constants;
using namespace musik::box;
TrackListViewQuery::TrackListViewQuery(LibraryPtr library, const std::string& column, DBID id) {
CategoryTrackListQuery::CategoryTrackListQuery(LibraryPtr library, const std::string& column, DBID id) {
this->library = library;
this->column = column;
this->id = id;
@ -26,19 +26,19 @@ TrackListViewQuery::TrackListViewQuery(LibraryPtr library, const std::string& co
this->GetQueryHash();
}
TrackListViewQuery::~TrackListViewQuery() {
CategoryTrackListQuery::~CategoryTrackListQuery() {
}
TrackListViewQuery::Result TrackListViewQuery::GetResult() {
CategoryTrackListQuery::Result CategoryTrackListQuery::GetResult() {
return this->result;
}
TrackListViewQuery::Headers TrackListViewQuery::GetHeaders() {
CategoryTrackListQuery::Headers CategoryTrackListQuery::GetHeaders() {
return this->headers;
}
size_t TrackListViewQuery::GetQueryHash() {
size_t CategoryTrackListQuery::GetQueryHash() {
if (this->hash == 0) {
std::string parts = boost::str(
boost::format("%s-%s") % this->column % this->id);
@ -49,7 +49,7 @@ size_t TrackListViewQuery::GetQueryHash() {
return this->hash;
}
bool TrackListViewQuery::OnRun(Connection& db) {
bool CategoryTrackListQuery::OnRun(Connection& db) {
if (result) {
result.reset(new std::vector<TrackPtr>());
headers.reset(new std::set<size_t>());

View File

@ -8,16 +8,16 @@
namespace musik {
namespace box {
class TrackListViewQuery : public TrackListQueryBase {
class CategoryTrackListQuery : public TrackListQueryBase {
public:
TrackListViewQuery(
CategoryTrackListQuery(
musik::core::LibraryPtr library,
const std::string& column,
DBID id);
virtual ~TrackListViewQuery();
virtual ~CategoryTrackListQuery();
virtual std::string Name() { return "TrackListViewQuery"; }
virtual std::string Name() { return "CategoryTrackListQuery"; }
virtual Result GetResult();
virtual Headers GetHeaders();

View File

@ -0,0 +1,54 @@
#include "stdafx.h"
#include "NowPlayingTrackListQuery.h"
#include <core/library/track/LibraryTrack.h>
#include <core/library/LocalLibraryConstants.h>
#include <core/db/Statement.h>
using musik::core::db::Statement;
using musik::core::db::Row;
using musik::core::TrackPtr;
using musik::core::LibraryTrack;
using musik::core::LibraryPtr;
using namespace musik::core::db;
using namespace musik::core::library::constants;
using namespace musik::box;
NowPlayingTrackListQuery::NowPlayingTrackListQuery(PlaybackService& playback)
: playback(playback) {
this->result.reset(new std::vector<TrackPtr>());
this->headers.reset(new std::set<size_t>());
this->hash = 0;
}
NowPlayingTrackListQuery::~NowPlayingTrackListQuery() {
}
NowPlayingTrackListQuery::Result NowPlayingTrackListQuery::GetResult() {
return this->result;
}
NowPlayingTrackListQuery::Headers NowPlayingTrackListQuery::GetHeaders() {
return this->headers;
}
size_t NowPlayingTrackListQuery::GetQueryHash() {
if (this->hash == 0) {
this->hash = std::hash<std::string>()(this->Name());
}
return this->hash;
}
bool NowPlayingTrackListQuery::OnRun(Connection& db) {
if (result) {
result.reset(new std::vector<TrackPtr>());
headers.reset(new std::set<size_t>());
}
this->playback.Copy(*result);
return true;
}

View File

@ -0,0 +1,29 @@
#pragma once
#include <core/library/query/QueryBase.h>
#include "TrackListQueryBase.h"
#include <app/service/PlaybackService.h>
namespace musik {
namespace box {
class NowPlayingTrackListQuery : public TrackListQueryBase {
public:
NowPlayingTrackListQuery(PlaybackService& playback);
virtual ~NowPlayingTrackListQuery();
virtual std::string Name() { return "NowPlayingTrackListQuery"; }
virtual Result GetResult();
virtual Headers GetHeaders();
virtual size_t GetQueryHash();
protected:
virtual bool OnRun(musik::core::db::Connection &db);
private:
PlaybackService& playback;
Result result;
Headers headers;
size_t hash;
};
}
}

View File

@ -92,11 +92,23 @@ bool PlaybackService::Previous() {
}
void PlaybackService::Play(std::vector<TrackPtr>& tracks, size_t index) {
this->playlist.clear();
std::copy(tracks.begin(), tracks.end(), std::back_inserter(this->playlist));
/* do the copy outside of the critical section, then swap. */
std::vector<TrackPtr> temp;
std::copy(tracks.begin(), tracks.end(), std::back_inserter(temp));
{
boost::recursive_mutex::scoped_lock lock(this->stateMutex);
std::swap(temp, this->playlist);
}
this->Play(index);
}
void PlaybackService::Copy(std::vector<musik::core::TrackPtr>& target) {
boost::recursive_mutex::scoped_lock lock(this->stateMutex);
std::copy(this->playlist.begin(), this->playlist.end(), std::back_inserter(target));
}
void PlaybackService::Play(size_t index) {
transport.Start(URI_AT_INDEX(index));
this->nextIndex = NO_POSITION;

View File

@ -32,6 +32,7 @@ namespace musik {
size_t GetIndex();
size_t Count() { return this->playlist.size(); }
void Copy(std::vector<musik::core::TrackPtr>& target);
private:
void OnStreamEvent(int eventType, std::string uri);

View File

@ -44,8 +44,8 @@ TrackListView::~TrackListView() {
}
void TrackListView::Requery(const std::string& column, DBID id) {
this->query.reset(new TrackListViewQuery(this->library, column, id));
void TrackListView::Requery(std::shared_ptr<TrackListQueryBase> query) {
this->query = query;
this->library->Enqueue(this->query);
}
@ -55,16 +55,8 @@ void TrackListView::OnQueryCompleted(QueryPtr query) {
}
}
bool TrackListView::KeyPress(const std::string& key) {
if (key == "^M") { /* return */
size_t selected = this->GetSelectedIndex();
if (this->metadata && this->metadata->size() > selected) {
playback.Play(*this->metadata, selected);
return true;
}
}
return ListWindow::KeyPress(key);
TrackListView::TrackList TrackListView::GetTrackList() {
return this->metadata;
}
void TrackListView::ProcessMessage(IMessage &message) {

View File

@ -5,7 +5,7 @@
#include <cursespp/IKeyHandler.h>
#include <cursespp/ListWindow.h>
#include <app/query/TrackListViewQuery.h>
#include <app/query/TrackListQueryBase.h>
#include <app/service/PlaybackService.h>
#include <core/playback/Transport.h>
@ -21,6 +21,9 @@ namespace musik {
public sigslot::has_slots<>
{
public:
typedef std::shared_ptr<std::vector<musik::core::TrackPtr> > TrackList;
typedef std::shared_ptr<std::set<size_t> > Headers;
TrackListView(
PlaybackService& playback,
musik::core::LibraryPtr library);
@ -28,9 +31,9 @@ namespace musik {
virtual ~TrackListView();
virtual void ProcessMessage(cursespp::IMessage &message);
virtual bool KeyPress(const std::string& key);
TrackList GetTrackList();
void Requery(const std::string& column, DBID id);
void Requery(std::shared_ptr<TrackListQueryBase> query);
protected:
virtual cursespp::IScrollAdapter& GetScrollAdapter();
@ -51,14 +54,13 @@ namespace musik {
private:
void OnTrackChanged(size_t index, musik::core::TrackPtr track);
std::shared_ptr<TrackListViewQuery> query;
std::shared_ptr<std::vector<musik::core::TrackPtr> > metadata;
std::shared_ptr<std::set<size_t> > headers;
std::shared_ptr<TrackListQueryBase> query;
TrackList metadata;
Headers headers;
Adapter* adapter;
PlaybackService& playback;
musik::core::TrackPtr playing;
musik::core::LibraryPtr library;
size_t lastQueryHash;
};
}

View File

@ -116,10 +116,12 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="app\layout\LibraryLayout.cpp" />
<ClCompile Include="app\layout\MainLayout.cpp" />
<ClCompile Include="app\layout\ConsoleLayout.cpp" />
<ClCompile Include="app\layout\NowPlayingLayout.cpp" />
<ClCompile Include="app\query\CategoryListViewQuery.cpp" />
<ClCompile Include="app\query\NowPlayingTrackListQuery.cpp" />
<ClCompile Include="app\query\SingleTrackQuery.cpp" />
<ClCompile Include="app\query\TrackListViewQuery.cpp" />
<ClCompile Include="app\query\CategoryTrackListQuery.cpp" />
<ClCompile Include="app\service\PlaybackService.cpp" />
<ClCompile Include="app\util\GlobalHotkeys.cpp" />
<ClCompile Include="app\util\SystemInfo.cpp" />
@ -154,11 +156,13 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="app\layout\LibraryLayout.h" />
<ClInclude Include="app\layout\MainLayout.h" />
<ClInclude Include="app\layout\ConsoleLayout.h" />
<ClInclude Include="app\layout\NowPlayingLayout.h" />
<ClInclude Include="app\query\CategoryListViewQuery.h" />
<ClInclude Include="app\query\NowPlayingTrackListQuery.h" />
<ClInclude Include="app\query\TrackListQueryBase.h" />
<ClInclude Include="app\query\SingleTrackQuery.h" />
<ClInclude Include="app\query\TrackListViewQuery.h" />
<ClInclude Include="app\query\CategoryTrackListQuery.h" />
<ClInclude Include="app\service\PlaybackService.h" />
<ClInclude Include="app\util\GlobalHotkeys.h" />
<ClInclude Include="app\util\SystemInfo.h" />

View File

@ -30,15 +30,9 @@
<ClCompile Include="cursespp\LayoutBase.cpp">
<Filter>cursespp</Filter>
</ClCompile>
<ClCompile Include="app\layout\MainLayout.cpp">
<Filter>app\layout</Filter>
</ClCompile>
<ClCompile Include="app\layout\LibraryLayout.cpp">
<Filter>app\layout</Filter>
</ClCompile>
<ClCompile Include="app\query\TrackListViewQuery.cpp">
<Filter>app\query</Filter>
</ClCompile>
<ClCompile Include="app\query\CategoryListViewQuery.cpp">
<Filter>app\query</Filter>
</ClCompile>
@ -96,6 +90,18 @@
<ClCompile Include="app\window\EntryWithHeader.cpp">
<Filter>app\window</Filter>
</ClCompile>
<ClCompile Include="app\query\CategoryTrackListQuery.cpp">
<Filter>app\query</Filter>
</ClCompile>
<ClCompile Include="app\query\NowPlayingTrackListQuery.cpp">
<Filter>app\query</Filter>
</ClCompile>
<ClCompile Include="app\layout\ConsoleLayout.cpp">
<Filter>app\layout</Filter>
</ClCompile>
<ClCompile Include="app\layout\NowPlayingLayout.cpp">
<Filter>app\layout</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
@ -156,18 +162,12 @@
<ClInclude Include="cursespp\LayoutBase.h">
<Filter>cursespp</Filter>
</ClInclude>
<ClInclude Include="app\layout\MainLayout.h">
<Filter>app\layout</Filter>
</ClInclude>
<ClInclude Include="app\layout\LibraryLayout.h">
<Filter>app\layout</Filter>
</ClInclude>
<ClInclude Include="app\query\CategoryListViewQuery.h">
<Filter>app\query</Filter>
</ClInclude>
<ClInclude Include="app\query\TrackListViewQuery.h">
<Filter>app\query</Filter>
</ClInclude>
<ClInclude Include="app\util\SystemInfo.h">
<Filter>app\util</Filter>
</ClInclude>
@ -234,6 +234,18 @@
<ClInclude Include="app\query\TrackListQueryBase.h">
<Filter>app\query</Filter>
</ClInclude>
<ClInclude Include="app\query\CategoryTrackListQuery.h">
<Filter>app\query</Filter>
</ClInclude>
<ClInclude Include="app\query\NowPlayingTrackListQuery.h">
<Filter>app\query</Filter>
</ClInclude>
<ClInclude Include="app\layout\ConsoleLayout.h">
<Filter>app\layout</Filter>
</ClInclude>
<ClInclude Include="app\layout\NowPlayingLayout.h">
<Filter>app\layout</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="cursespp">