* Added InputOverlay.h/cpp. Still doesn't draw completely correctly.

* Added support for item deletion in ListOverlay. generally untested
* Fixed lastPlaylistId initialization in NowPlayingLayout
This commit is contained in:
Casey Langen 2017-01-24 23:05:05 -08:00
parent 3331e91d12
commit 5c4ef10f5f
6 changed files with 251 additions and 1 deletions

View File

@ -26,6 +26,7 @@ set (BOX_SRCS
./cursespp/Checkbox.cpp ./cursespp/Checkbox.cpp
./cursespp/Colors.cpp ./cursespp/Colors.cpp
./cursespp/DialogOverlay.cpp ./cursespp/DialogOverlay.cpp
./cursespp/InputOverlay.cpp
./cursespp/LayoutBase.cpp ./cursespp/LayoutBase.cpp
./cursespp/ListOverlay.cpp ./cursespp/ListOverlay.cpp
./cursespp/ListWindow.cpp ./cursespp/ListWindow.cpp

View File

@ -66,7 +66,8 @@ NowPlayingLayout::NowPlayingLayout(
: LayoutBase() : LayoutBase()
, playback(playback) , playback(playback)
, library(library) , library(library)
, reselectIndex(-1) { , reselectIndex(-1)
, lastPlaylistId(-1) {
this->InitializeWindows(); this->InitializeWindows();
this->playback.Shuffled.connect(this, &NowPlayingLayout::OnPlaybackShuffled); this->playback.Shuffled.connect(this, &NowPlayingLayout::OnPlaybackShuffled);
@ -138,6 +139,9 @@ void NowPlayingLayout::OnVisibilityChanged(bool visible) {
} }
void NowPlayingLayout::OnTrackListRequeried(musik::glue::TrackListQueryBase* query) { void NowPlayingLayout::OnTrackListRequeried(musik::glue::TrackListQueryBase* query) {
/* if the requery just finished for a regular playlist, we need to
make sure we load it into the PlaybackService. generally we just read
FROM the playback service */
if (query && query->GetId() == this->lastPlaylistId) { if (query && query->GetId() == this->lastPlaylistId) {
this->playback.CopyFrom(*query->GetResult()); this->playback.CopyFrom(*query->GetResult());
this->lastPlaylistId = -1; this->lastPlaylistId = -1;
@ -209,6 +213,9 @@ bool NowPlayingLayout::KeyPress(const std::string& key) {
std::bind(&NowPlayingLayout::OnPlaylistQueryStart, this, std::placeholders::_1)); std::bind(&NowPlayingLayout::OnPlaylistQueryStart, this, std::placeholders::_1));
return true; return true;
} }
else if (key == "M-s") {
PlayQueueOverlays::ShowSavePlaylistOverlay(this->playback, this->library);
}
else if (ProcessEditOperation(key)) { else if (ProcessEditOperation(key)) {
return true; return true;
} }

View File

@ -0,0 +1,151 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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 "InputOverlay.h"
#include "Colors.h"
#include "Screen.h"
#include "Text.h"
using namespace cursespp;
#define VERTICAL_PADDING 2
#define DEFAULT_WIDTH 26
#define MAX_HEIGHT 12
#define DISMISS() \
OverlayStack* overlays = this->GetOverlayStack(); \
if (overlays) { \
overlays->Remove(this); \
}
InputOverlay::InputOverlay() {
this->SetFrameVisible(true);
this->SetFrameColor(CURSESPP_OVERLAY_FRAME);
this->SetContentColor(CURSESPP_OVERLAY_BACKGROUND);
this->width = this->height = this->setWidth = 0;
this->textInput.reset(new TextInput());
this->textInput->SetFocusOrder(0);
this->textInput->SetFrameColor(CURSESPP_OVERLAY_FRAME);
this->textInput->SetContentColor(CURSESPP_OVERLAY_BACKGROUND);
this->AddWindow(this->textInput);
}
InputOverlay::~InputOverlay() {
}
void InputOverlay::Layout() {
this->RecalculateSize();
if (this->width > 0 && this->height > 0) {
this->MoveAndResize(
this->x,
this->y,
this->width,
this->height);
this->textInput->MoveAndResize(
1, /* one pixel padding L and R */
2, /* below the title, plus an extra space */
this->GetContentWidth() - 2,
3); /* top and bottom border plus text */
this->Redraw();
}
}
InputOverlay& InputOverlay::SetTitle(const std::string& title) {
this->title = title;
this->RecalculateSize();
this->Layout();
this->Invalidate();
return *this;
}
InputOverlay& InputOverlay::SetText(const std::string& text) {
this->title = title;
this->textInput->SetText(text);
return *this;
}
InputOverlay& InputOverlay::SetWidth(int width) {
this->setWidth = width;
if (this->IsVisible()) {
this->Layout();
}
return *this;
}
InputOverlay& InputOverlay::SetInputAcceptedCallback(InputAcceptedCallback cb) {
this->inputAcceptedCallback = cb;
return *this;
}
void InputOverlay::OnVisibilityChanged(bool visible) {
if (visible) {
this->SetFocus(this->textInput);
this->Redraw();
}
}
void InputOverlay::RecalculateSize() {
this->width = this->setWidth > 0 ? this->setWidth : DEFAULT_WIDTH;
this->height = 1 + 1 + 1 + 3 + 1; /* top frame + text + space + text input + bottom frame */
/* constrain to app bounds */
this->height = std::max(0, std::min(Screen::GetHeight() - 4, this->height));
this->width = std::max(0, std::min(Screen::GetWidth(), this->width));
this->y = VERTICAL_PADDING;
this->x = (Screen::GetWidth() / 2) - (this->width / 2);
}
void InputOverlay::Redraw() {
if (this->width <= 0 || this->height <= 0) {
return;
}
WINDOW* c = this->GetContent();
if (this->title.size()) {
wmove(c, 0, 1);
wattron(c, A_BOLD);
wprintw(c, text::Ellipsize(this->title, this->width - 4).c_str());
wattroff(c, A_BOLD);
}
}

View File

@ -0,0 +1,74 @@
//////////////////////////////////////////////////////////////////////////////
//
// 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 "OverlayBase.h"
#include "TextInput.h"
namespace cursespp {
class InputOverlay :
public OverlayBase
#if (__clang_major__ == 7 && __clang_minor__ == 3)
, public std::enable_shared_from_this<InputOverlay>
#endif
{
public:
using InputAcceptedCallback = std::function<void(const std::string&)>;
InputOverlay();
virtual ~InputOverlay();
InputOverlay& SetTitle(const std::string& title);
InputOverlay& SetText(const std::string& text);
InputOverlay& SetInputAcceptedCallback(InputAcceptedCallback cb);
InputOverlay& SetWidth(int width);
virtual void Layout();
protected:
virtual void OnVisibilityChanged(bool visible);
private:
void Redraw();
void RecalculateSize();
std::string title, text;
int x, y;
int width, height;
int setWidth;
std::shared_ptr<TextInput> textInput;
InputAcceptedCallback inputAcceptedCallback;
};
}

View File

@ -124,6 +124,11 @@ ListOverlay& ListOverlay::SetItemSelectedCallback(ItemSelectedCallback cb) {
return *this; return *this;
} }
ListOverlay& ListOverlay::SetDeleteKeyCallback(DeleteKeyCallback cb) {
this->deleteKeyCallback = cb;
return *this;
}
bool ListOverlay::KeyPress(const std::string& key) { bool ListOverlay::KeyPress(const std::string& key) {
if (key == "^[") { /* esc closes */ if (key == "^[") { /* esc closes */
DISMISS(); DISMISS();
@ -138,6 +143,15 @@ bool ListOverlay::KeyPress(const std::string& key) {
DISMISS(); DISMISS();
return true; return true;
} }
else if (key == "KEY_BACKSPACE" || key == "KEY_DC") {
if (deleteKeyCallback) {
deleteKeyCallback(
this->adapter,
listWindow->GetSelectedIndex());
return true;
}
}
return LayoutBase::KeyPress(key); return LayoutBase::KeyPress(key);
} }

View File

@ -49,6 +49,7 @@ namespace cursespp {
{ {
public: public:
using ItemSelectedCallback = std::function<void(IScrollAdapterPtr adapter, size_t index)>; using ItemSelectedCallback = std::function<void(IScrollAdapterPtr adapter, size_t index)>;
using DeleteKeyCallback = std::function<void(IScrollAdapterPtr adapter, size_t index)>;
ListOverlay(); ListOverlay();
virtual ~ListOverlay(); virtual ~ListOverlay();
@ -56,6 +57,7 @@ namespace cursespp {
ListOverlay& SetTitle(const std::string& title); ListOverlay& SetTitle(const std::string& title);
ListOverlay& SetAdapter(IScrollAdapterPtr adapter); ListOverlay& SetAdapter(IScrollAdapterPtr adapter);
ListOverlay& SetItemSelectedCallback(ItemSelectedCallback cb); ListOverlay& SetItemSelectedCallback(ItemSelectedCallback cb);
ListOverlay& SetDeleteKeyCallback(DeleteKeyCallback cb);
ListOverlay& SetSelectedIndex(size_t index); ListOverlay& SetSelectedIndex(size_t index);
ListOverlay& SetWidth(int width); ListOverlay& SetWidth(int width);
@ -76,5 +78,6 @@ namespace cursespp {
IScrollAdapterPtr adapter; IScrollAdapterPtr adapter;
std::shared_ptr<ListWindow> listWindow; std::shared_ptr<ListWindow> listWindow;
ItemSelectedCallback itemSelectedCallback; ItemSelectedCallback itemSelectedCallback;
DeleteKeyCallback deleteKeyCallback;
}; };
} }