From 4bdfb5840f4766aaa4f792e6b1b081ac11114870 Mon Sep 17 00:00:00 2001 From: vgmoose Date: Fri, 22 Mar 2024 02:58:43 -0400 Subject: [PATCH] add hover events on Element and EKeyboard highlighting --- src/DrawUtils.cpp | 10 ++++++++++ src/DrawUtils.hpp | 3 +++ src/EKeyboard.cpp | 25 +++++++++++++++++++------ src/EKeyboard.hpp | 2 ++ src/Element.cpp | 19 ++++++++++++++++++- src/InputEvents.cpp | 1 - src/InputEvents.hpp | 1 + src/RootDisplay.cpp | 12 +++++++----- src/TextElement.cpp | 2 +- src/Texture.cpp | 2 +- src/Texture.hpp | 3 +++ 11 files changed, 65 insertions(+), 15 deletions(-) diff --git a/src/DrawUtils.cpp b/src/DrawUtils.cpp index 10c8d42..7599498 100644 --- a/src/DrawUtils.cpp +++ b/src/DrawUtils.cpp @@ -365,6 +365,16 @@ int CST_GetTicks() return SDL_GetTicks(); } +void CST_LowRumble(InputEvents* event, int ms) +{ +#ifndef SDL1 + auto joystick = SDL_JoystickFromInstanceID(event->event.jdevice.which); + if (joystick && SDL_JoystickGetAttached(joystick)) { + SDL_JoystickRumble(joystick, 0x400, 0x400, 200); + } +#endif +} + bool CST_isRectOffscreen(CST_Rect* rect) { // if this element will be offscreen, don't try to render it diff --git a/src/DrawUtils.hpp b/src/DrawUtils.hpp index 02a779e..3f4380f 100644 --- a/src/DrawUtils.hpp +++ b/src/DrawUtils.hpp @@ -41,6 +41,7 @@ typedef SDL_Color CST_Color; typedef SDL_Rect CST_Rect; class RootDisplay; +class InputEvents; // init / rendering analogues bool CST_DrawInit(RootDisplay* root); @@ -87,6 +88,8 @@ void CST_GetRGBA(Uint32 pixel, SDL_PixelFormat* format, CST_Color* cstColor); bool CST_SavePNG(CST_Texture* texture, const char* filename); void CST_SetWindowTitle(const char* title); +void CST_LowRumble(InputEvents* event, int ms); + #ifdef MUSIC std::vector CST_GetMusicInfo(CST_Music* music); #endif diff --git a/src/EKeyboard.cpp b/src/EKeyboard.cpp index 3e0a328..da5db63 100644 --- a/src/EKeyboard.cpp +++ b/src/EKeyboard.cpp @@ -101,7 +101,7 @@ void EKeyboard::render(Element* parent) } // draw the currently selected tile if these index things are set - if (touchMode) + if (touchMode && !isTouchDrag) { if (hasRoundedKeys) { CST_roundedBoxRGBA(renderer, dimens2.x, dimens2.y, dimens2.x + dimens2.w, dimens2.y + dimens2.h, 20, 0xad, 0xd8, 0xe6, 0x90); @@ -178,14 +178,24 @@ bool EKeyboard::process(InputEvents* event) { curRow = index = -1; touchMode = true; + isTouchDrag = false; } if (event->isKeyDown()) touchMode = false; - + bool ret = false; + + // only set touch drag if a selection hasn't been made + auto prevTouchDrag = isTouchDrag; + isTouchDrag = (event->isTouchDrag() && (!touchMode || (curRow < 0 && index < 0))) || isTouchDrag; + if (prevTouchDrag != isTouchDrag && isTouchDrag) { + // started a drag event, play vibrate + CST_LowRumble(event, 200); + ret = true; + } - if (!touchMode) + if (!touchMode && !isTouchDrag) { if (curRow < 0 && index < 0) { @@ -277,16 +287,19 @@ bool EKeyboard::process(InputEvents* event) int extWidth = width + 305; - if (event->isTouchDown() && event->touchIn(this->x, this->y, extWidth, height + 200)) + if ((event->isTouchDown() || event->isTouchDrag()) && event->touchIn(this->x, this->y, extWidth, height + 200)) { for (int y = 0; y < rowCount(); y++) - for (int x = 0; x < rowLength(y) + 1; x++) - if (event->touchIn(this->x + kXPad + x * kXOff + y * yYOff, this->y + kYPad + y * ySpacing, keyWidth, keyWidth)) + for (int x = 0; x < rowLength(y) + 1; x++) { + auto xStart = this->x + kXPad + x * kXOff + y * yYOff; + auto yStart = this->y + kYPad + y * ySpacing; + if (event->touchIn(xStart, yStart, keyWidth, keyWidth)) { ret |= true; curRow = y; index = x; } + } return true; } diff --git a/src/EKeyboard.hpp b/src/EKeyboard.hpp index 813f210..f91f739 100644 --- a/src/EKeyboard.hpp +++ b/src/EKeyboard.hpp @@ -105,6 +105,8 @@ class EKeyboard : public Element bool preventEnterAndTab = false; // hide and don't allow enter/tab inputs bool storeOwnText = false; // whether or not this keyboard will store the text input on its own + bool isTouchDrag = false; // set to true during a touchdrag + void type(int y, int x); void generateEKeyboard(); void backspace(); diff --git a/src/Element.cpp b/src/Element.cpp index 4f9508d..ec47d3e 100644 --- a/src/Element.cpp +++ b/src/Element.cpp @@ -198,6 +198,22 @@ bool Element::onTouchDrag(InputEvents* event) if (!event->isTouchDrag()) return false; + // if we're not in a deeplight (a touchdown event), draw our own drag highlight + if (this->elasticCounter != DEEP_HIGHLIGHT) { + if (event->touchIn(this->xAbs, this->yAbs, this->width, this->height)) { + // if there's currently _no_ highlight, and we're in a drag event on this element, + // so we should turn on the hover highlight + this->elasticCounter = THICK_HIGHLIGHT; + ret |= true; + + // play a hover sound and vibrate + CST_LowRumble(event, 200); + } else { + // we're in a drag event, but not for this element + this->elasticCounter = NO_HIGHLIGHT; + } + } + // minimum amount of wiggle allowed by finger before calling off a touch event int TRESHOLD = 40 / SCALER / SCALER; @@ -209,7 +225,6 @@ bool Element::onTouchDrag(InputEvents* event) this->elasticCounter = NO_HIGHLIGHT; } - // ontouchdrag never decides whether to update the view or not return ret; } @@ -357,6 +372,8 @@ Element* Element::animate( animations.push_back(new Animation( CST_GetTicks(), duration, onStep, onFinish) ); + + return this; } // Move an element up within its parent diff --git a/src/InputEvents.cpp b/src/InputEvents.cpp index 6897356..76f935c 100644 --- a/src/InputEvents.cpp +++ b/src/InputEvents.cpp @@ -93,7 +93,6 @@ InputEvents::InputEvents() bool InputEvents::processSDLEvents() { // get an event from SDL - SDL_Event event; if (!SDL_PollEvent(&event)) return false; diff --git a/src/InputEvents.hpp b/src/InputEvents.hpp index 156aa3c..2914939 100644 --- a/src/InputEvents.hpp +++ b/src/InputEvents.hpp @@ -96,6 +96,7 @@ class InputEvents CST_Keycode keyCode = -1; CST_Keymod mod = -1; + SDL_Event event; // underlying SDL event bool held_directions[4] = { false, false, false, false }; Uint32 held_type; diff --git a/src/RootDisplay.cpp b/src/RootDisplay.cpp index da3319b..0799b8c 100644 --- a/src/RootDisplay.cpp +++ b/src/RootDisplay.cpp @@ -75,12 +75,11 @@ RootDisplay::RootDisplay() #elif defined(_3DS) || defined(_3DS_MOCK) setScreenResolution(400, 480); // 3ds has a special resolution! #else - setScreenResolution(1280, 720); + setScreenResolution(640, 480); + // setScreenResolution(1280, 720); #endif - // the main input handler this->events = new InputEvents(); - } void RootDisplay::initMusic() @@ -135,11 +134,14 @@ bool RootDisplay::process(InputEvents* event) return true; } + // process either the subscreen or the children elements, always return true if "dragging" + // (may be a mouse cursor or wiimote pointing and moving on the screen) + if (RootDisplay::subscreen) - return RootDisplay::subscreen->process(event); + return RootDisplay::subscreen->process(event) || event->isTouchDrag(); // keep processing child elements - return super::process(event); + return super::process(event) || event->isTouchDrag(); } void RootDisplay::render(Element* parent) diff --git a/src/TextElement.cpp b/src/TextElement.cpp index 8cc8647..2cf988a 100644 --- a/src/TextElement.cpp +++ b/src/TextElement.cpp @@ -63,7 +63,7 @@ void TextElement::update(bool forceUpdate) CST_Surface *textSurface = ((textFont == ICON) || (textWrappedWidth == 0)) ? TTF_RenderUTF8_Blended(font, text.c_str(), textColor) : - TTF_RenderText_Blended_Wrapped(font, text.c_str(), textColor, textWrappedWidth); + TTF_RenderUTF8_Blended_Wrapped(font, text.c_str(), textColor, textWrappedWidth); if(textSurface==NULL) printf("TTF_GetError: %s\n", TTF_GetError()); loadFromSurfaceSaveToCache(key, textSurface); diff --git a/src/Texture.cpp b/src/Texture.cpp index e6045db..639959c 100644 --- a/src/Texture.cpp +++ b/src/Texture.cpp @@ -178,7 +178,7 @@ void Texture::render(Element* parent) #ifndef SDL1 SDL_SetTextureColorMod(mTexture, 0xFF, 0xFF, 0xFF); #endif - } else { + } else { // render the texture normally CST_RenderCopy(renderer, mTexture, NULL, &rect); } diff --git a/src/Texture.hpp b/src/Texture.hpp index 45c36f6..5f6e909 100644 --- a/src/Texture.hpp +++ b/src/Texture.hpp @@ -62,6 +62,9 @@ class Texture : public Element /// update and load or reload the texture void loadPath(std::string& path, bool forceReload = false); + /// Rounded corner radius (if >0, will round) + int cornerRadius = 0; + protected: /// Cache previously displayed textures static std::unordered_map texCache;