X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-controller-event-handler.cpp;h=59f0b8d53dce05cd4998024c335172875ccc88f4;hp=c17c8205b31532c27eef4768dc4fd002d85c0c24;hb=3e844ed708b1cbe03cd5bfe9ad202aad27bbe360;hpb=64b92adb4035ab57f5ad265e0676a8ca8a23c64b diff --git a/dali-toolkit/internal/text/text-controller-event-handler.cpp b/dali-toolkit/internal/text/text-controller-event-handler.cpp index c17c820..59f0b8d 100644 --- a/dali-toolkit/internal/text/text-controller-event-handler.cpp +++ b/dali-toolkit/internal/text/text-controller-event-handler.cpp @@ -26,6 +26,8 @@ // INTERNAL INCLUDES #include #include +#include +#include #include namespace @@ -66,7 +68,7 @@ void Controller::EventHandler::KeyboardFocusGainEvent(Controller& controller) if(controller.mImpl->IsShowingPlaceholderText()) { // Show alternative placeholder-text when editing - controller.ShowPlaceholderText(); + PlaceholderHandler::ShowPlaceholderText(*controller.mImpl); } controller.mImpl->RequestRelayout(); @@ -81,12 +83,28 @@ void Controller::EventHandler::KeyboardFocusLostEvent(Controller& controller) { if(EventData::INTERRUPTED != controller.mImpl->mEventData->mState) { + // Init selection position + if(controller.mImpl->mEventData->mState == EventData::SELECTING) + { + uint32_t oldStart, oldEnd; + oldStart = controller.mImpl->mEventData->mLeftSelectionPosition; + oldEnd = controller.mImpl->mEventData->mRightSelectionPosition; + + controller.mImpl->mEventData->mLeftSelectionPosition = controller.mImpl->mEventData->mPrimaryCursorPosition; + controller.mImpl->mEventData->mRightSelectionPosition = controller.mImpl->mEventData->mPrimaryCursorPosition; + + if(controller.mImpl->mSelectableControlInterface != nullptr) + { + controller.mImpl->mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, controller.mImpl->mEventData->mPrimaryCursorPosition, controller.mImpl->mEventData->mPrimaryCursorPosition); + } + } + controller.mImpl->ChangeState(EventData::INACTIVE); if(!controller.mImpl->IsShowingRealText()) { // Revert to regular placeholder-text when not editing - controller.ShowPlaceholderText(); + PlaceholderHandler::ShowPlaceholderText(*controller.mImpl); } } } @@ -99,6 +117,7 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE bool textChanged = false; bool relayoutNeeded = false; + bool isEditable = controller.IsEditable() && controller.IsUserInteractionEnabled(); if((NULL != controller.mImpl->mEventData) && (keyEvent.GetState() == KeyEvent::DOWN)) @@ -130,7 +149,7 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE (Dali::DALI_KEY_CURSOR_DOWN == keyCode)) { // If don't have any text, do nothing. - if(!controller.mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters) + if(!controller.mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters || !isEditable) { return false; } @@ -151,12 +170,22 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE // Release the active highlight. if(controller.mImpl->mEventData->mState == EventData::SELECTING) { + uint32_t oldStart, oldEnd; + oldStart = controller.mImpl->mEventData->mLeftSelectionPosition; + oldEnd = controller.mImpl->mEventData->mRightSelectionPosition; + controller.mImpl->ChangeState(EventData::EDITING); // Update selection position. controller.mImpl->mEventData->mLeftSelectionPosition = controller.mImpl->mEventData->mPrimaryCursorPosition; controller.mImpl->mEventData->mRightSelectionPosition = controller.mImpl->mEventData->mPrimaryCursorPosition; controller.mImpl->mEventData->mUpdateCursorPosition = true; + + if(controller.mImpl->mSelectableControlInterface != nullptr) + { + controller.mImpl->mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, controller.mImpl->mEventData->mLeftSelectionPosition, controller.mImpl->mEventData->mRightSelectionPosition); + } + controller.mImpl->RequestRelayout(); } return false; @@ -179,7 +208,7 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE // Do nothing return false; } - else if(keyEvent.IsCtrlModifier() && !keyEvent.IsShiftModifier()) + else if(keyEvent.IsCtrlModifier() && !keyEvent.IsShiftModifier() && isEditable) { bool consumed = false; if(keyName == KEY_C_NAME || keyName == KEY_INSERT_NAME || logicalKey == KEY_C_NAME || logicalKey == KEY_INSERT_NAME) @@ -211,7 +240,7 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE else if((Dali::DALI_KEY_BACKSPACE == keyCode) || (Dali::DevelKey::DALI_KEY_DELETE == keyCode)) { - textChanged = controller.DeleteEvent(keyCode); + textChanged = DeleteEvent(controller, keyCode); // Will request for relayout. relayoutNeeded = true; @@ -245,14 +274,38 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE else { DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::KeyEvent %p keyString %s\n", &controller, keyString.c_str()); - if(!controller.IsEditable()) return false; + if(!isEditable) return false; + + std::string refinedKey = keyString; + if(controller.mImpl->mInputFilter != NULL && !refinedKey.empty()) + { + bool accepted = false; + bool rejected = false; + accepted = controller.mImpl->mInputFilter->Contains(Toolkit::InputFilter::Property::ACCEPTED, keyString); + rejected = controller.mImpl->mInputFilter->Contains(Toolkit::InputFilter::Property::REJECTED, keyString); + + if(!accepted) + { + // The filtered key is set to empty. + refinedKey = ""; + // Signal emits when the character to be inserted is filtered by the accepted filter. + controller.mImpl->mEditableControlInterface->InputFiltered(Toolkit::InputFilter::Property::ACCEPTED); + } + if(rejected) + { + // The filtered key is set to empty. + refinedKey = ""; + // Signal emits when the character to be inserted is filtered by the rejected filter. + controller.mImpl->mEditableControlInterface->InputFiltered(Toolkit::InputFilter::Property::REJECTED); + } + } - if(!keyString.empty()) + if(!refinedKey.empty()) { // InputMethodContext is no longer handling key-events controller.mImpl->ClearPreEditFlag(); - controller.InsertText(keyString, COMMIT); + TextUpdater::InsertText(controller, refinedKey, COMMIT); textChanged = true; @@ -283,6 +336,15 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE controller.mImpl->RequestRelayout(); } } + else if((NULL != controller.mImpl->mEventData) && (keyEvent.GetState() == KeyEvent::UP)) + { + // Handles specific keys that require event propagation. + if(Dali::DALI_KEY_BACK == keyEvent.GetKeyCode()) + { + // Do nothing + return false; + } + } if(textChanged && (NULL != controller.mImpl->mEditableControlInterface)) @@ -369,7 +431,7 @@ void Controller::EventHandler::TapEvent(Controller& controller, unsigned int tap if(controller.mImpl->IsShowingPlaceholderText() && !controller.mImpl->IsFocusedPlaceholderAvailable()) { // Hide placeholder text - controller.ResetText(); + TextUpdater::ResetText(controller); } if(EventData::INACTIVE == state) @@ -505,6 +567,27 @@ void Controller::EventHandler::SelectEvent(Controller& controller, float x, floa } } +void Controller::EventHandler::SelectEvent(Controller& controller, const uint32_t start, const uint32_t end, SelectionType selectType) +{ + DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::SelectEvent\n"); + + if(NULL != controller.mImpl->mEventData) + { + if(selectType == SelectionType::RANGE) + { + Event event(Event::SELECT_RANGE); + event.p2.mUint = start; + event.p3.mUint = end; + controller.mImpl->mEventData->mEventQueue.push_back(event); + } + + controller.mImpl->mEventData->mCheckScrollAmount = true; + controller.mImpl->mEventData->mIsLeftHandleSelected = true; + controller.mImpl->mEventData->mIsRightHandleSelected = true; + controller.mImpl->RequestRelayout(); + } +} + void Controller::EventHandler::ProcessModifyEvents(Controller& controller) { Vector& events = controller.mImpl->mModifyEvents; @@ -527,30 +610,39 @@ void Controller::EventHandler::ProcessModifyEvents(Controller& controller) // A (single) replace event should come first, otherwise we wasted time processing NOOP events DALI_ASSERT_DEBUG(it == events.Begin() && "Unexpected TEXT_REPLACED event"); - controller.TextReplacedEvent(); + TextReplacedEvent(controller); } else if(ModifyEvent::TEXT_INSERTED == event.type) { - controller.TextInsertedEvent(); + TextInsertedEvent(controller); } else if(ModifyEvent::TEXT_DELETED == event.type) { // Placeholder-text cannot be deleted if(!controller.mImpl->IsShowingPlaceholderText()) { - controller.TextDeletedEvent(); + TextDeletedEvent(controller); } } } if(NULL != controller.mImpl->mEventData) { + uint32_t oldStart, oldEnd; + oldStart = controller.mImpl->mEventData->mLeftSelectionPosition; + oldEnd = controller.mImpl->mEventData->mRightSelectionPosition; + // When the text is being modified, delay cursor blinking controller.mImpl->mEventData->mDecorator->DelayCursorBlink(); // Update selection position after modifying the text controller.mImpl->mEventData->mLeftSelectionPosition = controller.mImpl->mEventData->mPrimaryCursorPosition; controller.mImpl->mEventData->mRightSelectionPosition = controller.mImpl->mEventData->mPrimaryCursorPosition; + + if(controller.mImpl->mSelectableControlInterface != nullptr && controller.mImpl->mEventData->mState == EventData::SELECTING) + { + controller.mImpl->mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, controller.mImpl->mEventData->mLeftSelectionPosition, controller.mImpl->mEventData->mRightSelectionPosition); + } } // DISCARD temporary text @@ -631,22 +723,18 @@ bool Controller::EventHandler::DeleteEvent(Controller& controller, int keyCode) if(EventData::SELECTING == controller.mImpl->mEventData->mState) { - removed = controller.RemoveSelectedText(); + removed = TextUpdater::RemoveSelectedText(controller); } else if((controller.mImpl->mEventData->mPrimaryCursorPosition > 0) && (keyCode == Dali::DALI_KEY_BACKSPACE)) { // Remove the character before the current cursor position - removed = controller.RemoveText(-1, - 1, - UPDATE_INPUT_STYLE); + removed = TextUpdater::RemoveText(controller, -1, 1, UPDATE_INPUT_STYLE); } else if((controller.mImpl->mEventData->mPrimaryCursorPosition < controller.mImpl->mModel->mLogicalModel->mText.Count()) && (keyCode == Dali::DevelKey::DALI_KEY_DELETE)) { // Remove the character after the current cursor position - removed = controller.RemoveText(0, - 1, - UPDATE_INPUT_STYLE); + removed = TextUpdater::RemoveText(controller, 0, 1, UPDATE_INPUT_STYLE); } if(removed) @@ -658,7 +746,7 @@ bool Controller::EventHandler::DeleteEvent(Controller& controller, int keyCode) } else { - controller.ShowPlaceholderText(); + PlaceholderHandler::ShowPlaceholderText(*controller.mImpl); } controller.mImpl->mEventData->mUpdateCursorPosition = true; controller.mImpl->mEventData->mScrollAfterDelete = true; @@ -680,23 +768,24 @@ InputMethodContext::CallbackData Controller::EventHandler::OnInputMethodContextE { case InputMethodContext::COMMIT: { - controller.InsertText(inputMethodContextEvent.predictiveString, Text::Controller::COMMIT); + TextUpdater::InsertText(controller, inputMethodContextEvent.predictiveString, Text::Controller::COMMIT); requestRelayout = true; retrieveCursor = true; break; } case InputMethodContext::PRE_EDIT: { - controller.InsertText(inputMethodContextEvent.predictiveString, Text::Controller::PRE_EDIT); + TextUpdater::InsertText(controller, inputMethodContextEvent.predictiveString, Text::Controller::PRE_EDIT); requestRelayout = true; retrieveCursor = true; break; } case InputMethodContext::DELETE_SURROUNDING: { - const bool textDeleted = controller.RemoveText(inputMethodContextEvent.cursorOffset, - inputMethodContextEvent.numberOfChars, - DONT_UPDATE_INPUT_STYLE); + const bool textDeleted = TextUpdater::RemoveText(controller, + inputMethodContextEvent.cursorOffset, + inputMethodContextEvent.numberOfChars, + DONT_UPDATE_INPUT_STYLE); if(textDeleted) { @@ -707,7 +796,7 @@ InputMethodContext::CallbackData Controller::EventHandler::OnInputMethodContextE } else { - controller.ShowPlaceholderText(); + PlaceholderHandler::ShowPlaceholderText(*controller.mImpl); } controller.mImpl->mEventData->mUpdateCursorPosition = true; controller.mImpl->mEventData->mScrollAfterDelete = true; @@ -729,6 +818,21 @@ InputMethodContext::CallbackData Controller::EventHandler::OnInputMethodContextE retrieveCursor = true; break; } + case InputMethodContext::SELECTION_SET: + { + uint32_t start = static_cast(inputMethodContextEvent.startIndex); + uint32_t end = static_cast(inputMethodContextEvent.endIndex); + if(start == end) + { + controller.SetPrimaryCursorPosition(start, true); + } + else + { + controller.SelectText(start, end); + } + + break; + } case InputMethodContext::VOID: { // do nothing @@ -802,7 +906,7 @@ void Controller::EventHandler::PasteClipboardItemEvent(Controller& controller) controller.mImpl->SetClipboardHideEnable(false); // Paste - controller.PasteText(stringToPaste); + TextUpdater::PasteText(controller, stringToPaste); controller.mImpl->SetClipboardHideEnable(true); } @@ -872,43 +976,17 @@ void Controller::EventHandler::TextPopupButtonTouched(Controller& controller, Da { case Toolkit::TextSelectionPopup::CUT: { - if(!controller.IsEditable()) return; - controller.mImpl->SendSelectionToClipboard(true); // Synchronous call to modify text - controller.mImpl->mOperationsPending = ALL_OPERATIONS; - - if((0u != controller.mImpl->mModel->mLogicalModel->mText.Count()) || - !controller.mImpl->IsPlaceholderAvailable()) - { - controller.mImpl->QueueModifyEvent(ModifyEvent::TEXT_DELETED); - } - else - { - controller.ShowPlaceholderText(); - } - - controller.mImpl->mEventData->mUpdateCursorPosition = true; - controller.mImpl->mEventData->mScrollAfterDelete = true; - - controller.mImpl->RequestRelayout(); - - if(NULL != controller.mImpl->mEditableControlInterface) - { - controller.mImpl->mEditableControlInterface->TextChanged(true); - } + controller.CutText(); break; } case Toolkit::TextSelectionPopup::COPY: { - controller.mImpl->SendSelectionToClipboard(false); // Text not modified - - controller.mImpl->mEventData->mUpdateCursorPosition = true; - - controller.mImpl->RequestRelayout(); // Cursor, Handles, Selection Highlight, Popup + controller.CopyText(); break; } case Toolkit::TextSelectionPopup::PASTE: { - controller.mImpl->RequestGetTextFromClipboard(); // Request clipboard service to retrieve an item + controller.PasteText(); break; } case Toolkit::TextSelectionPopup::SELECT: @@ -918,14 +996,14 @@ void Controller::EventHandler::TextPopupButtonTouched(Controller& controller, Da if(controller.mImpl->mEventData->mSelectionEnabled) { // Creates a SELECT event. - controller.SelectEvent(currentCursorPosition.x, currentCursorPosition.y, SelectionType::INTERACTIVE); + SelectEvent(controller, currentCursorPosition.x, currentCursorPosition.y, SelectionType::INTERACTIVE); } break; } case Toolkit::TextSelectionPopup::SELECT_ALL: { // Creates a SELECT_ALL event - controller.SelectEvent(0.f, 0.f, SelectionType::ALL); + SelectEvent(controller, 0.f, 0.f, SelectionType::ALL); break; } case Toolkit::TextSelectionPopup::CLIPBOARD: