mirror of
https://github.com/clangen/musikcube.git
synced 2025-03-14 13:21:13 +00:00
Experimental change to support selectable headers in the TrackListView.
This commit is contained in:
parent
269dd1fb2e
commit
04eb8c13ea
@ -21,7 +21,6 @@ set (BOX_SRCS
|
||||
./app/util/PreferenceKeys.cpp
|
||||
./app/util/Playback.cpp
|
||||
./app/window/CategoryListView.cpp
|
||||
./app/window/EntryWithHeader.cpp
|
||||
./app/window/LogWindow.cpp
|
||||
./app/window/TrackListView.cpp
|
||||
./app/window/TransportWindow.cpp
|
||||
|
@ -201,8 +201,11 @@ bool BrowseLayout::KeyPress(const std::string& key) {
|
||||
}
|
||||
else if (Hotkeys::Is(Hotkeys::ContextMenu, key)) {
|
||||
if (this->GetFocus() == this->trackList) {
|
||||
PlayQueueOverlays::ShowAddTrackOverlay(this->playback, *this->trackList);
|
||||
return true;
|
||||
TrackPtr track = this->trackList->GetSelectedTrack();
|
||||
if (track) {
|
||||
PlayQueueOverlays::ShowAddTrackOverlay(this->playback, track->GetId());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Hotkeys::Is(Hotkeys::ViewRefresh, key)) {
|
||||
|
@ -152,7 +152,10 @@ bool TrackSearchLayout::KeyPress(const std::string& key) {
|
||||
return true;
|
||||
}
|
||||
else if (Hotkeys::Is(Hotkeys::ContextMenu, key)) {
|
||||
PlayQueueOverlays::ShowAddTrackOverlay(this->playback, *this->trackList);
|
||||
TrackPtr track = this->trackList->GetSelectedTrack();
|
||||
if (track) {
|
||||
PlayQueueOverlays::ShowAddTrackOverlay(this->playback, track->GetId());
|
||||
}
|
||||
}
|
||||
else if (key == "KEY_DOWN") {
|
||||
if (this->GetFocus() == this->input) {
|
||||
|
@ -226,16 +226,8 @@ PlayQueueOverlays::PlayQueueOverlays() {
|
||||
|
||||
void PlayQueueOverlays::ShowAddTrackOverlay(
|
||||
PlaybackService& playback,
|
||||
TrackListView& trackList)
|
||||
unsigned long long trackId)
|
||||
{
|
||||
size_t selectedIndex = trackList.GetSelectedIndex();
|
||||
|
||||
if (selectedIndex == ListWindow::NO_SELECTION) {
|
||||
return;
|
||||
}
|
||||
|
||||
DBID trackId = trackList.Get(selectedIndex)->GetId();
|
||||
|
||||
auto adapter = createAddToAdapter();
|
||||
|
||||
std::shared_ptr<ListOverlay> dialog(new ListOverlay());
|
||||
|
@ -47,7 +47,7 @@ namespace musik {
|
||||
|
||||
static void ShowAddTrackOverlay(
|
||||
musik::core::audio::PlaybackService& playback,
|
||||
musik::box::TrackListView& trackList);
|
||||
unsigned long long trackId);
|
||||
|
||||
static void ShowAddCategoryOverlay(
|
||||
musik::core::audio::PlaybackService& playback,
|
||||
|
@ -50,8 +50,14 @@ namespace musik {
|
||||
auto tracks = trackList->GetTrackList();
|
||||
|
||||
if (tracks && tracks->Count()) {
|
||||
size_t index = (focused.get() == trackList.get())
|
||||
? trackList->GetSelectedIndex() : 0;
|
||||
size_t index = 0;
|
||||
if (focused.get() == trackList.get()) {
|
||||
index = trackList->GetSelectedTrackIndex();
|
||||
|
||||
if (index == cursespp::ListWindow::NO_SELECTION) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
playback.Play(*tracks, index);
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2007-2016 musikcube team
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdafx.h>
|
||||
#include "EntryWithHeader.h"
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <cursespp/Text.h>
|
||||
|
||||
using namespace musik::box;
|
||||
using namespace cursespp;
|
||||
|
||||
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) {
|
||||
return text::Ellipsize(this->header, this->width);
|
||||
}
|
||||
|
||||
return TRUNCATE(this->value, this->width);
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2007-2016 musikcube team
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cursespp/IScrollAdapter.h>
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
||||
}
|
@ -44,7 +44,7 @@
|
||||
#include <glue/util/Duration.h>
|
||||
|
||||
#include <app/util/Hotkeys.h>
|
||||
#include <app/window/EntryWithHeader.h>
|
||||
#include <app/overlay/PlayQueueOverlays.h>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
@ -109,14 +109,14 @@ void TrackListView::Requery(std::shared_ptr<TrackListQueryBase> query) {
|
||||
void TrackListView::OnQueryCompleted(IQuery* query) {
|
||||
if (this->query && query == this->query.get()) {
|
||||
if (this->query->GetStatus() == IQuery::Finished) {
|
||||
this->metadata = this->query->GetResult();
|
||||
this->headers = this->query->GetHeaders();
|
||||
this->tracks = this->query->GetResult();
|
||||
this->headers.Set(this->query->GetHeaders());
|
||||
|
||||
/* if the query was functionally the same as the last query, don't
|
||||
mess with the selected index */
|
||||
if (this->lastQueryHash != this->query->GetQueryHash()) {
|
||||
this->SetSelectedIndex(0);
|
||||
this->ScrollToTop();
|
||||
this->SetSelectedIndex(this->headers.HeaderAt(0) ? 1 : 0);
|
||||
}
|
||||
|
||||
this->lastQueryHash = this->query->GetQueryHash();
|
||||
@ -130,12 +130,12 @@ void TrackListView::OnQueryCompleted(IQuery* query) {
|
||||
}
|
||||
|
||||
std::shared_ptr<const TrackList> TrackListView::GetTrackList() {
|
||||
return this->metadata;
|
||||
return this->tracks;
|
||||
}
|
||||
|
||||
void TrackListView::SetTrackList(std::shared_ptr<const TrackList> trackList) {
|
||||
if (this->metadata != trackList) {
|
||||
this->metadata = trackList;
|
||||
if (this->tracks != trackList) {
|
||||
this->tracks = trackList;
|
||||
this->SetSelectedIndex(0);
|
||||
this->ScrollToTop();
|
||||
this->OnAdapterChanged();
|
||||
@ -147,24 +147,34 @@ void TrackListView::SetTrackList(std::shared_ptr<const TrackList> trackList) {
|
||||
|
||||
void TrackListView::Clear() {
|
||||
this->query.reset();
|
||||
this->metadata.reset(new TrackList(this->library));
|
||||
this->headers.reset(new std::set<size_t>());
|
||||
this->tracks.reset(new TrackList(this->library));
|
||||
this->headers.Reset();
|
||||
this->OnAdapterChanged();
|
||||
}
|
||||
|
||||
TrackPtr TrackListView::Get(size_t index) {
|
||||
return this->metadata->Get(index);
|
||||
TrackPtr TrackListView::GetSelectedTrack() {
|
||||
auto i = this->GetSelectedTrackIndex();
|
||||
return (i == ListWindow::NO_SELECTION) ? TrackPtr() : this->tracks->Get(i);
|
||||
}
|
||||
|
||||
size_t TrackListView::GetSelectedTrackIndex() {
|
||||
auto i = this->GetSelectedIndex();
|
||||
if (i != ListWindow::NO_SELECTION) {
|
||||
auto entry = adapter->GetEntry(this, i);
|
||||
return static_cast<TrackListEntry*>(entry.get())->GetIndex();
|
||||
}
|
||||
return ListWindow::NO_SELECTION;
|
||||
}
|
||||
|
||||
size_t TrackListView::Count() {
|
||||
return this->metadata ? this->metadata->Count() : 0;
|
||||
return this->tracks ? this->tracks->Count() : 0;
|
||||
}
|
||||
|
||||
void TrackListView::ScrollToPlaying() {
|
||||
if (this->playing && this->metadata) {
|
||||
if (this->playing && this->tracks) {
|
||||
DBID id = this->playing->GetId();
|
||||
for (size_t i = 0; i < this->metadata->Count(); i++) {
|
||||
if (this->metadata->GetId(i) == id) {
|
||||
for (size_t i = 0; i < this->tracks->Count(); i++) {
|
||||
if (this->tracks->GetId(i) == id) {
|
||||
this->SetSelectedIndex(i);
|
||||
|
||||
auto pos = this->GetScrollPosition();
|
||||
@ -188,12 +198,29 @@ void TrackListView::ProcessMessage(IMessage &message) {
|
||||
bool TrackListView::KeyPress(const std::string& key) {
|
||||
bool handled = false;
|
||||
|
||||
if (Hotkeys::Is(Hotkeys::NavigateJumpToPlaying, key)) {
|
||||
if (key == "KEY_ENTER") {
|
||||
if (headers.HeaderAt(this->GetSelectedIndex())) {
|
||||
auto track = this->GetSelectedTrack();
|
||||
unsigned long long fieldId = std::stoull(
|
||||
track->GetValue(constants::Track::ALBUM_ID));
|
||||
|
||||
PlayQueueOverlays::ShowAddCategoryOverlay(
|
||||
this->playback,
|
||||
this->library,
|
||||
constants::Track::ALBUM,
|
||||
fieldId);
|
||||
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
else if (Hotkeys::Is(Hotkeys::NavigateJumpToPlaying, key)) {
|
||||
this->ScrollToPlaying();
|
||||
handled = true;
|
||||
}
|
||||
|
||||
handled = ListWindow::KeyPress(key);
|
||||
if (!handled) {
|
||||
handled = ListWindow::KeyPress(key);
|
||||
}
|
||||
|
||||
if (handled) {
|
||||
this->lastChanged = now();
|
||||
@ -224,8 +251,54 @@ TrackListView::Adapter::Adapter(TrackListView &parent)
|
||||
: parent(parent) {
|
||||
}
|
||||
|
||||
/* * * * TrackListView::HeaderCalculator * * * */
|
||||
|
||||
void TrackListView::HeaderCalculator::Set(Headers rawOffsets) {
|
||||
this->rawOffsets = rawOffsets;
|
||||
this->absoluteOffsets.reset();
|
||||
if (rawOffsets) {
|
||||
this->absoluteOffsets.reset(new std::set<size_t>());
|
||||
size_t i = 0;
|
||||
for (auto val : (*this->rawOffsets)) {
|
||||
this->absoluteOffsets->insert(val + i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TrackListView::HeaderCalculator::Reset() {
|
||||
this->absoluteOffsets.reset();
|
||||
this->rawOffsets.reset();
|
||||
}
|
||||
|
||||
size_t TrackListView::HeaderCalculator::OffsetTrackIndex(size_t index) {
|
||||
size_t result = index;
|
||||
if (this->absoluteOffsets) {
|
||||
for (auto offset : (*this->absoluteOffsets)) {
|
||||
if (result != 0 && offset <= index) {
|
||||
--result;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t TrackListView::HeaderCalculator::Count() {
|
||||
return this->absoluteOffsets ? this->absoluteOffsets->size() : 0;
|
||||
}
|
||||
|
||||
bool TrackListView::HeaderCalculator::HeaderAt(size_t index) {
|
||||
return this->absoluteOffsets &&
|
||||
this->absoluteOffsets->find(index) != this->absoluteOffsets->end();
|
||||
}
|
||||
|
||||
/* * * * TrackListView::Adapter * * * */
|
||||
|
||||
size_t TrackListView::Adapter::GetEntryCount() {
|
||||
return parent.metadata ? parent.metadata->Count() : 0;
|
||||
return parent.tracks ? parent.tracks->Count() + parent.headers.Count() : 0;
|
||||
}
|
||||
|
||||
#define TRACK_COL_WIDTH 3
|
||||
@ -267,8 +340,28 @@ static std::string formatWithoutAlbum(TrackPtr track, size_t width) {
|
||||
% trackNum % title % duration % artist);
|
||||
}
|
||||
|
||||
IScrollAdapter::EntryPtr TrackListView::Adapter::GetEntry(cursespp::ScrollableWindow* window, size_t index) {
|
||||
TrackPtr track = parent.metadata->Get(index);
|
||||
IScrollAdapter::EntryPtr TrackListView::Adapter::GetEntry(cursespp::ScrollableWindow* window, size_t rawIndex) {
|
||||
bool selected = (rawIndex == parent.GetSelectedIndex());
|
||||
|
||||
if (this->parent.headers.HeaderAt(rawIndex)) {
|
||||
/* the next track at the next logical index will have the album
|
||||
tracks we're interesetd in. */
|
||||
auto trackIndex = this->parent.headers.OffsetTrackIndex(rawIndex + 1);
|
||||
TrackPtr track = parent.tracks->Get(trackIndex);
|
||||
std::string album = track->GetValue(constants::Track::ALBUM);
|
||||
|
||||
std::shared_ptr<TrackListEntry> entry(new
|
||||
TrackListEntry(album, trackIndex, RowType::Separator));
|
||||
|
||||
entry->SetAttrs(selected
|
||||
? COLOR_PAIR(CURSESPP_LIST_ITEM_HIGHLIGHTED_HEADER)
|
||||
: COLOR_PAIR(CURSESPP_LIST_ITEM_HEADER));
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
size_t trackIndex = this->parent.headers.OffsetTrackIndex(rawIndex);
|
||||
TrackPtr track = parent.tracks->Get(trackIndex);
|
||||
|
||||
if (!track) {
|
||||
return MISSING_ENTRY;
|
||||
@ -277,11 +370,9 @@ IScrollAdapter::EntryPtr TrackListView::Adapter::GetEntry(cursespp::ScrollableWi
|
||||
int64 attrs = CURSESPP_DEFAULT_COLOR;
|
||||
|
||||
if (parent.decorator) {
|
||||
attrs = parent.decorator(track, index);
|
||||
attrs = parent.decorator(track, trackIndex);
|
||||
}
|
||||
else {
|
||||
bool selected = index == parent.GetSelectedIndex();
|
||||
|
||||
attrs = selected
|
||||
? COLOR_PAIR(CURSESPP_HIGHLIGHTED_LIST_ITEM)
|
||||
: CURSESPP_DEFAULT_COLOR;
|
||||
@ -304,15 +395,10 @@ IScrollAdapter::EntryPtr TrackListView::Adapter::GetEntry(cursespp::ScrollableWi
|
||||
? parent.formatter(track, this->GetWidth())
|
||||
: formatWithoutAlbum(track, this->GetWidth());
|
||||
|
||||
if (this->parent.headers && this->parent.headers->find(index) != this->parent.headers->end()) {
|
||||
std::string album = track->GetValue(constants::Track::ALBUM);
|
||||
std::shared_ptr<EntryWithHeader> entry(new EntryWithHeader(album, text));
|
||||
entry->SetAttrs(COLOR_PAIR(CURSESPP_LIST_ITEM_HEADER), attrs);
|
||||
return entry;
|
||||
}
|
||||
else {
|
||||
std::shared_ptr<SingleLineEntry> entry(new SingleLineEntry(text));
|
||||
entry->SetAttrs(attrs);
|
||||
return entry;
|
||||
}
|
||||
std::shared_ptr<TrackListEntry> entry(
|
||||
new TrackListEntry(text, trackIndex, RowType::Track));
|
||||
|
||||
entry->SetAttrs(attrs);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <cursespp/ScrollAdapterBase.h>
|
||||
#include <cursespp/IKeyHandler.h>
|
||||
#include <cursespp/ListWindow.h>
|
||||
#include <cursespp/SingleLineEntry.h>
|
||||
|
||||
#include <core/library/query/local/TrackListQueryBase.h>
|
||||
#include <core/audio/PlaybackService.h>
|
||||
@ -55,8 +56,10 @@ namespace musik {
|
||||
public sigslot::has_slots<>
|
||||
{
|
||||
public:
|
||||
/* events */
|
||||
sigslot::signal1<musik::core::db::local::TrackListQueryBase*> Requeried;
|
||||
|
||||
/* types */
|
||||
typedef std::function<std::string(
|
||||
musik::core::TrackPtr, size_t)> RowFormatter;
|
||||
|
||||
@ -65,8 +68,27 @@ namespace musik {
|
||||
|
||||
typedef std::shared_ptr<std::set<size_t> > Headers;
|
||||
|
||||
enum class RowType : char { Track = 't', Separator = 's' };
|
||||
|
||||
/* our special type of list entry */
|
||||
class TrackListEntry : public cursespp::SingleLineEntry {
|
||||
public:
|
||||
TrackListEntry(const std::string& str, int index, RowType type)
|
||||
: cursespp::SingleLineEntry(str), index(index), type(type) { }
|
||||
|
||||
virtual ~TrackListEntry() { }
|
||||
|
||||
RowType GetType() { return type; }
|
||||
int GetIndex() { return index; }
|
||||
|
||||
private:
|
||||
RowType type;
|
||||
int index;
|
||||
};
|
||||
|
||||
typedef musik::core::db::local::TrackListQueryBase TrackListQueryBase;
|
||||
|
||||
/* ctor, dtor */
|
||||
TrackListView(
|
||||
musik::core::audio::PlaybackService& playback,
|
||||
musik::core::ILibraryPtr library,
|
||||
@ -75,14 +97,16 @@ namespace musik {
|
||||
|
||||
virtual ~TrackListView();
|
||||
|
||||
/* IWindow */
|
||||
virtual void ProcessMessage(musik::core::runtime::IMessage &message);
|
||||
virtual bool KeyPress(const std::string& key);
|
||||
|
||||
/* regular methods */
|
||||
std::shared_ptr<const musik::core::TrackList> GetTrackList();
|
||||
void SetTrackList(std::shared_ptr<const musik::core::TrackList> trackList);
|
||||
|
||||
musik::core::TrackPtr GetSelectedTrack();
|
||||
size_t GetSelectedTrackIndex();
|
||||
void Clear();
|
||||
musik::core::TrackPtr Get(size_t index);
|
||||
size_t Count();
|
||||
|
||||
void Requery(std::shared_ptr<TrackListQueryBase> query);
|
||||
@ -105,12 +129,26 @@ namespace musik {
|
||||
};
|
||||
|
||||
private:
|
||||
/* class to help with header offset calculation */
|
||||
class HeaderCalculator {
|
||||
public:
|
||||
void Set(Headers rawOffsets);
|
||||
void Reset();
|
||||
size_t OffsetTrackIndex(size_t index);
|
||||
bool HeaderAt(size_t index);
|
||||
size_t Count();
|
||||
|
||||
private:
|
||||
Headers absoluteOffsets;
|
||||
Headers rawOffsets;
|
||||
};
|
||||
|
||||
void OnTrackChanged(size_t index, musik::core::TrackPtr track);
|
||||
void ScrollToPlaying();
|
||||
|
||||
std::shared_ptr<TrackListQueryBase> query;
|
||||
std::shared_ptr<const musik::core::TrackList> metadata;
|
||||
Headers headers;
|
||||
std::shared_ptr<const musik::core::TrackList> tracks;
|
||||
HeaderCalculator headers;
|
||||
Adapter* adapter;
|
||||
musik::core::audio::PlaybackService& playback;
|
||||
musik::core::TrackPtr playing;
|
||||
|
@ -66,12 +66,14 @@ indicies we'll use to store them */
|
||||
#define THEME_COLOR_BANNER_FOREGROUND 38
|
||||
#define THEME_COLOR_LIST_HEADER_BACKGROUND 39
|
||||
#define THEME_COLOR_LIST_HEADER_FOREGROUND 40
|
||||
#define THEME_COLOR_LIST_ITEM_HIGHLIGHTED_BACKGROUND 41
|
||||
#define THEME_COLOR_LIST_ITEM_HIGHLIGHTED_FOREGROUND 42
|
||||
#define THEME_COLOR_LIST_ITEM_ACTIVE_BACKGROUND 43
|
||||
#define THEME_COLOR_LIST_ITEM_ACTIVE_FOREGROUND 44
|
||||
#define THEME_COLOR_LIST_ITEM_ACTIVE_HIGHLIGHTED_BACKGROUND 45
|
||||
#define THEME_COLOR_LIST_ITEM_ACTIVE_HIGHLIGHTED_FOREGROUND 46
|
||||
#define THEME_COLOR_LIST_HEADER_HIGHLIGHTED_BACKGROUND 41
|
||||
#define THEME_COLOR_LIST_HEADER_HIGHLIGHTED_FOREGROUND 42
|
||||
#define THEME_COLOR_LIST_ITEM_HIGHLIGHTED_BACKGROUND 43
|
||||
#define THEME_COLOR_LIST_ITEM_HIGHLIGHTED_FOREGROUND 44
|
||||
#define THEME_COLOR_LIST_ITEM_ACTIVE_BACKGROUND 45
|
||||
#define THEME_COLOR_LIST_ITEM_ACTIVE_FOREGROUND 46
|
||||
#define THEME_COLOR_LIST_ITEM_ACTIVE_HIGHLIGHTED_BACKGROUND 47
|
||||
#define THEME_COLOR_LIST_ITEM_ACTIVE_HIGHLIGHTED_FOREGROUND 48
|
||||
|
||||
/* user-readable names for the color identifiers above. these are
|
||||
used as key names in the config files */
|
||||
@ -100,6 +102,8 @@ used as key names in the config files */
|
||||
#define JSON_KEY_COLOR_BANNER_FOREGROUND "banner_foreground"
|
||||
#define JSON_KEY_COLOR_LIST_HEADER_BACKGROUND "list_header_background"
|
||||
#define JSON_KEY_COLOR_LIST_HEADER_FOREGROUND "list_header_foreground"
|
||||
#define JSON_KEY_COLOR_LIST_HEADER_HIGHLIGHTED_BACKGROUND "list_header_highlighted_background"
|
||||
#define JSON_KEY_COLOR_LIST_HEADER_HIGHLIGHTED_FOREGROUND "list_header_highlighted_foreground"
|
||||
#define JSON_KEY_COLOR_LIST_ITEM_HIGHLIGHTED_BACKGROUND "list_item_highlighted_background"
|
||||
#define JSON_KEY_COLOR_LIST_ITEM_HIGHLIGHTED_FOREGROUND "list_item_highlighted_foreground"
|
||||
#define JSON_KEY_COLOR_LIST_ITEM_ACTIVE_BACKGROUND "list_item_active_background"
|
||||
@ -282,6 +286,8 @@ struct Theme {
|
||||
/* listview */
|
||||
listHeaderBackground.Set(THEME_COLOR_LIST_HEADER_BACKGROUND, 36, 36, 31, -1);
|
||||
listHeaderForeground.Set(THEME_COLOR_LIST_HEADER_FOREGROUND, 166, 226, 46, COLOR_256_GREEN);
|
||||
listHeaderHighlightedBackground.Set(THEME_COLOR_LIST_HEADER_HIGHLIGHTED_BACKGROUND, 166, 226, 46, COLOR_256_GREEN);
|
||||
listHeaderHighlightedForeground.Set(THEME_COLOR_LIST_HEADER_HIGHLIGHTED_FOREGROUND, 36, 36, 31, -1);
|
||||
listHighlightedBackground.Set(THEME_COLOR_LIST_ITEM_HIGHLIGHTED_BACKGROUND, 166, 226, 46, COLOR_256_GREEN);
|
||||
listHighlightedForeground.Set(THEME_COLOR_LIST_ITEM_HIGHLIGHTED_FOREGROUND, 24, 24, 20, COLOR_BLACK);
|
||||
listActiveBackground.Set(THEME_COLOR_LIST_ITEM_ACTIVE_BACKGROUND, 66, 66, 56, COLOR_256_MEDIUM_GRAY);
|
||||
@ -336,6 +342,8 @@ struct Theme {
|
||||
this->bannerForeground.Set(colors.value(JSON_KEY_COLOR_BANNER_FOREGROUND, unset));
|
||||
this->listHeaderBackground.Set(colors.value(JSON_KEY_COLOR_LIST_HEADER_BACKGROUND, unset));
|
||||
this->listHeaderForeground.Set(colors.value(JSON_KEY_COLOR_LIST_HEADER_FOREGROUND, unset));
|
||||
this->listHeaderHighlightedBackground.Set(colors.value(JSON_KEY_COLOR_LIST_HEADER_HIGHLIGHTED_BACKGROUND, unset));
|
||||
this->listHeaderHighlightedForeground.Set(colors.value(JSON_KEY_COLOR_LIST_HEADER_HIGHLIGHTED_FOREGROUND, unset));
|
||||
this->listHighlightedBackground.Set(colors.value(JSON_KEY_COLOR_LIST_ITEM_HIGHLIGHTED_BACKGROUND, unset));
|
||||
this->listHighlightedForeground.Set(colors.value(JSON_KEY_COLOR_LIST_ITEM_HIGHLIGHTED_FOREGROUND, unset));
|
||||
this->listActiveBackground.Set(colors.value(JSON_KEY_COLOR_LIST_ITEM_ACTIVE_BACKGROUND, unset));
|
||||
@ -414,6 +422,11 @@ struct Theme {
|
||||
listHeaderForeground.Id(mode, COLOR_GREEN),
|
||||
listHeaderBackground.Id(mode, -1));
|
||||
|
||||
init_pair(
|
||||
CURSESPP_LIST_ITEM_HIGHLIGHTED_HEADER,
|
||||
listHeaderHighlightedForeground.Id(mode, -1),
|
||||
listHeaderHighlightedBackground.Id(mode, COLOR_GREEN));
|
||||
|
||||
init_pair(
|
||||
CURSESPP_SELECTED_LIST_ITEM,
|
||||
listActiveForeground.Id(mode, COLOR_YELLOW),
|
||||
@ -468,6 +481,8 @@ struct Theme {
|
||||
/* listview */
|
||||
Color listHeaderBackground;
|
||||
Color listHeaderForeground;
|
||||
Color listHeaderHighlightedBackground;
|
||||
Color listHeaderHighlightedForeground;
|
||||
Color listHighlightedBackground;
|
||||
Color listHighlightedForeground;
|
||||
Color listActiveForeground;
|
||||
|
@ -42,30 +42,31 @@
|
||||
#define CURSESPP_HIGHLIGHTED_LIST_ITEM 2
|
||||
#define CURSESPP_HIGHLIGHTED_SELECTED_LIST_ITEM 3
|
||||
#define CURSESPP_LIST_ITEM_HEADER 4
|
||||
#define CURSESPP_LIST_ITEM_HIGHLIGHTED_HEADER 5
|
||||
|
||||
#define CURSESPP_DEFAULT_CONTENT_COLOR 5
|
||||
#define CURSESPP_DEFAULT_FRAME_COLOR 6
|
||||
#define CURSESPP_FOCUSED_FRAME_COLOR 7
|
||||
#define CURSESPP_DEFAULT_CONTENT_COLOR 6
|
||||
#define CURSESPP_DEFAULT_FRAME_COLOR 7
|
||||
#define CURSESPP_FOCUSED_FRAME_COLOR 8
|
||||
|
||||
#define CURSESPP_TEXT_DEFAULT 8
|
||||
#define CURSESPP_TEXT_DISABLED 9
|
||||
#define CURSESPP_TEXT_FOCUSED 10
|
||||
#define CURSESPP_TEXT_ACTIVE 11
|
||||
#define CURSESPP_TEXT_WARNING 12
|
||||
#define CURSESPP_TEXT_ERROR 13
|
||||
#define CURSESPP_TEXT_HIDDEN 14
|
||||
#define CURSESPP_TEXT_DEFAULT 9
|
||||
#define CURSESPP_TEXT_DISABLED 10
|
||||
#define CURSESPP_TEXT_FOCUSED 11
|
||||
#define CURSESPP_TEXT_ACTIVE 12
|
||||
#define CURSESPP_TEXT_WARNING 13
|
||||
#define CURSESPP_TEXT_ERROR 14
|
||||
#define CURSESPP_TEXT_HIDDEN 15
|
||||
|
||||
#define CURSESPP_BUTTON_NORMAL 16
|
||||
#define CURSESPP_BUTTON_HIGHLIGHTED 18
|
||||
#define CURSESPP_BUTTON_HIGHLIGHTED 17
|
||||
|
||||
#define CURSESPP_SHORTCUT_ROW_NORMAL 19
|
||||
#define CURSESPP_SHORTCUT_ROW_FOCUSED 20
|
||||
#define CURSESPP_SHORTCUT_ROW_NORMAL 18
|
||||
#define CURSESPP_SHORTCUT_ROW_FOCUSED 19
|
||||
|
||||
#define CURSESPP_OVERLAY_FRAME 21
|
||||
#define CURSESPP_OVERLAY_CONTENT 22
|
||||
#define CURSESPP_OVERLAY_INPUT_FRAME 23
|
||||
#define CURSESPP_OVERLAY_FRAME 20
|
||||
#define CURSESPP_OVERLAY_CONTENT 21
|
||||
#define CURSESPP_OVERLAY_INPUT_FRAME 22
|
||||
|
||||
#define CURSESPP_BANNER 24
|
||||
#define CURSESPP_BANNER 23
|
||||
|
||||
namespace cursespp {
|
||||
class Colors {
|
||||
|
@ -48,7 +48,7 @@ namespace cursespp {
|
||||
virtual std::string GetLine(size_t line);
|
||||
|
||||
void SetAttrs(int64 attrs);
|
||||
|
||||
|
||||
private:
|
||||
size_t width;
|
||||
std::string value;
|
||||
|
@ -149,7 +149,6 @@ xcopy "$(ProjectDir)data\locales\*" "$(TargetDir)locales\" /Y /e</Command>
|
||||
<ClCompile Include="app\util\Playback.cpp" />
|
||||
<ClCompile Include="app\util\PreferenceKeys.cpp" />
|
||||
<ClCompile Include="app\window\CategoryListView.cpp" />
|
||||
<ClCompile Include="app\window\EntryWithHeader.cpp" />
|
||||
<ClCompile Include="app\window\LogWindow.cpp" />
|
||||
<ClCompile Include="app\window\TrackListView.cpp" />
|
||||
<ClCompile Include="app\window\TransportWindow.cpp" />
|
||||
@ -203,7 +202,6 @@ xcopy "$(ProjectDir)data\locales\*" "$(TargetDir)locales\" /Y /e</Command>
|
||||
<ClInclude Include="app\util\PreferenceKeys.h" />
|
||||
<ClInclude Include="app\util\Version.h" />
|
||||
<ClInclude Include="app\window\CategoryListView.h" />
|
||||
<ClInclude Include="app\window\EntryWithHeader.h" />
|
||||
<ClInclude Include="app\window\LogWindow.h" />
|
||||
<ClInclude Include="app\window\TrackListView.h" />
|
||||
<ClInclude Include="app\window\TransportWindow.h" />
|
||||
|
@ -48,9 +48,6 @@
|
||||
<ClCompile Include="app\util\GlobalHotkeys.cpp">
|
||||
<Filter>app\util</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="app\window\EntryWithHeader.cpp">
|
||||
<Filter>app\window</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="app\layout\ConsoleLayout.cpp">
|
||||
<Filter>app\layout</Filter>
|
||||
</ClCompile>
|
||||
@ -219,9 +216,6 @@
|
||||
<ClInclude Include="cursespp\IOrderable.h">
|
||||
<Filter>cursespp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="app\window\EntryWithHeader.h">
|
||||
<Filter>app\window</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="app\layout\ConsoleLayout.h">
|
||||
<Filter>app\layout</Filter>
|
||||
</ClInclude>
|
||||
|
Loading…
x
Reference in New Issue
Block a user