LCOV - code coverage report
Current view: top level - xenolith/renderer/material2d/components/input - MaterialInputField.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 196 335 58.5 %
Date: 2024-05-12 00:16:13 Functions: 28 47 59.6 %

          Line data    Source code
       1             : /**
       2             :  Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       3             : 
       4             :  Permission is hereby granted, free of charge, to any person obtaining a copy
       5             :  of this software and associated documentation files (the "Software"), to deal
       6             :  in the Software without restriction, including without limitation the rights
       7             :  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       8             :  copies of the Software, and to permit persons to whom the Software is
       9             :  furnished to do so, subject to the following conditions:
      10             : 
      11             :  The above copyright notice and this permission notice shall be included in
      12             :  all copies or substantial portions of the Software.
      13             : 
      14             :  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      17             :  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      18             :  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      19             :  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      20             :  THE SOFTWARE.
      21             :  **/
      22             : 
      23             : #include "MaterialInputField.h"
      24             : #include "MaterialInputTextContainer.h"
      25             : #include "MaterialEasing.h"
      26             : #include "XLDirector.h"
      27             : #include "XL2dLayer.h"
      28             : #include "XLInputListener.h"
      29             : 
      30             : namespace STAPPLER_VERSIONIZED stappler::xenolith::material2d {
      31             : 
      32          20 : InputField::~InputField() { }
      33             : 
      34          10 : bool InputField::init(InputFieldStyle fieldStyle) {
      35          10 :         SurfaceStyle style;
      36          10 :         switch (fieldStyle) {
      37          10 :         case InputFieldStyle::Filled:
      38          10 :                 style.nodeStyle = NodeStyle::Filled;
      39          10 :                 style.colorRole = ColorRole::SurfaceVariant;
      40          10 :                 break;
      41           0 :         case InputFieldStyle::Outlined:
      42           0 :                 style.nodeStyle = NodeStyle::Outlined;
      43           0 :                 style.shapeStyle = ShapeStyle::ExtraSmall;
      44           0 :                 break;
      45             :         }
      46             : 
      47          20 :         return init(fieldStyle, style);
      48             : }
      49             : 
      50          10 : bool InputField::init(InputFieldStyle fieldStyle, const SurfaceStyle &surfaceStyle) {
      51          10 :         if (!Surface::init(surfaceStyle)) {
      52           0 :                 return false;
      53             :         }
      54             : 
      55          10 :         _container = addChild(Rc<InputTextContainer>::create(), ZOrder(1));
      56          10 :         _container->setAnchorPoint(Anchor::BottomLeft);
      57             : 
      58          10 :         _labelText = addChild(Rc<TypescaleLabel>::create(TypescaleRole::BodyLarge), ZOrder(1));
      59          10 :         _labelText->setAnchorPoint(Anchor::MiddleLeft);
      60             : 
      61          10 :         _supportingText = addChild(Rc<TypescaleLabel>::create(TypescaleRole::BodySmall), ZOrder(1));
      62          10 :         _supportingText->setAnchorPoint(Anchor::TopLeft);
      63             : 
      64          10 :         _leadingIcon = addChild(Rc<IconSprite>::create(IconName::None), ZOrder(1));
      65          10 :         _leadingIcon->setAnchorPoint(Anchor::MiddleLeft);
      66          10 :         _leadingIcon->setContentSize(Size2(24.0f, 24.0f));
      67             : 
      68          10 :         _trailingIcon = addChild(Rc<IconSprite>::create(IconName::None), ZOrder(1));
      69          10 :         _trailingIcon->setAnchorPoint(Anchor::MiddleRight);
      70          10 :         _trailingIcon->setContentSize(Size2(24.0f, 24.0f));
      71             : 
      72          10 :         _indicator = addChild(Rc<Surface>::create(SurfaceStyle(ColorRole::OnSurfaceVariant, NodeStyle::Filled)), ZOrder(1));
      73          10 :         _indicator->setAnchorPoint(Anchor::BottomLeft);
      74             : 
      75          10 :         _inputListener = addInputListener(Rc<InputListener>::create());
      76             : 
      77          10 :         _inputListener->setTouchFilter([this] (const InputEvent &event, const InputListener::DefaultEventFilter &cb) {
      78          51 :                 if (cb(event)) {
      79          51 :                         return true;
      80             :                 }
      81             : 
      82           0 :                 if (_container->getTouchedCursor(event.currentLocation)) {
      83           0 :                         return true;
      84             :                 }
      85             : 
      86           0 :                 return false;
      87             :         });
      88             : 
      89          10 :         _inputListener->addMouseOverRecognizer([this] (const GestureData &data) {
      90           0 :                 _mouseOver = (data.event == GestureEvent::Began);
      91           0 :                 updateActivityState();
      92           0 :                 return true;
      93             :         });
      94          10 :         _inputListener->addTapRecognizer([this] (const GestureTap &tap) {
      95          10 :                 return handleTap(tap.input->currentLocation);
      96          10 :         }, InputListener::makeButtonMask({InputMouseButton::Touch}), 1);
      97             : 
      98          10 :         _inputListener->addPressRecognizer([this] (const GesturePress &press) {
      99          20 :                 switch (press.event) {
     100          10 :                 case GestureEvent::Began:
     101          10 :                         return handlePressBegin(press.location());
     102             :                         break;
     103           0 :                 case GestureEvent::Activated:
     104           0 :                         return handleLongPress(press.location(), press.tickCount);
     105             :                         break;
     106          10 :                 case GestureEvent::Ended:
     107          10 :                         return handlePressEnd(press.location());
     108             :                         break;
     109           0 :                 case GestureEvent::Cancelled:
     110           0 :                         return handlePressCancel(press.location());
     111             :                         break;
     112             :                 }
     113           0 :                 return false;
     114          10 :         }, TimeInterval::milliseconds(425), true);
     115             : 
     116          10 :         _inputListener->addSwipeRecognizer([this] (const GestureSwipe &swipe) {
     117           0 :                 switch (swipe.event) {
     118           0 :                 case GestureEvent::Began:
     119           0 :                         if (handleSwipeBegin(swipe.input->originalLocation, swipe.delta / swipe.density)) {
     120           0 :                                 return handleSwipe(swipe.input->originalLocation, swipe.delta / swipe.density, swipe.velocity / swipe.density);
     121             :                         }
     122           0 :                         return false;
     123             :                         break;
     124           0 :                 case GestureEvent::Activated:
     125           0 :                         return handleSwipe(swipe.location(), swipe.delta / swipe.density, swipe.velocity / swipe.density);
     126             :                         break;
     127           0 :                 case GestureEvent::Ended:
     128             :                 case GestureEvent::Cancelled:
     129           0 :                         return handleSwipeEnd(swipe.velocity / swipe.density);
     130             :                         break;
     131             :                 }
     132           0 :                 return false;
     133             :         });
     134             : 
     135          10 :         _focusInputListener = addInputListener(Rc<InputListener>::create());
     136          10 :         _focusInputListener->setPriority(1);
     137          10 :         _focusInputListener->addTapRecognizer([this] (const GestureTap &tap) {
     138           0 :                 if (_handler.isActive()) {
     139           0 :                         _handler.cancel();
     140             :                 }
     141           0 :                 _focusInputListener->setEnabled(false);
     142           0 :                 return true;
     143          10 :         }, InputListener::makeButtonMask({InputMouseButton::Touch}), 1);
     144          10 :         _focusInputListener->setTouchFilter([this] (const InputEvent &event, const InputListener::DefaultEventFilter &cb) {
     145           0 :                 if (!_container->isTouched(event.currentLocation, 8.0f)) {
     146           0 :                         return true;
     147             :                 }
     148           0 :                 return false;
     149             :         });
     150          10 :         _focusInputListener->setEnabled(false);
     151             : 
     152          10 :         _handler.onText = std::bind(&InputField::handleTextInput, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
     153          10 :         _handler.onKeyboard = std::bind(&InputField::handleKeyboardEnabled, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
     154          10 :         _handler.onInput = std::bind(&InputField::handleInputEnabled, this, std::placeholders::_1);
     155             : 
     156          10 :         return true;
     157             : }
     158             : 
     159          10 : void InputField::onEnter(Scene *scene) {
     160          10 :         Surface::onEnter(scene);
     161          10 : }
     162             : 
     163          10 : void InputField::onExit() {
     164          10 :         Surface::onExit();
     165          10 :         _container->setCursorCallback(nullptr);
     166          10 : }
     167             : 
     168          10 : void InputField::onContentSizeDirty() {
     169          10 :         Surface::onContentSizeDirty();
     170             : 
     171          10 :         _supportingText->setPosition(Vec2(16.0f, -4.0f));
     172          10 :         _supportingText->setWidth(_contentSize.width - 32.0f);
     173             : 
     174          10 :         _leadingIcon->setPosition(Vec2(12.0f, _contentSize.height / 2.0f));
     175          10 :         _trailingIcon->setPosition(Vec2(_contentSize.width - 12.0f, _contentSize.height / 2.0f));
     176             : 
     177          10 :         float xOffset = 16.0f;
     178          10 :         float containerWidth = _contentSize.width - 16.0f * 2.0f;
     179             : 
     180          10 :         if (getLeadingIconName() != IconName::None) {
     181          10 :                 xOffset += _leadingIcon->getContentSize().width + 12.0f;
     182          10 :                 containerWidth -= _leadingIcon->getContentSize().width + 12.0f;
     183             :         }
     184             : 
     185          10 :         if (getTrailingIconName() != IconName::None) {
     186          10 :                 containerWidth -= _trailingIcon->getContentSize().width + 12.0f;
     187             :         }
     188             : 
     189          10 :         _container->setContentSize(Size2(containerWidth, _contentSize.height - 32.0f));
     190          10 :         _container->setPosition(Vec2(xOffset, 10.0f));
     191             : 
     192          10 :         if (_focused) {
     193           0 :                 _labelText->setAnchorPoint(Anchor::TopLeft);
     194           0 :                 _labelText->setPosition(Vec2(xOffset, _contentSize.height - 9.0f));
     195           0 :                 _indicator->setContentSize(Size2(_contentSize.width, 2.0f));
     196             :         } else {
     197          10 :                 if (!_inputString.empty()) {
     198           0 :                         _labelText->setAnchorPoint(Anchor::TopLeft);
     199           0 :                         _labelText->setPosition(Vec2(xOffset, _contentSize.height - 9.0f));
     200             :                 } else {
     201          10 :                         _labelText->setAnchorPoint(Anchor::MiddleLeft);
     202          10 :                         _labelText->setPosition(Vec2(xOffset, _contentSize.height / 2.0f));
     203             :                 }
     204          10 :                 _indicator->setContentSize(Size2(_contentSize.width, 1.0f));
     205             :         }
     206             : 
     207          10 :         stopAllActionsByTag(InputEnabledActionTag);
     208          10 : }
     209             : 
     210          10 : void InputField::setLabelText(StringView text) {
     211          10 :         _labelText->setString(text);
     212          10 : }
     213             : 
     214           0 : StringView InputField::getLabelText() const {
     215           0 :         return _labelText->getString8();
     216             : }
     217             : 
     218          10 : void InputField::setSupportingText(StringView text) {
     219          10 :         _supportingText->setString(text);
     220          10 : }
     221             : 
     222           0 : StringView InputField::getSupportingText() const {
     223           0 :         return _supportingText->getString8();
     224             : }
     225             : 
     226          10 : void InputField::setLeadingIconName(IconName name) {
     227          10 :         if (name != getLeadingIconName()) {
     228          10 :                 _leadingIcon->setIconName(name);
     229          10 :                 _contentSizeDirty = true;
     230             :         }
     231          10 : }
     232             : 
     233          30 : IconName InputField::getLeadingIconName() const {
     234          30 :         return _leadingIcon->getIconName();
     235             : }
     236             : 
     237          10 : void InputField::setTrailingIconName(IconName name) {
     238          10 :         if (name != getTrailingIconName()) {
     239          10 :                 _trailingIcon->setIconName(name);
     240          10 :                 _contentSizeDirty = true;
     241             :         }
     242          10 : }
     243             : 
     244          30 : IconName InputField::getTrailingIconName() const {
     245          30 :         return _trailingIcon->getIconName();
     246             : }
     247             : 
     248           0 : void InputField::setEnabled(bool value) {
     249           0 :         if (_enabled != value) {
     250           0 :                 _enabled = value;
     251           0 :                 updateActivityState();
     252             :         }
     253           0 : }
     254             : 
     255          20 : bool InputField::isEnabled() const {
     256          20 :         return _enabled;
     257             : }
     258             : 
     259           0 : void InputField::setInputType(TextInputType type) {
     260           0 :         _inputType = type;
     261           0 : }
     262             : 
     263           0 : void InputField::setPasswordMode(InputFieldPasswordMode mode) {
     264           0 :         _passwordMode = mode;
     265           0 : }
     266             : 
     267          20 : void InputField::updateActivityState() {
     268          20 :         auto style = getStyleTarget();
     269          20 :         if (!_enabled) {
     270           0 :                 style.activityState = ActivityState::Disabled;
     271          20 :         } else if (_focused) {
     272          10 :                 style.activityState = ActivityState::Enabled;
     273          10 :         } else if (_mouseOver) {
     274           0 :                 style.activityState = ActivityState::Hovered;
     275             :         } else {
     276          10 :                 style.activityState = ActivityState::Enabled;
     277             :         }
     278          20 :         setStyle(style, _activityAnimationDuration);
     279          20 : }
     280             : 
     281          10 : bool InputField::handleTap(const Vec2 &pt) {
     282          10 :         if (!isEnabled()) {
     283           0 :                 return false;
     284             :         }
     285             : 
     286          10 :         return true;
     287             : }
     288             : 
     289          10 : bool InputField::handlePressBegin(const Vec2 &pt) {
     290          10 :         if (!isEnabled()) {
     291           0 :                 return false;
     292             :         }
     293             : 
     294          10 :         if (_leadingIcon && getLeadingIconName() != IconName::None && _leadingIcon->isTouched(pt, 12)) {
     295           0 :                 return false;
     296             :         }
     297             : 
     298          10 :         if (_trailingIcon && getTrailingIconName() != IconName::None && _trailingIcon->isTouched(pt, 12)) {
     299           0 :                 return false;
     300             :         }
     301             : 
     302          10 :         _inputListener->setExclusive();
     303          10 :         _isLongPress = false;
     304          10 :         return true;
     305             : }
     306             : 
     307           0 : bool InputField::handleLongPress(const Vec2 &pt, uint32_t tickCount) {
     308           0 :         if (!isEnabled() || !_rangeSelectionAllowed) {
     309           0 :                 return false;
     310             :         }
     311             : 
     312           0 :         if (_container->handleLongPress(pt, tickCount)) {
     313           0 :                 _isLongPress = true;
     314           0 :                 if (!_focused) {
     315           0 :                         acquireInputFromContainer();
     316             :                 }
     317           0 :                 return true;
     318             :         }
     319           0 :         return false;
     320             : }
     321             : 
     322          10 : bool InputField::handlePressEnd(const Vec2 &pt) {
     323          10 :         if (_container->isTouched(pt, 8.0f)) {
     324          10 :                 if (!_isLongPress) {
     325          10 :                         if (!_focused) {
     326          10 :                                 acquireInput(pt);
     327             :                         } else {
     328           0 :                                 updateCursorForLocation(pt);
     329             :                         }
     330             :                 }
     331             :         }
     332          10 :         _isLongPress = false;
     333          10 :         return true;
     334             : }
     335             : 
     336           0 : bool InputField::handlePressCancel(const Vec2 &) {
     337           0 :         _isLongPress = false;
     338           0 :         return false;
     339             : }
     340             : 
     341           0 : bool InputField::handleSwipeBegin(const Vec2 &pt, const Vec2 &delta) {
     342           0 :         if (!isEnabled()) {
     343           0 :                 return false;
     344             :         }
     345             : 
     346           0 :         if (_focused) {
     347           0 :                 if (_container->handleSwipeBegin(pt)) {
     348           0 :                         _pointerSwipeCaptured = true;
     349           0 :                         return true;
     350             :                 }
     351             :         }
     352             : 
     353           0 :         if (_container->hasHorizontalOverflow() && _container->isTouched(pt, 8.0f)) {
     354           0 :                 _inputListener->setExclusive();
     355           0 :                 _containerSwipeCaptured = true;
     356           0 :                 return true;
     357             :         }
     358             : 
     359           0 :         return false;
     360             : }
     361             : 
     362           0 : bool InputField::handleSwipe(const Vec2 &pt, const Vec2 &delta, const Vec2 &v) {
     363           0 :         if (_pointerSwipeCaptured) {
     364           0 :                 return _container->handleSwipe(pt, delta);
     365             :         }
     366             : 
     367           0 :         if (_containerSwipeCaptured) {
     368           0 :                 _container->moveHorizontalOverflow(delta.x);
     369           0 :                 return true;
     370             :         }
     371             : 
     372           0 :         return false;
     373             : }
     374             : 
     375           0 : bool InputField::handleSwipeEnd(const Vec2 &pt) {
     376           0 :         if (_pointerSwipeCaptured) {
     377           0 :                 auto ret = _container->handleSwipeEnd(pt);
     378           0 :                 _pointerSwipeCaptured = false;
     379           0 :                 return ret;
     380             :         }
     381             : 
     382           0 :         if (_containerSwipeCaptured) {
     383           0 :                 _containerSwipeCaptured = false;
     384           0 :                 return true;
     385             :         }
     386           0 :         return false;
     387             : }
     388             : 
     389          20 : void InputField::updateInputEnabled() {
     390          20 :         if (!_running) {
     391          10 :                 _contentSizeDirty = true;
     392          10 :                 return;
     393             :         }
     394             : 
     395          10 :         stopAllActionsByTag(InputEnabledActionTag);
     396             : 
     397          10 :         bool populated = !_inputString.empty();
     398             : 
     399          10 :         auto labelAnchor = _labelText->getAnchorPoint();
     400          10 :         auto labelPos = _labelText->getPosition();
     401          10 :         auto indicatorSize = _indicator->getContentSize();
     402             : 
     403          10 :         auto targetLabelAnchor = Anchor::MiddleLeft;
     404          10 :         auto targetLabelPos = Vec3(labelPos.x, _contentSize.height / 2.0f, 0.0f);
     405          10 :         auto targetIndicatorSize = Size2(indicatorSize.width, _focused ? 2.0f : 1.0f);
     406             : 
     407          10 :         auto sourceLabelSize = _labelText->getFontSize();
     408          10 :         auto targetLabelSize = font::FontSize(16);
     409             : 
     410          10 :         auto sourceBlendValue = _labelText->getBlendColorValue();
     411          10 :         auto targetBlendValue = _focused ? 1.0f : 0.0f;
     412             : 
     413          10 :         if (populated || _focused) {
     414          10 :                 targetLabelAnchor = Anchor::TopLeft;
     415          10 :                 targetLabelPos = Vec3(labelPos.x, _contentSize.height - 9.0f, 0.0f);
     416          10 :                 targetLabelSize = font::FontSize(12);
     417             :         }
     418             : 
     419          10 :         runAction(makeEasing(Rc<ActionProgress>::create(_activityAnimationDuration, [=, this] (float p) {
     420         160 :                 _labelText->setAnchorPoint(progress(labelAnchor, targetLabelAnchor, p));
     421         160 :                 _labelText->setPosition(progress(labelPos, targetLabelPos, p));
     422         160 :                 _labelText->setFontSize(progress(sourceLabelSize, targetLabelSize, p));
     423         160 :                 _indicator->setContentSize(progress(indicatorSize, targetIndicatorSize, p));
     424         160 :         }), EasingType::Standard), InputEnabledActionTag);
     425             : 
     426          10 :         runAction(makeEasing(Rc<ActionProgress>::create(_activityAnimationDuration, [=, this] (float p) {
     427         160 :                 _labelText->setBlendColor(ColorRole::Primary, progress(sourceBlendValue, targetBlendValue, p));
     428         160 :         }), EasingType::Standard), InputEnabledLabelActionTag);
     429             : 
     430          10 :         auto indicatorStyle = _indicator->getStyleTarget();
     431          10 :         indicatorStyle.colorRole = _focused ? ColorRole::Primary : ColorRole::OnSurfaceVariant;
     432             : 
     433          10 :         _indicator->setStyle(indicatorStyle, _activityAnimationDuration);
     434             : }
     435             : 
     436           0 : void InputField::acquireInputFromContainer() {
     437           0 :         _cursor = _container->getCursor();
     438           0 :         _markedRegion = TextCursor::InvalidCursor;
     439           0 :         _handler.run(_director->getTextInputManager(), _inputString, _cursor, _markedRegion, _inputType);
     440           0 :         _focusInputListener->setEnabled(true);
     441           0 : }
     442             : 
     443          10 : void InputField::acquireInput(const Vec2 &targetLocation) {
     444          10 :         auto cursor = _container->getCursorForPosition(targetLocation);
     445          10 :         if (cursor != TextCursor::InvalidCursor) {
     446           0 :                 _cursor = cursor;
     447             :         } else {
     448          10 :                 _cursor = TextCursor(_inputString.size(), 0);
     449             :         }
     450             : 
     451          10 :         _container->setCursor(_cursor);
     452          10 :         _container->touchPointers();
     453          10 :         _markedRegion = TextCursor::InvalidCursor;
     454          10 :         _handler.run(_director->getTextInputManager(), _inputString, _cursor, _markedRegion, _inputType);
     455          10 :         _focusInputListener->setEnabled(true);
     456          10 : }
     457             : 
     458           0 : void InputField::updateCursorForLocation(const Vec2 &targetLocation) {
     459           0 :         auto cursor = _container->getCursorForPosition(targetLocation);
     460           0 :         if (cursor != TextCursor::InvalidCursor && cursor != _cursor) {
     461           0 :                 _cursor = cursor;
     462           0 :                 if (_handler.isActive()) {
     463           0 :                         _handler.setCursor(cursor);
     464           0 :                         _container->setCursor(cursor);
     465           0 :                         _container->touchPointers();
     466           0 :                         _markedRegion = TextCursor::InvalidCursor;
     467             :                 }
     468             :         }
     469           0 : }
     470             : 
     471         330 : void InputField::handleTextInput(WideStringView str, TextCursor cursor, TextCursor marked) {
     472         330 :         auto label = _container->getLabel();
     473             : 
     474         330 :         auto maxChars = label->getMaxChars();
     475         330 :         if (maxChars > 0) {
     476           0 :                 if (maxChars < str.size()) {
     477           0 :                         auto tmpString = WideStringView(str, 0, maxChars);
     478           0 :                         _handler.setString(tmpString, cursor);
     479           0 :                         handleTextInput(tmpString, _cursor, _markedRegion);
     480           0 :                         handleError(InputFieldError::Overflow);
     481           0 :                         return;
     482             :                 }
     483             :         }
     484             : 
     485        3675 :         for (auto &it : str) {
     486        3345 :                 if (!handleInputChar(it)) {
     487           0 :                         _handler.setString(getInputString(), _cursor);
     488           0 :                         handleError(InputFieldError::Overflow);
     489           0 :                         return;
     490             :                 }
     491             :         }
     492             : 
     493         330 :         _container->setCursor(cursor);
     494             : 
     495         330 :         _inputString = str.str<Interface>();
     496         330 :         _cursor = cursor;
     497             : 
     498         330 :         switch (_passwordMode) {
     499         330 :         case InputFieldPasswordMode::NotPassword:
     500             :         case InputFieldPasswordMode::ShowAll:
     501         330 :                 label->setString(_inputString);
     502         330 :                 break;
     503           0 :         case InputFieldPasswordMode::ShowNone:
     504             :         case InputFieldPasswordMode::ShowChar: {
     505           0 :                 WideString str; str.resize(_inputString.length(), u'*');
     506           0 :                 label->setString(str);
     507             :                 /*if (isInsert) {
     508             :                         showLastChar();
     509             :                 }*/
     510           0 :                 break;
     511           0 :         }
     512             :         }
     513             : 
     514         330 :         label->tryUpdateLabel();
     515             : 
     516         330 :         _container->handleLabelChanged();
     517             : }
     518             : 
     519           0 : void InputField::handleKeyboardEnabled(bool, const Rect &, float) {
     520             : 
     521           0 : }
     522             : 
     523          20 : void InputField::handleInputEnabled(bool enabled) {
     524          20 :         if (_focused != enabled) {
     525          20 :                 _focused = enabled;
     526          20 :                 updateActivityState();
     527          20 :                 updateInputEnabled();
     528          20 :                 if (_enabled) {
     529          20 :                         _container->setCursorCallback([this] (TextCursor cursor) {
     530           0 :                                 _cursor = cursor;
     531           0 :                                 _handler.setCursor(cursor);
     532           0 :                         });
     533             :                 } else {
     534           0 :                         _container->setCursorCallback(nullptr);
     535             :                 }
     536             :         }
     537          20 :         _container->setEnabled(enabled);
     538          20 : }
     539             : 
     540        3345 : bool InputField::handleInputChar(char16_t ch) {
     541        3345 :         return true;
     542             : }
     543             : 
     544           0 : void InputField::handleError(InputFieldError err) {
     545             : 
     546           0 : }
     547             : 
     548             : }

Generated by: LCOV version 1.14