/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
const std::string KEY_C_NAME = "c";
const std::string KEY_V_NAME = "v";
const std::string KEY_X_NAME = "x";
+const std::string KEY_A_NAME = "a";
+const std::string KEY_INSERT_NAME = "Insert";
const char * const PLACEHOLDER_TEXT = "text";
const char * const PLACEHOLDER_TEXT_FOCUSED = "textFocused";
}
ControllerPtr Controller::New( ControlInterface* controlInterface,
- EditableControlInterface* editableControlInterface )
+ EditableControlInterface* editableControlInterface,
+ SelectableControlInterface* selectableControlInterface )
{
return ControllerPtr( new Controller( controlInterface,
- editableControlInterface ) );
+ editableControlInterface,
+ selectableControlInterface ) );
}
// public : Configure the text controller.
DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
mImpl->mFontDefaults->familyDefined = !defaultFontFamily.empty();
+ if( mImpl->mEventData )
+ {
+ // Update the cursor position if it's in editing mode
+ if( EventData::IsEditingState( mImpl->mEventData->mState ) )
+ {
+ mImpl->mEventData->mDecoratorUpdated = true;
+ mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font family is updated.
+ }
+ }
+
// Clear the font-specific data
ClearFontData();
mImpl->mFontDefaults->mFontDescription.weight = weight;
mImpl->mFontDefaults->weightDefined = true;
+ if( mImpl->mEventData )
+ {
+ // Update the cursor position if it's in editing mode
+ if( EventData::IsEditingState( mImpl->mEventData->mState ) )
+ {
+ mImpl->mEventData->mDecoratorUpdated = true;
+ mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font weight is updated.
+ }
+ }
+
// Clear the font-specific data
ClearFontData();
mImpl->mFontDefaults->mFontDescription.width = width;
mImpl->mFontDefaults->widthDefined = true;
+ if( mImpl->mEventData )
+ {
+ // Update the cursor position if it's in editing mode
+ if( EventData::IsEditingState( mImpl->mEventData->mState ) )
+ {
+ mImpl->mEventData->mDecoratorUpdated = true;
+ mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font width is updated.
+ }
+ }
+
// Clear the font-specific data
ClearFontData();
mImpl->mFontDefaults->mFontDescription.slant = slant;
mImpl->mFontDefaults->slantDefined = true;
+ if( mImpl->mEventData )
+ {
+ // Update the cursor position if it's in editing mode
+ if( EventData::IsEditingState( mImpl->mEventData->mState ) )
+ {
+ mImpl->mEventData->mDecoratorUpdated = true;
+ mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font slant is updated.
+ }
+ }
+
// Clear the font-specific data
ClearFontData();
}
}
+ if( mImpl->mEventData )
+ {
+ // Update the cursor position if it's in editing mode
+ if( EventData::IsEditingState( mImpl->mEventData->mState ) )
+ {
+ mImpl->mEventData->mDecoratorUpdated = true;
+ mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
+ }
+ }
+
// Clear the font-specific data
ClearFontData();
return mImpl->mLayoutEngine.GetDefaultLineSpacing();
}
+bool Controller::SetDefaultLineSize( float lineSize )
+{
+ if( std::fabs( lineSize - mImpl->mLayoutEngine.GetDefaultLineSize() ) > Math::MACHINE_EPSILON_1000 )
+ {
+ mImpl->mLayoutEngine.SetDefaultLineSize(lineSize);
+ mImpl->mRecalculateNaturalSize = true;
+ return true;
+ }
+ return false;
+}
+
+float Controller::GetDefaultLineSize() const
+{
+ return mImpl->mLayoutEngine.GetDefaultLineSize();
+}
+
void Controller::SetInputColor( const Vector4& color )
{
if( NULL != mImpl->mEventData )
bool relayoutNeeded = false;
if( ( NULL != mImpl->mEventData ) &&
- ( keyEvent.state == KeyEvent::Down ) )
+ ( keyEvent.GetState() == KeyEvent::DOWN ) )
{
- int keyCode = keyEvent.keyCode;
- const std::string& keyString = keyEvent.keyPressed;
- const std::string keyName = keyEvent.keyPressedName;
+ int keyCode = keyEvent.GetKeyCode();
+ const std::string& keyString = keyEvent.GetKeyString();
+ const std::string keyName = keyEvent.GetKeyName();
const bool isNullKey = ( 0 == keyCode ) && ( keyString.empty() );
// Do nothing
return false;
}
- else if ( keyEvent.IsCtrlModifier() )
+ else if ( keyEvent.IsCtrlModifier() && !keyEvent.IsShiftModifier())
{
bool consumed = false;
- if (keyName == KEY_C_NAME)
+ if (keyName == KEY_C_NAME || keyName == KEY_INSERT_NAME)
{
- // Ctrl-C to copy the selected text
+ // Ctrl-C or Ctrl+Insert to copy the selected text
TextPopupButtonTouched( Toolkit::TextSelectionPopup::COPY );
consumed = true;
}
TextPopupButtonTouched( Toolkit::TextSelectionPopup::CUT );
consumed = true;
}
+ else if (keyName == KEY_A_NAME)
+ {
+ // Ctrl-A to select All the text
+ TextPopupButtonTouched( Toolkit::TextSelectionPopup::SELECT_ALL );
+ consumed = true;
+ }
return consumed;
}
else if( ( Dali::DALI_KEY_BACKSPACE == keyCode ) ||
else
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::KeyEvent %p keyString %s\n", this, keyString.c_str() );
+ if (!IsEditable()) return false;
if( !keyString.empty() )
{
mImpl->ResetInputMethodContext();
}
-void Controller::PanEvent( Gesture::State state, const Vector2& displacement )
+void Controller::PanEvent( GestureState state, const Vector2& displacement )
{
DALI_ASSERT_DEBUG( mImpl->mEventData && "Unexpected PanEvent" );
if( NULL != mImpl->mEventData )
{
Event event( Event::PAN_EVENT );
- event.p1.mInt = state;
+ event.p1.mInt = static_cast<int>( state );
event.p2.mFloat = displacement.x;
event.p3.mFloat = displacement.y;
mImpl->mEventData->mEventQueue.push_back( event );
}
}
-void Controller::LongPressEvent( Gesture::State state, float x, float y )
+void Controller::LongPressEvent( GestureState state, float x, float y )
{
DALI_ASSERT_DEBUG( mImpl->mEventData && "Unexpected LongPressEvent" );
- if( ( state == Gesture::Started ) &&
+ if( ( state == GestureState::STARTED ) &&
( NULL != mImpl->mEventData ) )
{
// The 1st long-press on inactive text-field is treated as tap
else if( !mImpl->IsShowingRealText() )
{
Event event( Event::LONG_PRESS_EVENT );
- event.p1.mInt = state;
+ event.p1.mInt = static_cast<int>( state );
event.p2.mFloat = x;
event.p3.mFloat = y;
mImpl->mEventData->mEventQueue.push_back( event );
mImpl->ResetInputMethodContext();
Event event( Event::LONG_PRESS_EVENT );
- event.p1.mInt = state;
+ event.p1.mInt = static_cast<int>( state );
event.p2.mFloat = x;
event.p3.mFloat = y;
mImpl->mEventData->mEventQueue.push_back( event );
}
}
+void Controller::SetTextSelectionRange(const uint32_t *start, const uint32_t *end)
+{
+ if( mImpl->mEventData )
+ {
+ mImpl->mEventData->mCheckScrollAmount = true;
+ mImpl->mEventData->mIsLeftHandleSelected = true;
+ mImpl->mEventData->mIsRightHandleSelected = true;
+ mImpl->SetTextSelectionRange(start, end);
+ mImpl->RequestRelayout();
+ KeyboardFocusGainEvent();
+ }
+}
+
+Uint32Pair Controller::GetTextSelectionRange() const
+{
+ return mImpl->GetTextSelectionRange();
+}
+
+void Controller::SelectWholeText()
+{
+ SelectEvent( 0.f, 0.f, SelectionType::ALL );
+}
+
+void Controller::SelectNone()
+{
+ SelectEvent( 0.f, 0.f, SelectionType::NONE );
+}
+
+string Controller::GetSelectedText() const
+{
+ string text;
+ if( EventData::SELECTING == mImpl->mEventData->mState )
+ {
+ mImpl->RetrieveSelection( text, false );
+ }
+ return text;
+}
+
InputMethodContext::CallbackData Controller::OnInputMethodContextEvent( InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent )
{
// Whether the text needs to be relaid-out.
}
}
+bool Controller::IsEditable() const
+{
+ return mImpl->IsEditable();
+}
+
+void Controller::SetEditable( bool editable )
+{
+ mImpl->SetEditable( editable );
+ if(mImpl->mEventData && mImpl->mEventData->mDecorator)
+ {
+ mImpl->mEventData->mDecorator->SetEditable( editable );
+ }
+}
+
void Controller::DecorationEvent( HandleType handleType, HandleState state, float x, float y )
{
DALI_ASSERT_DEBUG( mImpl->mEventData && "Unexpected DecorationEvent" );
{
case Toolkit::TextSelectionPopup::CUT:
{
+ if (!IsEditable()) return;
mImpl->SendSelectionToClipboard( true ); // Synchronous call to modify text
mImpl->mOperationsPending = ALL_OPERATIONS;
if( ( currentText.Count() - numberOfCharacters == 0 ) && ( cursorIndex == 0 ) )
{
mImpl->ClearPreEditFlag();
+ mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = 0;
}
// Updates the text style runs by removing characters. Runs with no characters are removed.
return textRemoved;
}
-std::string Controller::GetSelectedText()
-{
- std::string text;
- if( EventData::SELECTING == mImpl->mEventData->mState )
- {
- mImpl->RetrieveSelection( text, false );
- }
- return text;
-}
-
// private : Relayout.
bool Controller::DoRelayout( const Size& size,
mImpl->mEventData->mRightSelectionPosition = mImpl->mEventData->mPrimaryCursorPosition;
}
- // Discard temporary text
+ // DISCARD temporary text
events.Clear();
}
return;
}
+ if (!IsEditable()) return;
+
mImpl->mEventData->mCheckScrollAmount = true;
// The natural size needs to be re-calculated.
return removed;
}
+ if (!IsEditable()) return false;
+
// InputMethodContext is no longer handling key-events
mImpl->ClearPreEditFlag();
Controller::Controller()
: mImpl( NULL )
{
- mImpl = new Controller::Impl( NULL, NULL );
+ mImpl = new Controller::Impl( nullptr, nullptr, nullptr );
}
Controller::Controller( ControlInterface* controlInterface )
{
- mImpl = new Controller::Impl( controlInterface, NULL );
+ mImpl = new Controller::Impl( controlInterface, NULL, NULL );
}
Controller::Controller( ControlInterface* controlInterface,
- EditableControlInterface* editableControlInterface )
+ EditableControlInterface* editableControlInterface,
+ SelectableControlInterface* selectableControlInterface )
{
mImpl = new Controller::Impl( controlInterface,
- editableControlInterface );
+ editableControlInterface,
+ selectableControlInterface );
}
// The copy constructor and operator are left unimplemented.