M5Stack使用GUIslice库1 官方例程5,多页面切换
针对M5s的按键修改的例程
#include <Arduino.h> /// // GUIslice Library Examples // - Calvin Hass // - https://www.impulseadventure.com/elec/guislice-gui.html // - https://github.com/ImpulseAdventure/GUIslice // - Example 05 (Arduino): // - Multiple page handling, checkboxes // - NOTE: This is the simple version of the example without // optimizing for memory consumption. Therefore, it may not // run on Arduino devices with limited memory. A "minimal" // version is located in the "arduino_min" folder which includes // FLASH memory optimization for reduced memory devices. // // ARDUINO NOTES: // - GUIslice_config.h must be edited to match the pinout connections // between the Arduino CPU and the display controller (see ADAGFX_PIN_*). // - To support a larger number of GUI elements, it is recommended to // use a CPU that provides more than 2KB of SRAM (eg. ATmega2560). // // // GUIslice 库示例 // - 卡尔文哈斯 // - https://www.impulseadventure.com/elec/guislice-gui.html // - https://github.com/ImpulseAdventure/GUIslice // - 示例 05(Arduino): // - 多页处理,复选框 // - 注意:这是示例的简单版本,没有 // 优化内存消耗。 因此,它可能不会 // 在内存有限的 Arduino 设备上运行。 一个“最小” // 版本位于“arduino_min”文件夹中,其中包括 // 闪存优化减少内存设备。 // // ARDUINO 注释: // - 必须编辑 GUIslice_config.h 以匹配引脚连接 // 在 Arduino CPU 和显示控制器之间(参见 ADAGFX_PIN_*)。 // - 为了支持更多的 GUI 元素,建议使用 // 使用提供超过 2KB SRAM 的 CPU(例如 ATmega2560)。 // #include "GUIslice.h" #include "GUIslice_drv.h" // Include any extended elements包括任何扩展元素 #include "elem/XCheckbox.h" #include "elem/XProgress.h" // Defines for resources // Enumerations for pages, elements, fonts, images枚举资源 enum {E_PG_MAIN,E_PG_EXTRA}; enum {E_ELEM_BTN_QUIT,E_ELEM_BTN_EXTRA,E_ELEM_BTN_BACK, E_ELEM_TXT_COUNT,E_ELEM_PROGRESS, E_ELEM_CHECK1,E_ELEM_CHECK2,E_ELEM_CHECK3}; enum {E_FONT_BTN,E_FONT_TXT,E_FONT_TITLE,MAX_FONT}; // Use separate enum for fonts, MAX_FONT at end bool m_bQuit = false; // Free-running counter for display 计数器变量 unsigned m_nCount = 0; // Instantiate the GUI 实例化gui #define MAX_PAGE 2 // Define the maximum number of elements per page定义每页的最大元素数 #define MAX_ELEM_PG_MAIN 9 // # Elems total on Main page #define MAX_ELEM_PG_EXTRA 7 // # Elems total on Extra page #define MAX_ELEM_PG_MAIN_RAM MAX_ELEM_PG_MAIN // # Elems in RAM #define MAX_ELEM_PG_EXTRA_RAM MAX_ELEM_PG_EXTRA // # Elems in RAM //声明gui元素 gslc_tsGui m_gui; gslc_tsDriver m_drv; gslc_tsFont m_asFont[MAX_FONT]; gslc_tsPage m_asPage[MAX_PAGE]; gslc_tsElem m_asMainElem[MAX_ELEM_PG_MAIN_RAM]; gslc_tsElemRef m_asMainElemRef[MAX_ELEM_PG_MAIN]; gslc_tsElem m_asExtraElem[MAX_ELEM_PG_EXTRA_RAM]; gslc_tsElemRef m_asExtraElemRef[MAX_ELEM_PG_EXTRA]; gslc_tsXProgress m_sXGauge; gslc_tsXCheckbox m_asXCheck[3]; // 定义输入映射 #define MAX_INPUT_MAP 5 gslc_tsInputMap m_asInputMap[MAX_INPUT_MAP]; #define MAX_STR 8 // Save some element pointers for quick access 保存指针用于快速访问 gslc_tsElemRef* m_pElemCnt = NULL; gslc_tsElemRef* m_pElemProgress = NULL; // Define debug message function static int16_t DebugOut(char ch) { Serial.write(ch); return 0; } // Button callbacks // - Show example of common callback function 按钮回调 bool CbBtnCommon(void* pvGui,void *pvElemRef,gslc_teTouch eTouch,int16_t nX,int16_t nY) { gslc_tsGui* pGui = (gslc_tsGui*)pvGui; gslc_tsElemRef* pElemRef = (gslc_tsElemRef*)(pvElemRef); gslc_tsElem* pElem = gslc_GetElemFromRef(pGui,pElemRef); int16_t nElemId = pElem->nId; if (eTouch == GSLC_TOUCH_UP_IN) { if (nElemId == E_ELEM_BTN_QUIT) { m_bQuit = true; } else if (nElemId == E_ELEM_BTN_EXTRA) { gslc_SetPageCur(pGui,E_PG_EXTRA); } else if (nElemId == E_ELEM_BTN_BACK) { gslc_SetPageCur(pGui,E_PG_MAIN); } }//根据事件发生的元素做出不同反应 return true; } // Create the default elements on each page 给每个页面创建元素 bool InitOverlays() { gslc_tsElemRef* pElemRef = NULL; gslc_PageAdd(&m_gui,E_PG_MAIN,m_asMainElem,MAX_ELEM_PG_MAIN_RAM,m_asMainElemRef,MAX_ELEM_PG_MAIN); gslc_PageAdd(&m_gui,E_PG_EXTRA,m_asExtraElem,MAX_ELEM_PG_EXTRA_RAM,m_asExtraElemRef,MAX_ELEM_PG_EXTRA); // ----------------------------------- // PAGE: MAIN 主页面 // Create background box 背景框 pElemRef = gslc_ElemCreateBox(&m_gui,GSLC_ID_AUTO,E_PG_MAIN,(gslc_tsRect){20,50,280,150}); gslc_ElemSetCol(&m_gui,pElemRef,GSLC_COL_WHITE,GSLC_COL_BLACK,GSLC_COL_BLACK); // Create title 抬头 pElemRef = gslc_ElemCreateTxt(&m_gui,GSLC_ID_AUTO,E_PG_MAIN,(gslc_tsRect){10,10,310,40}, (char*)"GUIslice Demo",0,E_FONT_TITLE); gslc_ElemSetTxtAlign(&m_gui,pElemRef,GSLC_ALIGN_MID_MID); gslc_ElemSetFillEn(&m_gui,pElemRef,false); gslc_ElemSetTxtCol(&m_gui,pElemRef,GSLC_COL_WHITE); // Create Quit button with text label 按钮 pElemRef = gslc_ElemCreateBtnTxt(&m_gui,E_ELEM_BTN_QUIT,E_PG_MAIN, (gslc_tsRect){100,140,50,20},(char*)"Quit",0,E_FONT_BTN,&CbBtnCommon); // Create Extra button with text label 按钮 pElemRef = gslc_ElemCreateBtnTxt(&m_gui,E_ELEM_BTN_EXTRA,E_PG_MAIN, (gslc_tsRect){170,140,50,20},(char*)"Extra",0,E_FONT_BTN,&CbBtnCommon); // Create counter 计数器 pElemRef = gslc_ElemCreateTxt(&m_gui,GSLC_ID_AUTO,E_PG_MAIN,(gslc_tsRect){40,60,50,10}, (char*)"Count:",0,E_FONT_TXT); static char mstr1[8] = ""; pElemRef = gslc_ElemCreateTxt(&m_gui,E_ELEM_TXT_COUNT,E_PG_MAIN,(gslc_tsRect){100,60,50,10}, mstr1,sizeof(mstr1),E_FONT_TXT); gslc_ElemSetTxtCol(&m_gui,pElemRef,GSLC_COL_YELLOW); m_pElemCnt = pElemRef; // Save for quick access // Create progress bar 进度条 pElemRef = gslc_ElemCreateTxt(&m_gui,GSLC_ID_AUTO,E_PG_MAIN,(gslc_tsRect){40,80,50,10}, (char*)"Progress:",0,E_FONT_TXT); pElemRef = gslc_ElemXProgressCreate(&m_gui,E_ELEM_PROGRESS,E_PG_MAIN,&m_sXGauge,(gslc_tsRect){100,80,50,10}, 0,100,0,GSLC_COL_GREEN,false); m_pElemProgress = pElemRef; // Save for quick access // Checkbox element pElemRef = gslc_ElemXCheckboxCreate(&m_gui,E_ELEM_CHECK1,E_PG_MAIN,&m_asXCheck[0], (gslc_tsRect){200,80,30,30},false,GSLCX_CHECKBOX_STYLE_X,GSLC_COL_BLUE_LT2,false); // ----------------------------------- // PAGE: EXTRA 另一个页面 // Create background box pElemRef = gslc_ElemCreateBox(&m_gui,GSLC_ID_AUTO,E_PG_EXTRA,(gslc_tsRect){40,40,240,160}); gslc_ElemSetCol(&m_gui,pElemRef,GSLC_COL_WHITE,GSLC_COL_BLACK,GSLC_COL_BLACK); // Create Back button with text label 返回按钮 pElemRef = gslc_ElemCreateBtnTxt(&m_gui,E_ELEM_BTN_BACK,E_PG_EXTRA, (gslc_tsRect){50,170,50,20},(char*)"Back",0,E_FONT_BTN,&CbBtnCommon); // Create a few labels & checkboxes int16_t nPosY = 50; int16_t nSpaceY = 30; pElemRef = gslc_ElemXCheckboxCreate(&m_gui,E_ELEM_CHECK2,E_PG_EXTRA,&m_asXCheck[1], (gslc_tsRect){60,nPosY,20,20},false,GSLCX_CHECKBOX_STYLE_X,GSLC_COL_RED_LT2,false); pElemRef = gslc_ElemCreateTxt(&m_gui,GSLC_ID_AUTO,E_PG_EXTRA,(gslc_tsRect){100,nPosY,50,10}, (char*)"Data 1",0,E_FONT_TXT); nPosY += nSpaceY; pElemRef = gslc_ElemXCheckboxCreate(&m_gui,E_ELEM_CHECK3,E_PG_EXTRA,&m_asXCheck[2], (gslc_tsRect){60,nPosY,20,20},false,GSLCX_CHECKBOX_STYLE_X,GSLC_COL_RED_LT2,false); pElemRef = gslc_ElemCreateTxt(&m_gui,GSLC_ID_AUTO,E_PG_EXTRA,(gslc_tsRect){100,nPosY,50,10}, (char*)"Data 2",0,E_FONT_TXT); nPosY += nSpaceY; pElemRef = gslc_ElemCreateTxt(&m_gui,GSLC_ID_AUTO,E_PG_EXTRA,(gslc_tsRect){100,nPosY,50,10}, (char*)"Data 3",0,E_FONT_TXT); nPosY += nSpaceY; return true; } void setup() { // Initialize debug output Serial.begin(9600); gslc_InitDebug(&DebugOut); //delay(1000); // NOTE: Some devices require a delay after Serial.begin() before serial port can be used // Initialize 初始化 if (!gslc_Init(&m_gui,&m_drv,m_asPage,MAX_PAGE,m_asFont,MAX_FONT)) { return; } // Create the GUI input mapping (pin event to GUI action) 创建 GUI 输入映射(将事件固定到 GUI 操作) gslc_InitInputMap(&m_gui, m_asInputMap, MAX_INPUT_MAP); gslc_InputMapAdd(&m_gui, GSLC_INPUT_PIN_DEASSERT, GSLC_PIN_BTN_A, GSLC_ACTION_FOCUS_PREV, 0); gslc_InputMapAdd(&m_gui, GSLC_INPUT_PIN_DEASSERT, GSLC_PIN_BTN_B, GSLC_ACTION_SELECT, 0); gslc_InputMapAdd(&m_gui, GSLC_INPUT_PIN_DEASSERT, GSLC_PIN_BTN_C, GSLC_ACTION_FOCUS_NEXT, 0); gslc_InputMapAdd(&m_gui, GSLC_INPUT_PIN_ASSERT, GSLC_PIN_BTN_A_LONG, GSLC_ACTION_SET_REL, -10); gslc_InputMapAdd(&m_gui, GSLC_INPUT_PIN_ASSERT, GSLC_PIN_BTN_C_LONG, GSLC_ACTION_SET_REL, +10); // Load Fonts 加载字体 if (!gslc_FontSet(&m_gui,E_FONT_BTN,GSLC_FONTREF_PTR,NULL,1)) { return; } if (!gslc_FontSet(&m_gui,E_FONT_TXT,GSLC_FONTREF_PTR,NULL,1)) { return; } if (!gslc_FontSet(&m_gui,E_FONT_TITLE,GSLC_FONTREF_PTR,NULL,1)) { return; } // Create page elements 生成页面元素 InitOverlays(); // Start up display on main page 显示主页 gslc_SetPageCur(&m_gui,E_PG_MAIN); m_bQuit = false; } void loop() { char acTxt[MAX_STR]; // Save some element references for easy access 保存方便使用的元素引用 gslc_tsElemRef* pElemCnt = gslc_PageFindElemById(&m_gui,E_PG_MAIN,E_ELEM_TXT_COUNT); gslc_tsElemRef* pElemProgress = gslc_PageFindElemById(&m_gui,E_PG_MAIN,E_ELEM_PROGRESS); m_nCount++; // Perform drawing updates // - Note: we can make the updates conditional on the active // page by checking gslc_GetPageCur() first. 绘图更新 snprintf(acTxt,MAX_STR,"%u",m_nCount); gslc_ElemSetTxtStr(&m_gui,pElemCnt,acTxt); gslc_ElemXProgressSetVal(&m_gui,pElemProgress,((m_nCount/2)%100)); // Periodically call GUIslice update function gslc_Update(&m_gui); // Slow down updates delay(100); // In a real program, we would detect the button press and take an action. // For this Arduino demo, we will pretend to exit by emulating it with an // infinite loop. Note that interrupts are not disabled so that any debug // messages via Serial have an opportunity to be transmitted. if (m_bQuit) { gslc_Quit(&m_gui); while (1) { } } }