- Added Overlays::Push, Overlays::Remove

- Fixed dismissing of overlay and proper redrawing in App
- New overlay frame style in Colors
This commit is contained in:
Casey Langen 2016-09-02 00:34:04 -07:00
parent b1bbb6485c
commit 55b2f262bf
7 changed files with 118 additions and 18 deletions

View File

@ -256,10 +256,11 @@ void App::CheckShowOverlay() {
this->state.overlay = top;
if (top) {
top->Layout();
top->Show();
top->BringToTop();
ILayoutPtr newTopLayout = this->state.ActiveLayout();
if (newTopLayout) {
newTopLayout->Layout();
newTopLayout->Show();
newTopLayout->BringToTop();
}
}
}

View File

@ -138,5 +138,6 @@ void Colors::Init(bool disableCustomColors) {
init_pair(CURSESPP_SHORTCUT_ROW_NORMAL, yellow, selected);
init_pair(CURSESPP_SHORTCUT_ROW_FOCUSED, white, darkRed);
init_pair(CURSESPP_OVERLAY_FRAME, blue, selected);
init_pair(CURSESPP_OVERLAY_BACKGROUND, white, selected);
}

View File

@ -61,7 +61,8 @@
#define CURSESPP_SHORTCUT_ROW_NORMAL 19
#define CURSESPP_SHORTCUT_ROW_FOCUSED 20
#define CURSESPP_OVERLAY_BACKGROUND 21
#define CURSESPP_OVERLAY_FRAME 21
#define CURSESPP_OVERLAY_BACKGROUND 22
namespace cursespp {
class Colors {

View File

@ -43,25 +43,40 @@ using namespace cursespp;
#define VERTICAL_PADDING 2
DialogOverlay::DialogOverlay() {
this->SetFrameVisible(true);
this->SetFrameColor(CURSESPP_OVERLAY_FRAME);
this->SetContentColor(CURSESPP_OVERLAY_BACKGROUND);
this->width = this->height = 0;
this->shortcuts.reset(new ShortcutsWindow());
this->AddWindow(this->shortcuts);
}
void DialogOverlay::Layout() {
void DialogOverlay::Layout() {
this->RecalculateSize();
this->MoveAndResize(
HORIZONTAL_PADDING,
VERTICAL_PADDING,
this->width,
this->height);
if (this->width > 0 && this->height > 0) {
this->MoveAndResize(
HORIZONTAL_PADDING,
VERTICAL_PADDING,
this->width,
this->height + 2);
this->Redraw();
this->shortcuts->MoveAndResize(
HORIZONTAL_PADDING + 1,
VERTICAL_PADDING + this->height,
this->GetContentWidth(),
1);
this->Redraw();
}
}
DialogOverlay& DialogOverlay::SetTitle(const std::string& title) {
this->title = title;
this->RecalculateSize();
this->Layout();
this->Repaint();
return *this;
}
@ -70,10 +85,35 @@ DialogOverlay& DialogOverlay::SetMessage(const std::string& message) {
this->message = message;
this->width = 0; /* implicitly triggers a new BreakLines() */
this->RecalculateSize();
this->Layout();
this->Repaint();
return *this;
}
DialogOverlay& DialogOverlay::AddButton(
const std::string& rawKey,
const std::string& key,
const std::string& caption,
ButtonCallback callback)
{
this->shortcuts->AddShortcut(key, caption);
this->buttons[rawKey] = callback;
this->Layout();
this->Repaint();
return *this;
}
bool DialogOverlay::KeyPress(const std::string& key) {
ButtonCallback cb = this->buttons[key];
if (cb) {
cb(key);
return true;
}
return LayoutBase::KeyPress(key);
}
void DialogOverlay::OnVisibilityChanged(bool visible) {
if (visible) {
this->Redraw();
@ -82,24 +122,29 @@ void DialogOverlay::OnVisibilityChanged(bool visible) {
void DialogOverlay::RecalculateSize() {
int lastWidth = this->width;
this->width = std::max(0, Screen::GetWidth() - (HORIZONTAL_PADDING * 2));
if (lastWidth != this->width) {
/* the "-2" is for left and right padding */
messageLines = text::BreakLines(this->message, this->width - 2);
}
this->height = 1; /* top padding */
this->height = 0; /* top padding */
this->height += (this->title.size()) ? 2 : 0;
this->height += (this->messageLines.size()) ? messageLines.size() + 1 : 0;
this->height += 1; /* shortcuts */
}
void DialogOverlay::Redraw() {
if (this->width <= 0 || this->height <= 0) {
return;
}
WINDOW* c = this->GetContent();
const int currentX = 1;
int currentY = 1;
int currentY = 0;
if (this->title.size()) {
wmove(c, currentY, currentX);

View File

@ -36,7 +36,10 @@
#include "LayoutBase.h"
#include "TextLabel.h"
#include "ShortcutsWindow.h"
#include <vector>
#include <map>
namespace cursespp {
class DialogOverlay :
@ -44,12 +47,22 @@ namespace cursespp {
public std::enable_shared_from_this<DialogOverlay>
{
public:
using ButtonCallback = std::function<void(std::string key)>;
DialogOverlay();
virtual void Layout();
DialogOverlay& SetTitle(const std::string& title);
DialogOverlay& SetMessage(const std::string& message);
DialogOverlay& AddButton(
const std::string& rawKey,
const std::string& key,
const std::string& caption,
ButtonCallback callback);
virtual void Layout();
virtual bool KeyPress(const std::string& key);
protected:
virtual void OnVisibilityChanged(bool visible);
@ -60,6 +73,9 @@ namespace cursespp {
std::string title;
std::string message;
std::vector<std::string> messageLines;
std::shared_ptr<ShortcutsWindow> shortcuts;
int width, height;
std::map<std::string, ButtonCallback> buttons;
};
}

View File

@ -45,11 +45,42 @@ std::shared_ptr<DialogOverlay> temp;
Overlays::Overlays() {
temp.reset(new DialogOverlay());
temp->SetTitle("musikbox")
.SetMessage("welcome to musikbox! welcome to musikbox! welcome to musikbox! welcome to musikbox!\n\ntesting line breaks");
temp->AddButton(
"KEY_ENTER",
"ENTER",
"ok",
[this](std::string kn) {
this->Remove(temp);
});
temp->AddButton(
"^[",
"ESC",
"cancel",
[this](std::string kn) {
});
this->Push(temp);
}
ILayoutPtr Overlays::Top() {
// return temp;
return none;
return this->stack.size() ? this->stack[0] : none;
}
void Overlays::Push(ILayoutPtr overlay) {
this->stack.insert(this->stack.begin(), overlay);
}
void Overlays::Remove(ILayoutPtr overlay) {
auto it = std::find(
this->stack.begin(), this->stack.end(), overlay);
if (it != this->stack.end()) {
this->stack.erase(it);
}
}

View File

@ -41,5 +41,10 @@ namespace cursespp {
public:
Overlays();
ILayoutPtr Top();
void Push(ILayoutPtr overlay);
void Remove(ILayoutPtr overlay);
private:
std::vector<ILayoutPtr> stack;
};
}