forked from Mirror/libstarlight
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:
parent
5d7fd4d802
commit
5954dc5768
@ -347,11 +347,11 @@ TextConfig::TextConfig(const std::string& fontName, Color text, Color border) {
|
|||||||
textColor = text; borderColor = 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;
|
if (!justification) justification = this->justification;
|
||||||
font->Print(position, text, 1, textColor, justification, borderColor);
|
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;
|
if (!justification) justification = this->justification;
|
||||||
font->Print(rect, text, 1, textColor, justification, borderColor);
|
font->Print(rect, text, 1, textColor, justification, borderColor);
|
||||||
}
|
}
|
||||||
|
@ -85,8 +85,8 @@ namespace starlight {
|
|||||||
TextConfig(const std::string& fontName, Color text, Color border = Color::transparent);
|
TextConfig(const std::string& fontName, Color text, Color border = Color::transparent);
|
||||||
~TextConfig() = default;
|
~TextConfig() = default;
|
||||||
|
|
||||||
void Print(Vector2 position, std::string& text, Vector2 justification = Vector2::invalid);
|
void Print(Vector2 position, const std::string& text, Vector2 justification = Vector2::invalid);
|
||||||
void Print(VRect rect, 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);
|
Vector2 Measure(const std::string& text, float maxWidth = 65536*64);
|
||||||
|
|
||||||
|
@ -36,13 +36,15 @@ namespace {
|
|||||||
static auto tc = ThemeManager::GetMetric<starlight::TextConfig>("/dialogs/OSK/preview");
|
static auto tc = ThemeManager::GetMetric<starlight::TextConfig>("/dialogs/OSK/preview");
|
||||||
return tc;
|
return tc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const constexpr float textHang = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSK::OSK(osk::InputHandler* handler) : Form(true), handler(handler) {
|
OSK::OSK(osk::InputHandler* handler) : Form(true), handler(handler) {
|
||||||
priority = 1000; // probably don't want all that much displaying above the keyboard
|
priority = 1000; // probably don't want all that much displaying above the keyboard
|
||||||
handler->parent = this;
|
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;
|
cover->blockTouch = true;
|
||||||
touchScreen->Add(cover);
|
touchScreen->Add(cover);
|
||||||
|
|
||||||
@ -58,7 +60,7 @@ OSK::OSK(osk::InputHandler* handler) : Form(true), handler(handler) {
|
|||||||
|
|
||||||
Vector2 bs(24, 32);
|
Vector2 bs(24, 32);
|
||||||
Vector2 bpen;
|
Vector2 bpen;
|
||||||
Vector2 bpstart(160-bs.x*(12.5/2), 68);
|
Vector2 bpstart(160-bs.x*(12.5/2), 68+5);
|
||||||
int line = -1;
|
int line = -1;
|
||||||
float linestart [] = {0, .5, .75, 1.25, 2.75-1};
|
float linestart [] = {0, .5, .75, 1.25, 2.75-1};
|
||||||
string chr = "\n1234567890-=\nqwertyuiop[]\nasdfghjkl;\'\nzxcvbnm,./\n` \\";
|
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(); };
|
key->eOnTap = [this](auto& btn){ this->handler->Enter(); this->OnKey(); };
|
||||||
touchScreen->Add(key);
|
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); };
|
preview->eOnTap = [this](auto& layer){ this->OnPreviewTap(layer); };
|
||||||
touchScreen->Add(preview);
|
previewSc->Add(preview);
|
||||||
|
|
||||||
|
RefreshPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSK::Update(bool focused) {
|
void OSK::Update(bool focused) {
|
||||||
@ -117,30 +124,29 @@ void OSK::Update(bool focused) {
|
|||||||
}
|
}
|
||||||
if (focused) {
|
if (focused) {
|
||||||
if (InputManager::Pressed(Keys::B)) handler->Done();
|
if (InputManager::Pressed(Keys::B)) handler->Done();
|
||||||
if (true || handler->showPreview) {
|
if (handler->showPreview) {
|
||||||
if (InputManager::Pressed(Keys::DPadLeft)) {
|
if (InputManager::Pressed(Keys::DPadLeft)) {
|
||||||
handler->SetCursor(handler->GetCursor() - 1);
|
auto c = handler->GetCursor();
|
||||||
preview->Refresh();
|
if (c > 0) handler->SetCursor(c - 1);
|
||||||
|
RefreshPreview();
|
||||||
}
|
}
|
||||||
if (InputManager::Pressed(Keys::DPadRight)) {
|
if (InputManager::Pressed(Keys::DPadRight)) {
|
||||||
handler->SetCursor(handler->GetCursor() + 1);
|
handler->SetCursor(handler->GetCursor() + 1);
|
||||||
preview->Refresh();
|
RefreshPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& tc = PreviewTC();
|
auto& tc = PreviewTC();
|
||||||
if (InputManager::Pressed(Keys::DPadUp)) {
|
if (InputManager::Pressed(Keys::DPadUp)) {
|
||||||
Vector2 pt = tc.GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor());
|
Vector2 pt = tc.GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor());
|
||||||
string msr = "|";
|
pt.y -= tc.Measure("|").y * 0.5f;
|
||||||
pt.y -= tc.Measure(msr).y * 0.5f;
|
|
||||||
handler->SetCursor(tc.GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt));
|
handler->SetCursor(tc.GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt));
|
||||||
preview->Refresh();
|
RefreshPreview();
|
||||||
}
|
}
|
||||||
if (InputManager::Pressed(Keys::DPadDown)) {
|
if (InputManager::Pressed(Keys::DPadDown)) {
|
||||||
Vector2 pt = tc.GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor());
|
Vector2 pt = tc.GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor());
|
||||||
string msr = "|";
|
pt.y += tc.Measure("|").y * 1.5f;
|
||||||
pt.y += tc.Measure(msr).y * 1.5f;
|
|
||||||
handler->SetCursor(tc.GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt));
|
handler->SetCursor(tc.GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt));
|
||||||
preview->Refresh();
|
RefreshPreview();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,23 +163,47 @@ void OSK::Update(bool focused) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OSK::OnKey() {
|
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();
|
preview->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSK::DrawPreview(DrawLayerProxy& layer) {
|
void OSK::DrawPreview(DrawLayerProxy& layer) {
|
||||||
if (true || handler->showPreview) {
|
if (handler->showPreview) {
|
||||||
auto& tc = PreviewTC();
|
auto& tc = PreviewTC();
|
||||||
tc.Print(layer.rect, handler->GetPreviewText(), Vector2::zero);
|
tc.Print(layer.rect, handler->GetPreviewText(), Vector2::zero);
|
||||||
|
|
||||||
Vector2 cp = tc.GetCursorPosition(layer.rect, handler->GetPreviewText(), handler->GetCursor());
|
Vector2 cp = tc.GetCursorPosition(layer.rect, handler->GetPreviewText(), handler->GetCursor());
|
||||||
string cc = "|";
|
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) {
|
void OSK::OnPreviewTap(DrawLayerProxy& layer) {
|
||||||
|
if (handler->showPreview) {
|
||||||
Vector2 tpos = InputManager::TouchPos() - layer.ScreenRect().pos;
|
Vector2 tpos = InputManager::TouchPos() - layer.ScreenRect().pos;
|
||||||
auto& tc = PreviewTC();
|
auto& tc = PreviewTC();
|
||||||
handler->SetCursor(tc.GetCursorFromPoint(layer.rect, handler->GetPreviewText(), tpos));
|
handler->SetCursor(tc.GetCursorFromPoint(layer.rect, handler->GetPreviewText(), tpos));
|
||||||
preview->Refresh();
|
RefreshPreview();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "starlight/ui/Form.h"
|
#include "starlight/ui/Form.h"
|
||||||
|
#include "starlight/ui/ScrollField.h"
|
||||||
#include "starlight/ui/DrawLayerProxy.h"
|
#include "starlight/ui/DrawLayerProxy.h"
|
||||||
|
|
||||||
#include "starlight/dialog/osk/InputHandler.h"
|
#include "starlight/dialog/osk/InputHandler.h"
|
||||||
@ -15,8 +16,11 @@ namespace starlight {
|
|||||||
class OSK : public ui::Form, public ui::FormCreator<OSK> {
|
class OSK : public ui::Form, public ui::FormCreator<OSK> {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<ui::UIContainer> setContainer;
|
std::shared_ptr<ui::UIContainer> setContainer;
|
||||||
|
std::shared_ptr<ui::ScrollField> previewSc;
|
||||||
std::shared_ptr<ui::DrawLayerProxy> preview;
|
std::shared_ptr<ui::DrawLayerProxy> preview;
|
||||||
|
|
||||||
|
//Vector2 cursorPos;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<osk::InputHandler> handler;
|
std::unique_ptr<osk::InputHandler> handler;
|
||||||
|
|
||||||
@ -27,6 +31,7 @@ namespace starlight {
|
|||||||
|
|
||||||
void OnKey();
|
void OnKey();
|
||||||
|
|
||||||
|
void RefreshPreview();
|
||||||
void DrawPreview(ui::DrawLayerProxy& layer);
|
void DrawPreview(ui::DrawLayerProxy& layer);
|
||||||
void OnPreviewTap(ui::DrawLayerProxy& layer);
|
void OnPreviewTap(ui::DrawLayerProxy& layer);
|
||||||
};
|
};
|
||||||
|
@ -64,7 +64,9 @@ BitmapFont::CharInfo& BitmapFont::Char(char c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector2 BitmapFont::MeasureTo(const std::string& msg, bool total, unsigned int end, float maxWidth) {
|
Vector2 BitmapFont::MeasureTo(const std::string& msg, bool total, unsigned int end, float maxWidth) {
|
||||||
|
if (msg == "") return Vector2::zero;
|
||||||
if (total) {
|
if (total) {
|
||||||
|
if (end == 0) return Vector2(0, lineHeight);
|
||||||
Vector2 measure = Vector2::zero;
|
Vector2 measure = Vector2::zero;
|
||||||
|
|
||||||
ForChar(msg, [&, this](auto& s){
|
ForChar(msg, [&, this](auto& s){
|
||||||
@ -81,11 +83,14 @@ Vector2 BitmapFont::MeasureTo(const std::string& msg, bool total, unsigned int e
|
|||||||
Vector2 measure;
|
Vector2 measure;
|
||||||
bool found = false;
|
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);
|
measure = Vector2(s.lineAcc + s.cc->advX, lineHeight * s.lineNum);
|
||||||
if (s.i == end-1) {
|
if (s.i >= et) {
|
||||||
found = true;
|
found = true;
|
||||||
if (s.i == s.lineEnd) measure = Vector2(0, lineHeight * (s.lineNum + 1)); // linebreak == next line
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ void DrawLayerProxy::PreDraw() {
|
|||||||
|
|
||||||
void DrawLayerProxy::Draw() {
|
void DrawLayerProxy::Draw() {
|
||||||
if (canvas) {
|
if (canvas) {
|
||||||
|
auto rect = (this->rect + GFXManager::GetOffset()).IntSnap();
|
||||||
canvas->Draw(VRect(rect.pos, canvas->rect.size));
|
canvas->Draw(VRect(rect.pos, canvas->rect.size));
|
||||||
} else {
|
} else {
|
||||||
if (eDraw) eDraw(*this);
|
if (eDraw) eDraw(*this);
|
||||||
|
@ -58,7 +58,7 @@ namespace starlight {
|
|||||||
//
|
//
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int priority = 0;
|
float priority = 0;
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
|
|
||||||
std::shared_ptr<UIContainer> touchScreen = nullptr;
|
std::shared_ptr<UIContainer> touchScreen = nullptr;
|
||||||
|
@ -38,6 +38,18 @@ void ScrollField::Update() {
|
|||||||
scrollOffset.y = std::max(0.0f, std::min(scrollOffset.y, scrollMax.y));
|
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
|
void ScrollField::OnProcessTouchEvent() { // stop when child element touched
|
||||||
if (InputManager::Pressed(Keys::Touch)) scrollVel = Vector2::zero;
|
if (InputManager::Pressed(Keys::Touch)) scrollVel = Vector2::zero;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,9 @@ namespace starlight {
|
|||||||
|
|
||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
||||||
|
void ScrollIntoView(Vector2 pt);
|
||||||
|
void ScrollIntoView(VRect box);
|
||||||
|
|
||||||
// events
|
// events
|
||||||
void OnTouchOn() override;
|
void OnTouchOn() override;
|
||||||
void OnTouchOff() override { }
|
void OnTouchOff() override { }
|
||||||
@ -33,4 +36,3 @@ namespace starlight {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,20 +3,21 @@
|
|||||||
|
|
||||||
roadmap to first release, in no particular order {
|
roadmap to first release, in no particular order {
|
||||||
finish implementing OSK! {
|
finish implementing OSK! {
|
||||||
enable scrolling preview (and scroll to cursor where applicable)
|
- fix cursor-down
|
||||||
polish!
|
polish! {
|
||||||
|
- background
|
||||||
|
actual cursor image?
|
||||||
|
}
|
||||||
InputManager::OpenKeyboard
|
InputManager::OpenKeyboard
|
||||||
}
|
}
|
||||||
|
fix [ offset (-1 it)
|
||||||
|
|
||||||
add generic backdrop assets (and form)
|
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 license!! (MIT?)
|
||||||
ADD README.MD PLS
|
ADD README.MD PLS
|
||||||
} then consider these before 1.0 "gold" {
|
} 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)
|
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)
|
add customization for Button (alternate idle/press images, optional glyph drawable)
|
||||||
^ use that to spice up the OSK
|
^ use that to spice up the OSK
|
||||||
|
@ -78,6 +78,7 @@ void Core::Init() {
|
|||||||
|
|
||||||
auto tb = std::make_shared<sl::ui::TextBox>(VRect(0, 64, 320, 24).Expand(-16, 0));
|
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->text = "TextBox testing in progress. ij ji lj jl";
|
||||||
|
tb->multiLine = true;
|
||||||
form->touchScreen->Add(tb);
|
form->touchScreen->Add(tb);
|
||||||
|
|
||||||
/*label->SetFont("default.16");
|
/*label->SetFont("default.16");
|
||||||
|
BIN
themes/default/decorations/osk.background.png
Normal file
BIN
themes/default/decorations/osk.background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.8 KiB |
BIN
themes/default/decorations/osk.background.xcf
Normal file
BIN
themes/default/decorations/osk.background.xcf
Normal file
Binary file not shown.
@ -45,6 +45,12 @@
|
|||||||
"font" : "default.16",
|
"font" : "default.16",
|
||||||
"textColor" : "white",
|
"textColor" : "white",
|
||||||
"borderColor" : "black"
|
"borderColor" : "black"
|
||||||
|
},
|
||||||
|
"noPreview" : {
|
||||||
|
"font" : "default.16",
|
||||||
|
"textColor" : "midGray",
|
||||||
|
"borderColor" : "darkGray",
|
||||||
|
"justification" : [0.5, 0.5]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user