From e22c8995a648828973e35ff5c00b9e6ac77b7e54 Mon Sep 17 00:00:00 2001 From: zetaPRIME Date: Thu, 16 Mar 2017 13:25:16 -0400 Subject: [PATCH] TextBox widget, justification and inheritance in TextConfig, fix closing osk from InputHandler, make font text input const, font-related miscellany --- .../source/starlight/ThemeManager.cpp | 36 ++++-- libstarlight/source/starlight/ThemeManager.h | 10 +- libstarlight/source/starlight/dialog/OSK.cpp | 19 ++-- .../starlight/dialog/osk/InputHandler.cpp | 4 +- .../starlight/dialog/osk/InputHandler.h | 2 + .../source/starlight/gfx/BitmapFont.cpp | 4 +- .../source/starlight/gfx/BitmapFont.h | 4 +- libstarlight/source/starlight/gfx/Font.h | 11 +- libstarlight/source/starlight/gfx/FontBMF.cpp | 12 +- libstarlight/source/starlight/gfx/FontBMF.h | 10 +- libstarlight/source/starlight/gfx/ThemeRef.h | 1 + libstarlight/source/starlight/ui/Button.cpp | 4 +- libstarlight/source/starlight/ui/TextBox.cpp | 103 ++++++++++++++++++ libstarlight/source/starlight/ui/TextBox.h | 44 ++++++++ libstarlight/todo.txt | 69 +++--------- testbed/source/Core.cpp | 10 +- themes/default/controls/textBox.json | 4 + themes/default/controls/textBox.png | Bin 0 -> 418 bytes themes/default/controls/textBox.xcf | Bin 0 -> 4516 bytes themes/default/metrics.json | 7 ++ 20 files changed, 257 insertions(+), 97 deletions(-) create mode 100644 libstarlight/source/starlight/ui/TextBox.cpp create mode 100644 libstarlight/source/starlight/ui/TextBox.h create mode 100644 themes/default/controls/textBox.json create mode 100644 themes/default/controls/textBox.png create mode 100644 themes/default/controls/textBox.xcf diff --git a/libstarlight/source/starlight/ThemeManager.cpp b/libstarlight/source/starlight/ThemeManager.cpp index 7bd17fa..221c03d 100644 --- a/libstarlight/source/starlight/ThemeManager.cpp +++ b/libstarlight/source/starlight/ThemeManager.cpp @@ -347,10 +347,27 @@ TextConfig::TextConfig(const std::string& fontName, Color text, Color border) { textColor = text; borderColor = border; } -void TextConfig::Print(Vector2 position, std::string& text, Vector2 justification) - { font->Print(position, text, 1, textColor, justification, borderColor); } -void TextConfig::Print(VRect rect, std::string& text, Vector2 justification) - { font->Print(rect, text, 1, textColor, justification, borderColor); } +void TextConfig::Print(Vector2 position, 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) { + if (!justification) justification = this->justification; + font->Print(rect, text, 1, textColor, justification, borderColor); +} + +Vector2 TextConfig::Measure(const std::string& text, float maxWidth) { + return font->Measure(text, 1, maxWidth); +} + +Vector2 TextConfig::GetCursorPosition(VRect rect, const std::string& text, unsigned int end) { + if (borderColor != Color::transparent) rect = rect.Expand(-1); // sync with drawing where bordered + return font->GetCursorPosition(rect, text, end); +} +unsigned int TextConfig::GetCursorFromPoint(VRect rect, const std::string& text, Vector2 pt) { + if (borderColor != Color::transparent) rect = rect.Expand(-1); // sync with drawing where bordered + return font->GetCursorFromPoint(rect, text, pt); +} namespace starlight { // todo: expose these in the header void to_json(nlohmann::json& j, const TextConfig& tc) { @@ -358,9 +375,14 @@ namespace starlight { // todo: expose these in the header } void from_json(const nlohmann::json& j, TextConfig& tc) { if (j.is_object()) { - tc.font = ThemeManager::GetFont(j.value("font", "default.12")); - tc.textColor = j.value("textColor", Color::white); - tc.borderColor = j.value("borderColor", Color::transparent); + std::string inh = j.value("_inherit", ""); + if (inh != "") { + tc = ThemeManager::GetMetric(inh); + } + tc.font = ThemeManager::GetFont(j.value("font", tc.font.GetName())); + tc.textColor = j.value("textColor", tc.textColor); + tc.borderColor = j.value("borderColor", tc.borderColor); + tc.justification = j.value("justification", tc.justification); } // } diff --git a/libstarlight/source/starlight/ThemeManager.h b/libstarlight/source/starlight/ThemeManager.h index 8a694c4..2795d76 100644 --- a/libstarlight/source/starlight/ThemeManager.h +++ b/libstarlight/source/starlight/ThemeManager.h @@ -79,12 +79,18 @@ namespace starlight { gfx::ThemeRef font = ThemeManager::GetFont("default.12"); Color textColor = Color::white; Color borderColor = Color::transparent; + Vector2 justification = Vector2::zero; TextConfig() = default; TextConfig(const std::string& fontName, Color text, Color border = Color::transparent); ~TextConfig() = default; - void Print(Vector2 position, std::string& text, Vector2 justification = Vector2::zero); - void Print(VRect rect, std::string& text, Vector2 justification = Vector2::zero); + void Print(Vector2 position, std::string& text, Vector2 justification = Vector2::invalid); + void Print(VRect rect, std::string& text, Vector2 justification = Vector2::invalid); + + Vector2 Measure(const std::string& text, float maxWidth = 65536*64); + + Vector2 GetCursorPosition(VRect rect, const std::string& text, unsigned int end); + unsigned int GetCursorFromPoint(VRect rect, const std::string& text, Vector2 pt); }; } diff --git a/libstarlight/source/starlight/dialog/OSK.cpp b/libstarlight/source/starlight/dialog/OSK.cpp index 3cf42ca..8b6b713 100644 --- a/libstarlight/source/starlight/dialog/OSK.cpp +++ b/libstarlight/source/starlight/dialog/OSK.cpp @@ -112,6 +112,9 @@ OSK::OSK(osk::InputHandler* handler) : Form(true), handler(handler) { } void OSK::Update(bool focused) { + if (handler->done) { + Close(); + } if (focused) { if (InputManager::Pressed(Keys::B)) handler->Done(); if (true || handler->showPreview) { @@ -126,17 +129,17 @@ void OSK::Update(bool focused) { auto& tc = PreviewTC(); if (InputManager::Pressed(Keys::DPadUp)) { - Vector2 pt = tc.font->GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor()); + Vector2 pt = tc.GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor()); string msr = "|"; - pt.y -= tc.font->Measure(msr).y * 0.5f; - handler->SetCursor(tc.font->GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt)); + pt.y -= tc.Measure(msr).y * 0.5f; + handler->SetCursor(tc.GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt)); preview->Refresh(); } if (InputManager::Pressed(Keys::DPadDown)) { - Vector2 pt = tc.font->GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor()); + Vector2 pt = tc.GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor()); string msr = "|"; - pt.y += tc.font->Measure(msr).y * 1.5f; - handler->SetCursor(tc.font->GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt)); + pt.y += tc.Measure(msr).y * 1.5f; + handler->SetCursor(tc.GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt)); preview->Refresh(); } } @@ -162,7 +165,7 @@ void OSK::DrawPreview(DrawLayerProxy& layer) { auto& tc = PreviewTC(); tc.Print(layer.rect, handler->GetPreviewText(), Vector2::zero); - Vector2 cp = tc.font->GetCursorPosition(layer.rect, handler->GetPreviewText(), handler->GetCursor()); + Vector2 cp = tc.GetCursorPosition(layer.rect, handler->GetPreviewText(), handler->GetCursor()); string cc = "|"; tc.Print(cp, cc, Vector2::zero); } @@ -171,6 +174,6 @@ void OSK::DrawPreview(DrawLayerProxy& layer) { void OSK::OnPreviewTap(DrawLayerProxy& layer) { Vector2 tpos = InputManager::TouchPos() - layer.ScreenRect().pos; auto& tc = PreviewTC(); - handler->SetCursor(tc.font->GetCursorFromPoint(layer.rect, handler->GetPreviewText(), tpos)); + handler->SetCursor(tc.GetCursorFromPoint(layer.rect, handler->GetPreviewText(), tpos)); preview->Refresh(); } diff --git a/libstarlight/source/starlight/dialog/osk/InputHandler.cpp b/libstarlight/source/starlight/dialog/osk/InputHandler.cpp index fa7f09c..f74a2f5 100644 --- a/libstarlight/source/starlight/dialog/osk/InputHandler.cpp +++ b/libstarlight/source/starlight/dialog/osk/InputHandler.cpp @@ -40,7 +40,7 @@ void InputHandlerDirectEdit::Enter() { void InputHandlerDirectEdit::Done() { if (eOnFinalize) eOnFinalize(); - parent->Close(); + done = true; } // Buffered @@ -66,5 +66,5 @@ void InputHandlerBuffered::Enter() { void InputHandlerBuffered::Done() { if (eOnFinalize) eOnFinalize(buffer); - parent->Close(); + done = true; } diff --git a/libstarlight/source/starlight/dialog/osk/InputHandler.h b/libstarlight/source/starlight/dialog/osk/InputHandler.h index 6f9a16a..4b36ba3 100644 --- a/libstarlight/source/starlight/dialog/osk/InputHandler.h +++ b/libstarlight/source/starlight/dialog/osk/InputHandler.h @@ -18,6 +18,8 @@ namespace starlight { bool showPreview = false; ui::Form* parent; + bool done = false; + InputHandler() = default; virtual ~InputHandler() = default; diff --git a/libstarlight/source/starlight/gfx/BitmapFont.cpp b/libstarlight/source/starlight/gfx/BitmapFont.cpp index 98da6c5..9ca001d 100644 --- a/libstarlight/source/starlight/gfx/BitmapFont.cpp +++ b/libstarlight/source/starlight/gfx/BitmapFont.cpp @@ -63,7 +63,7 @@ BitmapFont::CharInfo& BitmapFont::Char(char c) { return cdefault; } -Vector2 BitmapFont::MeasureTo(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 (total) { Vector2 measure = Vector2::zero; @@ -100,7 +100,7 @@ Vector2 BitmapFont::MeasureTo(std::string& msg, bool total, unsigned int end, fl return measure; } -unsigned int BitmapFont::PointToIndex(std::string& msg, Vector2 pt, float maxWidth) { +unsigned int BitmapFont::PointToIndex(const std::string& msg, Vector2 pt, float maxWidth) { //pt -= Vector2(padX, 0*padY); if (pt.y < 0) return 0; unsigned int tl = std::floor(pt.y / lineHeight); diff --git a/libstarlight/source/starlight/gfx/BitmapFont.h b/libstarlight/source/starlight/gfx/BitmapFont.h index a692435..3247444 100644 --- a/libstarlight/source/starlight/gfx/BitmapFont.h +++ b/libstarlight/source/starlight/gfx/BitmapFont.h @@ -62,8 +62,8 @@ namespace starlight { void ForChar(const std::string& msg, std::function func, float maxWidth = 65536*64); - Vector2 MeasureTo(std::string& msg, bool total = true, unsigned int end = 4294967295, float maxWidth = 65536*64); - unsigned int PointToIndex(std::string& msg, Vector2 pt, float maxWidth = 65536*64); + Vector2 MeasureTo(const std::string& msg, bool total = true, unsigned int end = 4294967295, float maxWidth = 65536*64); + unsigned int PointToIndex(const std::string& msg, Vector2 pt, float maxWidth = 65536*64); static inline constexpr unsigned int KerningKey(char cl, char cr) { return (static_cast(cl) | (static_cast(cr) << 8)); diff --git a/libstarlight/source/starlight/gfx/Font.h b/libstarlight/source/starlight/gfx/Font.h index e4e3ed5..7995180 100644 --- a/libstarlight/source/starlight/gfx/Font.h +++ b/libstarlight/source/starlight/gfx/Font.h @@ -19,14 +19,15 @@ namespace starlight { Font() { } virtual ~Font() { } - virtual Vector2 Measure(std::string& text, float scale = 1, float maxWidth = 400) = 0; - virtual void Print(Vector2 position, std::string& text, float scale = 1, Color color = Color::white, Vector2 justification = Vector2::zero, OptRef borderColor = nullptr) = 0; - virtual void Print(VRect rect, std::string& text, float scale = 1, Color color = Color::white, Vector2 justification = Vector2::zero, OptRef borderColor = nullptr) = 0; + virtual void Print(Vector2 position, const std::string& text, float scale = 1, Color color = Color::white, Vector2 justification = Vector2::zero, OptRef borderColor = nullptr) = 0; + virtual void Print(VRect rect, const std::string& text, float scale = 1, Color color = Color::white, Vector2 justification = Vector2::zero, OptRef borderColor = nullptr) = 0; //virtual void PrintDisplayList(DisplayList* dl, Vector2 position, std::string& text, float scale = 1, Color color = Color::white, Vector2 justification = Vector2::zero, OptRef borderColor = nullptr) = 0; //virtual void PrintDisplayList(DisplayList* dl, VRect rect, std::string& text, float scale = 1, Color color = Color::white, Vector2 justification = Vector2::zero, OptRef borderColor = nullptr) = 0; - virtual Vector2 GetCursorPosition(VRect rect, std::string& text, unsigned int end, float scale = 1) = 0; - virtual unsigned int GetCursorFromPoint(VRect rect, std::string& text, Vector2 pt, float scale = 1) = 0; + virtual Vector2 Measure(const std::string& text, float scale = 1, float maxWidth = 400) = 0; + + virtual Vector2 GetCursorPosition(VRect rect, const std::string& text, unsigned int end, float scale = 1) = 0; + virtual unsigned int GetCursorFromPoint(VRect rect, const std::string& text, Vector2 pt, float scale = 1) = 0; }; } diff --git a/libstarlight/source/starlight/gfx/FontBMF.cpp b/libstarlight/source/starlight/gfx/FontBMF.cpp index dc49bce..65cd3ef 100644 --- a/libstarlight/source/starlight/gfx/FontBMF.cpp +++ b/libstarlight/source/starlight/gfx/FontBMF.cpp @@ -16,12 +16,12 @@ using starlight::gfx::FontBMF; //#define err(nth, wat) *((unsigned int*)0x00100000+(nth))=wat; //#define ded(wat) err(0,wat) -Vector2 FontBMF::Measure(std::string& text, float scale, float maxWidth) { +Vector2 FontBMF::Measure(const std::string& text, float scale, float maxWidth) { if (text == "") return Vector2::zero; return font->MeasureTo(text, true, text.length(), maxWidth) * scale; } -void FontBMF::Print(Vector2 position, std::string& text, float scale, Color color, Vector2 justification, OptRef borderColor) { +void FontBMF::Print(Vector2 position, const std::string& text, float scale, Color color, Vector2 justification, OptRef borderColor) { if (text == "") return; if (GFXManager::PrepareForDrawing()) { DisplayList dl = DisplayList(); @@ -48,10 +48,10 @@ void FontBMF::Print(Vector2 position, std::string& text, float scale, Color colo } } -void FontBMF::Print(VRect rect, std::string& text, float scale, Color color, Vector2 justification, OptRef borderColor) { +void FontBMF::Print(VRect rect, const std::string& text, float scale, Color color, Vector2 justification, OptRef borderColor) { if (text == "") return; if (GFXManager::PrepareForDrawing()) { - if (borderColor && borderColor.get() != Color::transparent) rect = rect.Expand(-1, -1); + if (borderColor && borderColor.get() != Color::transparent) rect = rect.Expand(-1); Vector2 position = rect.pos + rect.size * justification; DisplayList dl = DisplayList(); { @@ -78,10 +78,10 @@ void FontBMF::Print(VRect rect, std::string& text, float scale, Color color, Vec } } -Vector2 FontBMF::GetCursorPosition(VRect rect, std::string& text, unsigned int end, float scale) { +Vector2 FontBMF::GetCursorPosition(VRect rect, const std::string& text, unsigned int end, float scale) { return rect.pos + (font->MeasureTo(text, false, end, rect.size.x / scale)* scale); } -unsigned int FontBMF::GetCursorFromPoint(VRect rect, std::string& text, Vector2 pt, float scale) { +unsigned int FontBMF::GetCursorFromPoint(VRect rect, const std::string& text, Vector2 pt, float scale) { return font->PointToIndex(text, pt*scale - rect.pos, rect.size.x / scale); } diff --git a/libstarlight/source/starlight/gfx/FontBMF.h b/libstarlight/source/starlight/gfx/FontBMF.h index c004f27..a1d97b6 100644 --- a/libstarlight/source/starlight/gfx/FontBMF.h +++ b/libstarlight/source/starlight/gfx/FontBMF.h @@ -18,14 +18,14 @@ namespace starlight { FontBMF() { } ~FontBMF() { } - Vector2 Measure(std::string& text, float scale = 1, float maxWidth = 400) override; - void Print(Vector2 position, std::string& text, float scale = 1, Color color = Color::white, Vector2 justification = Vector2::zero, OptRef borderColor = nullptr) override; - void Print(VRect rect, std::string& text, float scale = 1, Color color = Color::white, Vector2 justification = Vector2::zero, OptRef borderColor = nullptr) override; + Vector2 Measure(const std::string& text, float scale = 1, float maxWidth = 400) override; + void Print(Vector2 position, const std::string& text, float scale = 1, Color color = Color::white, Vector2 justification = Vector2::zero, OptRef borderColor = nullptr) override; + void Print(VRect rect, const std::string& text, float scale = 1, Color color = Color::white, Vector2 justification = Vector2::zero, OptRef borderColor = nullptr) override; //void PrintDisplayList(DisplayList* dl, Vector2 position, std::string& text, float scale = 1, Color color = Color::white, Vector2 justification = Vector2::zero, OptRef borderColor = nullptr) override; //void PrintDisplayList(DisplayList* dl, VRect rect, std::string& text, float scale = 1, Color color = Color::white, Vector2 justification = Vector2::zero, OptRef borderColor = nullptr) override; - Vector2 GetCursorPosition(VRect rect, std::string& text, unsigned int end, float scale) override; - unsigned int GetCursorFromPoint(VRect rect, std::string& text, Vector2 pt, float scale) override; + Vector2 GetCursorPosition(VRect rect, const std::string& text, unsigned int end, float scale) override; + unsigned int GetCursorFromPoint(VRect rect, const std::string& text, Vector2 pt, float scale) override; }; } } diff --git a/libstarlight/source/starlight/gfx/ThemeRef.h b/libstarlight/source/starlight/gfx/ThemeRef.h index 9e81aad..9e32166 100644 --- a/libstarlight/source/starlight/gfx/ThemeRef.h +++ b/libstarlight/source/starlight/gfx/ThemeRef.h @@ -53,6 +53,7 @@ namespace starlight { inline const ThemeRefContainer& operator ->() const { return *cptr; } inline explicit operator bool() const { return cptr != nullptr; } inline std::shared_ptr GetShared() const { return (*cptr).ptr; } + inline const std::string& GetName() const { return (*cptr).name; } }; } } diff --git a/libstarlight/source/starlight/ui/Button.cpp b/libstarlight/source/starlight/ui/Button.cpp index dd02f2f..4d5dbcd 100644 --- a/libstarlight/source/starlight/ui/Button.cpp +++ b/libstarlight/source/starlight/ui/Button.cpp @@ -28,7 +28,7 @@ void Button::Draw() { static auto idle = ThemeManager::GetAsset("controls/button.idle"); static auto press = ThemeManager::GetAsset("controls/button.press"); - static TextConfig tc = ThemeManager::GetMetric("/controls/button/text", TextConfig()); + static TextConfig tc = ThemeManager::GetMetric("/controls/button/text", TextConfig()); auto rect = (this->rect + GFXManager::GetOffset()).IntSnap(); @@ -39,7 +39,7 @@ void Button::Draw() { } //font->Print(rect, label, 1, cl/*Color::white*/, Vector2(0.5f, 0.5f), Color::black); - tc.Print(rect, label, Vector2::half); + tc.Print(rect, label); } void Button::OnTouchOn() { diff --git a/libstarlight/source/starlight/ui/TextBox.cpp b/libstarlight/source/starlight/ui/TextBox.cpp new file mode 100644 index 0000000..3df8ac5 --- /dev/null +++ b/libstarlight/source/starlight/ui/TextBox.cpp @@ -0,0 +1,103 @@ +#include "TextBox.h" + +#include + +#include "starlight/_incLib/json.hpp" + +#include "starlight/InputManager.h" +#include "starlight/GFXManager.h" +#include "starlight/ThemeManager.h" + +#include "starlight/dialog/OSK.h" + +using starlight::Vector2; +using starlight::Color; + +using starlight::gfx::Font; + +using starlight::InputManager; +using starlight::GFXManager; +using starlight::ThemeManager; + +using starlight::TextConfig; + +using starlight::dialog::OSK; +using starlight::dialog::osk::InputHandlerBuffered; + +using starlight::ui::TextBox; + +void TextBox::SetText(const std::string& text) { + this->text = text; + textView.reset(); + MarkForRedraw(); +} + +void TextBox::PreDraw() { + if (!textView) { + static Vector2 margin = ThemeManager::GetMetric("/controls/textBox/margin", Vector2::zero); + + textView = std::make_unique(rect.size - margin*2); + textView->Clear(); + GFXManager::PushContext(textView.get()); + + static TextConfig tc = ThemeManager::GetMetric("/controls/textBox/text", TextConfig()); + if (multiLine) { + // for now I guess just flat top-left + tc.Print(textView->rect, text, Vector2::zero); + } else { + Vector2 sz = tc.Measure(text); + Vector2 justification = Vector2(tc.justification.x, 0.5f); + + tc.Print(textView->rect.RightEdge(std::max(textView->rect.size.x, sz.x)), text, justification); + } + + GFXManager::PopContext(); + } +} +void TextBox::PreDrawOffscreen() { textView.reset(); } // discard on offscreen + +void TextBox::Draw() { + static auto bg = ThemeManager::GetAsset("controls/textBox"); + static Vector2 margin = ThemeManager::GetMetric("/controls/textBox/margin", Vector2::zero); + auto rect = (this->rect + GFXManager::GetOffset()).IntSnap(); + + bg->Draw(rect); + + //tc.Print(rect.Expand(-margin), text); + if (textView) textView->Draw(rect.Expand(-margin)); +} + +void TextBox::OnResize() { + textView.reset(); + MarkForRedraw(); +} + +void TextBox::OnTouchOn() { + if (InputManager::Pressed(Keys::Touch)) { + InputManager::GetDragHandle().Grab(this); + MarkForRedraw(); + } +} + +void TextBox::OnTouchOff() { + auto& drag = InputManager::GetDragHandle(); + if (drag == this) drag.Release(); +} + +void TextBox::OnDragStart() { + // do we need to do anything here? +} + +void TextBox::OnDragHold() { + if (InputManager::TouchDragDist().Length() > InputManager::dragThreshold) { + InputManager::GetDragHandle().PassUp(); + } +} + +void TextBox::OnDragRelease() { + if (InputManager::Released(Keys::Touch)) { + // pop up osk + OSK::New(new InputHandlerBuffered(text, multiLine, [this](auto& str){ this->SetText(str); }))->Open(); + } + MarkForRedraw(); +} diff --git a/libstarlight/source/starlight/ui/TextBox.h b/libstarlight/source/starlight/ui/TextBox.h new file mode 100644 index 0000000..cf9e5aa --- /dev/null +++ b/libstarlight/source/starlight/ui/TextBox.h @@ -0,0 +1,44 @@ +#pragma once +#include "starlight/_global.h" + +#include + +#include "starlight/gfx/DrawContextCanvas.h" + +#include "starlight/ui/UIElement.h" + +namespace starlight { + namespace ui { + class TextBox : public UIElement { + private: + // + + public: + std::string text = ""; + bool multiLine = false; + + std::unique_ptr textView; + + TextBox(VRect rect) { this->rect = rect; } + TextBox(Vector2 pos) { this->rect = VRect(pos, Vector2(128, 24)); } + ~TextBox() { } + + void SetText(const std::string& text); + + void PreDraw() override; + void PreDrawOffscreen() override; + void Draw() override; + + // events + void OnResize() override; + + void OnTouchOn() override; + void OnTouchOff() override; + + void OnDragStart() override; + void OnDragRelease() override; + void OnDragHold() override; + + }; + } +} diff --git a/libstarlight/todo.txt b/libstarlight/todo.txt index 67b7492..33b6957 100644 --- a/libstarlight/todo.txt +++ b/libstarlight/todo.txt @@ -2,41 +2,28 @@ roadmap to first release, in no particular order { - - implement app:/ asset loading finish implementing OSK! { - - make backspace and enter actually do something - - abstract osk input actions into a separate object/class heirarchy - - preview where applicable - fix font glyph padding to eliminate slight "crosstalk" in bordered variants - fix lowercase j running into things - adjust monospace line height (and maybe offset) to closer match the vwf of the same size - add justification to TextConfig as a default + - MAKE IT NOT CRASH ON BEING CLOSED FROM INPUTHANDLER + enable scrolling preview (and scroll to cursor where applicable) polish! InputManager::OpenKeyboard } - textbox widget - - "draw proxy" UIElement (takes a std::function for draw operation) + - textbox widget + + add generic backdrop assets (and form) + + fix font glyph padding to eliminate slight "crosstalk" in bordered variants + 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 -} and some lesser priority things { - add language config and atlas support +} then consider these before 1.0 "gold" { + should form priority be a float? + language config and atlas support maybe implement some way of "knocking out" and replacing metrics during runtime for theme switching } -form system { framework done apart from some small api changes - capabilities { - updates, recieves events etc. as if it were a stackable Application - priority level (modals etc.) - can be stacked, reordered etc. via order shown - can occlude independently on top and bottom screen, causing lower-ordered things on that screen to not even render - can tell if it's the focused (topmost) form and use that to determine whether to accept button input - - } - meaningful state change signals current Application to resort and rebuild draw list during next update -} - - today's agenda { ... } then { @@ -53,18 +40,15 @@ unordered_roadmap { radio box tabs? auto-layout/list boxes - text/combo box + combo box slider progress bar } maybe switch drawoffset system from a stack to a pass-in - moar utility stuff in Vector2 and VRect { - - - } + moar utility stuff in basic types + make textbox scrollable when text is larger than container tween system - figure out theme layout and fallback system - maybe a few further refinements to bitmap fonts ... use ctrulib sync features for WorkerThread instead of spinlocks at some point - http://smealum.github.io/ctrulib/synchronization_8h.html#a9fe83ca3ec3c6ae269203acf367ad5a9 @@ -74,28 +58,6 @@ unordered_roadmap { figure out the whole font y offset deal } -theme layout { - sdmc:/.starlight/themes// { - fonts { - default.12.json/png/border.png - default.16 - mono.12/16 - } - controls { - button.idle/pressed - ... - } - } -} - - -drawable, drawcontext, gfxmanager (pushContext, popContext) (done mostly) -ThemeRef (done) { - theme-asset-specific reference so themes can be reloaded - -> operator overloaded etc. -} -T H E M E S - configurator for ui elements? maybe crtp after all noap, macro/include shenanigans new Button().at(40, 40).within(container).ofSize(64, 32).withText("Popsicles!"); @@ -109,4 +71,5 @@ maybe implement this: https://probablydance.com/2013/01/13/a-faster-implementati // notes { bitmap font converter - https://github.com/playcanvas/fonts/blob/master/fnt_to_json.py + pretty print - jsonprettyprint.com } diff --git a/testbed/source/Core.cpp b/testbed/source/Core.cpp index 5e54405..88203bb 100644 --- a/testbed/source/Core.cpp +++ b/testbed/source/Core.cpp @@ -15,6 +15,7 @@ #include "starlight/ui/ParallaxLayer.h" #include "starlight/ui/ScrollField.h" #include "starlight/ui/Button.h" +#include "starlight/ui/TextBox.h" #include "starlight/ui/Label.h" #include "starlight/dialog/MessageBox.h" @@ -72,9 +73,12 @@ void Core::Init() { tlbl->textConfig.borderColor = Color::black; tlbl->SetText("3DS:~# "); form->topScreen->Add(tlbl); - auto kb = sl::dialog::OSK::New(new sl::dialog::osk::InputHandlerDirectEdit(&(tlbl->text), true, 7, [tlbl](){tlbl->Refresh();})); - //&(tlbl->text), [tlbl](){tlbl->Refresh();}); - kb->Open(); + //auto kb = sl::dialog::OSK::New(new sl::dialog::osk::InputHandlerDirectEdit(&(tlbl->text), true, 7, [tlbl](){tlbl->Refresh();})); + //kb->Open(); + + auto tb = std::make_shared(VRect(0, 64, 320, 24).Expand(-16, 0)); + tb->text = "TextBox testing in progress."; + form->touchScreen->Add(tb); /*label->SetFont("default.16"); btn.SetText("I was pressed!"); diff --git a/themes/default/controls/textBox.json b/themes/default/controls/textBox.json new file mode 100644 index 0000000..6a4d529 --- /dev/null +++ b/themes/default/controls/textBox.json @@ -0,0 +1,4 @@ +{ + "assetType" : "ninepatch", + "margin" : [3, 3] +} diff --git a/themes/default/controls/textBox.png b/themes/default/controls/textBox.png new file mode 100644 index 0000000000000000000000000000000000000000..df5231f488c933ebe879ec90dc9902fb2c9ac287 GIT binary patch literal 418 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oVGw3ym^DWND9B#o z>Fdh=kXeA&*mCJ%!^J=$+02lL66gHf+|;}hAeVu`xhOTUBsE2$JhLQ2!QIn0AVn{g zoq>T-!qdeuB;xSf>l-Jw81Oh;%vU_NgI}m?!G9qS%|=P4#|IyDZz;dtpb(+X_kXiT z0K<%BD?c8HoTmE1#5Z?dIzv*=k|`2xjS|X+Zol@qhX#i3TIcM-p;+@yfN8C1RQ8?k ze|N5bz37_P+NqyyG?xZ=J+$B}IyWVVVb-j)*zj+)<&~9QorN-t0o6bEz0bM*%gTe~DWM4f D)aRnu literal 0 HcmV?d00001 diff --git a/themes/default/controls/textBox.xcf b/themes/default/controls/textBox.xcf new file mode 100644 index 0000000000000000000000000000000000000000..98547ca310a55b0f4f2b13e49ef8430cc1bad32a GIT binary patch literal 4516 zcmeHKJ8u&~5T3J99AY99o>Agrk}6jiIs5`*%Q6&5v=kJMeRny@kH|KV6v&lDOGiTy z{|Y0Tv@Yn~AR$?Fu3Wh=xnsV&UB`$(N8TfS{=S`k&hG8_&T%WdyjQgOO*;LU#8?4( zNnjZAb5}5*`9K7S-4omp!2dvLw7W0u^TLac44W#}Diy2Rlro|6PPT3pnpTP5y3HNV zKYRWHHMfJNZl&N@DW~q1;FHz{Z8VzuWs4iNvRg72Hf*O@E7$705m2h`Y!^8FC>_`d zVpCO_(slcUuDYK8F3@$av0Es*RfjkAT;kk6$*Fv)*HyR4Znd~$HPF9i+YPHZT_Ae@ z=?Xo+cf~#^Grkbby&_upM3h+6USU?i?k;6&^^#TRr>?V876jWqClxp+UofvU8sAh} zh>|mUVMfPi^sO0<1z=2ALV$6##YE`mLO&zut1Qw`f`tKT8+k7b;}DULD6G?pzfPV{ zD>RYCUnZ8IA`;!&b&MDLTxZVl2j`r2r`zifhNJPspNvPtLBH2MXggV^HS!pbu{_^7 zaE{0UJ49`8o2Ucs5Ou*_q8_+M)Cc#82H*kF5IiIrfk#AR@R(=GAb^U5q31AAk>z*QeK;g+Gg{x`Lo0^v}R0;OVUvczX4SQwDH#8+V$he&)wLDGvU>E+ZAT>n#>4UwJEj4EmC