mirror of
https://github.com/zetaPRIME/libstarlight.git
synced 2025-06-26 05:32:46 +00:00
Application::GetTime(), InputManager improvements,
shiftkey and fast scroll for OSK, partial ThemeManager GC, and planning
This commit is contained in:
parent
7f27018808
commit
c6a5781cf8
@ -30,6 +30,7 @@ using starlight::Application;
|
|||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
Application* Application::_currentApp = nullptr;
|
Application* Application::_currentApp = nullptr;
|
||||||
|
unsigned long long Application::ftime = 0;
|
||||||
|
|
||||||
bool Application::Quit() {
|
bool Application::Quit() {
|
||||||
if (_currentApp == nullptr) return false;
|
if (_currentApp == nullptr) return false;
|
||||||
@ -124,6 +125,8 @@ void Application::_mainLoop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update step
|
// update step
|
||||||
|
ftime = osGetTime();
|
||||||
|
|
||||||
InputManager::Update();
|
InputManager::Update();
|
||||||
Update();
|
Update();
|
||||||
{ // update loop for forms, guarded from snap-outs
|
{ // update loop for forms, guarded from snap-outs
|
||||||
|
@ -22,12 +22,14 @@ namespace starlight {
|
|||||||
////////////////////
|
////////////////////
|
||||||
private:
|
private:
|
||||||
static Application* _currentApp;
|
static Application* _currentApp;
|
||||||
|
static unsigned long long ftime;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static bool Quit();
|
static bool Quit();
|
||||||
static Config& GetConfig(const std::string& path);
|
static Config& GetConfig(const std::string& path);
|
||||||
static std::string AppName();
|
static std::string AppName();
|
||||||
static inline Application* Current() { return _currentApp; }
|
static inline Application* Current() { return _currentApp; }
|
||||||
|
static inline unsigned long long GetTime() { return ftime; }
|
||||||
|
|
||||||
//////////////////////
|
//////////////////////
|
||||||
// INSTANCE MEMBERS //
|
// INSTANCE MEMBERS //
|
||||||
|
@ -43,6 +43,9 @@ enum class Keys : unsigned int {
|
|||||||
Right = DPadRight | CPadRight, ///< D-Pad Right or Circle Pad Right
|
Right = DPadRight | CPadRight, ///< D-Pad Right or Circle Pad Right
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline constexpr unsigned int operator*(Keys k) { return static_cast<unsigned int>(k); }
|
||||||
|
inline constexpr Keys operator|(Keys k1, Keys k2) { return static_cast<Keys>(*k1 | *k2); }
|
||||||
|
|
||||||
namespace starlight {
|
namespace starlight {
|
||||||
// forward declare this for OpenKeyboard
|
// forward declare this for OpenKeyboard
|
||||||
namespace dialog {
|
namespace dialog {
|
||||||
@ -94,11 +97,11 @@ namespace starlight {
|
|||||||
static Vector2 CStick();
|
static Vector2 CStick();
|
||||||
|
|
||||||
static bool Held(unsigned int mask);
|
static bool Held(unsigned int mask);
|
||||||
static inline bool Held(Keys mask) { return Held(static_cast<unsigned int>(mask)); }
|
static inline bool Held(Keys mask) { return Held(*mask); }
|
||||||
static bool Pressed(unsigned int mask);
|
static bool Pressed(unsigned int mask);
|
||||||
static inline bool Pressed(Keys mask) { return Pressed(static_cast<unsigned int>(mask)); }
|
static inline bool Pressed(Keys mask) { return Pressed(*mask); }
|
||||||
static bool Released(unsigned int mask);
|
static bool Released(unsigned int mask);
|
||||||
static inline bool Released(Keys mask) { return Released(static_cast<unsigned int>(mask)); }
|
static inline bool Released(Keys mask) { return Released(*mask); }
|
||||||
|
|
||||||
static Vector2 TouchPos();
|
static Vector2 TouchPos();
|
||||||
static Vector2 TouchDelta();
|
static Vector2 TouchDelta();
|
||||||
|
@ -179,6 +179,14 @@ void ThemeManager::End() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThemeManager::GC() {
|
||||||
|
constexpr const int keepCycles = 5; // how many gc sweeps a drawable gets to stay loaded without being used
|
||||||
|
// WIP
|
||||||
|
for (auto& d : drawables) {
|
||||||
|
if (++d.second.lastAccess > keepCycles) d.second.Unload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ThemeRef<Drawable> ThemeManager::GetAsset(const std::string& name) {
|
ThemeRef<Drawable> ThemeManager::GetAsset(const std::string& name) {
|
||||||
auto const& itr = drawables.find(name);
|
auto const& itr = drawables.find(name);
|
||||||
if (itr == drawables.end()) {
|
if (itr == drawables.end()) {
|
||||||
@ -195,10 +203,10 @@ ThemeRef<Font> ThemeManager::GetFont(const std::string& name) {
|
|||||||
|
|
||||||
void ThemeManager::Fulfill(ThemeRefContainer<Drawable>& ref) {
|
void ThemeManager::Fulfill(ThemeRefContainer<Drawable>& ref) {
|
||||||
string path = ResolveAssetPath(ref.name);
|
string path = ResolveAssetPath(ref.name);
|
||||||
ref.ptr = LoadAsset(path);
|
ref.ptr = LoadAsset(path, ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Drawable> ThemeManager::LoadAsset(string& path) {
|
shared_ptr<Drawable> ThemeManager::LoadAsset(string& path, ThemeRefContainer<Drawable>& ref) {
|
||||||
static shared_ptr<Drawable> nulldrw = make_shared<starlight::gfx::DrawableTest>();
|
static shared_ptr<Drawable> nulldrw = make_shared<starlight::gfx::DrawableTest>();
|
||||||
|
|
||||||
string ext = FindExtension(path);
|
string ext = FindExtension(path);
|
||||||
@ -225,9 +233,8 @@ shared_ptr<Drawable> ThemeManager::LoadAsset(string& path) {
|
|||||||
// else if (type == "") { }
|
// else if (type == "") { }
|
||||||
else if (type == "link") {
|
else if (type == "link") {
|
||||||
string npath = ResolveAssetPath(j["path"]);
|
string npath = ResolveAssetPath(j["path"]);
|
||||||
//return LoadAsset(npath);
|
ref.redir = const_cast<ThemeRefContainer<Drawable>*>(GetAsset(npath).cptr); // link containers directly
|
||||||
return GetAsset(npath).GetShared(); // I guess this works; may need to be altered for asynchronity if I do that later
|
return nulldrw; // doesn't really matter what's inside, it'll never get used
|
||||||
// (perhaps by--wait no, making it the same ThemeRefContainer would require a full rearchitecture of this part @.@)
|
|
||||||
}
|
}
|
||||||
return nulldrw;
|
return nulldrw;
|
||||||
}
|
}
|
||||||
|
@ -48,13 +48,15 @@ namespace starlight {
|
|||||||
static void Fulfill(gfx::ThemeRefContainer<gfx::Drawable>& ref);
|
static void Fulfill(gfx::ThemeRefContainer<gfx::Drawable>& ref);
|
||||||
static void Fulfill(gfx::ThemeRefContainer<gfx::Font>& ref);
|
static void Fulfill(gfx::ThemeRefContainer<gfx::Font>& ref);
|
||||||
|
|
||||||
static std::shared_ptr<gfx::Drawable> LoadAsset(std::string& path);
|
static std::shared_ptr<gfx::Drawable> LoadAsset(std::string& path, gfx::ThemeRefContainer<gfx::Drawable>& ref);
|
||||||
public:
|
public:
|
||||||
ThemeManager() = delete; // "static" class
|
ThemeManager() = delete; // "static" class
|
||||||
|
|
||||||
static void Init();
|
static void Init();
|
||||||
static void End();
|
static void End();
|
||||||
|
|
||||||
|
static void GC();
|
||||||
|
|
||||||
static gfx::ThemeRef<gfx::Drawable> GetAsset(const std::string& name);
|
static gfx::ThemeRef<gfx::Drawable> GetAsset(const std::string& name);
|
||||||
static gfx::ThemeRef<gfx::Font> GetFont(const std::string& name);
|
static gfx::ThemeRef<gfx::Font> GetFont(const std::string& name);
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ namespace starlight {
|
|||||||
getdef = o.getdef;
|
getdef = o.getdef;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<T>& operator=(const nullptr_t&) { p.reset(); }
|
Optional<T>& operator=(const nullptr_t&) { p.reset(); return *this; }
|
||||||
Optional<T>& operator=(const T& o) { // assign by type's assignment operator if passed a "value"
|
Optional<T>& operator=(const T& o) { // assign by type's assignment operator if passed a "value"
|
||||||
if (!p) p = std::make_unique<T>();
|
if (!p) p = std::make_unique<T>();
|
||||||
*p = o;
|
*p = o;
|
||||||
|
@ -37,6 +37,10 @@ namespace {
|
|||||||
return tc;
|
return tc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool ShiftScroll(Keys k) {
|
||||||
|
return InputManager::Pressed(k) || (InputManager::Held(Keys::L | Keys::R) && InputManager::Held(k));
|
||||||
|
}
|
||||||
|
|
||||||
const constexpr float textHang = 4;
|
const constexpr float textHang = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,14 +48,13 @@ 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, "decorations/osk.background");
|
auto cover = touchScreen->AddNew<Image>(touchScreen->rect, "decorations/osk.background");
|
||||||
cover->blockTouch = true;
|
cover->blockTouch = true;
|
||||||
touchScreen->Add(cover);
|
|
||||||
|
|
||||||
// wip
|
// build keyboard
|
||||||
|
|
||||||
setContainer = std::make_shared<ui::UIContainer>(VRect::touchScreen);
|
//setContainer = touchScreen->AddNew<ui::UIContainer>(VRect::touchScreen); // kept as a test case
|
||||||
touchScreen->Add(setContainer);
|
setContainer = touchScreen->AddNew<ui::UICanvas>(VRect::touchScreen); // but this is much more efficient
|
||||||
|
|
||||||
auto actSym = [this](Button& key){
|
auto actSym = [this](Button& key){
|
||||||
this->handler->InputSymbol(key.label);
|
this->handler->InputSymbol(key.label);
|
||||||
@ -74,18 +77,16 @@ OSK::OSK(osk::InputHandler* handler) : Form(true), handler(handler) {
|
|||||||
bpen = bpstart + Vector2(linestart[line] * bs.x, bs.y * line);
|
bpen = bpstart + Vector2(linestart[line] * bs.x, bs.y * line);
|
||||||
} else {
|
} else {
|
||||||
// lower
|
// lower
|
||||||
auto key = std::make_shared<Button>(VRect(bpen, bs));
|
auto key = setContainer->AddNew<Button>(VRect(bpen, bs));
|
||||||
if (c == ' ') key->rect.size.x *= 6;
|
if (c == ' ') key->rect.size.x *= 6;
|
||||||
key->SetText(string(1, c));
|
key->SetText(string(1, c));
|
||||||
key->eOnTap = actSym;
|
key->eOnTap = actSym;
|
||||||
setContainer->Add(key);
|
|
||||||
|
|
||||||
// upper
|
// upper
|
||||||
key = std::make_shared<Button>(VRect(bpen + Vector2(0, 1000), bs));
|
key = setContainer->AddNew<Button>(VRect(bpen + Vector2(0, 1000), bs));
|
||||||
if (C == ' ') key->rect.size.x *= 6;
|
if (C == ' ') key->rect.size.x *= 6;
|
||||||
key->SetText(string(1, C));
|
key->SetText(string(1, C));
|
||||||
key->eOnTap = actSym;
|
key->eOnTap = actSym;
|
||||||
setContainer->Add(key);
|
|
||||||
|
|
||||||
// and after
|
// and after
|
||||||
bpen.x += key->rect.size.x;
|
bpen.x += key->rect.size.x;
|
||||||
@ -94,28 +95,30 @@ OSK::OSK(osk::InputHandler* handler) : Form(true), handler(handler) {
|
|||||||
|
|
||||||
// backspace
|
// backspace
|
||||||
bpen = bpstart + bs * Vector2(linestart[3] + 10, 3);
|
bpen = bpstart + bs * Vector2(linestart[3] + 10, 3);
|
||||||
auto key = std::make_shared<Button>(VRect(bpen, bs));
|
auto key = touchScreen->AddNew<Button>(VRect(bpen, bs));
|
||||||
key->rect.size.x *= 1.25;
|
key->rect.size.x *= 1.25;
|
||||||
//key->SetText("< <");
|
|
||||||
key->style.glyph = ThemeManager::GetAsset("glyphs/backspace.small");
|
key->style.glyph = ThemeManager::GetAsset("glyphs/backspace.small");
|
||||||
key->eOnTap = [this](auto& btn){ this->handler->Backspace(); this->OnKey(); };
|
key->eOnTap = [this](auto& btn){ this->handler->Backspace(); this->OnKey(); };
|
||||||
touchScreen->Add(key);
|
|
||||||
|
|
||||||
// enter
|
// enter
|
||||||
bpen = bpstart + bs * Vector2(linestart[4] + 8, 4);
|
bpen = bpstart + bs * Vector2(linestart[4] + 8, 4);
|
||||||
key = std::make_shared<Button>(VRect(bpen, bs));
|
key = touchScreen->AddNew<Button>(VRect(bpen, bs));
|
||||||
key->rect.size.x *= 2.5;
|
key->rect.size.x *= 2.5;
|
||||||
//key->SetText("Enter");
|
|
||||||
key->style.glyph = ThemeManager::GetAsset("glyphs/enter.large");
|
key->style.glyph = ThemeManager::GetAsset("glyphs/enter.large");
|
||||||
key->eOnTap = [this](auto& btn){ this->handler->Enter(); this->OnKey(); };
|
key->eOnTap = [this](auto& btn){ this->handler->Enter(); this->OnKey(); };
|
||||||
touchScreen->Add(key);
|
|
||||||
|
|
||||||
previewSc = std::make_shared<ScrollField>(VRect(VRect::touchScreen.TopEdge(66)));
|
// shift
|
||||||
touchScreen->Add(previewSc);
|
bpen = bpstart + bs * Vector2(linestart[0] + .25, 4);
|
||||||
|
key = touchScreen->AddNew<Button>(VRect(bpen, bs));
|
||||||
|
key->rect.size.x = bs.x * (linestart[4] - linestart[0] - .25);
|
||||||
|
key->style.glyph = ThemeManager::GetAsset("glyphs/shift.large");
|
||||||
|
key->eOnTap = [this](auto& btn){ this->shiftLock ^= true; };
|
||||||
|
shiftKey = key;
|
||||||
|
|
||||||
preview = std::make_shared<DrawLayerProxy>(VRect::touchScreen.TopEdge(66).Expand(-2, 0), [this](auto& layer){ this->DrawPreview(layer); }, true);
|
previewSc = touchScreen->AddNew<ScrollField>(VRect(VRect::touchScreen.TopEdge(66)));
|
||||||
|
|
||||||
|
preview = previewSc->AddNew<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); };
|
||||||
previewSc->Add(preview);
|
|
||||||
|
|
||||||
RefreshPreview();
|
RefreshPreview();
|
||||||
}
|
}
|
||||||
@ -126,46 +129,57 @@ void OSK::Update(bool focused) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (focused) {
|
if (focused) {
|
||||||
if (InputManager::Pressed(Keys::B)) handler->Done();
|
if (InputManager::Pressed(Keys::B | Keys::Start)) handler->Done();
|
||||||
if (handler->showPreview) {
|
if (handler->showPreview) {
|
||||||
if (InputManager::Pressed(Keys::DPadLeft)) {
|
auto& tc = PreviewTC();
|
||||||
|
bool refresh = false;
|
||||||
|
|
||||||
|
if (ShiftScroll(Keys::DPadLeft)) {
|
||||||
auto c = handler->GetCursor();
|
auto c = handler->GetCursor();
|
||||||
if (c > 0) handler->SetCursor(c - 1);
|
if (c > 0) handler->SetCursor(c - 1);
|
||||||
RefreshPreview();
|
refresh = true;
|
||||||
}
|
}
|
||||||
if (InputManager::Pressed(Keys::DPadRight)) {
|
if (ShiftScroll(Keys::DPadRight)) {
|
||||||
handler->SetCursor(handler->GetCursor() + 1);
|
handler->SetCursor(handler->GetCursor() + 1);
|
||||||
RefreshPreview();
|
refresh = true;
|
||||||
}
|
}
|
||||||
|
if (ShiftScroll(Keys::DPadUp)) {
|
||||||
auto& tc = PreviewTC();
|
|
||||||
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());
|
||||||
pt.y -= tc.Measure("|").y * 0.5f;
|
pt.y -= tc.Measure("|").y * 0.5f;
|
||||||
handler->SetCursor(tc.GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt));
|
handler->SetCursor(tc.GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt));
|
||||||
RefreshPreview();
|
refresh = true;
|
||||||
}
|
}
|
||||||
if (InputManager::Pressed(Keys::DPadDown)) {
|
if (ShiftScroll(Keys::DPadDown)) {
|
||||||
Vector2 pt = tc.GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor());
|
Vector2 pt = tc.GetCursorPosition(preview->rect, handler->GetPreviewText(), handler->GetCursor());
|
||||||
pt.y += tc.Measure("|").y * 1.5f;
|
pt.y += tc.Measure("|").y * 1.5f;
|
||||||
handler->SetCursor(tc.GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt));
|
handler->SetCursor(tc.GetCursorFromPoint(preview->rect, handler->GetPreviewText(), pt));
|
||||||
RefreshPreview();
|
refresh = true;
|
||||||
}
|
}
|
||||||
|
if (refresh) RefreshPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
float& s = setContainer->scrollOffset.y;
|
float& s = setContainer->scrollOffset.y;
|
||||||
float ts = 0;
|
float ts = 0;
|
||||||
if (InputManager::Held(Keys::L) || InputManager::Held(Keys::R)) {
|
if (InputManager::Held(Keys::L) || InputManager::Held(Keys::R)) {
|
||||||
ts = 1000;
|
ts = 1000;
|
||||||
}
|
shiftLock = false;
|
||||||
|
} else if (shiftLock) ts = 1000;
|
||||||
if (s != ts) {
|
if (s != ts) {
|
||||||
s = ts;
|
s = ts;
|
||||||
setContainer->MarkForRedraw();
|
setContainer->MarkForRedraw();
|
||||||
|
|
||||||
|
if (ts > 0) {
|
||||||
|
static TextConfig stc = ThemeManager::GetMetric<starlight::TextConfig>("/dialogs/OSK/keyHighlight");
|
||||||
|
shiftKey->style.textConfig = stc;
|
||||||
|
} else {
|
||||||
|
shiftKey->style.textConfig = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSK::OnKey() {
|
void OSK::OnKey() {
|
||||||
|
shiftLock = false;
|
||||||
RefreshPreview();
|
RefreshPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "starlight/ui/Form.h"
|
#include "starlight/ui/Form.h"
|
||||||
|
#include "starlight/ui/Button.h"
|
||||||
#include "starlight/ui/ScrollField.h"
|
#include "starlight/ui/ScrollField.h"
|
||||||
#include "starlight/ui/DrawLayerProxy.h"
|
#include "starlight/ui/DrawLayerProxy.h"
|
||||||
|
|
||||||
@ -19,7 +20,10 @@ namespace starlight {
|
|||||||
std::shared_ptr<ui::ScrollField> previewSc;
|
std::shared_ptr<ui::ScrollField> previewSc;
|
||||||
std::shared_ptr<ui::DrawLayerProxy> preview;
|
std::shared_ptr<ui::DrawLayerProxy> preview;
|
||||||
|
|
||||||
|
std::shared_ptr<ui::Button> shiftKey;
|
||||||
|
|
||||||
//Vector2 cursorPos;
|
//Vector2 cursorPos;
|
||||||
|
bool shiftLock = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<osk::InputHandler> handler;
|
std::unique_ptr<osk::InputHandler> handler;
|
||||||
|
@ -16,21 +16,29 @@ namespace starlight {
|
|||||||
protected:
|
protected:
|
||||||
const std::string name;
|
const std::string name;
|
||||||
std::shared_ptr<T> ptr = nullptr;
|
std::shared_ptr<T> ptr = nullptr;
|
||||||
void Unload() {
|
ThemeRefContainer* redir = nullptr;
|
||||||
|
unsigned int lastAccess = 0; // how many gc sweeps since last use
|
||||||
|
void Unload(bool full = false) {
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
|
if (full) redir = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeRefContainer(std::string name, std::shared_ptr<T> ptr) : name(name), ptr(ptr) { }
|
ThemeRefContainer(std::string name, std::shared_ptr<T> ptr) : name(name), ptr(ptr) { }
|
||||||
ThemeRefContainer(std::string name, T* ptr) : name(name), ptr(ptr) { }
|
ThemeRefContainer(std::string name, T* ptr) : name(name), ptr(ptr) { }
|
||||||
ThemeRefContainer(std::string name) : name(name) { }
|
ThemeRefContainer(std::string name) : name(name) { }
|
||||||
|
|
||||||
|
inline std::shared_ptr<T>& _getptr() {
|
||||||
|
lastAccess = 0;
|
||||||
|
if (!redir && !ptr) ThemeManager::Fulfill(*this); // call thememanager to grab things
|
||||||
|
if (redir) return redir->_getptr();
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
inline std::shared_ptr<T>& getptr() const { return const_cast<ThemeRefContainer<T>&>(*this)._getptr(); }
|
||||||
public:
|
public:
|
||||||
~ThemeRefContainer() { }
|
~ThemeRefContainer() { }
|
||||||
|
|
||||||
T* operator ->() const {
|
T* operator ->() const {
|
||||||
if (ptr == nullptr) {
|
return &*(getptr());
|
||||||
ThemeManager::Fulfill(const_cast<ThemeRefContainer<T>&>(*this)); // call thememanager to grab things
|
|
||||||
}
|
|
||||||
return &*ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*T& operator *() const {
|
/*T& operator *() const {
|
||||||
@ -44,7 +52,8 @@ namespace starlight {
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class ThemeRef {
|
class ThemeRef {
|
||||||
private:
|
friend class starlight::ThemeManager;
|
||||||
|
protected:
|
||||||
const ThemeRefContainer<T>* cptr;
|
const ThemeRefContainer<T>* cptr;
|
||||||
public:
|
public:
|
||||||
ThemeRef() : cptr(nullptr) { }
|
ThemeRef() : cptr(nullptr) { }
|
||||||
@ -52,7 +61,7 @@ namespace starlight {
|
|||||||
~ThemeRef() { }
|
~ThemeRef() { }
|
||||||
inline const ThemeRefContainer<T>& operator ->() const { return *cptr; }
|
inline const ThemeRefContainer<T>& operator ->() const { return *cptr; }
|
||||||
inline explicit operator bool() const { return cptr != nullptr; }
|
inline explicit operator bool() const { return cptr != nullptr; }
|
||||||
inline std::shared_ptr<T> GetShared() const { return (*cptr).ptr; }
|
inline std::shared_ptr<T> GetShared() const { return (*cptr).getptr(); }
|
||||||
inline const std::string& GetName() const { return (*cptr).name; }
|
inline const std::string& GetName() const { return (*cptr).name; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,22 +2,26 @@
|
|||||||
|
|
||||||
|
|
||||||
roadmap to v0.5.1 {
|
roadmap to v0.5.1 {
|
||||||
- add customization for Button (alternate idle/press images, optional glyph drawable) {
|
- fix the hang on osk when pressing (L|R)+up+left
|
||||||
- also add (optional) TextConfig
|
figure out what (else) to put on the left side of the keyboard (opposite backspace and enter)
|
||||||
- use that to spice up the OSK
|
|
||||||
}
|
|
||||||
figure out what to put on the left side of the keyboard (opposite backspace and enter)
|
|
||||||
temporary drawable loading, local themeref, discard etc.
|
temporary drawable loading, local themeref, discard etc.
|
||||||
^ both png and raw load
|
^ both png and raw load
|
||||||
maybe rgb565 for smdh icon loading?
|
maybe rgb565 for smdh icon loading?
|
||||||
some examples (minesweeper?)
|
some examples (minesweeper?)
|
||||||
proper thread dispatch?
|
fix `, ' and " glyph spacing/offset
|
||||||
|
adjust /\ some?
|
||||||
|
proper thread dispatch? {
|
||||||
|
Application main loop keeps a libctru TickCounter and keeps track of frame time;
|
||||||
|
thread objects are held in a std::list, Application dispatches resume events and splice()s them to the end until frame time reaches some proportion of 1/60s
|
||||||
|
thread gets a yield function that calls svcWaitSynchronization on its resume event
|
||||||
|
...and some mechanism for allowing it to opt out of the rest of the cycle
|
||||||
|
}
|
||||||
} then consider these before 1.0 "gold" {
|
} then consider these before 1.0 "gold" {
|
||||||
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)
|
||||||
garbage collection for not-recently-used theme assets {
|
garbage collection for not-recently-used theme assets {
|
||||||
keep track of last-use in ThemeRefContainer
|
- keep track of last-use in ThemeRefContainer
|
||||||
have ThemeManager sweep gc every so often
|
have ThemeManager sweep gc every so often
|
||||||
rework redirects (proxy drawable I guess...?)
|
- rework redirects (proxy drawable I guess...?) or a pointer to another container
|
||||||
}
|
}
|
||||||
HANDLE CANVAS OVERRUNS FOR LABELS AND OSK PREVIEW {
|
HANDLE CANVAS OVERRUNS FOR LABELS AND OSK PREVIEW {
|
||||||
- well, it doesn't actually *crash* anymore... or at least nowhere near as fast
|
- well, it doesn't actually *crash* anymore... or at least nowhere near as fast
|
||||||
@ -26,6 +30,7 @@ roadmap to v0.5.1 {
|
|||||||
}
|
}
|
||||||
actual cursor image for OSK instead of just using a | glypyh
|
actual cursor image for OSK instead of just using a | glypyh
|
||||||
input prompt dialog
|
input prompt dialog
|
||||||
|
make the panel background not just the button image
|
||||||
"shortcut" overloads for InputManager::OpenKeyboard
|
"shortcut" overloads for InputManager::OpenKeyboard
|
||||||
language config and atlas support
|
language config and atlas support
|
||||||
maybe implement some way of "knocking out" and replacing metrics during runtime for theme switching
|
maybe implement some way of "knocking out" and replacing metrics during runtime for theme switching
|
||||||
|
@ -44,7 +44,7 @@ void Core::Init() {
|
|||||||
auto label = std::make_shared<sl::ui::Label>(VRect(0,0,320,0));
|
auto label = std::make_shared<sl::ui::Label>(VRect(0,0,320,0));
|
||||||
label->textConfig->justification = Vector2::half;
|
label->textConfig->justification = Vector2::half;
|
||||||
label->autoSizeV = true;
|
label->autoSizeV = true;
|
||||||
label->SetText("~libstarlight UI test~\n\nHello. I'm a label.\nI have multiple lines and can resize to fit my content. Did you know that miles per gallon is actually a measure of volume? " + std::to_string(sizeof(std::unique_ptr<sl::ui::Label>)));
|
label->SetText("~libstarlight UI test~\n\nHello. I'm a label.\nI have multiple lines and can resize to fit my content. Did you know that miles per gallon is actually a measure of volume? " + std::to_string(sizeof(unsigned long long)));
|
||||||
container->Add(label);
|
container->Add(label);
|
||||||
|
|
||||||
auto button = std::make_shared<sl::ui::Button>(VRect(64,80,128,32));
|
auto button = std::make_shared<sl::ui::Button>(VRect(64,80,128,32));
|
||||||
|
BIN
themes/default/glyphs/shift.large.png
Normal file
BIN
themes/default/glyphs/shift.large.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 250 B |
BIN
themes/default/glyphs/shift.small.png
Normal file
BIN
themes/default/glyphs/shift.small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 234 B |
BIN
themes/default/glyphs/shift.xcf
Normal file
BIN
themes/default/glyphs/shift.xcf
Normal file
Binary file not shown.
@ -55,6 +55,10 @@
|
|||||||
"textColor" : "midGray",
|
"textColor" : "midGray",
|
||||||
"borderColor" : "darkGray",
|
"borderColor" : "darkGray",
|
||||||
"justification" : [0.5, 0.5]
|
"justification" : [0.5, 0.5]
|
||||||
|
},
|
||||||
|
"keyHighlight" : {
|
||||||
|
"_inherit" : "/controls/button/text",
|
||||||
|
"textColor" : [0.75, 0.825, 1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user