add OSK preview scrolling, background, fix DrawLayerProxy,

make TextConfig.Print string ref const, make form priority float,
ScrollField::ScrollIntoView, minor BitmapFont fix
This commit is contained in:
zetaPRIME 2017-03-16 20:35:04 -04:00
parent 5d7fd4d802
commit 5954dc5768
15 changed files with 98 additions and 35 deletions

View File

@ -347,11 +347,11 @@ TextConfig::TextConfig(const std::string& fontName, Color text, Color border) {
textColor = text; borderColor = border;
}
void TextConfig::Print(Vector2 position, std::string& text, Vector2 justification) {
void TextConfig::Print(Vector2 position, const std::string& text, Vector2 justification) {
if (!justification) justification = this->justification;
font->Print(position, text, 1, textColor, justification, borderColor);
}
void TextConfig::Print(VRect rect, std::string& text, Vector2 justification) {
void TextConfig::Print(VRect rect, const std::string& text, Vector2 justification) {
if (!justification) justification = this->justification;
font->Print(rect, text, 1, textColor, justification, borderColor);
}

View File

@ -85,8 +85,8 @@ namespace starlight {
TextConfig(const std::string& fontName, Color text, Color border = Color::transparent);
~TextConfig() = default;
void Print(Vector2 position, std::string& text, Vector2 justification = Vector2::invalid);
void Print(VRect rect, std::string& text, Vector2 justification = Vector2::invalid);
void Print(Vector2 position, const std::string& text, Vector2 justification = Vector2::invalid);
void Print(VRect rect, const std::string& text, Vector2 justification = Vector2::invalid);
Vector2 Measure(const std::string& text, float maxWidth = 65536*64);

View File

@ -32,7 +32,7 @@ namespace starlight {
VRect Intersect(const VRect & o) const;
VRect Expand(const Vector2& amount, const Vector2& bias) const;
VRect Expand(const Vector2& amount) const { return Expand(amount, Vector2::half); }
VRect Expand(float x, float y) const { return Expand(Vector2(x, y )); }
VRect Expand(float x, float y) const { return Expand(Vector2(x, y)); }
VRect Include(const Vector2& point) const;

View File

@ -36,13 +36,15 @@ namespace {
static auto tc = ThemeManager::GetMetric<starlight::TextConfig>("/dialogs/OSK/preview");
return tc;
}
const constexpr float textHang = 4;
}
OSK::OSK(osk::InputHandler* handler) : Form(true), handler(handler) {
priority = 1000; // probably don't want all that much displaying above the keyboard
handler->parent = this;
auto cover = std::make_shared<Image>(touchScreen->rect.Expand(4), "decorations/dialog.modal-cover");
auto cover = std::make_shared<Image>(touchScreen->rect, "decorations/osk.background");
cover->blockTouch = true;
touchScreen->Add(cover);
@ -58,7 +60,7 @@ OSK::OSK(osk::InputHandler* handler) : Form(true), handler(handler) {
Vector2 bs(24, 32);
Vector2 bpen;
Vector2 bpstart(160-bs.x*(12.5/2), 68);
Vector2 bpstart(160-bs.x*(12.5/2), 68+5);
int line = -1;
float linestart [] = {0, .5, .75, 1.25, 2.75-1};
string chr = "\n1234567890-=\nqwertyuiop[]\nasdfghjkl;\'\nzxcvbnm,./\n` \\";
@ -106,9 +108,14 @@ OSK::OSK(osk::InputHandler* handler) : Form(true), handler(handler) {
key->eOnTap = [this](auto& btn){ this->handler->Enter(); this->OnKey(); };
touchScreen->Add(key);
preview = std::make_shared<DrawLayerProxy>(VRect::touchScreen.TopEdge(68).Expand(-2), [this](auto& layer){ this->DrawPreview(layer); }, true);
previewSc = std::make_shared<ScrollField>(VRect(VRect::touchScreen.TopEdge(66)));
touchScreen->Add(previewSc);
preview = std::make_shared<DrawLayerProxy>(VRect::touchScreen.TopEdge(66).Expand(-2, 0), [this](auto& layer){ this->DrawPreview(layer); }, true);
preview->eOnTap = [this](auto& layer){ this->OnPreviewTap(layer); };
touchScreen->Add(preview);
previewSc->Add(preview);
RefreshPreview();
}
void OSK::Update(bool focused) {
@ -117,30 +124,29 @@ void OSK::Update(bool focused) {
}
if (focused) {
if (InputManager::Pressed(Keys::B)) handler->Done();
if (true || handler->showPreview) {
if (handler->showPreview) {
if (InputManager::Pressed(Keys::DPadLeft)) {
handler->SetCursor(handler->GetCursor() - 1);
preview->Refresh();
auto c = handler->GetCursor();
if (c > 0) handler->SetCursor(c - 1);
RefreshPreview();
}
if (InputManager::Pressed(Keys::DPadRight)) {
handler->SetCursor(handler->GetCursor() + 1);
preview->Refresh();
RefreshPreview();
}
auto& tc = PreviewTC();
if (InputManager::Pressed(Keys::DPadUp)) {
Vector2 pt = tc.GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor());
string msr = "|";
pt.y -= tc.Measure(msr).y * 0.5f;
pt.y -= tc.Measure("|").y * 0.5f;
handler->SetCursor(tc.GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt));
preview->Refresh();
RefreshPreview();
}
if (InputManager::Pressed(Keys::DPadDown)) {
Vector2 pt = tc.GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor());
string msr = "|";
pt.y += tc.Measure(msr).y * 1.5f;
pt.y += tc.Measure("|").y * 1.5f;
handler->SetCursor(tc.GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt));
preview->Refresh();
RefreshPreview();
}
}
@ -157,23 +163,47 @@ void OSK::Update(bool focused) {
}
void OSK::OnKey() {
RefreshPreview();
}
void OSK::RefreshPreview() {
auto& tc = PreviewTC();
if (handler->showPreview) {
Vector2 sz = tc.Measure(handler->GetPreviewText(), preview->rect.size.x);
preview->Resize(Vector2(preview->rect.size.x, std::max(sz.y + textHang, previewSc->rect.size.y))); // I guess a magic four will do
Vector2 cp = tc.GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor());
Vector2 cs = tc.Measure("|") + Vector2(0, textHang);
previewSc->ScrollIntoView(VRect(cp, cs));//*/
} else {
preview->Resize(Vector2(preview->rect.size.x, 66));
}
preview->Refresh();
}
void OSK::DrawPreview(DrawLayerProxy& layer) {
if (true || handler->showPreview) {
if (handler->showPreview) {
auto& tc = PreviewTC();
tc.Print(layer.rect, handler->GetPreviewText(), Vector2::zero);
Vector2 cp = tc.GetCursorPosition(layer.rect, handler->GetPreviewText(), handler->GetCursor());
string cc = "|";
tc.Print(cp, cc, Vector2::zero);
tc.Print(cp, cc);
//Vector2 cs = tc.Measure("|") + Vector2(0, textHang);
//previewSc->ScrollIntoView(VRect(cp, cs));
} else {
static auto tc = ThemeManager::GetMetric<starlight::TextConfig>("/dialogs/OSK/noPreview");
tc.Print(layer.rect, "(no preview available)");
}
}
void OSK::OnPreviewTap(DrawLayerProxy& layer) {
Vector2 tpos = InputManager::TouchPos() - layer.ScreenRect().pos;
auto& tc = PreviewTC();
handler->SetCursor(tc.GetCursorFromPoint(layer.rect, handler->GetPreviewText(), tpos));
preview->Refresh();
if (handler->showPreview) {
Vector2 tpos = InputManager::TouchPos() - layer.ScreenRect().pos;
auto& tc = PreviewTC();
handler->SetCursor(tc.GetCursorFromPoint(layer.rect, handler->GetPreviewText(), tpos));
RefreshPreview();
}
}

View File

@ -6,6 +6,7 @@
#include <memory>
#include "starlight/ui/Form.h"
#include "starlight/ui/ScrollField.h"
#include "starlight/ui/DrawLayerProxy.h"
#include "starlight/dialog/osk/InputHandler.h"
@ -15,7 +16,10 @@ namespace starlight {
class OSK : public ui::Form, public ui::FormCreator<OSK> {
private:
std::shared_ptr<ui::UIContainer> setContainer;
std::shared_ptr<ui::ScrollField> previewSc;
std::shared_ptr<ui::DrawLayerProxy> preview;
//Vector2 cursorPos;
public:
std::unique_ptr<osk::InputHandler> handler;
@ -27,6 +31,7 @@ namespace starlight {
void OnKey();
void RefreshPreview();
void DrawPreview(ui::DrawLayerProxy& layer);
void OnPreviewTap(ui::DrawLayerProxy& layer);
};

View File

@ -64,7 +64,9 @@ BitmapFont::CharInfo& BitmapFont::Char(char c) {
}
Vector2 BitmapFont::MeasureTo(const std::string& msg, bool total, unsigned int end, float maxWidth) {
if (msg == "") return Vector2::zero;
if (total) {
if (end == 0) return Vector2(0, lineHeight);
Vector2 measure = Vector2::zero;
ForChar(msg, [&, this](auto& s){
@ -81,11 +83,14 @@ Vector2 BitmapFont::MeasureTo(const std::string& msg, bool total, unsigned int e
Vector2 measure;
bool found = false;
ForChar(msg, [&, this, total, end](auto& s){
unsigned int et = end - 1;
if (end == 0) et = 0;
ForChar(msg, [&, this, total, end, et](auto& s){
measure = Vector2(s.lineAcc + s.cc->advX, lineHeight * s.lineNum);
if (s.i == end-1) {
if (s.i >= et) {
found = true;
if (s.i == s.lineEnd) measure = Vector2(0, lineHeight * (s.lineNum + 1)); // linebreak == next line
if (end == 0) measure = Vector2(0, lineHeight * s.lineNum);
return true;
}

View File

@ -29,6 +29,7 @@ void DrawLayerProxy::PreDraw() {
void DrawLayerProxy::Draw() {
if (canvas) {
auto rect = (this->rect + GFXManager::GetOffset()).IntSnap();
canvas->Draw(VRect(rect.pos, canvas->rect.size));
} else {
if (eDraw) eDraw(*this);

View File

@ -58,7 +58,7 @@ namespace starlight {
//
public:
int priority = 0;
float priority = 0;
unsigned int flags = 0;
std::shared_ptr<UIContainer> touchScreen = nullptr;

View File

@ -38,6 +38,18 @@ void ScrollField::Update() {
scrollOffset.y = std::max(0.0f, std::min(scrollOffset.y, scrollMax.y));
}
void ScrollField::ScrollIntoView(Vector2 pt) {
Vector2 sm = pt - rect.size;
scrollOffset.x = std::max(sm.x, std::min(scrollOffset.x, pt.x));
scrollOffset.y = std::max(sm.y, std::min(scrollOffset.y, pt.y));
// hmm. doesn't play well with pending resizes
//scrollOffset.x = std::max(0.0f, std::min(scrollOffset.x, scrollMax.x));
//scrollOffset.y = std::max(0.0f, std::min(scrollOffset.y, scrollMax.y));
}
void ScrollField::ScrollIntoView(VRect box) { ScrollIntoView(box.BottomRight()); ScrollIntoView(box.pos); }
void ScrollField::OnProcessTouchEvent() { // stop when child element touched
if (InputManager::Pressed(Keys::Touch)) scrollVel = Vector2::zero;
}

View File

@ -16,6 +16,9 @@ namespace starlight {
void Update() override;
void ScrollIntoView(Vector2 pt);
void ScrollIntoView(VRect box);
// events
void OnTouchOn() override;
void OnTouchOff() override { }
@ -33,4 +36,3 @@ namespace starlight {
};
}
}

View File

@ -3,20 +3,21 @@
roadmap to first release, in no particular order {
finish implementing OSK! {
enable scrolling preview (and scroll to cursor where applicable)
polish!
- fix cursor-down
polish! {
- background
actual cursor image?
}
InputManager::OpenKeyboard
}
fix [ offset (-1 it)
add generic backdrop assets (and form)
fix lowercase j running into things
adjust monospace line height (and maybe offset) to closer match the vwf of the same size
add license!! (MIT?)
ADD README.MD PLS
} then consider these before 1.0 "gold" {
should form priority be a float?
- should form priority be a float?
make closing forms a bit less finicky (add them to a separate list and let the Application remove them from the list)
add customization for Button (alternate idle/press images, optional glyph drawable)
^ use that to spice up the OSK

View File

@ -78,6 +78,7 @@ void Core::Init() {
auto tb = std::make_shared<sl::ui::TextBox>(VRect(0, 64, 320, 24).Expand(-16, 0));
tb->text = "TextBox testing in progress. ij ji lj jl";
tb->multiLine = true;
form->touchScreen->Add(tb);
/*label->SetFont("default.16");

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

View File

@ -45,6 +45,12 @@
"font" : "default.16",
"textColor" : "white",
"borderColor" : "black"
},
"noPreview" : {
"font" : "default.16",
"textColor" : "midGray",
"borderColor" : "darkGray",
"justification" : [0.5, 0.5]
}
}
},