From 80b16e58fd20746be9ef436dbc3a8805ee7a22e9 Mon Sep 17 00:00:00 2001 From: suhyung Eom Date: Thu, 5 Jan 2017 16:55:12 +0900 Subject: [PATCH] Implement vertical scroll animation on text input New property is added to control vertical scroll animation set DevelTextEditor::Property::VERTICAL_SCROLL_ANIMATION true to enable scroll animation Signed-off-by: suhyung Eom Change-Id: I5da8b1df603928e44b5f82d785227b67f6be4a5f --- .../src/dali-toolkit/utc-Dali-TextEditor.cpp | 85 +++++++++++++++++++ .../controls/text-controls/text-editor-devel.h | 98 ++++++++++++++++++++++ dali-toolkit/devel-api/file.list | 1 + .../controls/text-controls/text-editor-impl.cpp | 72 ++++++++++++++-- .../controls/text-controls/text-editor-impl.h | 11 +++ dali-toolkit/internal/file.list | 1 + dali-toolkit/internal/text/text-controller-impl.h | 1 + dali-toolkit/internal/text/text-controller.cpp | 20 +++++ dali-toolkit/internal/text/text-controller.h | 7 ++ dali-toolkit/internal/text/text-model.cpp | 1 + dali-toolkit/internal/text/text-model.h | 1 + .../internal/text/text-vertical-scroller.cpp | 97 +++++++++++++++++++++ .../internal/text/text-vertical-scroller.h | 93 ++++++++++++++++++++ 13 files changed, 483 insertions(+), 5 deletions(-) create mode 100644 dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h create mode 100644 dali-toolkit/internal/text/text-vertical-scroller.cpp create mode 100644 dali-toolkit/internal/text/text-vertical-scroller.h diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp index 2dae967..cd9d6bf 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp @@ -25,6 +25,7 @@ #include #include #include +#include using namespace Dali; using namespace Toolkit; @@ -84,6 +85,9 @@ const char* const PROPERTY_NAME_INPUT_EMBOSS = "inputEmb const char* const PROPERTY_NAME_OUTLINE = "outline"; const char* const PROPERTY_NAME_INPUT_OUTLINE = "inputOutline"; +const char* const PROPERTY_NAME_SMOOTH_SCROLL = "smoothScroll"; +const char* const PROPERTY_NAME_SMOOTH_SCROLL_DURATION = "smoothScrollDuration"; + const int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND; const Dali::Vector4 LIGHT_BLUE( 0.75f, 0.96f, 1.f, 1.f ); // The text highlight color. @@ -324,6 +328,8 @@ int UtcDaliTextEditorGetPropertyP(void) DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_EMBOSS ) == TextEditor::Property::INPUT_EMBOSS ); DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_OUTLINE ) == TextEditor::Property::OUTLINE ); DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_OUTLINE ) == TextEditor::Property::INPUT_OUTLINE ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SMOOTH_SCROLL ) == DevelTextEditor::Property::SMOOTH_SCROLL ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SMOOTH_SCROLL_DURATION ) == DevelTextEditor::Property::SMOOTH_SCROLL_DURATION ); END_TEST; } @@ -593,6 +599,15 @@ int UtcDaliTextEditorSetPropertyP(void) editor.SetProperty( TextEditor::Property::INPUT_OUTLINE, "Outline input properties" ); DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::INPUT_OUTLINE ), std::string("Outline input properties"), TEST_LOCATION ); + // Check the smooth scroll property + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SMOOTH_SCROLL ), false, TEST_LOCATION ); + editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL, true ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SMOOTH_SCROLL ), true, TEST_LOCATION ); + + // Check the smooth scroll duration property + editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL_DURATION, 0.2f ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SMOOTH_SCROLL_DURATION ), 0.2f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + END_TEST; } @@ -1520,3 +1535,73 @@ int utcDaliTextEditorEvent04(void) END_TEST; } + +int utcDaliTextEditorEvent05(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorEvent05"); + + // Checks if the highlight actor is created. + + TextEditor editor = TextEditor::New(); + DALI_TEST_CHECK( editor ); + + Stage::GetCurrent().Add( editor ); + + editor.SetProperty( TextEditor::Property::TEXT, "Hello\nworl" ); + editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f ); + editor.SetSize( 50.f, 50.f ); + editor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + editor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL, true ); + editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL_DURATION, 0.2f ); + + // Avoid a crash when core load gl resources. + application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Tap on the text editor + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Move at the end of the text. + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_DOWN, 0, 0, Integration::KeyEvent::Down ) ); + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_DOWN, 0, 0, Integration::KeyEvent::Down ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + for( unsigned int index = 0u; index < 10u; ++index ) + { + // Add a character + application.ProcessEvent( GenerateKey( "d", "d", 0, 0, 0, Integration::KeyEvent::Down ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + } + // Modify duration after scroll is enabled + editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL_DURATION, 0.1f ); + + // Continuous scroll left to increase coverage + for( unsigned int index = 0u; index < 10u; ++index ) + { + application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + } + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SMOOTH_SCROLL_DURATION ), 0.1f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SMOOTH_SCROLL ), true, TEST_LOCATION ); + + END_TEST; +} diff --git a/dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h b/dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h new file mode 100644 index 0000000..d842559 --- /dev/null +++ b/dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h @@ -0,0 +1,98 @@ +#ifndef DALI_TOOLKIT_TEXT_EDITOR_DEVEL_H +#define DALI_TOOLKIT_TEXT_EDITOR_DEVEL_H + +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace DevelTextEditor +{ + +namespace Property +{ + enum Type + { + RENDERING_BACKEND = Dali::Toolkit::TextEditor::Property::RENDERING_BACKEND, + TEXT = Dali::Toolkit::TextEditor::Property::TEXT, + TEXT_COLOR = Dali::Toolkit::TextEditor::Property::TEXT_COLOR, + FONT_FAMILY = Dali::Toolkit::TextEditor::Property::FONT_FAMILY, + FONT_STYLE = Dali::Toolkit::TextEditor::Property::FONT_STYLE, + POINT_SIZE = Dali::Toolkit::TextEditor::Property::POINT_SIZE, + HORIZONTAL_ALIGNMENT = Dali::Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT, + SCROLL_THRESHOLD = Dali::Toolkit::TextEditor::Property::SCROLL_THRESHOLD, + SCROLL_SPEED = Dali::Toolkit::TextEditor::Property::SCROLL_SPEED, + PRIMARY_CURSOR_COLOR = Dali::Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR, + SECONDARY_CURSOR_COLOR = Dali::Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR, + ENABLE_CURSOR_BLINK = Dali::Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK, + CURSOR_BLINK_INTERVAL = Dali::Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL, + CURSOR_BLINK_DURATION = Dali::Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION, + CURSOR_WIDTH = Dali::Toolkit::TextEditor::Property::CURSOR_WIDTH, + GRAB_HANDLE_IMAGE = Dali::Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE, + GRAB_HANDLE_PRESSED_IMAGE = Dali::Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE, + SELECTION_HANDLE_IMAGE_LEFT = Dali::Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT, + SELECTION_HANDLE_IMAGE_RIGHT = Dali::Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT, + SELECTION_HANDLE_PRESSED_IMAGE_LEFT = Dali::Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT, + SELECTION_HANDLE_PRESSED_IMAGE_RIGHT = Dali::Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT, + SELECTION_HANDLE_MARKER_IMAGE_LEFT = Dali::Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT, + SELECTION_HANDLE_MARKER_IMAGE_RIGHT = Dali::Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT, + SELECTION_HIGHLIGHT_COLOR = Dali::Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR, + DECORATION_BOUNDING_BOX = Dali::Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX, + ENABLE_MARKUP = Dali::Toolkit::TextEditor::Property::ENABLE_MARKUP, + INPUT_COLOR = Dali::Toolkit::TextEditor::Property::INPUT_COLOR, + INPUT_FONT_FAMILY = Dali::Toolkit::TextEditor::Property::INPUT_FONT_FAMILY, + INPUT_FONT_STYLE = Dali::Toolkit::TextEditor::Property::INPUT_FONT_STYLE, + INPUT_POINT_SIZE = Dali::Toolkit::TextEditor::Property::INPUT_POINT_SIZE, + LINE_SPACING = Dali::Toolkit::TextEditor::Property::LINE_SPACING, + INPUT_LINE_SPACING = Dali::Toolkit::TextEditor::Property::INPUT_LINE_SPACING, + UNDERLINE = Dali::Toolkit::TextEditor::Property::UNDERLINE, + INPUT_UNDERLINE = Dali::Toolkit::TextEditor::Property::INPUT_UNDERLINE, + SHADOW = Dali::Toolkit::TextEditor::Property::SHADOW, + INPUT_SHADOW = Dali::Toolkit::TextEditor::Property::INPUT_SHADOW, + EMBOSS = Dali::Toolkit::TextEditor::Property::EMBOSS, + INPUT_EMBOSS = Dali::Toolkit::TextEditor::Property::INPUT_EMBOSS, + OUTLINE = Dali::Toolkit::TextEditor::Property::OUTLINE, + INPUT_OUTLINE = Dali::Toolkit::TextEditor::Property::INPUT_OUTLINE, + + /** + * @brief name "smoothScroll", type bool + * @details Enable or disable the smooth scroll animation + */ + SMOOTH_SCROLL = INPUT_OUTLINE + 1, + + /** + * @brief name "smoothScrollDuration", type float + * @details Sets the duration of smooth scroll animation + */ + SMOOTH_SCROLL_DURATION + }; +} // namespace Property + +} // namespace DevelText + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_EDITOR_DEVEL_H \ No newline at end of file diff --git a/dali-toolkit/devel-api/file.list b/dali-toolkit/devel-api/file.list index c8e9f29..3108cc3 100755 --- a/dali-toolkit/devel-api/file.list +++ b/dali-toolkit/devel-api/file.list @@ -123,6 +123,7 @@ devel_api_super_blur_view_header_files = \ $(devel_api_src_dir)/controls/super-blur-view/super-blur-view.h devel_api_text_controls_header_files = \ + $(devel_api_src_dir)/controls/text-controls/text-editor-devel.h \ $(devel_api_src_dir)/controls/text-controls/text-selection-popup.h \ $(devel_api_src_dir)/controls/text-controls/text-selection-toolbar.h diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp index aab4f95..fb6588b 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -122,6 +124,8 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "emboss", DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputEmboss", MAP, INPUT_EMBOSS ) DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "outline", MAP, OUTLINE ) DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputOutline", MAP, INPUT_OUTLINE ) +DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "smoothScroll", BOOLEAN, SMOOTH_SCROLL ) +DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "smoothScrollDuration", FLOAT, SMOOTH_SCROLL_DURATION ) DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED ) DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED ) @@ -590,6 +594,26 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P } break; } + case Toolkit::DevelTextEditor::Property::SMOOTH_SCROLL: + { + const bool enable = value.Get< bool >(); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor SMOOTH_SCROLL %d\n", enable ); + + impl.mScrollAnimationEnabled = enable; + break; + } + case Toolkit::DevelTextEditor::Property::SMOOTH_SCROLL_DURATION: + { + const float duration = value.Get< float >(); + DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor SMOOTH_SCROLL_DURATION %f\n", duration ); + + impl.mScrollAnimationDuration = duration; + if ( impl.mTextVerticalScroller ) + { + impl.mTextVerticalScroller->SetDuration( duration ); + } + break; + } } // switch } // texteditor } @@ -891,6 +915,16 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind GetOutlineProperties( impl.mController, value, Text::EffectStyle::INPUT ); break; } + case Toolkit::DevelTextEditor::Property::SMOOTH_SCROLL: + { + value = impl.mScrollAnimationEnabled; + break; + } + case Toolkit::DevelTextEditor::Property::SMOOTH_SCROLL_DURATION: + { + value = impl.mScrollAnimationDuration; + break; + } } //switch } @@ -1106,10 +1140,6 @@ void TextEditor::RenderText( Text::Controller::UpdateTextType updateTextType ) if( mRenderableActor ) { - const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition(); - - mRenderableActor.SetPosition( scrollOffset.x + mAlignmentOffset, scrollOffset.y ); - // Make sure the actors are parented correctly with/without clipping Actor self = mStencil ? mStencil : Self(); @@ -1123,6 +1153,8 @@ void TextEditor::RenderText( Text::Controller::UpdateTextType updateTextType ) mClippingDecorationActors.clear(); self.Add( mRenderableActor ); + + ApplyScrollPosition(); } } @@ -1397,12 +1429,42 @@ void TextEditor::OnIdleSignal() mIdleCallback = NULL; } +void TextEditor::ApplyScrollPosition() +{ + const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition(); + float scrollAmount = 0.0f; + + if ( mScrollAnimationEnabled ) + { + scrollAmount = mController->GetScrollAmountByUserInput(); + } + if ( mTextVerticalScroller ) + { + mTextVerticalScroller->CheckStartAnimation( mRenderableActor, scrollOffset.x + mAlignmentOffset, scrollOffset.y - scrollAmount, scrollAmount ); + } + else if ( Equals( scrollAmount, 0.0f, Math::MACHINE_EPSILON_1 )) + { + mRenderableActor.SetPosition( scrollOffset.x + mAlignmentOffset, scrollOffset.y - scrollAmount ); + } + else + { + mTextVerticalScroller = Text::TextVerticalScroller::New(); + if ( !Equals( mScrollAnimationDuration, 0.0f, Math::MACHINE_EPSILON_1 )) + { + mTextVerticalScroller->SetDuration( mScrollAnimationDuration ); + } + mTextVerticalScroller->CheckStartAnimation( mRenderableActor, scrollOffset.x + mAlignmentOffset, scrollOffset.y - scrollAmount, scrollAmount ); + } +} + TextEditor::TextEditor() : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ), mIdleCallback( NULL ), mAlignmentOffset( 0.f ), + mScrollAnimationDuration( 0.f ), mRenderingBackend( DEFAULT_RENDERING_BACKEND ), - mHasBeenStaged( false ) + mHasBeenStaged( false ), + mScrollAnimationEnabled( false ) { } diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h index 2be7072..09465a8 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace Dali @@ -227,6 +228,13 @@ private: // Implementation void OnIdleSignal(); /** + * @brief set RenderActor's position with new scrollPosition + * + * Apply updated scroll position or start scroll animation if VerticalScrollAnimation is enabled + */ + void ApplyScrollPosition(); + + /** * Construct a new TextEditor. */ TextEditor(); @@ -257,6 +265,7 @@ private: // Data Text::ControllerPtr mController; Text::RendererPtr mRenderer; Text::DecoratorPtr mDecorator; + Text::TextVerticalScrollerPtr mTextVerticalScroller; Toolkit::Control mStencil; std::vector mClippingDecorationActors; ///< Decoration actors which need clipping. @@ -264,8 +273,10 @@ private: // Data CallbackBase* mIdleCallback; float mAlignmentOffset; + float mScrollAnimationDuration; int mRenderingBackend; bool mHasBeenStaged:1; + bool mScrollAnimationEnabled:1; }; } // namespace Internal diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 7f39ff6..27b079a 100755 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -118,6 +118,7 @@ toolkit_src_files = \ $(toolkit_src_dir)/text/text-io.cpp \ $(toolkit_src_dir)/text/text-model.cpp \ $(toolkit_src_dir)/text/text-scroller.cpp \ + $(toolkit_src_dir)/text/text-vertical-scroller.cpp \ $(toolkit_src_dir)/text/text-view.cpp \ $(toolkit_src_dir)/text/text-view-interface.cpp \ $(toolkit_src_dir)/text/visual-model-impl.cpp \ diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index 81b6554..424ac0b 100644 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -148,6 +148,7 @@ struct EventData bool mScrollAfterDelete : 1; ///< Whether to scroll after delete characters. bool mAllTextSelected : 1; ///< True if the selection handles are selecting all the text. bool mUpdateInputStyle : 1; ///< Whether to update the input style after moving the cursor. + bool mCheckScrollAmount : 1; ///< Whether to check scrolled amount after updating the position }; struct ModifyEvent diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 58def076..f10d93e 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -1467,6 +1467,18 @@ const ModelInterface* const Controller::GetTextModel() const return mImpl->mModel.Get(); } +float Controller::GetScrollAmountByUserInput() +{ + float scrollAmount = 0.0f; + + if (NULL != mImpl->mEventData && mImpl->mEventData->mCheckScrollAmount) + { + scrollAmount = mImpl->mModel->mScrollPosition.y - mImpl->mModel->mScrollPositionLast.y; + mImpl->mEventData->mCheckScrollAmount = false; + } + return scrollAmount; +} + // public : Relayout. Controller::UpdateTextType Controller::Relayout( const Size& size ) @@ -1538,6 +1550,7 @@ Controller::UpdateTextType Controller::Relayout( const Size& size ) // Do not re-do any operation until something changes. mImpl->mOperationsPending = NO_OPERATION; + mImpl->mModel->mScrollPositionLast = mImpl->mModel->mScrollPosition; // Whether the text control is editable const bool isEditable = NULL != mImpl->mEventData; @@ -1686,6 +1699,8 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) ( Dali::DALI_KEY_CURSOR_UP == keyCode ) || ( Dali::DALI_KEY_CURSOR_DOWN == keyCode ) ) { + mImpl->mEventData->mCheckScrollAmount = true; + Event event( Event::CURSOR_KEY_EVENT ); event.p1.mInt = keyCode; mImpl->mEventData->mEventQueue.push_back( event ); @@ -2792,6 +2807,8 @@ void Controller::TextInsertedEvent() return; } + mImpl->mEventData->mCheckScrollAmount = true; + // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; @@ -2808,6 +2825,8 @@ void Controller::TextDeletedEvent() return; } + mImpl->mEventData->mCheckScrollAmount = true; + // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; @@ -2834,6 +2853,7 @@ void Controller::SelectEvent( float x, float y, bool selectAll ) mImpl->mEventData->mEventQueue.push_back( event ); } + mImpl->mEventData->mCheckScrollAmount = true; mImpl->RequestRelayout(); } } diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index 6f4b864..f5b825e 100644 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -814,6 +814,13 @@ public: // Queries & retrieves. */ const ModelInterface* const GetTextModel() const; + /** + * @brief Used to get scrolled distance by user input + * + * @return Distance from last scroll offset to new scroll offset + */ + float GetScrollAmountByUserInput(); + public: // Relayout. /** diff --git a/dali-toolkit/internal/text/text-model.cpp b/dali-toolkit/internal/text/text-model.cpp index 5de3e43..7eae0e1 100644 --- a/dali-toolkit/internal/text/text-model.cpp +++ b/dali-toolkit/internal/text/text-model.cpp @@ -106,6 +106,7 @@ Model::Model() : mLogicalModel(), mVisualModel(), mScrollPosition(), + mScrollPositionLast(), mHorizontalAlignment( Layout::HORIZONTAL_ALIGN_BEGIN ), mVerticalAlignment( Layout::VERTICAL_ALIGN_TOP ), mAlignmentOffset( 0.0f ), diff --git a/dali-toolkit/internal/text/text-model.h b/dali-toolkit/internal/text/text-model.h index e0dd85e..26b9f08 100644 --- a/dali-toolkit/internal/text/text-model.h +++ b/dali-toolkit/internal/text/text-model.h @@ -156,6 +156,7 @@ public: * Typically this will have a negative value with scrolling occurs. */ Vector2 mScrollPosition; ///< The text is offset by this position when scrolling. + Vector2 mScrollPositionLast; ///< The last offset value of mScrollPosition Layout::HorizontalAlignment mHorizontalAlignment; ///< The layout's horizontal alignment. Layout::VerticalAlignment mVerticalAlignment; ///< The layout's vertical alignment. float mAlignmentOffset; ///< The alignment offset. diff --git a/dali-toolkit/internal/text/text-vertical-scroller.cpp b/dali-toolkit/internal/text/text-vertical-scroller.cpp new file mode 100644 index 0000000..fabf035 --- /dev/null +++ b/dali-toolkit/internal/text/text-vertical-scroller.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES + +// INTERNAL INCLUDES + +namespace Dali +{ + +namespace Toolkit +{ + +namespace +{ + +const float DEFAULT_VERTICAL_SCROLL_DURATION(0.15f); ///< Duration to complete scroll animation + +} // namespace + +namespace Text +{ + +TextVerticalScrollerPtr TextVerticalScroller::New() +{ + TextVerticalScrollerPtr textScroller( new TextVerticalScroller() ); + return textScroller; +} + +TextVerticalScroller::TextVerticalScroller() +: mDuration( DEFAULT_VERTICAL_SCROLL_DURATION ) +{ +} + +TextVerticalScroller::~TextVerticalScroller() +{ +} + +void TextVerticalScroller::CheckStartAnimation( Actor& sourceActor, float x, float y, float scrollAmount ) +{ + if ( Equals( scrollAmount, 0.0f, Math::MACHINE_EPSILON_1 ) ) + { + // scroll animation isn't required, set position only + if( mScrollAnimation && mScrollAnimation.GetState() == Animation::PLAYING ) + { + mScrollAnimation.Clear(); + } + sourceActor.SetPosition( x, y ); + return; + } + float toY = y + scrollAmount; + // Either actor or scroll area is changed, so restart animation + if( mScrollAnimation ) + { + mScrollAnimation.Clear(); + } + else + { + // Create animation at first + mScrollAnimation = Animation::New( mDuration ); + } + mScrollingActor = sourceActor; + mScrollTo = toY; + + // Set animation attribute + sourceActor.SetPosition( x, y ); + mScrollAnimation.AnimateTo( Property(sourceActor, Actor::Property::POSITION_Y), mScrollTo, AlphaFunction::EASE_OUT_SINE ); + mScrollAnimation.Play(); +} + +void TextVerticalScroller::SetDuration( float duration ) +{ + mDuration = duration; +} + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/text/text-vertical-scroller.h b/dali-toolkit/internal/text/text-vertical-scroller.h new file mode 100644 index 0000000..f6a005a --- /dev/null +++ b/dali-toolkit/internal/text/text-vertical-scroller.h @@ -0,0 +1,93 @@ +#ifndef DALI_TOOLKIT_TEXT_VERTICAL_SCROLLER_H +#define DALI_TOOLKIT_TEXT_VERTICAL_SCROLLER_H + +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +class TextVerticalScroller; + +typedef IntrusivePtr TextVerticalScrollerPtr; + +/** + * @brief A helper class for scrolling text vertically + */ +class TextVerticalScroller : public RefObject, public ConnectionTracker +{ +public: + + /** + * @brief Text Scrolling helper, used to automatically scroll text, StartScroll should be called when scrolling is needed. + * + */ + static TextVerticalScrollerPtr New(); + + /** + * @brief variables required to set up scrolling animation + * @param[in] sourceActor actor to be animated + * @param[in] x The new x position + * @param[in] y The new y position + * @param[in] scrollAmount The distance to destination y position for actor to be animated + */ + void CheckStartAnimation( Actor& sourceActor, float x, float y, float scrollAmount ); + + /** + * @brief Set duration the text should scroll + * @param[in] duration The duration in seconds + */ + void SetDuration( float duration ); + +private: // Implementation + /** + * Constructor + */ + TextVerticalScroller(); + + /** + * @brief Virtual Destructor. + */ + virtual ~TextVerticalScroller(); + +private: + + Animation mScrollAnimation; // Animation used to update the actor's position + Actor mScrollingActor; // The actor being animated + float mDuration; // The duration of text scrolling + float mScrollTo; // The destination y position +}; // TextVerticalScroller class + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_VERTICAL_SCROLLER_H -- 2.7.4