Files
tactility_apps/Apps/TamaTac/main/Source/CemeteryView.cpp
T
2026-02-13 21:26:23 +01:00

136 lines
4.8 KiB
C++

/**
* @file CemeteryView.cpp
* @brief Pet Cemetery / Hall of Fame view implementation
*/
#include "CemeteryView.h"
#include "TamaTac.h"
#include <TactilityCpp/Preferences.h>
#include <cstdio>
static constexpr const char* PREF_NS = "TamaTacCem";
void CemeteryView::loadRecords(PetRecord records[MAX_RECORDS]) {
Preferences prefs(PREF_NS);
for (int i = 0; i < MAX_RECORDS; i++) {
char key[16];
snprintf(key, sizeof(key), "valid%d", i);
records[i].valid = prefs.getBool(key, false);
if (records[i].valid) {
snprintf(key, sizeof(key), "pers%d", i);
records[i].personality = static_cast<Personality>(prefs.getInt32(key, 0));
snprintf(key, sizeof(key), "stage%d", i);
records[i].stageReached = static_cast<LifeStage>(prefs.getInt32(key, 0));
snprintf(key, sizeof(key), "age%d", i);
records[i].ageHours = static_cast<uint16_t>(prefs.getInt32(key, 0));
}
}
}
void CemeteryView::recordDeath(Personality personality, LifeStage stage, uint16_t ageHours) {
Preferences prefs(PREF_NS);
// Shift existing records down (newest at index 0)
for (int i = MAX_RECORDS - 1; i > 0; i--) {
char srcKey[16], dstKey[16];
snprintf(srcKey, sizeof(srcKey), "valid%d", i - 1);
snprintf(dstKey, sizeof(dstKey), "valid%d", i);
bool srcValid = prefs.getBool(srcKey, false);
prefs.putBool(dstKey, srcValid);
if (srcValid) {
snprintf(srcKey, sizeof(srcKey), "pers%d", i - 1);
snprintf(dstKey, sizeof(dstKey), "pers%d", i);
prefs.putInt32(dstKey, prefs.getInt32(srcKey, 0));
snprintf(srcKey, sizeof(srcKey), "stage%d", i - 1);
snprintf(dstKey, sizeof(dstKey), "stage%d", i);
prefs.putInt32(dstKey, prefs.getInt32(srcKey, 0));
snprintf(srcKey, sizeof(srcKey), "age%d", i - 1);
snprintf(dstKey, sizeof(dstKey), "age%d", i);
prefs.putInt32(dstKey, prefs.getInt32(srcKey, 0));
}
}
// Write new record at index 0
prefs.putBool("valid0", true);
prefs.putInt32("pers0", static_cast<int32_t>(personality));
prefs.putInt32("stage0", static_cast<int32_t>(stage));
prefs.putInt32("age0", static_cast<int32_t>(ageHours));
}
void CemeteryView::onStart(lv_obj_t* parentWidget, TamaTac* appInstance) {
parent = parentWidget;
app = appInstance;
lv_coord_t screenWidth = lv_display_get_horizontal_resolution(nullptr);
lv_coord_t screenHeight = lv_display_get_vertical_resolution(nullptr);
bool isSmall = (screenWidth < 280 || screenHeight < 180);
bool isXLarge = (screenWidth >= 600);
int padAll = isSmall ? 4 : (isXLarge ? 16 : 8);
int padRow = isSmall ? 4 : (isXLarge ? 12 : 6);
mainWrapper = lv_obj_create(parent);
lv_obj_set_size(mainWrapper, LV_PCT(100), LV_PCT(100));
lv_obj_set_style_pad_all(mainWrapper, padAll, 0);
lv_obj_set_style_pad_row(mainWrapper, padRow, 0);
lv_obj_set_style_bg_opa(mainWrapper, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(mainWrapper, 0, 0);
lv_obj_set_flex_flow(mainWrapper, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(mainWrapper, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
// Title
lv_obj_t* title = lv_label_create(mainWrapper);
lv_label_set_text(title, "Pet Cemetery");
lv_obj_set_style_text_color(title, lv_color_hex(0xFFFFFF), 0);
// Load records
PetRecord records[MAX_RECORDS];
loadRecords(records);
bool anyRecords = false;
for (int i = 0; i < MAX_RECORDS; i++) {
if (!records[i].valid) continue;
anyRecords = true;
lv_obj_t* row = lv_obj_create(mainWrapper);
lv_obj_set_size(row, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(row, isSmall ? 4 : (isXLarge ? 12 : 6), 0);
lv_obj_set_style_bg_color(row, lv_color_hex(0x2a2a4e), 0);
lv_obj_set_style_border_width(row, 0, 0);
lv_obj_set_style_radius(row, isSmall ? 4 : (isXLarge ? 10 : 6), 0);
char text[80];
int days = records[i].ageHours / 24;
int hours = records[i].ageHours % 24;
snprintf(text, sizeof(text), "#%d %s %s %dd %dh",
i + 1,
personalityToString(records[i].personality),
lifeStageToString(records[i].stageReached),
days, hours);
lv_obj_t* label = lv_label_create(row);
lv_label_set_text(label, text);
lv_obj_set_style_text_color(label, lv_color_hex(0xCCCCCC), 0);
}
if (!anyRecords) {
lv_obj_t* emptyLabel = lv_label_create(mainWrapper);
lv_label_set_text(emptyLabel, "No records yet.");
lv_obj_set_style_text_color(emptyLabel, lv_palette_lighten(LV_PALETTE_GREY, 3), 0);
}
}
void CemeteryView::onStop() {
mainWrapper = nullptr;
parent = nullptr;
app = nullptr;
}