#include
// 配置常量
enum {
MENU_COUNT = 4,
LINE_H = 16,
SEL_H = 16,
MIN_W = 20,
ANIM_SPEED = 4,
FRAME_DELAY = 1,
SCREEN_WIDTH = 128
};
// 主菜单配置
static const char* const menu_items[MENU_COUNT] = {
" Wos", " main.py", " main1.py", " main2.py"
};
static const uint8_t item_widths[MENU_COUNT] = {30, 53, 60, 60};
// Wos二级菜单
static const char* const wos_submenu[] = {" Wos", " 版本1.0.0.3", " CPU:ESP-32", " 主频:240Mhz"};
// 主程序二级菜单模板
static const char* const program_submenu[] = {"", "", " 运行", " 返回"}; // 第一行会在代码中动态设置
// 状态变量
struct {
// 主菜单状态
volatile float selected_line;
float anim_progress;
uint32_t last_frame;
uint8_t current;
uint8_t target;
bool animating;
// 二级菜单通用状态
bool inSubmenu = false;
bool isEntering = false;
bool animationDone = false;
int16_t submenuOffset = 0;
// Wos菜单状态
bool showWosInfo = false;
// 程序子菜单状态
uint8_t submenuSelection = 2; // 默认选中"运行"
char currentProgram[9] = ""; // 存储当前程序名
} menu;
// 函数声明
void drawMenu();
void pin13TouchCallback();
void drawWosSubmenu();
void drawProgramSubmenu();
void updateSubmenuAnimation();
void handleProgramSubmenuInput();
void setup() {
mPython.begin();
menu.current = 1;
menu.selected_line = 1.0f;
touchPadH.setTouchedCallback(pin13TouchCallback);
drawMenu();
}
void loop() {
uint32_t now = millis();
float delta = min(0.1f, (now - menu.last_frame) / 200.0f);
menu.last_frame = now;
if (menu.inSubmenu) {
if (!menu.animationDone) {
updateSubmenuAnimation();
} else if (menu.current >= 2 && menu.current <= 4) { // 程序子菜单处理输入
handleProgramSubmenuInput();
}
return;
}
if (menu.animating) {
menu.anim_progress += delta * ANIM_SPEED;
if (menu.anim_progress >= 1.0f) {
menu.anim_progress = 0;
menu.current = menu.target;
menu.animating = false;
}
drawMenu();
}
if (!menu.animating) {
if (buttonA.isPressed()) {
menu.target = (menu.current == 1) ? MENU_COUNT : menu.current - 1;
menu.animating = true;
while(buttonA.isPressed());
}
else if (buttonB.isPressed()) {
menu.target = (menu.current == MENU_COUNT) ? 1 : menu.current + 1;
menu.animating = true;
while(buttonB.isPressed());
}
}
menu.selected_line = menu.current;
delay(FRAME_DELAY);
}
void pin13TouchCallback() {
if (!menu.inSubmenu) {
if (menu.current == 1) { // Wos菜单
menu.showWosInfo = true;
menu.inSubmenu = true;
menu.isEntering = true;
menu.animationDone = false;
menu.submenuOffset = SCREEN_WIDTH;
menu.anim_progress = 0;
} else if (menu.current >= 2 && menu.current <= 4) { // 程序菜单
strncpy(menu.currentProgram, menu_items[menu.current-1]+1, 8); // 去掉前面的空格
menu.currentProgram[8] = '\0';
menu.inSubmenu = true;
menu.isEntering = true;
menu.animationDone = false;
menu.submenuOffset = SCREEN_WIDTH;
menu.anim_progress = 0;
menu.submenuSelection = 2; // 默认选中"运行"
}
}
else if (menu.inSubmenu && menu.current >= 2 && menu.current <= 4 && menu.submenuSelection == 3) {
// 程序子菜单中选中"返回"
menu.isEntering = false;
menu.animationDone = false;
menu.anim_progress = 0;
menu.animating = false; // 新增:重置主菜单动画状态
}
else if (menu.inSubmenu && menu.current == 1) {
// Wos子菜单按H返回
menu.isEntering = false;
menu.animationDone = false;
menu.anim_progress = 0;
menu.animating = false; // 新增:重置主菜单动画状态
}
}
void updateSubmenuAnimation() {
if (menu.isEntering) {
menu.anim_progress += 0.1f * ANIM_SPEED;
menu.submenuOffset = SCREEN_WIDTH * (1 - menu.anim_progress);
if (menu.anim_progress >= 1.0f) {
menu.anim_progress = 1.0f;
menu.submenuOffset = 0;
menu.animationDone = true;
}
} else {
menu.anim_progress += 0.1f * ANIM_SPEED;
menu.submenuOffset = SCREEN_WIDTH * menu.anim_progress;
if (menu.anim_progress >= 1.0f) {
menu.inSubmenu = false;
menu.showWosInfo = false;
menu.submenuOffset = 0;
menu.animationDone = true;
menu.animating = false; // 确保重置动画状态
menu.anim_progress = 0; // 确保重置动画进度
drawMenu();
return;
}
}
// 根据当前菜单项绘制不同的子菜单
if (menu.current == 1) {
drawWosSubmenu();
} else if (menu.current >= 2 && menu.current <= 4) {
drawProgramSubmenu();
}
}
void handleProgramSubmenuInput() {
static uint8_t lastSelection = menu.submenuSelection;
if (buttonA.isPressed()) {
menu.submenuSelection = (menu.submenuSelection == 2) ? 3 : menu.submenuSelection - 1;
while(buttonA.isPressed());
drawProgramSubmenu();
}
else if (buttonB.isPressed()) {
menu.submenuSelection = (menu.submenuSelection == 3) ? 2 : menu.submenuSelection + 1;
while(buttonB.isPressed());
drawProgramSubmenu();
}
}
void drawWosSubmenu() {
display.fillScreen(0);
// 应用偏移量
int16_t xPos = menu.submenuOffset;
// 绘制Wos信息
for (uint8_t i = 0; i < 4; i++) {
display.setCursor(xPos, i * LINE_H);
display.print(wos_submenu[i]);
}
}
void drawProgramSubmenu() {
display.fillScreen(0);
// 应用偏移量
int16_t xPos = menu.submenuOffset;
// 第一行显示程序名
display.setCursor(xPos, 0);
display.print(" ");
display.print(menu.currentProgram);
// 绘制程序子菜单项(跳过空行)
for (uint8_t i = 2; i < 4; i++) {
display.setCursor(xPos, i * LINE_H);
display.print(program_submenu[i]);
}
// 绘制选择框(跳过空行)
uint8_t selectLine = menu.submenuSelection;
if (selectLine >= 2) selectLine++; // 跳过空行
display.rect(0, (selectLine - 1) * LINE_H, 30, SEL_H, false);
}
void drawMenu() {
float y = (menu.current - 1) * LINE_H;
uint16_t w = item_widths[menu.current - 1];
if (menu.animating) {
float y1 = (menu.current - 1) * LINE_H;
float y2 = (menu.target - 1) * LINE_H;
y = y1 + (y2 - y1) * menu.anim_progress;
uint16_t w2 = item_widths[menu.target - 1];
w = w + (w2 - w) * menu.anim_progress;
}
for (uint8_t i = 0; i < MENU_COUNT; i++) {
display.fillInLine(i+1, 0);
display.setCursorLine(i+1);
display.printLine(menu_items[i]);
}
display.rect(0, (uint16_t)y, max(MIN_W, w), SEL_H, false);
}
使用方法,A/B切换,H确定退出
评论