mirror of
https://github.com/usatiuk/cardboy.git
synced 2025-10-28 23:27:49 +01:00
settings app
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
#include "cardboy/apps/clock_app.hpp"
|
#include "cardboy/apps/clock_app.hpp"
|
||||||
#include "cardboy/apps/gameboy_app.hpp"
|
#include "cardboy/apps/gameboy_app.hpp"
|
||||||
#include "cardboy/apps/menu_app.hpp"
|
#include "cardboy/apps/menu_app.hpp"
|
||||||
|
#include "cardboy/apps/settings_app.hpp"
|
||||||
#include "cardboy/apps/tetris_app.hpp"
|
#include "cardboy/apps/tetris_app.hpp"
|
||||||
#include "cardboy/backend/esp_backend.hpp"
|
#include "cardboy/backend/esp_backend.hpp"
|
||||||
#include "cardboy/sdk/app_system.hpp"
|
#include "cardboy/sdk/app_system.hpp"
|
||||||
@@ -222,6 +223,7 @@ extern "C" void app_main() {
|
|||||||
context.system = &system;
|
context.system = &system;
|
||||||
|
|
||||||
system.registerApp(apps::createMenuAppFactory());
|
system.registerApp(apps::createMenuAppFactory());
|
||||||
|
system.registerApp(apps::createSettingsAppFactory());
|
||||||
system.registerApp(apps::createClockAppFactory());
|
system.registerApp(apps::createClockAppFactory());
|
||||||
system.registerApp(apps::createTetrisAppFactory());
|
system.registerApp(apps::createTetrisAppFactory());
|
||||||
system.registerApp(apps::createGameboyAppFactory());
|
system.registerApp(apps::createGameboyAppFactory());
|
||||||
|
|||||||
@@ -14,5 +14,6 @@ target_compile_features(cardboy_apps PUBLIC cxx_std_20)
|
|||||||
|
|
||||||
add_subdirectory(menu)
|
add_subdirectory(menu)
|
||||||
add_subdirectory(clock)
|
add_subdirectory(clock)
|
||||||
|
add_subdirectory(settings)
|
||||||
add_subdirectory(gameboy)
|
add_subdirectory(gameboy)
|
||||||
add_subdirectory(tetris)
|
add_subdirectory(tetris)
|
||||||
|
|||||||
9
Firmware/sdk/apps/settings/CMakeLists.txt
Normal file
9
Firmware/sdk/apps/settings/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
target_sources(cardboy_apps
|
||||||
|
PRIVATE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/settings_app.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(cardboy_apps
|
||||||
|
PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
)
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cardboy/sdk/app_framework.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace apps {
|
||||||
|
|
||||||
|
inline constexpr char kSettingsAppName[] = "Settings";
|
||||||
|
|
||||||
|
std::unique_ptr<cardboy::sdk::IAppFactory> createSettingsAppFactory();
|
||||||
|
|
||||||
|
} // namespace apps
|
||||||
130
Firmware/sdk/apps/settings/src/settings_app.cpp
Normal file
130
Firmware/sdk/apps/settings/src/settings_app.cpp
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
#include "cardboy/apps/settings_app.hpp"
|
||||||
|
|
||||||
|
#include "cardboy/apps/menu_app.hpp"
|
||||||
|
#include "cardboy/gfx/font16x8.hpp"
|
||||||
|
#include "cardboy/sdk/app_framework.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace apps {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using cardboy::sdk::AppContext;
|
||||||
|
using Framebuffer = typename AppContext::Framebuffer;
|
||||||
|
|
||||||
|
class SettingsApp final : public cardboy::sdk::IApp {
|
||||||
|
public:
|
||||||
|
explicit SettingsApp(AppContext& ctx) : context(ctx), framebuffer(ctx.framebuffer) {}
|
||||||
|
|
||||||
|
void onStart() override {
|
||||||
|
refreshState();
|
||||||
|
dirty = true;
|
||||||
|
renderIfNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleEvent(const cardboy::sdk::AppEvent& event) override {
|
||||||
|
if (event.type != cardboy::sdk::AppEventType::Button)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto& current = event.button.current;
|
||||||
|
const auto& previous = event.button.previous;
|
||||||
|
|
||||||
|
const bool prevAvailable = buzzerAvailable;
|
||||||
|
const bool prevMuted = muted;
|
||||||
|
refreshState();
|
||||||
|
if (prevAvailable != buzzerAvailable || prevMuted != muted)
|
||||||
|
dirty = true;
|
||||||
|
|
||||||
|
if (current.b && !previous.b) {
|
||||||
|
context.requestAppSwitchByName(kMenuAppName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool togglePressed = (current.a && !previous.a) || (current.select && !previous.select) ||
|
||||||
|
(current.start && !previous.start);
|
||||||
|
if (togglePressed)
|
||||||
|
toggleMute();
|
||||||
|
|
||||||
|
renderIfNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
AppContext& context;
|
||||||
|
Framebuffer& framebuffer;
|
||||||
|
|
||||||
|
bool buzzerAvailable = false;
|
||||||
|
bool muted = false;
|
||||||
|
bool dirty = false;
|
||||||
|
|
||||||
|
void refreshState() {
|
||||||
|
if (auto* buzzer = context.buzzer()) {
|
||||||
|
buzzerAvailable = true;
|
||||||
|
muted = buzzer->isMuted();
|
||||||
|
} else {
|
||||||
|
buzzerAvailable = false;
|
||||||
|
muted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleMute() {
|
||||||
|
auto* buzzer = context.buzzer();
|
||||||
|
if (!buzzer)
|
||||||
|
return;
|
||||||
|
const bool targetMuted = !muted;
|
||||||
|
buzzer->setMuted(targetMuted);
|
||||||
|
muted = buzzer->isMuted();
|
||||||
|
if (!muted)
|
||||||
|
buzzer->beepMove();
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawCenteredText(Framebuffer& fb, int y, std::string_view text, int scale, int letterSpacing = 1) {
|
||||||
|
const int width = font16x8::measureText(text, scale, letterSpacing);
|
||||||
|
const int x = (fb.width() - width) / 2;
|
||||||
|
font16x8::drawText(fb, x, y, text, scale, true, letterSpacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderIfNeeded() {
|
||||||
|
if (!dirty)
|
||||||
|
return;
|
||||||
|
dirty = false;
|
||||||
|
|
||||||
|
framebuffer.frameReady();
|
||||||
|
framebuffer.clear(false);
|
||||||
|
|
||||||
|
drawCenteredText(framebuffer, 24, "SETTINGS", 1, 1);
|
||||||
|
|
||||||
|
const int centerY = framebuffer.height() / 2;
|
||||||
|
if (!buzzerAvailable) {
|
||||||
|
drawCenteredText(framebuffer, centerY - 12, "BUZZER SERVICE", 1, 1);
|
||||||
|
drawCenteredText(framebuffer, centerY + 8, "UNAVAILABLE", 1, 1);
|
||||||
|
} else {
|
||||||
|
const char* stateText = muted ? "ON" : "OFF";
|
||||||
|
std::string line = std::string("MUTE: ") + stateText;
|
||||||
|
drawCenteredText(framebuffer, centerY - 20, line, 2, 0);
|
||||||
|
drawCenteredText(framebuffer, centerY + 26, "A TOGGLE", 1, 1);
|
||||||
|
drawCenteredText(framebuffer, centerY + 44, "START/SELECT ALSO", 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawCenteredText(framebuffer, framebuffer.height() - 28, "B BACK", 1, 1);
|
||||||
|
|
||||||
|
framebuffer.sendFrame();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SettingsAppFactory final : public cardboy::sdk::IAppFactory {
|
||||||
|
public:
|
||||||
|
const char* name() const override { return kSettingsAppName; }
|
||||||
|
std::unique_ptr<cardboy::sdk::IApp> create(cardboy::sdk::AppContext& context) override {
|
||||||
|
return std::make_unique<SettingsApp>(context);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
std::unique_ptr<cardboy::sdk::IAppFactory> createSettingsAppFactory() { return std::make_unique<SettingsAppFactory>(); }
|
||||||
|
|
||||||
|
} // namespace apps
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "cardboy/apps/clock_app.hpp"
|
#include "cardboy/apps/clock_app.hpp"
|
||||||
#include "cardboy/apps/gameboy_app.hpp"
|
#include "cardboy/apps/gameboy_app.hpp"
|
||||||
#include "cardboy/apps/menu_app.hpp"
|
#include "cardboy/apps/menu_app.hpp"
|
||||||
|
#include "cardboy/apps/settings_app.hpp"
|
||||||
#include "cardboy/apps/tetris_app.hpp"
|
#include "cardboy/apps/tetris_app.hpp"
|
||||||
#include "cardboy/backend/desktop_backend.hpp"
|
#include "cardboy/backend/desktop_backend.hpp"
|
||||||
#include "cardboy/sdk/app_system.hpp"
|
#include "cardboy/sdk/app_system.hpp"
|
||||||
@@ -19,6 +20,7 @@ int main() {
|
|||||||
cardboy::sdk::AppSystem system(context);
|
cardboy::sdk::AppSystem system(context);
|
||||||
|
|
||||||
system.registerApp(apps::createMenuAppFactory());
|
system.registerApp(apps::createMenuAppFactory());
|
||||||
|
system.registerApp(apps::createSettingsAppFactory());
|
||||||
system.registerApp(apps::createClockAppFactory());
|
system.registerApp(apps::createClockAppFactory());
|
||||||
system.registerApp(apps::createGameboyAppFactory());
|
system.registerApp(apps::createGameboyAppFactory());
|
||||||
system.registerApp(apps::createTetrisAppFactory());
|
system.registerApp(apps::createTetrisAppFactory());
|
||||||
|
|||||||
Reference in New Issue
Block a user