├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── platformio.yml │ └── test.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── cmake └── CMakeLists.txt ├── examples ├── arduino32 │ ├── dynamicMenuItems │ │ ├── ThemeCoolBlueTraditionalBuilder.h │ │ ├── dynamicMenuItems.emf │ │ ├── dynamicMenuItems.ino │ │ └── generated │ │ │ ├── dynamicMenuItems_menu.cpp │ │ │ ├── dynamicMenuItems_menu.h │ │ │ ├── tcMenuAdaFruitGfx.cpp │ │ │ └── tcMenuAdaFruitGfx.h │ ├── nano33ble │ │ ├── MotionDetection.h │ │ ├── SensorManager.h │ │ ├── ThemeMonoInverseBuilder.h │ │ ├── nano33ble.emf │ │ ├── nano33ble.ino │ │ ├── nano33ble_menu.cpp │ │ ├── nano33ble_menu.h │ │ ├── tcMenuU8g2.cpp │ │ └── tcMenuU8g2.h │ ├── picoAdafruitDashboard │ │ ├── SerialTransport.cpp │ │ ├── SerialTransport.h │ │ ├── ThemeCoolBlueTraditionalBuilder.h │ │ ├── dashboardConfig.cpp │ │ ├── dashboardConfig.h │ │ ├── i18n │ │ │ ├── project-lang.properties │ │ │ └── project-lang_fr.properties │ │ ├── picoAdafruitDashboard.emf │ │ ├── picoAdafruitDashboard.ino │ │ ├── picoAdafruitDashboard_lang.h │ │ ├── picoAdafruitDashboard_langSelect.h │ │ ├── picoAdafruitDashboard_lang_fr.h │ │ ├── picoAdafruitDashboard_menu.cpp │ │ ├── picoAdafruitDashboard_menu.h │ │ ├── tcMenuAdaFruitGfx.cpp │ │ └── tcMenuAdaFruitGfx.h │ ├── picoAw9523LcdEncoder │ │ ├── picoAw9523LcdEncoder.emf │ │ ├── picoAw9523LcdEncoder.ino │ │ ├── picoAw9523LcdEncoder_menu.cpp │ │ ├── picoAw9523LcdEncoder_menu.h │ │ ├── tcMenuLiquidCrystal.cpp │ │ └── tcMenuLiquidCrystal.h │ ├── r4UnoButtonsTft │ │ ├── DiscoTime.cpp │ │ ├── DiscoTime.h │ │ ├── EthernetTransport.cpp │ │ ├── EthernetTransport.h │ │ ├── ThemeCoolBlueTraditionalBuilder.h │ │ ├── r4UnoButtonsTft.emf │ │ ├── r4UnoButtonsTft.ino │ │ ├── r4UnoButtonsTft_menu.cpp │ │ ├── r4UnoButtonsTft_menu.h │ │ ├── tcMenuAdaFruitGfx.cpp │ │ ├── tcMenuAdaFruitGfx.h │ │ └── xbmpImages.h │ ├── stm32DuinoDemo │ │ ├── RawCustomDrawing.h │ │ ├── ThemeMonoInverseBuilder.h │ │ ├── app_icondata.h │ │ ├── generated │ │ │ ├── EthernetTransport.cpp │ │ │ ├── EthernetTransport.h │ │ │ ├── stm32DuinoDemo_menu.cpp │ │ │ ├── stm32DuinoDemo_menu.h │ │ │ ├── tcMenuU8g2.cpp │ │ │ └── tcMenuU8g2.h │ │ ├── stm32DuinoDemo.emf │ │ └── stm32DuinoDemo.ino │ └── stm32DuinoOneButton │ │ ├── ThemeMonoInverseBuilder.h │ │ ├── generated │ │ ├── SerialTransport.cpp │ │ ├── SerialTransport.h │ │ ├── stm32DuinoOneButton_menu.cpp │ │ ├── stm32DuinoOneButton_menu.h │ │ ├── tcMenuU8g2.cpp │ │ └── tcMenuU8g2.h │ │ ├── stm32DuinoOneButton.emf │ │ └── stm32DuinoOneButton.ino ├── avr │ ├── analogDfRobot │ │ ├── analogDfRobot.emf │ │ ├── analogDfRobot.ino │ │ ├── analogDfRobot_menu.cpp │ │ ├── analogDfRobot_menu.h │ │ ├── tcMenuLiquidCrystal.cpp │ │ └── tcMenuLiquidCrystal.h │ ├── keyboardEthernetShield │ │ ├── EthernetTransport.cpp │ │ ├── EthernetTransport.h │ │ ├── keyboardEthernetShield.emf │ │ ├── keyboardEthernetShield.ino │ │ ├── keyboardEthernetShield_menu.cpp │ │ ├── keyboardEthernetShield_menu.h │ │ ├── tcMenuLiquidCrystal.cpp │ │ └── tcMenuLiquidCrystal.h │ └── nokia5110 │ │ ├── EthernetTransport.cpp │ │ ├── EthernetTransport.h │ │ ├── ThemeMonoInverseBuilder.h │ │ ├── nokia5110.ino │ │ ├── nokia5110_menu.cpp │ │ ├── nokia5110_menu.h │ │ ├── securitySystem.emf │ │ ├── tcMenuAdaFruitGfxMono.cpp │ │ └── tcMenuAdaFruitGfxMono.h ├── esp │ ├── esp32Amplifier │ │ ├── AmplifierController.h │ │ ├── ClientEthernetTransport.cpp │ │ ├── ClientEthernetTransport.h │ │ ├── TestingDialogController.h │ │ ├── ThemeCoolBlueModernBuilder.h │ │ ├── additonalCallbacks.cpp │ │ ├── app_icondata.h │ │ ├── esp32Amplifier.emf │ │ ├── esp32Amplifier.ino │ │ ├── esp32Amplifier_menu.cpp │ │ ├── esp32Amplifier_menu.h │ │ ├── tcMenuTfteSpi.cpp │ │ └── tcMenuTfteSpi.h │ ├── esp32SimHub │ │ ├── Fonts │ │ │ ├── RobotoMonoBold60pt.h │ │ │ └── robotoLicense.txt │ │ ├── SimhubConnector.cpp │ │ ├── SimhubConnector.h │ │ ├── ThemeCoolBlueTraditionalBuilder.h │ │ ├── appTheme.cpp │ │ ├── dashboardSetup.cpp │ │ ├── dashboardSetup.h │ │ ├── esp32SimHub.emf │ │ ├── esp32SimHub.ino │ │ ├── esp32SimHub_menu.cpp │ │ ├── esp32SimHub_menu.h │ │ ├── tcMenuAdaFruitGfx.cpp │ │ └── tcMenuAdaFruitGfx.h │ ├── esp32s2Saola │ │ ├── ThemeMonoInverseBuilder.h │ │ ├── esp32s2Saola.emf │ │ ├── esp32s2Saola.ino │ │ ├── generated │ │ │ ├── ClientEthernetTransport.cpp │ │ │ ├── ClientEthernetTransport.h │ │ │ ├── EthernetTransport.cpp │ │ │ ├── EthernetTransport.h │ │ │ ├── esp32s2Saola_menu.cpp │ │ │ ├── esp32s2Saola_menu.h │ │ │ ├── tcMenuU8g2.cpp │ │ │ └── tcMenuU8g2.h │ │ ├── u8g2DashConfig.cpp │ │ └── u8g2DashConfig.h │ ├── esp32s3TftEncoder │ │ ├── ThemeCoolBlueTraditionalBuilder.h │ │ ├── app_icondata.h │ │ ├── esp32s3TftEncoder.emf │ │ ├── esp32s3TftEncoder.ino │ │ └── generated │ │ │ ├── esp32s3TftEncoder_menu.cpp │ │ │ ├── esp32s3TftEncoder_menu.h │ │ │ ├── tcMenuAdaFruitGfx.cpp │ │ │ └── tcMenuAdaFruitGfx.h │ ├── esp8266WifiOled │ │ ├── EthernetTransport.cpp │ │ ├── EthernetTransport.h │ │ ├── Greenhouse.emf │ │ ├── README.md │ │ ├── ThemeMonoInverseBuilder.h │ │ ├── appicons.h │ │ ├── esp8266WifiOled.ino │ │ ├── esp8266WifiOled_menu.cpp │ │ ├── esp8266WifiOled_menu.h │ │ ├── tcMenuU8g2.cpp │ │ └── tcMenuU8g2.h │ ├── espCapTouchTft │ │ ├── ThemeCoolBlueModernBuilder.h │ │ ├── espCapTouchTft.emf │ │ ├── espCapTouchTft.ino │ │ ├── espCapTouchTft_menu.cpp │ │ ├── espCapTouchTft_menu.h │ │ ├── tcMenuAdaTouchDriver.h │ │ ├── tcMenuTfteSpi.cpp │ │ └── tcMenuTfteSpi.h │ └── simpleU8g2 │ │ ├── ThemeMonoBorderedBuilder.h │ │ ├── simpleU8g2.emf │ │ ├── simpleU8g2.ino │ │ ├── simpleU8g2_menu.cpp │ │ ├── simpleU8g2_menu.h │ │ ├── tcMenuU8g2.cpp │ │ └── tcMenuU8g2.h └── mbed │ ├── stm32OledEncoder │ ├── NTPTimeEvent.cpp │ ├── NTPTimeEvent.h │ ├── ScreenSaverCustomDrawing.h │ ├── ThemeMonoInverseBuilder.h │ ├── generated │ │ ├── MBedEthernetTransport.cpp │ │ ├── MBedEthernetTransport.h │ │ ├── stm32OledEncoder_menu.cpp │ │ ├── stm32OledEncoder_menu.h │ │ ├── tcMenuAdaFruitGfxMono.cpp │ │ └── tcMenuAdaFruitGfxMono.h │ ├── stm32OledEncoder.emf │ └── tcmenu_main.cpp │ └── stm32f429FrameBuffer │ ├── BspUserSettings.h │ ├── ThemeCoolBlueModernBuilder.h │ ├── dashboardConfig.cpp │ ├── dashboardConfig.h │ ├── stm32f429FrameBuffer.emf │ ├── stm32f429FrameBuffer_menu.cpp │ ├── stm32f429FrameBuffer_menu.h │ ├── tcMenuStChromaArt.cpp │ ├── tcMenuStChromaArt.h │ └── tcmenu_main.cpp ├── keywords.txt ├── library.json ├── library.properties ├── merge-bin.py ├── platformio-test.ini ├── platformio.ini ├── src ├── BaseDialog.cpp ├── BaseDialog.h ├── BaseRenderers.cpp ├── BaseRenderers.h ├── EditableLargeNumberMenuItem.cpp ├── EditableLargeNumberMenuItem.h ├── EepromItemStorage.cpp ├── EepromItemStorage.h ├── GfxMenuConfig.h ├── MenuHistoryNavigator.cpp ├── MenuHistoryNavigator.h ├── MenuItems.cpp ├── MenuItems.h ├── MenuIterator.cpp ├── MenuIterator.h ├── MessageProcessors.cpp ├── MessageProcessors.h ├── RemoteAuthentication.cpp ├── RemoteAuthentication.h ├── RemoteConnector.cpp ├── RemoteConnector.h ├── RemoteMenuItem.cpp ├── RemoteMenuItem.h ├── RemoteTypes.h ├── RuntimeMenuItem.cpp ├── RuntimeMenuItem.h ├── ScrollChoiceMenuItem.cpp ├── ScrollChoiceMenuItem.h ├── SecuredMenuPopup.cpp ├── SecuredMenuPopup.h ├── extras │ ├── DrawableDashboard.cpp │ ├── DrawableDashboard.h │ ├── DrawableTouchCalibrator.cpp │ ├── DrawableTouchCalibrator.h │ ├── MenuItemDelegate.cpp │ ├── MenuItemDelegate.h │ ├── TcOneButtonHandler.h │ ├── TwoButtonSwitchEncoder.cpp │ └── TwoButtonSwitchEncoder.h ├── graphics │ ├── BaseGraphicalRenderer.cpp │ ├── BaseGraphicalRenderer.h │ ├── CardLayoutPanel.cpp │ ├── CardLayoutPanel.h │ ├── DeviceDrawable.cpp │ ├── DeviceDrawable.h │ ├── DeviceDrawableHelper.cpp │ ├── DeviceDrawableHelper.h │ ├── DialogRuntimeEditor.cpp │ ├── DialogRuntimeEditor.h │ ├── DrawingPrimitives.h │ ├── GfxMenuConfig.cpp │ ├── GfxMenuConfig.h │ ├── GraphicsDeviceRenderer.cpp │ ├── GraphicsDeviceRenderer.h │ ├── MenuTouchScreenEncoder.cpp │ ├── MenuTouchScreenEncoder.h │ ├── RuntimeTitleMenuItem.cpp │ ├── RuntimeTitleMenuItem.h │ ├── TcDrawableButton.cpp │ ├── TcDrawableButton.h │ ├── TcThemeBuilder.cpp │ └── TcThemeBuilder.h ├── lang │ ├── language_cs.h │ ├── language_cs_ascii.h │ ├── language_de.h │ ├── language_de_ascii.h │ ├── language_en.h │ ├── language_fr.h │ ├── language_fr_ascii.h │ ├── language_select.h │ ├── language_sk.h │ ├── language_sk_ascii.h │ ├── language_uk.h │ └── language_uk_ascii.h ├── remote │ ├── BaseBufferedRemoteTransport.cpp │ ├── BaseBufferedRemoteTransport.h │ ├── BaseRemoteComponents.cpp │ └── BaseRemoteComponents.h ├── stockIcons │ ├── directionalIcons.h │ ├── wifiAndConnectionIcons16x12.h │ ├── wifiAndConnectionIcons8x7.h │ └── wifiAndConnectionIconsLCD.h ├── tcMenu.cpp ├── tcMenu.h ├── tcMenuKeyboard.cpp ├── tcMenuKeyboard.h ├── tcMenuVersion.h ├── tcUtil.cpp ├── tcUtil.h └── tcm_test │ └── testFixtures.h └── test ├── test_core_items ├── CoreMenuItemTests.cpp ├── DateTimeItemTestCases.cpp ├── LargeNumberItemTests.cpp ├── RuntimeItemTestCases.cpp ├── ScrollChoiceMenuItemTests.cpp ├── ValueItemTestCases.cpp └── test_main.cpp ├── test_menumgr ├── authenticationTests.cpp ├── menuManagerTests.cpp ├── menuNavigatorTests.cpp ├── tcMenuCoreTests.cpp └── test_main.cpp ├── test_rendering ├── CoreRendererTests.cpp ├── baseDialogTests.cpp └── test_main.cpp └── tutils ├── TestCapturingRenderer.h ├── fixtures_extern.h └── tcMenuFixturesExtra.h /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: davetcc 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Confirm that the bug is in the embedded library** 14 | If the bug is in the designer, or you are not sure, raise in the main [tcMenu repo](https://github.com/TcMenu/tcMenu). 15 | 16 | **To Reproduce** 17 | Please include a simple sketch that recreates the problem unless the problem is so easily recreated that such a sketch is not needed. 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Screenshots** 23 | If applicable, add screenshots to help explain your problem. 24 | 25 | **Device Specs** 26 | Please provide exact device specs (eg board, attached hardware, schematics if applicable to the problem etc) 27 | 28 | **Additional context** 29 | Add any other context about the problem here. 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Confirm that the bug is in the embedded library** 14 | If the bug is in the designer, or you are not sure, raise in the main [tcMenu repo](https://github.com/TcMenu/tcMenu). 15 | 16 | **Describe the solution you'd like** 17 | A clear and concise description of what you want to happen. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/platformio.yml: -------------------------------------------------------------------------------- 1 | name: PlatformIO CI 2 | on: [push] 3 | 4 | jobs: 5 | build: 6 | runs-on: ubuntu-latest 7 | strategy: 8 | matrix: 9 | include: 10 | # Arduino32 11 | # - examples/arduino32/colorTftEthernet32 12 | # - examples/arduino32/dynamicMenuItems 13 | # - examples/arduino32/nano33ble 14 | # - examples/arduino32/picoAdafruitDashboard 15 | # - examples/arduino32/picoAw9523LcdEncoder 16 | # - examples/arduino32/stm32DuinoDemo 17 | # MBED 18 | # - examples/mbed/stm32EncoderLcdI2c 19 | # - examples/mbed/stm32f429FrameBuffer 20 | # - examples/mbed/stm32OledEncoder 21 | # AVR 22 | - example: examples/avr/analogDfRobot 23 | board: megaatmega2560 24 | - example: examples/avr/keyboardEthernetShield 25 | board: megaatmega2560 26 | - example: examples/avr/nokia5110 27 | board: megaatmega2560 28 | # ESP 29 | - example: examples/esp/esp32Amplifier 30 | board: esp32dev 31 | - example: examples/esp/esp32s2Saola 32 | board: esp32dev 33 | - example: examples/esp/esp32s3TftEncoder 34 | board: esp32dev 35 | - example: examples/esp/esp32SimHub 36 | board: esp32dev 37 | - example: examples/esp/esp8266WifiOled 38 | board: esp01_1m 39 | - example: examples/esp/espCapTouchTft 40 | board: [esp32dev, esp01_1m] 41 | - example: examples/esp/simpleU8g2 42 | board: [esp32dev, esp01_1m] 43 | steps: 44 | - uses: actions/checkout@v4 45 | - uses: actions/cache@v4 46 | with: 47 | path: | 48 | ~/.cache/pip 49 | ~/.platformio/.cache 50 | key: ${{ runner.os }}-pio 51 | - uses: actions/setup-python@v5 52 | with: 53 | python-version: '3.12' 54 | - name: Install PlatformIO Core 55 | run: pip install --upgrade platformio 56 | - name: Set Board Environment Variables 57 | run: | 58 | if [ -n "${{ matrix.board }}" ] && [ "${{ matrix.board }}" != "null" ]; then 59 | BOARD_ENVS="" 60 | if [ "${{ matrix.board }}" = "Array" ]; then 61 | # If matrix.board is an array 62 | for board in $(echo '${{ toJSON(matrix.board) }}' | jq -r '.[]'); do 63 | BOARD_ENVS="$BOARD_ENVS --environment $board" 64 | done 65 | else 66 | # If matrix.board is a single value 67 | BOARD_ENVS="--environment ${{ matrix.board }}" 68 | fi 69 | echo "BOARD_ENVS=$BOARD_ENVS" >> $GITHUB_ENV 70 | fi 71 | shell: bash 72 | - name: Build PlatformIO examples 73 | run: pio ci --lib "." --project-conf=platformio.ini $BOARD_ENVS 74 | env: 75 | PLATFORMIO_CI_SRC: ${{ matrix.example }} 76 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: [push] 3 | 4 | jobs: 5 | test: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v4 9 | - uses: actions/cache@v4 10 | with: 11 | path: | 12 | ~/.cache/pip 13 | ~/.platformio/.cache 14 | key: ${{ runner.os }}-pio 15 | - name: Install dependencies 16 | run: sudo apt-get update && sudo apt-get install -y libsdl2-2.0-0 17 | - uses: actions/setup-python@v5 18 | with: 19 | python-version: '3.12' 20 | - name: Install PlatformIO Core 21 | run: pip install --upgrade platformio 22 | - name: Set up QEMU 23 | id: setup-qemu 24 | run: | 25 | if [[ "$(uname -m)" == "x86_64" ]]; then 26 | QEMU_URL="https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-xtensa-softmmu-esp_develop_8.2.0_20240122-x86_64-linux-gnu.tar.xz" 27 | elif [[ "$(uname -m)" == "aarch64" ]]; then 28 | QEMU_URL="https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-xtensa-softmmu-esp_develop_8.2.0_20240122-aarch64-linux-gnu.tar.xz" 29 | else 30 | echo "Unsupported architecture: $(uname -m)" 31 | exit 1 32 | fi 33 | wget $QEMU_URL -O qemu.tar.xz 34 | mkdir -p qemu 35 | tar -xf qemu.tar.xz -C qemu --strip-components=1 36 | sudo mv qemu /usr/local/qemu 37 | 38 | - name: Add QEMU to PATH 39 | run: echo "/usr/local/qemu/bin" >> $GITHUB_PATH 40 | 41 | - name: Run unit tests 42 | run: pio test --without-uploading --project-conf=platformio-test.ini 43 | 44 | static-analysis: 45 | runs-on: ubuntu-latest 46 | steps: 47 | - uses: actions/checkout@v4 48 | - uses: actions/cache@v4 49 | with: 50 | path: | 51 | ~/.cache/pip 52 | ~/.platformio/.cache 53 | key: ${{ runner.os }}-pio 54 | - uses: actions/setup-python@v5 55 | with: 56 | python-version: '3.12' 57 | 58 | - name: Install PlatformIO Core 59 | run: pip install --upgrade platformio 60 | 61 | - name: Run static analysis 62 | run: pio check 63 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Summary 2 | 3 | First of all let me say that we are very glad to have any contributions to the library; as the more people developing and 4 | looking over and testing it, the more likely it is to be stable and succeed. I'm not one for liking hard and fast rules, 5 | but like any community a few rules are needed in order to ensure things go smoothly. 6 | 7 | * Don't start working on any large features without creating an issue first, this allows for feedback before proceeding, 8 | potentially avoiding a lot of wasted time later. 9 | * Please try and use a similar code style to the rest of the project. At an absolute minimum please keep fields, 10 | variable styles and braces the same. Use camel case for all variables. Functions should always start with a lower 11 | case letter. Classes always start with an upper case letter. 12 | * Please be sure that you're happy with the licensing model of this project. For any files you create, you can retain 13 | copyright, but they must be provided under the same Apache as the rest of the project, and with copyright granted to 14 | the library at the top of the file. 15 | * If you edit keywords.txt, be exceptionally careful that tabs have not been replaced as spaces. 16 | * Please make sure that compiler warnings are set to All, (Arduino Menu -> Preferences -> Compiler warnings) 17 | 18 | ## Why do all TheCodersCorner libraries use an Apache license? 19 | 20 | The apache license allows others to use this library commercially. You may ask why that is important, it is important 21 | because any strong and stable ecosystem, such as Java, has got where it is because it's used by the Hobbyist, the 22 | Enterprise, start-ups and just about any other group you care to mention. 23 | 24 | I think it's a shame that so many Arduino libraries are GPL instead of Apache, LGPL or MIT; as it means these can't be used 25 | by commercial entities, at least without contacting the vendor of the library first. Will they bother to do that, NO, they 26 | will just write what they need to get the job done and probably never give it back. If the library were open, and this 27 | same commercial made changes, they could well decide to give them back! 28 | -------------------------------------------------------------------------------- /cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | add_library(tcMenu 4 | ../src/BaseDialog.cpp 5 | ../src/BaseRenderers.cpp 6 | ../src/EditableLargeNumberMenuItem.cpp 7 | ../src/EepromItemStorage.cpp 8 | ../src/MenuHistoryNavigator.cpp 9 | ../src/MenuItems.cpp 10 | ../src/MenuIterator.cpp 11 | ../src/MessageProcessors.cpp 12 | ../src/RemoteAuthentication.cpp 13 | ../src/RemoteConnector.cpp 14 | ../src/RemoteMenuItem.cpp 15 | ../src/RuntimeMenuItem.cpp 16 | ../src/ScrollChoiceMenuItem.cpp 17 | ../src/SecuredMenuPopup.cpp 18 | ../src/tcMenu.cpp 19 | ../src/tcMenuKeyboard.cpp 20 | ../src/tcUtil.cpp 21 | ../src/extras/DrawableDashboard.cpp 22 | ../src/extras/DrawableTouchCalibrator.cpp 23 | ../src/extras/MenuItemDelegate.cpp 24 | ../src/extras/TwoButtonSwitchEncoder.cpp 25 | ../src/graphics/BaseGraphicalRenderer.cpp 26 | ../src/graphics/CardLayoutPanel.cpp 27 | ../src/graphics/DeviceDrawable.cpp 28 | ../src/graphics/DeviceDrawableHelper.cpp 29 | ../src/graphics/DialogRuntimeEditor.cpp 30 | ../src/graphics/GfxMenuConfig.cpp 31 | ../src/graphics/GraphicsDeviceRenderer.cpp 32 | ../src/graphics/MenuTouchScreenEncoder.cpp 33 | ../src/graphics/RuntimeTitleMenuItem.cpp 34 | ../src/graphics/TcDrawableButton.cpp 35 | ../src/graphics/TcThemeBuilder.cpp 36 | ../src/remote/BaseBufferedRemoteTransport.cpp 37 | ../src/remote/BaseRemoteComponents.cpp 38 | ) 39 | 40 | target_compile_definitions(tcMenu 41 | PUBLIC BUILD_FOR_PICO_CMAKE=1 BUILD_PICO_FORCE_UART=1 IO_LOGGING_DEBUG=1 42 | ) 43 | 44 | target_include_directories(tcMenu PUBLIC 45 | ../src 46 | ) 47 | 48 | target_link_libraries(tcMenu PUBLIC pico_stdlib pico_sync IoAbstraction TaskManagerIO tcUnicodeHelper) 49 | -------------------------------------------------------------------------------- /examples/arduino32/nano33ble/MotionDetection.h: -------------------------------------------------------------------------------- 1 | #ifndef TCLIBRARYDEV_MOTIONDETECTION_H 2 | #define TCLIBRARYDEV_MOTIONDETECTION_H 3 | 4 | #include 5 | #include 6 | #include "nano33ble_menu.h" 7 | 8 | /** 9 | * Here we create a polling event that checks if the acceleration / magnetic data is available, and whenever it is 10 | * it triggers the event. This tidies up the class slightly by avoiding if statements in the exec() methods. 11 | * In short, the timeOfNextCheck method is called every `eventFrequency` micros, and we tell taskManager that the 12 | * event is triggered when both readings are available. At this point `exec()` is called and we take the readings 13 | * and put then into menu items. 14 | */ 15 | class MotionDetection : public BaseEvent { 16 | private: 17 | uint32_t eventFrequency = 1000UL; 18 | public: 19 | void initialise() { 20 | IMU.begin(); 21 | auto imuRate = IMU.magneticFieldSampleRate(); 22 | eventFrequency = min(int(imuRate), 100) * 1000UL; 23 | } 24 | 25 | uint32_t timeOfNextCheck() override { 26 | setTriggered(IMU.magneticFieldAvailable() && IMU.accelerationAvailable()); 27 | 28 | return eventFrequency; 29 | } 30 | 31 | void exec() override { 32 | float x, y, z; 33 | IMU.readMagneticField(x, y, z); 34 | menuAccelerometerMagX.setFloatValue(x); 35 | menuAccelerometerMagY.setFloatValue(y); 36 | menuAccelerometerMagZ.setFloatValue(z); 37 | 38 | IMU.readAcceleration(x, y, z); 39 | menuAccelerometerAccelX.setFloatValue(x); 40 | menuAccelerometerAccelY.setFloatValue(y); 41 | menuAccelerometerAccelZ.setFloatValue(z); 42 | } 43 | }; 44 | 45 | #endif //TCLIBRARYDEV_MOTIONDETECTION_H 46 | -------------------------------------------------------------------------------- /examples/arduino32/nano33ble/SensorManager.h: -------------------------------------------------------------------------------- 1 | #ifndef TCLIBRARYDEV_SENSORMANAGER_H 2 | #define TCLIBRARYDEV_SENSORMANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "nano33ble_menu.h" 9 | 10 | /** 11 | * Here we have a class that extends `Executable`, meaning that the `exec()` method is called every time the event 12 | * is scheduled by task manager. We read the data from the sensors and set them onto menu items. 13 | */ 14 | class SensorManager : public Executable { 15 | private: 16 | bool initialised{}; 17 | public: 18 | void initialise() { 19 | initialised = HTS.begin() != 0; 20 | initialised = initialised && BARO.begin(); 21 | } 22 | 23 | void exec() override { 24 | menuTemp.setFromFloatingPointValue(HTS.readTemperature()); 25 | menuHumidity.setFromFloatingPointValue(HTS.readHumidity()); 26 | menuBPressure.setFromFloatingPointValue(BARO.readPressure()); 27 | } 28 | }; 29 | 30 | #endif //TCLIBRARYDEV_SENSORMANAGER_H 31 | -------------------------------------------------------------------------------- /examples/arduino32/nano33ble/ThemeMonoInverseBuilder.h: -------------------------------------------------------------------------------- 1 | #ifndef TCMENU_THEME_MONO_INVERSE 2 | #define TCMENU_THEME_MONO_INVERSE 3 | 4 | #include 5 | 6 | color_t defaultItemPaletteMono[] = {1, 0, 1, 1}; 7 | color_t defaultTitlePaletteMono[] = {0, 1, 0, 0}; 8 | 9 | #define TITLE_PADDING 2 10 | #define TITLE_SPACING 2 11 | 12 | /** 13 | * This is one of the stock themes, you can modify it to meet your requirements, and it will not be updated by tcMenu 14 | * Designer unless you delete it. This sets up the fonts, spacing and padding for all items. 15 | * @param gr the graphical renderer 16 | * @param itemFont the font for items 17 | * @param titleFont the font for titles 18 | * @param needEditingIcons if editing icons are needed 19 | */ 20 | void installMonoInverseTitleTheme(GraphicsDeviceRenderer& gr, const MenuFontDef& itemFont, const MenuFontDef& titleFont, 21 | bool needEditingIcons, BaseGraphicalRenderer::TitleMode titleMode, bool useUnicode) { 22 | 23 | // See https://tcmenu.github.io/documentation/arduino-libraries/tc-menu/themes/rendering-with-themes-icons-grids/ 24 | TcThemeBuilder themeBuilder(gr); 25 | themeBuilder.withSelectedColors(0, 2) 26 | .dimensionsFromRenderer() 27 | .withItemPadding(MenuPadding(1)) 28 | .withRenderingSettings(titleMode, false) 29 | .withPalette(defaultItemPaletteMono) 30 | .withNativeFont(itemFont.fontData, itemFont.fontMag) 31 | .withSpacing(1); 32 | 33 | if(needEditingIcons) { 34 | themeBuilder.withStandardLowResCursorIcons(); 35 | } 36 | 37 | if(useUnicode) { 38 | themeBuilder.enableTcUnicode(); 39 | } 40 | 41 | themeBuilder.defaultTitleProperties() 42 | .withNativeFont(titleFont.fontData, titleFont.fontMag) 43 | .withPalette(defaultTitlePaletteMono) 44 | .withPadding(MenuPadding(TITLE_PADDING)) 45 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 46 | .withSpacing(TITLE_SPACING) 47 | .apply(); 48 | 49 | themeBuilder.defaultActionProperties() 50 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 51 | .apply(); 52 | 53 | themeBuilder.defaultItemProperties() 54 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_VALUE_RIGHT) 55 | .apply(); 56 | 57 | themeBuilder.apply(); 58 | } 59 | 60 | #endif //TCMENU_THEME_MONO_INVERSE 61 | -------------------------------------------------------------------------------- /examples/arduino32/nano33ble/nano33ble_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include "tcMenuU8g2.h" 17 | #include 18 | #include 19 | 20 | // variables we declare that you may need to access 21 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 22 | extern U8G2_SSD1306_128X64_NONAME_F_HW_I2C gfx; 23 | extern U8g2Drawable gfxDrawable; 24 | extern GraphicsDeviceRenderer renderer; 25 | 26 | // Any externals needed by IO expanders, EEPROMs etc 27 | extern IoAbstractionRef io23017; 28 | 29 | // Global Menu Item exports 30 | extern AnalogMenuItem menuAnalogReadingsOutputPWM; 31 | extern FloatMenuItem menuAnalogReadingsInA0; 32 | extern BackMenuItem menuBackAnalogReadings; 33 | extern SubMenuItem menuAnalogReadings; 34 | extern FloatMenuItem menuAccelerometerAccelZ; 35 | extern FloatMenuItem menuAccelerometerAccelY; 36 | extern FloatMenuItem menuAccelerometerAccelX; 37 | extern FloatMenuItem menuAccelerometerMagZ; 38 | extern FloatMenuItem menuAccelerometerMagY; 39 | extern FloatMenuItem menuAccelerometerMagX; 40 | extern BackMenuItem menuBackAccelerometer; 41 | extern SubMenuItem menuAccelerometer; 42 | extern AnalogMenuItem menuBPressure; 43 | extern AnalogMenuItem menuHumidity; 44 | extern AnalogMenuItem menuTemp; 45 | 46 | // Provide a wrapper to get hold of the root menu item and export setupMenu 47 | inline MenuItem& rootMenuItem() { return menuTemp; } 48 | void setupMenu(); 49 | 50 | // Callback functions must always include CALLBACK_FUNCTION after the return type 51 | #define CALLBACK_FUNCTION 52 | 53 | void CALLBACK_FUNCTION onPWMChanged(int id); 54 | 55 | #endif // MENU_GENERATED_CODE_H 56 | -------------------------------------------------------------------------------- /examples/arduino32/picoAdafruitDashboard/SerialTransport.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * Serial remote capability plugin. This file is a plugin file and should not be directly edited, 8 | * it will be replaced each time the project is built. If you want to edit this file in place, 9 | * make sure to rename it first. 10 | */ 11 | 12 | #include "SerialTransport.h" 13 | #include 14 | 15 | SerialTagValueTransport::SerialTagValueTransport(Stream* thePort) : TagValueTransport(TVAL_UNBUFFERED) { 16 | this->serialPort = thePort; 17 | } 18 | 19 | void SerialTagValueTransport::close() { 20 | currentField.msgType = UNKNOWN_MSG_TYPE; 21 | currentField.fieldType = FVAL_PROCESSING_AWAITINGMSG; 22 | } 23 | 24 | // DO NOT replace this with the standard char* write method on serial. 25 | // It cannot handle large volumes of data going through at once and often 26 | // overflows the buffer causing data errors. 27 | int SerialTagValueTransport::writeChar(char ch) { 28 | if(available()) { 29 | serialPort->write(ch); 30 | } 31 | else { 32 | int tries = 30; 33 | while(tries && !available()) { 34 | --tries; 35 | serialPort->flush(); 36 | taskManager.yieldForMicros(100); 37 | } 38 | 39 | // if it's not available now, it probably will timeout anyway. 40 | if(!available()) { 41 | return 0; 42 | } 43 | 44 | serialPort->write(ch); 45 | } 46 | return 1; 47 | } 48 | 49 | int SerialTagValueTransport::writeStr(const char* str) { 50 | int i=0; 51 | bool lastWriteOk = true; 52 | while(str[i] && lastWriteOk) { 53 | lastWriteOk = writeChar(str[i]); 54 | i++; 55 | } 56 | return i; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /examples/arduino32/picoAdafruitDashboard/SerialTransport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * @file SerialTransport.h 8 | * 9 | * Serial remote capability plugin. This file is a plugin file and should not be directly edited, 10 | * it will be replaced each time the project is built. If you want to edit this file in place, 11 | * make sure to rename it first. 12 | */ 13 | 14 | #ifndef TCMENU_SERIALTRANSPORT_H_ 15 | #define TCMENU_SERIALTRANSPORT_H_ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | namespace tcremote { 25 | 26 | /** 27 | * Serial transport is an implementation of TagValueTransport that works over a serial port 28 | */ 29 | class SerialTagValueTransport : public TagValueTransport { 30 | private: 31 | Stream* serialPort; 32 | public: 33 | explicit SerialTagValueTransport(Stream* thePort); 34 | ~SerialTagValueTransport() override = default; 35 | 36 | void flush() override {serialPort->flush();} 37 | int writeChar(char data) override; 38 | int writeStr(const char* data) override; 39 | 40 | uint8_t readByte() override { return serialPort->read(); } 41 | bool readAvailable() override { return serialPort->available(); } 42 | bool available() override { return serialPort->availableForWrite() != 0;} 43 | bool connected() override { return true;} 44 | 45 | void close() override; 46 | }; 47 | } 48 | 49 | #ifndef TC_MANUAL_NAMESPACING 50 | using namespace tcremote; 51 | #endif // TC_MANUAL_NAMESPACING 52 | 53 | #endif /* TCMENU_SERIALTRANSPORT_H_ */ 54 | -------------------------------------------------------------------------------- /examples/arduino32/picoAdafruitDashboard/dashboardConfig.h: -------------------------------------------------------------------------------- 1 | // A few references from the dashboard source exported for the main file. 2 | 3 | #ifndef TCEXAMPLE_DASHBOARDCONFIG_H 4 | #define TCEXAMPLE_DASHBOARDCONFIG_H 5 | 6 | #include "picoAdafruitDashboard_menu.h" 7 | #include "extras/DrawableDashboard.h" 8 | 9 | void setupDashboard(); 10 | extern TitleWidget YesNoWidget; 11 | extern DrawableDashboard* mainDashboard; 12 | 13 | #endif //TCEXAMPLE_DASHBOARDCONFIG_H 14 | -------------------------------------------------------------------------------- /examples/arduino32/picoAdafruitDashboard/i18n/project-lang.properties: -------------------------------------------------------------------------------- 1 | # Created by TcMenu to hold menu translations, will always be written in UTF-8 2 | menu.3.enum.1=Item2 3 | menu.3.enum.0=Item 1 4 | menu.3.name=Enum 5 | menu.5.name=Settings 6 | menu.3.enum.2=ChangeMe 7 | menu.1.name=Analog 8 | menu.1.unit=V 9 | menu.2.name=Float 10 | menu.4.name=Power 11 | menu.8.name=YesNo 12 | menu.7.name=RGB 13 | menu.6.name=Action 14 | project.name=Adafruit Dashboard -------------------------------------------------------------------------------- /examples/arduino32/picoAdafruitDashboard/i18n/project-lang_fr.properties: -------------------------------------------------------------------------------- 1 | # Created by TcMenu to hold menu translations, will always be written in UTF-8 2 | menu.5.name=Paramètres 3 | menu.3.enum.1=Pâtes 4 | menu.3.enum.2=Pizza 5 | menu.3.enum.0=Salade 6 | menu.3.name=Le Enum 7 | menu.2.name=Flotter 8 | menu.1.name=Analogique 9 | menu.1.unit=V 10 | menu.8.name=Oui Non 11 | menu.7.name=Couleur 12 | project.name=Tableau de bord -------------------------------------------------------------------------------- /examples/arduino32/picoAdafruitDashboard/picoAdafruitDashboard.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * This is a simple example menu wise that has a dashboard view incorporated within it. As of 3.0 the dashboard 3 | * support has been formalized into the main project. This example presents a very simple dashboard that takes 4 | * effect when the display is taken over. 5 | * 6 | * Getting started: https://www.thecoderscorner.com/products/arduino-libraries/tc-menu/tcmenu-overview-quick-start/ 7 | */ 8 | 9 | #include 10 | #include "picoAdafruitDashboard_menu.h" 11 | #include "dashboardConfig.h" 12 | 13 | void setup() { 14 | // This example logs using IoLogging, see the following guide to enable 15 | // https://www.thecoderscorner.com/products/arduino-libraries/io-abstraction/arduino-logging-with-io-logging/ 16 | IOLOG_START_SERIAL 17 | 18 | Serial.begin(115200); 19 | while (!Serial && millis() < 10000UL); 20 | 21 | // prepare the SPI device on the right pins, configure as needed! 22 | SPI.setRX(4); 23 | SPI.setTX(7); 24 | SPI.setSCK(6); 25 | SPI.begin(); 26 | 27 | setupMenu(); 28 | 29 | // see the dashboardConfig.* files in this directory for the dashboard implementation 30 | setupDashboard(); 31 | 32 | // here we just change a few menu items frequently, on a 150 millis schedule 33 | taskManager.scheduleFixedRate(150, [] { 34 | menuFloat.setFloatValue((rand() % 100000) / 100.0F); 35 | menuAnalog.setCurrentValue((rand() % 1000)); 36 | YesNoWidget.setCurrentState(rand() % 2); 37 | }); 38 | 39 | // here we add an extra switch that triggers the action callback on menuSettingsAction 40 | switches.addSwitch(22, [](pinid_t, bool) { menuSettingsAction.triggerCallback(); }); 41 | 42 | // add a title widget to the screen, see title widget docs 43 | // the widget is defined in dashboardConfig.h/cpp 44 | renderer.setFirstWidget(&YesNoWidget); 45 | } 46 | 47 | void loop() { 48 | taskManager.runLoop(); 49 | } 50 | 51 | // when either the extra button is pressed or the action item is triggered from the menu, take over 52 | // the display which starts the dashboard. 53 | void CALLBACK_FUNCTION onSettingsAction(int id) { 54 | renderer.takeOverDisplay(); // start the dashboard now. 55 | } 56 | -------------------------------------------------------------------------------- /examples/arduino32/picoAdafruitDashboard/picoAdafruitDashboard_lang.h: -------------------------------------------------------------------------------- 1 | // TcMenu Generated Locale File, do not edit this file. Locale 2 | // Never include directly, always include the langSelect header 3 | 4 | #define TC_I18N_MENU_2_NAME "Float" 5 | #define TC_I18N_MENU_8_NAME "YesNo" 6 | #define TC_I18N_MENU_5_NAME "Settings" 7 | #define TC_I18N_PROJECT_NAME "Adafruit Dashboard" 8 | #define TC_I18N_MENU_7_NAME "RGB" 9 | #define TC_I18N_MENU_3_ENUM_1 "Item2" 10 | #define TC_I18N_MENU_3_ENUM_2 "ChangeMe" 11 | #define TC_I18N_MENU_1_NAME "Analog" 12 | #define TC_I18N_MENU_4_NAME "Power" 13 | #define TC_I18N_MENU_1_UNIT "V" 14 | #define TC_I18N_MENU_3_ENUM_0 "Item 1" 15 | #define TC_I18N_MENU_6_NAME "Action" 16 | #define TC_I18N_MENU_3_NAME "Enum" 17 | -------------------------------------------------------------------------------- /examples/arduino32/picoAdafruitDashboard/picoAdafruitDashboard_langSelect.h: -------------------------------------------------------------------------------- 1 | // TcMenu Generated Locale File, do not edit this file. 2 | // This is the header to include. Set TC_LOCAL_?? to a locale 3 | // or omit for the default language 4 | 5 | #if defined(TC_LOCALE_FR) 6 | # include "picoAdafruitDashboard_lang_fr.h" 7 | #else 8 | #include "picoAdafruitDashboard_lang.h" 9 | #endif 10 | -------------------------------------------------------------------------------- /examples/arduino32/picoAdafruitDashboard/picoAdafruitDashboard_lang_fr.h: -------------------------------------------------------------------------------- 1 | // TcMenu Generated Locale File, do not edit this file. Locale fr 2 | // Never include directly, always include the langSelect header 3 | 4 | #define TC_I18N_MENU_2_NAME "Flotter" 5 | #define TC_I18N_MENU_8_NAME "Oui Non" 6 | #define TC_I18N_MENU_5_NAME "Paramètres" 7 | #define TC_I18N_PROJECT_NAME "Tableau de bord" 8 | #define TC_I18N_MENU_7_NAME "Couleur" 9 | #define TC_I18N_MENU_3_ENUM_1 "Pâtes" 10 | #define TC_I18N_MENU_3_ENUM_2 "Pizza" 11 | #define TC_I18N_MENU_1_NAME "Analogique" 12 | #define TC_I18N_MENU_4_NAME "Power" 13 | #define TC_I18N_MENU_1_UNIT "V" 14 | #define TC_I18N_MENU_3_ENUM_0 "Salade" 15 | #define TC_I18N_MENU_6_NAME "Action" 16 | #define TC_I18N_MENU_3_NAME "Le Enum" 17 | -------------------------------------------------------------------------------- /examples/arduino32/picoAdafruitDashboard/picoAdafruitDashboard_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include "tcMenuAdaFruitGfx.h" 18 | #include 19 | #include "SerialTransport.h" 20 | #include 21 | #include 22 | #include 23 | #include "picoAdafruitDashboard_langSelect.h" 24 | 25 | // variables we declare that you may need to access 26 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 27 | extern TcMenuRemoteServer remoteServer; 28 | extern Adafruit_ILI9341 gfx; 29 | extern AdafruitDrawable gfxDrawable; 30 | extern GraphicsDeviceRenderer renderer; 31 | extern const UnicodeFont OpenSansRegular18pt[]; 32 | extern const UnicodeFont RobotoMedium24[]; 33 | 34 | // Any externals needed by IO expanders, EEPROMs etc 35 | 36 | 37 | // Global Menu Item exports 38 | extern BooleanMenuItem menuSettingsCheckBox; 39 | extern BooleanMenuItem menuSettingsYesNo; 40 | extern Rgb32MenuItem menuSettingsRGB; 41 | extern ActionMenuItem menuSettingsAction; 42 | extern BackMenuItem menuBackSettings; 43 | extern SubMenuItem menuSettings; 44 | extern BooleanMenuItem menuPower; 45 | extern EnumMenuItem menuEnum; 46 | extern FloatMenuItem menuFloat; 47 | extern AnalogMenuItem menuAnalog; 48 | 49 | // Provide a wrapper to get hold of the root menu item and export setupMenu 50 | inline MenuItem& rootMenuItem() { return menuAnalog; } 51 | void setupMenu(); 52 | 53 | // Callback functions must always include CALLBACK_FUNCTION after the return type 54 | #define CALLBACK_FUNCTION 55 | 56 | void CALLBACK_FUNCTION onSettingsAction(int id); 57 | 58 | #endif // MENU_GENERATED_CODE_H 59 | -------------------------------------------------------------------------------- /examples/arduino32/picoAw9523LcdEncoder/picoAw9523LcdEncoder.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * A very simple tcMenu example that shows how to configure the menu to work with an AW9523 for both LCD display and 3 | * rotary encoder input. We've chosen to use interrupt input here, but you could choose either mode you see fit. 4 | * 5 | * Getting started: https://www.thecoderscorner.com/products/arduino-libraries/tc-menu/tcmenu-overview-quick-start/ 6 | * 7 | * For this example the wiring is as follows: 8 | * AW9523 connected to Pico - SDA 12, SCL 13, Device Interrupt - 15 9 | * AW9523 to rotary encoder - 0 - switch, 1,2 A and B 10 | * AW9523 to display - RS, RW, EN, Data lines, 0..6 in order. 11 | * AW9523 Backlight - controlled by the AW9523 LED controller on pin 15 12 | */ 13 | #include "picoAw9523LcdEncoder_menu.h" 14 | #include 15 | 16 | const int backlightPin = 15; 17 | 18 | // We create an analog device for the LED controller in the AW9523, we can then use the device analog output functions. 19 | // as the actual abstraction was created in the designer, we just use the reference to it from 20 | AW9523AnalogAbstraction aw9523Analog(iodev_aw9523); 21 | 22 | void setup() { 23 | Wire.setSDA(12); 24 | Wire.setSCL(13); 25 | Wire.begin(); 26 | setupMenu(); 27 | 28 | // now we configure our backlight to be controlled by the AW9523 LED controller 29 | iodev_aw9523.writeGlobalControl(true, AW9523IoAbstraction::CURRENT_HALF); 30 | lcd.configureAnalogBacklight(&aw9523Analog, backlightPin); 31 | lcd.setBacklight(menuBacklight.getCurrentValue()); 32 | 33 | // You can provide a callback function to be called when the title is clicked. We call withMenuDialogIfAvailable 34 | // which in turn calls the function provided if the menu dialog is available. You can then show a dialog, here 35 | // we show a version dialog. 36 | setTitlePressedCallback([](int) { 37 | withMenuDialogIfAvailable([](MenuBasedDialog *dlg) { 38 | dlg->setButtons(BTNTYPE_CLOSE, BTNTYPE_NONE); 39 | dlg->show("Pico example", false); 40 | char sz[20]; 41 | tccore::copyTcMenuVersion(sz, sizeof sz); 42 | dlg->copyIntoBuffer(sz); 43 | }); 44 | }); 45 | } 46 | 47 | void loop() { 48 | taskManager.runLoop(); 49 | } 50 | 51 | void CALLBACK_FUNCTION onBacklight(int id) { 52 | lcd.setBacklight(menuBacklight.getCurrentValue()); 53 | } 54 | 55 | void CALLBACK_FUNCTION onRunMe(int id) { 56 | withMenuDialogIfAvailable([](MenuBasedDialog *dlg) { 57 | dlg->setButtons(BTNTYPE_NONE, BTNTYPE_CLOSE); 58 | dlg->show("Run me pressed", false); 59 | dlg->copyIntoBuffer("from the menu"); 60 | }); 61 | } 62 | -------------------------------------------------------------------------------- /examples/arduino32/picoAw9523LcdEncoder/picoAw9523LcdEncoder_menu.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #include 12 | #include "picoAw9523LcdEncoder_menu.h" 13 | 14 | // Global variable declarations 15 | const ConnectorLocalInfo applicationInfo = { "picoAw9523LcdEncoder", "b547b450-b96d-4d14-bd2d-47b21787f54a" }; 16 | AW9523IoAbstraction iodev_aw9523(0x58, 15); 17 | IoAbstractionRef ioexp_aw9523 = &iodev_aw9523; 18 | LiquidCrystal lcd(8, 9, 10, 11, 12, 13, 14); 19 | LiquidCrystalRenderer renderer(lcd, 20, 4); 20 | 21 | // Global Menu Item declarations 22 | const AnyMenuInfo minfoMoreRunMe = { "Run me", 5, 0xffff, 0, onRunMe }; 23 | ActionMenuItem menuMoreRunMe(&minfoMoreRunMe, NULL, INFO_LOCATION_PGM); 24 | const SubMenuInfo minfoMore = { "More", 4, 0xffff, 0, NO_CALLBACK }; 25 | BackMenuItem menuBackMore(&minfoMore, &menuMoreRunMe, INFO_LOCATION_PGM); 26 | SubMenuItem menuMore(&minfoMore, &menuBackMore, NULL, INFO_LOCATION_PGM); 27 | RENDERING_CALLBACK_NAME_INVOKE(fnTextRtCall, textItemRenderFn, "Text", 12, NO_CALLBACK) 28 | TextMenuItem menuText(fnTextRtCall, "", 3, 5, &menuMore); 29 | RENDERING_CALLBACK_NAME_INVOKE(fnLargeNumRtCall, largeNumItemRenderFn, "LargeNum", 4, NO_CALLBACK) 30 | EditableLargeNumberMenuItem menuLargeNum(fnLargeNumRtCall, LargeFixedNumber(6, 0, 222U, 0U, false), 2, false, &menuText); 31 | const AnalogMenuInfo minfoBacklight = { "Backlight", 1, 2, 255, onBacklight, 0, 1, "" }; 32 | AnalogMenuItem menuBacklight(&minfoBacklight, 100, &menuLargeNum, INFO_LOCATION_PGM); 33 | 34 | void setupMenu() { 35 | // First we set up eeprom and authentication (if needed). 36 | setSizeBasedEEPROMStorageEnabled(false); 37 | // Code generated by plugins. 38 | lcd.setIoAbstraction(ioexp_aw9523); 39 | lcd.begin(20, 4); 40 | renderer.setUpdatesPerSecond(2); 41 | switches.init(ioexp_aw9523, SWITCHES_NO_POLLING, true); 42 | menuMgr.initForEncoder(&renderer, &menuBacklight, 1, 2, 0); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /examples/arduino32/picoAw9523LcdEncoder/picoAw9523LcdEncoder_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "tcMenuLiquidCrystal.h" 23 | 24 | // variables we declare that you may need to access 25 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 26 | extern LiquidCrystal lcd; 27 | extern LiquidCrystalRenderer renderer; 28 | 29 | // Any externals needed by IO expanders, EEPROMs etc 30 | extern AW9523IoAbstraction iodev_aw9523; 31 | extern IoAbstractionRef ioexp_aw9523; 32 | 33 | // Global Menu Item exports 34 | extern ActionMenuItem menuMoreRunMe; 35 | extern BackMenuItem menuBackMore; 36 | extern SubMenuItem menuMore; 37 | extern TextMenuItem menuText; 38 | extern EditableLargeNumberMenuItem menuLargeNum; 39 | extern AnalogMenuItem menuBacklight; 40 | 41 | // Provide a wrapper to get hold of the root menu item and export setupMenu 42 | inline MenuItem& rootMenuItem() { return menuBacklight; } 43 | void setupMenu(); 44 | 45 | // Callback functions must always include CALLBACK_FUNCTION after the return type 46 | #define CALLBACK_FUNCTION 47 | 48 | void CALLBACK_FUNCTION onBacklight(int id); 49 | void CALLBACK_FUNCTION onRunMe(int id); 50 | 51 | #endif // MENU_GENERATED_CODE_H 52 | -------------------------------------------------------------------------------- /examples/arduino32/picoAw9523LcdEncoder/tcMenuLiquidCrystal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * @file tcMenuLiquidCrystal.h 8 | * 9 | * LiquidCrystalIO renderer that renders menus onto this type of display. This file is a plugin file and should not 10 | * be directly edited, it will be replaced each time the project is built. If you want to edit this file in place, 11 | * make sure to rename it first. 12 | * 13 | * LIBRARY REQUIREMENT 14 | * This renderer is designed for use with this library: https://github.com/TcMenu/LiquidCrystalIO 15 | */ 16 | 17 | #ifndef _TCMENU_LIQUID_CRYSTAL_H 18 | #define _TCMENU_LIQUID_CRYSTAL_H 19 | 20 | #include "tcMenu.h" 21 | #include 22 | #include 23 | #include 24 | 25 | using namespace tcgfx; 26 | 27 | /** 28 | * A renderer that can renderer onto a LiquidCrystal display and supports the concept of single level 29 | * sub menus, active items and editing. 30 | */ 31 | class LiquidCrystalRenderer : public BaseGraphicalRenderer { 32 | private: 33 | LiquidCrystal* lcd; 34 | NullItemDisplayPropertiesFactory propertiesFactory; 35 | char backChar; 36 | char forwardChar; 37 | char editChar; 38 | uint8_t lcdEditorCursorX = 0xFF; 39 | uint8_t lcdEditorCursorY = 0xFF; 40 | public: 41 | LiquidCrystalRenderer(LiquidCrystal& lcd, int dimX, int dimY); 42 | ~LiquidCrystalRenderer() override; 43 | void initialise() override; 44 | void setTitleRequired(bool titleRequired) { titleMode = (titleRequired) ? TITLE_FIRST_ROW : NO_TITLE; } 45 | void setEditorChars(char back, char forward, char edit); 46 | 47 | uint8_t getRows() {return height;} 48 | LiquidCrystal* getLCD() {return lcd;} 49 | BaseDialog* getDialog() override; 50 | 51 | void drawingCommand(RenderDrawingCommand command) override; 52 | void drawWidget(Coord where, TitleWidget* widget, color_t colorFg, color_t colorBg) override; 53 | void drawMenuItem(GridPositionRowCacheEntry* entry, Coord where, Coord areaSize, bool drawAll) override; 54 | void fillWithBackgroundTo(int endPoint) override; 55 | 56 | ItemDisplayPropertiesFactory &getDisplayPropertiesFactory() override { return propertiesFactory; } 57 | NullItemDisplayPropertiesFactory &getLcdDisplayPropertiesFactory() { return propertiesFactory; } 58 | 59 | void setupEditorPlacement(int32_t x, int32_t y); 60 | }; 61 | 62 | #endif // _TCMENU_LIQUID_CRYSTAL_H 63 | -------------------------------------------------------------------------------- /examples/arduino32/r4UnoButtonsTft/DiscoTime.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef TCLIBRARYDEV_DISCOTIME_H 3 | #define TCLIBRARYDEV_DISCOTIME_H 4 | 5 | #include "r4UnoButtonsTft_menu.h" 6 | #include 7 | #include 8 | 9 | /** 10 | * Create an event that will run our LED Matrix as something akin to disco lights. When the disco is running it will 11 | * schedule very frequently and use an AdaFruit_GFX GFXCanvas1 to represent the 12x8 display, and with that you can 12 | * draw anything onto it that is possible with Adafruit_GFX. Feel free to make it better! 13 | * 14 | * This also shows how to create custom messages, we have two custom "disco messages" that the Java API can receive and 15 | * you can easily create additional protocol handlers to process them. 16 | */ 17 | class DiscoTime : public BaseEvent { 18 | public: 19 | // the types of disco lights we have! 20 | enum DiscoMode { TEXT, CIRCLES, SQUARES, STROBE, PICTURE }; 21 | private: 22 | // when the disco is running, this is true 23 | bool discoIsRunning = false; 24 | // the speed of our disco in milliseconds 25 | int speed = 250; 26 | // the canvas we will draw into 27 | GFXcanvas1 canvas; 28 | // the text area to store the text to print in text mode 29 | char textBuffer[32]; 30 | // the font handler that draws unicode fonts using TcUnicode format 31 | UnicodeFontHandler unicodeHelper; 32 | // the current position in the animation 33 | int currPos = 0; 34 | // the amount of time the loop has been running 35 | int loopTimer = 0; 36 | // the current mode 37 | DiscoMode mode = CIRCLES; 38 | public: 39 | explicit DiscoTime(); 40 | void init(); 41 | 42 | // 43 | // These two are part of TaskManagerIO BaseEvent processing, see TaskManagerIO event handling for docs: 44 | // https://tcmenu.github.io/documentation/arduino-libraries/taskmanager-io/ 45 | // 46 | void exec() override; 47 | uint32_t timeOfNextCheck() override; 48 | 49 | // start the disco on the matrix 50 | void start(int speed); 51 | // draw a picture on the matrix in 12x8 XBMP format 52 | void picture(const uint8_t* xbmpData); 53 | // draw text on the matrix 54 | void text(const char* data); 55 | // stop the animation 56 | void stop(); 57 | 58 | // These two send non-standard custom messages over the wire, this shows how easy it is to define your own. 59 | // https://tcmenu.github.io/documentation/arduino-libraries/tc-menu/tcmenu-iot/embed-control-tagval-wire-protocol/ 60 | void sendDiscoMsg(); 61 | void sendXbmpData(const uint8_t* xbmpData, size_t length); 62 | 63 | // these are the animation methods 64 | void runSquares(); 65 | void drawText(); 66 | void runStrobe(); 67 | 68 | // and lastly we convert the canvas to LED output with this 69 | void drawCanvasToLeds(); 70 | 71 | void runCircles(); 72 | 73 | void switchMode(DiscoMode mode); 74 | }; 75 | 76 | 77 | #endif //TCLIBRARYDEV_DISCOTIME_H 78 | -------------------------------------------------------------------------------- /examples/arduino32/r4UnoButtonsTft/r4UnoButtonsTft_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include "tcMenuAdaFruitGfx.h" 18 | #include "EthernetTransport.h" 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | // variables we declare that you may need to access 26 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 27 | extern TcMenuRemoteServer remoteServer; 28 | extern Adafruit_ST7735 gfx; 29 | extern AdafruitDrawable gfxDrawable; 30 | extern GraphicsDeviceRenderer renderer; 31 | extern WiFiServer server; 32 | extern EthernetInitialisation ethernetInitialisation; 33 | extern const UnicodeFont OpenSansRegular12pt[]; 34 | extern const UnicodeFont OpenSansCyrillicLatin14[]; 35 | 36 | // Any externals needed by IO expanders, EEPROMs etc 37 | 38 | 39 | // Global Menu Item exports 40 | extern BooleanMenuItem menuWiFiConnected; 41 | extern IpAddressMenuItem menuWiFiIPAddress; 42 | extern BackMenuItem menuBackWiFi; 43 | extern SubMenuItem menuWiFi; 44 | extern FloatMenuItem menuAnalogA1Value; 45 | extern AnalogMenuItem menuAnalogA0DAC; 46 | extern BackMenuItem menuBackAnalog; 47 | extern SubMenuItem menuAnalog; 48 | extern ActionMenuItem menuShowXbmpShowImage; 49 | extern ScrollChoiceMenuItem menuShowXbmpXbmp; 50 | extern BackMenuItem menuBackShowXbmp; 51 | extern SubMenuItem menuShowXbmp; 52 | extern ActionMenuItem menuScrollTextStartScroll; 53 | extern TextMenuItem menuScrollTextText; 54 | extern BackMenuItem menuBackScrollText; 55 | extern SubMenuItem menuScrollText; 56 | extern ActionMenuItem menuZoomTextStartZoom; 57 | extern AnalogMenuItem menuDiscoSpeed; 58 | extern BackMenuItem menuBackDisco; 59 | extern SubMenuItem menuDisco; 60 | 61 | // Provide a wrapper to get hold of the root menu item and export setupMenu 62 | inline MenuItem& rootMenuItem() { return menuDisco; } 63 | void setupMenu(); 64 | 65 | // Callback functions must always include CALLBACK_FUNCTION after the return type 66 | #define CALLBACK_FUNCTION 67 | 68 | int fnShowXbmpXbmpRtCall(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize); 69 | void CALLBACK_FUNCTION onAnalogDacChange(int id); 70 | void CALLBACK_FUNCTION onShowXbmp(int id); 71 | void CALLBACK_FUNCTION onStartDisco(int id); 72 | void CALLBACK_FUNCTION onStartScroll(int id); 73 | 74 | #endif // MENU_GENERATED_CODE_H 75 | -------------------------------------------------------------------------------- /examples/arduino32/r4UnoButtonsTft/xbmpImages.h: -------------------------------------------------------------------------------- 1 | #ifndef XBMP_IMAGES_H 2 | #define XBMP_IMAGES_H 3 | 4 | // To use palette and size constants we need to use tcgfx types 5 | #include 6 | #include 7 | 8 | using namespace tcgfx; 9 | 10 | // XBM_LSB_FIRST width=12, height=8, size=16 11 | // auto size = Coord(12, 8); 12 | const uint8_t faceIconXbm12x8[] PROGMEM = { 13 | 0x09,0x09,0x95,0x0a,0x62,0x04,0x0a,0x05,0x02,0x04,0x64,0x02,0x98,0x01,0x04,0x02 14 | }; 15 | 16 | // XBM_LSB_FIRST width=12, height=8, size=16 17 | // auto size = Coord(12, 8); 18 | const uint8_t logoIconXbm12x8[] PROGMEM = { 19 | 0x28,0x00,0x28,0x00,0x54,0x0c,0x54,0x02,0xca,0x02,0x4a,0x02,0x45,0x02,0x85,0x0d 20 | }; 21 | 22 | /** 23 | * A really simple value class that represents each of the icons declared above to be stored in a simple array 24 | */ 25 | class XBmpImageWithDescription { 26 | private: 27 | const uint8_t* data; 28 | char name[20]; 29 | public: 30 | XBmpImageWithDescription(const uint8_t* data, const char* n): name{}, data(data) { 31 | strncpy(name, n, sizeof name); 32 | } 33 | 34 | const uint8_t* getData() { return data; } 35 | const char* getName() { return name; } 36 | }; 37 | 38 | XBmpImageWithDescription imageWithDescription[] = { 39 | XBmpImageWithDescription(logoIconXbm12x8, "Tc Logo"), 40 | XBmpImageWithDescription(faceIconXbm12x8, "Face") 41 | }; 42 | 43 | #define NUMBER_OF_XBMPS 2 44 | 45 | #endif //XBMP_IMAGES_H -------------------------------------------------------------------------------- /examples/arduino32/stm32DuinoDemo/RawCustomDrawing.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef TCLIBRARYDEV_RAWCUSTOMDRAWING_H 3 | #define TCLIBRARYDEV_RAWCUSTOMDRAWING_H 4 | 5 | #include "generated/stm32DuinoDemo_menu.h" 6 | 7 | // Here we implement the custom drawing capability of the renderer, it allows us to receive reset and custom drawing 8 | // requests. More info in the link below: 9 | // https://www.thecoderscorner.com/products/arduino-libraries/tc-menu/renderer-take-over-display/ 10 | // 11 | class MyCustomDrawing : public CustomDrawing { 12 | private: 13 | GraphicsDeviceRenderer& dev; 14 | int ticks; 15 | public: 16 | MyCustomDrawing(GraphicsDeviceRenderer& r) : dev(r), ticks(0) {} 17 | 18 | void registerWithRenderer() { 19 | dev.setCustomDrawingHandler(this); 20 | } 21 | 22 | void started(BaseMenuRenderer *currentRenderer) override { 23 | // called once when the take-over display is started before calling renderLoop so you can set things up. 24 | switches.getEncoder()->changePrecision(100, 50); 25 | } 26 | 27 | void reset() override { 28 | renderer.takeOverDisplay(); 29 | } 30 | 31 | void renderLoop(unsigned int currentValue, RenderPressMode userClick) override { 32 | // called in a game loop between takeOverDisplay and giveBackDisplay, at this point you renderer the display. 33 | if(userClick == RPRESS_PRESSED) { 34 | dev.giveBackDisplay(); 35 | } 36 | else if(++ticks % 10 == 1) { 37 | // Why write your own code using device drawable? The main reason is, that it works exactly the same over 38 | // Adafruit, PicoSDK, FrameBuffer, u8g2 and TFTeSPI with a moderately complete API. 39 | DeviceDrawable *dd = dev.getDeviceDrawable(); 40 | dd->startDraw(); 41 | const Coord &dims = dd->getDisplayDimensions(); 42 | dd->setDrawColor(BLACK); 43 | dd->drawBox(Coord(0, 0), dims, true); 44 | dd->setColors(WHITE, BLACK); 45 | auto height = int(dims.y) - 16; 46 | int width = int(dims.x) - 20; 47 | dd->drawText(Coord(rand() % width, (rand() % height) + 10), nullptr, 1, "hello"); 48 | dd->drawText(Coord(rand() % width, (rand() % height) + 10), nullptr, 1, "world"); 49 | char sz[10]; 50 | ltoaClrBuff(sz, currentValue, 4, NOT_PADDED, sizeof sz); 51 | dd->drawText(Coord(0, 0), nullptr, 1, sz); 52 | dd->endDraw(); 53 | } 54 | } 55 | } myCustomDrawing(renderer); 56 | 57 | 58 | #endif //TCLIBRARYDEV_RAWCUSTOMDRAWING_H 59 | -------------------------------------------------------------------------------- /examples/arduino32/stm32DuinoDemo/ThemeMonoInverseBuilder.h: -------------------------------------------------------------------------------- 1 | #ifndef TCMENU_THEME_MONO_INVERSE 2 | #define TCMENU_THEME_MONO_INVERSE 3 | 4 | #include 5 | 6 | color_t defaultItemPaletteMono[] = {1, 0, 1, 1}; 7 | color_t defaultTitlePaletteMono[] = {0, 1, 0, 0}; 8 | 9 | #define TITLE_PADDING 2 10 | #define TITLE_SPACING 2 11 | 12 | /** 13 | * This is one of the stock themes, you can modify it to meet your requirements, and it will not be updated by tcMenu 14 | * Designer unless you delete it. This sets up the fonts, spacing and padding for all items. 15 | * @param gr the graphical renderer 16 | * @param itemFont the font for items 17 | * @param titleFont the font for titles 18 | * @param needEditingIcons if editing icons are needed 19 | */ 20 | void installMonoInverseTitleTheme(GraphicsDeviceRenderer& gr, const MenuFontDef& itemFont, const MenuFontDef& titleFont, 21 | bool needEditingIcons, BaseGraphicalRenderer::TitleMode titleMode, bool useUnicode) { 22 | 23 | // See https://tcmenu.github.io/documentation/arduino-libraries/tc-menu/themes/rendering-with-themes-icons-grids/ 24 | TcThemeBuilder themeBuilder(gr); 25 | themeBuilder.withSelectedColors(0, 2) 26 | .dimensionsFromRenderer() 27 | .withItemPadding(MenuPadding(1)) 28 | .withRenderingSettings(titleMode, false) 29 | .withPalette(defaultItemPaletteMono) 30 | .withNativeFont(itemFont.fontData, itemFont.fontMag) 31 | .withSpacing(1); 32 | 33 | if(needEditingIcons) { 34 | themeBuilder.withStandardLowResCursorIcons(); 35 | } 36 | 37 | if(useUnicode) { 38 | themeBuilder.enableTcUnicode(); 39 | } 40 | 41 | themeBuilder.defaultTitleProperties() 42 | .withNativeFont(titleFont.fontData, titleFont.fontMag) 43 | .withPalette(defaultTitlePaletteMono) 44 | .withPadding(MenuPadding(TITLE_PADDING)) 45 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 46 | .withSpacing(TITLE_SPACING) 47 | .apply(); 48 | 49 | themeBuilder.defaultActionProperties() 50 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 51 | .apply(); 52 | 53 | themeBuilder.defaultItemProperties() 54 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_VALUE_RIGHT) 55 | .apply(); 56 | 57 | themeBuilder.apply(); 58 | } 59 | 60 | #endif //TCMENU_THEME_MONO_INVERSE 61 | -------------------------------------------------------------------------------- /examples/arduino32/stm32DuinoOneButton/ThemeMonoInverseBuilder.h: -------------------------------------------------------------------------------- 1 | #ifndef TCMENU_THEME_MONO_INVERSE 2 | #define TCMENU_THEME_MONO_INVERSE 3 | 4 | #include 5 | 6 | color_t defaultItemPaletteMono[] = {1, 0, 1, 1}; 7 | color_t defaultTitlePaletteMono[] = {0, 1, 0, 0}; 8 | 9 | #define TITLE_PADDING 2 10 | #define TITLE_SPACING 2 11 | 12 | /** 13 | * This is one of the stock themes, you can modify it to meet your requirements, and it will not be updated by tcMenu 14 | * Designer unless you delete it. This sets up the fonts, spacing and padding for all items. 15 | * @param gr the graphical renderer 16 | * @param itemFont the font for items 17 | * @param titleFont the font for titles 18 | * @param needEditingIcons if editing icons are needed 19 | */ 20 | void installMonoInverseTitleTheme(GraphicsDeviceRenderer& gr, const MenuFontDef& itemFont, const MenuFontDef& titleFont, 21 | bool needEditingIcons, BaseGraphicalRenderer::TitleMode titleMode, bool useUnicode) { 22 | 23 | // See https://tcmenu.github.io/documentation/arduino-libraries/tc-menu/themes/rendering-with-themes-icons-grids/ 24 | TcThemeBuilder themeBuilder(gr); 25 | themeBuilder.withSelectedColors(0, 2) 26 | .dimensionsFromRenderer() 27 | .withItemPadding(MenuPadding(1)) 28 | .withRenderingSettings(titleMode, false) 29 | .withPalette(defaultItemPaletteMono) 30 | .withNativeFont(itemFont.fontData, itemFont.fontMag) 31 | .withSpacing(1); 32 | 33 | if(needEditingIcons) { 34 | themeBuilder.withStandardLowResCursorIcons(); 35 | } 36 | 37 | if(useUnicode) { 38 | themeBuilder.enableTcUnicode(); 39 | } 40 | 41 | themeBuilder.defaultTitleProperties() 42 | .withNativeFont(titleFont.fontData, titleFont.fontMag) 43 | .withPalette(defaultTitlePaletteMono) 44 | .withPadding(MenuPadding(TITLE_PADDING)) 45 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 46 | .withSpacing(TITLE_SPACING) 47 | .apply(); 48 | 49 | themeBuilder.defaultActionProperties() 50 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 51 | .apply(); 52 | 53 | themeBuilder.defaultItemProperties() 54 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_VALUE_RIGHT) 55 | .apply(); 56 | 57 | themeBuilder.apply(); 58 | } 59 | 60 | #endif //TCMENU_THEME_MONO_INVERSE 61 | -------------------------------------------------------------------------------- /examples/arduino32/stm32DuinoOneButton/generated/SerialTransport.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * Serial remote capability plugin. This file is a plugin file and should not be directly edited, 8 | * it will be replaced each time the project is built. If you want to edit this file in place, 9 | * make sure to rename it first. 10 | */ 11 | 12 | // we'll wait 100 times this amount in a loop when serial is not available 13 | #ifndef MICROS_TO_WAIT_FOR_SERIAL 14 | #define MICROS_TO_WAIT_FOR_SERIAL 10000 15 | #endif //MICROS_TO_WAIT_FOR_SERIAL 16 | 17 | #include "SerialTransport.h" 18 | #include 19 | 20 | SerialTagValueTransport::SerialTagValueTransport(Stream* thePort) : TagValueTransport(TVAL_UNBUFFERED) { 21 | this->serialPort = thePort; 22 | } 23 | 24 | void SerialTagValueTransport::close() { 25 | currentField.msgType = UNKNOWN_MSG_TYPE; 26 | currentField.fieldType = FVAL_PROCESSING_AWAITINGMSG; 27 | } 28 | 29 | // DO NOT replace this with the standard char* write method on serial. 30 | // It cannot handle large volumes of data going through at once and often 31 | // overflows the buffer causing data errors. 32 | int SerialTagValueTransport::writeChar(char ch) { 33 | if(available()) { 34 | serialPort->write(ch); 35 | } 36 | else { 37 | int tries = 100; 38 | while(tries && !available()) { 39 | --tries; 40 | serialPort->flush(); 41 | taskManager.yieldForMicros(MICROS_TO_WAIT_FOR_SERIAL); 42 | } 43 | 44 | // if it's not available now, it probably will timeout anyway. 45 | if(!available()) { 46 | return 0; 47 | } 48 | 49 | serialPort->write(ch); 50 | } 51 | return 1; 52 | } 53 | 54 | int SerialTagValueTransport::writeStr(const char* str) { 55 | int i=0; 56 | bool lastWriteOk = true; 57 | while(str[i] && lastWriteOk) { 58 | lastWriteOk = writeChar(str[i]); 59 | i++; 60 | } 61 | return i; 62 | } 63 | 64 | -------------------------------------------------------------------------------- /examples/arduino32/stm32DuinoOneButton/generated/SerialTransport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * @file SerialTransport.h 8 | * 9 | * Serial remote capability plugin. This file is a plugin file and should not be directly edited, 10 | * it will be replaced each time the project is built. If you want to edit this file in place, 11 | * make sure to rename it first. 12 | */ 13 | 14 | #ifndef TCMENU_SERIALTRANSPORT_H_ 15 | #define TCMENU_SERIALTRANSPORT_H_ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | namespace tcremote { 25 | 26 | /** 27 | * Serial transport is an implementation of TagValueTransport that works over a serial port 28 | */ 29 | class SerialTagValueTransport : public TagValueTransport { 30 | private: 31 | Stream* serialPort; 32 | public: 33 | explicit SerialTagValueTransport(Stream* thePort); 34 | ~SerialTagValueTransport() override = default; 35 | 36 | void flush() override {serialPort->flush();} 37 | int writeChar(char data) override; 38 | int writeStr(const char* data) override; 39 | 40 | uint8_t readByte() override { return serialPort->read(); } 41 | bool readAvailable() override { return serialPort->available(); } 42 | bool available() override { return serialPort->availableForWrite() != 0;} 43 | bool connected() override { return true;} 44 | 45 | void close() override; 46 | }; 47 | } 48 | 49 | #ifndef TC_MANUAL_NAMESPACING 50 | using namespace tcremote; 51 | #endif // TC_MANUAL_NAMESPACING 52 | 53 | #endif /* TCMENU_SERIALTRANSPORT_H_ */ 54 | -------------------------------------------------------------------------------- /examples/arduino32/stm32DuinoOneButton/generated/stm32DuinoOneButton_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include "tcMenuU8g2.h" 18 | #include 19 | #include 20 | #include "SerialTransport.h" 21 | #include 22 | #include 23 | #include 24 | 25 | // variables we declare that you may need to access 26 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 27 | extern TcMenuRemoteServer remoteServer; 28 | extern U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI gfx; 29 | extern U8g2Drawable gfxDrawable; 30 | extern GraphicsDeviceRenderer renderer; 31 | extern TcOneButtonHandler oneButtonHandler; 32 | extern const UnicodeFont OpenSansRegular8pt[]; 33 | 34 | // Any externals needed by IO expanders, EEPROMs etc 35 | 36 | 37 | // Global Menu Item exports 38 | extern EnumMenuItem menuSettingsEnumProp; 39 | extern AnalogMenuItem menuSettingsIntProp; 40 | extern BooleanMenuItem menuSettingsOption; 41 | extern BackMenuItem menuBackSettings; 42 | extern SubMenuItem menuSettings; 43 | extern AnalogMenuItem menuTemp; 44 | extern ActionMenuItem menuPressMe; 45 | 46 | // Provide a wrapper to get hold of the root menu item and export setupMenu 47 | inline MenuItem& rootMenuItem() { return menuPressMe; } 48 | void setupMenu(); 49 | 50 | // Callback functions must always include CALLBACK_FUNCTION after the return type 51 | #define CALLBACK_FUNCTION 52 | 53 | void CALLBACK_FUNCTION onPressMe(int id); 54 | 55 | #endif // MENU_GENERATED_CODE_H 56 | -------------------------------------------------------------------------------- /examples/arduino32/stm32DuinoOneButton/stm32DuinoOneButton.ino: -------------------------------------------------------------------------------- 1 | // 2 | // A TcMenu example that demonstrates how to use the one button support with an STM32 based 3 | // board, but it is sufficiently simple that it should be easy to move to any other board. 4 | // 5 | // You configure the single pin in code generator, and away you go. 6 | // 7 | // Getting started: https://tcmenu.github.io/documentation/arduino-libraries/tc-menu/tcmenu-overview-quick-start/ 8 | // 9 | 10 | #include "generated/stm32DuinoOneButton_menu.h" 11 | #include 12 | 13 | void setup() { 14 | // Start the serial port so that we can use the remote connectivity 15 | Serial.begin(115200); 16 | 17 | // Start up serial and prepare the correct SPI, your pins may differ 18 | SPI.setMISO(PB4); 19 | SPI.setMOSI(PB5); 20 | SPI.setSCLK(PB3); 21 | 22 | setupMenu(); 23 | 24 | } 25 | 26 | void loop() { 27 | taskManager.runLoop(); 28 | } 29 | 30 | 31 | void CALLBACK_FUNCTION onPressMe(int id) { 32 | // the callback functions are added by designer when we provide a callback function name 33 | // in the menu item editor. It will be called when the item changes along with the item id 34 | serlogF2(SER_DEBUG, "Pressed ", id); 35 | } 36 | -------------------------------------------------------------------------------- /examples/avr/analogDfRobot/analogDfRobot.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * This example assumes you've got an Uno / MEGA with the DF robot board. It uses the switches that are connected to 3 | * A0 to control the menu, including the next and back support. 4 | * 5 | * Getting started: https://www.thecoderscorner.com/products/arduino-libraries/tc-menu/tcmenu-overview-quick-start/ 6 | */ 7 | #include "analogDfRobot_menu.h" 8 | #include "AnalogDeviceAbstraction.h" 9 | 10 | ArduinoAnalogDevice analog; 11 | 12 | //using namespace tcgfx; 13 | 14 | void setup() { 15 | // first we setup the menu 16 | setupMenu(); 17 | 18 | // we are going to toggle the built in LED, so set it as output. 19 | pinMode(LED_BUILTIN, OUTPUT); 20 | analog.initPin(A1, DIR_IN); 21 | 22 | // now we read the value of A0 every 200millis and set it onto a menu item 23 | taskManager.scheduleFixedRate(200, [] { 24 | menuValueA0.setCurrentValue(int(analog.getCurrentFloat(A1) * 100.0)); 25 | }); 26 | 27 | // This registers a special callback, unlike the usual one, this callback is 28 | // only called when editing is completely finished, you register it once and 29 | // it triggers for every menu item. 30 | menuMgr.setItemCommittedHook([](int id) { 31 | menuCommits.setCurrentValue(menuCommits.getCurrentValue() + 1); 32 | }); 33 | } 34 | 35 | void loop() { 36 | taskManager.runLoop(); 37 | } 38 | 39 | void CALLBACK_FUNCTION onLed1(int id) { 40 | digitalWrite(LED_BUILTIN, menuL1.getBoolean()); 41 | } 42 | 43 | void CALLBACK_FUNCTION onLed2(int id) { 44 | // TODO: write your own second LED function.. 45 | // Called whenever you change the LED2 menu item.. 46 | } 47 | 48 | 49 | // When dealing with custom rendering, either using lists or custom choices, we have to do everything from scratch. We need 50 | // to handle the EEPROM storage location, the item name, the value etc. 51 | // see tcMenu list documentation on thecoderscorner.com 52 | int CALLBACK_FUNCTION fnChooseItemRtCall(RuntimeMenuItem * item, uint8_t row, RenderFnMode mode, char * buffer, int bufferSize) { 53 | switch(mode) { 54 | case RENDERFN_INVOKE: 55 | // we don't want to do anything on a selection, ignore it. 56 | return true; 57 | case RENDERFN_NAME: 58 | // here we return the name for the scroll item 59 | strcpy(buffer, "Choose"); 60 | return true; 61 | case RENDERFN_VALUE: 62 | // here we define the text value for each possible setting, we just set it to V followed by the row 63 | buffer[0] = 'V'; buffer[1]=0; 64 | fastltoa(buffer, row, 3, NOT_PADDED, bufferSize); 65 | return true; 66 | case RENDERFN_EEPROM_POS: return 18; // Choices are saved to rom, we copy the value from the designer. 67 | default: return false; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /examples/avr/analogDfRobot/analogDfRobot_menu.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | // Generated for Arduino AVR/Uno/Mega by TcMenu 4.3.1 on 2024-10-12T11:23:21.762740700Z. 12 | 13 | #include 14 | #include "analogDfRobot_menu.h" 15 | 16 | // Global variable declarations 17 | const PROGMEM ConnectorLocalInfo applicationInfo = { "DfRobot", "2ba37227-a412-40b7-94e7-42caf9bb0ff4" }; 18 | 19 | LiquidCrystal lcd(8, 9, 4, 5, 6, 7); 20 | LiquidCrystalRenderer renderer(lcd, 16, 2); 21 | 22 | // Global Menu Item declarations 23 | const PROGMEM AnalogMenuInfo minfoCommits = { "Commits", 7, 0xffff, 65000, NO_CALLBACK, 0, 1, "" }; 24 | AnalogMenuItem menuCommits(&minfoCommits, 0, nullptr, INFO_LOCATION_PGM); 25 | const PROGMEM AnyMenuInfo minfoChooseItem = { "Choose Item", 8, 18, 0, NO_CALLBACK }; 26 | ScrollChoiceMenuItem menuChooseItem(&minfoChooseItem, fnChooseItemRtCall, 0, 20, &menuCommits, INFO_LOCATION_PGM); 27 | const PROGMEM AnyMenuInfo minfoText = { "Text", 6, 4, 0, NO_CALLBACK }; 28 | TextMenuItem menuText(&minfoText, "", 6, &menuChooseItem, INFO_LOCATION_PGM); 29 | const PROGMEM AnyMenuInfo minfoLgeNum = { "LgeNum", 5, 10, 0, NO_CALLBACK }; 30 | EditableLargeNumberMenuItem menuLgeNum(&minfoLgeNum, LargeFixedNumber(8, 4, 0U, 0U, false), true, &menuText, INFO_LOCATION_PGM); 31 | const PROGMEM BooleanMenuInfo minfoL2 = { "L2", 4, 3, 1, onLed2, NAMING_ON_OFF }; 32 | BooleanMenuItem menuL2(&minfoL2, false, nullptr, INFO_LOCATION_PGM); 33 | const PROGMEM BooleanMenuInfo minfoL1 = { "L1", 3, 2, 1, onLed1, NAMING_ON_OFF }; 34 | BooleanMenuItem menuL1(&minfoL1, false, &menuL2, INFO_LOCATION_PGM); 35 | const PROGMEM SubMenuInfo minfoLEDStates = { "LED States", 2, 0xffff, 0, NO_CALLBACK }; 36 | BackMenuItem menuBackLEDStates(&minfoLEDStates, &menuL1, INFO_LOCATION_PGM); 37 | SubMenuItem menuLEDStates(&minfoLEDStates, &menuBackLEDStates, &menuLgeNum, INFO_LOCATION_PGM); 38 | const PROGMEM AnalogMenuInfo minfoValueA0 = { "Value A0", 1, 0xffff, 1024, NO_CALLBACK, 0, 1, "" }; 39 | AnalogMenuItem menuValueA0(&minfoValueA0, 0, &menuLEDStates, INFO_LOCATION_PGM); 40 | 41 | void setupMenu() { 42 | // First we set up eeprom and authentication (if needed). 43 | setSizeBasedEEPROMStorageEnabled(false); 44 | // Now add any readonly, non-remote and visible flags. 45 | menuValueA0.setReadOnly(true); 46 | menuCommits.setReadOnly(true); 47 | 48 | // Code generated by plugins and new operators. 49 | lcd.begin(16, 2); 50 | renderer.setUpdatesPerSecond(2); 51 | lcd.configureBacklightPin(10); 52 | lcd.backlight(); 53 | pinMode(A0, INPUT); 54 | switches.initialise(inputFromDfRobotShield(), false); 55 | menuMgr.initFor4WayJoystick(&renderer, &menuValueA0, DF_KEY_DOWN, DF_KEY_UP, DF_KEY_LEFT, DF_KEY_RIGHT, DF_KEY_SELECT, 10); 56 | } 57 | 58 | -------------------------------------------------------------------------------- /examples/avr/analogDfRobot/analogDfRobot_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include "tcMenuLiquidCrystal.h" 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | // variables we declare that you may need to access 26 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 27 | extern LiquidCrystal lcd; 28 | extern LiquidCrystalRenderer renderer; 29 | 30 | // Any externals needed by IO expanders, EEPROMs etc 31 | 32 | 33 | // Global Menu Item exports 34 | extern AnalogMenuItem menuCommits; 35 | extern ScrollChoiceMenuItem menuChooseItem; 36 | extern TextMenuItem menuText; 37 | extern EditableLargeNumberMenuItem menuLgeNum; 38 | extern BooleanMenuItem menuL2; 39 | extern BooleanMenuItem menuL1; 40 | extern BackMenuItem menuBackLEDStates; 41 | extern SubMenuItem menuLEDStates; 42 | extern AnalogMenuItem menuValueA0; 43 | 44 | // Provide a wrapper to get hold of the root menu item and export setupMenu 45 | inline MenuItem& rootMenuItem() { return menuValueA0; } 46 | void setupMenu(); 47 | 48 | // Callback functions must always include CALLBACK_FUNCTION after the return type 49 | #define CALLBACK_FUNCTION 50 | 51 | int fnChooseItemRtCall(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize); 52 | void CALLBACK_FUNCTION onLed1(int id); 53 | void CALLBACK_FUNCTION onLed2(int id); 54 | 55 | #endif // MENU_GENERATED_CODE_H 56 | -------------------------------------------------------------------------------- /examples/avr/analogDfRobot/tcMenuLiquidCrystal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * @file tcMenuLiquidCrystal.h 8 | * 9 | * LiquidCrystalIO renderer that renders menus onto this type of display. This file is a plugin file and should not 10 | * be directly edited, it will be replaced each time the project is built. If you want to edit this file in place, 11 | * make sure to rename it first. 12 | * 13 | * LIBRARY REQUIREMENT 14 | * This renderer is designed for use with this library: https://github.com/TcMenu/LiquidCrystalIO 15 | */ 16 | 17 | #ifndef _TCMENU_LIQUID_CRYSTAL_H 18 | #define _TCMENU_LIQUID_CRYSTAL_H 19 | 20 | #include "tcMenu.h" 21 | #include "BaseRenderers.h" 22 | #include 23 | #include 24 | 25 | /** 26 | * A renderer that can renderer onto a LiquidCrystal display and supports the concept of single level 27 | * sub menus, active items and editing. 28 | */ 29 | class LiquidCrystalRenderer : public BaseMenuRenderer { 30 | private: 31 | LiquidCrystal* lcd; 32 | uint8_t dimY; 33 | uint8_t backChar; 34 | uint8_t forwardChar; 35 | uint8_t editChar; 36 | bool drewTitleThisTime; 37 | bool titleRequired; 38 | uint8_t lcdEditorCursorX = 0xFF; 39 | uint8_t lcdEditorCursorY = 0xFF; 40 | public: 41 | 42 | LiquidCrystalRenderer(LiquidCrystal& lcd, uint8_t dimX, uint8_t dimY); 43 | virtual ~LiquidCrystalRenderer(); 44 | void render() override; 45 | void initialise() override; 46 | void setTitleRequired(bool titleRequired) { this->titleRequired = titleRequired; } 47 | 48 | void setEditorChars(char back, char forward, char edit); 49 | 50 | uint8_t getRows() {return dimY;} 51 | LiquidCrystal* getLCD() {return lcd;} 52 | BaseDialog* getDialog() override; 53 | private: 54 | void renderTitle(bool forceDraw); 55 | void renderMenuItem(uint8_t row, MenuItem* item); 56 | void renderActionItem(uint8_t row, MenuItem* item); 57 | void renderBackItem(uint8_t row, MenuItem* item); 58 | void renderList(); 59 | void setupEditorPlacement(int32_t x, int32_t y); 60 | }; 61 | 62 | class LiquidCrystalDialog : public BaseDialog { 63 | public: 64 | LiquidCrystalDialog(LiquidCrystalRenderer* renderer) { 65 | bitWrite(flags, DLG_FLAG_SMALLDISPLAY, (renderer->getRows() <= 2)); 66 | } 67 | protected: 68 | void internalRender(int currentValue) override; 69 | }; 70 | 71 | /** 72 | * This method constructs an instance of a liquid crystal renderer. 73 | */ 74 | inline MenuRenderer* liquidCrystalRenderer(LiquidCrystal& lcd, uint8_t dimX, uint8_t dimY) { 75 | return new LiquidCrystalRenderer(lcd, dimX, dimY); 76 | } 77 | 78 | #endif // _TCMENU_LIQUID_CRYSTAL_H 79 | -------------------------------------------------------------------------------- /examples/avr/keyboardEthernetShield/tcMenuLiquidCrystal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * @file tcMenuLiquidCrystal.h 8 | * 9 | * LiquidCrystalIO renderer that renders menus onto this type of display. This file is a plugin file and should not 10 | * be directly edited, it will be replaced each time the project is built. If you want to edit this file in place, 11 | * make sure to rename it first. 12 | * 13 | * LIBRARY REQUIREMENT 14 | * This renderer is designed for use with this library: https://github.com/TcMenu/LiquidCrystalIO 15 | */ 16 | 17 | #ifndef _TCMENU_LIQUID_CRYSTAL_H 18 | #define _TCMENU_LIQUID_CRYSTAL_H 19 | 20 | #include "tcMenu.h" 21 | #include 22 | #include 23 | #include 24 | 25 | using namespace tcgfx; 26 | 27 | /** 28 | * A renderer that can renderer onto a LiquidCrystal display and supports the concept of single level 29 | * sub menus, active items and editing. 30 | */ 31 | class LiquidCrystalRenderer : public BaseGraphicalRenderer { 32 | private: 33 | LiquidCrystal* lcd; 34 | NullItemDisplayPropertiesFactory propertiesFactory; 35 | char backChar; 36 | char forwardChar; 37 | char editChar; 38 | uint8_t lcdEditorCursorX = 0xFF; 39 | uint8_t lcdEditorCursorY = 0xFF; 40 | public: 41 | LiquidCrystalRenderer(LiquidCrystal& lcd, int dimX, int dimY); 42 | ~LiquidCrystalRenderer() override; 43 | void initialise() override; 44 | void setTitleRequired(bool titleRequired) { titleMode = (titleRequired) ? TITLE_FIRST_ROW : NO_TITLE; } 45 | void setEditorChars(char back, char forward, char edit); 46 | 47 | uint8_t getRows() {return height;} 48 | LiquidCrystal* getLCD() {return lcd;} 49 | BaseDialog* getDialog() override; 50 | 51 | void drawingCommand(RenderDrawingCommand command) override; 52 | void drawWidget(Coord where, TitleWidget* widget, color_t colorFg, color_t colorBg) override; 53 | void drawMenuItem(GridPositionRowCacheEntry* entry, Coord where, Coord areaSize, const DrawingFlags& drawAll) override; 54 | void fillWithBackgroundTo(int endPoint) override; 55 | 56 | ItemDisplayPropertiesFactory &getDisplayPropertiesFactory() override { return propertiesFactory; } 57 | NullItemDisplayPropertiesFactory &getLcdDisplayPropertiesFactory() { return propertiesFactory; } 58 | 59 | void setupEditorPlacement(int32_t x, int32_t y); 60 | }; 61 | 62 | #endif // _TCMENU_LIQUID_CRYSTAL_H 63 | -------------------------------------------------------------------------------- /examples/avr/nokia5110/ThemeMonoInverseBuilder.h: -------------------------------------------------------------------------------- 1 | #ifndef TCMENU_THEME_MONO_INVERSE 2 | #define TCMENU_THEME_MONO_INVERSE 3 | 4 | #include 5 | 6 | color_t defaultItemPaletteMono[] = {1, 0, 1, 1}; 7 | color_t defaultTitlePaletteMono[] = {0, 1, 0, 0}; 8 | 9 | #define TITLE_PADDING 2 10 | #define TITLE_SPACING 2 11 | 12 | /** 13 | * This is one of the stock themes, you can modify it to meet your requirements, and it will not be updated by tcMenu 14 | * Designer unless you delete it. This sets up the fonts, spacing and padding for all items. 15 | * @param gr the graphical renderer 16 | * @param itemFont the font for items 17 | * @param titleFont the font for titles 18 | * @param needEditingIcons if editing icons are needed 19 | */ 20 | void installMonoInverseTitleTheme(GraphicsDeviceRenderer& gr, const MenuFontDef& itemFont, const MenuFontDef& titleFont, 21 | bool needEditingIcons, BaseGraphicalRenderer::TitleMode titleMode, bool useUnicode) { 22 | 23 | // See https://tcmenu.github.io/documentation/arduino-libraries/tc-menu/themes/rendering-with-themes-icons-grids/ 24 | TcThemeBuilder themeBuilder(gr); 25 | themeBuilder.withSelectedColors(0, 2) 26 | .dimensionsFromRenderer() 27 | .withItemPadding(MenuPadding(1)) 28 | .withRenderingSettings(titleMode, false) 29 | .withPalette(defaultItemPaletteMono) 30 | .withNativeFont(itemFont.fontData, itemFont.fontMag) 31 | .withSpacing(1); 32 | 33 | if(needEditingIcons) { 34 | themeBuilder.withStandardLowResCursorIcons(); 35 | } 36 | 37 | if(useUnicode) { 38 | themeBuilder.enableTcUnicode(); 39 | } 40 | 41 | themeBuilder.defaultTitleProperties() 42 | .withNativeFont(titleFont.fontData, titleFont.fontMag) 43 | .withPalette(defaultTitlePaletteMono) 44 | .withPadding(MenuPadding(TITLE_PADDING)) 45 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 46 | .withSpacing(TITLE_SPACING) 47 | .apply(); 48 | 49 | themeBuilder.defaultActionProperties() 50 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 51 | .apply(); 52 | 53 | themeBuilder.defaultItemProperties() 54 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_VALUE_RIGHT) 55 | .apply(); 56 | 57 | themeBuilder.apply(); 58 | } 59 | 60 | #endif //TCMENU_THEME_MONO_INVERSE 61 | -------------------------------------------------------------------------------- /examples/avr/nokia5110/nokia5110_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include "tcMenuAdaFruitGfxMono.h" 17 | #include "EthernetTransport.h" 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | // variables we declare that you may need to access 28 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 29 | extern TcMenuRemoteServer remoteServer; 30 | extern Adafruit_PCD8544 gfx; 31 | extern AdafruitDrawable gfxDrawable; 32 | extern GraphicsDeviceRenderer renderer; 33 | extern EthernetServer server; 34 | extern EthernetInitialisation ethernetInitialisation; 35 | 36 | // Any externals needed by IO expanders, EEPROMs etc 37 | 38 | 39 | // Global Menu Item exports 40 | extern EepromAuthenticationInfoMenuItem menuAuthenticator; 41 | extern RemoteMenuItem menuIoTMonitor; 42 | extern IpAddressMenuItem menuIP; 43 | extern BackMenuItem menuBackConnectivity; 44 | extern SubMenuItem menuConnectivity; 45 | extern TextMenuItem menuTxt; 46 | extern FloatMenuItem menuCurrent; 47 | extern FloatMenuItem menuVoltsIn; 48 | extern BackMenuItem menuBackStatus; 49 | extern SubMenuItem menuStatus; 50 | extern Rgb32MenuItem menuRGB; 51 | extern ActionMenuItem menuShutdownNow; 52 | extern AnalogMenuItem menuDelay; 53 | extern BooleanMenuItem menuPwrDelay; 54 | extern BackMenuItem menuBackSettings; 55 | extern SubMenuItem menuSettings; 56 | extern EnumMenuItem menuOnAlm; 57 | extern AnalogMenuItem menuKitchen; 58 | extern AnalogMenuItem menuLiving; 59 | extern AnalogMenuItem menuHall; 60 | 61 | // Provide a wrapper to get hold of the root menu item and export setupMenu 62 | inline MenuItem& rootMenuItem() { return menuHall; } 63 | void setupMenu(); 64 | 65 | // Callback functions must always include CALLBACK_FUNCTION after the return type 66 | #define CALLBACK_FUNCTION 67 | 68 | void CALLBACK_FUNCTION onHallLight(int id); 69 | void CALLBACK_FUNCTION onKitchenLight(int id); 70 | void CALLBACK_FUNCTION onLivingRoomLight(int id); 71 | void CALLBACK_FUNCTION onPowerDownDetected(int id); 72 | 73 | #endif // MENU_GENERATED_CODE_H 74 | -------------------------------------------------------------------------------- /examples/esp/esp32Amplifier/AmplifierController.h: -------------------------------------------------------------------------------- 1 | #ifndef TCMENU_ESPAMPLIFIER_AMPLIFIERCONTROLLER_H 2 | #define TCMENU_ESPAMPLIFIER_AMPLIFIERCONTROLLER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "esp32Amplifier_menu.h" 8 | 9 | #ifndef MENU_MAGIC_KEY 10 | #define MENU_MAGIC_KEY 0xfade 11 | #endif // MENU_MAGIC_KEY 12 | 13 | #ifndef NUM_CHANNELS 14 | #define NUM_CHANNELS 4 15 | #endif // NUM_CHANNELS 16 | 17 | #define EEPROM_TRIM_POS 140 18 | 19 | // 1234567890123456 1234567890123456 1234567890123456 1234567890123456 20 | const char pgmDefaultChannelNames[] PROGMEM = "Turntable\0 Auxiliary\0 USB Audio\0 Storage\0"; 21 | 22 | 23 | class AmplifierController { 24 | public: 25 | enum AmplifierStatus { 26 | WARMING_UP, 27 | VALVE_WARM_UP, 28 | RUNNING, 29 | DC_PROTECTION, 30 | OVERLOADED, 31 | OVERHEATED 32 | }; 33 | private: 34 | bool audioDirect; 35 | bool muted = true; 36 | int levelTrims[NUM_CHANNELS]; 37 | public: 38 | explicit AmplifierController() : levelTrims{} { 39 | menuMute.setBoolean(true); 40 | setAmpStatus(WARMING_UP); 41 | } 42 | 43 | void initialise() { 44 | for(int i=0; iread8(EEPROM_TRIM_POS + i); 46 | } 47 | } 48 | 49 | uint8_t getChannelInt() { 50 | uint8_t ch = menuChannels.getCurrentValue(); 51 | if(ch > NUM_CHANNELS) return 0; 52 | return ch; 53 | } 54 | 55 | void setAmpStatus(AmplifierStatus status) { 56 | menuStatusAmpStatus.setCurrentValue(status); 57 | } 58 | 59 | AmplifierStatus getAmpStatus() { 60 | return static_cast(menuStatusAmpStatus.getCurrentValue()); 61 | } 62 | 63 | void onVolumeChanged() { 64 | auto trim = levelTrims[getChannelInt()]; 65 | auto vol = menuVolume.getCurrentValue() + trim; 66 | auto volToWrite = menuMute.getBoolean() ? 0 : vol; 67 | serdebugF2("write volume to bus", volToWrite); 68 | } 69 | 70 | void onChannelChanged() { 71 | auto ch = (muted) ? 0 : (1 << getChannelInt()); 72 | onVolumeChanged(); 73 | serdebugF2("write channel to bus", ch); 74 | } 75 | 76 | void onAudioDirect(bool direct) { 77 | audioDirect = direct; 78 | } 79 | 80 | void onMute(bool mute) { 81 | muted = mute; 82 | } 83 | 84 | int getTrim(uint8_t channel) { 85 | if(channel >= NUM_CHANNELS) return 0; 86 | return levelTrims[channel]; 87 | } 88 | 89 | void setTrim(uint8_t channel, int newTrim) { 90 | if(channel >= NUM_CHANNELS) return; 91 | levelTrims[channel] = newTrim; 92 | menuMgr.getEepromAbstraction()->write8(EEPROM_TRIM_POS + channel, newTrim); 93 | } 94 | 95 | }; 96 | 97 | #endif //TCMENU_ESPAMPLIFIER_AMPLIFIERCONTROLLER_H 98 | -------------------------------------------------------------------------------- /examples/esp/esp32Amplifier/ClientEthernetTransport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * @file EthernetTransport.h 8 | * 9 | * Ethernet remote capability plugin. This file is a plugin file and should not be directly edited, 10 | * it will be replaced each time the project is built. If you want to edit this file in place, 11 | * make sure to rename it first. 12 | */ 13 | 14 | #ifndef TCMENU_ETHERNETTRANSPORT_H_ 15 | #define TCMENU_ETHERNETTRANSPORT_H_ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #ifndef ETHERNET_BUFFER_SIZE 24 | #define ETHERNET_BUFFER_SIZE 96 25 | #endif // ETHERNET_BUFFER_SIZE 26 | 27 | #ifndef DEFAULT_BACKOFF_PERIOD 28 | #define DEFAULT_BACKOFF_PERIOD HEARTBEAT_INTERVAL 29 | #endif // DEFAULT_BACKOFF_PERIOD 30 | 31 | #include 32 | 33 | namespace tcremote { 34 | 35 | /** 36 | * An implementation of TagValueTransport that is able to read and write via a buffer to sockets. 37 | */ 38 | class ClientEthernetTagValTransport : public tcremote::BaseBufferedRemoteTransport { 39 | private: 40 | WiFiClient client; 41 | public: 42 | ClientEthernetTagValTransport() : BaseBufferedRemoteTransport(BUFFER_ONE_MESSAGE, ETHERNET_BUFFER_SIZE, MAX_VALUE_LEN) { } 43 | ~ClientEthernetTagValTransport() override = default; 44 | void setClient(WiFiClient cl) { this->client = cl; } 45 | 46 | int fillReadBuffer(uint8_t* data, int maxSize) override; 47 | void flush() override; 48 | bool available() override; 49 | bool connected() override; 50 | void close() override; 51 | }; 52 | 53 | 54 | /** 55 | * This class provides the initialisation and connection generation logic for ethernet connections. 56 | */ 57 | class ClientEthernetInitialisation : public DeviceInitialisation { 58 | private: 59 | WiFiClient client; 60 | const char* host; 61 | uint16_t port; 62 | uint16_t backOffPeriod = 0; 63 | public: 64 | explicit ClientEthernetInitialisation(const char* host, uint16_t port) : host(host), port(port) {} 65 | 66 | bool attemptInitialisation() override; 67 | 68 | bool attemptNewConnection(BaseRemoteServerConnection *transport) override; 69 | private: 70 | bool checkBackoffPeriod(); 71 | }; 72 | 73 | /** 74 | * This function converts from a RSSI (Radio Strength indicator) 75 | * measurement into a series of icons (of the ones we have defined 76 | * in the stock icons. The input is the RSSI figure in dB as an 77 | * integer. 78 | * @param strength the signal strength (usually negative) as an int 79 | * @return a state that can be used with the standard wifi TitleWidget 80 | */ 81 | int fromWiFiRSSITo4StateIndicator(int strength); 82 | 83 | } // namespace tcremote 84 | 85 | #ifndef TC_MANUAL_NAMESPACING 86 | using namespace tcremote; 87 | #endif // TC_MANUAL_NAMESPACING 88 | 89 | #endif /* TCMENU_ETHERNETTRANSPORT_H_ */ 90 | -------------------------------------------------------------------------------- /examples/esp/esp32Amplifier/TestingDialogController.h: -------------------------------------------------------------------------------- 1 | #ifndef TCMENU_ESPAMPLIFIER_TESTINGDIALOGCONTROLLER_H 2 | #define TCMENU_ESPAMPLIFIER_TESTINGDIALOGCONTROLLER_H 3 | 4 | #include 5 | 6 | class TestingDialogController : public BaseDialogController { 7 | private: 8 | MenuBasedDialog* theDialog; 9 | public: 10 | void initialiseAndGetHeader(BaseDialog *dialog, char *buffer, size_t bufferSize) override { 11 | theDialog = reinterpret_cast(dialog); 12 | strcpy(buffer, "Test Dialog"); 13 | } 14 | 15 | void dialogDismissed(ButtonType buttonType) override { 16 | if(buttonType == BTNTYPE_OK) { 17 | theDialog->setButtons(BTNTYPE_NONE, BTNTYPE_CLOSE); 18 | theDialog->showRam("Extra dlg", true); 19 | theDialog->copyIntoBuffer("more text"); 20 | } 21 | } 22 | 23 | bool dialogButtonPressed(int buttonNum) override { 24 | return true; 25 | } 26 | 27 | void copyCustomButtonText(int buttonNumber, char *buffer, size_t bufferSize) override { 28 | buffer[0] = 0; 29 | } 30 | } testingDialogController; 31 | 32 | inline void showDialogs() { 33 | auto *dlg = renderer.getDialog(); 34 | if (dlg && !dlg->isInUse()) { 35 | dlg->setButtons(BTNTYPE_OK, BTNTYPE_CANCEL); 36 | dlg->showController(true, &testingDialogController); 37 | dlg->copyIntoBuffer("some more text"); 38 | } 39 | } 40 | 41 | #endif //TCMENU_ESPAMPLIFIER_TESTINGDIALOGCONTROLLER_H 42 | -------------------------------------------------------------------------------- /examples/esp/esp32Amplifier/ThemeCoolBlueModernBuilder.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Cool blue modern theme by TheCodersCorner.com. This is part of the standard themes shipped with TcMenu. 3 | * This file will not be updated by the designer, you can edit. 4 | */ 5 | #ifndef THEME_COOL_BLUE 6 | #define THEME_COOL_BLUE 7 | 8 | #include 9 | 10 | const color_t coolBlueTitlePalette[] = {RGB(0,0,0), RGB(20,132,255), RGB(192,192,192), RGB(64, 64, 64)}; 11 | const color_t coolBlueItemPalette[] = {RGB(255, 255, 255), RGB(0,64,135), RGB(20,133,255), RGB(31,100,178)}; 12 | const color_t coolBlueActionPalette[] = {RGB(255, 255, 255), RGB(0,45,120), RGB(20,133,255), RGB(31,100,178)}; 13 | 14 | #define ACTION_BORDER_WIDTH 0 15 | #define USE_SLIDER_FOR_ANALOG 1 16 | 17 | /** 18 | * This is one of the stock themes, you can modify it to meet your requirements, and it will not be updated by tcMenu 19 | * Designer unless you delete it. This sets up the fonts, spacing and padding for all items. 20 | * @param gr the graphical renderer 21 | * @param itemFont the font for items 22 | * @param titleFont the font for titles 23 | * @param needEditingIcons if editing icons are needed 24 | */ 25 | void installCoolBlueModernTheme(GraphicsDeviceRenderer& gr, const MenuFontDef& itemFont, const MenuFontDef& titleFont, 26 | bool needEditingIcons, BaseGraphicalRenderer::TitleMode titleMode, bool useUnicode) { 27 | 28 | TcThemeBuilder themeBuilder(gr); 29 | 30 | themeBuilder.dimensionsFromRenderer() 31 | .withSelectedColors(RGB(31, 88, 100), RGB(255, 255, 255)) 32 | .withItemPadding(MenuPadding(4, 3, 4, 3)) 33 | .withTitlePadding(MenuPadding(4, 3, 4, 3)) 34 | .withRenderingSettings(titleMode, USE_SLIDER_FOR_ANALOG) 35 | .withPalette(coolBlueItemPalette) 36 | .withNativeFont(itemFont.fontData, itemFont.fontMag) 37 | .withSpacing(2); 38 | 39 | if(needEditingIcons) { 40 | themeBuilder.withStandardMedResCursorIcons(); 41 | } 42 | 43 | if(useUnicode) { 44 | themeBuilder.enableTcUnicode(); 45 | } 46 | 47 | themeBuilder.defaultItemProperties() 48 | .withJustification(GridPosition::JUSTIFY_TITLE_LEFT_VALUE_RIGHT) 49 | .apply(); 50 | 51 | themeBuilder.defaultTitleProperties() 52 | .withJustification(GridPosition::JUSTIFY_CENTER_WITH_VALUE) 53 | .withNativeFont(titleFont.fontData, titleFont.fontMag) 54 | .withPalette(coolBlueTitlePalette) 55 | .withSpacing(3) 56 | .apply(); 57 | 58 | 59 | themeBuilder.defaultActionProperties() 60 | .withJustification(GridPosition::JUSTIFY_CENTER_WITH_VALUE) 61 | .withPalette(coolBlueActionPalette) 62 | .withBorder(MenuBorder(ACTION_BORDER_WIDTH)) 63 | .apply(); 64 | 65 | themeBuilder.apply(); 66 | } 67 | 68 | #endif //THEME_COOL_BLUE -------------------------------------------------------------------------------- /examples/esp/esp32Amplifier/additonalCallbacks.cpp: -------------------------------------------------------------------------------- 1 | // ADVANCED: here we show how to add additional callbacks when you've declared callbacks using the advanced 2 | // @functionName syntax in the onChange field in the designer UI. 3 | // 4 | // In this case only the header entries are created for you leaving you to create the functions whereever you wish. 5 | // The usual way to proceed here is to get the header definitions from the projectName_menu.h 6 | 7 | #include "esp32Amplifier_menu.h" 8 | 9 | void CALLBACK_FUNCTION valveHeatingChanged(int id) { 10 | serdebugF("valve heating callback called"); 11 | } 12 | 13 | void CALLBACK_FUNCTION warmUpChanged(int id) { 14 | serdebugF("warm up callback called"); 15 | } 16 | -------------------------------------------------------------------------------- /examples/esp/esp32SimHub/Fonts/robotoLicense.txt: -------------------------------------------------------------------------------- 1 | This example includes a compiled version of roboto mono font from google fonts. 2 | License file: 3 | https://fonts.google.com/specimen/Roboto+Mono#license -------------------------------------------------------------------------------- /examples/esp/esp32SimHub/SimhubConnector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * SimHub Connector that connects to simhub using the serial port and changes menu items based on simhub update. 8 | * This class should not be directly edited, it will be replaced each time the project is built. 9 | * If you want to edit this file in place, make sure to rename it first. 10 | */ 11 | 12 | #ifndef TCLIBRARYDEV_SIMHUBCONNECTOR_H 13 | #define TCLIBRARYDEV_SIMHUBCONNECTOR_H 14 | 15 | /** 16 | * this is the maximum number of chars on a line 17 | */ 18 | #define MAX_LINE_WIDTH 32 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #if defined(ESP8266) || defined(ESP32) 27 | # define SerPortName HardwareSerial 28 | #else 29 | # define SerPortName Stream 30 | #endif 31 | 32 | namespace tcremote { 33 | 34 | class SimhubConnector { 35 | private: 36 | SerPortName* serialPort; 37 | BooleanMenuItem* statusMenuItem; 38 | char lineBuffer[MAX_LINE_WIDTH]; 39 | int linePosition; 40 | bool connected; 41 | public: 42 | SimhubConnector(SerPortName* serialPort, menuid_t statusMenuId); 43 | void tick(); 44 | bool getStatus() { return connected; } 45 | private: 46 | void processCommandFromSimhub(); 47 | void processTcMenuCommand(); 48 | void changeStatus(bool b); 49 | }; 50 | 51 | 52 | class SimHubRemoteConnection : public BaseRemoteServerConnection { 53 | private: 54 | SimhubConnector connector; 55 | NoInitialisationNeeded noInitialisation; 56 | public: 57 | SimHubRemoteConnection(SerPortName* serialPort, menuid_t statusMenuId) 58 | : BaseRemoteServerConnection(noInitialisation, SIMHUB_CONNECTOR), connector(serialPort, statusMenuId) { 59 | } 60 | 61 | void init(int remoteNumber, const ConnectorLocalInfo &info) override; 62 | 63 | void tick() override; 64 | 65 | bool connected() override; 66 | 67 | void copyConnectionStatus(char *buffer, int bufferSize) override; 68 | }; 69 | } 70 | 71 | #ifndef TC_MANUAL_NAMESPACING 72 | using namespace tcremote; 73 | #endif // TC_MANUAL_NAMESPACING 74 | 75 | #endif //TCLIBRARYDEV_SIMHUBCONNECTOR_H 76 | -------------------------------------------------------------------------------- /examples/esp/esp32SimHub/dashboardSetup.h: -------------------------------------------------------------------------------- 1 | #ifndef TCLIBRARYDEV_DASHBOARDSETUP_H 2 | #define TCLIBRARYDEV_DASHBOARDSETUP_H 3 | 4 | #include 5 | #include "esp32SimHub_menu.h" 6 | #include 7 | 8 | #define LED_STATES 10 9 | 10 | class CustomDashboardDelegate : public DrawableDashboardDelegate { 11 | private: 12 | uint16_t ledColors[LED_STATES]; 13 | bool ledsChanged = true; 14 | public: 15 | 16 | void setLed(int i, uint16_t color); 17 | 18 | bool dashboardWillOpen(BaseMenuRenderer *renderer) override; 19 | void dashboardDidDraw(unsigned int encVal, RenderPressMode pressMode) override; 20 | }; 21 | 22 | extern DrawableDashboard* dashCustomDrawing; // from the ino file. 23 | extern CustomDashboardDelegate dashboardDelegate; // from the ino file. 24 | void setupDashboard(); 25 | 26 | #endif //TCLIBRARYDEV_DASHBOARDSETUP_H 27 | -------------------------------------------------------------------------------- /examples/esp/esp32SimHub/esp32SimHub_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include "tcMenuAdaFruitGfx.h" 18 | #include 19 | #include "SimhubConnector.h" 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | // variables we declare that you may need to access 27 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 28 | extern TcMenuRemoteServer remoteServer; 29 | extern Adafruit_ILI9341 gfx; 30 | extern AdafruitDrawable gfxDrawable; 31 | extern GraphicsDeviceRenderer renderer; 32 | extern ESP32TouchKeysAbstraction esp32Touch; 33 | extern const UnicodeFont OpenSansCyrillicLatin14[]; 34 | extern const UnicodeFont OpenSansCyrillicLatin18[]; 35 | 36 | // Any externals needed by IO expanders, EEPROMs etc 37 | 38 | 39 | // Global Menu Item exports 40 | extern ActionMenuItem menuEngineV836S; 41 | extern ActionMenuItem menuEngineV630T; 42 | extern ActionMenuItem menuEngineI420T; 43 | extern ActionMenuItem menuCardsI416T; 44 | extern BackMenuItem menuBackEngine; 45 | extern SubMenuItem menuEngine; 46 | extern ActionMenuItem menuShowDashboard; 47 | extern AnalogMenuItem menuLap; 48 | extern EnumMenuItem menuDashboard; 49 | extern EditableLargeNumberMenuItem menuSettingsNewLargeNumber; 50 | extern RemoteMenuItem menuSettingsIoTMonitor; 51 | extern EditableLargeNumberMenuItem menuSettingsLargeTest; 52 | extern BooleanMenuItem menuSettingsOverboost; 53 | extern ActionMenuItem menuSettingsShowDialogs; 54 | extern AnalogMenuItem menuSettingsTestItem1; 55 | extern BackMenuItem menuBackSettings; 56 | extern SubMenuItem menuSettings; 57 | extern BooleanMenuItem menuSimHubLink; 58 | extern AnalogMenuItem menuTyreTemp; 59 | extern TextMenuItem menuGear; 60 | extern AnalogMenuItem menuRPM; 61 | extern AnalogMenuItem menuSpeed; 62 | 63 | // Provide a wrapper to get hold of the root menu item and export setupMenu 64 | inline MenuItem& rootMenuItem() { return menuSpeed; } 65 | void setupMenu(); 66 | 67 | // Callback functions must always include CALLBACK_FUNCTION after the return type 68 | #define CALLBACK_FUNCTION 69 | 70 | void CALLBACK_FUNCTION onConnectionChange(int id); 71 | void CALLBACK_FUNCTION onDashChanged(int id); 72 | void CALLBACK_FUNCTION onEngineHasChanged(int id); 73 | void CALLBACK_FUNCTION onShowDash(int id); 74 | void CALLBACK_FUNCTION onShowDialogs(int id); 75 | 76 | #endif // MENU_GENERATED_CODE_H 77 | -------------------------------------------------------------------------------- /examples/esp/esp32s2Saola/ThemeMonoInverseBuilder.h: -------------------------------------------------------------------------------- 1 | #ifndef TCMENU_THEME_MONO_INVERSE 2 | #define TCMENU_THEME_MONO_INVERSE 3 | 4 | #include 5 | 6 | color_t defaultItemPaletteMono[] = {1, 0, 1, 1}; 7 | color_t defaultTitlePaletteMono[] = {0, 1, 0, 0}; 8 | 9 | #define TITLE_PADDING 2 10 | #define TITLE_SPACING 2 11 | 12 | /** 13 | * This is one of the stock themes, you can modify it to meet your requirements, and it will not be updated by tcMenu 14 | * Designer unless you delete it. This sets up the fonts, spacing and padding for all items. 15 | * @param gr the graphical renderer 16 | * @param itemFont the font for items 17 | * @param titleFont the font for titles 18 | * @param needEditingIcons if editing icons are needed 19 | */ 20 | void installMonoInverseTitleTheme(GraphicsDeviceRenderer& gr, const MenuFontDef& itemFont, const MenuFontDef& titleFont, 21 | bool needEditingIcons, BaseGraphicalRenderer::TitleMode titleMode, bool useUnicode) { 22 | TcThemeBuilder themeBuilder(gr); 23 | themeBuilder.withSelectedColors(0, 2) 24 | .dimensionsFromRenderer() 25 | .withItemPadding(MenuPadding(1)) 26 | .withRenderingSettings(titleMode, false) 27 | .withPalette(defaultItemPaletteMono) 28 | .withNativeFont(itemFont.fontData, itemFont.fontMag) 29 | .withSpacing(1); 30 | 31 | if(needEditingIcons) { 32 | themeBuilder.withStandardLowResCursorIcons(); 33 | } 34 | 35 | if(useUnicode) { 36 | themeBuilder.enablingTcUnicode(); 37 | } 38 | 39 | themeBuilder.defaultTitleProperties() 40 | .withNativeFont(titleFont.fontData, titleFont.fontMag) 41 | .withPalette(defaultTitlePaletteMono) 42 | .withPadding(MenuPadding(TITLE_PADDING)) 43 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 44 | .withSpacing(TITLE_SPACING) 45 | .apply(); 46 | 47 | themeBuilder.defaultActionProperties() 48 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 49 | .apply(); 50 | 51 | themeBuilder.defaultItemProperties() 52 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_VALUE_RIGHT) 53 | .apply(); 54 | 55 | themeBuilder.apply(); 56 | } 57 | 58 | #endif //TCMENU_THEME_MONO_INVERSE 59 | -------------------------------------------------------------------------------- /examples/esp/esp32s2Saola/generated/ClientEthernetTransport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * @file EthernetTransport.h 8 | * 9 | * Ethernet remote capability plugin. This file is a plugin file and should not be directly edited, 10 | * it will be replaced each time the project is built. If you want to edit this file in place, 11 | * make sure to rename it first. 12 | */ 13 | 14 | #ifndef TCMENU_ETHERNETTRANSPORT_H_ 15 | #define TCMENU_ETHERNETTRANSPORT_H_ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #ifndef ETHERNET_BUFFER_SIZE 24 | #define ETHERNET_BUFFER_SIZE 96 25 | #endif // ETHERNET_BUFFER_SIZE 26 | 27 | #ifndef DEFAULT_BACKOFF_PERIOD 28 | #define DEFAULT_BACKOFF_PERIOD (4 * (1000 / TICK_INTERVAL)) 29 | #endif // DEFAULT_BACKOFF_PERIOD 30 | 31 | #include 32 | 33 | namespace tcremote { 34 | 35 | /** 36 | * An implementation of TagValueTransport that is able to read and write via a buffer to sockets. 37 | */ 38 | class ClientEthernetTagValTransport : public tcremote::BaseBufferedRemoteTransport { 39 | private: 40 | WiFiClient client; 41 | public: 42 | ClientEthernetTagValTransport() : BaseBufferedRemoteTransport(BUFFER_ONE_MESSAGE, ETHERNET_BUFFER_SIZE, MAX_VALUE_LEN) { } 43 | ~ClientEthernetTagValTransport() override = default; 44 | void setClient(WiFiClient cl) { this->client = cl; } 45 | 46 | int fillReadBuffer(uint8_t* data, int maxSize) override; 47 | void flush() override; 48 | bool available() override; 49 | bool connected() override; 50 | void close() override; 51 | }; 52 | 53 | 54 | /** 55 | * This class provides the initialisation and connection generation logic for ethernet connections. 56 | */ 57 | class ClientEthernetInitialisation : public DeviceInitialisation { 58 | private: 59 | WiFiClient client; 60 | const char* host; 61 | uint16_t port; 62 | uint16_t backOffPeriod = 0; 63 | public: 64 | explicit ClientEthernetInitialisation(const char* host, uint16_t port) : host(host), port(port) {} 65 | 66 | bool attemptInitialisation() override; 67 | 68 | bool attemptNewConnection(BaseRemoteServerConnection *transport) override; 69 | private: 70 | bool checkBackoffPeriod(); 71 | }; 72 | 73 | /** 74 | * This function converts from a RSSI (Radio Strength indicator) 75 | * measurement into a series of icons (of the ones we have defined 76 | * in the stock icons. The input is the RSSI figure in dB as an 77 | * integer. 78 | * @param strength the signal strength (usually negative) as an int 79 | * @return a state that can be used with the standard wifi TitleWidget 80 | */ 81 | int fromWiFiRSSITo4StateIndicator(int strength); 82 | 83 | } // namespace tcremote 84 | 85 | #ifndef TC_MANUAL_NAMESPACING 86 | using namespace tcremote; 87 | #endif // TC_MANUAL_NAMESPACING 88 | 89 | #endif /* TCMENU_ETHERNETTRANSPORT_H_ */ 90 | -------------------------------------------------------------------------------- /examples/esp/esp32s2Saola/generated/esp32s2Saola_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include "tcMenuU8g2.h" 17 | #include "EthernetTransport.h" 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | // variables we declare that you may need to access 28 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 29 | extern TcMenuRemoteServer remoteServer; 30 | extern U8G2_SH1106_128X64_NONAME_F_HW_I2C gfx; 31 | extern U8g2Drawable gfxDrawable; 32 | extern GraphicsDeviceRenderer renderer; 33 | extern WiFiServer server; 34 | extern EthernetInitialisation ethernetInitialisation; 35 | 36 | // Any externals needed by IO expanders, EEPROMs etc 37 | 38 | 39 | // Global Menu Item exports 40 | extern EepromAuthenticationInfoMenuItem menuConnectivityAuthenticator; 41 | extern RemoteMenuItem menuConnectivityIoTMonitor; 42 | extern IpAddressMenuItem menuConnectivityIPAddress; 43 | extern EnumMenuItem menuConnectivityWiFiMode; 44 | extern TextMenuItem menuConnectivityPasscode; 45 | extern TextMenuItem menuConnectivitySSID; 46 | extern BackMenuItem menuBackConnectivity; 47 | extern SubMenuItem menuConnectivity; 48 | extern ListRuntimeMenuItem menuExtrasMyList; 49 | extern Rgb32MenuItem menuExtrasColor; 50 | extern TextMenuItem menuExtrasText; 51 | extern BackMenuItem menuBackExtras; 52 | extern SubMenuItem menuExtras; 53 | extern BooleanMenuItem menuSelectMeNewBoolItem; 54 | extern ActionMenuItem menuSelectMePressMe; 55 | extern FloatMenuItem menuSelectMeFloat2; 56 | extern FloatMenuItem menuSelectMeFloat1; 57 | extern BackMenuItem menuBackSelectMe; 58 | extern SubMenuItem menuSelectMe; 59 | extern BooleanMenuItem menuDoorOpen; 60 | extern EnumMenuItem menuFoods; 61 | extern AnalogMenuItem menuHalves; 62 | extern AnalogMenuItem menuDecEdit; 63 | extern AnalogMenuItem menuIntEdit; 64 | 65 | // Provide a wrapper to get hold of the root menu item and export setupMenu 66 | inline MenuItem& rootMenuItem() { return menuIntEdit; } 67 | void setupMenu(); 68 | 69 | // Callback functions must always include CALLBACK_FUNCTION after the return type 70 | #define CALLBACK_FUNCTION 71 | 72 | void CALLBACK_FUNCTION onListSelected(int id); 73 | int fnExtrasMyListRtCall(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize); 74 | void CALLBACK_FUNCTION pressMeActionRun(int id); 75 | 76 | #endif // MENU_GENERATED_CODE_H 77 | -------------------------------------------------------------------------------- /examples/esp/esp32s2Saola/u8g2DashConfig.h: -------------------------------------------------------------------------------- 1 | // A few references from the dashboard source exported for the main file. 2 | 3 | #ifndef TCEXAMPLE_DASHBOARDCONFIG_H 4 | #define TCEXAMPLE_DASHBOARDCONFIG_H 5 | 6 | #include "generated/esp32s2Saola_menu.h" 7 | #include "extras/DrawableDashboard.h" 8 | 9 | void setupDashboard(); 10 | extern TitleWidget wifiWidget; // reference from the ino file 11 | extern DrawableDashboard* mainDashboard; // reference from the dashboard file 12 | 13 | #endif //TCEXAMPLE_DASHBOARDCONFIG_H 14 | -------------------------------------------------------------------------------- /examples/esp/esp32s3TftEncoder/generated/esp32s3TftEncoder_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include "tcMenuAdaFruitGfx.h" 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | // variables we declare that you may need to access 25 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 26 | extern Adafruit_ST7735 gfx; 27 | extern AdafruitDrawable gfxDrawable; 28 | extern GraphicsDeviceRenderer renderer; 29 | extern const UnicodeFont OpenSansRegular8pt[]; 30 | extern const UnicodeFont OpenSansRegular10pt[]; 31 | 32 | // Any externals needed by IO expanders, EEPROMs etc 33 | 34 | 35 | // Global Menu Item exports 36 | extern BooleanMenuItem menuToGo; 37 | extern EnumMenuItem menuFoods; 38 | extern EnumMenuItem menuBatteryCondition; 39 | extern AnalogMenuItem menuBatteryCharge; 40 | extern BackMenuItem menuBackBattery; 41 | extern SubMenuItem menuBattery; 42 | extern BooleanMenuItem menuMute; 43 | extern EditableLargeNumberMenuItem menuSettingsLgeNum1; 44 | extern AnalogMenuItem menuSettingsTenths1; 45 | extern AnalogMenuItem menuSettingsPercent1; 46 | extern DateFormattedMenuItem menuNewSubMenuDate; 47 | extern TextMenuItem menuNewSubMenuText; 48 | extern Rgb32MenuItem menuNewSubMenuColor; 49 | extern BackMenuItem menuBackSettings; 50 | extern SubMenuItem menuSettings; 51 | 52 | // Provide a wrapper to get hold of the root menu item and export setupMenu 53 | inline MenuItem& rootMenuItem() { return menuSettings; } 54 | void setupMenu(); 55 | 56 | // Callback functions must always include CALLBACK_FUNCTION after the return type 57 | #define CALLBACK_FUNCTION 58 | 59 | 60 | #endif // MENU_GENERATED_CODE_H 61 | -------------------------------------------------------------------------------- /examples/esp/esp8266WifiOled/README.md: -------------------------------------------------------------------------------- 1 | # ESP8266 and ESP32 Arduino menu with Wifi control and a local OLED SSD1306. 2 | 3 | This example shows a more complex menu with the following components. 4 | 5 | * 128 x 32 OLED menu 6 | * Rotary encoder wired directly 7 | * I2C EEPROM device to load and save menu. 8 | * Wifi support using the inbuilt WiFi device. 9 | 10 | This example is built for the ESP device. However, with a few changes it could probably be used for other boards. Although you'd be better off starting 11 | with a more appropriate example for your hardware. 12 | 13 | In order to connect using the Java API there are two possibilities, either use the connector UI that's shipped with TcMenu, or work with the tcMenu API directly. See [https://github.com/TcMenu/tcMenu]. We'll be building out the API in other languages over time, but you can also write directly to the 14 | protocol, which is very simple. 15 | 16 | The authentication on this version is using the EEPROM based authenticator. This stores a number of keys in the EEPROM. However, its using the flash 17 | based rom by default, so you need to choose save all from the setup menu after pairing. This commits the changes to ROM. BE VERY AWARE that you are 18 | writing to FLASH memory when you do this, and the workable cycles are much lower than proper EEPROM. I prefer including EEPROM i2c devices which are 19 | safer. 20 | 21 | The files in this example are as follows: 22 | 23 | * `Greenhouse.emf` the controller system simulating our food growing greenhouse. Open this is the designer UI 24 | * `esp8266WifiOled.ino` the main sketch file, this will be modified by designer when new callbacks are added. 25 | * `EthernetTransport.cpp` and `.h` contain the ethernet plugin for tcMenu and should not be altered. Rewritten each code generation 26 | * `tcMenuAdaFruitGfx.cpp` and `.h` contain the graphics drawing plugin and should not be altered. Rewritten each code generation. 27 | * `esp8266WifiOled_menu.cpp` and `.h` contain the definitions of the menu item, and should not be altered. Rewritten each code generation. 28 | -------------------------------------------------------------------------------- /examples/esp/esp8266WifiOled/ThemeMonoInverseBuilder.h: -------------------------------------------------------------------------------- 1 | #ifndef TCMENU_THEME_MONO_INVERSE 2 | #define TCMENU_THEME_MONO_INVERSE 3 | 4 | #include 5 | 6 | color_t defaultItemPaletteMono[] = {1, 0, 1, 1}; 7 | color_t defaultTitlePaletteMono[] = {0, 1, 0, 0}; 8 | 9 | #define TITLE_PADDING 2 10 | #define TITLE_SPACING 2 11 | 12 | /** 13 | * This is one of the stock themes, you can modify it to meet your requirements, and it will not be updated by tcMenu 14 | * Designer unless you delete it. This sets up the fonts, spacing and padding for all items. 15 | * @param gr the graphical renderer 16 | * @param itemFont the font for items 17 | * @param titleFont the font for titles 18 | * @param needEditingIcons if editing icons are needed 19 | */ 20 | void installMonoInverseTitleTheme(GraphicsDeviceRenderer& gr, const MenuFontDef& itemFont, const MenuFontDef& titleFont, 21 | bool needEditingIcons, BaseGraphicalRenderer::TitleMode titleMode, bool useUnicode) { 22 | 23 | // See https://tcmenu.github.io/documentation/arduino-libraries/tc-menu/themes/rendering-with-themes-icons-grids/ 24 | TcThemeBuilder themeBuilder(gr); 25 | themeBuilder.withSelectedColors(0, 2) 26 | .dimensionsFromRenderer() 27 | .withItemPadding(MenuPadding(1)) 28 | .withRenderingSettings(titleMode, false) 29 | .withPalette(defaultItemPaletteMono) 30 | .withNativeFont(itemFont.fontData, itemFont.fontMag) 31 | .withSpacing(1); 32 | 33 | if(needEditingIcons) { 34 | themeBuilder.withStandardLowResCursorIcons(); 35 | } 36 | 37 | if(useUnicode) { 38 | themeBuilder.enableTcUnicode(); 39 | } 40 | 41 | themeBuilder.defaultTitleProperties() 42 | .withNativeFont(titleFont.fontData, titleFont.fontMag) 43 | .withPalette(defaultTitlePaletteMono) 44 | .withPadding(MenuPadding(TITLE_PADDING)) 45 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 46 | .withSpacing(TITLE_SPACING) 47 | .apply(); 48 | 49 | themeBuilder.defaultActionProperties() 50 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 51 | .apply(); 52 | 53 | themeBuilder.defaultItemProperties() 54 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_VALUE_RIGHT) 55 | .apply(); 56 | 57 | themeBuilder.apply(); 58 | } 59 | 60 | #endif //TCMENU_THEME_MONO_INVERSE 61 | -------------------------------------------------------------------------------- /examples/esp/esp8266WifiOled/appicons.h: -------------------------------------------------------------------------------- 1 | 2 | #define APPICON_SETTINGS_WIDTH 24 3 | #define APPICON_SETTINGS_HEIGHT 24 4 | static unsigned char appIconSettings[] = { 5 | 0x00, 0x81, 0x00, 0xc0, 0xe3, 0x03, 0xc0, 0xe3, 0x03, 0xc0, 0xf7, 0x03, 6 | 0xc0, 0xff, 0x01, 0xc0, 0xff, 0x03, 0xee, 0xf7, 0x7f, 0xfe, 0x81, 0x7f, 7 | 0xff, 0x00, 0xff, 0x7e, 0x00, 0x7e, 0x7e, 0x00, 0x1e, 0x78, 0x00, 0x1e, 8 | 0x70, 0x00, 0x1e, 0x7c, 0x00, 0x3e, 0x7e, 0x00, 0xfe, 0xfe, 0x00, 0xff, 9 | 0xfe, 0x81, 0x7f, 0xfe, 0xf7, 0x77, 0xc0, 0xff, 0x03, 0x80, 0xff, 0x03, 10 | 0xc0, 0xef, 0x03, 0xc0, 0xc7, 0x03, 0xc0, 0xc3, 0x03, 0x00, 0x83, 0x00 }; 11 | 12 | #define APPICON_HEAT_WIDTH 24 13 | #define APPICON_HEAT_HEIGHT 24 14 | static unsigned char appIconHeatOff[] = { 15 | 0x1c, 0x1c, 0x0c, 0x3e, 0x3e, 0x1e, 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0x3f, 16 | 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0xff, 0x7f, 0x7f, 0xff, 17 | 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0x3f, 18 | 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0x3f, 19 | 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0xff, 0x7f, 0x7f, 0xff, 20 | 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0x3f, 0x3e, 0x3e, 0x1e, 0x1c, 0x1c, 0x0c }; 21 | 22 | static unsigned char appIconHeatOn[] = { 23 | 0x1c, 0x1c, 0x0c, 0x3e, 0x3e, 0x1e, 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0x3f, 24 | 0x7f, 0x7f, 0x3f, 0x77, 0x77, 0x37, 0x77, 0x77, 0xf7, 0x7b, 0x7b, 0xfb, 25 | 0x7b, 0x7b, 0x3b, 0x7b, 0x7b, 0x3b, 0x77, 0x77, 0x37, 0x77, 0x77, 0x37, 26 | 0x77, 0x77, 0x37, 0x7b, 0x7b, 0x3b, 0x7b, 0x7b, 0x3b, 0x7b, 0x7b, 0x3b, 27 | 0x77, 0x77, 0x37, 0x77, 0x77, 0x37, 0x7f, 0x7f, 0xff, 0x7f, 0x7f, 0xff, 28 | 0x7f, 0x7f, 0x3f, 0x7f, 0x7f, 0x3f, 0x3e, 0x3e, 0x1e, 0x1c, 0x1c, 0x0c }; 29 | 30 | 31 | #define APPICON_LOCK_WIDTH 19 32 | #define APPICON_LOCK_HEIGHT 24 33 | static unsigned char appIconLockOpen[] = { 34 | 0x80, 0x0f, 0x00, 0xe0, 0x3f, 0x00, 0xf0, 0x7d, 0x00, 0xf0, 0x78, 0x00, 35 | 0x78, 0xf0, 0x00, 0x38, 0xe0, 0x00, 0x3c, 0xe0, 0x01, 0x3c, 0xe0, 0x01, 36 | 0x1c, 0xc0, 0x01, 0x00, 0xc0, 0x01, 0x00, 0xc0, 0x01, 0xff, 0xff, 0x07, 37 | 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0xff, 0xf8, 0x07, 38 | 0x7f, 0xf0, 0x07, 0x7f, 0xf0, 0x07, 0xff, 0xf8, 0x07, 0xff, 0xf8, 0x07, 39 | 0xff, 0xf8, 0x07, 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0xff, 0xff, 0x07 }; 40 | 41 | static unsigned char appIconLockClosed[] = { 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0xe0, 0x3f, 0x00, 43 | 0xf0, 0x7d, 0x00, 0xf0, 0x78, 0x00, 0x78, 0xf0, 0x00, 0x38, 0xe0, 0x00, 44 | 0x3c, 0xe0, 0x01, 0x3c, 0xe0, 0x01, 0x1c, 0xc0, 0x01, 0xff, 0xff, 0x07, 45 | 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0xff, 0xf8, 0x07, 46 | 0x7f, 0xf0, 0x07, 0x7f, 0xf0, 0x07, 0xff, 0xf8, 0x07, 0xff, 0xf8, 0x07, 47 | 0xff, 0xf8, 0x07, 0xff, 0xff, 0x07, 0xff, 0xff, 0x07, 0xff, 0xff, 0x07 }; 48 | -------------------------------------------------------------------------------- /examples/esp/esp8266WifiOled/esp8266WifiOled_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include "tcMenuU8g2.h" 17 | #include "EthernetTransport.h" 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | // variables we declare that you may need to access 29 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 30 | extern TcMenuRemoteServer remoteServer; 31 | extern U8G2_SH1106_128X64_NONAME_F_HW_I2C gfx; 32 | extern U8g2Drawable gfxDrawable; 33 | extern GraphicsDeviceRenderer renderer; 34 | extern WiFiServer server; 35 | extern EthernetInitialisation ethernetInitialisation; 36 | 37 | // Any externals needed by IO expanders, EEPROMs etc 38 | extern IoAbstractionRef ioexp_io8574; 39 | 40 | // Global Menu Item exports 41 | extern EnumMenuItem menuWiFiMode; 42 | extern EepromAuthenticationInfoMenuItem menuAuthenticator; 43 | extern RemoteMenuItem menuIoTMonitor; 44 | extern IpAddressMenuItem menuIpAddress; 45 | extern TextMenuItem menuPwd; 46 | extern TextMenuItem menuSSID; 47 | extern BackMenuItem menuBackConnectivity; 48 | extern SubMenuItem menuConnectivity; 49 | extern ActionMenuItem menuLoadFiles; 50 | extern ScrollChoiceMenuItem menuFile; 51 | extern BooleanMenuItem menuSecretEntry; 52 | extern ActionMenuItem menuSaveAll; 53 | extern EnumMenuItem menuWinOpening; 54 | extern EnumMenuItem menuHeaterPower; 55 | extern BackMenuItem menuBackSetup; 56 | extern SubMenuItem menuSetup; 57 | extern BooleanMenuItem menuLockDoor; 58 | extern BooleanMenuItem menuElectricHeater; 59 | extern AnalogMenuItem menuCucumberTemp; 60 | extern AnalogMenuItem menuTomatoTemp; 61 | 62 | // Provide a wrapper to get hold of the root menu item and export setupMenu 63 | inline MenuItem& rootMenuItem() { return menuTomatoTemp; } 64 | void setupMenu(); 65 | 66 | // Callback functions must always include CALLBACK_FUNCTION after the return type 67 | #define CALLBACK_FUNCTION 68 | 69 | void CALLBACK_FUNCTION onElectricHeater(int id); 70 | void CALLBACK_FUNCTION onFileChoice(int id); 71 | void CALLBACK_FUNCTION onHeaterPower(int id); 72 | void CALLBACK_FUNCTION onLoadFiles(int id); 73 | void CALLBACK_FUNCTION onLockDoor(int id); 74 | void CALLBACK_FUNCTION onSaveAll(int id); 75 | void CALLBACK_FUNCTION onWindowOpening(int id); 76 | 77 | #endif // MENU_GENERATED_CODE_H 78 | -------------------------------------------------------------------------------- /examples/esp/espCapTouchTft/ThemeCoolBlueModernBuilder.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Cool blue modern theme by tcMenu organisation. This is part of the standard themes shipped with TcMenu. 3 | * This file will not be updated by the designer, you can edit. 4 | * See https://www.thecoderscorner.com/products/arduino-libraries/tc-menu/themes/rendering-with-themes-icons-grids/ 5 | */ 6 | 7 | #ifndef THEME_COOL_BLUE 8 | #define THEME_COOL_BLUE 9 | 10 | #include 11 | 12 | const color_t coolBlueTitlePalette[] = {RGB(0,0,0), RGB(20,132,255), RGB(192,192,192), RGB(64, 64, 64)}; 13 | const color_t coolBlueItemPalette[] = {RGB(255, 255, 255), RGB(0,64,135), RGB(20,133,255), RGB(31,100,178)}; 14 | const color_t coolBlueActionPalette[] = {RGB(255, 255, 255), RGB(0,45,120), RGB(20,133,255), RGB(31,100,178)}; 15 | 16 | #define ACTION_BORDER_WIDTH 0 17 | #define USE_SLIDER_FOR_ANALOG true 18 | 19 | /** 20 | * This is one of the stock themes, you can modify it to meet your requirements, and it will not be updated by tcMenu 21 | * Designer unless you delete it. This sets up the fonts, spacing and padding for all items. 22 | * @param gr the graphical renderer 23 | * @param itemFont the font for items 24 | * @param titleFont the font for titles 25 | * @param needEditingIcons if editing icons are needed 26 | */ 27 | void installCoolBlueModernTheme(GraphicsDeviceRenderer& gr, const MenuFontDef& itemFont, const MenuFontDef& titleFont, 28 | bool needEditingIcons, BaseGraphicalRenderer::TitleMode titleMode, bool useUnicode) { 29 | 30 | TcThemeBuilder themeBuilder(gr); 31 | 32 | themeBuilder.dimensionsFromRenderer() 33 | .withSelectedColors(RGB(31, 88, 100), RGB(255, 255, 255)) 34 | .withItemPadding(MenuPadding(4, 3, 4, 3)) 35 | .withTitlePadding(MenuPadding(4, 3, 4, 3)) 36 | .withRenderingSettings(titleMode, USE_SLIDER_FOR_ANALOG) 37 | .withPalette(coolBlueItemPalette) 38 | .withNativeFont(itemFont.fontData, itemFont.fontMag) 39 | .withSpacing(2); 40 | 41 | if(needEditingIcons) { 42 | themeBuilder.withStandardMedResCursorIcons(); 43 | } 44 | 45 | if(useUnicode) { 46 | themeBuilder.enableTcUnicode(); 47 | } 48 | 49 | themeBuilder.defaultItemProperties() 50 | .withJustification(GridPosition::JUSTIFY_TITLE_LEFT_VALUE_RIGHT) 51 | .apply(); 52 | 53 | themeBuilder.defaultTitleProperties() 54 | .withJustification(GridPosition::JUSTIFY_CENTER_WITH_VALUE) 55 | .withNativeFont(titleFont.fontData, titleFont.fontMag) 56 | .withPalette(coolBlueTitlePalette) 57 | .withSpacing(3) 58 | .apply(); 59 | 60 | 61 | themeBuilder.defaultActionProperties() 62 | .withJustification(GridPosition::JUSTIFY_CENTER_WITH_VALUE) 63 | .withPalette(coolBlueActionPalette) 64 | .withBorder(MenuBorder(ACTION_BORDER_WIDTH)) 65 | .apply(); 66 | 67 | themeBuilder.apply(); 68 | } 69 | 70 | #endif //THEME_COOL_BLUE -------------------------------------------------------------------------------- /examples/esp/espCapTouchTft/espCapTouchTft_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include "tcMenuTfteSpi.h" 17 | #include 18 | #include "tcMenuAdaTouchDriver.h" 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | // variables we declare that you may need to access 26 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 27 | extern TFT_eSPI gfx; 28 | extern TfteSpiDrawable gfxDrawable; 29 | extern GraphicsDeviceRenderer renderer; 30 | extern Adafruit_FT6206 touchDevice; 31 | extern iotouch::AdaLibTouchInterrogator touchInterrogator; 32 | extern MenuTouchScreenManager touchScreen; 33 | 34 | // Any externals needed by IO expanders, EEPROMs etc 35 | 36 | 37 | // Global Menu Item exports 38 | extern ActionMenuItem menuPressMe; 39 | extern ListRuntimeMenuItem menuNewRuntimeList; 40 | extern TextMenuItem menuRuntimesCustom; 41 | extern Rgb32MenuItem menuRuntimesRGB; 42 | extern TextMenuItem menuRuntimesText; 43 | extern BackMenuItem menuBackRuntimes; 44 | extern SubMenuItem menuRuntimes; 45 | extern BooleanMenuItem menuCheck; 46 | extern EnumMenuItem menuFoods; 47 | extern AnalogMenuItem menuPercentage; 48 | 49 | // Provide a wrapper to get hold of the root menu item and export setupMenu 50 | inline MenuItem& rootMenuItem() { return menuPercentage; } 51 | void setupMenu(); 52 | 53 | // Callback functions must always include CALLBACK_FUNCTION after the return type 54 | #define CALLBACK_FUNCTION 55 | 56 | int CustomTextCallbackRtCall(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize); 57 | int fnNewRuntimeListRtCall(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize); 58 | 59 | #endif // MENU_GENERATED_CODE_H 60 | -------------------------------------------------------------------------------- /examples/esp/espCapTouchTft/tcMenuAdaTouchDriver.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * Touch integration for libraries that are compatible with the Adafruit_FT2606 library interface. It has been tested 8 | * with both the XPT_2046 and FT_6206 libraries. 9 | * This file is a plugin file and should not be directly edited, it will be replaced each time the project 10 | * is built. If you want to edit this file in place, make sure to rename it first. 11 | * @file tcMenuAdaTouchDriver.h 12 | */ 13 | 14 | #ifndef TCMENU_TOUCH_PLUGIN_H 15 | #define TCMENU_TOUCH_PLUGIN_H 16 | 17 | #include 18 | #include 19 | 20 | // 21 | // This is the known absolute maximum value of the touch unit before calibration. It will become 1.0F 22 | // 23 | #define KNOWN_DEVICE_TOUCH_RANGE_X 240.0F 24 | #define KNOWN_DEVICE_TOUCH_RANGE_Y 320.0F 25 | 26 | namespace iotouch { 27 | 28 | /** 29 | * Implements the touch interrogator class, this purely gets the current reading from the device when requested. 30 | */ 31 | class AdaLibTouchInterrogator : public iotouch::TouchInterrogator { 32 | private: 33 | Adafruit_FT6206& theTouchDevice; 34 | public: 35 | AdaLibTouchInterrogator(Adafruit_FT6206& touchLibRef) : theTouchDevice(touchLibRef) {} 36 | 37 | void init() { 38 | theTouchDevice.begin(); 39 | } 40 | 41 | iotouch::TouchState internalProcessTouch(float *ptrX, float *ptrY, const iotouch::TouchOrientationSettings& rotation, const iotouch::CalibrationHandler& calib) { 42 | if(theTouchDevice.touched() == 0) return iotouch::NOT_TOUCHED; 43 | 44 | TS_Point pt = theTouchDevice.getPoint(); 45 | //serdebugF3("point at ", pt.x, pt.y); 46 | 47 | *ptrX = calib.calibrateX(float(pt.x) / KNOWN_DEVICE_TOUCH_RANGE_X, rotation.isXInverted()); 48 | *ptrY = calib.calibrateY(float(pt.y) / KNOWN_DEVICE_TOUCH_RANGE_Y, rotation.isYInverted()); 49 | return iotouch::TOUCHED; 50 | } 51 | }; 52 | 53 | } 54 | 55 | #endif // TCMENU_TOUCH_PLUGIN_H 56 | -------------------------------------------------------------------------------- /examples/esp/simpleU8g2/ThemeMonoBorderedBuilder.h: -------------------------------------------------------------------------------- 1 | #ifndef TCMENU_THEME_MONO_INVERSE 2 | #define TCMENU_THEME_MONO_INVERSE 3 | 4 | #include 5 | 6 | color_t defaultItemPaletteMono[] = {WHITE, BLACK, WHITE, WHITE}; 7 | 8 | #define TITLE_BORDER_THICKNESS 2 9 | #define TITLE_SPACING 2 10 | 11 | /** 12 | * This is one of the stock themes, you can modify it to meet your requirements, and it will not be updated by tcMenu 13 | * Designer unless you delete it. This sets up the fonts, spacing and padding for all items. 14 | * @param gr the graphical renderer 15 | * @param itemFont the font for items 16 | * @param titleFont the font for titles 17 | * @param needEditingIcons if editing icons are needed 18 | */ 19 | void installMonoBorderTitleTheme(GraphicsDeviceRenderer& gr, const MenuFontDef& itemFont, const MenuFontDef& titleFont, 20 | bool needEditingIcons, BaseGraphicalRenderer::TitleMode titleMode, bool useUnicode) { 21 | 22 | // See https://tcmenu.github.io/documentation/arduino-libraries/tc-menu/themes/rendering-with-themes-icons-grids/ 23 | TcThemeBuilder themeBuilder(gr); 24 | themeBuilder.withSelectedColors(0, 1) 25 | .dimensionsFromRenderer() 26 | .withItemPadding(MenuPadding(1)) 27 | .withRenderingSettings(titleMode, false) 28 | .withPalette(defaultItemPaletteMono) 29 | .withNativeFont(itemFont.fontData, itemFont.fontMag) 30 | .withSpacing(1); 31 | 32 | if(needEditingIcons) { 33 | themeBuilder.withStandardLowResCursorIcons(); 34 | } 35 | 36 | if(useUnicode) { 37 | themeBuilder.enableTcUnicode(); 38 | } 39 | 40 | themeBuilder.defaultTitleProperties() 41 | .withNativeFont(titleFont.fontData, titleFont.fontMag) 42 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 43 | .withSpacing(TITLE_SPACING) 44 | .withBorder(MenuBorder(0, 0, TITLE_BORDER_THICKNESS, 0)) 45 | .apply(); 46 | 47 | themeBuilder.defaultActionProperties() 48 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 49 | .apply(); 50 | 51 | themeBuilder.defaultItemProperties() 52 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_VALUE_RIGHT) 53 | .apply(); 54 | 55 | themeBuilder.apply(); 56 | } 57 | 58 | #endif //TCMENU_THEME_MONO_INVERSE 59 | -------------------------------------------------------------------------------- /examples/esp/simpleU8g2/simpleU8g2_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | #include "tcMenuU8g2.h" 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | // variables we declare that you may need to access 25 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 26 | extern U8G2_SH1106_128X64_NONAME_F_SW_I2C gfx; 27 | extern U8g2Drawable gfxDrawable; 28 | extern GraphicsDeviceRenderer renderer; 29 | 30 | // Any externals needed by IO expanders, EEPROMs etc 31 | 32 | 33 | // Global Menu Item exports 34 | extern DateFormattedMenuItem menuExtrasDate; 35 | extern TimeFormattedMenuItem menuExtrasTime; 36 | extern IpAddressMenuItem menuExtrasIp; 37 | extern Rgb32MenuItem menuExtrasRGB; 38 | extern BackMenuItem menuBackExtras; 39 | extern SubMenuItem menuExtras; 40 | extern ActionMenuItem menuSettingsSaveSettings; 41 | extern EditableLargeNumberMenuItem menuSettingsSerialNumber; 42 | extern TextMenuItem menuSettingsUserName; 43 | extern BooleanMenuItem menuSettingsSafetyLock; 44 | extern BackMenuItem menuBackSettings; 45 | extern SubMenuItem menuSettings; 46 | extern ActionMenuItem menuStartToasting; 47 | extern BooleanMenuItem menuFrozen; 48 | extern EnumMenuItem menuType; 49 | extern AnalogMenuItem menuToasterPower; 50 | 51 | // Provide a wrapper to get hold of the root menu item and export setupMenu 52 | inline MenuItem& rootMenuItem() { return menuToasterPower; } 53 | void setupMenu(); 54 | 55 | // Callback functions must always include CALLBACK_FUNCTION after the return type 56 | #define CALLBACK_FUNCTION 57 | 58 | void CALLBACK_FUNCTION onNameChanged(int id); 59 | void CALLBACK_FUNCTION onSaveSettings(int id); 60 | void CALLBACK_FUNCTION onStartToasting(int id); 61 | 62 | #endif // MENU_GENERATED_CODE_H 63 | -------------------------------------------------------------------------------- /examples/mbed/stm32OledEncoder/NTPTimeEvent.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by David Cherry on 25/06/2020. 3 | // 4 | 5 | #include 6 | #include "NTPTimeEvent.h" 7 | 8 | void acquireNtpTimeThreadProc(NTPTimeEvent *ntpTime) { 9 | ntpTime->acquireNtpOnThread(); 10 | } 11 | 12 | NTPTimeEvent::NTPTimeEvent(NetworkInterface *nwInterface, const char *serverName, int port) 13 | : timeServer(serverName), timePort(port), interface(nwInterface), 14 | ntpThread(), _presentValue(0) { 15 | ntpThread.start(callback(acquireNtpTimeThreadProc, this)); 16 | } 17 | 18 | void NTPTimeEvent::acquireNtpOnThread() { 19 | int retriesLeft = 20; 20 | while(--retriesLeft > 0) { 21 | // wait a second before trying to avoid a tight loop. 22 | ThisThread::sleep_for((20 - retriesLeft) * 1000); 23 | 24 | serdebugF2("Starting ntp loop retries = ", retriesLeft); 25 | 26 | SocketAddress serverAddr; 27 | if (interface->gethostbyname(timeServer, &serverAddr) < 0) { 28 | continue; 29 | } 30 | serverAddr.set_port(timePort); 31 | 32 | serdebugF("Found NTP host"); 33 | 34 | int32_t ntpRx[12] = {0}; 35 | char ntpTx[48] = {0}; 36 | ntpTx[0] = 0x1b; 37 | 38 | UDPSocket socket; 39 | socket.open(interface); 40 | socket.set_blocking(true); 41 | socket.set_timeout(10); 42 | 43 | int sendCount = 0; 44 | nsapi_size_or_error_t sendRet; 45 | while((sendRet = socket.sendto(serverAddr, ntpTx, sizeof(ntpTx))) <= 0) { 46 | if(sendRet != NSAPI_ERROR_WOULD_BLOCK || ++sendCount > 20) break; 47 | ThisThread::sleep_for(500); 48 | } 49 | 50 | serdebugF("Sent NTP message"); 51 | 52 | SocketAddress sourceAddr; 53 | sendCount = 0; 54 | while(sendRet > 0 && ++sendCount < 20) { 55 | int n = socket.recvfrom(&sourceAddr, ntpRx, sizeof(ntpRx)); 56 | 57 | if (n > 10) { 58 | uint32_t tmNowRaw = ntpRx[10]; 59 | uint32_t ret = (tmNowRaw & 0xffU) << 24U; 60 | ret |= (tmNowRaw & 0xff00U) << 8U; 61 | ret |= (tmNowRaw & 0xff0000UL) >> 8U; 62 | ret |= (tmNowRaw & 0xff000000UL) >> 24U; 63 | _presentValue = ret - EPOCH_CONVERT_OFFSET; 64 | markTriggeredAndNotify(); 65 | serdebugF2("Time was set to ", (unsigned long) _presentValue); 66 | return; 67 | } 68 | } 69 | // finally close the socket 70 | socket.close(); 71 | } 72 | } 73 | 74 | uint32_t NTPTimeEvent::timeOfNextCheck() { 75 | return secondsToMicros(1); 76 | } 77 | -------------------------------------------------------------------------------- /examples/mbed/stm32OledEncoder/NTPTimeEvent.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef TCMENUEXAMPLE_NTPTIMEEVENT_H 4 | #define TCMENUEXAMPLE_NTPTIMEEVENT_H 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /** 12 | * Provides an easy way to get the time from an NTP server as an event, the exec method is not implemented on this 13 | * so that you can implement it how you see fit. This class works by starting a thread to acquire the time from an 14 | * NTP server, and when the time is obtained, it triggers the event. 15 | */ 16 | class NTPTimeEvent : public BaseEvent { 17 | public: 18 | /** 19 | * Create the event for a given interface, server and port. 20 | * @param interface the interface to use 21 | * @param timeServer the NTP server name 22 | * @param timePort the port to connect on 23 | */ 24 | NTPTimeEvent(NetworkInterface* interface, const char* timeServer, int timePort); 25 | 26 | uint32_t timeOfNextCheck() override; 27 | 28 | private: 29 | const time_t EPOCH_CONVERT_OFFSET = (time_t)2208988800UL; 30 | const char* const timeServer; 31 | const int volatile timePort; 32 | NetworkInterface* const interface; 33 | Thread ntpThread; 34 | 35 | void acquireNtpOnThread(); 36 | friend void acquireNtpTimeThreadProc(NTPTimeEvent *ntpTime); 37 | protected: 38 | volatile time_t _presentValue; 39 | }; 40 | 41 | 42 | #endif //TCMENUEXAMPLE_NTPTIMEEVENT_H 43 | -------------------------------------------------------------------------------- /examples/mbed/stm32OledEncoder/ScreenSaverCustomDrawing.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef TCMENUEXAMPLE_SCREENSAVERCUSTOMDRAWING_H 3 | #define TCMENUEXAMPLE_SCREENSAVERCUSTOMDRAWING_H 4 | 5 | #include "generated/stm32OledEncoder_menu.h" 6 | #include 7 | /** 8 | * Here we implement the custom drawing class so that we can register for drawing and reset events with it. 9 | * When the display times out the reset method is called, where in this case we take over the display. Then 10 | * when the take over of the display starts started() is called, followed by renderLoop() being called frequently 11 | * in a game loop until you give the display back. 12 | */ 13 | class ScreenSaverCustomDrawing : public CustomDrawing { 14 | private: 15 | bool exitDisplayProc = false; 16 | int offsetX = 0, offsetY = 0; 17 | int renderTickCount = 0; 18 | public: 19 | /** 20 | * Called when the display resets after a timeout, IE a period of inactivity. Here we use this to show 21 | * the screensaver 22 | */ 23 | void reset() override { 24 | renderer.takeOverDisplay(); 25 | } 26 | 27 | /** 28 | * Called when take over display starts, reset the display how you want it at this point and prepare any 29 | * variables etc. 30 | * @param currentRenderer the renderer that is being taken over. 31 | */ 32 | void started(BaseMenuRenderer *currentRenderer) override { 33 | exitDisplayProc = false; 34 | offsetX = 16; 35 | offsetY = 16; 36 | 37 | gfx->clearDisplay(); 38 | gfx->setFont(OpenSansRegular8pt); 39 | } 40 | 41 | /** 42 | * Called in a game loop so that you can render the screen if there are changes that need repainting. 43 | * @param currentValue the current value of the rotary encoder 44 | * @param userClick if the user has clicked on the button, one of: RPRESS_NONE, PRESS_PRESSED, RPRESS_HELD 45 | */ 46 | void renderLoop(unsigned int currentValue, RenderPressMode userClick) override { 47 | if(userClick != RPRESS_NONE || exitDisplayProc) { 48 | renderer.giveBackDisplay(); 49 | return; 50 | } 51 | 52 | if((renderTickCount % 100) == 0) { 53 | offsetX = rand() % 64; 54 | offsetY = rand() % 25; 55 | } 56 | 57 | gfx->clearDisplay(); 58 | 59 | gfx->setCursor(offsetX, offsetY + 12); 60 | gfx->print("Mbed demo"); 61 | 62 | gfx->setFont(OpenSansRegular8pt); 63 | gfx->setCursor(5 + offsetX, 20 + offsetY); 64 | char sz[32]; 65 | menuRTCDate.copyValue(sz, sizeof sz); 66 | gfx->print(sz); 67 | 68 | gfx->setCursor(5 + offsetX, 32 + offsetY); 69 | menuRTCTime.copyValue(sz, sizeof sz); 70 | gfx->print(sz); 71 | 72 | gfx->display(); 73 | renderTickCount++; 74 | } 75 | 76 | /** 77 | * Close out the screen saver if presently active. 78 | */ 79 | void removeScreenSaver() { 80 | exitDisplayProc = true; 81 | } 82 | }; 83 | 84 | #endif //TCMENUEXAMPLE_SCREENSAVERCUSTOMDRAWING_H 85 | -------------------------------------------------------------------------------- /examples/mbed/stm32OledEncoder/ThemeMonoInverseBuilder.h: -------------------------------------------------------------------------------- 1 | #ifndef TCMENU_THEME_MONO_INVERSE 2 | #define TCMENU_THEME_MONO_INVERSE 3 | 4 | #include 5 | 6 | color_t defaultItemPaletteMono[] = {1, 0, 1, 1}; 7 | color_t defaultTitlePaletteMono[] = {0, 1, 0, 0}; 8 | 9 | #define TITLE_PADDING 2 10 | #define TITLE_SPACING 2 11 | 12 | /** 13 | * This is one of the stock themes, you can modify it to meet your requirements, and it will not be updated by tcMenu 14 | * Designer unless you delete it. This sets up the fonts, spacing and padding for all items. 15 | * @param gr the graphical renderer 16 | * @param itemFont the font for items 17 | * @param titleFont the font for titles 18 | * @param needEditingIcons if editing icons are needed 19 | */ 20 | void installMonoInverseTitleTheme(GraphicsDeviceRenderer& gr, const MenuFontDef& itemFont, const MenuFontDef& titleFont, 21 | bool needEditingIcons, BaseGraphicalRenderer::TitleMode titleMode, bool useUnicode) { 22 | 23 | // See https://tcmenu.github.io/documentation/arduino-libraries/tc-menu/themes/rendering-with-themes-icons-grids/ 24 | TcThemeBuilder themeBuilder(gr); 25 | themeBuilder.withSelectedColors(0, 2) 26 | .dimensionsFromRenderer() 27 | .withItemPadding(MenuPadding(1)) 28 | .withRenderingSettings(titleMode, false) 29 | .withPalette(defaultItemPaletteMono) 30 | .withNativeFont(itemFont.fontData, itemFont.fontMag) 31 | .withSpacing(1); 32 | 33 | if(needEditingIcons) { 34 | themeBuilder.withStandardLowResCursorIcons(); 35 | } 36 | 37 | if(useUnicode) { 38 | themeBuilder.enableTcUnicode(); 39 | } 40 | 41 | themeBuilder.defaultTitleProperties() 42 | .withNativeFont(titleFont.fontData, titleFont.fontMag) 43 | .withPalette(defaultTitlePaletteMono) 44 | .withPadding(MenuPadding(TITLE_PADDING)) 45 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 46 | .withSpacing(TITLE_SPACING) 47 | .apply(); 48 | 49 | themeBuilder.defaultActionProperties() 50 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_WITH_VALUE) 51 | .apply(); 52 | 53 | themeBuilder.defaultItemProperties() 54 | .withJustification(tcgfx::GridPosition::JUSTIFY_TITLE_LEFT_VALUE_RIGHT) 55 | .apply(); 56 | 57 | themeBuilder.apply(); 58 | } 59 | 60 | #endif //TCMENU_THEME_MONO_INVERSE 61 | -------------------------------------------------------------------------------- /examples/mbed/stm32OledEncoder/generated/MBedEthernetTransport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * Ethernet remote capability plugin. This file is a plugin file and should not be directly edited, 8 | * it will be replaced each time the project is built. If you want to edit this file in place, 9 | * make sure to rename it first. 10 | */ 11 | 12 | #ifndef TCMENU_MBEDETHERNETTRANSPORT_H 13 | #define TCMENU_MBEDETHERNETTRANSPORT_H 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | namespace tcremote { 25 | 26 | /** 27 | * An implementation of TagValueTransport that is able to read and write via a buffer to sockets. 28 | */ 29 | class MBedEthernetTransport : public BaseBufferedRemoteTransport { 30 | private: 31 | InternetSocket* socket; 32 | bool isOpen; 33 | public: 34 | MBedEthernetTransport() : BaseBufferedRemoteTransport(BUFFER_MESSAGES_TILL_FULL, 96, 250) { 35 | this->socket = nullptr; 36 | isOpen = false; 37 | } 38 | 39 | ~MBedEthernetTransport() override; 40 | 41 | void setSocket(InternetSocket* sock) { 42 | close(); 43 | 44 | socket = sock; 45 | socket->set_blocking(false); 46 | isOpen = true; 47 | } 48 | 49 | int fillReadBuffer(uint8_t* data, int maxSize) override; 50 | void flush() override; 51 | bool available() override; 52 | bool connected() override { return socket != nullptr && isOpen; } 53 | void close() override; 54 | 55 | }; 56 | 57 | class MbedEthernetInitialiser : public DeviceInitialisation { 58 | public: 59 | enum MbedInitState { TRY_CONNECT, TRY_BIND, FULLY_CONNECTED }; 60 | private: 61 | NetworkInterface* interface; 62 | TCPSocket server; 63 | int port; 64 | MbedInitState initState; 65 | public: 66 | explicit MbedEthernetInitialiser(int port, NetworkInterface* interface = nullptr); 67 | bool attemptInitialisation() override; 68 | bool attemptNewConnection(BaseRemoteServerConnection *remoteConnection) override; 69 | NetworkInterface* getInterface() const { return interface; } 70 | }; 71 | 72 | } 73 | 74 | #ifndef TC_MANUAL_NAMESPACING 75 | using namespace tcremote; 76 | #endif // TC_MANUAL_NAMESPACING 77 | 78 | #endif //TCMENU_MBEDETHERNETTRANSPORT_H 79 | -------------------------------------------------------------------------------- /examples/mbed/stm32OledEncoder/generated/stm32OledEncoder_menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | The code in this file uses open source libraries provided by thecoderscorner 3 | 4 | DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER 5 | INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE. 6 | 7 | All the variables you may need access to are marked extern in this file for easy 8 | use elsewhere. 9 | */ 10 | 11 | #ifndef MENU_GENERATED_CODE_H 12 | #define MENU_GENERATED_CODE_H 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include "Adafruit_SSD1306.h" 19 | #include "tcMenuAdaFruitGfxMono.h" 20 | #include "MBedEthernetTransport.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | // variables we declare that you may need to access 32 | extern const PROGMEM ConnectorLocalInfo applicationInfo; 33 | extern TcMenuRemoteServer remoteServer; 34 | extern SPI spi; 35 | extern AdafruitSSD1306Spi* gfx; 36 | extern AdafruitDrawable gfxDrawable; 37 | extern GraphicsDeviceRenderer renderer; 38 | extern MbedEthernetInitialiser mbedEthInitialisation; 39 | extern const UnicodeFont OpenSansRegular7pt[]; 40 | 41 | // Any externals needed by IO expanders, EEPROMs etc 42 | 43 | 44 | // Global Menu Item exports 45 | extern TextMenuItem menuEdit; 46 | extern AnalogMenuItem menuCommits; 47 | extern EepromAuthenticationInfoMenuItem menuAuthenticator; 48 | extern RemoteMenuItem menuIoTMonitor; 49 | extern IpAddressMenuItem menuIP; 50 | extern BackMenuItem menuBackConnectivity; 51 | extern SubMenuItem menuConnectivity; 52 | extern ActionMenuItem menuSaveAll; 53 | extern FloatMenuItem menuAvgTemp; 54 | extern ListRuntimeMenuItem menuCountingList; 55 | extern ScrollChoiceMenuItem menuChoices; 56 | extern BackMenuItem menuBackOther; 57 | extern SubMenuItem menuOther; 58 | extern Rgb32MenuItem menuRGB; 59 | extern EditableLargeNumberMenuItem menuFrequency; 60 | extern BooleanMenuItem menuPower; 61 | extern EnumMenuItem menuFoods; 62 | extern AnalogMenuItem menuTenths; 63 | extern BackMenuItem menuBackEditing; 64 | extern SubMenuItem menuEditing; 65 | extern TimeFormattedMenuItem menuRTCTime; 66 | extern DateFormattedMenuItem menuRTCDate; 67 | 68 | // Provide a wrapper to get hold of the root menu item and export setupMenu 69 | inline MenuItem& rootMenuItem() { return menuRTCDate; } 70 | void setupMenu(); 71 | 72 | // Callback functions must always include CALLBACK_FUNCTION after the return type 73 | #define CALLBACK_FUNCTION 74 | 75 | int fnCountingListRtCall(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize); 76 | void CALLBACK_FUNCTION onFoodChange(int id); 77 | void CALLBACK_FUNCTION onFrequencyChanged(int id); 78 | void CALLBACK_FUNCTION onSaveAll(int id); 79 | void CALLBACK_FUNCTION onTenthsChaned(int id); 80 | 81 | #endif // MENU_GENERATED_CODE_H 82 | -------------------------------------------------------------------------------- /examples/mbed/stm32f429FrameBuffer/BspUserSettings.h: -------------------------------------------------------------------------------- 1 | #ifndef TCMENU_BSP_INCLUDES 2 | #define TCMENU_BSP_INCLUDES 3 | 4 | // 5 | // In this file you provide all the includes needed for your BSP driver. It may even be that you need to provide 6 | // mappings between any incompatible functions and the ones you have available. In most cases this should be minimal. 7 | // 8 | 9 | // These are the includes needed to access the display and touch BSP functions 10 | // This path works for platformio, change as needed for your arrangements. 11 | 12 | #include "Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_ts.h" 13 | #include "Drivers/BSP/STM32F429I-Discovery/stm32f429i_discovery_lcd.h" 14 | 15 | // define as true if your BSP libraries have a touch screen interface that supports the methods shown below. 16 | #define TC_BSP_TOUCH_DEVICE_PRESENT true 17 | 18 | // Here's the functions we expect to be present, if you don't have these in your setup, you will need to provide them. 19 | 20 | // Touch screen 21 | 22 | // LCD 23 | // structure TS_StateTypeDef must be defined 24 | // BSP_TS_Init(xSize, ySize) 25 | // BSP_TS_GetState(TS_StateTypeDef*) 26 | 27 | // structure sFONT must be defined 28 | // BSP_LCD_Init() 29 | // BSP_LCD_LayerDefaultInit(layer, address) 30 | // BSP_LCD_DrawBitmap(x, y, data) 31 | // BSP_LCD_DrawPixel(x, y, color) 32 | // BSP_LCD_FillRect(x, y, w, h) 33 | // BSP_LCD_DrawRect(x, y, w, h) 34 | // BSP_LCD_FillCircle(x, y, r) 35 | // BSP_LCD_DrawCircle(x, y, r) 36 | // BSP_LCD_DrawLine(x, y, x1, y1) 37 | // BSP_LCD_FillTriangle(x, y, x1, y1, x2, y2) 38 | // BSP_LCD_SetFont(sFONT*) 39 | // BSP_LCD_SetTextColor(uint32_t) 40 | // BSP_LCD_SetBackColor(uint32_t) 41 | // BSP_LCD_DisplayStringAt(x, y, text, justification) 42 | 43 | #endif -------------------------------------------------------------------------------- /examples/mbed/stm32f429FrameBuffer/dashboardConfig.h: -------------------------------------------------------------------------------- 1 | // A few references from the dashboard source exported for the main file. 2 | 3 | #ifndef TCEXAMPLE_DASHBOARDCONFIG_H 4 | #define TCEXAMPLE_DASHBOARDCONFIG_H 5 | 6 | #include "stm32f429FrameBuffer_menu.h" 7 | #include "extras/DrawableDashboard.h" 8 | 9 | void setupDashboard(); 10 | extern TitleWidget connectedWidget; 11 | extern DrawableDashboard* mainDashboard; 12 | 13 | #endif //TCEXAMPLE_DASHBOARDCONFIG_H 14 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For tcMenu 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | MenuManager KEYWORD1 9 | AnalogMenuItem KEYWORD1 10 | EnumMenuItem KEYWORD1 11 | BooleanMenuItem KEYWORD1 12 | TextMenuItem KEYWORD1 13 | SubMenuItem KEYWORD1 14 | BackMenuItem KEYWORD1 15 | RemoteConnector KEYWORD1 16 | ConnectorListener KEYWORD1 17 | BaseDialog KEYWORD1 18 | TitleWidget KEYWORD1 19 | LargeFixedNumber KEYWORD1 20 | EditableLargeNumberMenuItem KEYWORD1 21 | ListRuntimeMenuItem KEYWORD1 22 | IpAddressMenuItem KEYWORD1 23 | TimeStorage KEYWORD1 24 | TimeFormattedMenuItem KEYWORD1 25 | 26 | ####################################### 27 | # Methods and Functions (KEYWORD2) 28 | ####################################### 29 | getBoolean KEYWORD2 30 | setBoolean KEYWORD2 31 | getCurrentValue KEYWORD2 32 | setCurrentValue KEYWORD2 33 | getTextValue KEYWORD2 34 | setTextValue KEYWORD2 35 | load KEYWORD2 36 | save KEYWORD2 37 | getRoot KEYWORD2 38 | isChanged KEYWORD2 39 | setChanged KEYWORD2 40 | isSendRemoteNeeded KEYWORD2 41 | setSendRemoteNeeded KEYWORD2 42 | isActive KEYWORD2 43 | setActive KEYWORD2 44 | setButtons KEYWORD2 45 | show KEYWORD2 46 | setUserData KEYWORD2 47 | copyIntoBuffer KEYWORD2 48 | hide KEYWORD2 49 | isInUse KEYWORD2 50 | getWidth KEYWORD2 51 | getHeight KEYWORD2 52 | getMaxValue KEYWORD2 53 | getNext KEYWORD2 54 | setNext KEYWORD2 55 | initialise KEYWORD2 56 | getDialog KEYWORD2 57 | getInstance KEYWORD2 58 | getBuffer KEYWORD2 59 | getBufferSize KEYWORD2 60 | getRendererType KEYWORD2 61 | setResetIntervalTimeSeconds KEYWORD2 62 | setResetCallback KEYWORD2 63 | setFirstWidget KEYWORD2 64 | takeOverDisplay KEYWORD2 65 | giveBackDisplay KEYWORD2 66 | resetToDefault KEYWORD2 67 | decimalPointIndex KEYWORD2 68 | setPrecision KEYWORD2 69 | setFromFloat KEYWORD2 70 | fromBcdPacked KEYWORD2 71 | convertToBcdPacked KEYWORD2 72 | getDigit KEYWORD2 73 | setDigit KEYWORD2 74 | getAsFloat KEYWORD2 75 | isNegative KEYWORD2 76 | setNegative KEYWORD2 77 | getWhole KEYWORD2 78 | getFraction KEYWORD2 79 | getLargeNumber KEYWORD2 80 | fastltoa KEYWORD2 81 | fastltoa_mv KEYWORD2 82 | ltoaClrBuff KEYWORD2 83 | dpToDivisor KEYWORD2 84 | safeProgCpy KEYWORD2 85 | 86 | ####################################### 87 | # Instances (KEYWORD2) 88 | ####################################### 89 | 90 | menuMgr KEYWORD2 91 | 92 | ####################################### 93 | # Constants (LITERAL1) 94 | ####################################### 95 | 96 | DLG_VISIBLE LITERAL1 97 | DLG_HIDDEN LITERAL1 98 | DLG_ACTION LITERAL1 99 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tcMenu", 3 | "keywords": "menu, IoT, display, encoder, ethernet", 4 | "description": "Menu library for Arduino with IoT capabilities supporting full multi level navigation. Complete with a designer UI and CLI that can round trip. It has plugins for Adafruit_GFX, U8G2, TFT_eSPI and LiquidCrystalIO. Input is supported from Touch, Rotary Encoder, Digital / Analog joysticks, DfRobot, Keypad and more. Any menu can be remotely using embedCONTROL UI / API over Ethernet2, UIP, STM32 Ethernet and Serial / Bluetooth. Even works with no local display for remote control only.", 5 | "repository": 6 | { 7 | "type": "git", 8 | "url": "https://github.com/TcMenu/tcMenuLib" 9 | }, 10 | "authors": 11 | [ 12 | { 13 | "name": "tcmenu", 14 | "url": "https://tcmenu.github.io/documentation/", 15 | "maintainer": true 16 | } 17 | ], 18 | "dependencies": 19 | [ 20 | { 21 | "name": "IoAbstraction", 22 | "authors": "tcmenu" 23 | }, 24 | { 25 | "name": "tcUnicodeHelper", 26 | "authors": "tcmenu" 27 | } 28 | ], 29 | "version": "4.4.0", 30 | "license": "Apache-2.0", 31 | "frameworks": "arduino, mbed", 32 | "platforms": "*" 33 | } 34 | 35 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | # This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | # 5 | 6 | name=tcMenu 7 | version=4.4.0 8 | maintainer=www.thecoderscorner.com 9 | author=davetcc 10 | category=Other 11 | url=https://github.com/TcMenu/tcMenuLib 12 | sentence=Menu library for Arduino with IoT capabilities that supports many input and display devices with a designer UI, code generator, CLI, and strong remote control capability. 13 | paragraph=Menu library for Arduino with IoT capabilities supporting full multi level navigation. Complete with a designer UI and CLI that can round trip. It has plugins for Adafruit_GFX, U8G2, TFT_eSPI and LiquidCrystalIO. Input is supported from Touch, Rotary Encoder, Digital / Analog joysticks, DfRobot, Keypad and more. Any menu can be remotely using embedCONTROL UI / API over Ethernet2, UIP, STM32 Ethernet and Serial / Bluetooth. Even works with no local display for remote control only. 14 | depends=IoAbstraction,tcUnicodeHelper 15 | architectures=* -------------------------------------------------------------------------------- /merge-bin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # Adds PlatformIO post-processing to merge all the ESP flash images into a single image. 4 | 5 | import os 6 | 7 | Import("env", "projenv") 8 | 9 | board_config = env.BoardConfig() 10 | firmware_bin = "${BUILD_DIR}/${PROGNAME}.bin" 11 | merged_bin = os.environ.get("MERGED_BIN_PATH", "${BUILD_DIR}/${PROGNAME}-merged.bin") 12 | 13 | 14 | def merge_bin_action(source, target, env): 15 | flash_images = [ 16 | *env.Flatten(env.get("FLASH_EXTRA_IMAGES", [])), 17 | "$ESP32_APP_OFFSET", 18 | source[0].get_abspath(), 19 | ] 20 | merge_cmd = " ".join( 21 | [ 22 | '"$PYTHONEXE"', 23 | '"$OBJCOPY"', 24 | "--chip", 25 | board_config.get("build.mcu", "esp32"), 26 | "merge_bin", 27 | "-o", 28 | merged_bin, 29 | "--flash_mode", 30 | board_config.get("build.flash_mode", "dio"), 31 | "--flash_freq", 32 | "${__get_board_f_flash(__env__)}", 33 | "--flash_size", 34 | board_config.get("upload.flash_size", "4MB"), 35 | "--fill-flash-size", 36 | board_config.get("upload.flash_size", "4MB"), 37 | *flash_images, 38 | ] 39 | ) 40 | env.Execute(merge_cmd) 41 | 42 | 43 | env.AddPostAction("buildprog", merge_bin_action) 44 | -------------------------------------------------------------------------------- /platformio-test.ini: -------------------------------------------------------------------------------- 1 | [env:esp32dev] 2 | platform = espressif32 3 | framework = arduino 4 | board = esp32dev 5 | extra_scripts = post:merge-bin.py 6 | test_build_src = true 7 | 8 | lib_deps = 9 | IoAbstraction 10 | TaskManagerIO 11 | tcUnicodeHelper 12 | 13 | test_testing_command = 14 | qemu-system-xtensa 15 | -nographic 16 | -machine 17 | esp32 18 | -drive 19 | file=${platformio.build_dir}/${this.__env__}/firmware-merged.bin,if=mtd,format=raw 20 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | [env] 2 | framework = arduino 3 | 4 | lib_deps = 5 | SPI 6 | tcmenu/IoAbstraction@^4.0.2 7 | tcmenu/tcUnicodeHelper@^1.0.0 8 | tcmenu/LiquidCrystalIO@^1.4.3 9 | bodmer/TFT_eSPI@^2.5.43 10 | adafruit/Adafruit GFX Library@^1.11.9 11 | adafruit/Adafruit BusIO@^1.16.1 12 | adafruit/Adafruit FT6206 Library@^1.1.0 13 | 14 | [env:megaatmega2560] 15 | platform = atmelavr 16 | board = megaatmega2560 17 | 18 | lib_deps = 19 | ${env.lib_deps} 20 | adafruit/Adafruit PCD8544 Nokia 5110 LCD library@^2.0.3 21 | uipethernet/UIPEthernet@^2.0.12 22 | adafruit/Adafruit ST7735 and ST7789 Library@^1.10.4 23 | greiman/SSD1306Ascii@^1.3.5 24 | 25 | [env:esp32dev] 26 | platform = espressif32 27 | board = esp32dev 28 | 29 | lib_deps = 30 | ${env.lib_deps} 31 | FS 32 | SPIFFS 33 | olikraus/U8g2@^2.35.17 34 | adafruit/Adafruit ILI9341@^1.6.1 35 | adafruit/Adafruit ST7735 and ST7789 Library@^1.10.4 36 | 37 | [env:esp01_1m] 38 | platform = espressif8266 39 | board = esp01_1m 40 | 41 | lib_deps = 42 | ${env.lib_deps} 43 | ESP8266WiFi 44 | olikraus/U8g2@^2.35.17 45 | -------------------------------------------------------------------------------- /src/EepromItemStorage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | #ifndef _EEPROM_ITEM_STORAGE_H_ 7 | #define _EEPROM_ITEM_STORAGE_H_ 8 | 9 | /** 10 | * @file EepromItemStorage.h 11 | * @brief this file contains a series of helper methods for loading and saving menu item to eeprom. 12 | */ 13 | 14 | #include "EepromAbstraction.h" 15 | 16 | class MenuItem; 17 | 18 | /** 19 | * Save a menu structure to the EEPROM storage device passed in, such that all editable menu items with valid EEPROM 20 | * address (IE not -1). The eeprom structure will be saved after the first two bytes which are the magic key. This key 21 | * is so that we know the structure is valid when loading back 22 | * @param eeprom the EEPROM device to save to 23 | * @param magicKey the magic key to store, will be validated on loading back. 24 | */ 25 | void saveMenuStructure(EepromAbstraction* eeprom, uint16_t magicKey = 0xfade); 26 | 27 | /** 28 | * Loads a menu structure back from EEPROM storage into the menu items, but only if the magic key in the first two 29 | * bytes matches exactly. 30 | * @param eeprom the EEPROM storage to load from 31 | * @param magicKey the key to check against, only loaded if the key matches. 32 | */ 33 | bool loadMenuStructure(EepromAbstraction* eeprom, uint16_t magicKey = 0xfade); 34 | 35 | /** 36 | * Loads a single menu item back from storage, this can be used to selectively load items from the EEPROM. Mainly for 37 | * cases when you want to selectively load a few items from ROM. 38 | * @param eeprom the EEPROM storage to load from 39 | * @param theItem the menu item to try and load if the magic key matches 40 | * @param magicKey the key to check against, only loaded if the key matches. 41 | */ 42 | bool loadMenuItem(EepromAbstraction* eeprom, MenuItem* theItem, uint16_t magicKey = 0xfade); 43 | 44 | /** 45 | * Saves a single item back to the EEPROM, it will NOT write the magic key, it is assumed that a full save has already 46 | * been done at some point in the past. 47 | * @param eeprom the EEPROM storage to save to 48 | * @param theItem the item to save 49 | */ 50 | void saveMenuItem(EepromAbstraction* eeprom, MenuItem* theItem); 51 | 52 | /** 53 | * This will trigger callbacks in a controlled manner, for only items that would be loaded from EEPROM, and only if 54 | * the item is marked as changed. This is much safer than the previous option, which was to run all callbacks as 55 | * part of the load call, when most of the system may not have started yet. 56 | */ 57 | void triggerAllChangedCallbacks(); 58 | 59 | /** 60 | * This enables the sized EEPROM support. When this is on, new items that are beyond the last saved EEPROM position 61 | * will not attempt to be loaded. This allows new items to initialise properly as long as they are at the end. 62 | */ 63 | void setSizeBasedEEPROMStorageEnabled(bool ena); 64 | 65 | #endif //_EEPROM_ITEM_STORAGE_H_ 66 | -------------------------------------------------------------------------------- /src/GfxMenuConfig.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef TCMENU_LEGACY_GFXMENUCONFIG_H 3 | #define TCMENU_LEGACY_GFXMENUCONFIG_H 4 | 5 | #include "graphics/GfxMenuConfig.h" 6 | 7 | // now include the namespace to ensure everything sees it exactly as before. 8 | using namespace tcgfx; 9 | 10 | #endif //TCMENU_LEGACY_GFXMENUCONFIG_H 11 | -------------------------------------------------------------------------------- /src/MenuHistoryNavigator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | #include 7 | #include "MenuHistoryNavigator.h" 8 | #include "MenuIterator.h" 9 | #include "RuntimeMenuItem.h" 10 | #include "tcMenu.h" 11 | 12 | void tcnav::MenuNavigationStore::setRootItem(MenuItem *item) { 13 | root = item; 14 | currentRoot = root; 15 | currentSub = &MenuManager::ROOT; 16 | navIdx = 0; 17 | currentIsCustom = false; 18 | triggerNavigationListener(false); 19 | } 20 | 21 | void tcnav::MenuNavigationStore::navigateTo(MenuItem *activeItem, MenuItem *newRoot, bool custom) { 22 | // we only stack when 23 | if(navIdx < NAV_ITEM_ARRAY_SIZE && !currentIsCustom) { 24 | navItems[navIdx] = currentRoot; 25 | activeItems[navIdx] = activeItem ? activeItem : currentRoot; 26 | serlogF4(SER_TCMENU_INFO, "NavigateTo pushed ", navIdx, currentRoot->getId(), activeItems[navIdx]->getId()); 27 | currentIsCustom = custom; 28 | navIdx++; 29 | } 30 | else { 31 | serlogF(SER_ERROR, "Nav exceeded"); 32 | } 33 | currentRoot = newRoot; 34 | currentSub = getSubMenuFor(newRoot); 35 | triggerNavigationListener(false); 36 | } 37 | 38 | MenuItem *tcnav::MenuNavigationStore::popNavigationGetActive() { 39 | currentIsCustom = false; 40 | if(navIdx == 0) { 41 | serlogF(SER_TCMENU_INFO, "Nav pop root"); 42 | currentSub = &MenuManager::ROOT; 43 | currentRoot = root; 44 | triggerNavigationListener(false); 45 | return root; 46 | } else { 47 | navIdx--; 48 | currentRoot = navItems[navIdx]; 49 | currentSub = getSubMenuFor(currentRoot); 50 | serlogF3(SER_TCMENU_INFO, "Nav pop ", navIdx, currentRoot->getId()); 51 | triggerNavigationListener(false); 52 | return activeItems[navIdx]; 53 | } 54 | } 55 | 56 | bool tcnav::MenuNavigationStore::isShowingRoot() { 57 | return currentRoot == root; 58 | } 59 | 60 | void tcnav::MenuNavigationStore::resetStack() { 61 | setRootItem(root); 62 | triggerNavigationListener(true); 63 | } 64 | 65 | void tcnav::MenuNavigationStore::addNavigationListener(tcnav::NavigationListener *newListener) { 66 | if(this->navigationLister == nullptr) { 67 | this->navigationLister = newListener; 68 | } else { 69 | newListener->setNext(navigationLister); 70 | navigationLister = newListener; 71 | } 72 | newListener->navigationHasChanged(currentRoot, false); 73 | } 74 | 75 | void tcnav::MenuNavigationStore::triggerNavigationListener(bool completeReset) { 76 | auto current = navigationLister; 77 | while(current) { 78 | current->navigationHasChanged(currentRoot, completeReset); 79 | current = navigationLister->getNext(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/SecuredMenuPopup.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | #include "SecuredMenuPopup.h" 7 | #include "tcMenu.h" 8 | #include "BaseDialog.h" 9 | #include "lang/language_select.h" 10 | #include "MenuItems.h" 11 | 12 | const char pgmProceedText[] PROGMEM = TXT_SECURE_MENU_PROCEED; 13 | const char pgmCancelText[] PROGMEM = TXT_SECURE_MENU_CANCEL; 14 | const char pgmHeaderNotAuth[] PROGMEM = TXT_SECURE_PIN_WRONG; 15 | 16 | RENDERING_CALLBACK_NAME_INVOKE(fnpopupPasswordRtCall, textItemRenderFn, "Password", -1, NULL) 17 | RENDERING_CALLBACK_NAME_INVOKE(fnpopupSubmenuSecured, backSubItemRenderFn, "Enter PIN", -1, NULL) 18 | 19 | SecuredMenuPopup::SecuredMenuPopup(AuthenticationManager * authentication) 20 | : backMenuItem(fnpopupSubmenuSecured, &pinEntryItem), 21 | pinEntryItem(fnpopupPasswordRtCall, nextRandomId(), MAX_PIN_LENGTH, &actionProceedItem), 22 | actionProceedItem(secPopupActionRenderFn, 1, &actionCancelItem), 23 | actionCancelItem(secPopupActionRenderFn, 0, NULL) { 24 | 25 | this->authentication = authentication; 26 | } 27 | 28 | MenuItem* SecuredMenuPopup::start(SubMenuItem* securedMenu) { 29 | actionProceedItem.setSecuredItem(securedMenu); 30 | actionCancelItem.setSecuredItem(NULL); 31 | 32 | pinEntryItem.setTextValue("", true); 33 | pinEntryItem.setPasswordField(true); 34 | return &backMenuItem; 35 | } 36 | 37 | int secPopupActionRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize) { 38 | if (item->getMenuType() != MENUTYPE_ACTIVATE_SUBMENU) return false; 39 | ActivateSubMenuItem* act = reinterpret_cast(item); 40 | 41 | switch (mode) { 42 | case RENDERFN_VALUE: 43 | buffer[0] = 0; 44 | return true; 45 | case RENDERFN_NAME: 46 | strncpy_P(buffer, (row != 0) ? pgmProceedText : pgmCancelText, bufferSize); 47 | return true; 48 | case RENDERFN_EEPROM_POS: 49 | return -1; 50 | case RENDERFN_INVOKE: 51 | if(act->getSecuredItem() != NULL) { 52 | if (menuMgr.secureMenuInstance()->doesPinMatch()) { 53 | menuMgr.navigateToMenu(act->getSecuredItem()->getChild()); 54 | } 55 | else { 56 | menuMgr.resetMenu(false); 57 | BaseDialog* dlg = menuMgr.getRenderer()->getDialog(); 58 | dlg->setButtons(BTNTYPE_NONE, BTNTYPE_CLOSE); 59 | char sz[15]; 60 | act->getSecuredItem()->copyNameToBuffer(sz, sizeof(sz)); 61 | dlg->show(pgmHeaderNotAuth, false); 62 | dlg->copyIntoBuffer(sz); 63 | } 64 | } 65 | else { 66 | menuMgr.resetMenu(false); 67 | } 68 | return true; 69 | default: 70 | return false; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/SecuredMenuPopup.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | #ifndef _SECURED_MENU_POPUP_H_ 7 | #define _SECURED_MENU_POPUP_H_ 8 | 9 | /** 10 | * @file SecuredMenuPopup.h 11 | * @brief contains the code to show a security screen for secured menus. 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | int secPopupActionRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize); 18 | 19 | class ActivateSubMenuItem : public RuntimeMenuItem { 20 | private: 21 | SubMenuItem* securedItem; 22 | public: 23 | ActivateSubMenuItem(RuntimeRenderingFn customRenderFn, int activeStatus, MenuItem* next = NULL) 24 | : RuntimeMenuItem(MENUTYPE_ACTIVATE_SUBMENU, nextRandomId(), customRenderFn, activeStatus, 1, next) { 25 | } 26 | 27 | void setSecuredItem(SubMenuItem *secured) { 28 | securedItem = secured; 29 | } 30 | 31 | SubMenuItem* getSecuredItem() { return securedItem; } 32 | }; 33 | 34 | /** 35 | * Secured menu popup is a detatched menu that is never presented remotely, it allows 36 | * for secured menus that can only be edited on the device after entering a pin. 37 | * It has a pin entry area, the ability to proceed (if the pin is correct) and the 38 | * ability to go back to the main menu. 39 | */ 40 | class SecuredMenuPopup { 41 | private: 42 | BackMenuItem backMenuItem; 43 | TextMenuItem pinEntryItem; 44 | ActivateSubMenuItem actionProceedItem; 45 | ActivateSubMenuItem actionCancelItem; 46 | AuthenticationManager* authentication; 47 | public: 48 | SecuredMenuPopup(AuthenticationManager *authentication); 49 | 50 | MenuItem* getItemToActivate() { return &pinEntryItem; } 51 | 52 | MenuItem* start(SubMenuItem* securedMenu); 53 | 54 | MenuItem* getRootItem() { 55 | return &backMenuItem; 56 | } 57 | 58 | bool doesPinMatch() { 59 | return authentication->doesPinMatch(pinEntryItem.getTextValue()); 60 | } 61 | }; 62 | 63 | #endif // _SECURED_MENU_POPUP_H_ 64 | -------------------------------------------------------------------------------- /src/extras/MenuItemDelegate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | #include "MenuItemDelegate.h" 7 | 8 | using namespace tccore; 9 | 10 | bool MenuItemDelegate::onEachItem(MenuItemDelegate::ItemDelegateFn itemDelegateFn, AnyOrAll modeAny) { 11 | bool combinedReturn = true; 12 | for(int i=0; ibool { 23 | item->setReadOnly(flg); 24 | return false; 25 | }, ALL); 26 | } 27 | 28 | void MenuItemDelegate::setLocalOnly(bool localOnly) { 29 | internalFlag = localOnly; 30 | onEachItem([](MenuItem* item, bool flg)->bool { 31 | item->setLocalOnly(flg); 32 | return true; 33 | }, ALL); 34 | } 35 | 36 | void MenuItemDelegate::setVisible(bool visible) { 37 | internalFlag = visible; 38 | onEachItem([](MenuItem* item, bool flg)->bool { 39 | item->setVisible(flg); 40 | return true; 41 | }, ALL); 42 | } 43 | 44 | void MenuItemDelegate::setChangedAndRemoteSend() { 45 | onEachItem([](MenuItem* item, bool flg)->bool { 46 | item->setChanged(true); 47 | item->setSendRemoteNeededAll(); 48 | return true; 49 | }, ALL); 50 | } 51 | 52 | void MenuItemDelegate::setChangedOnly() { 53 | onEachItem([](MenuItem* item, bool flg)->bool { 54 | item->setChanged(true); 55 | return true; 56 | }, ALL); 57 | } 58 | 59 | bool MenuItemDelegate::isReadOnly(AnyOrAll anyOrAll) { 60 | return onEachItem([](MenuItem* item, bool flg) { return item->isReadOnly(); }, anyOrAll); 61 | } 62 | 63 | bool MenuItemDelegate::isLocalOnly(AnyOrAll anyOrAll) { 64 | return onEachItem([](MenuItem* item, bool flg) { return item->isLocalOnly(); }, anyOrAll); 65 | } 66 | 67 | bool MenuItemDelegate::isVisible(AnyOrAll anyOrAll) { 68 | return onEachItem([](MenuItem* item, bool flg) { return item->isVisible(); }, anyOrAll); 69 | } 70 | 71 | bool MenuItemDelegate::isChanged(AnyOrAll anyOrAll) { 72 | return onEachItem([](MenuItem* item, bool flg) { return item->isVisible(); }, anyOrAll); 73 | } 74 | 75 | -------------------------------------------------------------------------------- /src/extras/TcOneButtonHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef TCLIBRARYDEV_TCONEBUTTONHANDLER_H 2 | #define TCLIBRARYDEV_TCONEBUTTONHANDLER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * Support for a menu with a single button, it will add a button on the required pin, and listen for changes 10 | * With the following: 11 | * Short press: increment by 1 12 | * Double press (when not editing): back navigation 13 | * Hold down: select 14 | */ 15 | class TcOneButtonHandler : public SwitchListener { 16 | private: 17 | uint32_t lastPress; 18 | int doubleClickThreshold; 19 | pinid_t buttonPin; 20 | public: 21 | TcOneButtonHandler(pinid_t buttonPin, int doubleClickThreshold) 22 | : lastPress(0), buttonPin(buttonPin), doubleClickThreshold(doubleClickThreshold) { 23 | } 24 | 25 | void start() { 26 | switches.addSwitchListener(buttonPin, this, NO_REPEAT, false); 27 | } 28 | 29 | void onPressed(pinid_t pin, bool held) override { 30 | } 31 | 32 | void onReleased(pinid_t pin, bool held) override { 33 | if(held && pin == buttonPin) { 34 | menuMgr.onMenuSelect(false); 35 | lastPress = 0; 36 | } else { 37 | if((millis() - lastPress) < doubleClickThreshold) { 38 | menuMgr.performDirectionMove(true); 39 | lastPress = 0; 40 | } else { 41 | auto enc = switches.getEncoder(); 42 | if(enc->getCurrentReading() == enc->getMaximumValue()) { 43 | enc->setCurrentReading(0); 44 | enc->runCallback(enc->getCurrentReading()); 45 | } else { 46 | enc->increment(1); 47 | } 48 | lastPress = millis(); 49 | } 50 | } 51 | } 52 | }; 53 | 54 | #endif //TCLIBRARYDEV_TCONEBUTTONHANDLER_H 55 | -------------------------------------------------------------------------------- /src/extras/TwoButtonSwitchEncoder.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "TwoButtonSwitchEncoder.h" 3 | 4 | TwoButtonSwitchEncoder::TwoButtonSwitchEncoder(pinid_t up, pinid_t down, EncoderCallbackFn callbackFn) 5 | : RotaryEncoder(callbackFn), upPin(up), downPin(down) { 6 | switches.addSwitchListener(up, this, NO_REPEAT); 7 | switches.addSwitchListener(down, this, NO_REPEAT); 8 | } 9 | 10 | void TwoButtonSwitchEncoder::onReleased(pinid_t pin, bool held) { 11 | auto invert = intent == SCROLL_THROUGH_ITEMS; 12 | if(pin == upPin) { 13 | if(held) { 14 | menuMgr.performDirectionMove(true); 15 | } else { 16 | int8_t dir = invert ? -stepSize : stepSize; 17 | increment(dir); 18 | } 19 | } else if(pin == downPin) { 20 | if(held) { 21 | menuMgr.onMenuSelect(false); 22 | } else { 23 | int8_t dir = invert ? stepSize : -stepSize; 24 | increment(dir); 25 | } 26 | } 27 | } 28 | 29 | void TwoButtonSwitchEncoder::onPressed(pinid_t pin, bool held) { 30 | // ignored for two button case 31 | } 32 | -------------------------------------------------------------------------------- /src/extras/TwoButtonSwitchEncoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | #ifndef TCMENU_TWOBUTTONSWITCHCONTROL_H 7 | #define TCMENU_TWOBUTTONSWITCHCONTROL_H 8 | 9 | /** 10 | * @file TwoButtonSwitchControl.h 11 | * @brief contains a class that can be used to set up basic two button control of a menu 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | /** 18 | * Use this class to control a menu application with only two buttons. The up/down buttons double up as back and 19 | * select when held. This means that repeat operation is not possible, keep integer and choice value ranges small 20 | * so as to avoid needing many presses. 21 | */ 22 | class TwoButtonSwitchEncoder : public RotaryEncoder, public SwitchListener { 23 | private: 24 | pinid_t upPin; 25 | pinid_t downPin; 26 | 27 | public: 28 | /** 29 | * Create a two button switch given an up and down button along with the callback function for the encoder. 30 | * @param up the up button (doubles as back when held) 31 | * @param down the down button (doubles as OK when held) 32 | * @param callbackFn the encoder change callback. 33 | */ 34 | TwoButtonSwitchEncoder(pinid_t up, pinid_t down, EncoderCallbackFn callbackFn); 35 | 36 | void onPressed(pinid_t pin, bool held) override; 37 | 38 | void onReleased(pinid_t pin, bool held) override; 39 | 40 | }; 41 | 42 | #endif //TCMENU_TWOBUTTONSWITCHCONTROL_H 43 | -------------------------------------------------------------------------------- /src/graphics/DeviceDrawable.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "DeviceDrawable.h" 3 | #include "GraphicsDeviceRenderer.h" 4 | #include 5 | 6 | using namespace tcgfx; 7 | 8 | void DeviceDrawable::drawText(const Coord& where, const void* font, int mag, const char* text) { 9 | auto handler = getUnicodeHandler(false); 10 | if(handler) { 11 | handler->setDrawColor(drawColor); 12 | setTcFontAccordingToMag(handler, font, mag); 13 | handler->setCursor((int)where.x, (int)where.y + (handler->getYAdvance() - handler->getBaseline())); 14 | handler->print(text); 15 | } else { 16 | internalDrawText(where, font, mag, text); 17 | } 18 | } 19 | 20 | UnicodeFontHandler *DeviceDrawable::getUnicodeHandler(bool enableIfNeeded) { 21 | if(fontHandler == nullptr && enableIfNeeded) { 22 | fontHandler = createFontHandler(); 23 | } 24 | return fontHandler; // if null, there is no font handler. 25 | } 26 | 27 | UnicodeFontHandler *DeviceDrawable::createFontHandler() { 28 | return fontHandler = new UnicodeFontHandler(new DrawableTextPlotPipeline(this), ENCMODE_UTF8); 29 | } 30 | 31 | Coord DeviceDrawable::textExtents(const void *font, int mag, const char *text, int *baseline) { 32 | auto handler = getUnicodeHandler(false); 33 | if(handler) { 34 | setTcFontAccordingToMag(handler, font, mag); 35 | return handler->textExtents(text, baseline, false); 36 | } else { 37 | return internalTextExtents(font, mag, text, baseline); 38 | } 39 | } 40 | 41 | void tcgfx::setTcFontAccordingToMag(UnicodeFontHandler* handler, const void* font, int mag) { 42 | if(mag == 0) { 43 | handler->setFont((UnicodeFont*) font); 44 | } else { 45 | handler->setFont((GFXfont*) font); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/graphics/DialogRuntimeEditor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | #include 7 | #include "DialogRuntimeEditor.h" 8 | 9 | DialogMultiPartEditor* DialogMultiPartEditor::theInstance; 10 | 11 | void onScrollingChanged(int id) { 12 | DialogMultiPartEditor::theInstance->scrollChanged(); 13 | } 14 | 15 | void DialogMultiPartEditor::startEditing(MenuBasedDialog* dlg, EditableMultiPartMenuItem *item) { 16 | menuMgr.setEditorHintsLocked(true); 17 | dialog = reinterpret_cast(dlg); 18 | menuItemBeingEdited = item; 19 | dlg->setButtons(BTNTYPE_OK, BTNTYPE_CUSTOM0); 20 | dlg->showController(false, this); 21 | menuItemBeingEdited->beginMultiEdit(); 22 | dialogButtonPressed(SECOND_DEFAULT_BUTTON); 23 | } 24 | 25 | void DialogMultiPartEditor::dialogDismissed(ButtonType buttonType) { 26 | menuMgr.setEditorHintsLocked(false); 27 | menuItemBeingEdited->stopMultiEdit(); 28 | menuItemBeingEdited = nullptr; 29 | dialog = nullptr; 30 | } 31 | 32 | bool DialogMultiPartEditor::dialogButtonPressed(int buttonNum) { 33 | if(buttonNum == SECOND_DEFAULT_BUTTON) { 34 | auto range = menuItemBeingEdited->nextPart(); 35 | if(range != 0) { 36 | scrollingInfo.maxValue = range; 37 | scrollingEditor.setCurrentValue(menuItemBeingEdited->getPartValueAsInt()); 38 | scrollChanged(); 39 | return false; 40 | } 41 | } 42 | return true; 43 | } 44 | 45 | void DialogMultiPartEditor::copyCustomButtonText(int buttonNumber, char *buffer, size_t bufferSize) { 46 | if(buttonNumber == 1) { 47 | strcpy(buffer, "Next"); 48 | } 49 | } 50 | 51 | void DialogMultiPartEditor::initialiseAndGetHeader(BaseDialog* dlg, char *buffer, size_t bufferSize) { 52 | dialog->insertMenuItem(&scrollingEditor); 53 | strcpy(buffer, "Edit "); 54 | menuItemBeingEdited->copyNameToBuffer(buffer, strlen(buffer), bufferSize); 55 | } 56 | 57 | void DialogMultiPartEditor::scrollChanged() { 58 | menuItemBeingEdited->valueChanged(scrollingEditor.getCurrentValue()); 59 | char sz[32]; 60 | copyMenuItemValue(menuItemBeingEdited, sz, sizeof sz); 61 | 62 | int srcLoc = 0; 63 | int dstLoc = 0; 64 | while(sz[srcLoc] != 0) { 65 | dialog->getBufferMenuItem()->setCharValue(dstLoc++, sz[srcLoc]); 66 | if(srcLoc == menuItemBeingEdited->getItemPosition() - 1) { 67 | dialog->getBufferMenuItem()->setCharValue(dstLoc++, '|'); 68 | } 69 | srcLoc++; 70 | } 71 | dialog->getBufferMenuItem()->setCharValue(dstLoc, 0); 72 | } 73 | -------------------------------------------------------------------------------- /src/graphics/DialogRuntimeEditor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | #ifndef TCMENU_DIALOGRUNTIMEEDITOR_H 7 | #define TCMENU_DIALOGRUNTIMEEDITOR_H 8 | 9 | #include "../MenuItems.h" 10 | #include "../RuntimeMenuItem.h" 11 | #include "../BaseDialog.h" 12 | 13 | /** 14 | * @file DialogRuntimeEditor.h 15 | * @brief Contains the functionality to handle editing runtime multipart items 16 | */ 17 | 18 | 19 | void onScrollingChanged(int id); 20 | 21 | class DialogMultiPartEditor : BaseDialogController { 22 | private: 23 | MenuBasedDialog *dialog; 24 | EditableMultiPartMenuItem* menuItemBeingEdited; 25 | AnalogMenuInfo scrollingInfo = {"Item Value", nextRandomId(), 0xffff, 1, onScrollingChanged, 0, 1, "" }; 26 | AnalogMenuItem scrollingEditor = AnalogMenuItem(&scrollingInfo, 0, nullptr, INFO_LOCATION_RAM); 27 | 28 | public: 29 | static DialogMultiPartEditor* theInstance; 30 | 31 | DialogMultiPartEditor() { 32 | theInstance = this; 33 | menuItemBeingEdited = nullptr; 34 | dialog = nullptr; 35 | }; 36 | 37 | void startEditing(MenuBasedDialog* dlg, EditableMultiPartMenuItem* item); 38 | 39 | void scrollChanged(); 40 | 41 | void dialogDismissed(ButtonType buttonType) override; 42 | 43 | bool dialogButtonPressed(int buttonNum) override; 44 | 45 | void copyCustomButtonText(int buttonNumber, char *buffer, size_t bufferSize) override; 46 | 47 | void initialiseAndGetHeader(BaseDialog* dialog, char* buffer, size_t bufferSize) override; 48 | }; 49 | 50 | #endif //TCMENU_DIALOGRUNTIMEEDITOR_H 51 | -------------------------------------------------------------------------------- /src/graphics/RuntimeTitleMenuItem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | #include "PlatformDetermination.h" 7 | #include "RuntimeTitleMenuItem.h" 8 | 9 | namespace tcgfx { 10 | 11 | RuntimeTitleMenuItem appTitleMenuItem(0, nullptr); 12 | 13 | int appTitleRenderingFn(RuntimeMenuItem *item, uint8_t, RenderFnMode mode, char *buffer, int bufferSize) { 14 | if (item->getMenuType() != MENUTYPE_TITLE_ITEM) return 0; 15 | auto *pTitleItem = reinterpret_cast(item); 16 | 17 | switch (mode) { 18 | case RENDERFN_INVOKE: 19 | if (pTitleItem->getCallback()) { 20 | auto cb = pTitleItem->getCallback(); 21 | cb(item->getId()); 22 | } 23 | return true; 24 | case RENDERFN_VALUE: { 25 | buffer[0] = '^'; 26 | buffer[1] = 0; 27 | return true; 28 | } 29 | case RENDERFN_NAME: { 30 | safeProgCpy(buffer, pTitleItem->getTitleHeaderPgm(), bufferSize); 31 | return true; 32 | } 33 | default: 34 | return false; 35 | } 36 | } 37 | 38 | }; 39 | -------------------------------------------------------------------------------- /src/lang/language_cs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language_cs.h 3 | * @brief Never include directly; contains the Czech language text for tcMenu text, controlled by TC_LOCALE. 4 | */ 5 | 6 | // 7 | // Dialog support, note: please keep ok, cancel, close and accept in lower case 8 | // 9 | 10 | #define TXT_DIALOG_OK "ok" 11 | #define TXT_DIALOG_CANCEL "storno" 12 | #define TXT_DIALOG_CLOSE "zavřít" 13 | #define TXT_DIALOG_ACCEPT "přijmout" 14 | 15 | // 16 | // Boolean naming options 17 | // 18 | 19 | #define TXT_BOOL_ON_TEXT "ZAP." 20 | #define TXT_BOOL_OFF_TEXT "VYP." 21 | #define TXT_BOOL_YES_TEXT "ANO" 22 | #define TXT_BOOL_NO_TEXT "NE" 23 | #define TXT_BOOL_TRUE_TEXT "TRUE" 24 | #define TXT_BOOL_FALSE_TEXT "FALSE" 25 | 26 | // 27 | // Touch screen text options IOA 28 | // 29 | 30 | #define TXT_TOUCH_CONFIGURE "Konfigurace dotyků" 31 | #define TXT_TOUCH_CONFIGURE_2ND "Dotkněte se zvolených oblastí" 32 | 33 | // 34 | // Remote Connector - pairing 35 | // 36 | 37 | #define TXT_PAIRING_TEXT "Čekání na párování" 38 | 39 | // 40 | // RemoteMenuItem dialog text for remote connections and authentication 41 | // 42 | 43 | #define TXT_CLOSE_CONNECTION "Uzavřít spojení" 44 | #define TXT_AUTH_REMOVE "Vymazat" 45 | #define TXT_AUTH_REMOVE_ALL_KEYS "Vymazat VŠECHNY klíče?" 46 | #define TXT_AUTH_EMPTY_KEY "PrázdnýKlíč" 47 | 48 | // 49 | // Secure menu item popup 50 | // 51 | 52 | #define TXT_SECURE_MENU_PROCEED "Pokračovat" 53 | #define TXT_SECURE_MENU_CANCEL "Storno" 54 | #define TXT_SECURE_PIN_WRONG "Nesprávný pin" 55 | -------------------------------------------------------------------------------- /src/lang/language_cs_ascii.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language_cs_ascii.h 3 | * @brief Never include directly; contains the Czech language text for tcMenu text (ASCII only), controlled by TC_LOCALE. 4 | */ 5 | 6 | // 7 | // Dialog support, note: please keep ok, cancel, close and accept in lower case 8 | // 9 | 10 | #define TXT_DIALOG_OK "ok" 11 | #define TXT_DIALOG_CANCEL "storno" 12 | #define TXT_DIALOG_CLOSE "zavrit" 13 | #define TXT_DIALOG_ACCEPT "prijmout" 14 | 15 | // 16 | // Boolean naming options 17 | // 18 | 19 | #define TXT_BOOL_ON_TEXT "ZAP." 20 | #define TXT_BOOL_OFF_TEXT "VYP." 21 | #define TXT_BOOL_YES_TEXT "ANO" 22 | #define TXT_BOOL_NO_TEXT "NE" 23 | #define TXT_BOOL_TRUE_TEXT "TRUE" 24 | #define TXT_BOOL_FALSE_TEXT "FALSE" 25 | 26 | // 27 | // Touch screen text options IOA 28 | // 29 | 30 | #define TXT_TOUCH_CONFIGURE "Konfigurace dotyku" 31 | #define TXT_TOUCH_CONFIGURE_2ND "Dotknete se zvolenych oblasti" 32 | 33 | // 34 | // Remote Connector - pairing 35 | // 36 | 37 | #define TXT_PAIRING_TEXT "Cekani na parovani" 38 | 39 | // 40 | // RemoteMenuItem dialog text for remote connections and authentication 41 | // 42 | 43 | #define TXT_CLOSE_CONNECTION "Uzavrit spojeni" 44 | #define TXT_AUTH_REMOVE "Vymazat" 45 | #define TXT_AUTH_REMOVE_ALL_KEYS "Vymazat VSECHNY klice?" 46 | #define TXT_AUTH_EMPTY_KEY "PrazdnyKlic" 47 | 48 | // 49 | // Secure menu item popup 50 | // 51 | 52 | #define TXT_SECURE_MENU_PROCEED "Pokracovat" 53 | #define TXT_SECURE_MENU_CANCEL "Storno" 54 | #define TXT_SECURE_PIN_WRONG "Nespravny pin" 55 | -------------------------------------------------------------------------------- /src/lang/language_de.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language_de.h 3 | * @brief Never include directly; contains the German language text for tcMenu text, controlled by TC_LOCALE. 4 | */ 5 | 6 | // 7 | // Dialog support, note: please keep ok, cancel, close and accept in lower case 8 | // 9 | 10 | #define TXT_DIALOG_OK "ok" 11 | #define TXT_DIALOG_CANCEL "abbrechen" 12 | #define TXT_DIALOG_CLOSE "schließen" 13 | #define TXT_DIALOG_ACCEPT "akzeptieren" 14 | 15 | // 16 | // Boolean naming options 17 | // 18 | 19 | #define TXT_BOOL_ON_TEXT "EIN" 20 | #define TXT_BOOL_OFF_TEXT "AUS" 21 | #define TXT_BOOL_YES_TEXT "JA" 22 | #define TXT_BOOL_NO_TEXT "NEIN" 23 | #define TXT_BOOL_TRUE_TEXT "WAHR" 24 | #define TXT_BOOL_FALSE_TEXT "FALSCH" 25 | 26 | // 27 | // Touch screen text options IOA 28 | // 29 | 30 | #define TXT_TOUCH_CONFIGURE "Touch-Konfiguration" 31 | #define TXT_TOUCH_CONFIGURE_2ND "Berühren Sie ausgewählte Bereiche" 32 | 33 | // 34 | // Remote Connector - pairing 35 | // 36 | 37 | #define TXT_PAIRING_TEXT "Pairing warten" 38 | 39 | // 40 | // RemoteMenuItem dialog text for remote connections and authentication 41 | // 42 | 43 | #define TXT_CLOSE_CONNECTION "Verbindung schließen" 44 | #define TXT_AUTH_REMOVE "Entfernen" 45 | #define TXT_AUTH_REMOVE_ALL_KEYS "ALLE Schlüssel entfernen?" 46 | #define TXT_AUTH_EMPTY_KEY "LeererSchlüssel" 47 | 48 | // 49 | // Secure menu item popup 50 | // 51 | 52 | #define TXT_SECURE_MENU_PROCEED "Fortfahren" 53 | #define TXT_SECURE_MENU_CANCEL "Abbrechen" 54 | #define TXT_SECURE_PIN_WRONG "Pin inkorrekt" 55 | -------------------------------------------------------------------------------- /src/lang/language_de_ascii.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language_de_ascii.h 3 | * @brief Never include directly; contains the German language text for tcMenu text (ASCII only), controlled by TC_LOCALE. 4 | */ 5 | 6 | // 7 | // Dialog support, note: please keep ok, cancel, close and accept in lower case 8 | // 9 | 10 | #define TXT_DIALOG_OK "ok" 11 | #define TXT_DIALOG_CANCEL "abbrechen" 12 | #define TXT_DIALOG_CLOSE "schliessen" 13 | #define TXT_DIALOG_ACCEPT "akzeptieren" 14 | 15 | // 16 | // Boolean naming options 17 | // 18 | 19 | #define TXT_BOOL_ON_TEXT "EIN" 20 | #define TXT_BOOL_OFF_TEXT "AUS" 21 | #define TXT_BOOL_YES_TEXT "JA" 22 | #define TXT_BOOL_NO_TEXT "NEIN" 23 | #define TXT_BOOL_TRUE_TEXT "WAHR" 24 | #define TXT_BOOL_FALSE_TEXT "FALSCH" 25 | 26 | // 27 | // Touch screen text options IOA 28 | // 29 | 30 | #define TXT_TOUCH_CONFIGURE "Touch-Konfiguration" 31 | #define TXT_TOUCH_CONFIGURE_2ND "Beruehren Sie ausgewaehlte Bereiche" 32 | 33 | // 34 | // Remote Connector - pairing 35 | // 36 | 37 | #define TXT_PAIRING_TEXT "Pairing warten" 38 | 39 | // 40 | // RemoteMenuItem dialog text for remote connections and authentication 41 | // 42 | 43 | #define TXT_CLOSE_CONNECTION "Verbindung schliessen" 44 | #define TXT_AUTH_REMOVE "Entfernen" 45 | #define TXT_AUTH_REMOVE_ALL_KEYS "ALLE Schluessel entfernen?" 46 | #define TXT_AUTH_EMPTY_KEY "LeererSchluessel" 47 | 48 | // 49 | // Secure menu item popup 50 | // 51 | 52 | #define TXT_SECURE_MENU_PROCEED "Fortfahren" 53 | #define TXT_SECURE_MENU_CANCEL "Abbrechen" 54 | #define TXT_SECURE_PIN_WRONG "Pin inkorrekt" -------------------------------------------------------------------------------- /src/lang/language_en.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language_en.h 3 | * @brief Never include directly; contains the English language text for tcMenu text, controlled by TC_LOCALE, this is the default (EN). 4 | */ 5 | 6 | // 7 | // Dialog support, note: please keep ok, cancel, close and accept in lower case 8 | // 9 | 10 | #define TXT_DIALOG_OK "ok" 11 | #define TXT_DIALOG_CANCEL "cancel" 12 | #define TXT_DIALOG_CLOSE "close" 13 | #define TXT_DIALOG_ACCEPT "accept" 14 | 15 | // 16 | // Boolean naming options 17 | // 18 | 19 | #define TXT_BOOL_ON_TEXT "ON" 20 | #define TXT_BOOL_OFF_TEXT "OFF" 21 | #define TXT_BOOL_YES_TEXT "YES" 22 | #define TXT_BOOL_NO_TEXT "NO" 23 | #define TXT_BOOL_TRUE_TEXT "TRUE" 24 | #define TXT_BOOL_FALSE_TEXT "FALSE" 25 | 26 | // 27 | // Touch screen text options IOA 28 | // 29 | 30 | #define TXT_TOUCH_CONFIGURE "Touch configuration" 31 | #define TXT_TOUCH_CONFIGURE_2ND "Touch selected areas" 32 | 33 | // 34 | // Remote Connector - pairing 35 | // 36 | 37 | #define TXT_PAIRING_TEXT "Pairing waiting" 38 | 39 | // 40 | // RemoteMenuItem dialog text for remote connections and authentication 41 | // 42 | 43 | #define TXT_CLOSE_CONNECTION "Close Connection" 44 | #define TXT_AUTH_REMOVE "Remove" 45 | #define TXT_AUTH_REMOVE_ALL_KEYS "Remove ALL keys?" 46 | #define TXT_AUTH_EMPTY_KEY "EmptyKey" 47 | 48 | // 49 | // Secure menu item popup 50 | // 51 | 52 | #define TXT_SECURE_MENU_PROCEED "Proceed" 53 | #define TXT_SECURE_MENU_CANCEL "Cancel" 54 | #define TXT_SECURE_PIN_WRONG "Pin incorrect" 55 | -------------------------------------------------------------------------------- /src/lang/language_fr.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language_fr.h 3 | * @brief Never include directly; contains the French language text for tcMenu text, controlled by TC_LOCALE. 4 | */ 5 | 6 | // 7 | // Dialog support, note: please keep ok, cancel, close and accept in lower case 8 | // 9 | 10 | #define TXT_DIALOG_OK "d'accord" 11 | #define TXT_DIALOG_CANCEL "annuler" 12 | #define TXT_DIALOG_CLOSE "fermer" 13 | #define TXT_DIALOG_ACCEPT "j'accepte" 14 | 15 | // 16 | // Boolean naming options 17 | // 18 | 19 | #define TXT_BOOL_ON_TEXT "AU" 20 | #define TXT_BOOL_OFF_TEXT "VIDE" 21 | #define TXT_BOOL_YES_TEXT "OUI" 22 | #define TXT_BOOL_NO_TEXT "NON" 23 | #define TXT_BOOL_TRUE_TEXT "VRAI" 24 | #define TXT_BOOL_FALSE_TEXT "FAUX" 25 | 26 | // 27 | // Touch screen text options IOA 28 | // 29 | 30 | #define TXT_TOUCH_CONFIGURE "Configuration de l'écran tactile" 31 | #define TXT_TOUCH_CONFIGURE_2ND "Veuillez toucher" 32 | 33 | // 34 | // Remote Connector - pairing 35 | // 36 | 37 | #define TXT_PAIRING_TEXT "Jumelage en attente" 38 | 39 | // 40 | // RemoteMenuItem dialog text for remote connections and authentication 41 | // 42 | 43 | #define TXT_CLOSE_CONNECTION "Fermer la connexion" 44 | #define TXT_AUTH_REMOVE "Éliminer" 45 | #define TXT_AUTH_REMOVE_ALL_KEYS "Supprimer TOUTES les clés" 46 | #define TXT_AUTH_EMPTY_KEY "Clé vide" 47 | 48 | // 49 | // Secure menu item popup 50 | // 51 | 52 | #define TXT_SECURE_MENU_PROCEED "Procéder" 53 | #define TXT_SECURE_MENU_CANCEL "Annuler" 54 | #define TXT_SECURE_PIN_WRONG "Broche incorrecte" 55 | -------------------------------------------------------------------------------- /src/lang/language_fr_ascii.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language_fr.h 3 | * @brief Never include directly; contains the French language text for tcMenu text (ASCII only), controlled by TC_LOCALE. 4 | */ 5 | 6 | // 7 | // Dialog support, note: please keep ok, cancel, close and accept in lower case 8 | // 9 | 10 | #define TXT_DIALOG_OK "d'accord" 11 | #define TXT_DIALOG_CANCEL "annuler" 12 | #define TXT_DIALOG_CLOSE "fermer" 13 | #define TXT_DIALOG_ACCEPT "j'accepte" 14 | 15 | // 16 | // Boolean naming options 17 | // 18 | 19 | #define TXT_BOOL_ON_TEXT "AU" 20 | #define TXT_BOOL_OFF_TEXT "VIDE" 21 | #define TXT_BOOL_YES_TEXT "OUI" 22 | #define TXT_BOOL_NO_TEXT "NON" 23 | #define TXT_BOOL_TRUE_TEXT "VRAI" 24 | #define TXT_BOOL_FALSE_TEXT "FAUX" 25 | 26 | // 27 | // Touch screen text options IOA 28 | // 29 | 30 | #define TXT_TOUCH_CONFIGURE "Configuration de l'ecran tactile" 31 | #define TXT_TOUCH_CONFIGURE_2ND "Veuillez toucher" 32 | 33 | // 34 | // Remote Connector - pairing 35 | // 36 | 37 | #define TXT_PAIRING_TEXT "Jumelage en attente" 38 | 39 | // 40 | // RemoteMenuItem dialog text for remote connections and authentication 41 | // 42 | 43 | #define TXT_CLOSE_CONNECTION "Fermer la connexion" 44 | #define TXT_AUTH_REMOVE "Eliminer" 45 | #define TXT_AUTH_REMOVE_ALL_KEYS "Supprimer TOUTES les cles" 46 | #define TXT_AUTH_EMPTY_KEY "Cle vide" 47 | 48 | // 49 | // Secure menu item popup 50 | // 51 | 52 | #define TXT_SECURE_MENU_PROCEED "Proceder" 53 | #define TXT_SECURE_MENU_CANCEL "Annuler" 54 | #define TXT_SECURE_PIN_WRONG "Broche incorrecte" 55 | -------------------------------------------------------------------------------- /src/lang/language_select.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language_select.h 3 | * @brief contains the logic to select the right language entries for internal tcMenu library strings at compile time. 4 | */ 5 | 6 | #ifndef TCLIBRARYDEV_LANGUAGE_SELECT_H 7 | #define TCLIBRARYDEV_LANGUAGE_SELECT_H 8 | 9 | // 10 | // The highest precedence is to add `project_locale.h` if your build chain supports it. English is the default 11 | // 12 | // PlatformIO/full build systems - for French ASCII as an example -DTC_LOCALE_FR -DTC_LOCAL_ASCII 13 | // 14 | // If you're using original Arduino IDE you can force a definition of TC_LOCALE here. Commented out example below. 15 | // For example if we wanted french with only ASCII (32..126) 16 | // 17 | // #define TC_LOCALE_FR 18 | // #define TC_LOCAL_ASCII 19 | // 20 | 21 | 22 | #if __has_include() 23 | # include 24 | #elif defined(TC_LOCALE_FR) || defined(TC_LOCALE_FR_BE) \ 25 | || defined(TC_LOCALE_FR_CA) || defined(TC_LOCALE_FR_FR) \ 26 | || defined(TC_LOCALE_FR_LU) || defined(TC_LOCALE_FR_CH) 27 | #if defined(TC_LOCAL_ASCII) 28 | # include "language_fr_ascii.h" 29 | #else 30 | # include "language_fr.h" 31 | #endif // use ASCII 32 | #elif defined(TC_LOCALE_DE) || defined(TC_LOCALE_DE_AT) \ 33 | || defined(TC_LOCALE_DE_DE) || defined(TC_LOCALE_DE_LU) \ 34 | || defined(TC_LOCALE_DE_CH) 35 | #if defined(TC_LOCAL_ASCII) 36 | # include "language_de_ascii.h" 37 | #else 38 | # include "language_de.h" 39 | #endif // use ASCII 40 | #elif defined(TC_LOCALE_SK) || defined(TC_LOCALE_SK_SK) 41 | #if defined(TC_LOCAL_ASCII) 42 | # include "language_sk_ascii.h" 43 | #else 44 | # include "language_sk.h" 45 | #endif // use ASCII 46 | #elif defined(TC_LOCALE_CS) || defined(TC_LOCALE_CS_CZ) 47 | #if defined(TC_LOCAL_ASCII) 48 | # include "language_cs_ascii.h" 49 | #else 50 | # include "language_cs.h" 51 | #endif // use ASCII 52 | //add ukrainian language as uk 53 | #elif defined(TC_LOCALE_UK) || defined(TC_LOCALE_UK_UA) 54 | #if defined(TC_LOCAL_ASCII) 55 | # include "language_uk_ascii.h" 56 | #else 57 | # include "language_uk.h" 58 | #endif 59 | #else 60 | # include "language_en.h" 61 | #endif 62 | 63 | #endif //TCLIBRARYDEV_LANGUAGE_SELECT_H 64 | -------------------------------------------------------------------------------- /src/lang/language_sk.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language_sk.h 3 | * @brief Never include directly; contains the Slovak language text for tcMenu text, controlled by TC_LOCALE. 4 | */ 5 | 6 | // 7 | // Dialog support, note: please keep ok, cancel, close and accept in lower case 8 | // 9 | 10 | #define TXT_DIALOG_OK "ok" 11 | #define TXT_DIALOG_CANCEL "zrušiť" 12 | #define TXT_DIALOG_CLOSE "zavrieť" 13 | #define TXT_DIALOG_ACCEPT "prijať" 14 | 15 | // 16 | // Boolean naming options 17 | // 18 | 19 | #define TXT_BOOL_ON_TEXT "ZAP." 20 | #define TXT_BOOL_OFF_TEXT "VYP." 21 | #define TXT_BOOL_YES_TEXT "ÁNO" 22 | #define TXT_BOOL_NO_TEXT "NIE" 23 | #define TXT_BOOL_TRUE_TEXT "TRUE" 24 | #define TXT_BOOL_FALSE_TEXT "FALSE" 25 | 26 | // 27 | // Touch screen text options IOA 28 | // 29 | 30 | #define TXT_TOUCH_CONFIGURE "Konfigurácia dotykov" 31 | #define TXT_TOUCH_CONFIGURE_2ND "Dotknite sa zvolených oblastí" 32 | 33 | // 34 | // Remote Connector - pairing 35 | // 36 | 37 | #define TXT_PAIRING_TEXT "Čaká sa na párovanie" 38 | 39 | // 40 | // RemoteMenuItem dialog text for remote connections and authentication 41 | // 42 | 43 | #define TXT_CLOSE_CONNECTION "Zavrieť spojenie" 44 | #define TXT_AUTH_REMOVE "Vymazať" 45 | #define TXT_AUTH_REMOVE_ALL_KEYS "Vymazať VŠETKY kľúče?" 46 | #define TXT_AUTH_EMPTY_KEY "PrázdnyKľúč" 47 | 48 | // 49 | // Secure menu item popup 50 | // 51 | 52 | #define TXT_SECURE_MENU_PROCEED "Pokračovať" 53 | #define TXT_SECURE_MENU_CANCEL "Zrušiť" 54 | #define TXT_SECURE_PIN_WRONG "Nesprávny pin" 55 | -------------------------------------------------------------------------------- /src/lang/language_sk_ascii.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language_sk_ascii.h 3 | * @brief Never include directly; contains the Slovak language text for tcMenu text (ASCII only), controlled by TC_LOCALE. 4 | */ 5 | 6 | // 7 | // Dialog support, note: please keep ok, cancel, close and accept in lower case 8 | // 9 | 10 | #define TXT_DIALOG_OK "ok" 11 | #define TXT_DIALOG_CANCEL "zrusit" 12 | #define TXT_DIALOG_CLOSE "zavriet" 13 | #define TXT_DIALOG_ACCEPT "prijat" 14 | 15 | // 16 | // Boolean naming options 17 | // 18 | 19 | #define TXT_BOOL_ON_TEXT "ZAP." 20 | #define TXT_BOOL_OFF_TEXT "VYP." 21 | #define TXT_BOOL_YES_TEXT "ANO" 22 | #define TXT_BOOL_NO_TEXT "NIE" 23 | #define TXT_BOOL_TRUE_TEXT "TRUE" 24 | #define TXT_BOOL_FALSE_TEXT "FALSE" 25 | 26 | // 27 | // Touch screen text options IOA 28 | // 29 | 30 | #define TXT_TOUCH_CONFIGURE "Konfiguracia dotykov" 31 | #define TXT_TOUCH_CONFIGURE_2ND "Dotknite sa zvolenych oblasti" 32 | 33 | // 34 | // Remote Connector - pairing 35 | // 36 | 37 | #define TXT_PAIRING_TEXT "Caka sa na parovanie" 38 | 39 | // 40 | // RemoteMenuItem dialog text for remote connections and authentication 41 | // 42 | 43 | #define TXT_CLOSE_CONNECTION "Zavriet spojenie" 44 | #define TXT_AUTH_REMOVE "Vymazat" 45 | #define TXT_AUTH_REMOVE_ALL_KEYS "Vymazat VSETKY kluce?" 46 | #define TXT_AUTH_EMPTY_KEY "PrazdnyKluc" 47 | 48 | // 49 | // Secure menu item popup 50 | // 51 | 52 | #define TXT_SECURE_MENU_PROCEED "Pokracovat" 53 | #define TXT_SECURE_MENU_CANCEL "Zrusit" 54 | #define TXT_SECURE_PIN_WRONG "Nespravny pin" 55 | -------------------------------------------------------------------------------- /src/lang/language_uk.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language_uk.h 3 | * @brief Ніколи не включайте безпосередньо; містить англійський текст для тексту tcMenu, керованого TC_LOCALE, це значення за замовчуванням (EN). 4 | */ 5 | 6 | // 7 | // Підтримка діалогів, зауважте: будь ласка, зберігайте ok, cancel, close та accept у нижньому регістрі 8 | // 9 | 10 | #define TXT_DIALOG_OK "ок" 11 | #define TXT_DIALOG_CANCEL "відміна" 12 | #define TXT_DIALOG_CLOSE "закрити" 13 | #define TXT_DIALOG_ACCEPT "прийняти" 14 | 15 | // 16 | // Варіанти назв булевих значень 17 | // 18 | 19 | #define TXT_BOOL_ON_TEXT "УВІМК" 20 | #define TXT_BOOL_OFF_TEXT "ВИМК" 21 | #define TXT_BOOL_YES_TEXT "ТАК" 22 | #define TXT_BOOL_NO_TEXT "НІ" 23 | #define TXT_BOOL_TRUE_TEXT "ПРАВДА" 24 | #define TXT_BOOL_FALSE_TEXT "ХИБА" 25 | 26 | // 27 | // Опції тексту сенсорного екрану IOA 28 | // 29 | 30 | #define TXT_TOUCH_CONFIGURE "Налаштування сенсорного екрану" 31 | #define TXT_TOUCH_CONFIGURE_2ND "Вибрані області сенсорного екрану" 32 | 33 | // 34 | // Підключення до віддаленого з'єднання - спарювання 35 | // 36 | 37 | #define TXT_PAIRING_TEXT "Очікування спарювання" 38 | 39 | // 40 | // Текст діалогу RemoteMenuItem для віддалених підключень та аутентифікації 41 | // 42 | 43 | #define TXT_CLOSE_CONNECTION "Закрити з'єднання" 44 | #define TXT_AUTH_REMOVE "Видалити" 45 | #define TXT_AUTH_REMOVE_ALL_KEYS "Видалити ВСІ ключі?" 46 | #define TXT_AUTH_EMPTY_KEY "Порожній ключ" 47 | 48 | // 49 | // Безпечний пункт меню спливаючого вікна 50 | // 51 | 52 | #define TXT_SECURE_MENU_PROCEED "Продовжити" 53 | #define TXT_SECURE_MENU_CANCEL "Скасувати" 54 | #define TXT_SECURE_PIN_WRONG "Неправильний PIN" 55 | -------------------------------------------------------------------------------- /src/lang/language_uk_ascii.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file language_uk.h 3 | * @brief Ніколи не включайте безпосередньо; містить англійський текст для тексту tcMenu, керованого TC_LOCALE, це значення за замовчуванням (EN). 4 | */ 5 | 6 | // 7 | // Підтримка діалогів, зауважте: будь ласка, зберігайте ok, cancel, close та accept у нижньому регістрі 8 | // 9 | 10 | #define TXT_DIALOG_OK "ок" 11 | #define TXT_DIALOG_CANCEL "скасувати" 12 | #define TXT_DIALOG_CLOSE "закрити" 13 | #define TXT_DIALOG_ACCEPT "прийняти" 14 | 15 | // 16 | // Варіанти назв булевих значень 17 | // 18 | 19 | #define TXT_BOOL_ON_TEXT "УВІМК" 20 | #define TXT_BOOL_OFF_TEXT "ВИМК" 21 | #define TXT_BOOL_YES_TEXT "ТАК" 22 | #define TXT_BOOL_NO_TEXT "НІ" 23 | #define TXT_BOOL_TRUE_TEXT "ПРАВДА" 24 | #define TXT_BOOL_FALSE_TEXT "ХИБА" 25 | 26 | // 27 | // Опції тексту сенсорного екрану IOA 28 | // 29 | 30 | #define TXT_TOUCH_CONFIGURE "Налаштування сенсорного екрану" 31 | #define TXT_TOUCH_CONFIGURE_2ND "Вибрані області сенсорного екрану" 32 | 33 | // 34 | // Підключення до віддаленого з'єднання - спарювання 35 | // 36 | 37 | #define TXT_PAIRING_TEXT "Очікування спарювання" 38 | 39 | // 40 | // Текст діалогу RemoteMenuItem для віддалених підключень та аутентифікації 41 | // 42 | 43 | #define TXT_CLOSE_CONNECTION "Закрити з'єднання" 44 | #define TXT_AUTH_REMOVE "Видалити" 45 | #define TXT_AUTH_REMOVE_ALL_KEYS "Видалити ВСІ ключі?" 46 | #define TXT_AUTH_EMPTY_KEY "Порожній ключ" 47 | 48 | // 49 | // Безпечний пункт меню спливаючого вікна 50 | // 51 | 52 | #define TXT_SECURE_MENU_PROCEED "Продовжити" 53 | #define TXT_SECURE_MENU_CANCEL "Скасувати" 54 | #define TXT_SECURE_PIN_WRONG "Неправильний PIN" 55 | -------------------------------------------------------------------------------- /src/stockIcons/directionalIcons.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | #ifndef TCMENU_DIRECTIONAL_ICONS_H 7 | #define TCMENU_DIRECTIONAL_ICONS_H 8 | 9 | /** 10 | * @file directionalIcons.h 11 | * @brief Contains directional icons in XBM format suited to use where arrow buttons are needed. 12 | */ 13 | 14 | 15 | #include 16 | 17 | /** 18 | * ArrowHoriz11x22 icon=0, width=11, height=22, size=44 19 | * A left arrow that is 11 pixels wide by 22 high 20 | */ 21 | const uint8_t ArrowHoriz11x22BitmapLeft[] PROGMEM = { 22 | 0x00,0x04,0x00,0x06,0x00,0x07,0x80,0x03,0xc0,0x01,0xe0,0x00,0x70,0x00,0x38,0x00,0x1c,0x00,0x0e,0x00, 23 | 0x07,0x00,0x07,0x00,0x0e,0x00,0x1c,0x00,0x38,0x00,0x70,0x00,0xe0,0x00,0xc0,0x01,0x80,0x03,0x00,0x07, 24 | 0x00,0x06,0x00,0x04 25 | }; 26 | 27 | /** 28 | * ArrowHoriz11x22 icon=1, width=11, height=22, size=44 29 | * A right arrow that is 11 pixels wide by 22 high 30 | */ 31 | const uint8_t ArrowHoriz11x22BitmapRight[] PROGMEM = { 32 | 0x01,0x00,0x03,0x00,0x07,0x00,0x0e,0x00,0x1c,0x00,0x38,0x00,0x70,0x00,0xe0,0x00,0xc0,0x01,0x80,0x03, 33 | 0x00,0x07,0x00,0x07,0x80,0x03,0xc0,0x01,0xe0,0x00,0x70,0x00,0x38,0x00,0x1c,0x00,0x0e,0x00,0x07,0x00, 34 | 0x03,0x00,0x01,0x00 35 | }; 36 | 37 | /** 38 | * defaultBackIconBitmap - the default back icon that can be used with card layout. It is 32x32 in size. 39 | */ 40 | // XBM_LSB_FIRST width=32, height=32, size=128 41 | // auto size = Coord(32, 32); 42 | const uint8_t defaultBackIconBitmap[] PROGMEM = { 43 | 0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0xfc,0x00,0x00, 44 | 0x00,0xff,0x00,0x00,0x80,0xff,0x00,0x00,0xe0,0xff,0x03,0x00,0xf0,0xff,0x3f,0x00,0xfc,0xff,0xff,0x00, 45 | 0xfe,0xff,0xff,0x03,0xff,0xff,0xff,0x0f,0xff,0xff,0xff,0x1f,0xfe,0xff,0xff,0x3f,0xfc,0xff,0xff,0x3f, 46 | 0xf0,0xff,0xff,0x7f,0xe0,0xff,0xff,0x7f,0x80,0xff,0x00,0x7f,0x00,0xff,0x00,0x7c,0x00,0xfc,0x00,0x70, 47 | 0x00,0xf8,0x00,0x60,0x00,0xf0,0x00,0x40,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x78, 48 | 0x00,0x00,0x01,0x40,0x00,0x00,0x01,0x40,0x00,0x00,0x01,0x40,0x00,0x00,0x61,0x43,0x00,0x00,0x61,0x43, 49 | 0x00,0x00,0x0f,0x78,0x00,0x00,0x00,0x00 50 | }; 51 | 52 | 53 | 54 | #endif //TCMENU_DIRECTIONAL_ICONS_H 55 | -------------------------------------------------------------------------------- /src/stockIcons/wifiAndConnectionIcons8x7.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | #ifndef _WIFI_AND_CONNECTION_ICONS_8X7 7 | #define _WIFI_AND_CONNECTION_ICONS_8X7 8 | 9 | #include 10 | 11 | /** 12 | * @file wifiAndConnectionIcons8x7.h 13 | * @brief Contains definitions for standard icons including the connection active icon and the wifi signal strength icon. 14 | * Icons in this file are all 8 x 8 pixels for low res displays. 15 | */ 16 | 17 | 18 | const uint8_t iconConnectionNone[] PROGMEM = { 0x7e, 0xab, 0xd5, 0xab, 0xd5, 0xab, 0xd5, 0x7e }; 19 | 20 | const uint8_t iconConnected[] PROGMEM = { 0x7e, 0x81, 0x81, 0x81, 0x81, 0x81, 0x99, 0x7e }; 21 | 22 | const uint8_t iconWifiNone[] PROGMEM = { 0x00, 0x3e, 0x41, 0x41, 0x22, 0x22, 0x14, 0x08 }; 23 | 24 | const uint8_t iconWifiLow[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 }; 25 | 26 | const uint8_t iconWifiMed[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x08 }; 27 | 28 | const uint8_t iconWifiGood[] PROGMEM = { 0x00, 0x00, 0x00, 0x3e, 0x41, 0x1c, 0x22, 0x08 }; 29 | 30 | const uint8_t iconWifiStrong[] PROGMEM = { 0x00, 0x3e, 0x41, 0x3e, 0x41, 0x1c, 0x22, 0x08 }; 31 | 32 | 33 | 34 | /** 35 | * Defines a set of 5 icons for wifi, not connected and then various signal strength. 0 is no connection, 4 is good signal. 36 | * Usually used with a TitleWidget on a low resolution display. the icons are 8 x 8 pixels. 37 | */ 38 | const uint8_t* const iconsWifi[] PROGMEM = { iconWifiNone, iconWifiLow, iconWifiMed, iconWifiGood, iconWifiStrong }; 39 | 40 | /** 41 | * Defines a set of 2 icons for connection active, a boolean state of either active (1) or not active (0). 42 | * Usually used with a TitleWidget on a low resolution display. the icons are 8 x 8 pixels. 43 | */ 44 | const uint8_t* const iconsConnection[] PROGMEM = { iconConnectionNone, iconConnected }; 45 | 46 | #endif //_WIFI_AND_CONNECTION_ICONS_8X7 -------------------------------------------------------------------------------- /src/stockIcons/wifiAndConnectionIconsLCD.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | #ifndef _WIFI_STOCK_CONNECTION_LCD_H 7 | #define _WIFI_STOCK_CONNECTION_LCD_H 8 | 9 | #include 10 | 11 | /** 12 | * @file wifiAndConnectionIconsLCD.h 13 | * @brief Contains definitions for standard icons including the connection active icon and the wifi signal strength icon. 14 | * Icons in this file are for use on LCD display and are arranged to show as custom characters. 15 | */ 16 | 17 | const uint8_t iconWifiNotConnected[8] PROGMEM = { 18 | 0b00000, 19 | 0b01110, 20 | 0b10001, 21 | 0b10001, 22 | 0b01010, 23 | 0b01010, 24 | 0b00100, 25 | 0 26 | }; 27 | 28 | const uint8_t iconWifiLowSignal[8] PROGMEM = { 29 | 0b00000, 30 | 0b00000, 31 | 0b00000, 32 | 0b00000, 33 | 0b00000, 34 | 0b00000, 35 | 0b00100, 36 | 0 37 | }; 38 | 39 | const uint8_t iconWifiMedSignal[8] PROGMEM = { 40 | 0b00000, 41 | 0b00000, 42 | 0b00000, 43 | 0b00100, 44 | 0b01010, 45 | 0b00000, 46 | 0b00100, 47 | 0 48 | }; 49 | 50 | const uint8_t iconWifiStrongSignal[8] PROGMEM = { 51 | 0b00000, 52 | 0b01110, 53 | 0b10001, 54 | 0b00100, 55 | 0b01010, 56 | 0b00000, 57 | 0b00100, 58 | 0 59 | }; 60 | 61 | const uint8_t iconWifiBestSignal[8] PROGMEM = { 62 | 0b01110, 63 | 0b10001, 64 | 0b01110, 65 | 0b10001, 66 | 0b00100, 67 | 0b01010, 68 | 0b00100, 69 | 0 70 | }; 71 | 72 | const uint8_t iconConnected[8] PROGMEM = { 73 | 0b00001110, 74 | 0b00010001, 75 | 0b00010001, 76 | 0b00010001, 77 | 0b00010001, 78 | 0b00011111, 79 | 0b00001110, 80 | 0 81 | }; 82 | 83 | const uint8_t iconDisconnected[8] PROGMEM = { 84 | 0b00011111, 85 | 0b00010011, 86 | 0b00010011, 87 | 0b00010101, 88 | 0b00010101, 89 | 0b00011001, 90 | 0b00011111, 91 | 0 92 | }; 93 | 94 | /** 95 | * Defines a set of 5 icons for wifi, not connected and then various signal strength. 0 is no connection, 4 is good signal. 96 | * Usually used with a TitleWidget on LCD display units, note that each entry will take a custom character (5 in this case) 97 | */ 98 | const uint8_t* const iconsWifi[] PROGMEM = { iconWifiNotConnected, iconWifiLowSignal, iconWifiMedSignal, iconWifiStrongSignal, iconWifiBestSignal }; 99 | 100 | /** 101 | * Defines a set of 2 icons for connection active, a boolean state of either active (1) or not active (0). 102 | * Usually used with a TitleWidget on LCD display units, note that each entry will take a custom character (2 in this case) 103 | */ 104 | const uint8_t* const iconsConnection[] PROGMEM = { iconDisconnected, iconConnected }; 105 | 106 | #endif //_WIFI_STOCK_CONNECTION_LCD_H -------------------------------------------------------------------------------- /src/tcMenuVersion.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). 3 | * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. 4 | */ 5 | 6 | /** 7 | * @file TcMenuVersion.h 8 | * @brief contains the version information and accessor functions. 9 | */ 10 | 11 | #ifndef TCMENU_VERSION_H 12 | #define TCMENU_VERSION_H 13 | 14 | #include "tcUtil.h" 15 | 16 | namespace tccore { 17 | 18 | // here we define the version as both a string and a separate field 19 | #define TCMENU_MAJOR 4 20 | #define TCMENU_MINOR 4 21 | #define TCMENU_PATCH 0 22 | 23 | /** 24 | * A helper to generate the major minor version numbers used in the protocol 25 | */ 26 | #define majorminor(maj, min) ((maj * 100) + min) 27 | 28 | /** 29 | * Definition of the current API version 30 | */ 31 | #define API_VERSION majorminor(TCMENU_MAJOR, TCMENU_MINOR) 32 | 33 | inline void copyTcMenuVersion(char* buffer, size_t bufferSize) { 34 | buffer[0] = 'V'; buffer[1]=0; 35 | fastltoa(buffer, TCMENU_MAJOR, 3, NOT_PADDED, bufferSize); 36 | appendChar(buffer, '.', bufferSize); 37 | fastltoa(buffer, TCMENU_MINOR, 3, NOT_PADDED, bufferSize); 38 | appendChar(buffer, '.', bufferSize); 39 | fastltoa(buffer, TCMENU_PATCH, 3, NOT_PADDED, bufferSize); 40 | } 41 | 42 | 43 | } 44 | 45 | #endif //TCMENU_VERSION_H 46 | -------------------------------------------------------------------------------- /test/test_menumgr/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../tutils/tcMenuFixturesExtra.h" 4 | #include 5 | #include "../tutils/fixtures_extern.h" 6 | 7 | // core tests 8 | void testTcUtilGetParentAndVisit(); 9 | void testIteratorGetSubMenu(); 10 | void testGetItemById(); 11 | void testIterationWithPredicate(); 12 | void testIteratorTypePredicateLocalOnly(); 13 | void testIteratorNothingMatchesPredicate(); 14 | void testIterationOverAllMenuItems(); 15 | void testIterationOnSimpleMenu(); 16 | 17 | // authentication tests 18 | void authenticationTest(); 19 | void testNoAuthenicatorMode(); 20 | void testProgmemAuthenicatorMode(); 21 | 22 | // menu manager 23 | void testSaveAndLoadFromMenuSized(); 24 | void testAddingItemsAndMenuCallbacks(); 25 | void testCreatingAndInitialisation(); 26 | void testNavigationPushAndPop(); 27 | void testRebuildingNavigation(); 28 | 29 | void setup() { 30 | menuMgr.initWithoutInput(&noRenderer, &menuVolume); 31 | Serial.begin(115200); 32 | 33 | UNITY_BEGIN(); 34 | 35 | /* core */ 36 | RUN_TEST(testTcUtilGetParentAndVisit); 37 | RUN_TEST(testIteratorGetSubMenu); 38 | RUN_TEST(testGetItemById); 39 | RUN_TEST(testIterationWithPredicate); 40 | RUN_TEST(testIteratorTypePredicateLocalOnly); 41 | RUN_TEST(testIteratorNothingMatchesPredicate); 42 | RUN_TEST(testIterationOverAllMenuItems); 43 | RUN_TEST(testIterationOnSimpleMenu); 44 | 45 | /* Authentication tests file */ 46 | RUN_TEST(authenticationTest); 47 | RUN_TEST(testNoAuthenicatorMode); 48 | RUN_TEST(testProgmemAuthenicatorMode); 49 | 50 | /* menu mgr and navigator */ 51 | RUN_TEST(testSaveAndLoadFromMenuSized); 52 | RUN_TEST(testAddingItemsAndMenuCallbacks); 53 | RUN_TEST(testCreatingAndInitialisation); 54 | //IGNORED RUN_TEST(testNavigationPushAndPop); 55 | //IGNORED RUN_TEST(testRebuildingNavigation); 56 | 57 | UNITY_END(); 58 | } 59 | 60 | void loop() { 61 | } -------------------------------------------------------------------------------- /test/test_rendering/test_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../tutils/fixtures_extern.h" 4 | #include "../tutils/tcMenuFixturesExtra.h" 5 | #include 6 | 7 | // dialog tests 8 | void testBaseDialogInfo(); 9 | void testBaseDialogQuestion(); 10 | 11 | // core renderer tests 12 | void testEmptyItemPropertiesFactory(); 13 | void testDefaultItemPropertiesFactory(); 14 | void testSubAndItemSelectionPropertiesFactory(); 15 | void testIconStorageAndRetrival(); 16 | void testGridPositionStorageAndRetrival(); 17 | void testWidgetFunctionality(); 18 | void testBaseRendererWithDefaults(); 19 | void testTakeOverDisplay(); 20 | void testListRendering(); 21 | 22 | void setup() { 23 | menuMgr.initWithoutInput(&noRenderer, &menuVolume); 24 | Serial.begin(115200); 25 | 26 | UNITY_BEGIN(); 27 | 28 | /* base dialog */ 29 | RUN_TEST(testBaseDialogInfo); 30 | RUN_TEST(testBaseDialogQuestion); 31 | 32 | /* core renderer - keep last */ 33 | RUN_TEST(testEmptyItemPropertiesFactory); 34 | RUN_TEST(testDefaultItemPropertiesFactory); 35 | RUN_TEST(testSubAndItemSelectionPropertiesFactory); 36 | RUN_TEST(testIconStorageAndRetrival); 37 | RUN_TEST(testGridPositionStorageAndRetrival); 38 | RUN_TEST(testWidgetFunctionality); 39 | RUN_TEST(testBaseRendererWithDefaults); 40 | RUN_TEST(testTakeOverDisplay); 41 | RUN_TEST(testListRendering); 42 | 43 | UNITY_END(); 44 | } 45 | 46 | void loop() { 47 | } 48 | 49 | bool renderActivateCalled = false; 50 | 51 | int testBasicRuntimeFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize) { 52 | switch (mode) { 53 | case RENDERFN_NAME: { 54 | if (row < 10) { 55 | strcpy(buffer, "name"); 56 | fastltoa(buffer, row, 3, NOT_PADDED, bufferSize); 57 | } 58 | else { 59 | strcpy(buffer, "hello"); 60 | } 61 | break; 62 | } 63 | case RENDERFN_VALUE: 64 | ltoaClrBuff(buffer, row, row, NOT_PADDED, bufferSize); 65 | break; 66 | case RENDERFN_EEPROM_POS: 67 | return 44; 68 | case RENDERFN_INVOKE: 69 | renderActivateCalled = true; 70 | break; 71 | default: break; 72 | } 73 | return true; 74 | } 75 | 76 | NoRenderer noRenderer; -------------------------------------------------------------------------------- /test/tutils/fixtures_extern.h: -------------------------------------------------------------------------------- 1 | #ifndef TCLIBRARYDEV_FIXTURES_EXTERN_H 2 | #define TCLIBRARYDEV_FIXTURES_EXTERN_H 3 | 4 | #include 5 | #include 6 | 7 | extern AnalogMenuItem menuNumTwoDp; 8 | extern AnalogMenuItem menuHalvesOffs; 9 | extern IpAddressMenuItem menuIpAddr; 10 | extern AnalogMenuItem menuSubAnalog; 11 | extern BackMenuItem menuBackSub; 12 | extern SubMenuItem menuSub; 13 | extern AnalogMenuItem menuAnalog; 14 | extern AnalogMenuItem menuAnalog2; 15 | extern EnumMenuItem menuEnum1; 16 | extern BooleanMenuItem boolItem1; 17 | extern TextMenuItem textMenuItem1; 18 | extern AnalogMenuItem menuCaseTemp; 19 | extern FloatMenuItem menuFloatItem; 20 | extern ActionMenuItem menuPressMe; 21 | extern BackMenuItem menuBackSecondLevel; 22 | extern SubMenuItem menuSecondLevel; 23 | extern AnalogMenuItem menuRHSTemp; 24 | extern AnalogMenuItem menuLHSTemp; 25 | extern BackMenuItem menuBackStatus; 26 | extern SubMenuItem menuStatus; 27 | extern AnalogMenuItem menuContrast; 28 | extern BooleanMenuItem menu12VStandby; 29 | extern BackMenuItem menuBackSettings; 30 | extern SubMenuItem menuSettings; 31 | extern EnumMenuItem menuChannel; 32 | extern AnalogMenuItem menuVolume; 33 | 34 | extern AnalogMenuItem menuSimple1; 35 | extern AnalogMenuItem menuSimple2; 36 | 37 | extern int idOfCallback; 38 | extern MockEepromAbstraction eeprom; 39 | 40 | extern const char pgmMyName[]; 41 | extern NoRenderer noRenderer; 42 | 43 | extern const char *uuid1; 44 | extern const char *uuid2; 45 | extern const char *uuid3; 46 | 47 | bool checkEditorHints(int start, int end, CurrentEditorRenderingHints::EditorRenderingType ty); 48 | 49 | inline void printMenuItem(MenuItem* menuItem) { 50 | if(menuItem == nullptr) { 51 | serdebugF("NULL"); 52 | } 53 | else { 54 | char buffer[20]; 55 | menuItem->copyNameToBuffer(buffer, sizeof buffer); 56 | serdebug3(menuItem->getId(), menuItem->getMenuType(),buffer); 57 | } 58 | } 59 | 60 | 61 | #endif //TCLIBRARYDEV_FIXTURES_EXTERN_H 62 | -------------------------------------------------------------------------------- /test/tutils/tcMenuFixturesExtra.h: -------------------------------------------------------------------------------- 1 | #ifndef _TCMENU_FIXTURES_LOCAL_H_ 2 | #define _TCMENU_FIXTURES_LOCAL_H_ 3 | 4 | #include "tcUtil.h" 5 | #include "MenuItems.h" 6 | #include "RuntimeMenuItem.h" 7 | 8 | const PGM_TCM AnalogMenuInfo minfoNumTwoDp = { "TwoDpNum", 23, 32, 30000, NO_CALLBACK, 0, 100, "" }; 9 | AnalogMenuItem menuNumTwoDp(&minfoNumTwoDp, 0, NULL); 10 | 11 | const PGM_TCM AnalogMenuInfo minfoNumHalvesOffs = { "Halves", 22, 30, 255, NO_CALLBACK, -100, 2, "dB" }; 12 | AnalogMenuItem menuHalvesOffs(&minfoNumHalvesOffs, 0, &menuNumTwoDp); 13 | 14 | 15 | RENDERING_CALLBACK_NAME_INVOKE(fnIpAddrRenderFn, ipAddressRenderFn, "Ip Addr", 22, NULL) 16 | IpAddressMenuItem menuIpAddr(fnIpAddrRenderFn, 99, &menuHalvesOffs); 17 | 18 | const PGM_TCM AnalogMenuInfo minfoAnalogSub = { "SubAnalog", 10, 20, 255, NO_CALLBACK, 0, 1, "SU" }; 19 | AnalogMenuItem menuSubAnalog(&minfoAnalogSub, 0, &menuIpAddr); 20 | 21 | RENDERING_CALLBACK_NAME_INVOKE(backSubFixturesFn, backSubItemRenderFn, "Settings", 0xffff, NULL) 22 | BackMenuItem menuBackSub(backSubFixturesFn, &menuSubAnalog); 23 | const PGM_TCM SubMenuInfo minfoSub = { "Settings", 7, 0xffff, 0, NO_CALLBACK }; 24 | SubMenuItem menuSub(&minfoSub, &menuBackSub, NULL); 25 | 26 | const PGM_TCM AnalogMenuInfo minfoAnalog = { "Analog", 1, 34, 255, NO_CALLBACK, 0, 1, "AB" }; 27 | AnalogMenuItem menuAnalog(&minfoAnalog, 0, &menuSub); 28 | 29 | const PGM_TCM AnalogMenuInfo minfoAnalog2 = { "Analog2", 2, 4, 100, NO_CALLBACK, -10, 10, "" }; 30 | AnalogMenuItem menuAnalog2(&minfoAnalog2, 0, &menuAnalog); 31 | 32 | const char enumStrItem1[] PGM_TCM = "ITEM1"; 33 | const char enumStrItem2[] PGM_TCM = "ITEM2"; 34 | const char enumStrItem3[] PGM_TCM = "ITEM3"; 35 | const char* const enumStrPort2Dir[] PGM_TCM = { enumStrItem1, enumStrItem2, enumStrItem3 }; 36 | const PGM_TCM EnumMenuInfo minfoEnum1 = { "Enum1", 3, 6, 2, NO_CALLBACK , enumStrPort2Dir }; 37 | EnumMenuItem menuEnum1(&minfoEnum1, false, &menuAnalog2); 38 | 39 | int idOfCallback = 0; 40 | void testCallback(int id) { 41 | idOfCallback = id; 42 | } 43 | 44 | const PGM_TCM BooleanMenuInfo boolMenu1 = {"Bool1", 4, 8, 1, testCallback, NAMING_TRUE_FALSE }; 45 | BooleanMenuItem boolItem1(&boolMenu1, false, &menuEnum1); 46 | 47 | RENDERING_CALLBACK_NAME_INVOKE(textMenuItem1Callback, textItemRenderFn, "Text1", 9, NULL) 48 | TextMenuItem textMenuItem1(textMenuItem1Callback, 5, 10, &boolItem1); 49 | 50 | #endif // defined --------------------------------------------------------------------------------