#include #include #include #include #include "attachablecursor.hpp" #ifdef DEFINE_MY_OWN_CURSOR #define CURSORMEMBERREF(c) c. #else #define CURSORMEMBERREF(c) c-> #endif using namespace touchgfx; namespace tdylib { AttachableCursor::AttachableCursor() : cursorPosition(0), cursorXCoord(0), cursorIsVisible(true), txtAttached(nullptr) { // If the cursor (= Line) is not defined/initialized in the Screen itself then there's // an exception when it is first rendered. Putting it here does not work. #ifdef DEFINE_MY_OWN_CURSOR cursor.setPosition(2,0,2,20); // A placeholder cursor.setStart(0, 0); // A placeholder cursor.setEnd(2, 19); // A placeholder cursorPainter.setColor(Color::getColorFromRGB(0x0, 0x0, 0x0)); // black cursor.setPainter(cursorPainter); cursor.setLineWidth(1); #endif } /** \brief Pass in a TextAreaWithOneWildcard (or nullptr), if it's the former we'll draw the cursor over it. * * \param textArea This should actually be a TextAreaWithOneWildcard, but (for the time being) we'll dynamic cast * it to verify that this is the case. This is the widget we're drawing the cursor over. * Is allowed to be a nullptr. * \param visible Whether the cursor should be visible or not. */ void AttachableCursor::AttachCursorToTextArea(TextArea* textArea, bool visible) { #ifndef DEFINE_MY_OWN_CURSOR assert(cursor != nullptr); #endif if (txtAttached != nullptr) // remove the cursor from any previously associated TextArea { CURSORMEMBERREF(cursor)setVisible(false); CURSORMEMBERREF(cursor)invalidate(); } txtAttached = dynamic_cast(textArea); if (txtAttached != nullptr) { cursorPosition = Unicode::strlen(txtAttached->getWildcard1()); calculateCursorCoordinate(); cursorIsVisible = visible; CURSORMEMBERREF(cursor)setVisible(cursorIsVisible); if (visible) { CURSORMEMBERREF(cursor)invalidate(); } } } /** \brief Determine where the cursor should be positioned on the screen, and move it there; does not redraw the cursor. * */ void AttachableCursor::calculateCursorCoordinate() { if (txtAttached == nullptr) return; Unicode::UnicodeChar temp[50]; Unicode::strncpy(temp, txtAttached->getWildcard1(), 49); temp[49] = 0; temp[cursorPosition] = 0; cursorXCoord = txtAttached->getTypedText().getFont()->getStringWidth(temp); if (txtAttached->getAlignment() == CENTER) { int fullTextLength = txtAttached->getTypedText().getFont()->getStringWidth(txtAttached->getWildcard1()); int textStartPosn = (txtAttached->getWidth() - fullTextLength) / 2; cursorXCoord += textStartPosn; } CURSORMEMBERREF(cursor)setPosition((int16_t)(txtAttached->getX() + cursorXCoord), txtAttached->getY(), 2, txtAttached->getTextHeight()); CURSORMEMBERREF(cursor)setStart(0, 0); CURSORMEMBERREF(cursor)setEnd(0, txtAttached->getTextHeight() - 1); } void AttachableCursor::setCursorIsVisible(bool value) { if (txtAttached == nullptr) return; if (CURSORMEMBERREF(cursor)isVisible()) { CURSORMEMBERREF(cursor)setVisible(false); CURSORMEMBERREF(cursor)invalidate(); } cursorIsVisible = value; if (!value) return; calculateCursorCoordinate(); CURSORMEMBERREF(cursor)setVisible(true); CURSORMEMBERREF(cursor)invalidate(); } void AttachableCursor::incrementCursorPosition() { assert(txtAttached != nullptr); #ifndef DEFINE_MY_OWN_CURSOR assert(cursor != nullptr); #endif setCursorPosition(MIN(Unicode::strlen(txtAttached->getWildcard1()), cursorPosition + 1)); } void AttachableCursor::decrementCursorPosition() { assert(txtAttached != nullptr); #ifndef DEFINE_MY_OWN_CURSOR assert(cursor != nullptr); #endif setCursorPosition(MAX(0,cursorPosition-1)); } void AttachableCursor::setCursorPosition(const uint16_t value) { #ifndef DEFINE_MY_OWN_CURSOR assert(cursor != nullptr); #endif if (txtAttached == nullptr) return; int strlength = Unicode::strlen(txtAttached->getWildcard1()); cursorPosition = (value <= strlength) ? value : strlength; CURSORMEMBERREF(cursor)setVisible(false); txtAttached->invalidate(); calculateCursorCoordinate(); CURSORMEMBERREF(cursor)setVisible(true); txtAttached->invalidate(); } #ifndef DEFINE_MY_OWN_CURSOR void AttachableCursor::setCursor(Line* line) { assert(nullptr != line); cursor = line; CURSORMEMBERREF(cursor)setLineWidth(1); CURSORMEMBERREF(cursor)setVisible(false); CURSORMEMBERREF(cursor)invalidate(); } #endif }