├── .gitattributes ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── default_16MB.csv ├── include └── README ├── lib └── README ├── platformio.ini └── src ├── epdgui ├── epdgui.cpp ├── epdgui.h ├── epdgui_base.cpp ├── epdgui_base.h ├── epdgui_button.cpp ├── epdgui_button.h ├── epdgui_keyboard.cpp ├── epdgui_keyboard.h ├── epdgui_mutexswitch.cpp ├── epdgui_mutexswitch.h ├── epdgui_switch.cpp ├── epdgui_switch.h ├── epdgui_textbox.cpp └── epdgui_textbox.h ├── frame ├── frame.cpp ├── frame.h ├── frame_base.cpp ├── frame_base.h ├── frame_compare.cpp ├── frame_compare.h ├── frame_factorytest.cpp ├── frame_factorytest.h ├── frame_fileindex.cpp ├── frame_fileindex.h ├── frame_home.cpp ├── frame_home.h ├── frame_keyboard.cpp ├── frame_keyboard.h ├── frame_lifegame.cpp ├── frame_lifegame.h ├── frame_main.cpp ├── frame_main.h ├── frame_pictureviewer.cpp ├── frame_pictureviewer.h ├── frame_settings.cpp ├── frame_settings.h ├── frame_settings_wallpaper.cpp ├── frame_settings_wallpaper.h ├── frame_settings_wifi.cpp ├── frame_settings_wifi.h ├── frame_settings_wifi_password.cpp ├── frame_settings_wifi_password.h ├── frame_txtreader.cpp └── frame_txtreader.h ├── global_setting.cpp ├── global_setting.h ├── main.cpp ├── resources ├── ImageResource.h └── binaryttf.h ├── systeminit.cpp └── systeminit.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | .pio 35 | .vscode 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Continuous Integration (CI) is the practice, in software 2 | # engineering, of merging all developer working copies with a shared mainline 3 | # several times a day < https://docs.platformio.org/page/ci/index.html > 4 | # 5 | # Documentation: 6 | # 7 | # * Travis CI Embedded Builds with PlatformIO 8 | # < https://docs.travis-ci.com/user/integration/platformio/ > 9 | # 10 | # * PlatformIO integration with Travis CI 11 | # < https://docs.platformio.org/page/ci/travis.html > 12 | # 13 | # * User Guide for `platformio ci` command 14 | # < https://docs.platformio.org/page/userguide/cmd_ci.html > 15 | # 16 | # 17 | # Please choose one of the following templates (proposed below) and uncomment 18 | # it (remove "# " before each line) or use own configuration according to the 19 | # Travis CI documentation (see above). 20 | # 21 | 22 | 23 | # 24 | # Template #1: General project. Test it using existing `platformio.ini`. 25 | # 26 | 27 | # language: python 28 | # python: 29 | # - "2.7" 30 | # 31 | # sudo: false 32 | # cache: 33 | # directories: 34 | # - "~/.platformio" 35 | # 36 | # install: 37 | # - pip install -U platformio 38 | # - platformio update 39 | # 40 | # script: 41 | # - platformio run 42 | 43 | 44 | # 45 | # Template #2: The project is intended to be used as a library with examples. 46 | # 47 | 48 | # language: python 49 | # python: 50 | # - "2.7" 51 | # 52 | # sudo: false 53 | # cache: 54 | # directories: 55 | # - "~/.platformio" 56 | # 57 | # env: 58 | # - PLATFORMIO_CI_SRC=path/to/test/file.c 59 | # - PLATFORMIO_CI_SRC=examples/file.ino 60 | # - PLATFORMIO_CI_SRC=path/to/test/directory 61 | # 62 | # install: 63 | # - pip install -U platformio 64 | # - platformio update 65 | # 66 | # script: 67 | # - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N 68 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 m5stack 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # M5PaperOS 2 | 3 | I'm improving on the [m5stack/M5Paper_FactoryTest](https://github.com/m5stack/M5Paper_FactoryTest), fixing bugs and adding functionality. 4 | 5 | 6 | ## Improvements so far 7 | 8 | - Moved Wi-Fi configuration into Settings app 9 | - Added Wi-Fi indicator to status bar 10 | - Added DejaVu-Sans in order to see utf-8 icons 11 | - Extended Wi-Fi connection timeout to establish connection more reliably 12 | - Preventing Wi-Fi from disconnecting 13 | - Automatically syncing time after Wi-Fi connection was established 14 | - Removed unused button from keyboard and enlarged number-alpha switch 15 | - Increased back arrow size to prevent labels from beeing cut off 16 | - Made some visual improvements to the UI 17 | 18 | 19 | ## Bugfixes so far 20 | 21 | - Fixed bootup sequence to automatically connect to saved Wi-Fi network 22 | - Added missing dependency to `platformio.ini` 23 | - Fixed typos and misspellings 24 | - Fixed label centering issues 25 | 26 | 27 | ## Other changes 28 | 29 | - Removed poorly implemented language selection 30 | - Renamed `WLAN` to `Wi-Fi` -------------------------------------------------------------------------------- /default_16MB.csv: -------------------------------------------------------------------------------- 1 | # Name, Type, SubType, Offset, Size, Flags 2 | nvs, data, nvs, 0x9000, 0x5000, 3 | otadata, data, ota, 0xe000, 0x2000, 4 | app0, app, ota_0, 0x10000, 0x640000, 5 | app1, app, ota_1, 0x650000,0x640000, 6 | spiffs, data, spiffs, 0xc90000,0x370000, -------------------------------------------------------------------------------- /include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:m5stack-fire] 12 | platform = espressif32 13 | board = m5stack-fire 14 | framework = arduino 15 | upload_port = /dev/cu.usbserial-02129749 16 | upload_speed = 2000000 17 | monitor_port = /dev/cu.usbserial-02129749 18 | monitor_speed = 115200 19 | board_build.partitions = default_16MB.csv 20 | build_flags = 21 | -DCORE_DEBUG_LEVEL=4 22 | -DBOARD_HAS_PSRAM 23 | -mfix-esp32-psram-cache-issue 24 | lib_deps = 25 | m5stack/M5EPD 26 | -------------------------------------------------------------------------------- /src/epdgui/epdgui.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "epdgui.h" 5 | 6 | typedef struct { 7 | Frame_Base* frame; 8 | epdgui_args_vector_t args; 9 | }frame_struct_t; 10 | 11 | std::list epdgui_object_list; 12 | uint32_t obj_id = 1; 13 | Frame_Base* wait_for_delete = NULL; 14 | std::stack frame_stack; 15 | std::map frame_map; 16 | uint8_t frame_switch_count = 0; 17 | bool _is_auto_update = true; 18 | uint16_t _last_pos_x = 0xFFFF, _last_pos_y = 0xFFFF; 19 | 20 | void EPDGUI_AddObject(EPDGUI_Base* object) { 21 | object->SetID(obj_id); 22 | obj_id++; 23 | epdgui_object_list.push_back(object); 24 | } 25 | 26 | void EPDGUI_Draw(m5epd_update_mode_t mode) { 27 | for (std::list::iterator p = epdgui_object_list.begin(); p != epdgui_object_list.end(); p++) { 28 | (*p)->Draw(mode); 29 | } 30 | } 31 | 32 | void EPDGUI_Process(void) { 33 | for (std::list::iterator p = epdgui_object_list.begin(); p != epdgui_object_list.end(); p++) { 34 | (*p)->UpdateState(-1, -1); 35 | } 36 | } 37 | 38 | void EPDGUI_Process(int16_t x, int16_t y) { 39 | for (std::list::iterator p = epdgui_object_list.begin(); p != epdgui_object_list.end(); p++) { 40 | // log_d("%d, %d -> %d, %d, %d, %d", x, y, (*p)->getX(), (*p)->getY(), (*p)->getRX(), (*p)->getBY()); 41 | (*p)->UpdateState(x, y); 42 | } 43 | } 44 | 45 | void EPDGUI_Clear(void) { 46 | epdgui_object_list.clear(); 47 | } 48 | 49 | void EPDGUI_Run(Frame_Base* frame) { 50 | uint32_t last_active_time = 0; 51 | 52 | if (frame->isRun() == 0) { 53 | frame->exit(); 54 | log_d("Exit %s", frame->GetFrameName().c_str()); 55 | if (wait_for_delete != NULL) { 56 | delete wait_for_delete; 57 | wait_for_delete = NULL; 58 | } 59 | return; 60 | } 61 | 62 | EPDGUI_Draw(UPDATE_MODE_NONE); 63 | if ((frame->GetFrameID() == 1) || (frame_switch_count > 3)) { 64 | frame_switch_count = 0; 65 | M5.EPD.UpdateFull(UPDATE_MODE_GC16); 66 | } else { 67 | M5.EPD.UpdateFull(UPDATE_MODE_GL16); 68 | frame_switch_count++; 69 | } 70 | 71 | while (true) { 72 | if ((frame->isRun() == 0) || (frame->run() == 0)) { 73 | frame->exit(); 74 | // M5.EPD.Clear(); 75 | log_d("Exit %s", frame->GetFrameName().c_str()); 76 | if (wait_for_delete != NULL) { 77 | log_d("delete %s", wait_for_delete->GetFrameName().c_str()); 78 | delete wait_for_delete; 79 | wait_for_delete = NULL; 80 | } 81 | return; 82 | } 83 | 84 | if (M5.TP.avaliable()) { 85 | M5.TP.update(); 86 | bool is_finger_up = M5.TP.isFingerUp(); 87 | if (is_finger_up || (_last_pos_x != M5.TP.readFingerX(0)) || (_last_pos_y != M5.TP.readFingerY(0))) { 88 | _last_pos_x = M5.TP.readFingerX(0); 89 | _last_pos_y = M5.TP.readFingerY(0); 90 | if (is_finger_up) { 91 | EPDGUI_Process(); 92 | last_active_time = millis(); 93 | } else { 94 | EPDGUI_Process(M5.TP.readFingerX(0), M5.TP.readFingerY(0)); 95 | last_active_time = 0; 96 | } 97 | } 98 | 99 | 100 | M5.TP.flush(); 101 | } 102 | 103 | if ((last_active_time != 0) && (millis() - last_active_time > 2000)) { 104 | if (M5.EPD.UpdateCount() > 4) { 105 | M5.EPD.ResetUpdateCount(); 106 | if (_is_auto_update) { 107 | M5.EPD.UpdateFull(UPDATE_MODE_GL16); 108 | } 109 | } 110 | last_active_time = 0; 111 | } 112 | } 113 | } 114 | 115 | void EPDGUI_MainLoop(void) { 116 | if ((!frame_stack.empty()) && (frame_stack.top() != NULL)) { 117 | Frame_Base *frame = frame_stack.top(); 118 | log_d("Run %s", frame->GetFrameName().c_str()); 119 | EPDGUI_Clear(); 120 | _is_auto_update = true; 121 | frame->init(frame_map[frame->GetFrameName()].args); 122 | EPDGUI_Run(frame); 123 | } 124 | } 125 | 126 | void EPDGUI_AddFrame(String name, Frame_Base* frame) { 127 | frame_struct_t f; 128 | f.frame = frame; 129 | frame_map.insert(std::pair(name, f)); 130 | } 131 | 132 | void EPDGUI_AddFrameArg(String name, int n, void* arg) { 133 | if (frame_map.count(name) == 0) { 134 | return; 135 | } 136 | if (frame_map[name].args.size() > n) { 137 | frame_map[name].args[n] = arg; 138 | } else { 139 | frame_map[name].args.push_back(arg); 140 | } 141 | log_d("%d", frame_map[name].args.size()); 142 | } 143 | 144 | Frame_Base* EPDGUI_GetFrame(String name) { 145 | if (frame_map.count(name) > 0) { 146 | return frame_map[name].frame; 147 | } 148 | return NULL; 149 | } 150 | 151 | void EPDGUI_PushFrame(Frame_Base* frame) { 152 | frame_stack.push(frame); 153 | } 154 | 155 | void EPDGUI_PopFrame(bool isDelete) { 156 | if (isDelete) { 157 | wait_for_delete = frame_stack.top(); 158 | } 159 | frame_stack.pop(); 160 | } 161 | 162 | void EPDGUI_OverwriteFrame(Frame_Base* frame) { 163 | while (!frame_stack.empty()) { 164 | frame_stack.pop(); 165 | } 166 | frame_stack.push(frame); 167 | } 168 | 169 | void EPDGUI_SetAutoUpdate(bool isAuto) { 170 | _is_auto_update = isAuto; 171 | } 172 | -------------------------------------------------------------------------------- /src/epdgui/epdgui.h: -------------------------------------------------------------------------------- 1 | #ifndef __EPDGUI_H 2 | #define __EPDGUI_H 3 | 4 | #include "epdgui_base.h" 5 | #include "epdgui_button.h" 6 | #include "epdgui_switch.h" 7 | #include "epdgui_keyboard.h" 8 | #include "epdgui_textbox.h" 9 | #include "epdgui_mutexswitch.h" 10 | #include "../frame/frame_base.h" 11 | 12 | void EPDGUI_AddObject(EPDGUI_Base* object); 13 | void EPDGUI_Draw(m5epd_update_mode_t mode = UPDATE_MODE_GC16); 14 | void EPDGUI_Process(void); 15 | void EPDGUI_Process(int16_t x, int16_t y); 16 | void EPDGUI_Clear(void); 17 | void EPDGUI_Run(Frame_Base* frame); 18 | void EPDGUI_MainLoop(void); 19 | void EPDGUI_PushFrame(Frame_Base* frame); 20 | void EPDGUI_PopFrame(bool isDelete = false); 21 | void EPDGUI_OverwriteFrame(Frame_Base* frame); 22 | void EPDGUI_AddFrame(String name, Frame_Base* frame); 23 | void EPDGUI_AddFrameArg(String name, int n, void* arg); 24 | Frame_Base* EPDGUI_GetFrame(String name); 25 | void EPDGUI_SetAutoUpdate(bool isAuto); 26 | 27 | #endif //__EPDGUI_H -------------------------------------------------------------------------------- /src/epdgui/epdgui_base.cpp: -------------------------------------------------------------------------------- 1 | #include "epdgui_base.h" 2 | 3 | EPDGUI_Base::EPDGUI_Base(int16_t x, int16_t y, int16_t w, int16_t h) { 4 | x = (x + 3) & 0xFFFC; 5 | w = (w + 3) & 0xFFFC; 6 | this->_x = x; 7 | this->_y = y; 8 | this->_w = w; 9 | this->_h = h; 10 | _rx = _x + _w; 11 | _by = _y + _h; 12 | } 13 | 14 | EPDGUI_Base::EPDGUI_Base() { 15 | } 16 | 17 | bool EPDGUI_Base::isSelected(void) { 18 | return _issel; 19 | } 20 | 21 | bool EPDGUI_Base::isInBox(int16_t x, int16_t y) { 22 | if (x == -1 || y == -1) { 23 | return false; 24 | } 25 | 26 | if ((x > _x) && (x < _rx) && (y > _y) && (y < _by)) { 27 | _issel = true; 28 | return 1; 29 | } 30 | _issel = false; 31 | return 0; 32 | } 33 | 34 | void EPDGUI_Base::SetHide(bool ishide) { 35 | this->_ishide = ishide; 36 | } 37 | 38 | void EPDGUI_Base::SetEnable(bool isenable) { 39 | this->_isenable = isenable; 40 | } 41 | 42 | void EPDGUI_Base::SetGeometry(int16_t x, int16_t y, int16_t w, int16_t h) { 43 | x = (x + 3) & 0xFFFC; 44 | w = (w + 3) & 0xFFFC; 45 | this->_x = x; 46 | this->_y = y; 47 | this->_w = w; 48 | this->_h = h; 49 | } 50 | 51 | void EPDGUI_Base::SetPos(int16_t x, int16_t y) { 52 | x = (x + 3) & 0xFFFC; 53 | this->_x = x; 54 | this->_y = y; 55 | } 56 | 57 | void EPDGUI_Base::UpdateGram(m5epd_update_mode_t mode) { 58 | M5.EPD.UpdateArea(_x, _y, _w, _h, mode); 59 | } 60 | -------------------------------------------------------------------------------- /src/epdgui/epdgui_base.h: -------------------------------------------------------------------------------- 1 | #ifndef __EPDGUI_BASE_H 2 | #define __EPDGUI_BASE_H 3 | 4 | #include 5 | #include 6 | #include "../global_setting.h" 7 | #include "../resources/ImageResource.h" 8 | 9 | typedef std::vector epdgui_args_vector_t; 10 | 11 | class EPDGUI_Base { 12 | public: 13 | EPDGUI_Base(int16_t x, int16_t y, int16_t w, int16_t h); 14 | EPDGUI_Base(); 15 | virtual ~EPDGUI_Base() {}; 16 | virtual void Draw(m5epd_update_mode_t mode) = 0; 17 | virtual void Bind(int16_t event, void (* func_cb)(epdgui_args_vector_t&)) = 0; 18 | virtual void UpdateState(int16_t x, int16_t y) = 0; 19 | virtual void Draw(M5EPD_Canvas* canvas) = 0; 20 | 21 | bool isInBox(int16_t x, int16_t y); 22 | virtual bool isSelected(void); 23 | void SetHide(bool ishide); 24 | void SetEnable(bool isenable); 25 | void SetGeometry(int16_t x, int16_t y, int16_t w, int16_t h); 26 | void SetPos(int16_t x, int16_t y); 27 | void UpdateGram(m5epd_update_mode_t mode = UPDATE_MODE_DU4); 28 | uint32_t GetID(void) { return _id;} 29 | uint32_t* GetID_P(void) { return &_id;} 30 | void SetID(uint32_t id) { _id = id;} 31 | void SetCustomString(String s) {_user_custom_str = s;} 32 | String GetCustomString(void) {return _user_custom_str;} 33 | 34 | inline int16_t getX() {return _x;} 35 | inline int16_t getY() {return _y;} 36 | inline int16_t getW() {return _w;} 37 | inline int16_t getH() {return _h;} 38 | inline int16_t getRX() {return _rx;} 39 | inline int16_t getBY() {return _by;} 40 | 41 | protected: 42 | String _user_custom_str; 43 | int16_t _x, _y, _w, _h; 44 | int16_t _rx, _by; 45 | uint32_t _id; 46 | bool _issel = false; 47 | bool _ishide = false; 48 | bool _isenable = true; 49 | }; 50 | 51 | 52 | #endif //__EPDGUI_BASE_H -------------------------------------------------------------------------------- /src/epdgui/epdgui_button.cpp: -------------------------------------------------------------------------------- 1 | #include "epdgui_button.h" 2 | 3 | EPDGUI_Button::EPDGUI_Button(int16_t x, int16_t y, int16_t w, int16_t h): 4 | EPDGUI_Base(x, y, w, h) { 5 | this->_CanvasNormal = new M5EPD_Canvas(&M5.EPD); 6 | this->_CanvasPressed = new M5EPD_Canvas(&M5.EPD); 7 | this->_CanvasNormal->createCanvas(_w, _h); 8 | this->_CanvasPressed->createCanvas(_w, _h); 9 | } 10 | 11 | EPDGUI_Button::EPDGUI_Button(String label, int16_t x, int16_t y, int16_t w, int16_t h, uint32_t style): 12 | EPDGUI_Base(x, y, w, h) { 13 | if (style & STYLE_INVISABLE) { 14 | _is_invisable = true; 15 | return; 16 | } 17 | 18 | this->_label = label; 19 | 20 | this->_CanvasNormal = new M5EPD_Canvas(&M5.EPD); 21 | this->_CanvasPressed = new M5EPD_Canvas(&M5.EPD); 22 | 23 | // log_d("[%s] %d, %d", label.c_str(), _x, _y); 24 | 25 | this->_CanvasNormal->createCanvas(_w, _h); 26 | this->_CanvasPressed->createCanvas(_w, _h); 27 | 28 | this->_CanvasNormal->fillCanvas(0); 29 | this->_CanvasNormal->setTextSize(26); 30 | this->_CanvasNormal->setTextColor(15); 31 | 32 | this->_CanvasPressed->fillCanvas(15); 33 | this->_CanvasPressed->setTextSize(26); 34 | this->_CanvasPressed->setTextColor(0); 35 | if (style & STYLE_SOLIDBORDER) { 36 | this->_CanvasNormal->drawRect(0, 0, _w, _h, 15); 37 | } 38 | 39 | if (style & STYLE_ALIGN_LEFT) { 40 | this->_CanvasNormal->setTextDatum(CL_DATUM); 41 | this->_CanvasPressed->setTextDatum(CL_DATUM); 42 | this->_CanvasNormal->drawString(_label, 5, _h / 2 + 3); 43 | this->_CanvasPressed->drawString(_label, 5, _h / 2 + 3); 44 | } else if (style & STYLE_ALIGN_RIGHT) { 45 | this->_CanvasNormal->setTextDatum(CR_DATUM); 46 | this->_CanvasPressed->setTextDatum(CR_DATUM); 47 | this->_CanvasNormal->drawString(_label, _w - 5, _h / 2 + 3); 48 | this->_CanvasPressed->drawString(_label, _w - 5, _h / 2 + 3); 49 | } else if (style & STYLE_ALIGN_CENTER) { 50 | this->_CanvasNormal->setTextDatum(CC_DATUM); 51 | this->_CanvasPressed->setTextDatum(CC_DATUM); 52 | this->_CanvasNormal->drawString(_label, _w / 2, _h / 2 + 3); 53 | this->_CanvasPressed->drawString(_label, _w / 2, _h / 2 + 3); 54 | } 55 | } 56 | 57 | EPDGUI_Button::~EPDGUI_Button() { 58 | delete this->_CanvasNormal; 59 | delete this->_CanvasPressed; 60 | } 61 | 62 | M5EPD_Canvas* EPDGUI_Button::CanvasNormal() { 63 | return this->_CanvasNormal; 64 | } 65 | 66 | M5EPD_Canvas* EPDGUI_Button::CanvasPressed() { 67 | return this->_CanvasPressed; 68 | } 69 | 70 | void EPDGUI_Button::Draw(m5epd_update_mode_t mode) { 71 | if (_ishide || _is_invisable) { 72 | return; 73 | } 74 | 75 | if (_state == EVENT_NONE || _state == EVENT_RELEASED) { 76 | this->_CanvasNormal->pushCanvas(_x, _y, mode); 77 | } else if (_state == EVENT_PRESSED) { 78 | this->_CanvasPressed->pushCanvas(_x, _y, mode); 79 | } 80 | } 81 | 82 | void EPDGUI_Button::Draw(M5EPD_Canvas* canvas) { 83 | if (_ishide) { 84 | return; 85 | } 86 | 87 | if (_state == EVENT_NONE || _state == EVENT_RELEASED) { 88 | _CanvasNormal->pushToCanvas(_x, _y, canvas); 89 | } else if (_state == EVENT_PRESSED) { 90 | _CanvasPressed->pushToCanvas(_x, _y, canvas); 91 | } 92 | } 93 | 94 | void EPDGUI_Button::Bind(int16_t event, void (* func_cb)(epdgui_args_vector_t&)) { 95 | if (event == EVENT_PRESSED) { 96 | _pressed_cb = func_cb; 97 | } else if (event == EVENT_RELEASED) { 98 | _released_cb = func_cb; 99 | } 100 | } 101 | 102 | void EPDGUI_Button::UpdateState(int16_t x, int16_t y) { 103 | if (!_isenable || _ishide) { 104 | return; 105 | } 106 | 107 | bool is_in_area = isInBox(x, y); 108 | 109 | if (is_in_area) { 110 | if (_state == EVENT_NONE) { 111 | _state = EVENT_PRESSED; 112 | // Serial.printf("%s Pressed ", _label.c_str()); 113 | Draw(); 114 | if (_pressed_cb != NULL) { 115 | _pressed_cb(_pressed_cb_args); 116 | } 117 | } 118 | } else { 119 | if (_state == EVENT_PRESSED) { 120 | _state = EVENT_NONE; 121 | Draw(); 122 | if (_released_cb != NULL) { 123 | _released_cb(_released_cb_args); 124 | } 125 | } 126 | } 127 | } 128 | 129 | void EPDGUI_Button::setBMPButton(String label_l, String label_r, const uint8_t *bmp32x32) { 130 | _CanvasNormal->fillCanvas(0); 131 | _CanvasNormal->drawRect(0, 0, _w, _h, 15); 132 | _CanvasNormal->setTextSize(26); 133 | _CanvasNormal->setTextColor(15); 134 | if (label_l.length()) { 135 | _CanvasNormal->setTextDatum(CL_DATUM); 136 | _CanvasNormal->drawString(label_l, 47 + 8, (_h >> 1) + 2); // Default: (_h >> 1) + 5 137 | } 138 | if (label_r.length()) { 139 | _CanvasNormal->setTextDatum(CR_DATUM); 140 | _CanvasNormal->drawString(label_r, _w - 15, (_h >> 1)); // Default: (_h >> 1) + 5 141 | } 142 | _CanvasNormal->pushImage(15, (_h >> 1) - 16, 32, 32, bmp32x32); 143 | *(_CanvasPressed) = *(_CanvasNormal); 144 | _CanvasPressed->ReverseColor(); 145 | } 146 | 147 | void EPDGUI_Button::setLabel(String label) { 148 | _label = label; 149 | this->_CanvasNormal->fillCanvas(0); 150 | this->_CanvasNormal->drawRect(0, 0, _w, _h, 15); 151 | this->_CanvasNormal->setTextSize(26); 152 | this->_CanvasNormal->setTextDatum(CC_DATUM); 153 | this->_CanvasNormal->setTextColor(15); 154 | this->_CanvasNormal->drawString(_label, _w / 2, _h / 2 + 3); 155 | 156 | this->_CanvasPressed->fillCanvas(15); 157 | this->_CanvasPressed->setTextSize(26); 158 | this->_CanvasPressed->setTextDatum(CC_DATUM); 159 | this->_CanvasPressed->setTextColor(0); 160 | this->_CanvasPressed->drawString(_label, _w / 2, _h / 2 + 3); 161 | } 162 | 163 | void EPDGUI_Button::AddArgs(int16_t event, uint16_t n, void* arg) { 164 | if (event == EVENT_PRESSED) { 165 | if (_pressed_cb_args.size() > n) { 166 | _pressed_cb_args[n] = arg; 167 | } else { 168 | _pressed_cb_args.push_back(arg); 169 | } 170 | } else if (event == EVENT_RELEASED) { 171 | if (_released_cb_args.size() > n) { 172 | _released_cb_args[n] = arg; 173 | } else { 174 | _released_cb_args.push_back(arg); 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /src/epdgui/epdgui_button.h: -------------------------------------------------------------------------------- 1 | #ifndef __EPDGUI_BUTTON_H 2 | #define __EPDGUI_BUTTON_H 3 | 4 | #include "epdgui_base.h" 5 | 6 | class EPDGUI_Button: public EPDGUI_Base { 7 | public: 8 | static const int16_t EVENT_NONE = 0; 9 | static const int16_t EVENT_PRESSED = 1; 10 | static const int16_t EVENT_RELEASED = 2; 11 | 12 | static const uint32_t STYLE_BORDERLESS = 0x00000001; 13 | static const uint32_t STYLE_SOLIDBORDER = 0x00000002; 14 | static const uint32_t STYLE_ALIGN_LEFT = 0x00000004; 15 | static const uint32_t STYLE_ALIGN_RIGHT = 0x00000008; 16 | static const uint32_t STYLE_ALIGN_CENTER = 0x00000010; 17 | static const uint32_t STYLE_INVISABLE = 0x00000020; 18 | static const uint32_t STYLE_DEFAULT = STYLE_SOLIDBORDER | STYLE_ALIGN_CENTER; 19 | 20 | public: 21 | EPDGUI_Button(int16_t x, int16_t y, int16_t w, int16_t h); 22 | EPDGUI_Button(String label, int16_t x, int16_t y, int16_t w, int16_t h, uint32_t style = STYLE_DEFAULT); 23 | ~EPDGUI_Button(); 24 | void Draw(m5epd_update_mode_t mode = UPDATE_MODE_DU4); 25 | void Draw(M5EPD_Canvas* canvas); 26 | void Bind(int16_t event, void (* func_cb)(epdgui_args_vector_t&)); 27 | void UpdateState(int16_t x, int16_t y); 28 | void setLabel(String label); 29 | String getLabel(void) {return _label;} 30 | void AddArgs(int16_t event, uint16_t n, void* arg); 31 | void setBMPButton(String label_l, String label_r, const uint8_t *bmp32x32); 32 | 33 | M5EPD_Canvas* CanvasNormal(); 34 | M5EPD_Canvas* CanvasPressed(); 35 | 36 | private: 37 | void (*_pressed_cb)(epdgui_args_vector_t& args) = NULL; 38 | void (*_released_cb)(epdgui_args_vector_t& args) = NULL; 39 | epdgui_args_vector_t _pressed_cb_args; 40 | epdgui_args_vector_t _released_cb_args; 41 | int16_t _state = EVENT_NONE; 42 | String _label; 43 | bool _is_invisable = false; 44 | 45 | public: 46 | M5EPD_Canvas* _CanvasNormal = NULL; 47 | M5EPD_Canvas* _CanvasPressed = NULL; 48 | }; 49 | 50 | 51 | #endif //__EPDGUI_BUTTON_H -------------------------------------------------------------------------------- /src/epdgui/epdgui_keyboard.cpp: -------------------------------------------------------------------------------- 1 | #include "epdgui_keyboard.h" 2 | 3 | static const char* kKeyAlphaMapLowerCase[26] = { 4 | "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", //10 5 | "a", "s", "d", "f", "g", "h", "j", "k", "l", //9 6 | "z", "x", "c", "v", "b", "n", "m", //7 7 | }; 8 | 9 | static const char* kKeyAlphaMapUpperCase[26] = { 10 | "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", //10 11 | "A", "S", "D", "F", "G", "H", "J", "K", "L", //9 12 | "Z", "X", "C", "V", "B", "N", "M", //7 13 | }; 14 | 15 | static const char* kKeyAlphaMapNumber[26] = { 16 | "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", //10 17 | "-", "/", ":", ";", "(", ")", "$", "&", "@", //9 18 | "_", "\"", ".", ",", "?", "!", "'", //7 19 | }; 20 | 21 | static const char* kKeyAlphaMapSymbol[26] = { 22 | "[", "]", "{", "}", "#", "%", "^", "*", "+", "=", //10 23 | "_", "\\", "|", "~", "<", ">", "€", "£", "¥", //9 24 | "•", "✿", "\u221A", "\u221E", "\u2103", "\u2109", "\u2116", //7 25 | }; 26 | 27 | enum { 28 | kKeySpace = 26, 29 | kKeyBackspace, 30 | kKeyWrap, 31 | kKeyCase, 32 | kKeyNumber 33 | }; 34 | 35 | enum { 36 | kSWCase = 0, 37 | kSWNumber 38 | }; 39 | 40 | enum { 41 | kLayoutLowerAlpha = 0, 42 | kLayoutUpperAlpha, 43 | kLayoutNumber, 44 | kLayoutSymbol 45 | }; 46 | 47 | EPDGUI_Keyboard::EPDGUI_Keyboard(uint32_t style): EPDGUI_Base() { 48 | const uint16_t kBaseX = 16; 49 | const uint16_t kBaseY = 700; 50 | const uint16_t kKeyWidth = 44; 51 | const uint16_t kKeyHeight = 52; 52 | const uint16_t kKeyInterval = 8; 53 | const uint16_t kFirstLineY = kBaseY; 54 | const uint16_t kSecondLineY = kBaseY + 64; 55 | const uint16_t kThirdLineY = kSecondLineY + 64; 56 | const uint16_t k4thLineY = kThirdLineY + 64; 57 | 58 | for (int i = 0; i < 10; i++) { 59 | _btn[i] = new EPDGUI_Button(kKeyAlphaMapLowerCase[i], kBaseX + (kKeyInterval + kKeyWidth) * i, kFirstLineY, kKeyWidth, kKeyHeight); 60 | } 61 | for (int i = 10; i < 19; i++) { 62 | _btn[i] = new EPDGUI_Button(kKeyAlphaMapLowerCase[i], kBaseX + 28 + (kKeyInterval + kKeyWidth) * (i - 10), kSecondLineY, kKeyWidth, kKeyHeight); 63 | } 64 | for (int i = 19; i < 26; i++) { 65 | _btn[i] = new EPDGUI_Button(kKeyAlphaMapLowerCase[i], kBaseX + 80 + (kKeyInterval + kKeyWidth) * (i - 19), kThirdLineY, kKeyWidth, kKeyHeight); 66 | } 67 | 68 | _btn[kKeyBackspace] = new EPDGUI_Button("", kBaseX + 512 - 60, kThirdLineY, 60, kKeyHeight); 69 | _btn[kKeyBackspace]->CanvasNormal()->pushImage(_btn[kKeyBackspace]->getW() / 2 - 16, _btn[kKeyBackspace]->getH() / 2 - 16, 32, 32, ImageResource_backspace_32x32); 70 | _btn[kKeyBackspace]->CanvasPressed()->fillCanvas(0); 71 | _btn[kKeyBackspace]->CanvasPressed()->pushImage(_btn[kKeyBackspace]->getW() / 2 - 16, _btn[kKeyBackspace]->getH() / 2 - 16, 32, 32, ImageResource_backspace_32x32); 72 | _btn[kKeyBackspace]->CanvasPressed()->ReverseColor(); 73 | 74 | _btn[kKeySpace] = new EPDGUI_Button("Space", kBaseX + 132, k4thLineY, 244, kKeyHeight); 75 | if (style & STYLE_INPUTMODE_NORMALTEXT) 76 | _btn[kKeyWrap] = new EPDGUI_Button("Wrap", kBaseX + 512 - 128, k4thLineY, 128, kKeyHeight); 77 | else if (style & STYLE_INPUTMODE_NEEDCONFIRM) 78 | _btn[kKeyWrap] = new EPDGUI_Button("Confirm", kBaseX + 512 - 128, k4thLineY, 128, kKeyHeight); 79 | 80 | // function key 81 | _sw[kSWCase] = new EPDGUI_Switch(2, kBaseX, kThirdLineY, 60, kKeyHeight); 82 | _sw[kSWNumber] = new EPDGUI_Switch(2, kBaseX, k4thLineY, 124, kKeyHeight); 83 | 84 | _sw[kSWCase]->Canvas(0)->pushImage(_sw[kSWCase]->getW() / 2 - 16, _sw[kSWCase]->getH() / 2 - 16, 32, 32, ImageResource_upper_32x32); 85 | _sw[kSWCase]->Canvas(1)->pushImage(_sw[kSWCase]->getW() / 2 - 16, _sw[kSWCase]->getH() / 2 - 16, 32, 32, ImageResource_upper_32x32); 86 | _sw[kSWCase]->Canvas(1)->ReverseColor(); 87 | _sw[kSWNumber]->SetLabel(0, "123"); 88 | _sw[kSWNumber]->SetLabel(1, "Abc"); 89 | 90 | for (int i = 0; i < 29; i++) { 91 | _key[i] = _btn[i]; 92 | } 93 | _key[kKeyCase] = _sw[kSWCase]; 94 | _key[kKeyNumber] = _sw[kSWNumber]; 95 | 96 | _layout = kLayoutLowerAlpha; 97 | } 98 | 99 | EPDGUI_Keyboard::~EPDGUI_Keyboard() { 100 | for (int i = 0; i < 29; i++) { 101 | delete _btn[i]; 102 | } 103 | for (int i = 0; i < 2; i++) { 104 | delete _sw[i]; 105 | } 106 | } 107 | 108 | void EPDGUI_Keyboard::Draw(m5epd_update_mode_t mode) { 109 | if (_ishide) { 110 | return; 111 | } 112 | 113 | for (int i = 0; i < 31; i++) { 114 | _key[i]->Draw(mode); 115 | } 116 | } 117 | 118 | void EPDGUI_Keyboard::Draw(M5EPD_Canvas* canvas) { 119 | if (_ishide) { 120 | return; 121 | } 122 | 123 | for (int i = 0; i < 31; i++) { 124 | _key[i]->Draw(canvas); 125 | } 126 | } 127 | 128 | void EPDGUI_Keyboard::Bind(int16_t state, void (* func_cb)(epdgui_args_vector_t&)) { 129 | 130 | } 131 | 132 | void EPDGUI_Keyboard::UpdateState(int16_t x, int16_t y) { 133 | if (!_isenable) { 134 | return; 135 | } 136 | // log_d("UpdateState %d, %d", x, y); 137 | for (int i = 0; i < 31; i++) { 138 | bool keypressed = _key[i]->isInBox(x, y); 139 | _key[i]->UpdateState(x, y); 140 | if (keypressed) { 141 | if (i < 26) { 142 | switch (_layout) { 143 | case kLayoutLowerAlpha: 144 | _data += kKeyAlphaMapLowerCase[i]; 145 | break; 146 | case kLayoutUpperAlpha: 147 | _data += kKeyAlphaMapUpperCase[i]; 148 | break; 149 | case kLayoutNumber: 150 | _data += kKeyAlphaMapNumber[i]; 151 | break; 152 | case kLayoutSymbol: 153 | _data += kKeyAlphaMapSymbol[i]; 154 | break; 155 | } 156 | } 157 | switch (i) { 158 | case kKeyBackspace: 159 | _data += "\u0008"; 160 | break; 161 | case kKeySpace: 162 | _data += " "; 163 | break; 164 | case kKeyWrap: 165 | _data += "\n"; 166 | break; 167 | case kKeyCase: 168 | if (_layout == kLayoutNumber || _layout == kLayoutSymbol) { 169 | if (_sw[kSWCase]->getState() == 1) { 170 | for (int j = 0; j < 26; j++) { 171 | _btn[j]->setLabel(kKeyAlphaMapNumber[j]); 172 | _layout = kLayoutNumber; 173 | } 174 | } else { 175 | for (int j = 0; j < 26; j++) { 176 | _btn[j]->setLabel(kKeyAlphaMapSymbol[j]); 177 | _layout = kLayoutSymbol; 178 | } 179 | } 180 | _sw[kSWCase]->UpdateState(-1, -1); 181 | Draw(UPDATE_MODE_NONE); 182 | M5.EPD.UpdateFull(UPDATE_MODE_GL16); 183 | } else { 184 | if (_sw[kSWCase]->getState() == 1) { 185 | for (int j = 0; j < 26; j++) { 186 | _btn[j]->setLabel(kKeyAlphaMapLowerCase[j]); 187 | _layout = kLayoutLowerAlpha; 188 | } 189 | } else { 190 | for (int j = 0; j < 26; j++) { 191 | _btn[j]->setLabel(kKeyAlphaMapUpperCase[j]); 192 | _layout = kLayoutUpperAlpha; 193 | } 194 | } 195 | _sw[kSWCase]->UpdateState(-1, -1); 196 | Draw(UPDATE_MODE_NONE); 197 | M5.EPD.UpdateFull(UPDATE_MODE_GL16); 198 | } 199 | break; 200 | case kKeyNumber: 201 | if (_sw[kSWNumber]->getState() == 1) { 202 | _sw[kSWCase]->setState(0); 203 | _sw[kSWCase]->Canvas(0)->fillCanvas(0); 204 | _sw[kSWCase]->Canvas(1)->fillCanvas(0); 205 | _sw[kSWCase]->Canvas(0)->drawRect(0, 0, _sw[kSWCase]->getW(), _sw[kSWCase]->getH(), 15); 206 | _sw[kSWCase]->Canvas(1)->drawRect(0, 0, _sw[kSWCase]->getW(), _sw[kSWCase]->getH(), 15); 207 | _sw[kSWCase]->Canvas(0)->pushImage(_sw[kSWCase]->getW() / 2 - 16, _sw[kSWCase]->getH() / 2 - 16, 32, 32, ImageResource_upper_32x32); 208 | _sw[kSWCase]->Canvas(1)->pushImage(_sw[kSWCase]->getW() / 2 - 16, _sw[kSWCase]->getH() / 2 - 16, 32, 32, ImageResource_upper_32x32); 209 | _sw[kSWCase]->Canvas(1)->ReverseColor(); 210 | 211 | for (int j = 0; j < 26; j++) { 212 | _btn[j]->setLabel(kKeyAlphaMapLowerCase[j]); 213 | _layout = kLayoutLowerAlpha; 214 | } 215 | } else { 216 | _sw[kSWCase]->setState(0); 217 | _sw[kSWCase]->SetLabel(0, "#+-"); 218 | _sw[kSWCase]->SetLabel(1, "123"); 219 | 220 | for (int j = 0; j < 26; j++) { 221 | _btn[j]->setLabel(kKeyAlphaMapNumber[j]); 222 | _layout = kLayoutNumber; 223 | } 224 | } 225 | _sw[kSWNumber]->UpdateState(-1, -1); 226 | Draw(UPDATE_MODE_NONE); 227 | M5.EPD.UpdateFull(UPDATE_MODE_GL16); 228 | break; 229 | } 230 | } 231 | } 232 | } 233 | 234 | String EPDGUI_Keyboard::getData(void) { 235 | String data = _data; 236 | _data = ""; 237 | return data; 238 | } -------------------------------------------------------------------------------- /src/epdgui/epdgui_keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef __EPDGUI_KEYBOARD_H 2 | #define __EPDGUI_KEYBOARD_H 3 | 4 | #include "epdgui_button.h" 5 | #include "epdgui_switch.h" 6 | 7 | class EPDGUI_Keyboard: public EPDGUI_Base { 8 | public: 9 | static const uint32_t STYLE_INPUTMODE_NORMALTEXT = 0x00000001; 10 | static const uint32_t STYLE_INPUTMODE_NEEDCONFIRM = 0x00000002; 11 | static const uint32_t STYLE_DEFAULT = STYLE_INPUTMODE_NORMALTEXT; 12 | 13 | public: 14 | EPDGUI_Keyboard(uint32_t style = STYLE_DEFAULT); 15 | ~EPDGUI_Keyboard(); 16 | void Draw(m5epd_update_mode_t mode = UPDATE_MODE_DU4); 17 | void Draw(M5EPD_Canvas* canvas); 18 | void Bind(int16_t event, void (* func_cb)(epdgui_args_vector_t&)); 19 | void UpdateState(int16_t x, int16_t y); 20 | String getData(void); 21 | 22 | private: 23 | EPDGUI_Button *_btn[29]; 24 | EPDGUI_Switch *_sw[2]; 25 | EPDGUI_Base *_key[31]; 26 | String _data; 27 | uint8_t _layout = 0; 28 | 29 | public: 30 | 31 | }; 32 | 33 | 34 | #endif //__EPDGUI_KEYBOARD_H -------------------------------------------------------------------------------- /src/epdgui/epdgui_mutexswitch.cpp: -------------------------------------------------------------------------------- 1 | #include "epdgui_mutexswitch.h" 2 | 3 | EPDGUI_MutexSwitch::EPDGUI_MutexSwitch() { 4 | 5 | } 6 | 7 | void EPDGUI_MutexSwitch::Draw(m5epd_update_mode_t mode) { 8 | if (_ishide) { 9 | return; 10 | } 11 | for (std::list::iterator p = _object_list.begin(); p != _object_list.end(); p++) { 12 | (*p)->Draw(mode); 13 | } 14 | } 15 | 16 | void EPDGUI_MutexSwitch::Draw(M5EPD_Canvas* canvas) { 17 | if (_ishide) { 18 | return; 19 | } 20 | for (std::list::iterator p = _object_list.begin(); p != _object_list.end(); p++) { 21 | (*p)->Draw(canvas); 22 | } 23 | } 24 | 25 | void EPDGUI_MutexSwitch::Bind(int16_t event, void (* func_cb)(epdgui_args_vector_t&)) { 26 | 27 | } 28 | 29 | void EPDGUI_MutexSwitch::UpdateState(int16_t x, int16_t y) { 30 | if (!_isenable) { 31 | return; 32 | } 33 | 34 | std::list::iterator pressed_sw = _object_list.end(); 35 | for (std::list::iterator p = _object_list.begin(); p != _object_list.end(); p++) { 36 | if (_last_pressed == p) { 37 | (*p)->UpdateState(-1, -1); 38 | continue; 39 | } 40 | 41 | if ((*p)->isInBox(x, y)) { 42 | _last_pressed = p; 43 | pressed_sw = p; 44 | } 45 | 46 | (*p)->UpdateState(x, y); 47 | } 48 | 49 | if (!_is_exclusive) { 50 | return; 51 | } 52 | 53 | if (pressed_sw == _object_list.end()) { 54 | return; 55 | } 56 | 57 | for (std::list::iterator p = _object_list.begin(); p != _object_list.end(); p++) { 58 | if (pressed_sw == p) { 59 | continue; 60 | } 61 | 62 | if ((*p)->getState() != 0) { 63 | (*p)->setState(0); 64 | (*p)->Draw(UPDATE_MODE_GL16); 65 | } 66 | } 67 | } 68 | 69 | void EPDGUI_MutexSwitch::SetDefault(uint16_t idx) { 70 | if (idx < _object_list.size()) { 71 | _default_idx = idx; 72 | } 73 | 74 | int i = 0; 75 | for (std::list::iterator p = _object_list.begin(); p != _object_list.end(); p++) { 76 | if (i == _default_idx) { 77 | _last_pressed = p; 78 | (*p)->setState(1); 79 | // (*p)->Draw(UPDATE_MODE_GL16); 80 | } else { 81 | (*p)->setState(0); 82 | // (*p)->Draw(UPDATE_MODE_GL16); 83 | } 84 | i++; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/epdgui/epdgui_mutexswitch.h: -------------------------------------------------------------------------------- 1 | #ifndef _EPDGUI_MUTEXSWITCH_H 2 | #define _EPDGUI_MUTEXSWITCH_H 3 | 4 | #include "epdgui_switch.h" 5 | #include 6 | 7 | class EPDGUI_MutexSwitch : public EPDGUI_Base { 8 | public: 9 | EPDGUI_MutexSwitch(); 10 | 11 | void Draw(m5epd_update_mode_t mode); 12 | void Draw(M5EPD_Canvas* canvas); 13 | void Bind(int16_t event, void (* func_cb)(epdgui_args_vector_t&)); 14 | void UpdateState(int16_t x, int16_t y); 15 | 16 | void Add(EPDGUI_Switch* object) {_object_list.push_back(object);} 17 | void SetExclusive(bool isExclusive) {_is_exclusive = isExclusive;} 18 | void SetDefault(uint16_t idx); 19 | 20 | private: 21 | bool _is_exclusive = true; 22 | uint16_t _default_idx = 0; 23 | std::list _object_list; 24 | std::list::iterator _last_pressed; 25 | }; 26 | 27 | 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /src/epdgui/epdgui_switch.cpp: -------------------------------------------------------------------------------- 1 | #include "epdgui_switch.h" 2 | 3 | EPDGUI_Switch::EPDGUI_Switch(int16_t state_num, int16_t x, int16_t y, int16_t w, int16_t h): 4 | EPDGUI_Base(x, y, w, h) { 5 | if (state_num > EPDGUI_SWITCH_MAX_STATE) { 6 | state_num = EPDGUI_SWITCH_MAX_STATE; 7 | } 8 | this->_state_num = state_num; 9 | 10 | for (int i = 0; i < _state_num; i++) { 11 | this->_canvas[i] = new M5EPD_Canvas(&M5.EPD); 12 | this->_canvas[i]->createCanvas(_w, _h); 13 | // this->_canvas[i]->fillCanvas(i & 0x01 ? 0 : 15); 14 | this->_canvas[i]->setTextSize(26); 15 | this->_canvas[i]->fillCanvas(0); 16 | this->_canvas[i]->drawRect(0, 0, _w, _h, 15); 17 | } 18 | _canvas_pressed = new M5EPD_Canvas(&M5.EPD); 19 | _canvas_pressed->createCanvas(_w, _h); 20 | _canvas_pressed->fillCanvas(15); 21 | } 22 | 23 | EPDGUI_Switch::~EPDGUI_Switch() { 24 | for (int i = 0; i < _state_num; i++) { 25 | delete this->_canvas[i]; 26 | } 27 | } 28 | 29 | M5EPD_Canvas* EPDGUI_Switch::Canvas(int16_t state) { 30 | if (state == -1) { 31 | return _canvas_pressed; 32 | } 33 | return _canvas[state]; 34 | } 35 | 36 | void EPDGUI_Switch::SetLabel(int16_t state, String label) { 37 | if (state > EPDGUI_SWITCH_MAX_STATE || state < 0) { 38 | return; 39 | } 40 | 41 | this->_canvas[state]->fillCanvas(0); 42 | this->_canvas[state]->drawRect(0, 0, _w, _h, 15); 43 | this->_canvas[state]->setTextSize(26); 44 | this->_canvas[state]->setTextDatum(CC_DATUM); 45 | // this->_canvas[state]->setTextColor(state & 0x01 ? 15 : 0); 46 | this->_canvas[state]->setTextColor(15); 47 | this->_canvas[state]->drawString(label, _w / 2, _h / 2 + 5); 48 | this->_label_array[state] = label; 49 | } 50 | 51 | void EPDGUI_Switch::Draw(m5epd_update_mode_t mode) { 52 | if (_ishide) { 53 | return; 54 | } 55 | 56 | if (_event == EVENT_PRESSED) { 57 | _canvas_pressed->pushCanvas(_x, _y, mode); 58 | return; 59 | } 60 | 61 | this->_canvas[_state]->pushCanvas(_x, _y, mode); 62 | } 63 | 64 | void EPDGUI_Switch::Draw(M5EPD_Canvas* canvas) { 65 | if (_ishide) { 66 | return; 67 | } 68 | 69 | if (_event == EVENT_PRESSED) { 70 | _canvas_pressed->pushToCanvas(_x, _y, canvas); 71 | return; 72 | } 73 | 74 | this->_canvas[_state]->pushToCanvas(_x, _y, canvas); 75 | } 76 | 77 | void EPDGUI_Switch::Bind(int16_t state, void (* func_cb)(epdgui_args_vector_t&)) { 78 | if (state > EPDGUI_SWITCH_MAX_STATE || state < 0) { 79 | return; 80 | } 81 | 82 | this->_func_cb_array[state] = func_cb; 83 | } 84 | 85 | void EPDGUI_Switch::UpdateState(int16_t x, int16_t y) { 86 | if (!_isenable || _ishide) { 87 | return; 88 | } 89 | 90 | bool is_in_area = isInBox(x, y); 91 | 92 | if (is_in_area) { 93 | if (_event == EVENT_NONE) { 94 | _event = EVENT_PRESSED; 95 | Draw(); 96 | } 97 | } else { 98 | if (_event == EVENT_PRESSED) { 99 | _event = EVENT_NONE; 100 | _state++; 101 | if (_state == _state_num) { 102 | _state = 0; 103 | } 104 | 105 | Draw(); 106 | if (this->_func_cb_array[_state] != NULL) { 107 | this->_func_cb_array[_state](this->_func_cb_param_array[_state]); 108 | } 109 | } 110 | } 111 | } 112 | 113 | void EPDGUI_Switch::setState(int16_t state) { 114 | if (state >= _state_num || state < 0) { 115 | return; 116 | } 117 | _state = state; 118 | Draw(UPDATE_MODE_NONE); 119 | } 120 | 121 | int16_t EPDGUI_Switch::getState(void) { 122 | return _state; 123 | } 124 | 125 | void EPDGUI_Switch::AddArgs(int16_t state, uint16_t n, void* arg) { 126 | if (state > EPDGUI_SWITCH_MAX_STATE || state < 0) { 127 | return; 128 | } 129 | 130 | if (this->_func_cb_param_array[state].size() > n) { 131 | this->_func_cb_param_array[state][n] = arg; 132 | } else { 133 | this->_func_cb_param_array[state].push_back(arg); 134 | } 135 | } -------------------------------------------------------------------------------- /src/epdgui/epdgui_switch.h: -------------------------------------------------------------------------------- 1 | #ifndef __EPDGUI_SWITCH_H 2 | #define __EPDGUI_SWITCH_H 3 | 4 | #include "epdgui_base.h" 5 | 6 | #define EPDGUI_SWITCH_MAX_STATE 5 7 | 8 | class EPDGUI_Switch: public EPDGUI_Base { 9 | public: 10 | static const int16_t EVENT_NONE = 0; 11 | static const int16_t EVENT_PRESSED = 1; 12 | static const int16_t EVENT_RELEASED = 2; 13 | 14 | 15 | public: 16 | EPDGUI_Switch(int16_t state_num, int16_t x, int16_t y, int16_t w, int16_t h); 17 | ~EPDGUI_Switch(); 18 | void Draw(m5epd_update_mode_t mode = UPDATE_MODE_DU4); 19 | void Draw(M5EPD_Canvas* canvas); 20 | void Bind(int16_t state, void (* func_cb)(epdgui_args_vector_t&)); 21 | void UpdateState(int16_t x, int16_t y); 22 | void AddArgs(int16_t state, uint16_t n, void* arg); 23 | 24 | int16_t getState(void); 25 | void setState(int16_t state); 26 | void SetLabel(int16_t state, String label); 27 | M5EPD_Canvas* Canvas(int16_t state); 28 | 29 | private: 30 | int16_t _state_num; 31 | void (*_func_cb_array[EPDGUI_SWITCH_MAX_STATE])(epdgui_args_vector_t &args) = {NULL}; 32 | epdgui_args_vector_t _func_cb_param_array[EPDGUI_SWITCH_MAX_STATE]; 33 | int16_t _state = 0; 34 | int16_t _event = EVENT_NONE; 35 | String _label_array[EPDGUI_SWITCH_MAX_STATE]; 36 | 37 | public: 38 | M5EPD_Canvas* _canvas[EPDGUI_SWITCH_MAX_STATE] = {NULL}; 39 | M5EPD_Canvas* _canvas_pressed = NULL; 40 | }; 41 | 42 | 43 | #endif //__EPDGUI_BUTTON_H -------------------------------------------------------------------------------- /src/epdgui/epdgui_textbox.cpp: -------------------------------------------------------------------------------- 1 | #include "epdgui_textbox.h" 2 | 3 | uint32_t EPDGUI_Textbox::_textbox_touching_id = 0; 4 | 5 | EPDGUI_Textbox::EPDGUI_Textbox(int16_t x, int16_t y, int16_t w, int16_t h) : EPDGUI_Base(x, y, w, h) { 6 | _canvas = new M5EPD_Canvas(&M5.EPD); 7 | 8 | _size = 26; 9 | _thiscreat = false; 10 | 11 | _canvas->createCanvas(_w, _h); 12 | 13 | _canvas->fillCanvas(15); 14 | _canvas->drawRect(0, 0, _w, _h, 15); 15 | if (!_canvas->isRenderExist(_size)) { 16 | _canvas->createRender(_size, 60); 17 | _thiscreat = true; 18 | } 19 | _canvas->setTextSize(_size); 20 | 21 | _canvas->setTextDatum(TL_DATUM); 22 | _canvas->setTextColor(15); 23 | 24 | for (int i = 0; i < 26; i++) { 25 | _canvas->preRender('a' + i); 26 | _canvas->preRender('A' + i); 27 | } 28 | 29 | _margin_left = 8; 30 | _margin_right = 8; 31 | _margin_top = 8; 32 | _margin_bottom = 8; 33 | 34 | _state = EVENT_NONE; 35 | } 36 | 37 | EPDGUI_Textbox::~EPDGUI_Textbox() { 38 | delete _canvas; 39 | } 40 | 41 | void EPDGUI_Textbox::SetTextMargin(int16_t left, int16_t top, int16_t right, int16_t bottom) { 42 | _margin_left = left; 43 | _margin_top = top; 44 | _margin_right = right + left; 45 | _margin_bottom = bottom + top; 46 | } 47 | 48 | void EPDGUI_Textbox::SetTextSize(uint16_t size) { 49 | if (_thiscreat) { 50 | _canvas->destoryRender(_size); 51 | } 52 | _size = size; 53 | if (!_canvas->isRenderExist(_size)) { 54 | _canvas->createRender(_size, 60); 55 | _thiscreat = true; 56 | } else { 57 | _thiscreat = false; 58 | } 59 | 60 | _canvas->setTextSize(_size); 61 | for (int i = 0; i < 26; i++) { 62 | _canvas->preRender('a' + i); 63 | _canvas->preRender('A' + i); 64 | } 65 | Draw(UPDATE_MODE_GC16); 66 | } 67 | 68 | void EPDGUI_Textbox::Draw(m5epd_update_mode_t mode) { 69 | if (_ishide) { 70 | return; 71 | } 72 | 73 | if (_state == EVENT_NONE) { 74 | _canvas->setTextSize(_size); 75 | _canvas->fillCanvas(0); 76 | _canvas->drawRect(0, 0, _w, _h, 15); 77 | _canvas->setTextArea(_margin_left, _margin_top, _w - _margin_right, _h - _margin_bottom); 78 | _canvas->print(_data); 79 | _canvas->pushCanvas(_x, _y, mode); 80 | } else { 81 | _canvas->setTextSize(_size); 82 | _canvas->fillCanvas(0); 83 | _canvas->drawRect(0, 0, _w, _h, 15); 84 | _canvas->drawRect(1, 1, _w - 2, _h - 2, 15); 85 | _canvas->drawRect(2, 2, _w - 4, _h - 4, 15); 86 | _canvas->setTextArea(_margin_left, _margin_top, _w - _margin_right, _h - _margin_bottom); 87 | _canvas->print(_data); 88 | _canvas->pushCanvas(_x, _y, mode); 89 | } 90 | } 91 | 92 | void EPDGUI_Textbox::Draw(M5EPD_Canvas* canvas) { 93 | if (_ishide) { 94 | return; 95 | } 96 | 97 | if (_state == EVENT_NONE) { 98 | _canvas->setTextSize(_size); 99 | _canvas->fillCanvas(0); 100 | _canvas->drawRect(0, 0, _w, _h, 15); 101 | _canvas->setTextArea(_margin_left, _margin_top, _w - _margin_right, _h - _margin_bottom); 102 | _canvas->print(_data); 103 | _canvas->pushToCanvas(_x, _y, canvas); 104 | } else { 105 | _canvas->setTextSize(_size); 106 | _canvas->fillCanvas(0); 107 | _canvas->drawRect(0, 0, _w, _h, 15); 108 | _canvas->drawRect(1, 1, _w - 2, _h - 2, 15); 109 | _canvas->drawRect(2, 2, _w - 4, _h - 4, 15); 110 | _canvas->setTextArea(_margin_left, _margin_top, _w - _margin_right, _h - _margin_bottom); 111 | _canvas->print(_data); 112 | _canvas->pushToCanvas(_x, _y, canvas); 113 | } 114 | } 115 | 116 | void EPDGUI_Textbox::Bind(int16_t event, void (*func_cb)(epdgui_args_vector_t &)) { 117 | } 118 | 119 | void EPDGUI_Textbox::UpdateState(int16_t x, int16_t y) { 120 | if (!_isenable) { 121 | return; 122 | } 123 | 124 | int16_t state = _state; 125 | if ((_state == EVENT_PRESSED) && (_textbox_touching_id != _id)) { 126 | state = EVENT_NONE; 127 | } 128 | 129 | if (isInBox(x, y)) { 130 | _textbox_touching_id = _id; 131 | state = EVENT_PRESSED; 132 | } 133 | 134 | SetState(state); 135 | } 136 | 137 | void EPDGUI_Textbox::SetState(int16_t state) { 138 | if (state != _state) { 139 | if (state == EVENT_PRESSED) { 140 | _textbox_touching_id = _id; 141 | } 142 | _state = state; 143 | } 144 | } 145 | 146 | void EPDGUI_Textbox::SetText(String text) { 147 | if (text != _data) { 148 | _data = text; 149 | Draw(UPDATE_MODE_A2); 150 | } 151 | } 152 | 153 | void EPDGUI_Textbox::Remove(int16_t idx) { 154 | uint16_t n = 0, last_n = 0; 155 | uint8_t* buf = (uint8_t *)_data.c_str(); 156 | uint16_t len = strlen((char*)buf); 157 | uint16_t cnt = 0; 158 | while (n < len) { 159 | last_n = n; 160 | _canvas->decodeUTF8(buf, &n, len - n); 161 | if (cnt == idx) { 162 | _data.remove(last_n, n - last_n); 163 | return; 164 | } 165 | cnt++; 166 | } 167 | if (idx == -1) { 168 | _data.remove(last_n, n - last_n); 169 | } 170 | } 171 | 172 | void EPDGUI_Textbox::AddText(String text) { 173 | if (text.length() == 0) { 174 | return; 175 | } 176 | 177 | uint8_t* buf = (uint8_t *)text.c_str(); 178 | uint16_t len = strlen((char*)buf); 179 | uint16_t n = 0, last_n = 0; 180 | 181 | while (n < len) { 182 | last_n = n; 183 | uint16_t uniCode = _canvas->decodeUTF8(buf, &n, len - n); 184 | if (uniCode == 0x0008) { 185 | Remove(-1); 186 | } else { 187 | _data += text.substring(last_n, n); 188 | } 189 | } 190 | 191 | Draw(UPDATE_MODE_A2); 192 | } 193 | -------------------------------------------------------------------------------- /src/epdgui/epdgui_textbox.h: -------------------------------------------------------------------------------- 1 | #ifndef __EPDGUI_TEXTBOX_H 2 | #define __EPDGUI_TEXTBOX_H 3 | 4 | #include "epdgui_base.h" 5 | 6 | class EPDGUI_Textbox : public EPDGUI_Base { 7 | public: 8 | static const int16_t EVENT_NONE = 0; 9 | static const int16_t EVENT_PRESSED = 1; 10 | 11 | public: 12 | EPDGUI_Textbox(int16_t x, int16_t y, int16_t w, int16_t h); 13 | ~EPDGUI_Textbox(); 14 | void Draw(m5epd_update_mode_t mode = UPDATE_MODE_DU4); 15 | void Draw(M5EPD_Canvas* canvas); 16 | void Bind(int16_t event, void (*func_cb)(epdgui_args_vector_t &)); 17 | void UpdateState(int16_t x, int16_t y); 18 | void SetState(int16_t state); 19 | void SetText(String text); 20 | String GetText(void) {return _data;} 21 | void AddText(String text); 22 | void Remove(int16_t idx); 23 | void SetTextSize(uint16_t size); 24 | bool isSelected(void) {return _state;} 25 | void SetTextMargin(int16_t left, int16_t top, int16_t right, int16_t bottom); 26 | 27 | private: 28 | M5EPD_Canvas *_canvas = NULL; 29 | String _data; 30 | uint16_t _size; 31 | bool _thiscreat; 32 | int16_t _state; 33 | int16_t _margin_left, _margin_right, _margin_top, _margin_bottom; 34 | static uint32_t _textbox_touching_id; 35 | 36 | public: 37 | }; 38 | 39 | #endif //__EPDGUI_KEYBOARD_H -------------------------------------------------------------------------------- /src/frame/frame.cpp: -------------------------------------------------------------------------------- 1 | #include "frame.h" -------------------------------------------------------------------------------- /src/frame/frame.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_H_ 2 | #define _FRAME_H_ 3 | 4 | #include "frame_main.h" 5 | #include "frame_settings.h" 6 | #include "frame_settings_wifi.h" 7 | #include "frame_settings_wallpaper.h" 8 | #include "frame_keyboard.h" 9 | #include "frame_factorytest.h" 10 | #include "frame_settings_wifi_password.h" 11 | #include "frame_lifegame.h" 12 | #include "frame_fileindex.h" 13 | #include "frame_txtreader.h" 14 | #include "frame_compare.h" 15 | #include "frame_pictureviewer.h" 16 | #include "frame_home.h" 17 | 18 | #endif // _FRAME_H_ -------------------------------------------------------------------------------- /src/frame/frame_base.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_base.h" 2 | #include "../epdgui/epdgui.h" 3 | 4 | Frame_Base::Frame_Base(bool _has_title) { 5 | if (_has_title) { 6 | _canvas_title = new M5EPD_Canvas(&M5.EPD); 7 | _canvas_title->createCanvas(540, 64); 8 | _canvas_title->drawFastHLine(0, 64, 540, 15); 9 | _canvas_title->drawFastHLine(0, 63, 540, 15); 10 | _canvas_title->drawFastHLine(0, 62, 540, 15); 11 | _canvas_title->setTextSize(26); 12 | _canvas_title->setTextDatum(CC_DATUM); 13 | } 14 | _frame_id = 0; 15 | _frame_name = "Frame_Base"; 16 | } 17 | 18 | Frame_Base::~Frame_Base() { 19 | if (_key_exit != NULL) 20 | delete _key_exit; 21 | if (_canvas_title != NULL) 22 | delete _canvas_title; 23 | } 24 | 25 | void Frame_Base::exitbtn(String title, uint16_t width) { 26 | _key_exit = new EPDGUI_Button(8, 12, width, 48); 27 | _key_exit->CanvasNormal()->fillCanvas(0); 28 | _key_exit->CanvasNormal()->setTextSize(26); 29 | _key_exit->CanvasNormal()->setTextDatum(CL_DATUM); 30 | _key_exit->CanvasNormal()->setTextColor(15); 31 | _key_exit->CanvasNormal()->drawString(title, 47 + 13, 28); 32 | _key_exit->CanvasNormal()->pushImage(15, 8, 32, 32, ImageResource_item_icon_arrow_l_32x32); 33 | *(_key_exit->CanvasPressed()) = *(_key_exit->CanvasNormal()); 34 | _key_exit->CanvasPressed()->ReverseColor(); 35 | } 36 | 37 | int Frame_Base::run(void) { 38 | return _is_run; 39 | } 40 | 41 | void Frame_Base::exit(void) { 42 | } 43 | 44 | void Frame_Base::exit_cb(epdgui_args_vector_t &args) { 45 | EPDGUI_PopFrame(); 46 | *((int*)(args[0])) = 0; 47 | } -------------------------------------------------------------------------------- /src/frame/frame_base.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_BASE_H_ 2 | #define _FRAME_BASE_H_ 3 | 4 | #include 5 | #include "../epdgui/epdgui_button.h" 6 | #include "../global_setting.h" 7 | #include "../resources/ImageResource.h" 8 | 9 | class Frame_Base { 10 | public: 11 | Frame_Base(bool _has_title = true); 12 | void exitbtn(String title, uint16_t width = 180); 13 | virtual ~Frame_Base(); 14 | virtual int run(); 15 | virtual void exit(); 16 | virtual int init(epdgui_args_vector_t &args) = 0; 17 | String GetFrameName() {return _frame_name;} 18 | int isRun() {return _is_run;} 19 | void SetFrameID(uint32_t id) {_frame_id = id;} 20 | uint32_t GetFrameID() {return _frame_id;} 21 | protected: 22 | static void exit_cb(epdgui_args_vector_t &args); 23 | String _frame_name; 24 | int _is_run = 1; 25 | M5EPD_Canvas *_canvas_title = NULL; 26 | EPDGUI_Button *_key_exit = NULL; 27 | uint32_t _frame_id; 28 | }; 29 | 30 | 31 | 32 | #endif -------------------------------------------------------------------------------- /src/frame/frame_compare.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_compare.h" 2 | 3 | void UpdateCompareCanvasDraw(uint8_t mode, M5EPD_Canvas *update_canvas) { 4 | update_canvas->fillCanvas(0); 5 | for (int i = 0; i < 16; i++) { 6 | update_canvas->fillRect(i * 27, 0, 27, 50, i); 7 | } 8 | switch (mode) { 9 | case UPDATE_MODE_INIT : { 10 | update_canvas->drawString("Display initialization", 8, 60); 11 | break; 12 | } 13 | case UPDATE_MODE_DU : { 14 | update_canvas->drawString("Monochrome menu, text input ", 8, 60); 15 | break; 16 | } 17 | case UPDATE_MODE_GC16 : { 18 | update_canvas->drawString("High quality images", 8, 60); 19 | break; 20 | } 21 | case UPDATE_MODE_GL16 : { 22 | update_canvas->drawString("Text with white background", 8, 60); 23 | break; 24 | } 25 | case UPDATE_MODE_GLR16: { 26 | update_canvas->drawString("Text with white background", 8, 60); 27 | break; 28 | } 29 | case UPDATE_MODE_GLD16: { 30 | update_canvas->drawString("Graphics with white background", 8, 60); 31 | break; 32 | } 33 | case UPDATE_MODE_DU4 : { 34 | update_canvas->drawString("Fast page flipping", 8, 60); 35 | break; 36 | } 37 | case UPDATE_MODE_A2 : { 38 | update_canvas->drawString("Anti-aliased text in menus", 8, 60); 39 | break; 40 | } 41 | } 42 | update_canvas->drawRect(0, 0, 432, 100, 15); 43 | } 44 | 45 | void key_update_mode_cb(epdgui_args_vector_t &args) { 46 | EPDGUI_Button *btn = (EPDGUI_Button*)(args[0]); 47 | M5EPD_Canvas *canvas = (M5EPD_Canvas*)(args[1]); 48 | M5EPD_Canvas *canvas_time = (M5EPD_Canvas*)(args[2]); 49 | int mode = btn->GetCustomString().toInt(); 50 | UpdateCompareCanvasDraw(mode, canvas); 51 | canvas_time->fillCanvas(0); 52 | uint32_t time = millis(); 53 | canvas->pushCanvas(104, 168 + (mode-1) * 108, (m5epd_update_mode_t)mode); 54 | M5.EPD.CheckAFSR(); 55 | char buf[30]; 56 | sprintf(buf, "%lu ms", millis() - time); 57 | canvas_time->drawString(buf, 200, 15); 58 | canvas_time->pushCanvas(330, 925, UPDATE_MODE_GL16); 59 | } 60 | 61 | void key_update_reset_cb(epdgui_args_vector_t &args) { 62 | M5.EPD.FillPartGram4bpp(104, 168, 432, 748, 0xFFFF); 63 | M5.EPD.UpdateArea(104, 168, 432, 748, UPDATE_MODE_INIT); 64 | } 65 | 66 | Frame_Compare::Frame_Compare(void) { 67 | _frame_name = "Frame_Compare"; 68 | 69 | _canvas_time = new M5EPD_Canvas(&M5.EPD); 70 | _canvas = new M5EPD_Canvas(&M5.EPD); 71 | _canvas->createCanvas(432, 100); 72 | _canvas_time->createCanvas(200, 30); 73 | _canvas->setTextSize(26); 74 | _canvas_time->setTextSize(26); 75 | _canvas_time->setTextDatum(CR_DATUM); 76 | 77 | exitbtn("Home"); 78 | _canvas_title->drawString("Compare", 270, 34); 79 | _key_updatemode[UPDATE_MODE_INIT] = new EPDGUI_Button("Reset all", 4, 88, 532, 60); 80 | 81 | _key_updatemode[UPDATE_MODE_INIT]->Bind(EPDGUI_Button::EVENT_RELEASED, key_update_reset_cb); 82 | 83 | for (int i = 1; i < 8; i++) { 84 | _key_updatemode[i] = new EPDGUI_Button(0, 168 + (i-1) * 108, 100, 100); 85 | char buf[10]; 86 | sprintf(buf, "%d", i); 87 | _key_updatemode[i]->SetCustomString(buf); 88 | _key_updatemode[i]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, _key_updatemode[i]); 89 | _key_updatemode[i]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, _canvas); 90 | _key_updatemode[i]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 2, _canvas_time); 91 | _key_updatemode[i]->Bind(EPDGUI_Button::EVENT_RELEASED, key_update_mode_cb); 92 | } 93 | 94 | _key_updatemode[UPDATE_MODE_DU ]->setLabel("DU"); 95 | _key_updatemode[UPDATE_MODE_GC16 ]->setLabel("GC16"); 96 | _key_updatemode[UPDATE_MODE_GL16 ]->setLabel("GL16"); 97 | _key_updatemode[UPDATE_MODE_GLR16]->setLabel("GLR16"); 98 | _key_updatemode[UPDATE_MODE_GLD16]->setLabel("GLD16"); 99 | _key_updatemode[UPDATE_MODE_DU4 ]->setLabel("DU4"); 100 | _key_updatemode[UPDATE_MODE_A2 ]->setLabel("A2"); 101 | 102 | _key_exit->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 103 | _key_exit->Bind(EPDGUI_Button::EVENT_RELEASED, &Frame_Base::exit_cb); 104 | } 105 | 106 | Frame_Compare::~Frame_Compare(void) { 107 | for (int i = 0; i < 8; i++) { 108 | delete _key_updatemode[i]; 109 | } 110 | delete _canvas; 111 | } 112 | 113 | int Frame_Compare::run() { 114 | switch (_update_flag) { 115 | case 1: { 116 | _update_flag = 0; 117 | for (int i = 1; i < 8; i++) { 118 | UpdateCompareCanvasDraw(i, _canvas); 119 | _canvas->pushCanvas(104, 168 + (i-1) * 108, (m5epd_update_mode_t)i); 120 | } 121 | break; 122 | } 123 | } 124 | return 1; 125 | } 126 | 127 | int Frame_Compare::init(epdgui_args_vector_t &args) { 128 | _is_run = 1; 129 | _update_flag = 1; 130 | M5.EPD.Clear(); 131 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 132 | EPDGUI_AddObject(_key_exit); 133 | for (int i = 0; i < 8; i++) { 134 | EPDGUI_AddObject(_key_updatemode[i]); 135 | } 136 | EPDGUI_SetAutoUpdate(false); 137 | return 3; 138 | } -------------------------------------------------------------------------------- /src/frame/frame_compare.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_COMPARE_H_ 2 | #define _FRAME_COMPARE_H_ 3 | 4 | #include "frame_base.h" 5 | #include "../epdgui/epdgui.h" 6 | 7 | class Frame_Compare : public Frame_Base { 8 | public: 9 | Frame_Compare(); 10 | ~Frame_Compare(); 11 | int init(epdgui_args_vector_t &args); 12 | int run(); 13 | 14 | private: 15 | EPDGUI_Button *_key_updatemode[8]; 16 | uint8_t _update_flag; 17 | M5EPD_Canvas *_canvas; 18 | M5EPD_Canvas *_canvas_time; 19 | }; 20 | 21 | #endif //_FRAME_COMPARE_H_ -------------------------------------------------------------------------------- /src/frame/frame_factorytest.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_factorytest.h" 2 | #include "WiFi.h" 3 | 4 | #define POS_LX (15) 5 | #define POS_RX (240 - 15) 6 | 7 | const uint8_t kPins[6] = {32, 25, 33, 26, 19, 18}; 8 | 9 | void frame_factorytest_exit_cb(epdgui_args_vector_t &args) { 10 | EPDGUI_PopFrame(); 11 | *((int *)(args[0])) = 0; 12 | } 13 | 14 | Frame_FactoryTest::Frame_FactoryTest(void) { 15 | //TODO: Voltage WiFi Psram touch pos 16 | _frame_name = "Frame_FactoryTest"; 17 | 18 | _canvas_base = new M5EPD_Canvas(&M5.EPD); 19 | _canvas_data = new M5EPD_Canvas(&M5.EPD); 20 | _canvas_pos = new M5EPD_Canvas(&M5.EPD); 21 | _canvas_btn = new M5EPD_Canvas(&M5.EPD); 22 | _canvas_pass = new M5EPD_Canvas(&M5.EPD); 23 | 24 | _canvas_base->createCanvas(300, 600); 25 | _canvas_data->createCanvas(240, 480); 26 | _canvas_pos->createCanvas(240, 60); 27 | _canvas_btn->createCanvas(240, 60); 28 | _canvas_pass->createCanvas(150, 32); 29 | 30 | _canvas_base->setTextSize(26); 31 | _canvas_data->setTextSize(26); 32 | _canvas_pos->setTextSize(26); 33 | _canvas_btn->setTextSize(26); 34 | _canvas_pass->setTextSize(26); 35 | 36 | _canvas_base->setTextDatum(CL_DATUM); 37 | _canvas_data->setTextDatum(CR_DATUM); 38 | _canvas_pos->setTextDatum(CR_DATUM); 39 | _canvas_btn->setTextDatum(CR_DATUM); 40 | _canvas_pass->setTextDatum(CR_DATUM); 41 | 42 | exitbtn("Home"); 43 | _canvas_title->drawString("Factory Test", 270, 34); 44 | 45 | _key_exit->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void *)(&_is_run)); 46 | _key_exit->Bind(EPDGUI_Button::EVENT_RELEASED, &Frame_Base::exit_cb); 47 | 48 | for (int i = 0; i < 6; i++) { 49 | pinMode(kPins[i], OUTPUT); 50 | digitalWrite(kPins[i], HIGH); 51 | } 52 | M5.SHT30.Begin(); 53 | M5.RTC.begin(); 54 | 55 | rtc_time_t time_struct; 56 | rtc_date_t date_struct; 57 | M5.RTC.getTime(&time_struct); 58 | M5.RTC.getDate(&date_struct); 59 | 60 | if ((isTimeSynced() == 0) || (date_struct.year < 2010)) { 61 | rtc_time_t time_struct; 62 | time_struct.hour = 23; 63 | time_struct.min = 33; 64 | time_struct.sec = 33; 65 | M5.RTC.setTime(&time_struct); 66 | rtc_date_t date_struct; 67 | date_struct.week = 4; 68 | date_struct.mon = 9; 69 | date_struct.day = 24; 70 | date_struct.year = 2020; 71 | M5.RTC.setDate(&date_struct); 72 | } 73 | 74 | _time = 0; 75 | _btn = 0; 76 | _psram_success = false; 77 | _isfirst = true; 78 | _pass_flag = 0; 79 | _pass_flag |= GetInitStatus(0) ? 0x0080 : 0; 80 | } 81 | 82 | Frame_FactoryTest::~Frame_FactoryTest(void) { 83 | delete _canvas_base; 84 | delete _canvas_data; 85 | delete _canvas_pos; 86 | delete _canvas_btn; 87 | delete _canvas_pass; 88 | } 89 | 90 | void Frame_FactoryTest::drawItem(uint16_t flag, const char* str, int y) { 91 | String prefix_pass("[PASS] "); 92 | String prefix_none(""); 93 | if (_pass_flag & flag) { 94 | _canvas_base->drawString(prefix_pass + str, POS_LX, y); 95 | } else { 96 | _canvas_base->drawString(str, POS_LX, y); 97 | _canvas_base->ReversePartColor(0, y - 30, 300, 60); 98 | } 99 | } 100 | 101 | void Frame_FactoryTest::drawItem(m5epd_update_mode_t mode) { 102 | 103 | _canvas_base->fillCanvas(0); 104 | drawItem(0x0001, "1.Date", 30); 105 | drawItem(0x0002, "2.Time", 90); 106 | drawItem(0x0004, "3.Temperature", 150); 107 | drawItem(0x0008, "4.Humidity", 210); 108 | drawItem(0x0010, "5.Battery", 270); 109 | drawItem(0x0020, "6.Wi-Fi", 330); 110 | drawItem(0x0040, "7.PSRAM", 390); 111 | drawItem(0x0080, "8.SD Card", 450); 112 | drawItem(0x0100, "9.Button", 510); 113 | drawItem(0x0200, "10.TouchPad", 570); 114 | _canvas_base->pushCanvas(0, 100, mode); 115 | } 116 | 117 | void Frame_FactoryTest::drawGrove(m5epd_update_mode_t mode) { 118 | M5.EPD.WritePartGram4bpp(428, 916, 100, 40, (_pass_flag & 0x0400) ? ImageResource_factory_pass_h_100x40 : ImageResource_factory_port_a_100x40); 119 | M5.EPD.WritePartGram4bpp(4, 848, 40, 100, (_pass_flag & 0x0800) ? ImageResource_factory_pass_v_40x100 : ImageResource_factory_port_b_40x100); 120 | M5.EPD.WritePartGram4bpp(4, 720, 40, 100, (_pass_flag & 0x1000) ? ImageResource_factory_pass_v_40x100 : ImageResource_factory_port_c_40x100); 121 | M5.EPD.UpdateArea(0, 720, 540, 240, mode); 122 | } 123 | 124 | bool Frame_FactoryTest::checkGrove(int sda, int scl) { 125 | Wire1.begin(sda, scl, 10000); 126 | bool groveCheck = true; 127 | 128 | Wire1.beginTransmission(0x76); 129 | Wire1.write(0xD0); 130 | if (Wire1.endTransmission() != 0) { 131 | groveCheck = false; 132 | } else { 133 | Wire1.requestFrom(0x76, 1); 134 | uint8_t chipID = Wire1.read(); 135 | if (chipID != 0x58) { 136 | groveCheck = false; 137 | } 138 | } 139 | 140 | return groveCheck; 141 | } 142 | 143 | void Frame_FactoryTest::drawPassCount(m5epd_update_mode_t mode) { 144 | uint16_t x = _pass_flag, n = 0; 145 | for (; x; x >>= 1) 146 | n += x & 1; 147 | char buf[20]; 148 | sprintf(buf, "PASS %d/13", n); 149 | _canvas_pass->fillCanvas(0); 150 | _canvas_pass->drawString(buf, 150, 14); 151 | _canvas_pass->pushCanvas(375, 28, mode); 152 | } 153 | 154 | void Frame_FactoryTest::scan(String *ssid, int32_t *rssi) { 155 | WiFi.mode(WIFI_STA); 156 | // WiFi.disconnect(); 157 | WiFi.scanNetworks(true); 158 | 159 | int wifi_num; 160 | while (true) { 161 | wifi_num = WiFi.scanComplete(); 162 | if (wifi_num >= 0) { 163 | break; 164 | } 165 | } 166 | 167 | *ssid = WiFi.SSID(0); 168 | *rssi = WiFi.RSSI(0); 169 | WiFi.scanDelete(); 170 | } 171 | 172 | int Frame_FactoryTest::run() { 173 | uint16_t pass_flag = _pass_flag; 174 | char buf[100]; 175 | // POS 176 | if ((M5.TP.readFingerX(0) != _last_x) || (M5.TP.readFingerY(0) != _last_y)) { 177 | pass_flag |= 0x0200; 178 | _last_x = M5.TP.readFingerX(0); 179 | _last_y = M5.TP.readFingerY(0); 180 | sprintf(buf, "X %d, Y %d", _last_x, _last_y); 181 | _canvas_pos->fillCanvas(0); 182 | _canvas_pos->drawString(buf, POS_RX, 30); 183 | _canvas_pos->pushCanvas(300, 640, UPDATE_MODE_A2); 184 | } 185 | 186 | // BTN 187 | M5.update(); 188 | int ptr = 0; 189 | bool ispressed = false; 190 | if (_btn == 0x07) { 191 | _btn |= 0x08; 192 | pass_flag |= 0x0100; 193 | } 194 | if (M5.BtnL.isPressed()) { 195 | _btn |= 0x01; 196 | buf[ptr++] = 'L'; 197 | ispressed = true; 198 | } 199 | if (M5.BtnP.isPressed()) { 200 | _btn |= 0x02; 201 | buf[ptr++] = 'P'; 202 | ispressed = true; 203 | } 204 | if (M5.BtnR.isPressed()) { 205 | _btn |= 0x04; 206 | buf[ptr++] = 'R'; 207 | ispressed = true; 208 | } 209 | buf[ptr] = '\0'; 210 | if (ptr == 0) { 211 | strcpy(buf, "Waiting..."); 212 | } 213 | if (ispressed) { 214 | _canvas_btn->fillCanvas(0); 215 | _canvas_btn->drawString(buf, POS_RX, 30); 216 | _canvas_btn->pushCanvas(300, 580, UPDATE_MODE_A2); 217 | } 218 | 219 | if (millis() - _time > 1000) { 220 | _time = millis(); 221 | rtc_time_t time_struct; 222 | rtc_date_t date_struct; 223 | M5.RTC.getTime(&time_struct); 224 | M5.RTC.getDate(&date_struct); 225 | 226 | if ((date_struct.year > 2010) && (time_struct.hour <= 24) && (time_struct.min <= 60) && (time_struct.sec <= 60)) { 227 | pass_flag |= 0x01; 228 | } 229 | if (_prev_sec == 255) { 230 | _prev_sec = time_struct.sec; 231 | } 232 | if (time_struct.sec != _prev_sec) { 233 | pass_flag |= 0x02; 234 | } 235 | 236 | _canvas_data->fillCanvas(0); 237 | _canvas_data->setTextSize(26); 238 | 239 | // RTC 240 | sprintf(buf, "%04d - %02d - %02d", date_struct.year, date_struct.mon, date_struct.day); 241 | _canvas_data->drawString(buf, POS_RX, 30); 242 | sprintf(buf, "%02d : %02d : %02d", time_struct.hour, time_struct.min, time_struct.sec); 243 | _canvas_data->drawString(buf, POS_RX, 90); 244 | 245 | // SHT30 246 | M5.SHT30.UpdateData(); 247 | if (M5.SHT30.GetError() == 0) { 248 | float ctemp = M5.SHT30.GetTemperature(); 249 | float chumi = M5.SHT30.GetRelHumidity(); 250 | 251 | if (!(pass_flag & 0x04)) { 252 | if (_prev_temp > 100) { 253 | _prev_temp = ctemp; 254 | } 255 | if ((ctemp < 40) && (ctemp > 0) && (_prev_temp != ctemp)) { 256 | pass_flag |= 0x04; 257 | } 258 | } 259 | 260 | if (!(pass_flag & 0x08)) { 261 | if (_prev_hum > 100) { 262 | _prev_hum = chumi; 263 | } 264 | if ((chumi >= 0) && (chumi <= 100) && (_prev_hum != chumi)) { 265 | pass_flag |= 0x08; 266 | } 267 | } 268 | 269 | sprintf(buf, "%.2f ℃", ctemp); 270 | _canvas_data->drawString(buf, POS_RX, 150); 271 | sprintf(buf, "%d %%", (int)chumi); 272 | _canvas_data->drawString(buf, POS_RX, 210); 273 | } else { 274 | _canvas_data->drawString("[FAILED]", POS_RX, 150); 275 | _canvas_data->drawString("[FAILED]", POS_RX, 210); 276 | } 277 | 278 | // Battery 279 | uint32_t vol = M5.getBatteryVoltage(); 280 | if (_prev_vol == 0) { 281 | _prev_vol = vol; 282 | } 283 | if (_prev_vol != vol) { 284 | pass_flag |= 0x10; 285 | } 286 | float vol_f = vol / 1000.0f; 287 | sprintf(buf, "%.2f V", vol_f); 288 | _canvas_data->drawString(buf, POS_RX, 270); 289 | 290 | // WiFi 291 | if (_isfirst) { 292 | String ssid; 293 | int32_t rssi; 294 | scan(&ssid, &rssi); 295 | sprintf(buf, "%s (%d db)", ssid.c_str(), rssi); 296 | _wifistr = String(buf); 297 | if (rssi > -55) { 298 | pass_flag |= 0x20; 299 | } 300 | } 301 | _canvas_data->drawString(_wifistr, POS_RX, 330); 302 | 303 | // PSRAM 304 | if (_isfirst) { 305 | uint8_t *test_p = (uint8_t *)ps_malloc(16); 306 | if (test_p != NULL) { 307 | free(test_p); 308 | _psram_success = true; 309 | sprintf(buf, "Free %.2f KiB", ESP.getFreePsram() / 1024.0f); 310 | _canvas_data->drawString(buf, POS_RX, 390); 311 | pass_flag |= 0x40; 312 | } else { 313 | _psram_success = false; 314 | sprintf(buf, "[FAILED]"); 315 | _canvas_data->drawString(buf, POS_RX, 390); 316 | } 317 | } else { 318 | if (_psram_success) { 319 | sprintf(buf, "Free %.2f KiB", ESP.getFreePsram() / 1024.0f); 320 | _canvas_data->drawString(buf, POS_RX, 390); 321 | } else { 322 | _canvas_data->drawString("[FAILED]", POS_RX, 390); 323 | } 324 | } 325 | 326 | // SD 327 | if (GetInitStatus(0)) { 328 | sprintf(buf, "%.2f MiB", SD.cardSize() / 1024.0f / 1024.0f); 329 | _canvas_data->drawString(buf, POS_RX, 450); 330 | } else { 331 | _canvas_data->drawString("[FAILED]", POS_RX, 450); 332 | } 333 | 334 | _canvas_data->pushCanvas(300, 100, UPDATE_MODE_A2); 335 | } 336 | 337 | 338 | // grove 339 | uint16_t temp = pass_flag; 340 | if (!(pass_flag & 0x0400)) { 341 | pass_flag |= checkGrove(M5EPD_PORTA_Y_PIN, M5EPD_PORTA_W_PIN) ? 0x0400 : 0x0000; 342 | } 343 | if (!(pass_flag & 0x0800)) { 344 | pass_flag |= checkGrove(M5EPD_PORTB_Y_PIN, M5EPD_PORTB_W_PIN) ? 0x0800 : 0x0000; 345 | } 346 | if (!(pass_flag & 0x1000)) { 347 | pass_flag |= checkGrove(M5EPD_PORTC_Y_PIN, M5EPD_PORTC_W_PIN) ? 0x1000 : 0x0000; 348 | } 349 | 350 | bool update_flag = false; 351 | if (temp != pass_flag) { 352 | if (pass_flag != _pass_flag) { 353 | update_flag = true; 354 | } 355 | _pass_flag = pass_flag; 356 | drawGrove(UPDATE_MODE_GL16); 357 | update_flag = true; 358 | } else if (update_flag || (pass_flag != _pass_flag)) { 359 | _pass_flag = pass_flag; 360 | drawItem(UPDATE_MODE_GL16); 361 | update_flag = true; 362 | } 363 | if (update_flag) { 364 | drawPassCount(UPDATE_MODE_GL16); 365 | } 366 | 367 | if (_isfirst) { 368 | _isfirst = false; 369 | } 370 | 371 | return 1; 372 | } 373 | 374 | int Frame_FactoryTest::init(epdgui_args_vector_t &args) { 375 | _is_run = 1; 376 | M5.EPD.Clear(); 377 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 378 | _canvas_base->pushCanvas(0, 100, UPDATE_MODE_NONE); 379 | drawItem(UPDATE_MODE_NONE); 380 | drawGrove(UPDATE_MODE_NONE); 381 | drawPassCount(UPDATE_MODE_NONE); 382 | EPDGUI_AddObject(_key_exit); 383 | 384 | _time = 0; 385 | _btn = 0; 386 | _psram_success = false; 387 | _isfirst = true; 388 | _last_x = 0; 389 | _last_y = 0; 390 | _prev_sec = 255; 391 | _prev_temp = 255; 392 | _prev_hum = 255; 393 | _prev_vol = 0; 394 | 395 | return 3; 396 | } -------------------------------------------------------------------------------- /src/frame/frame_factorytest.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_FACTORYTEST_H_ 2 | #define _FRAME_FACTORYTEST_H_ 3 | 4 | #include "frame_base.h" 5 | #include "../epdgui/epdgui.h" 6 | 7 | class Frame_FactoryTest : public Frame_Base { 8 | public: 9 | Frame_FactoryTest(); 10 | ~Frame_FactoryTest(); 11 | int run(); 12 | void scan(String *ssid, int32_t *rssi); 13 | int init(epdgui_args_vector_t &args); 14 | 15 | private: 16 | void drawItem(m5epd_update_mode_t mode); 17 | void drawItem(uint16_t flag, const char* str, int y); 18 | void drawGrove(m5epd_update_mode_t mode); 19 | bool checkGrove(int sda, int scl); 20 | void drawPassCount(m5epd_update_mode_t mode); 21 | 22 | 23 | private: 24 | M5EPD_Canvas *_canvas_base; 25 | M5EPD_Canvas *_canvas_data; 26 | M5EPD_Canvas *_canvas_pos; 27 | M5EPD_Canvas *_canvas_btn; 28 | M5EPD_Canvas *_canvas_pass; 29 | uint32_t _time; 30 | uint8_t _btn; 31 | bool _psram_success; 32 | bool _isfirst; 33 | String _wifistr; 34 | uint32_t _last_x, _last_y; 35 | uint16_t _pass_flag; 36 | uint8_t _prev_sec; 37 | float _prev_temp; 38 | float _prev_hum; 39 | uint16_t _prev_vol; 40 | }; 41 | 42 | #endif //_FRAME_FACTORYTEST_H_ -------------------------------------------------------------------------------- /src/frame/frame_fileindex.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_fileindex.h" 2 | #include "frame_txtreader.h" 3 | #include "frame_pictureviewer.h" 4 | 5 | 6 | #define MAX_BTN_NUM 14 7 | 8 | void key_fileindex_folder_cb(epdgui_args_vector_t &args) { 9 | Frame_Base *frame = new Frame_FileIndex(((EPDGUI_Button*)(args[0]))->GetCustomString()); 10 | EPDGUI_PushFrame(frame); 11 | *((int*)(args[1])) = 0; 12 | log_d("%s", ((EPDGUI_Button*)(args[0]))->GetCustomString().c_str()); 13 | } 14 | 15 | void key_fileindex_image_cb(epdgui_args_vector_t &args) { 16 | Frame_Base *frame = new Frame_PictureViewer(((EPDGUI_Button*)(args[0]))->GetCustomString()); 17 | EPDGUI_PushFrame(frame); 18 | *((int*)(args[1])) = 0; 19 | log_d("%s", ((EPDGUI_Button*)(args[0]))->GetCustomString().c_str()); 20 | } 21 | 22 | void key_fileindex_text_cb(epdgui_args_vector_t &args) { 23 | Frame_Base *frame = new Frame_txtReader(((EPDGUI_Button*)(args[0]))->GetCustomString()); 24 | EPDGUI_PushFrame(frame); 25 | *((int*)(args[1])) = 0; 26 | log_d("%s", ((EPDGUI_Button*)(args[0]))->GetCustomString().c_str()); 27 | } 28 | 29 | void key_fileindex_exit_cb(epdgui_args_vector_t &args) { 30 | EPDGUI_PopFrame(true); 31 | *((int*)(args[0])) = 0; 32 | } 33 | 34 | Frame_FileIndex::Frame_FileIndex(String path) { 35 | _frame_name = "Frame_FileIndex"; 36 | _path = path; 37 | 38 | _canvas_title->setTextDatum(CR_DATUM); 39 | if (path == "/") { 40 | exitbtn("Home"); 41 | _canvas_title->drawString("SD/", 540 - 15, 34); 42 | } else { 43 | String parent_directory = path.substring(0, path.lastIndexOf("/")); 44 | 45 | exitbtn("/.."); 46 | String subpath = path; 47 | if (path.length() > 20) { 48 | subpath = path.substring(0, 20) + "..."; 49 | } 50 | _canvas_title->drawString("SD" + subpath, 540 - 15, 34); 51 | } 52 | 53 | _key_exit->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void *)(&_is_run)); 54 | _key_exit->Bind(EPDGUI_Button::EVENT_RELEASED, &key_fileindex_exit_cb); 55 | } 56 | 57 | void Frame_FileIndex::listDir(fs::FS &fs, const char *dirname) { 58 | File root = fs.open(dirname); 59 | if (!root) { 60 | log_d("Failed to open directory"); 61 | return; 62 | } 63 | if (!root.isDirectory()) { 64 | log_d("Not a directory"); 65 | return; 66 | } 67 | 68 | std::vector folders; 69 | std::vector files; 70 | 71 | File file = root.openNextFile(); 72 | while (file) { 73 | if (file.isDirectory()) { 74 | folders.push_back(file); 75 | } else { 76 | files.push_back(file); 77 | } 78 | file = root.openNextFile(); 79 | } 80 | 81 | for (int n = 0; n < folders.size(); n++) { 82 | if (_key_files.size() > MAX_BTN_NUM) { 83 | break; 84 | } 85 | File file = folders[n]; 86 | EPDGUI_Button *btn = new EPDGUI_Button(4, 100 + _key_files.size() * 60, 532, 61); 87 | _key_files.push_back(btn); 88 | 89 | String filename(file.name()); 90 | filename = filename.substring(filename.lastIndexOf("/")); 91 | if (filename.length() > 19) { 92 | filename = filename.substring(0, 19) + "..."; 93 | } 94 | btn->CanvasNormal()->fillCanvas(0); 95 | btn->CanvasNormal()->drawRect(0, 0, 532, 61, 15); 96 | btn->CanvasNormal()->setTextSize(26); 97 | btn->CanvasNormal()->setTextDatum(CL_DATUM); 98 | btn->CanvasNormal()->setTextColor(15); 99 | btn->CanvasNormal()->drawString(filename, 47 + 13, 35); 100 | btn->SetCustomString(file.name()); 101 | btn->CanvasNormal()->setTextDatum(CR_DATUM); 102 | btn->CanvasNormal()->pushImage(15, 14, 32, 32, ImageResource_item_icon_file_folder_32x32); 103 | btn->CanvasNormal()->pushImage(532 - 15 - 32, 14, 32, 32, ImageResource_item_icon_arrow_r_32x32); 104 | *(btn->CanvasPressed()) = *(btn->CanvasNormal()); 105 | btn->CanvasPressed()->ReverseColor(); 106 | 107 | btn->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, btn); 108 | btn->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, (void*)(&_is_run)); 109 | btn->Bind(EPDGUI_Button::EVENT_RELEASED, key_fileindex_folder_cb); 110 | } 111 | 112 | for (int n = 0; n < files.size(); n++) { 113 | if (_key_files.size() > MAX_BTN_NUM) { 114 | break; 115 | } 116 | File file = files[n]; 117 | EPDGUI_Button *btn = new EPDGUI_Button(4, 100 + _key_files.size() * 60, 532, 61); 118 | _key_files.push_back(btn); 119 | 120 | String filename(file.name()); 121 | filename = filename.substring(filename.lastIndexOf("/")); 122 | if (filename.length() > 19) { 123 | filename = filename.substring(0, 19) + "..."; 124 | } 125 | btn->CanvasNormal()->fillCanvas(0); 126 | btn->CanvasNormal()->drawRect(0, 0, 532, 61, 15); 127 | btn->CanvasNormal()->setTextSize(26); 128 | btn->CanvasNormal()->setTextDatum(CL_DATUM); 129 | btn->CanvasNormal()->setTextColor(15); 130 | btn->CanvasNormal()->drawString(filename, 47 + 13, 35); 131 | btn->SetCustomString(file.name()); 132 | btn->CanvasNormal()->setTextDatum(CR_DATUM); 133 | 134 | String suffix = filename.substring(filename.lastIndexOf(".")); 135 | if (suffix.indexOf("txt") >= 0) { 136 | btn->CanvasNormal()->pushImage(15, 14, 32, 32, ImageResource_item_icon_file_text_32x32); 137 | btn->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, btn); 138 | btn->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, (void*)(&_is_run)); 139 | btn->Bind(EPDGUI_Button::EVENT_RELEASED, key_fileindex_text_cb); 140 | } else if ((suffix.indexOf("bmp") >= 0) 141 | || (suffix.indexOf("BMP") >= 0) 142 | || (suffix.indexOf("png") >= 0) 143 | || (suffix.indexOf("PNG") >= 0) 144 | || (suffix.indexOf("jpg") >= 0) 145 | || (suffix.indexOf("JPG") >= 0)) { 146 | btn->CanvasNormal()->pushImage(15, 14, 32, 32, ImageResource_item_icon_file_image_32x32); 147 | btn->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, btn); 148 | btn->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, (void*)(&_is_run)); 149 | btn->Bind(EPDGUI_Button::EVENT_RELEASED, key_fileindex_image_cb); 150 | } else { 151 | btn->CanvasNormal()->pushImage(15, 14, 32, 32, ImageResource_item_icon_file_unknow_32x32); 152 | btn->SetEnable(false); 153 | } 154 | 155 | char buf[50]; 156 | sprintf(buf, "%.2f KiB", file.size() / 1024.0f); 157 | btn->CanvasNormal()->drawString(buf, 532 - 15, 35); 158 | *(btn->CanvasPressed()) = *(btn->CanvasNormal()); 159 | btn->CanvasPressed()->ReverseColor(); 160 | } 161 | } 162 | 163 | Frame_FileIndex::~Frame_FileIndex(void) { 164 | for (int i = 0; i < _key_files.size(); i++) { 165 | delete _key_files[i]; 166 | } 167 | } 168 | 169 | int Frame_FileIndex::init(epdgui_args_vector_t &args) { 170 | _is_run = 1; 171 | 172 | if (_key_files.size() == 0) { 173 | listDir(SD, _path.c_str()); 174 | } 175 | 176 | M5.EPD.WriteFullGram4bpp(GetWallpaper()); 177 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 178 | EPDGUI_AddObject(_key_exit); 179 | 180 | for (int i = 0; i < _key_files.size(); i++) { 181 | EPDGUI_AddObject(_key_files[i]); 182 | } 183 | 184 | return 3; 185 | } -------------------------------------------------------------------------------- /src/frame/frame_fileindex.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_FILEINDEX_H_ 2 | #define _FRAME_FILEINDEX_H_ 3 | 4 | #include "frame_base.h" 5 | #include "../epdgui/epdgui.h" 6 | #include 7 | 8 | class Frame_FileIndex : public Frame_Base { 9 | public: 10 | Frame_FileIndex(String path); 11 | ~Frame_FileIndex(); 12 | void listDir(fs::FS &fs, const char *dirname); 13 | int init(epdgui_args_vector_t &args); 14 | 15 | private: 16 | std::vector _key_files; 17 | String _path; 18 | }; 19 | 20 | #endif //_FRAME_FILEINDEX_H_ -------------------------------------------------------------------------------- /src/frame/frame_home.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_home.h" 2 | 3 | void Frame_Home::InitSwitch(EPDGUI_Switch* sw, String title, String subtitle, const uint8_t *img1, const uint8_t *img2) { 4 | memcpy(sw->Canvas(0)->frameBuffer(), ImageResource_home_button_background_228x228, 228 * 228 / 2); 5 | sw->Canvas(0)->setTextSize(36); 6 | sw->Canvas(0)->setTextDatum(TC_DATUM); 7 | sw->Canvas(0)->drawString(title, 114, 136); 8 | sw->Canvas(0)->setTextSize(26); 9 | sw->Canvas(0)->drawString(subtitle, 114, 183); 10 | memcpy(sw->Canvas(1)->frameBuffer(), sw->Canvas(0)->frameBuffer(), 228 * 228 / 2); 11 | sw->Canvas(0)->pushImage(68, 20, 92, 92, img1); 12 | sw->Canvas(1)->pushImage(68, 20, 92, 92, img2); 13 | } 14 | 15 | void key_home_air_adjust_cb(epdgui_args_vector_t &args) { 16 | int operation = ((EPDGUI_Button*)(args[0]))->GetCustomString().toInt(); 17 | EPDGUI_Switch *sw = ((EPDGUI_Switch*)(args[1])); 18 | if (sw->getState() == 0) { 19 | return; 20 | } 21 | int temp = sw->GetCustomString().toInt(); 22 | char buf[10]; 23 | if (operation == 1) { 24 | temp++; 25 | 26 | } else { 27 | temp--; 28 | } 29 | sprintf(buf, "%d", temp); 30 | sw->SetCustomString(buf); 31 | sprintf(buf, "%d℃", temp); 32 | sw->Canvas(1)->setTextSize(36); 33 | sw->Canvas(1)->setTextDatum(TC_DATUM); 34 | sw->Canvas(1)->fillRect(114 - 100, 108, 200, 38, 0); 35 | sw->Canvas(1)->drawString(buf, 114, 108); 36 | sw->Canvas(1)->pushCanvas(sw->getX(), sw->getY(), UPDATE_MODE_A2); 37 | } 38 | 39 | void key_home_air_state0_cb(epdgui_args_vector_t &args) { 40 | EPDGUI_Button *b1 = ((EPDGUI_Button*)(args[0])); 41 | EPDGUI_Button *b2 = ((EPDGUI_Button*)(args[1])); 42 | b1->SetEnable(false); 43 | b2->SetEnable(false); 44 | } 45 | 46 | void key_home_air_state1_cb(epdgui_args_vector_t &args) { 47 | EPDGUI_Button *b1 = ((EPDGUI_Button*)(args[0])); 48 | EPDGUI_Button *b2 = ((EPDGUI_Button*)(args[1])); 49 | b1->SetEnable(true); 50 | b2->SetEnable(true); 51 | } 52 | 53 | Frame_Home::Frame_Home(void) { 54 | _frame_name = "Frame_Home"; 55 | 56 | _sw_light1 = new EPDGUI_Switch(2, 20, 44 + 72, 228, 228); 57 | _sw_light2 = new EPDGUI_Switch(2, 288, 44 + 72, 228, 228); 58 | _sw_socket1 = new EPDGUI_Switch(2, 20, 324 + 72, 228, 228); 59 | _sw_socket2 = new EPDGUI_Switch(2, 288, 324 + 72, 228, 228); 60 | _sw_air_1 = new EPDGUI_Switch(2, 20, 604 + 72, 228, 184); 61 | _sw_air_2 = new EPDGUI_Switch(2, 288, 604 + 72, 228, 184); 62 | _key_air_1_plus = new EPDGUI_Button(20 + 116, 604 + 72 + 184, 112, 44); 63 | _key_air_1_minus = new EPDGUI_Button(20, 604 + 72 + 184, 116, 44); 64 | _key_air_2_plus = new EPDGUI_Button(288 + 116, 604 + 72 + 184, 112, 44); 65 | _key_air_2_minus = new EPDGUI_Button(288, 604 + 72 + 184, 116, 44); 66 | 67 | _key_air_1_plus ->SetCustomString("1"); 68 | _key_air_1_minus->SetCustomString("0"); 69 | _key_air_2_plus ->SetCustomString("1"); 70 | _key_air_2_minus->SetCustomString("0"); 71 | _key_air_1_plus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, _key_air_1_plus); 72 | _key_air_1_plus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, _sw_air_1); 73 | _key_air_1_plus->Bind(EPDGUI_Button::EVENT_RELEASED, key_home_air_adjust_cb); 74 | _key_air_1_minus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, _key_air_1_minus); 75 | _key_air_1_minus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, _sw_air_1); 76 | _key_air_1_minus->Bind(EPDGUI_Button::EVENT_RELEASED, key_home_air_adjust_cb); 77 | _key_air_2_plus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, _key_air_2_plus); 78 | _key_air_2_plus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, _sw_air_2); 79 | _key_air_2_plus->Bind(EPDGUI_Button::EVENT_RELEASED, key_home_air_adjust_cb); 80 | _key_air_2_minus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, _key_air_2_minus); 81 | _key_air_2_minus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, _sw_air_2); 82 | _key_air_2_minus->Bind(EPDGUI_Button::EVENT_RELEASED, key_home_air_adjust_cb); 83 | 84 | M5EPD_Canvas canvas_temp(&M5.EPD); 85 | canvas_temp.createRender(36); 86 | 87 | InitSwitch(_sw_light1, "Ceiling Light", "Living Room", ImageResource_home_icon_light_off_92x92, ImageResource_home_icon_light_on_92x92); 88 | InitSwitch(_sw_light2, "Table Lamp", "Bedroom", ImageResource_home_icon_light_off_92x92, ImageResource_home_icon_light_on_92x92); 89 | InitSwitch(_sw_socket1, "Rice Cooker", "Kitchen", ImageResource_home_icon_socket_off_92x92, ImageResource_home_icon_socket_on_92x92); 90 | InitSwitch(_sw_socket2, "Computer", "Bedroom", ImageResource_home_icon_socket_off_92x92, ImageResource_home_icon_socket_on_92x92); 91 | 92 | memcpy(_sw_air_1->Canvas(0)->frameBuffer(), ImageResource_home_air_background_228x184, 228 * 184 / 2); 93 | _sw_air_1->Canvas(0)->setTextDatum(TC_DATUM); 94 | _sw_air_1->Canvas(0)->setTextSize(26); 95 | _sw_air_1->Canvas(0)->drawString("Bedroom", 114, 152); 96 | memcpy(_sw_air_1->Canvas(1)->frameBuffer(), _sw_air_1->Canvas(0)->frameBuffer(), 228 * 184 / 2); 97 | _sw_air_1->Canvas(0)->setTextSize(36); 98 | _sw_air_1->Canvas(0)->drawString("OFF", 114, 108); 99 | _sw_air_1->Canvas(1)->setTextSize(36); 100 | _sw_air_1->Canvas(1)->setTextDatum(TC_DATUM); 101 | _sw_air_1->Canvas(1)->drawString("26℃", 114, 108); 102 | _sw_air_1->SetCustomString("26"); 103 | 104 | memcpy(_sw_air_2->Canvas(0)->frameBuffer(), ImageResource_home_air_background_228x184, 228 * 184 / 2); 105 | _sw_air_2->Canvas(0)->setTextDatum(TC_DATUM); 106 | _sw_air_2->Canvas(0)->setTextSize(26); 107 | _sw_air_2->Canvas(0)->drawString("Living Room", 114, 152); 108 | memcpy(_sw_air_2->Canvas(1)->frameBuffer(), _sw_air_2->Canvas(0)->frameBuffer(), 228 * 184 / 2); 109 | _sw_air_2->Canvas(0)->setTextSize(36); 110 | _sw_air_2->Canvas(0)->drawString("OFF", 114, 108); 111 | _sw_air_2->Canvas(1)->setTextSize(36); 112 | _sw_air_2->Canvas(1)->setTextDatum(TC_DATUM); 113 | _sw_air_2->Canvas(1)->drawString("26℃", 114, 108); 114 | _sw_air_2->SetCustomString("26"); 115 | 116 | memcpy(_key_air_1_plus->CanvasNormal()->frameBuffer(), ImageResource_home_air_background_r_112x44, 112 * 44 / 2); 117 | memcpy(_key_air_1_plus->CanvasPressed()->frameBuffer(), _key_air_1_plus->CanvasNormal()->frameBuffer(), 112 * 44 / 2); 118 | _key_air_1_plus->CanvasPressed()->ReverseColor(); 119 | memcpy(_key_air_2_plus->CanvasNormal()->frameBuffer(), ImageResource_home_air_background_r_112x44, 112 * 44 / 2); 120 | memcpy(_key_air_2_plus->CanvasPressed()->frameBuffer(), _key_air_2_plus->CanvasNormal()->frameBuffer(), 112 * 44 / 2); 121 | _key_air_2_plus->CanvasPressed()->ReverseColor(); 122 | memcpy(_key_air_1_minus->CanvasNormal()->frameBuffer(), ImageResource_home_air_background_l_116x44, 116 * 44 / 2); 123 | memcpy(_key_air_1_minus->CanvasPressed()->frameBuffer(), _key_air_1_minus->CanvasNormal()->frameBuffer(), 116 * 44 / 2); 124 | _key_air_1_minus->CanvasPressed()->ReverseColor(); 125 | memcpy(_key_air_2_minus->CanvasNormal()->frameBuffer(), ImageResource_home_air_background_l_116x44, 116 * 44 / 2); 126 | memcpy(_key_air_2_minus->CanvasPressed()->frameBuffer(), _key_air_2_minus->CanvasNormal()->frameBuffer(), 116 * 44 / 2); 127 | _key_air_2_minus->CanvasPressed()->ReverseColor(); 128 | 129 | _key_air_1_plus->SetEnable(false); 130 | _key_air_2_plus->SetEnable(false); 131 | _key_air_1_minus->SetEnable(false); 132 | _key_air_2_minus->SetEnable(false); 133 | 134 | _sw_air_1->Canvas(0)->pushImage(68, 12, 92, 92, ImageResource_home_icon_conditioner_off_92x92); 135 | _sw_air_1->Canvas(1)->pushImage(68, 12, 92, 92, ImageResource_home_icon_conditioner_on_92x92); 136 | _sw_air_2->Canvas(0)->pushImage(68, 12, 92, 92, ImageResource_home_icon_conditioner_off_92x92); 137 | _sw_air_2->Canvas(1)->pushImage(68, 12, 92, 92, ImageResource_home_icon_conditioner_on_92x92); 138 | 139 | _sw_air_1->AddArgs(EPDGUI_Switch::EVENT_NONE, 0, _key_air_1_plus); 140 | _sw_air_1->AddArgs(EPDGUI_Switch::EVENT_NONE, 1, _key_air_1_minus); 141 | _sw_air_1->AddArgs(EPDGUI_Switch::EVENT_NONE, 2, _sw_air_1); 142 | _sw_air_1->Bind(0, key_home_air_state0_cb); 143 | _sw_air_1->AddArgs(EPDGUI_Switch::EVENT_PRESSED, 0, _key_air_1_plus); 144 | _sw_air_1->AddArgs(EPDGUI_Switch::EVENT_PRESSED, 1, _key_air_1_minus); 145 | _sw_air_1->AddArgs(EPDGUI_Switch::EVENT_PRESSED, 2, _sw_air_1); 146 | _sw_air_1->Bind(1, key_home_air_state1_cb); 147 | 148 | _sw_air_2->AddArgs(EPDGUI_Switch::EVENT_NONE, 0, _key_air_2_plus); 149 | _sw_air_2->AddArgs(EPDGUI_Switch::EVENT_NONE, 1, _key_air_2_minus); 150 | _sw_air_2->AddArgs(EPDGUI_Switch::EVENT_NONE, 2, _sw_air_2); 151 | _sw_air_2->Bind(0, key_home_air_state0_cb); 152 | _sw_air_2->AddArgs(EPDGUI_Switch::EVENT_PRESSED, 0, _key_air_2_plus); 153 | _sw_air_2->AddArgs(EPDGUI_Switch::EVENT_PRESSED, 1, _key_air_2_minus); 154 | _sw_air_2->AddArgs(EPDGUI_Switch::EVENT_PRESSED, 2, _sw_air_2); 155 | _sw_air_2->Bind(1, key_home_air_state1_cb); 156 | 157 | exitbtn("Home"); 158 | _canvas_title->drawString("Control Panel", 270, 34); 159 | 160 | _key_exit->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 161 | _key_exit->Bind(EPDGUI_Button::EVENT_RELEASED, &Frame_Base::exit_cb); 162 | } 163 | 164 | Frame_Home::~Frame_Home(void) { 165 | delete _sw_light1; 166 | delete _sw_light2; 167 | delete _sw_socket1; 168 | delete _sw_socket2; 169 | delete _sw_air_1; 170 | delete _sw_air_2; 171 | delete _key_air_1_plus; 172 | delete _key_air_1_minus; 173 | delete _key_air_2_plus; 174 | delete _key_air_2_minus; 175 | } 176 | 177 | int Frame_Home::init(epdgui_args_vector_t &args) { 178 | _is_run = 1; 179 | M5.EPD.Clear(); 180 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 181 | EPDGUI_AddObject(_sw_light1); 182 | EPDGUI_AddObject(_sw_light2); 183 | EPDGUI_AddObject(_sw_socket1); 184 | EPDGUI_AddObject(_sw_socket2); 185 | EPDGUI_AddObject(_sw_air_1); 186 | EPDGUI_AddObject(_sw_air_2); 187 | EPDGUI_AddObject(_key_air_1_plus); 188 | EPDGUI_AddObject(_key_air_1_minus); 189 | EPDGUI_AddObject(_key_air_2_plus); 190 | EPDGUI_AddObject(_key_air_2_minus); 191 | EPDGUI_AddObject(_key_exit); 192 | return 3; 193 | } -------------------------------------------------------------------------------- /src/frame/frame_home.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_HOME_H_ 2 | #define _FRAME_HOME_H_ 3 | 4 | #include "frame_base.h" 5 | #include "../epdgui/epdgui.h" 6 | 7 | class Frame_Home : public Frame_Base { 8 | public: 9 | Frame_Home(); 10 | ~Frame_Home(); 11 | int init(epdgui_args_vector_t &args); 12 | void InitSwitch(EPDGUI_Switch* sw, String title, String subtitle, const uint8_t *img1, const uint8_t *img2); 13 | private: 14 | EPDGUI_Switch *_sw_light1; 15 | EPDGUI_Switch *_sw_light2; 16 | EPDGUI_Switch *_sw_socket1; 17 | EPDGUI_Switch *_sw_socket2; 18 | EPDGUI_Switch *_sw_air_1; 19 | EPDGUI_Switch *_sw_air_2; 20 | EPDGUI_Button *_key_air_1_plus; 21 | EPDGUI_Button *_key_air_1_minus; 22 | EPDGUI_Button *_key_air_2_plus; 23 | EPDGUI_Button *_key_air_2_minus; 24 | }; 25 | 26 | #endif //_FRAME_HOME_H_ -------------------------------------------------------------------------------- /src/frame/frame_keyboard.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_keyboard.h" 2 | 3 | uint16_t textsize = 26; 4 | 5 | void key_textclear_cb(epdgui_args_vector_t &args) { 6 | ((EPDGUI_Textbox*)(args[0]))->SetText(""); 7 | } 8 | 9 | void key_textsize_plus_cb(epdgui_args_vector_t &args) { 10 | textsize += 4; 11 | if (textsize > 96) { 12 | textsize = 96; 13 | } 14 | char buf[10]; 15 | sprintf(buf, "%d", textsize); 16 | ((EPDGUI_Button*)(args[1]))->setLabel(buf); 17 | ((EPDGUI_Button*)(args[1]))->Draw(UPDATE_MODE_GL16); 18 | ((EPDGUI_Textbox*)(args[0]))->SetTextSize(textsize); 19 | } 20 | 21 | void key_textsize_minus_cb(epdgui_args_vector_t &args) { 22 | textsize -= 4; 23 | if (textsize < 12) { 24 | textsize = 12; 25 | } 26 | char buf[10]; 27 | sprintf(buf, "%d", textsize); 28 | ((EPDGUI_Button*)(args[1]))->setLabel(buf); 29 | ((EPDGUI_Button*)(args[1]))->Draw(UPDATE_MODE_GL16); 30 | ((EPDGUI_Textbox*)(args[0]))->SetTextSize(textsize); 31 | } 32 | 33 | void key_textsize_reset_cb(epdgui_args_vector_t &args) { 34 | textsize = 26; 35 | char buf[10]; 36 | sprintf(buf, "%d", textsize); 37 | ((EPDGUI_Button*)(args[1]))->setLabel(buf); 38 | ((EPDGUI_Button*)(args[1]))->Draw(UPDATE_MODE_GL16); 39 | ((EPDGUI_Textbox*)(args[0]))->SetTextSize(textsize); 40 | } 41 | 42 | Frame_Keyboard::Frame_Keyboard() : Frame_Base() { 43 | _frame_name = "Frame_Keyboard"; 44 | const uint16_t kKeyBaseY = 628; 45 | inputbox = new EPDGUI_Textbox(4, 100, 532, 512); 46 | key_textclear = new EPDGUI_Button("CLR", 4, kKeyBaseY, 260, 52); 47 | key_textsize_plus = new EPDGUI_Button("+", 448, kKeyBaseY, 88, 52); 48 | key_textsize_reset = new EPDGUI_Button("26", 360, kKeyBaseY, 88, 52); 49 | key_textsize_minus = new EPDGUI_Button("-", 272, kKeyBaseY, 88, 52); 50 | 51 | inputbox->SetState(EPDGUI_Textbox::EVENT_PRESSED); 52 | 53 | keyboard = new EPDGUI_Keyboard(); 54 | 55 | key_textclear->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)inputbox); 56 | key_textclear->Bind(EPDGUI_Button::EVENT_RELEASED, key_textclear_cb); 57 | key_textsize_plus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)inputbox); 58 | key_textsize_plus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, (void*)key_textsize_reset); 59 | key_textsize_plus->Bind(EPDGUI_Button::EVENT_RELEASED, key_textsize_plus_cb); 60 | key_textsize_reset->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)inputbox); 61 | key_textsize_reset->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, (void*)key_textsize_reset); 62 | key_textsize_reset->Bind(EPDGUI_Button::EVENT_RELEASED, key_textsize_reset_cb); 63 | key_textsize_minus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)inputbox); 64 | key_textsize_minus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, (void*)key_textsize_reset); 65 | key_textsize_minus->Bind(EPDGUI_Button::EVENT_RELEASED, key_textsize_minus_cb); 66 | 67 | exitbtn("Home"); 68 | _canvas_title->drawString("Keyboard", 270, 34); 69 | 70 | _key_exit->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 71 | _key_exit->Bind(EPDGUI_Button::EVENT_RELEASED, &Frame_Base::exit_cb); 72 | } 73 | 74 | Frame_Keyboard::~Frame_Keyboard() { 75 | delete inputbox; 76 | delete keyboard; 77 | delete key_textclear; 78 | delete key_textsize_plus; 79 | delete key_textsize_reset; 80 | delete key_textsize_minus; 81 | } 82 | 83 | int Frame_Keyboard::init(epdgui_args_vector_t &args) { 84 | _is_run = 1; 85 | M5.EPD.Clear(); 86 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 87 | EPDGUI_AddObject(inputbox); 88 | EPDGUI_AddObject(keyboard); 89 | EPDGUI_AddObject(_key_exit); 90 | EPDGUI_AddObject(key_textclear); 91 | EPDGUI_AddObject(key_textsize_plus); 92 | EPDGUI_AddObject(key_textsize_reset); 93 | EPDGUI_AddObject(key_textsize_minus); 94 | return 6; 95 | } 96 | 97 | int Frame_Keyboard::run(void) { 98 | inputbox->AddText(keyboard->getData()); 99 | return 1; 100 | } 101 | -------------------------------------------------------------------------------- /src/frame/frame_keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_KEYBOARD_H_ 2 | #define _FRAME_KEYBOARD_H_ 3 | 4 | #include "frame_base.h" 5 | #include "../epdgui/epdgui.h" 6 | 7 | class Frame_Keyboard : public Frame_Base { 8 | public: 9 | Frame_Keyboard(); 10 | ~Frame_Keyboard(); 11 | int run(); 12 | int init(epdgui_args_vector_t &args); 13 | 14 | private: 15 | EPDGUI_Textbox *inputbox; 16 | EPDGUI_Keyboard *keyboard; 17 | EPDGUI_Button *key_textclear; 18 | EPDGUI_Button *key_textsize_plus; 19 | EPDGUI_Button *key_textsize_reset; 20 | EPDGUI_Button *key_textsize_minus; 21 | }; 22 | 23 | #endif //_FRAME_KEYBOARD_H_ -------------------------------------------------------------------------------- /src/frame/frame_lifegame.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_lifegame.h" 2 | 3 | // #define CELL_W 10 4 | // #define CELL_H 10 5 | // #define CELL_X 54 + 2 6 | // #define CELL_Y 88 + 2 7 | 8 | 9 | #define CELL_W 4 10 | #define CELL_H 4 11 | #define CELL_X 135 + 2 12 | #define CELL_Y 222 + 2 13 | 14 | // #define CELL_W 2 15 | // #define CELL_H 2 16 | // #define CELL_X 270 + 2 17 | // #define CELL_Y 444 + 2 18 | 19 | static uint8_t lifegame_cells_flag = 0; 20 | M5EPD_Canvas lifegame_cells_0(&M5.EPD); 21 | M5EPD_Canvas lifegame_cells_1(&M5.EPD); 22 | M5EPD_Canvas lifegame_canvas_0(&M5.EPD); 23 | M5EPD_Canvas lifegame_canvas_1(&M5.EPD); 24 | 25 | void LifeGame_RandomCell() { 26 | lifegame_cells_flag = 0; 27 | uint8_t randbuf[CELL_X]; 28 | for (int y = 0; y < CELL_Y; y++) { 29 | esp_fill_random(randbuf, CELL_X); 30 | for (int x = 0; x < CELL_X; x++) { 31 | lifegame_cells_0.drawPixel(x, y, randbuf[x] & 0x01 ? 15 : 0); 32 | } 33 | } 34 | lifegame_cells_1.fillCanvas(0); 35 | } 36 | 37 | uint8_t LifeGame_Count3x3_0(uint8_t x, uint8_t y) { 38 | uint8_t count = 0; 39 | for (int j = y - 1; j < y + 2; j++) { 40 | for (int i = x - 1; i < x + 2; i++) { 41 | if (lifegame_cells_0.readPixel(i, j)) { 42 | count++; 43 | } 44 | } 45 | } 46 | if (lifegame_cells_0.readPixel(x, y)) { 47 | count--; 48 | } 49 | return count; 50 | } 51 | 52 | uint8_t LifeGame_Count3x3_1(uint8_t x, uint8_t y) { 53 | uint8_t count = 0; 54 | for (int j = y - 1; j < y + 2; j++) { 55 | for (int i = x - 1; i < x + 2; i++) { 56 | if (lifegame_cells_1.readPixel(i, j)) { 57 | count++; 58 | } 59 | } 60 | } 61 | if (lifegame_cells_1.readPixel(x, y)) { 62 | count--; 63 | } 64 | return count; 65 | } 66 | 67 | void LifeGame_CellProcess_0(uint8_t x, uint8_t y) { 68 | uint8_t count = LifeGame_Count3x3_0(x, y); 69 | if (lifegame_cells_0.readPixel(x, y)) { 70 | //dead 71 | if (count < 2 || count > 3) { 72 | lifegame_cells_1.drawPixel(x, y, 0); 73 | } else { 74 | lifegame_cells_1.drawPixel(x, y, 15); 75 | } 76 | } else { 77 | //new life 78 | if (count == 3) { 79 | lifegame_cells_1.drawPixel(x, y, 15); 80 | } else { 81 | lifegame_cells_1.drawPixel(x, y, 0); 82 | } 83 | } 84 | } 85 | 86 | void LifeGame_CellProcess_1(uint8_t x, uint8_t y) { 87 | uint8_t count = LifeGame_Count3x3_1(x, y); 88 | if (lifegame_cells_1.readPixel(x, y)) { 89 | //dead 90 | if (count < 2 || count > 3) { 91 | lifegame_cells_0.drawPixel(x, y, 0); 92 | } else { 93 | lifegame_cells_0.drawPixel(x, y, 15); 94 | } 95 | } else { 96 | //new life 97 | if (count == 3) { 98 | lifegame_cells_0.drawPixel(x, y, 15); 99 | } else { 100 | lifegame_cells_0.drawPixel(x, y, 0); 101 | } 102 | } 103 | } 104 | 105 | void LifeGame_RoundProcess() { 106 | if (lifegame_cells_flag == 0) { 107 | for (int y = 1; y < CELL_Y - 1; y++) { 108 | for (int x = 1; x < CELL_X - 1; x++) { 109 | LifeGame_CellProcess_0(x, y); 110 | lifegame_canvas_0.fillRect((x - 1) * CELL_W, (y - 1) * CELL_H, CELL_W, CELL_H, lifegame_cells_1.readPixel(x, y)); 111 | } 112 | } 113 | lifegame_cells_flag = 1; 114 | } else { 115 | for (int y = 1; y < CELL_Y - 1; y++) { 116 | for (int x = 1; x < CELL_X - 1; x++) { 117 | LifeGame_CellProcess_1(x, y); 118 | lifegame_canvas_1.fillRect((x - 1) * CELL_W, (y - 1) * CELL_H, CELL_W, CELL_H, lifegame_cells_0.readPixel(x, y)); 119 | } 120 | } 121 | lifegame_cells_flag = 0; 122 | } 123 | } 124 | 125 | void LifeGame_NextGen(void *pvParameters) { 126 | LifeGame_RoundProcess(); 127 | vTaskDelete(NULL); 128 | } 129 | 130 | int Frame_Lifegame::run() { 131 | M5.update(); 132 | if (M5.BtnP.wasReleased()) { 133 | LifeGame_RandomCell(); 134 | } 135 | xTaskCreatePinnedToCore(LifeGame_NextGen, "LifeGame_NextGen", 4096, NULL, 1, NULL, 0); 136 | if (lifegame_cells_flag == 0) { 137 | lifegame_canvas_1.pushCanvas(0, 72, UPDATE_MODE_DU4); 138 | } else { 139 | lifegame_canvas_0.pushCanvas(0, 72, UPDATE_MODE_DU4); 140 | } 141 | log_d(""); 142 | return 1; 143 | } 144 | 145 | void Frame_Lifegame::exit() { 146 | lifegame_cells_0.deleteCanvas(); 147 | lifegame_cells_1.deleteCanvas(); 148 | lifegame_canvas_0.deleteCanvas(); 149 | lifegame_canvas_1.deleteCanvas(); 150 | } 151 | 152 | Frame_Lifegame::Frame_Lifegame(void) { 153 | _frame_name = "Frame_Lifegame"; 154 | 155 | exitbtn("Home"); 156 | _canvas_title->drawString("Life Game", 270, 34); 157 | 158 | _key_exit->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 159 | _key_exit->Bind(EPDGUI_Button::EVENT_RELEASED, &Frame_Base::exit_cb); 160 | } 161 | 162 | Frame_Lifegame::~Frame_Lifegame(void) { 163 | } 164 | 165 | int Frame_Lifegame::init(epdgui_args_vector_t &args) { 166 | _is_run = 1; 167 | 168 | lifegame_cells_0.createCanvas(CELL_X, CELL_Y); 169 | lifegame_cells_1.createCanvas(CELL_X, CELL_Y); 170 | lifegame_canvas_0.createCanvas(540, 888); 171 | lifegame_canvas_1.createCanvas(540, 888); 172 | 173 | lifegame_cells_0.fillCanvas(0); 174 | lifegame_cells_1.fillCanvas(0); 175 | lifegame_canvas_0.fillCanvas(0); 176 | lifegame_canvas_1.fillCanvas(0); 177 | 178 | lifegame_cells_0.pushImage(2, 2, 132, 120, ImageResource_lifegame_seeder_132x120); 179 | lifegame_cells_flag = 0; 180 | 181 | M5.EPD.Clear(); 182 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 183 | EPDGUI_AddObject(_key_exit); 184 | return 3; 185 | } -------------------------------------------------------------------------------- /src/frame/frame_lifegame.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_LIFEGAME_H_ 2 | #define _FRAME_LIFEGAME_H_ 3 | 4 | #include "frame_base.h" 5 | #include "../epdgui/epdgui.h" 6 | 7 | class Frame_Lifegame : public Frame_Base { 8 | public: 9 | Frame_Lifegame(); 10 | ~Frame_Lifegame(); 11 | int init(epdgui_args_vector_t &args); 12 | int run(); 13 | void exit(); 14 | 15 | private: 16 | M5EPD_Canvas *cells_0; 17 | M5EPD_Canvas *cells_1; 18 | M5EPD_Canvas *canvas_0; 19 | M5EPD_Canvas *canvas_1; 20 | }; 21 | 22 | #endif //_FRAME_LIFEGAME_H_ -------------------------------------------------------------------------------- /src/frame/frame_main.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_main.h" 2 | #include "frame_settings.h" 3 | #include "frame_keyboard.h" 4 | #include "frame_factorytest.h" 5 | #include "frame_lifegame.h" 6 | #include "frame_fileindex.h" 7 | #include "frame_compare.h" 8 | #include "frame_home.h" 9 | #include 10 | 11 | enum { 12 | kKeyFactoryTest = 0, 13 | kKeySetting, 14 | kKeyKeyboard, 15 | kKeyWifiScan, 16 | kKeySDFile, 17 | kKeyCompare, 18 | kKeyHome, 19 | kKeyLifeGame 20 | }; 21 | 22 | #define KEY_W 92 23 | #define KEY_H 92 24 | 25 | void key_setting_cb(epdgui_args_vector_t &args) { 26 | Frame_Base *frame = EPDGUI_GetFrame("Frame_Settings"); 27 | if (frame == NULL) { 28 | frame = new Frame_Settings(); 29 | EPDGUI_AddFrame("Frame_Settings", frame); 30 | } 31 | EPDGUI_PushFrame(frame); 32 | *((int*)(args[0])) = 0; 33 | } 34 | 35 | void key_keyboard_cb(epdgui_args_vector_t &args) { 36 | Frame_Base *frame = EPDGUI_GetFrame("Frame_Keyboard"); 37 | if (frame == NULL) { 38 | frame = new Frame_Keyboard(); 39 | EPDGUI_AddFrame("Frame_Keyboard", frame); 40 | } 41 | EPDGUI_PushFrame(frame); 42 | *((int*)(args[0])) = 0; 43 | } 44 | 45 | void key_factorytest_cb(epdgui_args_vector_t &args) { 46 | Frame_Base *frame = EPDGUI_GetFrame("Frame_FactoryTest"); 47 | if (frame == NULL) { 48 | frame = new Frame_FactoryTest(); 49 | EPDGUI_AddFrame("Frame_FactoryTest", frame); 50 | } 51 | EPDGUI_PushFrame(frame); 52 | *((int*)(args[0])) = 0; 53 | } 54 | 55 | // void key_wifiscan_cb(epdgui_args_vector_t &args) { 56 | // Frame_Base *frame = EPDGUI_GetFrame("Frame_WifiScan"); 57 | // if (frame == NULL) { 58 | // frame = new Frame_WifiScan(); 59 | // EPDGUI_AddFrame("Frame_WifiScan", frame); 60 | // } 61 | // EPDGUI_PushFrame(frame); 62 | // *((int*)(args[0])) = 0; 63 | // } 64 | 65 | void key_lifegame_cb(epdgui_args_vector_t &args) { 66 | Frame_Base *frame = EPDGUI_GetFrame("Frame_Lifegame"); 67 | if (frame == NULL) { 68 | frame = new Frame_Lifegame(); 69 | EPDGUI_AddFrame("Frame_Lifegame", frame); 70 | } 71 | EPDGUI_PushFrame(frame); 72 | *((int*)(args[0])) = 0; 73 | } 74 | 75 | void key_sdfile_cb(epdgui_args_vector_t &args) { 76 | Frame_Base *frame = new Frame_FileIndex("/"); 77 | EPDGUI_PushFrame(frame); 78 | *((int*)(args[0])) = 0; 79 | } 80 | 81 | void key_compare_cb(epdgui_args_vector_t &args) { 82 | Frame_Base *frame = EPDGUI_GetFrame("Frame_Compare"); 83 | if (frame == NULL) { 84 | frame = new Frame_Compare(); 85 | EPDGUI_AddFrame("Frame_Compare", frame); 86 | } 87 | EPDGUI_PushFrame(frame); 88 | *((int*)(args[0])) = 0; 89 | } 90 | 91 | void key_home_cb(epdgui_args_vector_t &args) { 92 | Frame_Base *frame = EPDGUI_GetFrame("Frame_Home"); 93 | if (frame == NULL) { 94 | frame = new Frame_Home(); 95 | EPDGUI_AddFrame("Frame_Home", frame); 96 | } 97 | EPDGUI_PushFrame(frame); 98 | *((int*)(args[0])) = 0; 99 | } 100 | 101 | 102 | Frame_Main::Frame_Main(void): Frame_Base(false) { 103 | _frame_name = "Frame_Main"; 104 | _frame_id = 1; 105 | 106 | _bar = new M5EPD_Canvas(&M5.EPD); 107 | _bar->createCanvas(540, 44); 108 | _bar->setTextSize(26); 109 | 110 | _names = new M5EPD_Canvas(&M5.EPD); 111 | _names->createCanvas(540, 32); 112 | _names->setTextDatum(CC_DATUM); 113 | 114 | for (int i = 0; i < 4; i++) { 115 | _key[i] = new EPDGUI_Button("Test", 20 + i * 136, 90, KEY_W, KEY_H); 116 | } 117 | 118 | for (int i = 0; i < 4; i++) { 119 | _key[i + 4] = new EPDGUI_Button("Test", 20 + i * 136, 240, KEY_W, KEY_H); 120 | } 121 | 122 | _key[kKeySetting]->CanvasNormal()->pushImage(0, 0, 92, 92, ImageResource_main_icon_setting_92x92); 123 | *(_key[kKeySetting]->CanvasPressed()) = *(_key[kKeySetting]->CanvasNormal()); 124 | _key[kKeySetting]->CanvasPressed()->ReverseColor(); 125 | _key[kKeySetting]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 126 | _key[kKeySetting]->Bind(EPDGUI_Button::EVENT_RELEASED, key_setting_cb); 127 | 128 | _key[kKeyKeyboard]->CanvasNormal()->pushImage(0, 0, 92, 92, ImageResource_main_icon_keyboard_92x92); 129 | *(_key[kKeyKeyboard]->CanvasPressed()) = *(_key[kKeyKeyboard]->CanvasNormal()); 130 | _key[kKeyKeyboard]->CanvasPressed()->ReverseColor(); 131 | _key[kKeyKeyboard]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 132 | _key[kKeyKeyboard]->Bind(EPDGUI_Button::EVENT_RELEASED, key_keyboard_cb); 133 | 134 | _key[kKeyFactoryTest]->CanvasNormal()->pushImage(0, 0, 92, 92, ImageResource_main_icon_factorytest_92x92); 135 | *(_key[kKeyFactoryTest]->CanvasPressed()) = *(_key[kKeyFactoryTest]->CanvasNormal()); 136 | _key[kKeyFactoryTest]->CanvasPressed()->ReverseColor(); 137 | _key[kKeyFactoryTest]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 138 | _key[kKeyFactoryTest]->Bind(EPDGUI_Button::EVENT_RELEASED, key_factorytest_cb); 139 | 140 | // _key[kKeyWifiScan]->CanvasNormal()->pushImage(0, 0, 92, 92, ImageResource_main_icon_wifi_92x92); 141 | // *(_key[kKeyWifiScan]->CanvasPressed()) = *(_key[kKeyWifiScan]->CanvasNormal()); 142 | // _key[kKeyWifiScan]->CanvasPressed()->ReverseColor(); 143 | // _key[kKeyWifiScan]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 144 | // _key[kKeyWifiScan]->Bind(EPDGUI_Button::EVENT_RELEASED, key_wifiscan_cb); 145 | 146 | _key[kKeyLifeGame]->CanvasNormal()->pushImage(0, 0, 92, 92, ImageResource_main_icon_lifegame_92x92); 147 | *(_key[kKeyLifeGame]->CanvasPressed()) = *(_key[kKeyLifeGame]->CanvasNormal()); 148 | _key[kKeyLifeGame]->CanvasPressed()->ReverseColor(); 149 | _key[kKeyLifeGame]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 150 | _key[kKeyLifeGame]->Bind(EPDGUI_Button::EVENT_RELEASED, key_lifegame_cb); 151 | 152 | _key[kKeySDFile]->CanvasNormal()->pushImage(0, 0, 92, 92, ImageResource_main_icon_sdcard_92x92); 153 | *(_key[kKeySDFile]->CanvasPressed()) = *(_key[kKeySDFile]->CanvasNormal()); 154 | _key[kKeySDFile]->CanvasPressed()->ReverseColor(); 155 | _key[kKeySDFile]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 156 | _key[kKeySDFile]->Bind(EPDGUI_Button::EVENT_RELEASED, key_sdfile_cb); 157 | 158 | _key[kKeyCompare]->CanvasNormal()->pushImage(0, 0, 92, 92, ImageResource_main_icon_compare_92x92); 159 | *(_key[kKeyCompare]->CanvasPressed()) = *(_key[kKeyCompare]->CanvasNormal()); 160 | _key[kKeyCompare]->CanvasPressed()->ReverseColor(); 161 | _key[kKeyCompare]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 162 | _key[kKeyCompare]->Bind(EPDGUI_Button::EVENT_RELEASED, key_compare_cb); 163 | 164 | _key[kKeyHome]->CanvasNormal()->pushImage(0, 0, 92, 92, ImageResource_main_icon_home_92x92); 165 | *(_key[kKeyHome]->CanvasPressed()) = *(_key[kKeyHome]->CanvasNormal()); 166 | _key[kKeyHome]->CanvasPressed()->ReverseColor(); 167 | _key[kKeyHome]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 168 | _key[kKeyHome]->Bind(EPDGUI_Button::EVENT_RELEASED, key_home_cb); 169 | 170 | _time = 0; 171 | _next_update_time = 0; 172 | } 173 | 174 | 175 | Frame_Main::~Frame_Main(void) { 176 | for (int i = 0; i < 8; i++) { 177 | delete _key[i]; 178 | } 179 | } 180 | 181 | void Frame_Main::AppName(m5epd_update_mode_t mode) { 182 | if (!_names->isRenderExist(20)) { 183 | _names->createRender(20, 26); 184 | } 185 | _names->setTextSize(20); 186 | _names->fillCanvas(0); 187 | 188 | _names->drawString("Test", 20 + 46, 16); 189 | _names->drawString("Settings", 20 + 46 + 136, 16); 190 | _names->drawString("Keyboard", 20 + 46 + 2 * 136, 16); 191 | _names->drawString("Wi-Fi", 20 + 46 + 3 * 136, 16); 192 | _names->pushCanvas(0, 186, mode); 193 | 194 | _names->fillCanvas(0); 195 | _names->drawString("Storage", 20 + 46, 16); 196 | _names->drawString("Compare", 20 + 46 + 136, 16); 197 | _names->drawString("Home", 20 + 46 + 2 * 136, 16); 198 | _names->drawString("LifeGame", 20 + 46 + 3 * 136, 16); 199 | _names->pushCanvas(0, 337, mode); 200 | } 201 | 202 | void Frame_Main::StatusBar(m5epd_update_mode_t mode) { 203 | if ((millis() - _time) < _next_update_time) { 204 | return; 205 | } 206 | char buf[20]; 207 | _bar->fillCanvas(0); 208 | _bar->drawFastHLine(0, 43, 540, 15); 209 | _bar->setTextDatum(CL_DATUM); 210 | _bar->drawString("M5Paper", 10, 27); 211 | 212 | // Wi-Fi 213 | if (isWiFiConfiged()) { 214 | const uint8_t *kIMGWifiLevel[4] = { 215 | NULL, 216 | ImageResource_item_icon_wifi_1_32x32, 217 | ImageResource_item_icon_wifi_2_32x32, 218 | ImageResource_item_icon_wifi_3_32x32 219 | }; 220 | if (WiFi.status() == WL_CONNECTED) { 221 | int rssi = WiFi.RSSI(); 222 | int level = 0; 223 | if (rssi > -55) { 224 | level = 3; 225 | } else if (rssi > -88) { 226 | level = 2; 227 | } else { 228 | level = 1; 229 | } 230 | _bar->pushImage(134, 8, 32, 32, kIMGWifiLevel[level]); 231 | } /* else { 232 | WiFi.begin(GetWifiSSID(), GetWifiPassword()) 233 | } */ 234 | } 235 | 236 | // Battery 237 | _bar->setTextDatum(CR_DATUM); 238 | _bar->pushImage(498, 8, 32, 32, ImageResource_status_bar_battery_32x32); 239 | uint32_t vol = M5.getBatteryVoltage(); 240 | 241 | if (vol < 3300) { 242 | vol = 3300; 243 | } else if (vol > 4350) { 244 | vol = 4350; 245 | } 246 | float battery = (float)(vol - 3300) / (float)(4350 - 3300); 247 | if (battery <= 0.01) { 248 | battery = 0.01; 249 | } 250 | if (battery > 1) { 251 | battery = 1; 252 | } 253 | uint8_t px = battery * 25; 254 | sprintf(buf, "%d%%", (int)(battery * 100)); 255 | _bar->drawString(buf, 498 - 10, 27); 256 | _bar->fillRect(498 + 3, 8 + 10, px, 13, 15); 257 | // _bar->pushImage(498, 8, 32, 32, 2, ImageResource_status_bar_battery_charging_32x32); 258 | 259 | // Time 260 | rtc_time_t time_struct; 261 | rtc_date_t date_struct; 262 | M5.RTC.getTime(&time_struct); 263 | M5.RTC.getDate(&date_struct); 264 | sprintf(buf, "%2d:%02d", time_struct.hour, time_struct.min); 265 | _bar->setTextDatum(CC_DATUM); 266 | _bar->drawString(buf, 270, 27); 267 | _bar->pushCanvas(0, 0, mode); 268 | 269 | _time = millis(); 270 | _next_update_time = (60 - time_struct.sec) * 1000; 271 | } 272 | 273 | 274 | int Frame_Main::init(epdgui_args_vector_t &args) { 275 | _is_run = 1; 276 | M5.EPD.WriteFullGram4bpp(GetWallpaper()); 277 | for (int i = 0; i < 8; i++) { 278 | EPDGUI_AddObject(_key[i]); 279 | } 280 | _time = 0; 281 | _next_update_time = 0; 282 | StatusBar(UPDATE_MODE_NONE); 283 | AppName(UPDATE_MODE_NONE); 284 | return 9; 285 | } 286 | 287 | int Frame_Main::run() { 288 | StatusBar(UPDATE_MODE_GL16); 289 | return 1; 290 | } -------------------------------------------------------------------------------- /src/frame/frame_main.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_MAIN_H_ 2 | #define _FRAME_MAIN_H_ 3 | 4 | #include "frame_base.h" 5 | 6 | class Frame_Main : public Frame_Base { 7 | public: 8 | Frame_Main(); 9 | ~Frame_Main(); 10 | int run(); 11 | int init(epdgui_args_vector_t &args); 12 | void StatusBar(m5epd_update_mode_t mode); 13 | void AppName(m5epd_update_mode_t mode); 14 | 15 | private: 16 | EPDGUI_Button *_key[8]; 17 | M5EPD_Canvas *_bar; 18 | M5EPD_Canvas *_names; 19 | uint32_t _next_update_time; 20 | uint32_t _time; 21 | }; 22 | 23 | #endif //_FRAME_MAIN_H_ -------------------------------------------------------------------------------- /src/frame/frame_pictureviewer.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_pictureviewer.h" 2 | #include "SD.h" 3 | 4 | void key_pictureviewer_exit_cb(epdgui_args_vector_t &args) { 5 | EPDGUI_PopFrame(true); 6 | *((int*)(args[0])) = 0; 7 | } 8 | 9 | Frame_PictureViewer::Frame_PictureViewer(String path) { 10 | _frame_name = "Frame_PictureViewer"; 11 | _pic_path = path; 12 | 13 | _canvas_picture = new M5EPD_Canvas(&M5.EPD); 14 | _canvas_picture->createCanvas(540, 888); 15 | _canvas_picture->setTextSize(26); 16 | _canvas_picture->setTextColor(0); 17 | _canvas_picture->setTextDatum(CC_DATUM); 18 | 19 | exitbtn("Back"); 20 | 21 | _canvas_title->drawString(path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")), 270, 34); 22 | 23 | _key_exit->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 24 | _key_exit->Bind(EPDGUI_Button::EVENT_RELEASED, &key_pictureviewer_exit_cb); 25 | 26 | _is_first = true; 27 | } 28 | 29 | Frame_PictureViewer::~Frame_PictureViewer(void) { 30 | delete _canvas_picture; 31 | } 32 | 33 | void Frame_PictureViewer::err(String info) { 34 | _canvas_picture->fillCanvas(0); 35 | _canvas_picture->fillRect(254 - 150, 500 - 50, 300, 100, 15); 36 | _canvas_picture->drawString(info, 150, 55); 37 | } 38 | 39 | int Frame_PictureViewer::run() { 40 | if (_is_first) { 41 | _is_first = false; 42 | LoadingAnime_32x32_Start(254, 500); 43 | String suffix = _pic_path.substring(_pic_path.lastIndexOf(".")); 44 | if ((suffix.indexOf("bmp") >= 0) || (suffix.indexOf("BMP") >= 0)) { 45 | bool ret = _canvas_picture->drawBmpFile(SD, _pic_path.c_str(), 0, 0); 46 | if (ret == 0) { 47 | err("Error opening " + _pic_path.substring(_pic_path.lastIndexOf("/"))); 48 | } 49 | } else if ((suffix.indexOf("png") >= 0) || (suffix.indexOf("PNG") >= 0)) { 50 | bool ret = _canvas_picture->drawPngFile(SD, _pic_path.c_str()); 51 | if (ret == 0) { 52 | err("Error opening " + _pic_path.substring(_pic_path.lastIndexOf("/"))); 53 | } 54 | } else if ((suffix.indexOf("jpg") >= 0) || (suffix.indexOf("JPG") >= 0)) { 55 | bool ret = _canvas_picture->drawJpgFile(SD, _pic_path.c_str()); 56 | if (ret == 0) { 57 | err("Error opening " + _pic_path.substring(_pic_path.lastIndexOf("/"))); 58 | } 59 | } 60 | LoadingAnime_32x32_Stop(); 61 | _canvas_picture->pushCanvas(0, 72, UPDATE_MODE_GC16); 62 | } 63 | return 1; 64 | } 65 | 66 | int Frame_PictureViewer::init(epdgui_args_vector_t &args) { 67 | _is_run = 1; 68 | M5.EPD.Clear(); 69 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 70 | EPDGUI_AddObject(_key_exit); 71 | return 3; 72 | } 73 | 74 | 75 | -------------------------------------------------------------------------------- /src/frame/frame_pictureviewer.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_PICTUREVIEWER_H_ 2 | #define _FRAME_PICTUREVIEWER_H_ 3 | 4 | #include "frame_base.h" 5 | #include "../epdgui/epdgui.h" 6 | 7 | class Frame_PictureViewer : public Frame_Base { 8 | public: 9 | Frame_PictureViewer(String path); 10 | ~Frame_PictureViewer(); 11 | int init(epdgui_args_vector_t &args); 12 | int run(); 13 | void err(String info); 14 | 15 | private: 16 | M5EPD_Canvas *_canvas_picture; 17 | String _pic_path; 18 | bool _is_first; 19 | }; 20 | 21 | #endif //_FRAME_PICTUREVIEWER_H_ -------------------------------------------------------------------------------- /src/frame/frame_settings.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_settings.h" 2 | #include "frame_settings_wifi.h" 3 | #include "frame_settings_wallpaper.h" 4 | #include "WiFi.h" 5 | 6 | #define KEY_W 92 7 | #define KEY_H 92 8 | const uint16_t kTimeZoneY = 500; 9 | 10 | void key_shutdown_cb(epdgui_args_vector_t &args) { 11 | M5.EPD.WriteFullGram4bpp(GetWallpaper()); 12 | M5.EPD.UpdateFull(UPDATE_MODE_GC16); 13 | M5.EPD.UpdateFull(UPDATE_MODE_GC16); 14 | SaveSetting(); 15 | delay(600); 16 | M5.disableEPDPower(); 17 | M5.disableEXTPower(); 18 | M5.disableMainPower(); 19 | esp_deep_sleep_start(); 20 | while (true); 21 | } 22 | 23 | void key_restart_cb(epdgui_args_vector_t &args) { 24 | M5.EPD.WriteFullGram4bpp(GetWallpaper()); 25 | M5.EPD.UpdateFull(UPDATE_MODE_GC16); 26 | SaveSetting(); 27 | esp_restart(); 28 | } 29 | 30 | void key_wifi_cb(epdgui_args_vector_t &args) { 31 | Frame_Base *frame = EPDGUI_GetFrame("Frame_Settings_Wifi"); 32 | if (frame == NULL) { 33 | frame = new Frame_Settings_Wifi(); 34 | EPDGUI_AddFrame("Frame_Settings_Wifi", frame); 35 | } 36 | EPDGUI_PushFrame(frame); 37 | *((int*)(args[0])) = 0; 38 | } 39 | 40 | void key_wallpaper_cb(epdgui_args_vector_t &args) { 41 | Frame_Base *frame = EPDGUI_GetFrame("Frame_Settings_Wallpaper"); 42 | if (frame == NULL) { 43 | frame = new Frame_Settings_Wallpaper(); 44 | EPDGUI_AddFrame("Frame_Settings_Wallpaper", frame); 45 | } 46 | EPDGUI_PushFrame(frame); 47 | *((int*)(args[0])) = 0; 48 | } 49 | 50 | void key_synctime_cb(epdgui_args_vector_t &args) { 51 | // SaveSetting(); 52 | M5EPD_Canvas info(&M5.EPD); 53 | M5EPD_Canvas *title = (M5EPD_Canvas*)(args[0]); 54 | M5EPD_Canvas *tzone = (M5EPD_Canvas*)(args[1]); 55 | info.createCanvas(300, 100); 56 | info.fillCanvas(15); 57 | info.setTextSize(26); 58 | info.setTextColor(0); 59 | info.setTextDatum(CC_DATUM); 60 | if (WiFi.status() != WL_CONNECTED) { 61 | info.drawString("Wi-Fi not connected", 150, 55); 62 | info.pushCanvas(120, 430, UPDATE_MODE_GL16); 63 | M5.EPD.WriteFullGram4bpp(GetWallpaper()); 64 | title->pushCanvas(0, 8, UPDATE_MODE_NONE); 65 | tzone->pushCanvas(4, kTimeZoneY, UPDATE_MODE_NONE); 66 | EPDGUI_Draw(UPDATE_MODE_NONE); 67 | while (!M5.TP.avaliable()); 68 | M5.EPD.UpdateFull(UPDATE_MODE_GL16); 69 | return; 70 | } 71 | LoadingAnime_32x32_Start(532 - 15 - 32, 220 + 14); 72 | bool ret = SyncNTPTime(); 73 | LoadingAnime_32x32_Stop(); 74 | 75 | if (ret == 0) { 76 | info.drawString("Time sync failed", 150, 55); 77 | info.pushCanvas(120, 430, UPDATE_MODE_GL16); 78 | } else { 79 | info.drawString("Success", 150, 55); 80 | info.pushCanvas(120, 430, UPDATE_MODE_GL16); 81 | } 82 | M5.EPD.WriteFullGram4bpp(GetWallpaper()); 83 | title->pushCanvas(0, 8, UPDATE_MODE_NONE); 84 | tzone->pushCanvas(4, kTimeZoneY, UPDATE_MODE_NONE); 85 | EPDGUI_Draw(UPDATE_MODE_NONE); 86 | while (!M5.TP.avaliable()); 87 | M5.EPD.UpdateFull(UPDATE_MODE_GL16); 88 | } 89 | 90 | void key_timezone_plus_cb(epdgui_args_vector_t &args) { 91 | int *tz = (int*)(args[0]); 92 | (*tz)++; 93 | if ((*tz) > 12) { 94 | (*tz) = 12; 95 | } 96 | String str = String(*tz); 97 | if ((*tz) > 0) { 98 | str = "+" + str; 99 | } 100 | ((EPDGUI_Button*)(args[1]))->setLabel(str); 101 | ((EPDGUI_Button*)(args[1]))->Draw(UPDATE_MODE_GL16); 102 | SetTimeZone(*tz); 103 | } 104 | 105 | void key_timezone_minus_cb(epdgui_args_vector_t &args) { 106 | int *tz = (int*)(args[0]); 107 | (*tz)--; 108 | if ((*tz) < -11) { 109 | (*tz) = -11; 110 | } 111 | String str = String(*tz); 112 | if ((*tz) > 0) { 113 | str = "+" + str; 114 | } 115 | ((EPDGUI_Button*)(args[1]))->setLabel(str); 116 | ((EPDGUI_Button*)(args[1]))->Draw(UPDATE_MODE_GL16); 117 | SetTimeZone(*tz); 118 | } 119 | 120 | void key_timezone_reset_cb(epdgui_args_vector_t &args) { 121 | int *tz = (int*)(args[0]); 122 | (*tz) = 0; 123 | ((EPDGUI_Button*)(args[1]))->setLabel(String(*tz)); 124 | ((EPDGUI_Button*)(args[1]))->Draw(UPDATE_MODE_GL16); 125 | SetTimeZone(*tz); 126 | } 127 | 128 | Frame_Settings::Frame_Settings(void) { 129 | _frame_name = "Frame_Settings"; 130 | 131 | _timezone_canvas = new M5EPD_Canvas(&M5.EPD); 132 | _timezone_canvas->createCanvas(540, 60); 133 | _timezone_canvas->fillCanvas(0); 134 | _timezone_canvas->setTextSize(26); 135 | _timezone_canvas->setTextColor(15); 136 | _timezone_canvas->setTextDatum(CL_DATUM); 137 | _timezone_canvas->drawRect(0, 0, 540, 60, 15); 138 | 139 | _key_wifi = new EPDGUI_Button(4, 100, 532, 61); 140 | _key_wallpaper = new EPDGUI_Button(4, 160, 532, 61); 141 | _key_syncntp = new EPDGUI_Button(4, 220, 532, 61); 142 | _key_restart = new EPDGUI_Button(4, 320, 532, 61); 143 | _key_shutdown = new EPDGUI_Button(4, 380, 532, 61); 144 | 145 | key_timezone_plus = new EPDGUI_Button("+", 448, kTimeZoneY + 2, 88, 52); 146 | String str = String(GetTimeZone()); 147 | if (GetTimeZone() > 0) { 148 | str = "+" + str; 149 | } 150 | key_timezone_reset = new EPDGUI_Button(str, 360, kTimeZoneY + 2, 88, 52); 151 | key_timezone_minus = new EPDGUI_Button("–", 272, kTimeZoneY + 2, 88, 52); 152 | 153 | key_timezone_plus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, &_timezone); 154 | key_timezone_plus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, key_timezone_reset); 155 | key_timezone_plus->Bind(EPDGUI_Button::EVENT_RELEASED, key_timezone_plus_cb); 156 | 157 | key_timezone_reset->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, &_timezone); 158 | key_timezone_reset->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, key_timezone_reset); 159 | key_timezone_reset->Bind(EPDGUI_Button::EVENT_RELEASED, key_timezone_reset_cb); 160 | 161 | key_timezone_minus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, &_timezone); 162 | key_timezone_minus->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, key_timezone_reset); 163 | key_timezone_minus->Bind(EPDGUI_Button::EVENT_RELEASED, key_timezone_minus_cb); 164 | 165 | _key_wifi->setBMPButton(" Wi-Fi", "\u25B6", ImageResource_item_icon_wifi_3_32x32); 166 | _key_wallpaper->setBMPButton(" Wallpaper", "\u25B6", ImageResource_item_icon_wallpaper_32x32); 167 | _key_syncntp->setBMPButton(" Sync Time", "", ImageResource_item_icon_ntptime_32x32); 168 | _key_restart->setBMPButton(" Restart", "", ImageResource_item_icon_restart_32x32); 169 | _key_shutdown->setBMPButton(" Shutdown", "", ImageResource_item_icon_shutdown_32x32); 170 | _timezone_canvas->drawString("Time Zone (UTC)", 15, 35); 171 | exitbtn("Home"); 172 | _canvas_title->drawString("Settings", 270, 34); 173 | 174 | _key_exit->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 175 | _key_exit->Bind(EPDGUI_Button::EVENT_RELEASED, &Frame_Base::exit_cb); 176 | 177 | _key_wifi->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 178 | _key_wifi->Bind(EPDGUI_Button::EVENT_RELEASED, &key_wifi_cb); 179 | 180 | _key_wallpaper->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 181 | _key_wallpaper->Bind(EPDGUI_Button::EVENT_RELEASED, &key_wallpaper_cb); 182 | 183 | _key_shutdown->Bind(EPDGUI_Button::EVENT_RELEASED, &key_shutdown_cb); 184 | _key_restart->Bind(EPDGUI_Button::EVENT_RELEASED, &key_restart_cb); 185 | _key_syncntp->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, _canvas_title); 186 | _key_syncntp->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, _timezone_canvas); 187 | _key_syncntp->Bind(EPDGUI_Button::EVENT_RELEASED, &key_synctime_cb); 188 | 189 | _timezone = GetTimeZone(); 190 | } 191 | 192 | Frame_Settings::~Frame_Settings(void) { 193 | delete _key_wifi; 194 | delete _key_wallpaper; 195 | delete _key_shutdown; 196 | delete _key_restart; 197 | delete _key_syncntp; 198 | } 199 | 200 | int Frame_Settings::init(epdgui_args_vector_t &args) { 201 | _is_run = 1; 202 | M5.EPD.WriteFullGram4bpp(GetWallpaper()); 203 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 204 | _timezone_canvas->pushCanvas(0, kTimeZoneY, UPDATE_MODE_NONE); 205 | EPDGUI_AddObject(_key_wifi); 206 | EPDGUI_AddObject(_key_wallpaper); 207 | EPDGUI_AddObject(_key_shutdown); 208 | EPDGUI_AddObject(_key_restart); 209 | EPDGUI_AddObject(_key_syncntp); 210 | EPDGUI_AddObject(_key_exit); 211 | EPDGUI_AddObject(key_timezone_plus); 212 | EPDGUI_AddObject(key_timezone_reset); 213 | EPDGUI_AddObject(key_timezone_minus); 214 | return 3; 215 | } -------------------------------------------------------------------------------- /src/frame/frame_settings.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_SETTINGS_H_ 2 | #define _FRAME_SETTINGS_H_ 3 | 4 | #include "frame_base.h" 5 | #include "../epdgui/epdgui.h" 6 | 7 | class Frame_Settings : public Frame_Base { 8 | public: 9 | Frame_Settings(); 10 | ~Frame_Settings(); 11 | int init(epdgui_args_vector_t &args); 12 | 13 | 14 | private: 15 | EPDGUI_Button *_key_wifi; 16 | EPDGUI_Button *_key_wallpaper; 17 | EPDGUI_Button *_key_shutdown; 18 | EPDGUI_Button *_key_restart; 19 | EPDGUI_Button *_key_syncntp; 20 | 21 | EPDGUI_Button *key_timezone_plus; 22 | EPDGUI_Button *key_timezone_reset; 23 | EPDGUI_Button *key_timezone_minus; 24 | int _timezone; 25 | M5EPD_Canvas *_timezone_canvas; 26 | }; 27 | 28 | #endif //_FRAME_SETTINGS_H_ -------------------------------------------------------------------------------- /src/frame/frame_settings_wallpaper.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_settings_wallpaper.h" 2 | 3 | void sw_wallpapers_cb(epdgui_args_vector_t &args) { 4 | SetWallpaper(*((uint32_t*)(args[0]))); 5 | } 6 | 7 | Frame_Settings_Wallpaper::Frame_Settings_Wallpaper(void) { 8 | _frame_name = "Frame_Settings_Wallpaper"; 9 | 10 | _sw_mutex_group = new EPDGUI_MutexSwitch(); 11 | 12 | for (int i = 0; i < WALLPAPER_NUM; i++) { 13 | _sw_wallpapers[i] = new EPDGUI_Switch(2, 4, 100 + i * 60, 532, 61); 14 | _sw_mutex_group->Add(_sw_wallpapers[i]); 15 | _sw_wallpapers[i]->SetLabel(0, GetWallpaperName(i)); 16 | _sw_wallpapers[i]->SetLabel(1, GetWallpaperName(i)); 17 | _sw_wallpapers[i]->Canvas(1)->ReverseColor(); 18 | _sw_wallpapers[i]->SetID(i); 19 | _sw_wallpapers[i]->AddArgs(EPDGUI_Switch::EVENT_PRESSED, 0, (void*)(_sw_wallpapers[i]->GetID_P())); 20 | _sw_wallpapers[i]->Bind(1, &sw_wallpapers_cb); 21 | } 22 | _sw_wallpapers[GetWallpaperID()]->setState(1); 23 | 24 | exitbtn("Settings"); 25 | _canvas_title->drawString("Wallpaper", 270, 34); 26 | 27 | _key_exit->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 28 | _key_exit->Bind(EPDGUI_Button::EVENT_RELEASED, &Frame_Base::exit_cb); 29 | } 30 | 31 | Frame_Settings_Wallpaper::~Frame_Settings_Wallpaper(void) { 32 | for (int i = 0; i < WALLPAPER_NUM; i++) { 33 | delete _sw_wallpapers[i]; 34 | } 35 | delete _sw_mutex_group; 36 | } 37 | 38 | int Frame_Settings_Wallpaper::init(epdgui_args_vector_t &args) { 39 | _is_run = 1; 40 | M5.EPD.WriteFullGram4bpp(GetWallpaper()); 41 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 42 | EPDGUI_AddObject(_sw_mutex_group); 43 | EPDGUI_AddObject(_key_exit); 44 | return 2; 45 | } -------------------------------------------------------------------------------- /src/frame/frame_settings_wallpaper.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_WALLPAPER_H_ 2 | #define _FRAME_WALLPAPER_H_ 3 | 4 | #include "frame_base.h" 5 | #include "../epdgui/epdgui.h" 6 | 7 | class Frame_Settings_Wallpaper : public Frame_Base { 8 | public: 9 | Frame_Settings_Wallpaper(); 10 | ~Frame_Settings_Wallpaper(); 11 | int init(epdgui_args_vector_t &args); 12 | 13 | private: 14 | EPDGUI_Switch* _sw_wallpapers[WALLPAPER_NUM]; 15 | EPDGUI_MutexSwitch* _sw_mutex_group; 16 | }; 17 | 18 | #endif //_FRAME_WALLPAPER_H_ -------------------------------------------------------------------------------- /src/frame/frame_settings_wifi.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_settings_wifi.h" 2 | #include "frame_settings_wifi_password.h" 3 | #include 4 | 5 | #define MAX_BTN_NUM 14 6 | #define MAX_WIFI_NUM (MAX_BTN_NUM - 1) 7 | bool _update_flag = false; 8 | EPDGUI_Button *_connect_key = NULL; 9 | 10 | void key_wifi_network_cb(epdgui_args_vector_t &args) { 11 | if (((EPDGUI_Button*)(args[0]))->GetCustomString() == "_$refresh$_") { 12 | _update_flag = true; 13 | } else { 14 | _connect_key = (EPDGUI_Button*)(args[0]); 15 | Frame_Base *frame = EPDGUI_GetFrame("Frame_Settings_Wifi_Password"); 16 | if (frame == NULL) { 17 | frame = new Frame_Settings_Wifi_Password(); 18 | EPDGUI_AddFrame("Frame_Settings_Wifi_Password", frame); 19 | } 20 | EPDGUI_PushFrame(frame); 21 | *((int*)(args[1])) = 0; 22 | } 23 | } 24 | 25 | Frame_Settings_Wifi::Frame_Settings_Wifi(void) { 26 | _frame_name = "Frame_Settings_Wifi"; 27 | 28 | for (int i = 0; i < MAX_BTN_NUM; i++) { 29 | _key_wifi[i] = new EPDGUI_Button(4, 100 + i * 60, 532, 61); 30 | _key_wifi[i]->SetHide(true); 31 | _key_wifi[i]->CanvasNormal()->setTextSize(26); 32 | _key_wifi[i]->CanvasNormal()->setTextDatum(CL_DATUM); 33 | _key_wifi[i]->CanvasNormal()->setTextColor(15); 34 | _key_wifi[i]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, _key_wifi[i]); 35 | _key_wifi[i]->AddArgs(EPDGUI_Button::EVENT_RELEASED, 1, (void*)(&_is_run)); 36 | _key_wifi[i]->Bind(EPDGUI_Button::EVENT_RELEASED, key_wifi_network_cb); 37 | } 38 | 39 | exitbtn("Settings"); 40 | _canvas_title->drawString("Wi-Fi", 270, 34); 41 | 42 | _key_exit->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 43 | _key_exit->Bind(EPDGUI_Button::EVENT_RELEASED, &Frame_Base::exit_cb); 44 | 45 | _update_flag = true; 46 | _connected = 0; 47 | } 48 | 49 | Frame_Settings_Wifi::~Frame_Settings_Wifi(void) { 50 | for (int i = 0; i < MAX_BTN_NUM; i++) { 51 | delete _key_wifi[i]; 52 | } 53 | } 54 | 55 | void Frame_Settings_Wifi::DrawItem(EPDGUI_Button *btn, String ssid, int rssi) { 56 | const uint8_t *kIMGWifiLevel[4] = { 57 | NULL, 58 | ImageResource_item_icon_wifi_1_32x32, 59 | ImageResource_item_icon_wifi_2_32x32, 60 | ImageResource_item_icon_wifi_3_32x32 61 | }; 62 | int level = 0; 63 | if (rssi > -55) { 64 | level = 3; 65 | } else if (rssi > -88) { 66 | level = 2; 67 | } else { 68 | level = 1; 69 | } 70 | if (ssid.length() > 22) { 71 | ssid = ssid.substring(0, 22) + "..."; 72 | } 73 | btn->SetHide(false); 74 | btn->CanvasNormal()->fillCanvas(0); 75 | btn->CanvasNormal()->drawRect(0, 0, 532, 61, 15); 76 | btn->CanvasNormal()->drawString(ssid, 15, 35); 77 | btn->SetCustomString(ssid); 78 | btn->CanvasNormal()->pushImage(532 - 15 - 32, 14, 32, 32, kIMGWifiLevel[level]); 79 | *(btn->CanvasPressed()) = *(btn->CanvasNormal()); 80 | btn->CanvasPressed()->ReverseColor(); 81 | } 82 | 83 | int Frame_Settings_Wifi::run() { 84 | if (_connect) { 85 | _connect = false; 86 | Connect(); 87 | } 88 | if (_update_flag) { 89 | _update_flag = false; 90 | scan(); 91 | } 92 | return 1; 93 | } 94 | 95 | int Frame_Settings_Wifi::scan() { 96 | WiFi.mode(WIFI_STA); 97 | // WiFi.disconnect(); 98 | WiFi.scanNetworks(true); 99 | 100 | if (_scan_count > 0) { 101 | M5.EPD.WriteFullGram4bpp(GetWallpaper()); 102 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 103 | _key_exit->Draw(UPDATE_MODE_NONE); 104 | M5.EPD.UpdateFull(UPDATE_MODE_GC16); 105 | } 106 | _scan_count++; 107 | 108 | int wifi_num; 109 | while (true) { 110 | wifi_num = WiFi.scanComplete(); 111 | if (wifi_num >= 0) { 112 | break; 113 | } 114 | } 115 | 116 | int connect_wifi_idx = -1; 117 | if (_connected) { 118 | for (int i = 0; i < wifi_num; i++) { 119 | String ssid = WiFi.SSID(i); 120 | 121 | if (ssid == _connect_ssid) { 122 | connect_wifi_idx = i; 123 | if (WiFi.RSSI(i) < -90) { 124 | connect_wifi_idx = -1; 125 | } 126 | break; 127 | } 128 | } 129 | if (connect_wifi_idx == -1) { 130 | // WiFi.disconnect(); 131 | _key_wifi[0]->SetEnable(true); 132 | _connected = 0; 133 | for (int i = 1; i < MAX_BTN_NUM; i++) { 134 | _key_wifi[i]->SetPos(_key_wifi[i]->getX(), _key_wifi[i]->getY() - 32); 135 | } 136 | } 137 | } 138 | 139 | wifi_num = wifi_num > MAX_WIFI_NUM ? MAX_WIFI_NUM : wifi_num; 140 | wifi_num -= _connected; 141 | 142 | for (int i = _connected; i < MAX_BTN_NUM; i++) { 143 | _key_wifi[i]->SetHide(true); 144 | } 145 | 146 | if (_connected) { 147 | _key_wifi[0]->Draw(UPDATE_MODE_A2); 148 | } 149 | 150 | int idx = 0, cnt = _connected; 151 | while (true) { 152 | if (idx == connect_wifi_idx) { 153 | idx++; 154 | continue; 155 | } 156 | 157 | String ssid = WiFi.SSID(idx); 158 | DrawItem(_key_wifi[cnt], ssid, WiFi.RSSI(idx)); 159 | _key_wifi[cnt]->Draw(UPDATE_MODE_A2); 160 | 161 | idx++; 162 | if (idx == wifi_num) { 163 | break; 164 | } 165 | 166 | cnt++; 167 | } 168 | 169 | _key_wifi[wifi_num]->SetCustomString("_$refresh$_"); 170 | _key_wifi[wifi_num]->SetHide(false); 171 | _key_wifi[wifi_num]->CanvasNormal()->fillCanvas(0); 172 | _key_wifi[wifi_num]->CanvasNormal()->drawRect(0, 0, 532, 61, 15); 173 | _key_wifi[wifi_num]->CanvasNormal()->pushImage(15, 14, 32, 32, ImageResource_item_icon_refresh_32x32); 174 | _key_wifi[wifi_num]->CanvasNormal()->drawString("Refresh", 58, 35); 175 | *(_key_wifi[wifi_num]->CanvasPressed()) = *(_key_wifi[wifi_num]->CanvasNormal()); 176 | _key_wifi[wifi_num]->CanvasPressed()->ReverseColor(); 177 | _key_wifi[wifi_num]->Draw(UPDATE_MODE_A2); 178 | 179 | M5.EPD.UpdateFull(UPDATE_MODE_GL16); 180 | // M5.EPD.UpdateArea(0, 64, 540, 72, UPDATE_MODE_GL16); 181 | 182 | WiFi.scanDelete(); 183 | 184 | return 0; 185 | } 186 | 187 | void Frame_Settings_Wifi::Connect() { 188 | int anime_cnt = 0; 189 | int x = 532 - 15 - 32; 190 | int y = _connect_key->getY() + 14; 191 | M5EPD_Canvas loading(&M5.EPD); 192 | loading.createCanvas(32, 32); 193 | loading.fillCanvas(0); 194 | loading.pushCanvas(x, y, UPDATE_MODE_GL16); 195 | _connect_ssid = _connect_key->GetCustomString(); 196 | log_d("SSID = [%s]\n", _connect_ssid.c_str()); 197 | log_d("PSWD = [%s]\n", _connect_password.c_str()); 198 | WiFi.disconnect(); 199 | WiFi.begin(_connect_ssid.c_str(), _connect_password.c_str()); 200 | uint32_t start_time = millis(); 201 | while (WiFi.status() != WL_CONNECTED) { 202 | loading.pushImage(0, 0, 32, 32, GetLoadingIMG_32x32(anime_cnt)); 203 | loading.pushCanvas(x, y, UPDATE_MODE_DU4); 204 | anime_cnt++; 205 | if (anime_cnt == 16) { 206 | anime_cnt = 0; 207 | } 208 | 209 | if (millis() - start_time > 30000) { 210 | M5EPD_Canvas err(&M5.EPD); 211 | err.createCanvas(300, 100); 212 | err.fillCanvas(15); 213 | err.setTextSize(26); 214 | err.setTextColor(0); 215 | err.setTextDatum(CC_DATUM); 216 | err.drawString("Wrong password", 150, 55); 217 | err.pushCanvas(120, 430, UPDATE_MODE_GL16); 218 | return; 219 | } 220 | } 221 | 222 | for (int i = 1; i < MAX_BTN_NUM; i++) { 223 | _key_wifi[i]->SetPos(_key_wifi[i]->getX(), _key_wifi[i]->getY() + 32); 224 | } 225 | 226 | _connect_key->CanvasNormal()->pushImage(532 - 15 - 32, 14, 32, 32, ImageResource_item_icon_success_32x32); 227 | 228 | _key_wifi[0]->SetEnable(false); 229 | _key_wifi[0]->SetHide(false); 230 | if (_connect_key != _key_wifi[0]) { 231 | *(_key_wifi[0]->CanvasNormal()) = *(_connect_key->CanvasNormal()); 232 | *(_key_wifi[0]->CanvasPressed()) = *(_connect_key->CanvasNormal()); 233 | _key_wifi[0]->CanvasPressed()->ReverseColor(); 234 | } 235 | loading.pushImage(0, 0, 32, 32, ImageResource_item_icon_success_32x32); 236 | loading.pushCanvas(x, y, UPDATE_MODE_GL16); 237 | _connected = 1; 238 | 239 | SetWifi(_connect_ssid, _connect_password); 240 | log_d("Saved Wifi Network"); 241 | SyncNTPTime(); 242 | scan(); 243 | } 244 | 245 | void Frame_Settings_Wifi::SetConnected(String ssid, int rssi) { 246 | _connect_ssid = ssid; 247 | DrawItem(_key_wifi[0], ssid, rssi); 248 | for (int i = 1; i < MAX_BTN_NUM; i++) { 249 | _key_wifi[i]->SetPos(_key_wifi[i]->getX(), _key_wifi[i]->getY() + 32); 250 | } 251 | _key_wifi[0]->SetEnable(false); 252 | _key_wifi[0]->SetHide(false); 253 | _connected = 1; 254 | } 255 | 256 | int Frame_Settings_Wifi::init(epdgui_args_vector_t &args) { 257 | _is_run = 1; 258 | M5.EPD.WriteFullGram4bpp(GetWallpaper()); 259 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 260 | if (args.size() > 0) { 261 | String *password = (String*)(args[0]); 262 | _connect_password = *password; 263 | delete password; 264 | args.pop_back(); 265 | 266 | for (int i = 0; i < MAX_BTN_NUM; i++) { 267 | EPDGUI_AddObject(_key_wifi[i]); 268 | } 269 | _update_flag = false; 270 | _connect = true; 271 | } else { 272 | for (int i = 0; i < MAX_BTN_NUM; i++) { 273 | _key_wifi[i]->SetHide(true); 274 | EPDGUI_AddObject(_key_wifi[i]); 275 | } 276 | if (_connected) { 277 | _key_wifi[0]->SetHide(false); 278 | } 279 | _update_flag = true; 280 | _scan_count = 0; 281 | _connect = false; 282 | } 283 | EPDGUI_AddObject(_key_exit); 284 | return 2; 285 | } -------------------------------------------------------------------------------- /src/frame/frame_settings_wifi.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_SETTINGS_WIFI_H_ 2 | #define _FRAME_SETTINGS_WIFI_H_ 3 | 4 | #include "frame_base.h" 5 | #include "../epdgui/epdgui.h" 6 | 7 | class Frame_Settings_Wifi : public Frame_Base { 8 | public: 9 | Frame_Settings_Wifi(); 10 | ~Frame_Settings_Wifi(); 11 | int init(epdgui_args_vector_t &args); 12 | int scan(); 13 | int run(); 14 | void Connect(); 15 | void DrawItem(EPDGUI_Button *btn, String ssid, int rssi); 16 | void SetConnected(String ssid, int rssi); 17 | 18 | private: 19 | EPDGUI_Button *_key_wifi[14]; 20 | uint32_t _scan_count = 0; 21 | bool _connect; 22 | uint8_t _connected; 23 | String _connect_ssid; 24 | String _connect_password; 25 | }; 26 | 27 | #endif //_FRAME_SETTINGS_WIFI_H_ -------------------------------------------------------------------------------- /src/frame/frame_settings_wifi_password.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_settings_wifi_password.h" 2 | 3 | 4 | void key_passwordclear_cb(epdgui_args_vector_t &args) { 5 | ((EPDGUI_Textbox*)(args[0]))->SetText(""); 6 | } 7 | 8 | Frame_Settings_Wifi_Password::Frame_Settings_Wifi_Password() : Frame_Base() { 9 | _frame_name = "Frame_Settings_Wifi_Password"; 10 | const uint16_t kKeyBaseY = 176; 11 | inputbox = new EPDGUI_Textbox(4, 100, 532, 60); 12 | key_textclear = new EPDGUI_Button("CLR", 4, kKeyBaseY, 260, 52); 13 | 14 | inputbox->SetTextMargin(8, 15, 8, 8); 15 | inputbox->SetState(EPDGUI_Textbox::EVENT_PRESSED); 16 | 17 | keyboard = new EPDGUI_Keyboard(EPDGUI_Keyboard::STYLE_INPUTMODE_NEEDCONFIRM); 18 | 19 | key_textclear->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)inputbox); 20 | key_textclear->Bind(EPDGUI_Button::EVENT_RELEASED, key_passwordclear_cb); 21 | 22 | exitbtn("Wi-Fi"); 23 | _canvas_title->drawString("Password", 270, 34); 24 | 25 | _key_exit->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 26 | _key_exit->Bind(EPDGUI_Button::EVENT_RELEASED, &Frame_Base::exit_cb); 27 | } 28 | 29 | Frame_Settings_Wifi_Password::~Frame_Settings_Wifi_Password() { 30 | delete inputbox; 31 | delete keyboard; 32 | delete key_textclear; 33 | } 34 | 35 | int Frame_Settings_Wifi_Password::init(epdgui_args_vector_t &args) { 36 | _is_run = 1; 37 | M5.EPD.Clear(); 38 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 39 | EPDGUI_AddObject(inputbox); 40 | EPDGUI_AddObject(keyboard); 41 | EPDGUI_AddObject(_key_exit); 42 | EPDGUI_AddObject(key_textclear); 43 | return 6; 44 | } 45 | 46 | int Frame_Settings_Wifi_Password::run(void) { 47 | String data = keyboard->getData(); 48 | if (data.indexOf("\n") >= 0) { 49 | String *pswd = new String(inputbox->GetText()); 50 | EPDGUI_AddFrameArg("Frame_Settings_Wifi", 0, pswd); 51 | inputbox->SetText(""); 52 | EPDGUI_PopFrame(); 53 | _is_run = 0; 54 | return 0; 55 | } 56 | inputbox->AddText(data); 57 | return 1; 58 | } 59 | -------------------------------------------------------------------------------- /src/frame/frame_settings_wifi_password.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_SETTINGS_WIFI_PASSWORD_H_ 2 | #define _FRAME_SETTINGS_WIFI_PASSWORD_H_ 3 | 4 | #include "frame_base.h" 5 | #include "../epdgui/epdgui.h" 6 | 7 | class Frame_Settings_Wifi_Password : public Frame_Base { 8 | public: 9 | Frame_Settings_Wifi_Password(); 10 | ~Frame_Settings_Wifi_Password(); 11 | int run(); 12 | int init(epdgui_args_vector_t &args); 13 | 14 | private: 15 | EPDGUI_Textbox *inputbox; 16 | EPDGUI_Keyboard *keyboard; 17 | EPDGUI_Button *key_textclear; 18 | }; 19 | 20 | #endif //_FRAME_SETTINGS_WIFI_PASSWORD_H_ -------------------------------------------------------------------------------- /src/frame/frame_txtreader.cpp: -------------------------------------------------------------------------------- 1 | #include "frame_txtreader.h" 2 | 3 | void key_txtreader_exit_cb(epdgui_args_vector_t &args) { 4 | EPDGUI_PopFrame(true); 5 | *((int*)(args[0])) = 0; 6 | } 7 | 8 | int8_t _key_operation = 0; 9 | void key_nextpage_released_cb(epdgui_args_vector_t &args) { 10 | _key_operation = 1; 11 | // *((int8_t*)(args[0])) = 1; 12 | } 13 | 14 | void key_prevpage_released_cb(epdgui_args_vector_t &args) { 15 | _key_operation = -1; 16 | // *((int8_t*)(args[0])) = -1; 17 | } 18 | 19 | Frame_txtReader::Frame_txtReader(String path) { 20 | _frame_name = "Frame_txtReader"; 21 | _txt_path = path; 22 | _text_size = GetTextSize(); 23 | 24 | _canvas_prev = new M5EPD_Canvas(&M5.EPD); 25 | _canvas_current = new M5EPD_Canvas(&M5.EPD); 26 | _canvas_next = new M5EPD_Canvas(&M5.EPD); 27 | _canvas_page = new M5EPD_Canvas(&M5.EPD); 28 | 29 | _key_next = new EPDGUI_Button("", 270, 72, 270, 888, EPDGUI_Button::STYLE_INVISABLE); 30 | _key_prev = new EPDGUI_Button("", 0, 72, 270, 888, EPDGUI_Button::STYLE_INVISABLE); 31 | // _key_next->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, &_key_operation); 32 | _key_next->Bind(EPDGUI_Button::EVENT_RELEASED, key_nextpage_released_cb); 33 | // _key_prev->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, &_key_operation); 34 | _key_prev->Bind(EPDGUI_Button::EVENT_RELEASED, key_prevpage_released_cb); 35 | 36 | exitbtn("Back"); 37 | 38 | _canvas_title->drawString(path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")), 270, 34); 39 | 40 | _key_exit->AddArgs(EPDGUI_Button::EVENT_RELEASED, 0, (void*)(&_is_run)); 41 | _key_exit->Bind(EPDGUI_Button::EVENT_RELEASED, &key_txtreader_exit_cb); 42 | } 43 | 44 | Frame_txtReader::~Frame_txtReader(void) { 45 | if (_text_size != 26) { 46 | _canvas_prev->destoryRender(_text_size); 47 | } 48 | delete _canvas_prev; 49 | delete _canvas_current; 50 | delete _canvas_next; 51 | delete _canvas_page; 52 | delete _key_next; 53 | delete _key_prev; 54 | _txt_file.close(); 55 | } 56 | 57 | uint32_t Frame_txtReader::renderText(uint32_t cursor, uint32_t length, M5EPD_Canvas *canvas) { 58 | canvas->fillCanvas(0); 59 | canvas->setTextArea(10, 10, 520, 868); 60 | canvas->setTextSize(_text_size); 61 | 62 | char buf[length + 1]; 63 | _txt_file.seek(cursor, SeekSet); 64 | uint32_t readlen = _txt_file.readBytes(buf, length); 65 | buf[readlen] = '\0'; 66 | canvas->print(buf); 67 | return canvas->getExceedOffset(); 68 | } 69 | 70 | int Frame_txtReader::run() { 71 | if (_is_first) { 72 | LoadingAnime_32x32_Start(254, 500); 73 | _is_first = false; 74 | uint32_t cursor; 75 | _page_cursor.insert(std::pair(0, 0)); 76 | cursor = renderText(0, _render_len, _canvas_current); 77 | if (cursor == 0) { 78 | _page_end = 0; 79 | _end_accessed = true; 80 | } else { 81 | _page_end = _page + 1; 82 | _page_cursor.insert(std::pair(1, cursor)); 83 | uint32_t offset = renderText(_page_cursor[1], _render_len, _canvas_next); 84 | if (offset == 0) { 85 | _page_end = 1; 86 | _end_accessed = true; 87 | } else { 88 | _page_cursor.insert(std::pair(2, cursor + offset)); 89 | } 90 | } 91 | LoadingAnime_32x32_Stop(); 92 | _canvas_current->pushCanvas(0, 72, UPDATE_MODE_GC16); 93 | } else { 94 | M5.update(); 95 | if (M5.BtnR.wasReleased() || (_key_operation == 1)) { 96 | _key_operation = 0; 97 | if (_page != _page_end) { 98 | _page++; 99 | _canvas_next->pushCanvas(0, 72, UPDATE_MODE_GC16); 100 | memcpy(_canvas_prev->frameBuffer(), _canvas_current->frameBuffer(), _canvas_current->getBufferSize()); 101 | memcpy(_canvas_current->frameBuffer(), _canvas_next->frameBuffer(), _canvas_next->getBufferSize()); 102 | 103 | if ((_end_accessed == false) || (_page != _page_end)) { 104 | uint32_t offset = renderText(_page_cursor[_page + 1], _render_len, _canvas_next); 105 | 106 | if (offset != 0) { 107 | if (_page_cursor.count(_page + 2) == 0) { 108 | _page_cursor.insert(std::pair(_page + 2, _page_cursor[_page + 1] + offset)); 109 | } 110 | } else if (_end_accessed == false) { 111 | _page_end = _page + 1; 112 | _end_accessed = true; 113 | } 114 | if (!_end_accessed) { 115 | _page_end = _page + 1; 116 | } 117 | } 118 | } 119 | } else if (M5.BtnL.wasReleased() || (_key_operation == -1)) { 120 | _key_operation = 0; 121 | if (_page > 0) { 122 | _page--; 123 | _canvas_prev->pushCanvas(0, 72, UPDATE_MODE_GC16); 124 | memcpy(_canvas_next->frameBuffer(), _canvas_current->frameBuffer(), _canvas_current->getBufferSize()); 125 | memcpy(_canvas_current->frameBuffer(), _canvas_prev->frameBuffer(), _canvas_prev->getBufferSize()); 126 | if (_page != 0) { 127 | renderText(_page_cursor[_page - 1], _render_len, _canvas_prev); 128 | } 129 | } 130 | } 131 | } 132 | if (_last_page != _page) { 133 | _last_page = _page; 134 | _canvas_page->setTextSize(26); 135 | _canvas_page->fillCanvas(0); 136 | char buf[5]; 137 | sprintf(buf, "%d", _page + 1); 138 | _canvas_page->drawString(buf, 100, 42); 139 | _canvas_page->pushCanvas(440 - 15, 0, UPDATE_MODE_GL16); 140 | } 141 | return 1; 142 | } 143 | 144 | int Frame_txtReader::init(epdgui_args_vector_t &args) { 145 | _is_run = 1; 146 | M5.EPD.Clear(); 147 | _canvas_title->pushCanvas(0, 8, UPDATE_MODE_NONE); 148 | _canvas_prev->createCanvas(540, 888); 149 | _canvas_current->createCanvas(540, 888); 150 | _canvas_next->createCanvas(540, 888); 151 | _canvas_page->createCanvas(100, 60); 152 | _canvas_page->setTextDatum(CR_DATUM); 153 | if (!_canvas_prev->isRenderExist(_text_size)) { 154 | _canvas_prev->createRender(_text_size, 128); 155 | } 156 | EPDGUI_AddObject(_key_exit); 157 | EPDGUI_AddObject(_key_next); 158 | EPDGUI_AddObject(_key_prev); 159 | 160 | _txt_file = SD.open(_txt_path); 161 | _last_page = 0; 162 | return 3; 163 | } 164 | 165 | 166 | -------------------------------------------------------------------------------- /src/frame/frame_txtreader.h: -------------------------------------------------------------------------------- 1 | #ifndef _FRAME_TXTREADER_H_ 2 | #define _FRAME_TXTREADER_H_ 3 | 4 | #include "frame_base.h" 5 | #include "../epdgui/epdgui.h" 6 | #include "SD.h" 7 | 8 | class Frame_txtReader : public Frame_Base { 9 | public: 10 | Frame_txtReader(String path); 11 | ~Frame_txtReader(); 12 | int init(epdgui_args_vector_t &args); 13 | uint32_t renderText(uint32_t cursor, uint32_t length, M5EPD_Canvas *canvas); 14 | int run(); 15 | 16 | private: 17 | EPDGUI_Button *_key_next; 18 | EPDGUI_Button *_key_prev; 19 | uint16_t _text_size = 32; 20 | M5EPD_Canvas *_canvas_prev; 21 | M5EPD_Canvas *_canvas_current; 22 | M5EPD_Canvas *_canvas_next; 23 | M5EPD_Canvas *_canvas_page; 24 | uint32_t _cursor_prev = 0; 25 | uint32_t _cursor_current = 0; 26 | uint32_t _cursor_next = 0; 27 | uint32_t _render_len = 1000; 28 | uint32_t _page = 0; 29 | uint32_t _last_page = 0xFFFFFFFF; 30 | String _txt_path; 31 | File _txt_file; 32 | std::map _page_cursor; 33 | uint32_t _page_end = 0; 34 | bool _end_accessed = false; 35 | bool _is_first = true; 36 | }; 37 | 38 | #endif //_FRAME_TXTREADER_H_ -------------------------------------------------------------------------------- /src/global_setting.cpp: -------------------------------------------------------------------------------- 1 | #include "global_setting.h" 2 | #include "./resources/ImageResource.h" 3 | #include "esp32-hal-log.h" 4 | #include 5 | 6 | #define DEFAULT_WALLPAPER 2 7 | SemaphoreHandle_t _xSemaphore_LoadingAnime = NULL; 8 | static uint8_t _loading_anime_eixt_flag = false; 9 | esp_err_t __espret__; 10 | #define NVS_CHECK(x) \ 11 | __espret__ = x; \ 12 | if (__espret__ != ESP_OK) { \ 13 | nvs_close(nvs_arg); \ 14 | log_e("Check Err"); \ 15 | return __espret__; \ 16 | } 17 | 18 | const uint8_t *wallpapers[] = { 19 | ImageResource_wallpaper_m5stack_540x960, 20 | ImageResource_wallpaper_engine_540x960, 21 | ImageResource_wallpaper_penrose_triangle_540x960 22 | }; 23 | 24 | const uint8_t *kIMGLoading[16] = { 25 | ImageResource_item_loading_01_32x32, 26 | ImageResource_item_loading_02_32x32, 27 | ImageResource_item_loading_03_32x32, 28 | ImageResource_item_loading_04_32x32, 29 | ImageResource_item_loading_05_32x32, 30 | ImageResource_item_loading_06_32x32, 31 | ImageResource_item_loading_07_32x32, 32 | ImageResource_item_loading_08_32x32, 33 | ImageResource_item_loading_09_32x32, 34 | ImageResource_item_loading_10_32x32, 35 | ImageResource_item_loading_11_32x32, 36 | ImageResource_item_loading_12_32x32, 37 | ImageResource_item_loading_13_32x32, 38 | ImageResource_item_loading_14_32x32, 39 | ImageResource_item_loading_15_32x32, 40 | ImageResource_item_loading_16_32x32 41 | }; 42 | 43 | const char *wallpapers_name[] = { 44 | "M5Paper", 45 | "Engine", 46 | "Penrose Triangle" 47 | }; 48 | 49 | uint16_t global_wallpaper = DEFAULT_WALLPAPER; 50 | String global_wifi_ssid; 51 | String global_wifi_password; 52 | uint8_t global_wifi_configed = false; 53 | uint16_t global_reader_textsize = 32; 54 | uint8_t global_time_synced = false; 55 | uint8_t global_ttf_file_loaded = false; 56 | uint8_t global_init_status = 0xFF; 57 | int8_t global_timezone = 0; 58 | 59 | 60 | int8_t GetTimeZone(void) { 61 | return global_timezone; 62 | } 63 | 64 | void SetTimeZone(int8_t time_zone) { 65 | global_timezone = time_zone; 66 | } 67 | 68 | void SetInitStatus(uint8_t idx, uint8_t val) { 69 | global_init_status &= ~(1 << idx); 70 | global_init_status |= (val << idx); 71 | } 72 | 73 | uint8_t GetInitStatus(uint8_t idx) { 74 | return (global_init_status & (1 << idx)) ? true : false; 75 | } 76 | 77 | void SetTTFLoaded(uint8_t val) { 78 | global_ttf_file_loaded = val; 79 | } 80 | 81 | uint8_t isTTFLoaded() { 82 | return global_ttf_file_loaded; 83 | } 84 | 85 | uint8_t isTimeSynced(void) { 86 | return global_time_synced; 87 | } 88 | 89 | void SetTimeSynced(uint8_t val) { 90 | global_time_synced = val; 91 | SaveSetting(); 92 | } 93 | 94 | void SetWallpaper(uint16_t wallpaper_id) { 95 | global_wallpaper = wallpaper_id; 96 | SaveSetting(); 97 | } 98 | 99 | uint16_t GetWallpaperID(void) { 100 | return global_wallpaper; 101 | } 102 | 103 | const uint8_t *GetWallpaper(void) { 104 | return wallpapers[global_wallpaper]; 105 | } 106 | 107 | const char *GetWallpaperName(uint16_t wallpaper_id) { 108 | return wallpapers_name[wallpaper_id]; 109 | } 110 | 111 | esp_err_t LoadSetting(void) { 112 | nvs_handle nvs_arg; 113 | NVS_CHECK(nvs_open("settings", NVS_READONLY, &nvs_arg)); 114 | NVS_CHECK(nvs_get_u16(nvs_arg, "wallpaper", &global_wallpaper)); 115 | NVS_CHECK(nvs_get_u8(nvs_arg, "time_synced", &global_time_synced)); 116 | nvs_get_i8(nvs_arg, "timezone", &global_timezone); 117 | 118 | if (global_wallpaper >= WALLPAPER_NUM) { 119 | global_wallpaper = DEFAULT_WALLPAPER; 120 | } 121 | 122 | size_t length = 128; 123 | char buf[128]; 124 | NVS_CHECK(nvs_get_str(nvs_arg, "ssid", buf, &length)); 125 | global_wifi_ssid = String(buf); 126 | length = 128; 127 | NVS_CHECK(nvs_get_str(nvs_arg, "pswd", buf, &length)); 128 | global_wifi_password = String(buf); 129 | if (!global_wifi_ssid.isEmpty() && !global_wifi_password.isEmpty()) 130 | global_wifi_configed = true; 131 | nvs_close(nvs_arg); 132 | return ESP_OK; 133 | } 134 | 135 | esp_err_t SaveSetting(void) { 136 | nvs_handle nvs_arg; 137 | NVS_CHECK(nvs_open("settings", NVS_READWRITE, &nvs_arg)); 138 | NVS_CHECK(nvs_set_u16(nvs_arg, "wallpaper", global_wallpaper)); 139 | NVS_CHECK(nvs_set_u8(nvs_arg, "time_synced", global_time_synced)); 140 | NVS_CHECK(nvs_set_i8(nvs_arg, "timezone", global_timezone)); 141 | NVS_CHECK(nvs_set_str(nvs_arg, "ssid", global_wifi_ssid.c_str())); 142 | NVS_CHECK(nvs_set_str(nvs_arg, "pswd", global_wifi_password.c_str())); 143 | NVS_CHECK(nvs_commit(nvs_arg)); 144 | nvs_close(nvs_arg); 145 | return ESP_OK; 146 | } 147 | 148 | void SetWifi(String ssid, String password) { 149 | global_wifi_ssid = ssid; 150 | global_wifi_password = password; 151 | SaveSetting(); 152 | } 153 | 154 | uint8_t isWiFiConfiged(void) { 155 | return global_wifi_configed; 156 | } 157 | 158 | String GetWifiSSID(void) { 159 | return global_wifi_ssid; 160 | } 161 | 162 | String GetWifiPassword(void) { 163 | return global_wifi_password; 164 | } 165 | 166 | bool SyncNTPTime(void) { 167 | const char *ntpServer = "time.cloudflare.com"; 168 | configTime(global_timezone * 3600, 0, ntpServer); 169 | 170 | struct tm timeInfo; 171 | if (getLocalTime(&timeInfo)) { 172 | rtc_time_t time_struct; 173 | time_struct.hour = timeInfo.tm_hour; 174 | time_struct.min = timeInfo.tm_min; 175 | time_struct.sec = timeInfo.tm_sec; 176 | M5.RTC.setTime(&time_struct); 177 | rtc_date_t date_struct; 178 | date_struct.week = timeInfo.tm_wday; 179 | date_struct.mon = timeInfo.tm_mon + 1; 180 | date_struct.day = timeInfo.tm_mday; 181 | date_struct.year = timeInfo.tm_year + 1900; 182 | M5.RTC.setDate(&date_struct); 183 | SetTimeSynced(1); 184 | return 1; 185 | } 186 | log_d("Time Sync failed"); 187 | return 0; 188 | } 189 | 190 | uint16_t GetTextSize() { 191 | return global_reader_textsize; 192 | } 193 | 194 | void SetTextSize(uint16_t size) { 195 | global_reader_textsize = size; 196 | } 197 | 198 | const uint8_t* GetLoadingIMG_32x32(uint8_t id) { 199 | return kIMGLoading[id]; 200 | } 201 | 202 | void __LoadingAnime_32x32(void *pargs) { 203 | uint16_t *args = (uint16_t *)pargs; 204 | uint16_t x = args[0]; 205 | uint16_t y = args[1]; 206 | free(pargs); 207 | M5EPD_Canvas loading(&M5.EPD); 208 | loading.createCanvas(32, 32); 209 | loading.fillCanvas(0); 210 | loading.pushCanvas(x, y, UPDATE_MODE_GL16); 211 | int anime_cnt = 0; 212 | uint32_t time = 0; 213 | while (true) { 214 | if (millis() - time > 200) { 215 | time = millis(); 216 | loading.pushImage(0, 0, 32, 32, GetLoadingIMG_32x32(anime_cnt)); 217 | loading.pushCanvas(x, y, UPDATE_MODE_DU4); 218 | anime_cnt++; 219 | if (anime_cnt == 16) { 220 | anime_cnt = 0; 221 | } 222 | } 223 | 224 | xSemaphoreTake(_xSemaphore_LoadingAnime, portMAX_DELAY); 225 | if (_loading_anime_eixt_flag == true) { 226 | xSemaphoreGive(_xSemaphore_LoadingAnime); 227 | break; 228 | } 229 | xSemaphoreGive(_xSemaphore_LoadingAnime); 230 | } 231 | vTaskDelete(NULL); 232 | } 233 | 234 | void LoadingAnime_32x32_Start(uint16_t x, uint16_t y) { 235 | if (_xSemaphore_LoadingAnime == NULL) { 236 | _xSemaphore_LoadingAnime = xSemaphoreCreateMutex(); 237 | } 238 | _loading_anime_eixt_flag = false; 239 | uint16_t *pos = (uint16_t*)calloc(2, sizeof(uint16_t)); 240 | pos[0] = x; 241 | pos[1] = y; 242 | xTaskCreatePinnedToCore(__LoadingAnime_32x32, "__LoadingAnime_32x32", 16 * 1024, pos, 1, NULL, 0); 243 | } 244 | 245 | void LoadingAnime_32x32_Stop() { 246 | xSemaphoreTake(_xSemaphore_LoadingAnime, portMAX_DELAY); 247 | _loading_anime_eixt_flag = true; 248 | xSemaphoreGive(_xSemaphore_LoadingAnime); 249 | delay(200); 250 | } 251 | -------------------------------------------------------------------------------- /src/global_setting.h: -------------------------------------------------------------------------------- 1 | #ifndef _GLOBAL_SETTING_H_ 2 | #define _GLOBAL_SETTING_H_ 3 | 4 | #include 5 | #include 6 | 7 | 8 | #define WALLPAPER_NUM 3 9 | 10 | enum { 11 | LANGUAGE_EN = 0, // default, English 12 | LANGUAGE_JA, // Japanese 13 | LANGUAGE_ZH // Simplified Chinese 14 | }; 15 | 16 | void SetWallpaper(uint16_t wallpaper_id); 17 | uint16_t GetWallpaperID(void); 18 | const uint8_t* GetWallpaper(void); 19 | const char* GetWallpaperName(uint16_t wallpaper_id); 20 | 21 | esp_err_t LoadSetting(void); 22 | esp_err_t SaveSetting(void); 23 | void SetWifi(String ssid, String password); 24 | String GetWifiSSID(void); 25 | String GetWifiPassword(void); 26 | uint8_t isWiFiConfiged(void); 27 | bool SyncNTPTime(void); 28 | int8_t GetTimeZone(void); 29 | void SetTimeZone(int8_t time_zone); 30 | 31 | uint16_t GetTextSize(); 32 | void SetTextSize(uint16_t size); 33 | 34 | const uint8_t* GetLoadingIMG_32x32(uint8_t id); 35 | void LoadingAnime_32x32_Start(uint16_t x, uint16_t y); 36 | void LoadingAnime_32x32_Stop(); 37 | 38 | uint8_t isTimeSynced(void); 39 | void SetTimeSynced(uint8_t val); 40 | 41 | void SetTTFLoaded(uint8_t val); 42 | uint8_t isTTFLoaded(void); 43 | void SetInitStatus(uint8_t idx, uint8_t val); 44 | uint8_t GetInitStatus(uint8_t idx); 45 | 46 | #endif //_GLOBAL_SETTING_H_ -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "epdgui/epdgui.h" 3 | #include "frame/frame.h" 4 | #include "systeminit.h" 5 | 6 | void setup() { 7 | pinMode(M5EPD_MAIN_PWR_PIN, OUTPUT); 8 | M5.enableMainPower(); 9 | 10 | SysInit_Start(); 11 | } 12 | 13 | 14 | void loop() { 15 | EPDGUI_MainLoop(); 16 | } 17 | -------------------------------------------------------------------------------- /src/systeminit.cpp: -------------------------------------------------------------------------------- 1 | #include "systeminit.h" 2 | #include "epdgui/epdgui.h" 3 | #include "frame/frame.h" 4 | #include "Free_Fonts.h" 5 | #include "global_setting.h" 6 | #include "resources/binaryttf.h" 7 | #include 8 | 9 | QueueHandle_t xQueue_Info = xQueueCreate(20, sizeof(uint32_t)); 10 | 11 | void WaitForUser(void) { 12 | SysInit_UpdateInfo("$ERR"); 13 | while (true) { 14 | M5.update(); 15 | if (M5.BtnP.wasReleased()) { 16 | SysInit_UpdateInfo("$RESUME"); 17 | return; 18 | } 19 | } 20 | } 21 | 22 | void SysInit_Start(void) { 23 | bool ret = false; 24 | Serial.begin(115200); 25 | Serial.flush(); 26 | delay(50); 27 | Serial.print("M5EPD initializing..."); 28 | 29 | pinMode(M5EPD_EXT_PWR_EN_PIN, OUTPUT); 30 | pinMode(M5EPD_EPD_PWR_EN_PIN, OUTPUT); 31 | pinMode(M5EPD_KEY_RIGHT_PIN, INPUT); 32 | pinMode(M5EPD_KEY_PUSH_PIN, INPUT); 33 | pinMode(M5EPD_KEY_LEFT_PIN, INPUT); 34 | delay(100); 35 | 36 | M5.enableEXTPower(); 37 | // M5.disableEPDPower(); 38 | // delay(500); 39 | M5.enableEPDPower(); 40 | delay(1000); 41 | 42 | M5.EPD.begin(M5EPD_SCK_PIN, M5EPD_MOSI_PIN, M5EPD_MISO_PIN, M5EPD_CS_PIN, M5EPD_BUSY_PIN); 43 | M5.EPD.Clear(true); 44 | M5.EPD.SetRotation(M5EPD_Driver::ROTATE_90); 45 | M5.TP.SetRotation(GT911::ROTATE_90); 46 | 47 | disableCore0WDT(); 48 | xTaskCreatePinnedToCore(SysInit_Loading, "SysInit_Loading", 4096, NULL, 1, NULL, 0); 49 | SysInit_UpdateInfo("Initializing SD card..."); 50 | SPI.begin(14, 13, 12, 4); 51 | ret = SD.begin(4, SPI, 20000000); 52 | if (ret == false) { 53 | SetInitStatus(0, 0); 54 | log_e("Failed to initialize SD card."); 55 | // SysInit_UpdateInfo("[ERROR] Failed to initialize SD card."); 56 | // WaitForUser(); 57 | } 58 | 59 | SysInit_UpdateInfo("Initializing Touch pad..."); 60 | if (M5.TP.begin(21, 22, 36) != ESP_OK) { 61 | SetInitStatus(1, 0); 62 | log_e("Touch pad initialization failed."); 63 | SysInit_UpdateInfo("[ERROR] Failed to initialize Touch pad."); 64 | WaitForUser(); 65 | } 66 | 67 | M5.BatteryADCBegin(); 68 | LoadSetting(); 69 | 70 | M5EPD_Canvas _initcanvas(&M5.EPD); 71 | if (SD.exists("/font.ttf")) { 72 | _initcanvas.loadFont("/font.ttf", SD); 73 | SetTTFLoaded(true); 74 | } else { 75 | _initcanvas.loadFont(binaryttf, sizeof(binaryttf)); 76 | SetTTFLoaded(false); 77 | } 78 | 79 | SysInit_UpdateInfo("Initializing system..."); 80 | 81 | _initcanvas.createRender(26, 128); 82 | 83 | Frame_Main *frame_main = new Frame_Main(); 84 | EPDGUI_PushFrame(frame_main); 85 | 86 | Frame_Settings_Wifi *frame_settings_wifi = new Frame_Settings_Wifi(); 87 | 88 | if (isWiFiConfiged()) { 89 | SysInit_UpdateInfo("Connect to " + GetWifiSSID() + "..."); 90 | WiFi.begin(GetWifiSSID().c_str(), GetWifiPassword().c_str()); 91 | uint32_t t = millis(); 92 | while (true) { 93 | if (millis() - t > 8000) { 94 | break; 95 | } 96 | 97 | if (WiFi.status() == WL_CONNECTED) { 98 | frame_settings_wifi->SetConnected(GetWifiSSID(), WiFi.RSSI()); 99 | break; 100 | } 101 | } 102 | } 103 | 104 | log_d("done"); 105 | 106 | while (uxQueueMessagesWaiting(xQueue_Info)); 107 | 108 | SysInit_UpdateInfo("$OK"); 109 | 110 | Serial.println("OK"); 111 | 112 | delay(1000); 113 | } 114 | 115 | void SysInit_Loading(void *pvParameters) { 116 | const uint16_t kPosy = 548; 117 | const uint8_t *kLD[] = { 118 | ImageResource_loading_01_96x96, 119 | ImageResource_loading_02_96x96, 120 | ImageResource_loading_03_96x96, 121 | ImageResource_loading_04_96x96, 122 | ImageResource_loading_05_96x96, 123 | ImageResource_loading_06_96x96, 124 | ImageResource_loading_07_96x96, 125 | ImageResource_loading_08_96x96, 126 | ImageResource_loading_09_96x96, 127 | ImageResource_loading_10_96x96, 128 | ImageResource_loading_11_96x96, 129 | ImageResource_loading_12_96x96, 130 | ImageResource_loading_13_96x96, 131 | ImageResource_loading_14_96x96, 132 | ImageResource_loading_15_96x96, 133 | ImageResource_loading_16_96x96 134 | }; 135 | 136 | M5EPD_Canvas LoadingIMG(&M5.EPD); 137 | M5EPD_Canvas Info(&M5.EPD); 138 | LoadingIMG.createCanvas(96, 96); 139 | Info.createCanvas(540, 50); 140 | Info.setFreeFont(FF18); 141 | Info.setTextSize(1); 142 | Info.setTextDatum(CC_DATUM); 143 | Info.setTextColor(15); 144 | 145 | M5.EPD.WritePartGram4bpp(92, 182, 356, 300, ImageResource_logo_356x300); 146 | M5.EPD.UpdateFull(UPDATE_MODE_GC16); 147 | 148 | int i = 0; 149 | char *p; 150 | uint32_t time = 0; 151 | while (true) { 152 | if (millis() - time > 250) { 153 | time = millis(); 154 | LoadingIMG.pushImage(0, 0, 96, 96, kLD[i]); 155 | LoadingIMG.pushCanvas(220, kPosy + 80, UPDATE_MODE_DU4); 156 | i++; 157 | if (i == 16) { 158 | i = 0; 159 | } 160 | } 161 | 162 | if (xQueueReceive(xQueue_Info, &p, 0)) { 163 | String str(p); 164 | free(p); 165 | if (str.indexOf("$OK") >= 0) { 166 | LoadingIMG.pushImage(0, 0, 96, 96, ImageResource_loading_success_96x96); 167 | LoadingIMG.pushCanvas(220, kPosy + 80, UPDATE_MODE_GL16); 168 | break; 169 | } else if (str.indexOf("$ERR") >= 0) { 170 | LoadingIMG.pushImage(0, 0, 96, 96, ImageResource_loading_error_96x96); 171 | LoadingIMG.pushCanvas(220, kPosy + 80, UPDATE_MODE_GL16); 172 | LoadingIMG.fillCanvas(0); 173 | while (true) { 174 | if (xQueueReceive(xQueue_Info, &p, 0)) { 175 | String str(p); 176 | free(p); 177 | if (str.indexOf("$RESUME") >= 0) { 178 | LoadingIMG.pushCanvas(220, kPosy + 80, UPDATE_MODE_GC16); 179 | break; 180 | } 181 | } 182 | } 183 | } else { 184 | Info.fillCanvas(0); 185 | Info.drawString(str, 270, 20); 186 | Info.pushCanvas(0, kPosy, UPDATE_MODE_DU); 187 | } 188 | } 189 | } 190 | vTaskDelete(NULL); 191 | } 192 | 193 | void SysInit_UpdateInfo(String info) { 194 | char *p = (char*)malloc(info.length() + 1); 195 | memcpy(p, info.c_str(), info.length()); 196 | p[info.length()] = '\0'; 197 | if (xQueueSend(xQueue_Info, &p, 0) == 0) { 198 | free(p); 199 | } 200 | } -------------------------------------------------------------------------------- /src/systeminit.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYSTEMINIT_H 2 | #define __SYSTEMINIT_H 3 | 4 | #include 5 | 6 | void SysInit_Start(void); 7 | void SysInit_Loading(void *pvParameters); 8 | void SysInit_UpdateInfo(String info); 9 | 10 | 11 | #endif //__SYSTEMINIT_H --------------------------------------------------------------------------------