Fixes and new apps (#30)
- M5 Unit Modules library + M5 Unit Test app - Minor fixes for TodoList, TwoEleven, Snake, Brainfuck and Breakout - Fixed SerialConsole to use the uart controller as it was broken in one of the many updates - Fixed keyboard input in TwoEleven, Breakout, Magic8Ball and Snake - Bluetooth Media Keys app, supports pressing physical keys to trigger the corresponding buttonmatrix button - Epub Reader app
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <tt_lvgl_keyboard.h>
|
||||
|
||||
#include <tactility/lvgl_module.h>
|
||||
#include <tactility/lvgl_fonts.h>
|
||||
|
||||
constexpr auto* TAG = "Breakout";
|
||||
|
||||
@@ -97,14 +98,19 @@ static uint32_t levelRng(uint32_t& seed) {
|
||||
|
||||
// ── UI Creation ──────────────────────────────────────────────
|
||||
|
||||
static int getToolbarHeight(UiDensity density) {
|
||||
if (density == LVGL_UI_DENSITY_COMPACT) {
|
||||
return 22;
|
||||
static uint32_t getToolbarHeight(UiDensity uiDensity) {
|
||||
if (uiDensity == LVGL_UI_DENSITY_COMPACT) {
|
||||
return lvgl_get_text_font_height(FONT_SIZE_DEFAULT) * 1.4f;
|
||||
} else {
|
||||
return 40;
|
||||
return lvgl_get_text_font_height(FONT_SIZE_LARGE) * 2.2f;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t getActionIconPadding(UiDensity uiDensity) {
|
||||
auto toolbar_height = getToolbarHeight(uiDensity);
|
||||
return (uiDensity != LVGL_UI_DENSITY_COMPACT) ? (uint32_t)(toolbar_height * 0.2f) : 8;
|
||||
}
|
||||
|
||||
void Breakout::onShow(AppHandle appHandle, lv_obj_t* parent) {
|
||||
lv_obj_remove_flag(parent, LV_OBJ_FLAG_SCROLLABLE);
|
||||
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
|
||||
@@ -157,21 +163,21 @@ void Breakout::onShow(AppHandle appHandle, lv_obj_t* parent) {
|
||||
lv_obj_set_style_text_color(livesLabel, lv_palette_main(LV_PALETTE_RED), 0);
|
||||
lv_obj_align(livesLabel, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
auto ui_density = lvgl_get_ui_density();
|
||||
auto toolbar_height = getToolbarHeight(ui_density);
|
||||
auto icon_padding = getActionIconPadding(ui_density);
|
||||
|
||||
// Toolbar buttons wrapper
|
||||
lv_obj_t* btnsWrapper = lv_obj_create(toolbar);
|
||||
lv_obj_set_width(btnsWrapper, LV_SIZE_CONTENT);
|
||||
lv_obj_set_flex_flow(btnsWrapper, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_style_pad_all(btnsWrapper, 2, LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_pad_all(btnsWrapper, icon_padding / 2, LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_border_width(btnsWrapper, 0, LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_bg_opa(btnsWrapper, 0, LV_STATE_DEFAULT);
|
||||
|
||||
auto ui_density = lvgl_get_ui_density();
|
||||
auto toolbar_height = getToolbarHeight(ui_density);
|
||||
int btnSize = (ui_density == LVGL_UI_DENSITY_COMPACT) ? toolbar_height - 8 : toolbar_height - 6;
|
||||
|
||||
// Pause button
|
||||
lv_obj_t* pauseBtn = lv_btn_create(btnsWrapper);
|
||||
lv_obj_set_size(pauseBtn, btnSize, btnSize);
|
||||
lv_obj_set_size(pauseBtn, toolbar_height - icon_padding, toolbar_height - icon_padding);
|
||||
lv_obj_set_style_pad_all(pauseBtn, 0, LV_STATE_DEFAULT);
|
||||
lv_obj_align(pauseBtn, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_add_event_cb(pauseBtn, onPauseClicked, LV_EVENT_CLICKED, this);
|
||||
@@ -182,7 +188,7 @@ void Breakout::onShow(AppHandle appHandle, lv_obj_t* parent) {
|
||||
|
||||
// Sound toggle button
|
||||
lv_obj_t* soundBtn = lv_btn_create(btnsWrapper);
|
||||
lv_obj_set_size(soundBtn, btnSize, btnSize);
|
||||
lv_obj_set_size(soundBtn, toolbar_height - icon_padding, toolbar_height - icon_padding);
|
||||
lv_obj_set_style_pad_all(soundBtn, 0, LV_STATE_DEFAULT);
|
||||
lv_obj_align(soundBtn, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_add_event_cb(soundBtn, onSoundToggled, LV_EVENT_CLICKED, this);
|
||||
@@ -333,9 +339,9 @@ void Breakout::onShow(AppHandle appHandle, lv_obj_t* parent) {
|
||||
lv_obj_add_event_cb(gameArea, onPressed, LV_EVENT_PRESSING, this);
|
||||
lv_obj_add_event_cb(gameArea, onClicked, LV_EVENT_SHORT_CLICKED, this);
|
||||
lv_obj_add_event_cb(gameArea, onKey, LV_EVENT_KEY, this);
|
||||
lv_obj_add_event_cb(gameArea, onFocused, LV_EVENT_FOCUSED, this);
|
||||
lv_obj_add_event_cb(gameArea, onReenterKeyMode, LV_EVENT_CLICKED, this);
|
||||
|
||||
// Keyboard focus
|
||||
// Keyboard focus - explicit enter/exit, no focus/defocus handlers
|
||||
lv_group_t* group = lv_group_get_default();
|
||||
if (group) {
|
||||
lv_group_add_obj(group, gameArea);
|
||||
@@ -352,6 +358,11 @@ void Breakout::onHide(AppHandle appHandle) {
|
||||
lv_timer_delete(gameTimer);
|
||||
gameTimer = nullptr;
|
||||
}
|
||||
if (gameArea) {
|
||||
lv_group_t* group = lv_group_get_default();
|
||||
if (group) lv_group_set_editing(group, false);
|
||||
lv_group_remove_obj(gameArea);
|
||||
}
|
||||
gameArea = nullptr;
|
||||
paddle = nullptr;
|
||||
for (int i = 0; i < MAX_BRICKS; i++) bricks[i] = nullptr;
|
||||
@@ -1454,6 +1465,16 @@ void Breakout::onKey(lv_event_t* e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LV_KEY_ESC:
|
||||
case 'q':
|
||||
case 'Q': {
|
||||
// Exit key/edit mode - remove from group so navigation is restored
|
||||
// Re-entry: tap/click the game area to return to key mode
|
||||
lv_group_t* group = lv_group_get_default();
|
||||
if (group) lv_group_set_editing(group, false);
|
||||
lv_group_remove_obj(lv_event_get_current_target_obj(e));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1472,7 +1493,13 @@ void Breakout::onSoundToggled(lv_event_t* e) {
|
||||
self->updateSoundIcon();
|
||||
}
|
||||
|
||||
void Breakout::onFocused(lv_event_t* e) {
|
||||
void Breakout::onReenterKeyMode(lv_event_t* e) {
|
||||
lv_obj_t* area = lv_event_get_current_target_obj(e);
|
||||
lv_group_t* group = lv_group_get_default();
|
||||
if (group) lv_group_set_editing(group, true);
|
||||
if (!group) return;
|
||||
if (lv_obj_get_group(area) == NULL) {
|
||||
lv_group_add_obj(group, area);
|
||||
}
|
||||
lv_group_focus_obj(area);
|
||||
lv_group_set_editing(group, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user