diff --git a/doc/doxy.sh b/doc/doxy.sh index 7d6ec9f..d0eaeed 100755 --- a/doc/doxy.sh +++ b/doc/doxy.sh @@ -6,6 +6,6 @@ ## Get git rev of HEAD LIB_VERSION="$(pcregrep -o1 "^\s*version\s*=\s*(\*|\d+(\.\d+){0,3}(\.\*)?)" library.properties)" #echo ${DOXYGEN_PROJECT_NUMBER} -DOXYGEN_PROJECT_NUMBER="${LIB_VERSION} git rev:$(git rev-parse HEAD)" doxygen doc/Doxyfile +DOXYGEN_PROJECT_NUMBER="${LIB_VERSION} git rev:$(git rev-parse --short HEAD)" doxygen doc/Doxyfile diff --git a/examples/rotation/rotation.ino b/examples/rotation/rotation.ino new file mode 100644 index 0000000..7eba7e2 --- /dev/null +++ b/examples/rotation/rotation.ino @@ -0,0 +1,2 @@ +#include +// setup/main in rotation_main.cpp diff --git a/examples/rotation/rotation_main.cpp b/examples/rotation/rotation_main.cpp new file mode 100644 index 0000000..8202d8c --- /dev/null +++ b/examples/rotation/rotation_main.cpp @@ -0,0 +1,47 @@ +/* + gob_unifiedButton example + rotation for CoreS3 + */ +#include +#include + +goblib::UnifiedButton unifiedButton; // gob_unifiedButton instance +auto& display = M5.Display; + +void setup() +{ + M5.begin(); + unifiedButton.begin(&display); + display.clear(TFT_DARKGREEN); + unifiedButton.getButtonA()->setLabelText("ROTATE"); +} + +void loop() +{ + bool force{}; + static uint_fast8_t rot{display.getRotation()}; + + M5.update(); + unifiedButton.update(); + + // Change rotation + if(M5.BtnA.wasClicked()) + { + rot = (rot + 1) & 0x07; + M5_LOGI("setRotation:%u", rot); + + display.clear(TFT_DARKGREEN); + + display.setRotation(rot); + unifiedButton.setRotation(display.getRotation()); // Do not use a value different from the target! + // If you have already customized the buttons, you will need to do it again. + unifiedButton.getButtonA()->setLabelText("ROTATE"); + + force = true; + } + + display.setCursor(16, 32); + display.printf("R:%u W:%d H:%d\n", display.getRotation(), display.width(), display.height()); + display.printf("Click A to rotate random"); + unifiedButton.draw(force); +} diff --git a/library.json b/library.json index edb1d7f..a821821 100644 --- a/library.json +++ b/library.json @@ -11,7 +11,7 @@ "type": "git", "url": "https://github.com/GOB52/gob_unifiedButton.git" }, - "version": "0.1.2", + "version": "0.1.3", "headers": "gob_unifiedButton.hpp", "license": "MIT", "platforms": "espressif32", @@ -19,4 +19,4 @@ "dependencies": { "m5stack/M5Unified": "^0.1.13" } -} +} \ No newline at end of file diff --git a/library.properties b/library.properties index a1de8d4..910245e 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=gob_unifiedButton -version=0.1.2 +version=0.1.3 author=GOB maintainer=GOB sentence=Add touch buttons for CoreS3 and commonality with conventional buttons (M5.BtnX) -paragraph= +paragraph=M5Stack CoreS3 category=Other url=https://github.com/GOB52/gob_unifiedButton.git architectures=esp32,esp32s3 diff --git a/platformio.ini b/platformio.ini index 9bbe3e9..5e058ad 100644 --- a/platformio.ini +++ b/platformio.ini @@ -64,3 +64,11 @@ board_build.arduino.memory_type = qio_qspi build_type=release build_flags=${env.build_flags} ${option_release.build_flags} build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/customButton/> + +; rotate screen example (only CoreS3) +[env:rotation_CoreS3] +board = esp32s3box +board_build.arduino.memory_type = qio_qspi +build_type=release +build_flags=${env.build_flags} ${option_release.build_flags} +build_src_filter = +<*> -<.git/> -<.svn/> +<../examples/rotation/> diff --git a/src/gob_unifiedButton.cpp b/src/gob_unifiedButton.cpp index 00776b4..cc3553b 100644 --- a/src/gob_unifiedButton.cpp +++ b/src/gob_unifiedButton.cpp @@ -6,21 +6,30 @@ #include #include "gob_unifiedButton.hpp" +namespace +{ +constexpr char labelA[] = "BtnA"; +constexpr char labelB[] = "BtnB"; +constexpr char labelC[] = "BtnC"; +constexpr const char* label_table[] = { labelA, labelB, labelC }; +constexpr int32_t olClr = lgfx::color565(64,64,64); +} namespace goblib { // class UnifiedButton void UnifiedButton::begin(LovyanGFX* gfx, const appearance_t app) { - _board = M5.getBoard(); assert(gfx); _gfx = gfx; _appearance = app; _dirty = true; _font = gfx->getFont(); - createButtons(_appearance); + _enable = M5.getBoard() == m5::board_t::board_M5StackCoreS3 && M5.Touch.isEnabled(); + _rotation = _gfx->getRotation(); + if(_enable) { create_buttons(_appearance); } } -void UnifiedButton::createButtons(const appearance_t app) +void UnifiedButton::create_buttons(const appearance_t app) { int32_t w{_gfx->width() / 3}; int32_t h{32}; @@ -41,19 +50,21 @@ void UnifiedButton::createButtons(const appearance_t app) top = h/2; break; } + for(uint_fast8_t i = 0; i < 3; ++i) + { + _btns[i].initButton(_gfx, left + w * i + w / 2, top, w, h, olClr, TFT_DARKGRAY, TFT_BLACK,label_table[i]); + } +} - constexpr int32_t olClr = lgfx::color565(64,64,64); - - _btns[0].initButton(_gfx, left + w * 0 + w / 2, top, w, h, olClr, TFT_DARKGRAY, TFT_BLACK, "BtnA"); - _btns[1].initButton(_gfx, left + w * 1 + w / 2, top, w, h, olClr, TFT_DARKGRAY, TFT_BLACK, "BtnB"); - _btns[2].initButton(_gfx, left + w * 2 + w / 2, top, w, h, olClr, TFT_DARKGRAY, TFT_BLACK, "BtnC"); - - //M5_LOGI("[gob] change appearance_t:%02xH", app); +void UnifiedButton::setRotation(const uint_fast8_t rot) +{ + _rotation = rot & 0x07; // Valid values are [0...7] + create_buttons(_appearance); } void UnifiedButton::update() { - if(_board != m5::board_t::board_M5StackCoreS3) { return; } + if(!_enable) { return; } // Processes buttons in the same way as they are processed in Core2 auto ms = m5gfx::millis(); @@ -72,15 +83,31 @@ void UnifiedButton::update() if (M5.BtnC.isPressed()) { btn_bits |= 1 << 2; } if (btn_bits || !(det.state & m5::touch_state_t::mask_moving)) { + // Correct coordinates to match rotation. + auto x = raw.x; + auto y = raw.y; + const uint32_t rot = _gfx->getRotation(); + const auto wid = _gfx->width(); + const auto hgt = _gfx->height(); + + if(!(rot & 1)) { std::swap(x, y); } + const auto rot4 = rot ^ ((((rot >> 2) ^ 1) - 1) & 0x07); // 0-3 => 0-3, 4-7 => 3-0 + switch(rot4) + { + case 0: x = wid - x - 1; break; + case 2: y = hgt - y - 1; break; + case 3: x = wid - x - 1; y = hgt - y - 1; break; + default: break; + } + for(int i=0; i<3; ++i) { - btn_bits |= (_btns[i].contains(raw.x, raw.y) << i); + btn_bits |= (_btns[i].contains(x, y) << i); } _press_bits = btn_bits; } } } - // Set status to M5.BtnX M5.BtnA.setRawState(ms, btn_bits & 1); M5.BtnB.setRawState(ms, btn_bits & 2); @@ -91,15 +118,13 @@ void UnifiedButton::update() void UnifiedButton::draw(const bool force) { - if(_board != m5::board_t::board_M5StackCoreS3) { return; } - - if(!(_appearance & appearance_t::transparent_bottom) && _show && (_dirty || force)) + if(_enable && !(_appearance & appearance_t::transparent_bottom) && _show && (_dirty || force)) { auto gfont = _gfx->getFont(); _gfx->setFont(_font); _dirty = false; - for(int i=0; i<3; ++i) + for(int i=0; i < 3; ++i) { _btns[i].drawButton(_press_bits & (1<GOB52 / Twitter:@GOB_52_GOB + @author GOB / GitHub:GOB52 / X:@GOB_52_GOB @copyright 2023 GOB @copyright Licensed under the MIT license. See LICENSE file in the project root for full license information. @@ -45,8 +45,13 @@ class UnifiedButton UnifiedButton() {} + ///@cond + UnifiedButton(const UnifiedButton&) = delete; + UnifiedButton& operator=(const UnifiedButton&) = delete; + ///@endcond + /*! - @brief Initialize + @brief Begin the unified button @param gfx Target for drawing @param app Button appearance */ @@ -90,10 +95,17 @@ class UnifiedButton { _dirty = true; _appearance = app; - createButtons(_appearance); + create_buttons(_appearance); } } + /*! + @brief Change rotation + @param rot Rotation code same as M5GFX [0...7] + @warning If you have already customized the buttons, you will need to do it again. + */ + void setRotation(const uint_fast8_t rot); + ///@name Gets the LGFX_Button ///@{ LGFX_Button* getButtonA() { return &_btns[0]; } //!< @brief Gets the button A @@ -111,15 +123,15 @@ class UnifiedButton /// @endcond private: - void createButtons(const appearance_t app); + void create_buttons(const appearance_t app); LGFX_Button _btns[3]; // 0:A, 1:B, 2:C LovyanGFX* _gfx{}; uint_fast8_t _press_bits{}; - bool _dirty{}, _show{true};; + bool _enable{}, _dirty{}, _show{true}; appearance_t _appearance{appearance_t::bottom}; - m5::board_t _board{m5::board_t::board_unknown}; const lgfx::IFont* _font{}; + uint_fast8_t _rotation{(uint_fast8_t)-1}; // Same as M5GFX }; // } diff --git a/src/gob_unifiedButton_version.hpp b/src/gob_unifiedButton_version.hpp index d6af998..f933f85 100644 --- a/src/gob_unifiedButton_version.hpp +++ b/src/gob_unifiedButton_version.hpp @@ -3,7 +3,7 @@ #define GOBLIB_UNIFIED_BUTTON_VERSION_MAJOR 0 #define GOBLIB_UNIFIED_BUTTON_VERSION_MINOR 1 -#define GOBLIB_UNIFIED_BUTTON_VERSION_PATCH 2 +#define GOBLIB_UNIFIED_BUTTON_VERSION_PATCH 3 #define GOBLIB_UNIFIED_BUTTON_VERSION_STRINGIFY_AGAIN(x) #x #define GOBLIB_UNIFIED_BUTTON_VERSION_STRINGIFY(x) GOBLIB_UNIFIED_BUTTON_VERSION_STRINGIFY_AGAIN(x)