application.GetScene().Add(actor);
- application.SendNotification();
- application.Render();
-
- // Trigger count is 1 - render the first frame
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
-
Property::Map attributes;
DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes);
application.SendNotification();
application.Render();
- // Wait for calculating frame drops
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ // Trigger count is 2 - render the first frame & calculating frame drops
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
// Check dropped frame
uint32_t frames = Test::VectorAnimationRenderer::GetDroppedFrames();
static bool gInputFilteredRejectedCallbackCalled;
static bool gInputStyleChangedCallbackCalled;
static bool gMaxCharactersCallBackCalled;
+static bool gCursorPositionChangedCallbackCalled;
+static uint32_t oldCursorPos;
static Dali::Toolkit::TextEditor::InputStyle::Mask gInputStyleMask;
struct CallbackFunctor
}
}
+static void TestCursorPositionChangedCallback( TextEditor control, unsigned int oldPos )
+{
+ tet_infoline(" TestCursorPositionChangedCallback");
+
+ gCursorPositionChangedCallbackCalled = true;
+ oldCursorPos = oldPos;
+}
+
static void TestTextChangedCallback( TextEditor control )
{
tet_infoline(" TestTextChangedCallback");
application.SendNotification();
application.Render();
+ // Check the line size property
+ DALI_TEST_EQUALS( editor.GetProperty<float>( DevelTextEditor::Property::MIN_LINE_SIZE ), 0.0f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ editor.SetProperty( DevelTextEditor::Property::MIN_LINE_SIZE, 50.f );
+ DALI_TEST_EQUALS( editor.GetProperty<float>( DevelTextEditor::Property::MIN_LINE_SIZE ), 50.0f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
END_TEST;
}
DALI_TEST_EQUALS( textEditor.GetProperty< int >( DevelTextEditor::Property::ELLIPSIS_POSITION ), static_cast< int >( Toolkit::DevelText::EllipsisPosition::END ), TEST_LOCATION );
END_TEST;
+}
+
+int UtcDaliTextEditorLineSpacing(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextEditorLineSpacing ");
+
+ TextEditor textEditor = TextEditor::New();
+ textEditor.SetProperty( Actor::Property::SIZE, Vector2( 400.0f, 400.f ) );
+ application.GetScene().Add( textEditor );
+ application.SendNotification();
+ application.Render();
+
+ textEditor.SetProperty( TextEditor::Property::TEXT, "Line #1\nLine #2\nLine #3" );
+ textEditor.SetProperty( DevelTextEditor::Property::LINE_SPACING, 0 );
+
+ Vector3 sizeBefore = textEditor.GetNaturalSize();
+
+ textEditor.SetProperty( DevelTextEditor::Property::LINE_SPACING, 20 );
+
+ //add 20 for each line 20 * 3
+ DALI_TEST_EQUALS(sizeBefore.height + 60.0f, textEditor.GetNaturalSize().height, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliTextEditorMinLineSize(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextEditorMinLineSize ");
+
+ TextEditor textEditor = TextEditor::New();
+ textEditor.SetProperty( Actor::Property::SIZE, Vector2( 400.0f, 400.f ) );
+ application.GetScene().Add( textEditor );
+ application.SendNotification();
+ application.Render();
+
+ textEditor.SetProperty( TextEditor::Property::TEXT, "Line #1\nLine #2\nLine #3" );
+ textEditor.SetProperty( DevelTextEditor::Property::MIN_LINE_SIZE, 0 );
+
+ Vector3 sizeBefore = textEditor.GetNaturalSize();
+
+ textEditor.SetProperty( DevelTextEditor::Property::MIN_LINE_SIZE, 60 );
+
+ DALI_TEST_NOT_EQUALS( sizeBefore, textEditor.GetNaturalSize(), 0.0f, TEST_LOCATION);
+
+ //60 * 3 lines
+ DALI_TEST_EQUALS(180.0f, textEditor.GetNaturalSize().height, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int utcDaliTextEditorCursorPositionChangedSignal(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextEditorCursorPositionChangedSignal");
+
+ TextEditor editor = TextEditor::New();
+ DALI_TEST_CHECK( editor );
+
+ application.GetScene().Add( editor );
+
+ // connect to the selection changed signal.
+ ConnectionTracker* testTracker = new ConnectionTracker();
+ DevelTextEditor::CursorPositionChangedSignal(editor).Connect(&TestCursorPositionChangedCallback);
+ bool cursorPositionChangedSignal = false;
+ editor.ConnectSignal( testTracker, "cursorPositionChanged", CallbackFunctor(&cursorPositionChangedSignal) );
+
+ editor.SetProperty( TextEditor::Property::TEXT, "Hello\nworld\nHello world" );
+ editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f );
+ editor.SetProperty( Actor::Property::SIZE, Vector2( 100.f, 50.f ) );
+ editor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+ editor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ editor.SetKeyInputFocus();
+
+ // Tap on the text editor
+ TestGenerateTap( application, 3.0f, 25.0f );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gCursorPositionChangedCallbackCalled);
+ DALI_TEST_EQUALS(oldCursorPos, 23, TEST_LOCATION);
+
+ gCursorPositionChangedCallbackCalled = false;
+
+ // Move to left.
+ application.ProcessEvent( GenerateKey( "", "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gCursorPositionChangedCallbackCalled);
+ DALI_TEST_EQUALS(oldCursorPos, 18, TEST_LOCATION);
+
+ gCursorPositionChangedCallbackCalled = false;
+
+ // Insert C
+ application.ProcessEvent( GenerateKey( "c", "", "c", KEY_C_CODE, 0, 0, Integration::KeyEvent::DOWN, "c", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gCursorPositionChangedCallbackCalled);
+ DALI_TEST_EQUALS(oldCursorPos, 17, TEST_LOCATION);
+
+ gCursorPositionChangedCallbackCalled = false;
+
+ //delete one character
+ application.ProcessEvent( GenerateKey( "", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gCursorPositionChangedCallbackCalled);
+ DALI_TEST_EQUALS(oldCursorPos, 18, TEST_LOCATION);
+
+ gCursorPositionChangedCallbackCalled = false;
+
+ editor.SetProperty( TextEditor::Property::TEXT, "Hello" );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gCursorPositionChangedCallbackCalled);
+ DALI_TEST_EQUALS(oldCursorPos, 17, TEST_LOCATION);
+
+ gCursorPositionChangedCallbackCalled = false;
+
+ editor.SetProperty( DevelTextEditor::Property::PRIMARY_CURSOR_POSITION, 3);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gCursorPositionChangedCallbackCalled);
+ DALI_TEST_EQUALS(oldCursorPos, 5, TEST_LOCATION);
+
+ END_TEST;
}
\ No newline at end of file
static bool gInputFilteredAcceptedCallbackCalled;
static bool gInputFilteredRejectedCallbackCalled;
static bool gInputStyleChangedCallbackCalled;
+static bool gCursorPositionChangedCallbackCalled;
+static uint32_t oldCursorPos;
static Dali::Toolkit::TextField::InputStyle::Mask gInputStyleMask;
static void LoadBitmapResource(TestPlatformAbstraction& platform, int width, int height)
}
}
+static void TestCursorPositionChangedCallback( TextField control, unsigned int oldPos )
+{
+ tet_infoline(" TestCursorPositionChangedCallback");
+
+ gCursorPositionChangedCallbackCalled = true;
+ oldCursorPos = oldPos;
+}
+
static void TestTextChangedCallback( TextField control )
{
tet_infoline(" TestTextChangedCallback");
DALI_TEST_EQUALS( textField.GetProperty< int >( DevelTextField::Property::ELLIPSIS_POSITION ), static_cast< int >( Toolkit::DevelText::EllipsisPosition::END ), TEST_LOCATION );
END_TEST;
+}
+
+int utcDaliTextFieldCursorPositionChangedSignal(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextFieldCursorPositionChangedSignal");
+
+ TextField field = TextField::New();
+ DALI_TEST_CHECK( field );
+
+ application.GetScene().Add( field );
+
+ // connect to the selection changed signal.
+ ConnectionTracker* testTracker = new ConnectionTracker();
+ DevelTextField::CursorPositionChangedSignal(field).Connect(&TestCursorPositionChangedCallback);
+ bool cursorPositionChangedSignal = false;
+ field.ConnectSignal( testTracker, "cursorPositionChanged", CallbackFunctor(&cursorPositionChangedSignal) );
+
+ field.SetProperty( TextField::Property::TEXT, "Hello world Hello world" );
+ field.SetProperty( TextField::Property::POINT_SIZE, 10.f );
+ field.SetProperty( Actor::Property::SIZE, Vector2( 100.f, 50.f ) );
+ field.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+ field.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ field.SetKeyInputFocus();
+
+ // Tap on the text field
+ TestGenerateTap( application, 3.0f, 25.0f );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gCursorPositionChangedCallbackCalled);
+ DALI_TEST_EQUALS(oldCursorPos, 23, TEST_LOCATION);
+
+ gCursorPositionChangedCallbackCalled = false;
+
+ // Move to left.
+ application.ProcessEvent( GenerateKey( "", "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gCursorPositionChangedCallbackCalled);
+ DALI_TEST_EQUALS(oldCursorPos, 17, TEST_LOCATION);
+
+ gCursorPositionChangedCallbackCalled = false;
+
+ // Insert D
+ application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gCursorPositionChangedCallbackCalled);
+ DALI_TEST_EQUALS(oldCursorPos, 16, TEST_LOCATION);
+
+ gCursorPositionChangedCallbackCalled = false;
+
+ //delete one character
+ application.ProcessEvent( GenerateKey( "", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gCursorPositionChangedCallbackCalled);
+ DALI_TEST_EQUALS(oldCursorPos, 17, TEST_LOCATION);
+
+ gCursorPositionChangedCallbackCalled = false;
+
+ field.SetProperty( TextField::Property::TEXT, "Hello" );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gCursorPositionChangedCallbackCalled);
+ DALI_TEST_EQUALS(oldCursorPos, 16, TEST_LOCATION);
+
+ gCursorPositionChangedCallbackCalled = false;
+
+ field.SetProperty(DevelTextField::Property::PRIMARY_CURSOR_POSITION, 3);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(gCursorPositionChangedCallbackCalled);
+ DALI_TEST_EQUALS(oldCursorPos, 5, TEST_LOCATION);
+
+ END_TEST;
}
\ No newline at end of file
return GetImpl(textEditor).AnchorClickedSignal();
}
+CursorPositionChangedSignalType& CursorPositionChangedSignal(TextEditor textEditor)
+{
+ return GetImpl(textEditor).CursorPositionChangedSignal();
+}
+
InputFilteredSignalType& InputFilteredSignal(TextEditor textEditor)
{
return GetImpl(textEditor).InputFilteredSignal();
* @see DevelText::EllipsisPosition
*/
ELLIPSIS_POSITION,
+
+ /**
+ * @brief Sets the height of the line in points.
+ * @details Name "minLineSize", type Property::FLOAT.
+ * @note If the font size is larger than the line size, it works with the font size.
+ */
+ MIN_LINE_SIZE,
};
} // namespace Property
DALI_TOOLKIT_API AnchorClickedSignalType& AnchorClickedSignal(TextEditor textEditor);
/**
+ * @brief cursor position changed signal type.
+ *
+ * @note Signal
+ * - uint32_t : old position.
+ */
+using CursorPositionChangedSignalType = Signal<void(TextEditor, uint32_t)>;
+
+/**
+ * @brief This signal is emitted when the cursor position has been changed.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ * void YourCallbackName(TextEditor textEditor, uint32_t oldPosition);
+ * @endcode
+ * @param[in] textEditor The instance of TextEditor.
+ * @return The signal to connect to.
+ */
+DALI_TOOLKIT_API CursorPositionChangedSignalType& CursorPositionChangedSignal(TextEditor textEditor);
+
+/**
* @brief Input filtered signal type.
*/
using InputFilteredSignalType = Signal<void(TextEditor, Toolkit::InputFilter::Property::Type)>;
return GetImpl(textField).AnchorClickedSignal();
}
+CursorPositionChangedSignalType& CursorPositionChangedSignal(TextField textField)
+{
+ return GetImpl(textField).CursorPositionChangedSignal();
+}
+
InputFilteredSignalType& InputFilteredSignal(TextField textField)
{
return GetImpl(textField).InputFilteredSignal();
DALI_TOOLKIT_API AnchorClickedSignalType& AnchorClickedSignal(TextField textField);
/**
+ * @brief cursor position changed signal type.
+ *
+ * @note Signal
+ * - uint32_t : old position.
+ */
+using CursorPositionChangedSignalType = Signal<void(TextField, uint32_t)>;
+
+/**
+ * @brief This signal is emitted when the cursor position has been changed.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ * void YourCallbackName(TextField textField, uint32_t oldPosition);
+ * @endcode
+ * @param[in] textField The instance of TextField.
+ * @return The signal to connect to.
+ */
+DALI_TOOLKIT_API CursorPositionChangedSignalType& CursorPositionChangedSignal(TextField textField);
+
+/**
* @brief Input filtered signal type.
*/
using InputFilteredSignalType = Signal<void(TextField, Toolkit::InputFilter::Property::Type)>;
{
Length finalNumberOfGlyphs = 0u;
- if((line.ascender - line.descender) > textLayoutArea.height)
+ if((GetLineHeight(line)) > textLayoutArea.height)
{
// The height of the line is bigger than the height of the text area.
// Show the ellipsis glyph even if it doesn't fit in the text area.
const LineRun& line = *(lines.Begin() + index);
numberOfCharacters += line.characterRun.numberOfCharacters;
- lineOffset = lineSize > 0.f ? lineSize : (line.ascender + -line.descender);
+ lineOffset = lineSize > 0.f ? lineSize : GetLineHeight(line);
penY += lineOffset;
if((penY + lineOffset) > boundingBox)
{
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "inputFilter", MAP, INPUT_FILTER )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "ellipsis", BOOLEAN, ELLIPSIS )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "ellipsisPosition", INTEGER, ELLIPSIS_POSITION )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "minLineSize", FLOAT, MIN_LINE_SIZE )
-DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED )
-DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED)
-DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED )
-DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "anchorClicked", SIGNAL_ANCHOR_CLICKED )
-DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputFiltered", SIGNAL_INPUT_FILTERED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "anchorClicked", SIGNAL_ANCHOR_CLICKED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputFiltered", SIGNAL_INPUT_FILTERED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "cursorPositionChanged", SIGNAL_CURSOR_POSITION_CHANGED)
DALI_TYPE_REGISTRATION_END()
}
case Toolkit::TextEditor::Property::LINE_SPACING:
{
- // The line spacing isn't supported by the TextEditor. Since it's supported
- // by the TextLabel for now it must be ignored. The property is being shadowed
- // locally so its value isn't affected.
const float lineSpacing = value.Get<float>();
- impl.mLineSpacing = lineSpacing;
- // set it to 0.0 due to missing implementation
- impl.mController->SetDefaultLineSpacing(0.0f);
+ impl.mController->SetDefaultLineSpacing(lineSpacing);
impl.mRenderer.Reset();
break;
}
}
break;
}
+ case Toolkit::DevelTextEditor::Property::MIN_LINE_SIZE:
+ {
+ const float minLineSize = value.Get<float>();
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextEditor %p MIN_LINE_SIZE %f\n", impl.mController.Get(), minLineSize);
+
+ impl.mController->SetDefaultLineSize(minLineSize);
+ impl.mRenderer.Reset();
+ break;
+ }
} // switch
} // texteditor
}
}
case Toolkit::TextEditor::Property::LINE_SPACING:
{
- // LINE_SPACING isn't implemented for the TextEditor. Returning
- // only shadowed value, not the real one.
- value = impl.mLineSpacing;
+ value = impl.mController->GetDefaultLineSpacing();
break;
}
case Toolkit::TextEditor::Property::INPUT_LINE_SPACING:
value = impl.mController->GetEllipsisPosition();
break;
}
+ case Toolkit::DevelTextEditor::Property::MIN_LINE_SIZE:
+ {
+ value = impl.mController->GetDefaultLineSize();
+ break;
+ }
} //switch
}
return mAnchorClickedSignal;
}
+DevelTextEditor::CursorPositionChangedSignalType& TextEditor::CursorPositionChangedSignal()
+{
+ return mCursorPositionChangedSignal;
+}
+
DevelTextEditor::InputFilteredSignalType& TextEditor::InputFilteredSignal()
{
return mInputFilteredSignal;
editorImpl.AnchorClickedSignal().Connect(tracker, functor);
}
}
+ else if(0 == strcmp(signalName.c_str(), SIGNAL_CURSOR_POSITION_CHANGED))
+ {
+ if(editor)
+ {
+ Internal::TextEditor& editorImpl(GetImpl(editor));
+ editorImpl.CursorPositionChangedSignal().Connect(tracker, functor);
+ }
+ }
else if(0 == strcmp(signalName.c_str(), SIGNAL_INPUT_FILTERED))
{
if(editor)
RenderText(updateTextType);
}
+ if(mCursorPositionChanged)
+ {
+ EmitCursorPositionChangedSignal();
+ }
+
// The text-editor emits signals when the input style changes. These changes of style are
// detected during the relayout process (size negotiation), i.e after the cursor has been moved. Signals
// can't be emitted during the size negotiation as the callbacks may update the UI.
}
}
-void TextEditor::CursorMoved(unsigned int position)
+void TextEditor::CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition)
{
if(Accessibility::IsUp())
{
- Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(position);
+ Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(newPosition);
+ }
+
+ if((oldPosition != newPosition) && !mCursorPositionChanged)
+ {
+ mCursorPositionChanged = true;
+ mOldPosition = oldPosition;
}
}
mAnchorClickedSignal.Emit(handle, href.c_str(), href.length());
}
+void TextEditor::EmitCursorPositionChangedSignal()
+{
+ Dali::Toolkit::TextEditor handle(GetOwner());
+ mCursorPositionChanged = false;
+ mCursorPositionChangedSignal.Emit(handle, mOldPosition);
+}
+
void TextEditor::InputFiltered(Toolkit::InputFilter::Property::Type type)
{
Dali::Toolkit::TextEditor handle(GetOwner());
mScrollAnimationEnabled(false),
mScrollBarEnabled(false),
mScrollStarted(false),
- mTextChanged(false)
+ mTextChanged(false),
+ mCursorPositionChanged(false)
{
}
return true;
}
-Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset( size_t offset, Dali::Accessibility::TextBoundary boundary)
+Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset(size_t offset, Dali::Accessibility::TextBoundary boundary)
{
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
+ auto self = Toolkit::TextEditor::DownCast(Self());
+ auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
auto textSize = text.size();
auto range = Dali::Accessibility::Range{};
case Dali::Accessibility::TextBoundary::LINE:
{
auto textString = text.c_str();
- auto breaks = std::vector<char>(textSize, 0);
+ auto breaks = std::vector<char>(textSize, 0);
if(boundary == Dali::Accessibility::TextBoundary::WORD)
{
return {};
}
- auto self = Toolkit::TextEditor::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
+ auto self = Toolkit::TextEditor::DownCast(Self());
+ auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
std::string value{};
controller->RetrieveSelection(value);
auto indices = controller->GetSelectionIndexes();
{
using namespace Dali::Accessibility;
- auto states = DevelControl::AccessibleImpl::CalculateStates();
+ auto states = DevelControl::AccessibleImpl::CalculateStates();
states[State::EDITABLE] = true;
states[State::FOCUSABLE] = true;
bool TextEditor::AccessibleImpl::InsertText(size_t startPosition, std::string text)
{
- auto self = Toolkit::TextEditor::DownCast(Self());
+ auto self = Toolkit::TextEditor::DownCast(Self());
auto insertedText = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
insertedText.insert(startPosition, text);
DevelTextEditor::AnchorClickedSignalType& AnchorClickedSignal();
/**
+ * @copydoc Dali::Toollkit::TextEditor::CursorPositionChangedSignal()
+ */
+ DevelTextEditor::CursorPositionChangedSignalType& CursorPositionChangedSignal();
+
+ /**
* @copydoc Dali::Toollkit::TextEditor::InputFilteredSignal()
*/
DevelTextEditor::InputFilteredSignalType& InputFilteredSignal();
void TextDeleted(unsigned int position, unsigned int length, const std::string& content) override;
/**
- * @copydoc Text::EditableControlInterface::CursorMoved()
+ * @copydoc Text::EditableControlInterface::CursorPositionChanged()
*/
- void CursorMoved(unsigned int position) override;
+ void CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition) override;
/**
* @copydoc Text::EditableControlInterface::TextChanged()
void OnIdleSignal();
/**
+ * @brief Emits CursorPositionChanged signal.
+ */
+ void EmitCursorPositionChangedSignal();
+
+ /**
* @brief Emits TextChanged signal.
*/
void EmitTextChangedSignal();
private: // Data
// Signals
- Toolkit::TextEditor::TextChangedSignalType mTextChangedSignal;
- Toolkit::TextEditor::InputStyleChangedSignalType mInputStyleChangedSignal;
- Toolkit::TextEditor::ScrollStateChangedSignalType mScrollStateChangedSignal;
- Toolkit::DevelTextEditor::MaxLengthReachedSignalType mMaxLengthReachedSignal;
- Toolkit::DevelTextEditor::AnchorClickedSignalType mAnchorClickedSignal;
- Toolkit::DevelTextEditor::InputFilteredSignalType mInputFilteredSignal;
+ Toolkit::TextEditor::TextChangedSignalType mTextChangedSignal;
+ Toolkit::TextEditor::InputStyleChangedSignalType mInputStyleChangedSignal;
+ Toolkit::TextEditor::ScrollStateChangedSignalType mScrollStateChangedSignal;
+ Toolkit::DevelTextEditor::MaxLengthReachedSignalType mMaxLengthReachedSignal;
+ Toolkit::DevelTextEditor::AnchorClickedSignalType mAnchorClickedSignal;
+ Toolkit::DevelTextEditor::InputFilteredSignalType mInputFilteredSignal;
+ Toolkit::DevelTextEditor::CursorPositionChangedSignalType mCursorPositionChangedSignal;
InputMethodContext mInputMethodContext;
Text::ControllerPtr mController;
bool mScrollAnimationEnabled : 1;
bool mScrollBarEnabled : 1;
bool mScrollStarted : 1;
- bool mTextChanged : 1; ///< If true, emits TextChangedSignal in next OnRelayout().
+ bool mTextChanged : 1; ///< If true, emits TextChangedSignal in next OnRelayout().
+ bool mCursorPositionChanged : 1; ///< If true, emits CursorPositionChangedSignal at the end of OnRelayout().
+
+ //args for cursor PositionChanged event
+ unsigned int mOldPosition;
/**
* @brief This structure is to connect TextEditor with Accessible functions.
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "inputFilter", MAP, INPUT_FILTER )
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "ellipsisPosition", INTEGER, ELLIPSIS_POSITION )
-DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "textChanged", SIGNAL_TEXT_CHANGED )
-DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED )
-DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED)
-DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "anchorClicked", SIGNAL_ANCHOR_CLICKED )
-DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "inputFiltered", SIGNAL_INPUT_FILTERED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "textChanged", SIGNAL_TEXT_CHANGED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "anchorClicked", SIGNAL_ANCHOR_CLICKED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "inputFiltered", SIGNAL_INPUT_FILTERED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "cursorPositionChanged", SIGNAL_CURSOR_POSITION_CHANGED)
DALI_TYPE_REGISTRATION_END()
// clang-format on
fieldImpl.AnchorClickedSignal().Connect(tracker, functor);
}
}
+ else if(0 == strcmp(signalName.c_str(), SIGNAL_CURSOR_POSITION_CHANGED))
+ {
+ if(field)
+ {
+ Internal::TextField& fieldImpl(GetImpl(field));
+ fieldImpl.CursorPositionChangedSignal().Connect(tracker, functor);
+ }
+ }
else if(0 == strcmp(signalName.c_str(), SIGNAL_INPUT_FILTERED))
{
if(field)
return mAnchorClickedSignal;
}
+DevelTextField::CursorPositionChangedSignalType& TextField::CursorPositionChangedSignal()
+{
+ return mCursorPositionChangedSignal;
+}
+
DevelTextField::InputFilteredSignalType& TextField::InputFilteredSignal()
{
return mInputFilteredSignal;
RenderText(updateTextType);
}
+ if(mCursorPositionChanged)
+ {
+ EmitCursorPositionChangedSignal();
+ }
+
// The text-field emits signals when the input style changes. These changes of style are
// detected during the relayout process (size negotiation), i.e after the cursor has been moved. Signals
// can't be emitted during the size negotiation as the callbacks may update the UI.
}
}
-void TextField::CursorMoved(unsigned int position)
+void TextField::CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition)
{
if(Accessibility::IsUp())
{
- Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(position);
+ Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(newPosition);
+ }
+
+ if((oldPosition != newPosition) && !mCursorPositionChanged)
+ {
+ mCursorPositionChanged = true;
+ mOldPosition = oldPosition;
}
}
mAnchorClickedSignal.Emit(handle, href.c_str(), href.length());
}
+void TextField::EmitCursorPositionChangedSignal()
+{
+ Dali::Toolkit::TextField handle(GetOwner());
+ mCursorPositionChangedSignal.Emit(handle, mOldPosition);
+ mCursorPositionChanged = false;
+}
+
void TextField::InputFiltered(Toolkit::InputFilter::Property::Type type)
{
Dali::Toolkit::TextField handle(GetOwner());
mRenderingBackend(DEFAULT_RENDERING_BACKEND),
mExceedPolicy(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP),
mHasBeenStaged(false),
- mTextChanged(false)
+ mTextChanged(false),
+ mCursorPositionChanged(false)
{
}
Dali::Accessibility::Range TextField::AccessibleImpl::GetTextAtOffset(
size_t offset, Dali::Accessibility::TextBoundary boundary)
{
- auto self = Toolkit::TextField::DownCast(Self());
- auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
+ auto self = Toolkit::TextField::DownCast(Self());
+ auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
auto textSize = text.size();
auto range = Dali::Accessibility::Range{};
case Dali::Accessibility::TextBoundary::LINE:
{
auto textString = text.c_str();
- auto breaks = std::vector<char>(textSize, 0);
+ auto breaks = std::vector<char>(textSize, 0);
if(boundary == Dali::Accessibility::TextBoundary::WORD)
{
return {};
}
- auto self = Toolkit::TextField::DownCast(Self());
- auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
+ auto self = Toolkit::TextField::DownCast(Self());
+ auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
std::string value{};
controller->RetrieveSelection(value);
auto indices = controller->GetSelectionIndexes();
bool TextField::AccessibleImpl::InsertText(size_t startPosition, std::string text)
{
- auto self = Toolkit::TextField::DownCast(Self());
+ auto self = Toolkit::TextField::DownCast(Self());
auto insertedText = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
insertedText.insert(startPosition, text);
DevelTextField::AnchorClickedSignalType& AnchorClickedSignal();
/**
+ * @copydoc TextField::CursorPositionChangedSignal()
+ */
+ DevelTextField::CursorPositionChangedSignalType& CursorPositionChangedSignal();
+
+ /**
* @copydoc TextField::InputFilteredSignal()
*/
DevelTextField::InputFilteredSignalType& InputFilteredSignal();
void TextDeleted(unsigned int position, unsigned int length, const std::string& content) override;
/**
- * @copydoc Text::EditableControlInterface::CursorMoved()
+ * @copydoc Text::EditableControlInterface::CursorPositionChanged()
*/
- void CursorMoved(unsigned int position) override;
+ void CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition) override;
/**
* @copydoc Text::EditableControlInterface::TextChanged()
void EmitTextChangedSignal();
/**
+ * @brief Emits CursorPositionChanged signal.
+ */
+ void EmitCursorPositionChangedSignal();
+
+ /**
* @brief Callback function for when the layout is changed.
* @param[in] actor The actor whose layoutDirection is changed.
* @param[in] type The layoutDirection.
private: // Data
// Signals
- Toolkit::TextField::TextChangedSignalType mTextChangedSignal;
- Toolkit::TextField::MaxLengthReachedSignalType mMaxLengthReachedSignal;
- Toolkit::TextField::InputStyleChangedSignalType mInputStyleChangedSignal;
- Toolkit::DevelTextField::AnchorClickedSignalType mAnchorClickedSignal;
- Toolkit::DevelTextField::InputFilteredSignalType mInputFilteredSignal;
+ Toolkit::TextField::TextChangedSignalType mTextChangedSignal;
+ Toolkit::TextField::MaxLengthReachedSignalType mMaxLengthReachedSignal;
+ Toolkit::TextField::InputStyleChangedSignalType mInputStyleChangedSignal;
+ Toolkit::DevelTextField::AnchorClickedSignalType mAnchorClickedSignal;
+ Toolkit::DevelTextField::InputFilteredSignalType mInputFilteredSignal;
+ Toolkit::DevelTextField::CursorPositionChangedSignalType mCursorPositionChangedSignal;
InputMethodContext mInputMethodContext;
Text::ControllerPtr mController;
int mRenderingBackend;
int mExceedPolicy;
bool mHasBeenStaged : 1;
- bool mTextChanged : 1; ///< If true, emits TextChangedSignal in next OnRelayout().
+ bool mTextChanged : 1; ///< If true, emits TextChangedSignal in next OnRelayout().
+ bool mCursorPositionChanged : 1; ///< If true, emits CursorPositionChangedSignal at the end of OnRelayout().
+
+ //args for cursor position changed event
+ unsigned int mOldPosition;
protected:
/**
{
const LineRun& lineRun = *it;
- // The line height is the addition of the line ascender and the line descender.
- // However, the line descender has a negative value, hence the subtraction.
- totalHeight += lineRun.ascender - lineRun.descender;
+ totalHeight += GetLineHeight(lineRun);
if(visualY < totalHeight)
{
{
const LineRun& lineRun = *it;
- // The line height is the addition of the line ascender and the line descender.
- // However, the line descender has a negative value, hence the subtraction.
- offset += lineRun.ascender - lineRun.descender;
+ offset += GetLineHeight(lineRun);
}
return offset;
cursorInfo.lineOffset = CalculateLineOffset(parameters.visualModel->mLines,
newLineIndex);
- // The line height is the addition of the line ascender and the line descender.
- // However, the line descender has a negative value, hence the subtraction.
- cursorInfo.lineHeight = newLine.ascender - newLine.descender;
+ cursorInfo.lineHeight = GetLineHeight(newLine);
// Set the primary cursor's height.
cursorInfo.primaryCursorHeight = cursorInfo.lineHeight;
cursorInfo.lineOffset = CalculateLineOffset(parameters.visualModel->mLines,
lineIndex);
- // The line height is the addition of the line ascender and the line descender.
- // However, the line descender has a negative value, hence the subtraction.
- cursorInfo.lineHeight = line.ascender - line.descender;
+ cursorInfo.lineHeight = GetLineHeight(line);
// Calculate the primary cursor.
{
namespace Text
{
+float GetLineHeight(const LineRun lineRun)
+{
+ // The line height is the addition of the line ascender, the line descender and the line spacing.
+ // However, the line descender has a negative value, hence the subtraction.
+ return lineRun.ascender - lineRun.descender + lineRun.lineSpacing;
+}
namespace Layout
{
namespace
layoutSize.width = layoutParameters.boundingBox.width;
if(layoutSize.height < Math::MACHINE_EPSILON_1000)
{
- layoutSize.height += (lineRun->ascender + -lineRun->descender) + lineRun->lineSpacing;
+ layoutSize.height += GetLineHeight(*lineRun);
}
const Vector<BidirectionalLineInfoRun>& bidirectionalLinesInfo = layoutParameters.textModel->mLogicalModel->mBidirectionalLineInfo;
layoutSize.width = lineRun.width;
}
- layoutSize.height += (lineRun.ascender + -lineRun.descender) + lineRun.lineSpacing;
+ layoutSize.height += GetLineHeight(lineRun);
}
/**
lineRun.lineSpacing += mDefaultLineSpacing;
- layoutSize.height += (lineRun.ascender + -lineRun.descender) + lineRun.lineSpacing;
+ layoutSize.height += GetLineHeight(lineRun);
}
/**
layoutSize.width = line.width;
}
- layoutSize.height += (line.ascender + -line.descender) + line.lineSpacing;
+ layoutSize.height += GetLineHeight(line);
}
}
CharacterRun characterRunForSecondHalfLine; ///< The initial character index and the number of characters of the run for the second half of line.
};
+/**
+ * @brief Get the line height for the specified line run.
+ *
+ * @param[in] lineRun The line runs to get the height for.
+ */
+float GetLineHeight(const LineRun lineRun);
+
} // namespace Text
} // namespace Toolkit
return false;
}
+ unsigned int oldPos = eventData->mPrimaryCursorPosition;
+
if(eventData->mDecorator)
{
for(std::vector<Event>::iterator iter = eventData->mEventQueue.begin();
{
// Updates the cursor position and scrolls the text to make it visible.
CursorInfo cursorInfo;
+
// Calculate the cursor position from the new cursor index.
impl.GetCursorPosition(eventData->mPrimaryCursorPosition, cursorInfo);
- if(nullptr != impl.mEditableControlInterface)
+ //only emit the event if the cursor is moved in current function.
+ if(nullptr != impl.mEditableControlInterface && eventData->mEventQueue.size() > 0)
{
- impl.mEditableControlInterface->CursorMoved(eventData->mPrimaryCursorPosition);
+ impl.mEditableControlInterface->CursorPositionChanged(oldPos, eventData->mPrimaryCursorPosition);
}
if(eventData->mUpdateCursorHookPosition)
const LineRun& line = *(visualModel->mLines.Begin() + previousLineIndex);
// Get the next hit 'y' point.
- const float hitPointY = cursorInfo.lineOffset - 0.5f * (line.ascender - line.descender);
+ const float hitPointY = cursorInfo.lineOffset - 0.5f * GetLineHeight(line);
// Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
bool matchedCharacter = false;
const LineRun& line = *(visualModel->mLines.Begin() + lineIndex + 1u);
// Get the next hit 'y' point.
- const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * (line.ascender - line.descender);
+ const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * GetLineHeight(line);
// Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
bool matchedCharacter = false;
}
uint32_t length = static_cast<uint32_t>(mModel->mLogicalModel->mText.Count());
+ uint32_t oldCursorPos = mEventData->mPrimaryCursorPosition;
mEventData->mPrimaryCursorPosition = std::min(index, length);
// If there is no focus, only the value is updated.
if(focused)
mEventData->mUpdateCursorPosition = true;
ScrollTextToMatchCursor();
}
+
+ if(nullptr != mEditableControlInterface)
+ {
+ mEditableControlInterface->CursorPositionChanged(oldCursorPos, mEventData->mPrimaryCursorPosition);
+ }
+
return true;
}
controller.ShowPlaceholderText();
}
+ unsigned int oldCursorPos = (nullptr != eventData ? eventData->mPrimaryCursorPosition : 0);
+
// Resets the cursor position.
controller.ResetCursorPosition(lastCursorIndex);
// Do this last since it provides callbacks into application code.
if(NULL != impl.mEditableControlInterface)
{
+ impl.mEditableControlInterface->CursorPositionChanged(oldCursorPos, lastCursorIndex);
impl.mEditableControlInterface->TextChanged(true);
}
}
return;
}
- bool removedPrevious = false;
- bool removedSelected = false;
- bool maxLengthReached = false;
+ bool removedPrevious = false;
+ bool removedSelected = false;
+ bool maxLengthReached = false;
+ unsigned int oldCursorPos = eventData->mPrimaryCursorPosition;
DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::InsertText %p %s (%s) mPrimaryCursorPosition %d mPreEditFlag %d mPreEditStartPosition %d mPreEditLength %d\n", &controller, text.c_str(), (COMMIT == type ? "COMMIT" : "PRE_EDIT"), eventData->mPrimaryCursorPosition, eventData->mPreEditFlag, eventData->mPreEditStartPosition, eventData->mPreEditLength);
}
}
+ if(nullptr != impl.mEditableControlInterface)
+ {
+ impl.mEditableControlInterface->CursorPositionChanged(oldCursorPos, eventData->mPrimaryCursorPosition);
+ }
+
if(maxLengthReached)
{
DALI_LOG_INFO(gLogFilter, Debug::Verbose, "MaxLengthReached (%d)\n", logicalModel->mText.Count());
RemoveTextAnchor(controller, cursorOffset, numberOfCharacters, previousCursorIndex);
}
+ if(nullptr != impl.mEditableControlInterface)
+ {
+ impl.mEditableControlInterface->CursorPositionChanged(previousCursorIndex, cursorIndex);
+ }
+
// Cursor position retreat
previousCursorIndex = cursorIndex;
return EMPTY_STRING;
}
+void Controller::RelayoutForNewLineSize()
+{
+ // relayout all characters
+ mImpl->mTextUpdateInfo.mCharacterIndex = 0;
+ mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
+ mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count();
+ mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | LAYOUT);
+
+ //remove selection
+ if((mImpl->mEventData != nullptr) && (mImpl->mEventData->mState == EventData::SELECTING))
+ {
+ mImpl->ChangeState(EventData::EDITING);
+ }
+
+ mImpl->RequestRelayout();
+}
+
bool Controller::SetDefaultLineSpacing(float lineSpacing)
{
if(std::fabs(lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing()) > Math::MACHINE_EPSILON_1000)
{
mImpl->mLayoutEngine.SetDefaultLineSpacing(lineSpacing);
mImpl->mRecalculateNaturalSize = true;
+
+ RelayoutForNewLineSize();
return true;
}
return false;
{
mImpl->mLayoutEngine.SetDefaultLineSize(lineSize);
mImpl->mRecalculateNaturalSize = true;
+
+ RelayoutForNewLineSize();
return true;
}
return false;
*/
void ResetScrollPosition();
+ /**
+ * @brief fill needed relayout parameters when line size is changed & request relayout.
+ */
+ void RelayoutForNewLineSize();
+
private: // Private contructors & copy operator.
/**
* @brief Private constructor.
/**
* @brief Called to signal that caret (cursor position) has been moved.
*/
- virtual void CursorMoved(unsigned int position) = 0;
+ virtual void CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition) = 0;
/**
* @brief Called to signal that text has been inserted or deleted.
lineRun += firstLineIndex;
- // The line height is the addition of the line ascender and the line descender.
- // However, the line descender has a negative value, hence the subtraction.
- selectionBoxInfo->lineHeight = lineRun->ascender - lineRun->descender;
+ selectionBoxInfo->lineHeight = GetLineHeight(*lineRun);
GlyphIndex lastGlyphOfLine = lineRun->glyphRun.glyphIndex + lineRun->glyphRun.numberOfGlyphs - 1u;
// Update the line's vertical offset.
selectionBoxInfo->lineOffset = currentLineOffset + currentLineHeight;
- // The line height is the addition of the line ascender and the line descender.
- // However, the line descender has a negative value, hence the subtraction.
- selectionBoxInfo->lineHeight = lineRun->ascender - lineRun->descender;
+ selectionBoxInfo->lineHeight = GetLineHeight(*lineRun);
}
}
}
lastGlyphIndexOfLine = (line->isSplitToTwoHalves ? line->glyphRunSecondHalf.glyphIndex + line->glyphRunSecondHalf.numberOfGlyphs : line->glyphRun.glyphIndex + line->glyphRun.numberOfGlyphs) - 1u;
- penY += line->ascender;
+ penY += line->ascender + line->lineSpacing;
}
}
}
const LineRun& elidedLine = *ellipsisLine;
if((1u == numberOfLines) &&
- (elidedLine.ascender - elidedLine.descender > mImpl->mVisualModel->mControlSize.height))
+ (GetLineHeight(elidedLine) > mImpl->mVisualModel->mControlSize.height))
{
// Replace the first glyph with ellipsis glyph
auto indexOfFirstGlyph = (ellipsisPosition == DevelText::EllipsisPosition::START) ? startIndexOfEllipsis : 0u;
{
uint32_t droppedFrames = 0;
- while(current > std::chrono::time_point_cast<TimePoint::duration>(mNextFrameStartTime + std::chrono::microseconds(mFrameDurationMicroSeconds)))
+ while(current > std::chrono::time_point_cast<TimePoint::duration>(mNextFrameStartTime + std::chrono::microseconds(mFrameDurationMicroSeconds)) && droppedFrames < mTotalFrame)
{
droppedFrames++;
mNextFrameStartTime = std::chrono::time_point_cast<TimePoint::duration>(mNextFrameStartTime + std::chrono::microseconds(mFrameDurationMicroSeconds));
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 39;
+const unsigned int TOOLKIT_MICRO_VERSION = 40;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.0.39
+Version: 2.0.40
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT