Added the concept of ScrollAdapter ItemDecorators that can be used to decorate entries in a ScrollableWindow.

This commit is contained in:
Casey Langen 2016-06-22 21:19:34 -07:00
parent e1086b9847
commit 45c8aeb1c7
9 changed files with 72 additions and 34 deletions

View File

@ -3,6 +3,7 @@ set (BOX_SRCS
./stdafx.cpp
./app/layout/BrowseLayout.cpp
./app/layout/ConsoleLayout.cpp
./app/layout/IndexerLayout.cpp
./app/layout/LibraryLayout.cpp
./app/layout/NowPlayingLayout.cpp
./app/layout/SearchLayout.cpp

View File

@ -44,15 +44,14 @@
#include "IndexerLayout.h"
using namespace musik::core::library::constants;
using namespace musik::core;
using namespace musik::box;
using namespace cursespp;
using namespace std::placeholders;
#define SEARCH_HEIGHT 3
IndexerLayout::IndexerLayout(
musik::core::LibraryPtr library)
IndexerLayout::IndexerLayout(musik::core::LibraryPtr library)
: LayoutBase()
, library(library) {
this->InitializeWindows();
@ -83,7 +82,7 @@ void IndexerLayout::Layout() {
int leftWidth = cx / 3; /* 1/3 width */
int rightX = leftWidth;
int rightWidth = cx - rightX; /* remainder (~2/3) */
this->browseLabel->MoveAndResize(leftX, startY, leftWidth, LABEL_HEIGHT);
this->addedPathsLabel->MoveAndResize(rightX, startY, rightWidth, LABEL_HEIGHT);
@ -106,9 +105,26 @@ void IndexerLayout::RefreshAddedPaths() {
this->addedPathsAdapter.AddEntry(e);
}
ScrollAdapterBase::ItemDecorator decorator =
std::bind(&IndexerLayout::ListItemDecorator, this, _1, _2, _3);
this->addedPathsAdapter.SetItemDecorator(decorator);
this->addedPathsList->OnAdapterChanged();
}
int64 IndexerLayout::ListItemDecorator(
cursespp::ScrollableWindow* scrollable,
size_t index,
cursespp::IScrollAdapter::EntryPtr entry)
{
if (scrollable == this->addedPathsList.get()) {
if (index == this->addedPathsList->GetSelectedIndex()) {
return COLOR_PAIR(BOX_COLOR_BLACK_ON_GREEN);
}
}
return -1;
}
void IndexerLayout::InitializeWindows() {
this->SetContentColor(BOX_COLOR_WHITE_ON_BLACK);
@ -116,10 +132,10 @@ void IndexerLayout::InitializeWindows() {
this->title->SetText("settings", TextLabel::AlignCenter);
this->browseLabel.reset(new TextLabel());
this->browseLabel->SetText("browse filesystem", TextLabel::AlignLeft);
this->browseLabel->SetText("browse (SPACE to add)", TextLabel::AlignLeft);
this->addedPathsLabel.reset(new TextLabel());
this->addedPathsLabel->SetText("indexed paths", TextLabel::AlignLeft);
this->addedPathsLabel->SetText("indexed paths (DEL to remove)", TextLabel::AlignLeft);
this->addedPathsList.reset(new cursespp::ListWindow(&this->addedPathsAdapter, nullptr));
this->addedPathsList->SetContentColor(BOX_COLOR_WHITE_ON_BLACK);

View File

@ -56,8 +56,7 @@ namespace musik {
public sigslot::has_slots<>
{
public:
IndexerLayout(
musik::core::LibraryPtr library);
IndexerLayout(musik::core::LibraryPtr library);
virtual ~IndexerLayout();
@ -72,6 +71,11 @@ namespace musik {
void InitializeWindows();
void RefreshAddedPaths();
int64 ListItemDecorator(
cursespp::ScrollableWindow* w,
size_t index,
cursespp::IScrollAdapter::EntryPtr entry);
musik::core::LibraryPtr library;
std::shared_ptr<cursespp::TextLabel> title;

View File

@ -37,6 +37,8 @@
#include <stdafx.h>
namespace cursespp {
class ScrollableWindow;
class IScrollAdapter {
public:
virtual ~IScrollAdapter() { }
@ -71,6 +73,6 @@ namespace cursespp {
virtual void SetDisplaySize(size_t width, size_t height) = 0;
virtual size_t GetEntryCount() = 0;
virtual EntryPtr GetEntry(size_t index) = 0;
virtual void DrawPage(WINDOW* window, size_t index, ScrollPosition *result = NULL) = 0;
virtual void DrawPage(ScrollableWindow* window, size_t index, ScrollPosition *result = NULL) = 0;
};
}

View File

@ -47,7 +47,7 @@ class EmptyAdapter : public IScrollAdapter {
virtual void SetDisplaySize(size_t width, size_t height) { }
virtual size_t GetEntryCount() { return 0; }
virtual EntryPtr GetEntry(size_t index) { return IScrollAdapter::EntryPtr(); }
virtual void DrawPage(WINDOW* window, size_t index, ScrollPosition *result = NULL) { }
virtual void DrawPage(ScrollableWindow* window, size_t index, ScrollPosition *result = NULL) { }
};
static EmptyAdapter emptyAdapter;
@ -156,9 +156,7 @@ void ListWindow::PageDown() {
void ListWindow::ScrollTo(size_t index) {
this->GetScrollAdapter().DrawPage(
this->GetContent(),
index,
&this->GetScrollPosition());
this, index, &this->GetScrollPosition());
this->Repaint();
}

View File

@ -40,7 +40,12 @@
#include <sigslot/sigslot.h>
namespace cursespp {
class ListWindow : public ScrollableWindow {
class ListWindow :
public ScrollableWindow
#if (__clang_major__ == 7 && __clang_minor__ == 3)
, public std::enable_shared_from_this<ListWindow>
#endif
{
public:
static size_t NO_SELECTION;

View File

@ -34,6 +34,7 @@
#include <stdafx.h>
#include "ScrollAdapterBase.h"
#include "ScrollableWindow.h"
#include "MultiLineEntry.h"
using namespace cursespp;
@ -103,7 +104,7 @@ void ScrollAdapterBase::GetVisibleItems(
start = actual;
}
void ScrollAdapterBase::DrawPage(WINDOW* window, size_t index, ScrollPosition *result) {
void ScrollAdapterBase::DrawPage(ScrollableWindow* scrollable, size_t index, ScrollPosition *result) {
if (result != NULL) {
result->visibleEntryCount = 0;
result->firstVisibleEntryIndex = 0;
@ -112,6 +113,8 @@ void ScrollAdapterBase::DrawPage(WINDOW* window, size_t index, ScrollPosition *r
result->logicalIndex = 0;
}
WINDOW* window = scrollable->GetContent();
werase(window);
if (this->height == 0 || this->width == 0 || this->GetEntryCount() == 0) {
@ -137,7 +140,15 @@ void ScrollAdapterBase::DrawPage(WINDOW* window, size_t index, ScrollPosition *r
size_t count = entry->GetLineCount();
for (size_t i = 0; i < count && drawnLines < this->height; i++) {
int64 attrs = entry->GetAttrs(i);
int64 attrs = -1;
if (this->decorator) {
attrs = this->decorator(scrollable, e, entry);
}
if (attrs == -1) {
attrs = entry->GetAttrs(i);
}
if (attrs != -1) {
wattron(window, attrs);

View File

@ -41,23 +41,33 @@
namespace cursespp {
class ScrollAdapterBase : public IScrollAdapter {
public:
typedef std::function<int64(ScrollableWindow*, size_t, EntryPtr)> ItemDecorator;
ScrollAdapterBase();
virtual ~ScrollAdapterBase();
virtual void SetDisplaySize(size_t width, size_t height);
virtual size_t GetLineCount();
virtual void DrawPage(WINDOW* window, size_t index, ScrollPosition *result = NULL);
virtual void DrawPage(
ScrollableWindow* window,
size_t index,
ScrollPosition *result = nullptr);
virtual size_t GetEntryCount() = 0;
virtual EntryPtr GetEntry(size_t index) = 0;
virtual void SetItemDecorator(ItemDecorator decorator) { this->decorator = decorator; }
protected:
void GetVisibleItems(size_t desired, std::deque<EntryPtr>& target, size_t& start);
virtual ItemDecorator GetItemDecorator() { return this->decorator; }
size_t GetWidth() { return this->width; }
size_t GetHeight() { return this->height; }
private:
size_t width, height;
ItemDecorator decorator;
};
}

View File

@ -49,7 +49,7 @@ typedef IScrollAdapter::ScrollPosition ScrollPos;
{ \
ScrollPos& pos = GetScrollPosition(); \
GetScrollAdapter().DrawPage( \
this->GetContent(), \
this, \
pos.firstVisibleEntryIndex, \
&pos); \
} \
@ -66,9 +66,9 @@ void ScrollableWindow::OnSizeChanged() {
IScrollAdapter& adapter = this->GetScrollAdapter();
ScrollPos& pos = this->GetScrollPosition();
adapter.SetDisplaySize(
this->GetContentWidth(),
this->GetContentWidth(),
this->GetContentHeight());
}
@ -96,12 +96,7 @@ void ScrollableWindow::OnAdapterChanged() {
}
else {
ScrollPos &pos = this->GetScrollPosition();
adapter->DrawPage(
this->GetContent(),
pos.firstVisibleEntryIndex,
&pos);
adapter->DrawPage(this, pos.firstVisibleEntryIndex, &pos);
this->Repaint();
}
}
@ -112,13 +107,13 @@ void ScrollableWindow::Show() {
}
void ScrollableWindow::ScrollToTop() {
GetScrollAdapter().DrawPage(this->GetContent(), 0, &this->GetScrollPosition());
GetScrollAdapter().DrawPage(this, 0, &this->GetScrollPosition());
this->Repaint();
}
void ScrollableWindow::ScrollToBottom() {
GetScrollAdapter().DrawPage(
this->GetContent(),
this,
GetScrollAdapter().GetEntryCount(),
&this->GetScrollPosition());
@ -130,9 +125,7 @@ void ScrollableWindow::ScrollUp(int delta) {
if (pos.firstVisibleEntryIndex > 0) {
GetScrollAdapter().DrawPage(
this->GetContent(),
pos.firstVisibleEntryIndex - delta,
&pos);
this, pos.firstVisibleEntryIndex - delta, &pos);
this->Repaint();
}
@ -142,9 +135,7 @@ void ScrollableWindow::ScrollDown(int delta) {
ScrollPos &pos = this->GetScrollPosition();
GetScrollAdapter().DrawPage(
this->GetContent(),
pos.firstVisibleEntryIndex + delta,
&pos);
this, pos.firstVisibleEntryIndex + delta, &pos);
this->Repaint();
}