add theme metrics and fallback, load from SD,

overhaul InputManager keys enum, adjust MessageBox layout, and random miscellany
This commit is contained in:
zetaPRIME 2017-03-04 03:48:25 -05:00
parent edf7945acd
commit e7e9ed7de7
21 changed files with 402 additions and 72 deletions

View File

@ -69,6 +69,7 @@ void Application::_init() {
romfsInit();
ConfigManager::Init();
RenderCore::Open();
ThemeManager::Init();
touchScreen = std::make_shared<TouchScreenCanvas>();
topScreen = std::make_shared<TopScreenCanvas>();
@ -83,6 +84,7 @@ void Application::_end() {
forms.clear(); // not sure why, but not doing this results in a data abort if any forms are active
ThemeManager::End();
RenderCore::Close();
ConfigManager::End();
}

View File

@ -68,6 +68,7 @@ std::unordered_map<std::string, std::shared_ptr<Config>> ConfigManager::cfg;
void ConfigManager::Init() {
//FSHelper::AssertDirPath("sdmc:/.starlight/config/app/" + Application::AppName());
Get("user").autoSave = true;
}
void ConfigManager::End() {

View File

@ -4,7 +4,8 @@
#include <memory>
#include <unordered_map>
#include "starlight/_incLib/json_fwd.hpp"
//#include "starlight/_incLib/json_fwd.hpp"
#include "starlight/_incLib/json.hpp"
#include "starlight/util/Path.h"
@ -26,6 +27,22 @@ namespace starlight {
void Save();
nlohmann::json& Json() { return *json; }
template <typename T>
T Get(const std::string& path, T defVal, bool writeDefault = false) {
auto jp = nlohmann::json::json_pointer(path);
auto& js = (*json)[jp];
if (js.is_null()) {
if (writeDefault) js = defVal;
return defVal;
}
return js;
}
template <typename T>
void Set(const std::string& path, T val) {
(*json)[nlohmann::json::json_pointer(path)] = val;
}
};
class ConfigManager {

View File

@ -58,11 +58,11 @@ void InputManager::Update() {
touchLast = touchNow;
hidTouchRead(&tp);
if (Held(Keys::TOUCH)) touchNow = Vector2(tp.px, tp.py);
if (Held(Keys::Touch)) touchNow = Vector2(tp.px, tp.py);
if (Pressed(Keys::TOUCH)) touchStart = touchLast = touchNow;
if (Pressed(Keys::Touch)) touchStart = touchLast = touchNow;
if (!Held(Keys::TOUCH) && !Released(Keys::TOUCH)) touchTime = 0;
if (!Held(Keys::Touch) && !Released(Keys::Touch)) touchTime = 0;
else touchTime++;
}

View File

@ -7,40 +7,40 @@
#include "starlight/ui/UIElement.h"
// borrow this from ctrulib
// based on ctrulib's enum
#ifndef BIT
#define BIT(n) (1U<<(n))
#endif
enum class Keys : unsigned int {
A = BIT(0), ///< A
B = BIT(1), ///< B
SELECT = BIT(2), ///< Select
START = BIT(3), ///< Start
DRIGHT = BIT(4), ///< D-Pad Right
DLEFT = BIT(5), ///< D-Pad Left
DUP = BIT(6), ///< D-Pad Up
DDOWN = BIT(7), ///< D-Pad Down
R = BIT(8), ///< R
L = BIT(9), ///< L
X = BIT(10), ///< X
Y = BIT(11), ///< Y
ZL = BIT(14), ///< ZL (New 3DS only)
ZR = BIT(15), ///< ZR (New 3DS only)
TOUCH = BIT(20), ///< Touch (Not actually provided by HID)
CSTICK_RIGHT = BIT(24), ///< C-Stick Right (New 3DS only)
CSTICK_LEFT = BIT(25), ///< C-Stick Left (New 3DS only)
CSTICK_UP = BIT(26), ///< C-Stick Up (New 3DS only)
CSTICK_DOWN = BIT(27), ///< C-Stick Down (New 3DS only)
CPAD_RIGHT = BIT(28), ///< Circle Pad Right
CPAD_LEFT = BIT(29), ///< Circle Pad Left
CPAD_UP = BIT(30), ///< Circle Pad Up
CPAD_DOWN = BIT(31), ///< Circle Pad Down
A = BIT(0), ///< A
B = BIT(1), ///< B
Select = BIT(2), ///< Select
Start = BIT(3), ///< Start
DPadRight = BIT(4), ///< D-Pad Right
DPadLeft = BIT(5), ///< D-Pad Left
DPadUp = BIT(6), ///< D-Pad Up
DPadDown = BIT(7), ///< D-Pad Down
R = BIT(8), ///< R
L = BIT(9), ///< L
X = BIT(10), ///< X
Y = BIT(11), ///< Y
ZL = BIT(14), ///< ZL (New 3DS only)
ZR = BIT(15), ///< ZR (New 3DS only)
Touch = BIT(20), ///< Touch (Not actually provided by HID)
CStickRight = BIT(24), ///< C-Stick Right (New 3DS only)
CStickLeft = BIT(25), ///< C-Stick Left (New 3DS only)
CStickUp = BIT(26), ///< C-Stick Up (New 3DS only)
CStickDown = BIT(27), ///< C-Stick Down (New 3DS only)
CPadRight = BIT(28), ///< Circle Pad Right
CPadLeft = BIT(29), ///< Circle Pad Left
CPadUp = BIT(30), ///< Circle Pad Up
CPadDown = BIT(31), ///< Circle Pad Down
// Generic catch-all directions
UP = DUP | CPAD_UP, ///< D-Pad Up or Circle Pad Up
DOWN = DDOWN | CPAD_DOWN, ///< D-Pad Down or Circle Pad Down
LEFT = DLEFT | CPAD_LEFT, ///< D-Pad Left or Circle Pad Left
RIGHT = DRIGHT | CPAD_RIGHT, ///< D-Pad Right or Circle Pad Right
Up = DPadUp | CPadUp, ///< D-Pad Up or Circle Pad Up
Down = DPadDown | CPadDown, ///< D-Pad Down or Circle Pad Down
Left = DPadLeft | CPadLeft, ///< D-Pad Left or Circle Pad Left
Right = DPadRight | CPadRight, ///< D-Pad Right or Circle Pad Right
};
namespace starlight {

View File

@ -1,3 +1,6 @@
#include "ThemeManager.h"
#include "starlight/gfx/ThemeRef.h"
#include <cstdlib>
#include <string>
#include <fstream>
@ -8,8 +11,7 @@
#include "starlight/_incLib/lodepng.h"
#include "starlight/_incLib/json.hpp"
#include "ThemeManager.h"
#include "starlight/gfx/ThemeRef.h"
#include "starlight/ConfigManager.h"
#include "starlight/gfx/DrawableImage.h"
#include "starlight/gfx/DrawableNinePatch.h"
@ -19,6 +21,8 @@
#include "starlight/gfx/RenderCore.h"
#include "starlight/gfx/BitmapFont.h"
#include "starlight/util/JsonConversions.h"
using std::string;
using std::shared_ptr;
using std::make_shared;
@ -26,8 +30,13 @@ using std::make_shared;
using nlohmann::json;
using starlight::Vector2;
using starlight::VRect;
using starlight::Color;
using starlight::util::Path;
using starlight::ConfigManager;
using starlight::ThemeManager;
using starlight::gfx::Drawable;
using starlight::gfx::Font;
using starlight::gfx::ThemeRef;
@ -40,6 +49,10 @@ using starlight::gfx::RenderCore;
using starlight::gfx::CTexture;
using starlight::gfx::BitmapFont;
using starlight::ThemeInfo;
using starlight::ThemeManager;
using starlight::TextConfig;
namespace {
inline int NextPow2(unsigned int x) {
--x;
@ -118,10 +131,51 @@ namespace {
}
}
ThemeInfo::ThemeInfo(const std::string& name) : ThemeInfo(Path(".starlight/themes").Combine(name), name) {
//ConfigManager::Get("user").Json()["log"].push_back(basePath);
}
ThemeInfo::ThemeInfo(const Path& path, const std::string& name) {
this->name = name;
basePath = path;
meta = std::make_shared<nlohmann::json>();
metrics = std::make_shared<nlohmann::json>();
if (!basePath.IsDirectory()) return; // don't bother trying to load stuff
{ // using...
std::ifstream load = basePath.Combine("meta.json").OpenI();
if (load.good()) load >> *meta;
load = basePath.Combine("metrics.json").OpenI();
if (load.good()) load >> *metrics;
}
}
std::list<ThemeInfo> ThemeManager::themeData;
std::unordered_map<std::string, ThemeRefContainer<Drawable>> ThemeManager::drawables;
std::unordered_map<std::string, ThemeRefContainer<Font>> ThemeManager::fonts;
std::list<std::function<void()>> ThemeManager::tq;
void ThemeManager::Init() {
auto& usercfg = ConfigManager::Get("user");
auto themeName = usercfg.Get<std::string>("/theme", "default", true);
ThemeInfo thm = ThemeInfo(themeName);
if (!thm.basePath.IsDirectory()) thm = ThemeInfo("default"); // fall back on default if not found
// ...and if "default" doesn't exist, fall back on a standard location in romfs:
if (!thm.basePath.IsDirectory()) thm = ThemeInfo(Path("romfs:/.fallback_theme", "FALLBACK"));
themeData.push_back(thm);
while (!(*thm.meta)["fallback"].is_null()) { // follow fallback chain
std::string fbn = (*thm.meta)["fallback"];
thm = ThemeInfo(fbn);
themeData.push_back(thm);
}
}
void ThemeManager::End() {
}
ThemeRef<Drawable> ThemeManager::GetAsset(const std::string& name) {
auto const& itr = drawables.find(name);
if (itr == drawables.end()) {
@ -201,37 +255,96 @@ void ThemeManager::LoadProc() {
}
string ThemeManager::ResolveAssetPath(const string& id) {
struct stat buf;
string path(id.length() + 64, ' '); // preallocate buffer space
//struct stat buf;
//string path(id.length() + 64, ' '); // preallocate buffer space
static const string pfxLocal = "app:/";
if (id.compare(0, pfxLocal.length(), pfxLocal)) {
if (id.compare(0, pfxLocal.length(), pfxLocal) == 0) {
// app-local asset
// check if present in theme/app/[appname]/, else check in romfs
}
else {
// theme asset; check in each theme from selected to most-fallback
for (auto thm : themeData) {
Path p = thm.basePath.Combine(id+".json");
if (p.IsFile()) return p;
p = thm.basePath.Combine(id+".png");
if (p.IsFile()) return p;
}
}
path.clear(); path.append("romfs:/"); path.append(id); path.append(".json");
/*path.clear(); path.append("romfs:/"); path.append(id); path.append(".json");
printf("attempt: %s\n", path.c_str());
if (stat(path.c_str(), &buf) == 0) return path;
path.erase(path.end()-5, path.end()); path.append(".png");
printf("attempt: %s\n", path.c_str());
if (stat(path.c_str(), &buf) == 0) return path;
if (stat(path.c_str(), &buf) == 0) return path;//*/
return string();
}
string ThemeManager::ResolveFontPath(const string& id) { // this needs redone, but whatever
struct stat buf;
string path(id.length() + 64, ' '); // preallocate buffer space
path.clear(); path.append("romfs:/fonts/"); path.append(id); path.append(".json");
printf("attempt: %s\n", path.c_str());
if (stat(path.c_str(), &buf) == 0) return path;
path.erase(path.end()-5, path.end()); path.append(".png");
printf("attempt: %s\n", path.c_str());
if (stat(path.c_str(), &buf) == 0) return path;
string ThemeManager::ResolveFontPath(const string& id) { // there we go, nice and simple
for (auto thm : themeData) {
Path p = thm.basePath.Combine("fonts").Combine(id+".json");
if (p.IsFile()) return p;
}
return string();
}
json& ThemeManager::GetMetric(const string& path) {
json::json_pointer jp(path);
for (auto& t : themeData) {
json& j = (*t.metrics)[jp];
if (!j.is_null()) {
if (j.is_object()) {
auto& jr = j["_redir"];
if (!jr.is_null()) return GetMetric(jr);
}
return j;
}
}
static json jx({});
return jx; // well, here's a null json
}
template <typename T>
T ThemeManager::GetMetric(const std::string& path, const T& defaultValue) {
//try {
json& j = GetMetric(path);
if (j.is_null()) return defaultValue;
return j;
/*} catch (std::exception& e) {
return defaultValue;
}//*/
}
TextConfig::TextConfig(const std::string& fontName, Color text, Color border) {
font = ThemeManager::GetFont(fontName);
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); }
namespace starlight { // todo: expose these in the header
void to_json(nlohmann::json& j, const TextConfig& tc) {
// todo: implement this
}
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);
}
//
}
}
template Vector2 ThemeManager::GetMetric(const std::string&, const Vector2&);
template VRect ThemeManager::GetMetric(const std::string&, const VRect&);
template Color ThemeManager::GetMetric(const std::string&, const Color&);
template starlight::TextConfig ThemeManager::GetMetric(const std::string&, const TextConfig&);

View File

@ -4,8 +4,13 @@
#include <string>
#include <unordered_map>
#include <list>
#include <memory>
#include <functional>
#include "starlight/_incLib/json_fwd.hpp"
#include "starlight/util/Path.h"
#include "starlight/gfx/Drawable.h"
#include "starlight/gfx/Font.h"
@ -16,6 +21,20 @@ namespace starlight {
template <class T> class ThemeRef;
}
struct ThemeInfo {
public:
std::string name;
util::Path basePath;
std::shared_ptr<nlohmann::json> meta;
std::shared_ptr<nlohmann::json> metrics;
ThemeInfo() = default;
ThemeInfo(const std::string& name);
ThemeInfo(const util::Path& path, const std::string& name = "");
~ThemeInfo() = default;
};
class ThemeManager {
template <class T>
friend class starlight::gfx::ThemeRefContainer;
@ -24,6 +43,8 @@ namespace starlight {
static std::unordered_map<std::string, gfx::ThemeRefContainer<gfx::Font>> fonts;
static std::list<std::function<void()>> tq;
protected:
static std::list<ThemeInfo> themeData;
static void Fulfill(gfx::ThemeRefContainer<gfx::Drawable>& ref);
static void Fulfill(gfx::ThemeRefContainer<gfx::Font>& ref);
@ -31,6 +52,9 @@ namespace starlight {
public:
ThemeManager() = delete; // "static" class
static void Init();
static void End();
static gfx::ThemeRef<gfx::Drawable> GetAsset(const std::string& name);
static gfx::ThemeRef<gfx::Font> GetFont(const std::string& name);
@ -38,8 +62,28 @@ namespace starlight {
static std::string ResolveAssetPath(const std::string& id);
static std::string ResolveFontPath(const std::string& id);
static inline std::string GetThemeName() { return themeData.front().name; }
static nlohmann::json& GetMetric(const std::string& path);
template <typename T> static T GetMetric(const std::string& path, const T& defaultValue);
};
}
// post-include dependency
#include "starlight/gfx/ThemeRef.h"
// and some metrics types depending on ThemeRef
namespace starlight {
struct TextConfig {
gfx::ThemeRef<gfx::Font> font = ThemeManager::GetFont("default.12");
Color textColor = Color::white;
Color borderColor = Color::transparent;
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);
};
}

View File

@ -12898,6 +12898,9 @@ basic_json_parser_74:
}
/// @}
// ZP EDIT: JSON EXTENSIONS
#include "json_extensions.hpp"
};
/////////////

View File

@ -0,0 +1,10 @@
// libstarlight extensions for nlohmann::json (include nested within basic_json)
// try_get: reads out if applicable, else leaves the target alone
void try_get(int& v) { if (is_number()) v = get<int>(); }
void try_get(float& v) { if (is_number()) v = get<float>(); }
void try_get(std::string& v) { if (is_string()) v = get<std::string>(); }
/*bool has(std::string& idx) const {
return find(idx) != end();
}*/

View File

@ -1,15 +1,9 @@
#include "Color.h"
#include "starlight/_incLib/json.hpp"
using starlight::Color;
//
//#define RGBA8(r, g, b, a) ((((a)&0xFF)<<24) | (((b)&0xFF)<<16) | (((g)&0xFF)<<8) | (((r)&0xFF)<<0))
//#define RGBA8_GET_R(c) (((c) >> 0) & 0xFF)
//#define RGBA8_GET_G(c) (((c) >> 8) & 0xFF)
//#define RGBA8_GET_B(c) (((c) >> 16) & 0xFF)
//#define RGBA8_GET_A(c) (((c) >> 24) & 0xFF)
const Color Color::transparent = Color(0.0f, 0.0f, 0.0f, 0.0f);
const Color Color::white = Color(1.0f, 1.0f, 1.0f);
const Color Color::black = Color(0.0f, 0.0f, 0.0f);

View File

@ -22,13 +22,13 @@ MessageBox::MessageBox(Mode m, const std::string& msg, std::function<void(int)>
priority = 10;
eOnSelect = onSelect;
VRect boxArea = VRect(160, 120, 0, 0).Expand(Vector2(300, 200)*.5);
VRect boxArea = VRect(160, 120, 0, 0).Expand(Vector2(240, 160)*.5);
auto bg = std::make_shared<Image>(boxArea, "decorations/panel.bg");
touchScreen->Add(bg);
auto scroll = std::make_shared<ScrollField>(boxArea.Expand(-8, -8).TopEdge(200-16-8-32));
auto scroll = std::make_shared<ScrollField>(boxArea.Expand(-8, -8).TopEdge(boxArea.size.y - 16 - 32 - 8));
touchScreen->Add(scroll);
auto label = std::make_shared<Label>(VRect(0, 0, 300-16, 0));
auto label = std::make_shared<Label>(VRect(0, 0, scroll->rect.size.x, 0));
label->autoSizeV = true;
label->SetFont("default.16");
label->SetText(msg);

View File

@ -28,4 +28,3 @@ namespace starlight {
}
}

View File

@ -1,5 +1,7 @@
#include "Button.h"
#include "starlight/_incLib/json.hpp"
#include "starlight/InputManager.h"
#include "starlight/GFXManager.h"
#include "starlight/ThemeManager.h"
@ -21,11 +23,13 @@ void Button::SetText(const std::string& text) {
}
void Button::Draw() {
static auto font = ThemeManager::GetFont("default.12");
//static auto font = ThemeManager::GetFont("default.12");
static auto idle = ThemeManager::GetAsset("controls/button.idle");
static auto press = ThemeManager::GetAsset("controls/button.press");
static TextConfig tc = ThemeManager::GetMetric<TextConfig>("/controls/button/text", TextConfig());
auto rect = (this->rect + GFXManager::GetOffset()).IntSnap();
if (InputManager::GetDragHandle() == this) {
@ -34,11 +38,12 @@ void Button::Draw() {
idle->Draw(rect);
}
font->Print(rect, label, 1, Color::white, Vector2(0.5f, 0.5f), Color::black);
//font->Print(rect, label, 1, cl/*Color::white*/, Vector2(0.5f, 0.5f), Color::black);
tc.Print(rect, label, Vector2(0.5f, 0.5f));
}
void Button::OnTouchOn() {
if (InputManager::Pressed(Keys::TOUCH)) {
if (InputManager::Pressed(Keys::Touch)) {
InputManager::GetDragHandle().Grab(this);
MarkForRedraw();
}
@ -60,7 +65,7 @@ void Button::OnDragHold() {
}
void Button::OnDragRelease() {
if (InputManager::Released(Keys::TOUCH)) {
if (InputManager::Released(Keys::Touch)) {
if (eOnTap) eOnTap(*this);
}
MarkForRedraw();

View File

@ -39,11 +39,11 @@ void ScrollField::Update() {
}
void ScrollField::OnProcessTouchEvent() { // stop when child element touched
if (InputManager::Pressed(Keys::TOUCH)) scrollVel = Vector2::zero;
if (InputManager::Pressed(Keys::Touch)) scrollVel = Vector2::zero;
}
void ScrollField::OnTouchOn() {
if (InputManager::Pressed(Keys::TOUCH)) {
if (InputManager::Pressed(Keys::Touch)) {
InputManager::GetDragHandle().Grab(this);
}
}
@ -67,7 +67,7 @@ void ScrollField::OnDragHold() {
}
void ScrollField::OnDragRelease() {
if (InputManager::Released(Keys::TOUCH)) {
if (InputManager::Released(Keys::Touch)) {
if (scrollPreVel.Length() < InputManager::flingThreshold) scrollPreVel = Vector2::zero;
scrollVel = scrollPreVel;
}

View File

@ -33,7 +33,7 @@ void TouchScreenCanvas::Update() {
// scan input
Vector2 tpos = InputManager::TouchPos();
auto& drag = InputManager::GetDragHandle();
if (!drag.valid() && InputManager::Held(Keys::TOUCH)) {
if (!drag.valid() && InputManager::Held(Keys::Touch)) {
Dive(
[&tpos](UIElement* e){
if (e->ScreenRect().Contains(tpos)) {
@ -47,7 +47,7 @@ void TouchScreenCanvas::Update() {
}, true, true);
} else if (drag.valid()) {
UIElement* e = drag.get();
if (InputManager::Held(Keys::TOUCH) && e != nullptr) {
if (InputManager::Held(Keys::Touch) && e != nullptr) {
if (e->ScreenRect().Contains(tpos)) {
touchedNow->insert({e, std::weak_ptr<UIElement>(e->shared_from_this())});
}

View File

@ -0,0 +1,74 @@
#include "JsonConversions.h"
#include "starlight/_incLib/json.hpp"
using nlohmann::json;
namespace starlight {
// Vector2
void to_json(nlohmann::json& j, const Vector2& v) {
j = json({v.x, v.y});
}
void from_json(const nlohmann::json& j, Vector2& v) {
if (j.is_array()) {
switch(j.size()) {
default:
case 2: v = Vector2(j[0], j[1]); break;
case 1: v = Vector2::one * j[0].get<float>(); break;
case 0: v = Vector2::zero;
}
return;
}
v = Vector2::zero;
}
// VRect
void to_json(nlohmann::json& j, const VRect& r) {
j = json({r.pos.x, r.pos.y, r.size.x, r.size.y});
}
void from_json(const nlohmann::json& j, VRect& r) {
if (j.is_array() && j.size() >= 4) { // todo: maybe support other formats
r = VRect(j[0], j[1], j[2], j[3]);
return;
}
r = VRect::zero;
}
// Color
void to_json(nlohmann::json& j, const Color& c) {
j = json({c.r, c.g, c.b, c.a});
}
void from_json(const nlohmann::json& j, Color& c) {
if (j.is_array()) {
c = Color::black;
switch(j.size()) {
default:
case 4: c.a = j[3];
case 3: c.b = j[2];
case 2: c.g = j[1];
case 1: c.r = j[0];
case 0: break; // maybe default to Color::white here instead
}
return;
} else if (j.is_string()) {
static std::map<std::string, Color> byName = {
{"transparent", Color::transparent},
{"white", Color::white},
{"black", Color::black},
{"lightGray", Color::lightGray},
{"midGray", Color::midGray},
{"darkGray", Color::darkGray}
};
auto f = byName.find(j);
if (f != byName.end()) {
c = f->second;
return;
}
}//*/
c = Color::white;
}
//
}

View File

@ -0,0 +1,22 @@
#pragma once
#include "starlight/_global.h"
#include "starlight/_incLib/json_fwd.hpp"
#include "starlight/datatypes/Vector2.h"
#include "starlight/datatypes/VRect.h"
#include "starlight/datatypes/Color.h"
namespace starlight {
void to_json(nlohmann::json& j, const Vector2& v);
void from_json(const nlohmann::json& j, Vector2& v);
void to_json(nlohmann::json& j, const VRect& r);
void from_json(const nlohmann::json& j, VRect& r);
void to_json(nlohmann::json& j, const Color& c);
void from_json(const nlohmann::json& j, Color& c);
//
}

View File

@ -1,6 +1,19 @@
roadmap to first release, in no particular order {
add touch interceptor (and possibly dimming "shroud") to modal box
make more stuff use theme metrics (particularly default text configs) {
label defaults
}
implement OSK!
add license!! (MIT?)
} and some lesser priority things {
add 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

View File

@ -125,5 +125,5 @@ void Core::End() {
}
void Core::Update() {
if (InputManager::Held(Keys::Y) || InputManager::Pressed(Keys::START)) Application::Quit();
if (InputManager::Held(Keys::Y) || InputManager::Pressed(Keys::Start)) Application::Quit();
}

View File

@ -0,0 +1,33 @@
{
"textPresets" : {
"normal.12.dark" : {
"font" : "default.12",
"textColor" : "black"
},
"normal.12.light" : {
"font" : "default.12",
"textColor" : "white"
},
"normal.16.dark" : {
"font" : "default.16",
"textColor" : "black"
},
"normal.16.light" : {
"font" : "default.16",
"textColor" : "white"
},
"normal.12" : { "_redir" : "/textPresets/normal.12.light" },
"normal.16" : { "_redir" : "/textPresets/normal.16.light" },
"":""
},
"controls" : {
"button" : {
"text" : { "_redir" : "/textPresets/normal.12" }
}
},
"":""
}