From b480cf8f1604782bc3104e1b170e73a27c9d351b Mon Sep 17 00:00:00 2001 From: suhyung Eom Date: Fri, 3 Feb 2017 16:07:01 +0900 Subject: [PATCH] Implement scroll bar in the TextEditor Signed-off-by: suhyung Eom Change-Id: Id7a227f8fcbf5b2298b68c702c5f3c326dfe5754 --- .../src/dali-toolkit/utc-Dali-TextEditor.cpp | 22 ++++ .../controls/text-controls/text-editor-devel.h | 22 +++- .../controls/text-controls/text-editor-impl.cpp | 119 ++++++++++++++++++++- .../controls/text-controls/text-editor-impl.h | 14 ++- dali-toolkit/internal/text/text-controller.cpp | 12 +++ dali-toolkit/internal/text/text-controller.h | 12 +++ .../1920x1080/dali-toolkit-default-theme.json | 5 +- .../styles/480x800/dali-toolkit-default-theme.json | 5 +- .../720x1280/dali-toolkit-default-theme.json | 5 +- 9 files changed, 209 insertions(+), 7 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp index 4635def..e410fb1 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp @@ -87,6 +87,9 @@ const char* const PROPERTY_NAME_INPUT_OUTLINE = "inputOut const char* const PROPERTY_NAME_SMOOTH_SCROLL = "smoothScroll"; const char* const PROPERTY_NAME_SMOOTH_SCROLL_DURATION = "smoothScrollDuration"; +const char* const PROPERTY_NAME_ENABLE_SCROLL_BAR = "enableScrollBar"; +const char* const PROPERTY_NAME_SCROLL_BAR_SHOW_DURATION = "scrollBarShowDuration"; +const char* const PROPERTY_NAME_SCROLL_BAR_FADE_DURATION = "scrollBarFadeDuration"; const int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND; @@ -330,6 +333,9 @@ int UtcDaliTextEditorGetPropertyP(void) 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 ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_ENABLE_SCROLL_BAR ) == DevelTextEditor::Property::ENABLE_SCROLL_BAR ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SCROLL_BAR_SHOW_DURATION ) == DevelTextEditor::Property::SCROLL_BAR_SHOW_DURATION ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SCROLL_BAR_FADE_DURATION ) == DevelTextEditor::Property::SCROLL_BAR_FADE_DURATION ); END_TEST; } @@ -608,6 +614,16 @@ int UtcDaliTextEditorSetPropertyP(void) 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 ); + // Check the scroll bar property + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::ENABLE_SCROLL_BAR ), false, TEST_LOCATION ); + editor.SetProperty( DevelTextEditor::Property::ENABLE_SCROLL_BAR, true ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::ENABLE_SCROLL_BAR ), true, TEST_LOCATION ); + + editor.SetProperty( DevelTextEditor::Property::SCROLL_BAR_SHOW_DURATION, 0.3f ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SCROLL_BAR_SHOW_DURATION ), 0.3f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + editor.SetProperty( DevelTextEditor::Property::SCROLL_BAR_FADE_DURATION, 0.2f ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SCROLL_BAR_FADE_DURATION ), 0.2f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + END_TEST; } @@ -1555,6 +1571,9 @@ int utcDaliTextEditorEvent05(void) editor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL, true ); editor.SetProperty( DevelTextEditor::Property::SMOOTH_SCROLL_DURATION, 0.2f ); + editor.SetProperty( DevelTextEditor::Property::ENABLE_SCROLL_BAR, true ); + editor.SetProperty( DevelTextEditor::Property::SCROLL_BAR_SHOW_DURATION, 0.3f ); + editor.SetProperty( DevelTextEditor::Property::SCROLL_BAR_FADE_DURATION, 0.2f ); // Avoid a crash when core load gl resources. application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE ); @@ -1602,6 +1621,9 @@ int utcDaliTextEditorEvent05(void) } 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 ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::ENABLE_SCROLL_BAR ), true, TEST_LOCATION ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SCROLL_BAR_SHOW_DURATION ), 0.3f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::SCROLL_BAR_FADE_DURATION ), 0.2f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); // Press Escape to increase coverage application.ProcessEvent( GenerateKey( "", "", DALI_KEY_ESCAPE, 0, 0, Integration::KeyEvent::Up ) ); 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 index d842559..fa90103 100644 --- a/dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h +++ b/dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h @@ -85,7 +85,25 @@ namespace Property * @brief name "smoothScrollDuration", type float * @details Sets the duration of smooth scroll animation */ - SMOOTH_SCROLL_DURATION + SMOOTH_SCROLL_DURATION, + + /** + * @brief name "enableScrollBar", type bool + * @details Enable or disable the scroll bar + */ + ENABLE_SCROLL_BAR, + + /** + * @brief name "scrollBarShowDuration", type float + * @details Sets the duration of scroll bar to show + */ + SCROLL_BAR_SHOW_DURATION, + + /** + * @brief name "scrollBarFadeDuration", type float + * @details Sets the duration of scroll bar to fade out + */ + SCROLL_BAR_FADE_DURATION }; } // namespace Property @@ -95,4 +113,4 @@ namespace Property } // namespace Dali -#endif // DALI_TOOLKIT_TEXT_EDITOR_DEVEL_H \ No newline at end of file +#endif // DALI_TOOLKIT_TEXT_EDITOR_DEVEL_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 a5aa7ff..5e2de42 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp @@ -74,6 +74,11 @@ const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] = }; const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] ); +const char* const SCROLL_BAR_POSITION("sourcePosition"); +const char* const SCROLL_BAR_POSITION_MIN("sourcePositionMin"); +const char* const SCROLL_BAR_POSITION_MAX("sourcePositionMax"); +const char* const SCROLL_BAR_CONTENT_SIZE("sourceContentSize"); + // Type registration BaseHandle Create() { @@ -125,6 +130,9 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "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_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableScrollBar", BOOLEAN, ENABLE_SCROLL_BAR ) +DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "scrollBarShowDuration", FLOAT, SCROLL_BAR_SHOW_DURATION ) +DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "scrollBarFadeDuration", FLOAT, SCROLL_BAR_FADE_DURATION ) DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED ) DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED ) @@ -613,6 +621,30 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P } break; } + case Toolkit::DevelTextEditor::Property::ENABLE_SCROLL_BAR: + { + const bool enable = value.Get< bool >(); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor SHOW_SCROLL_BAR %d\n", enable ); + + impl.mScrollBarEnabled = enable; + break; + } + case Toolkit::DevelTextEditor::Property::SCROLL_BAR_SHOW_DURATION: + { + const float duration = value.Get< float >(); + DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor SCROLL_BAR_SHOW_DURATION %f\n", duration ); + + impl.mAnimationPeriod.delaySeconds = duration; + break; + } + case Toolkit::DevelTextEditor::Property::SCROLL_BAR_FADE_DURATION: + { + const float duration = value.Get< float >(); + DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor SCROLL_BAR_FADE_DURATION %f\n", duration ); + + impl.mAnimationPeriod.durationSeconds = duration; + break; + } } // switch } // texteditor } @@ -924,6 +956,21 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind value = impl.mScrollAnimationDuration; break; } + case Toolkit::DevelTextEditor::Property::ENABLE_SCROLL_BAR: + { + value = impl.mScrollBarEnabled; + break; + } + case Toolkit::DevelTextEditor::Property::SCROLL_BAR_SHOW_DURATION: + { + value = impl.mAnimationPeriod.delaySeconds; + break; + } + case Toolkit::DevelTextEditor::Property::SCROLL_BAR_FADE_DURATION: + { + value = impl.mAnimationPeriod.durationSeconds; + break; + } } //switch } @@ -1157,6 +1204,7 @@ void TextEditor::RenderText( Text::Controller::UpdateTextType updateTextType ) ApplyScrollPosition(); } + UpdateScrollBar(); } void TextEditor::OnKeyInputFocusGained() @@ -1340,6 +1388,73 @@ void TextEditor::AddDecoration( Actor& actor, bool needsClipping ) } } +void TextEditor::UpdateScrollBar() +{ + using namespace Dali; + + float scrollPosition; + float controlSize; + float layoutSize; + bool latestScrolled; + + if ( !mScrollBarEnabled ) + { + return; + } + latestScrolled = mController->GetTextScrollInfo( scrollPosition, controlSize, layoutSize ); + if ( !latestScrolled || controlSize > layoutSize) + { + return; + } + + CustomActor self = Self(); + if( !mScrollBar ) + { + mScrollBar = Toolkit::ScrollBar::New( Toolkit::ScrollBar::Vertical ); + mScrollBar.SetIndicatorHeightPolicy( Toolkit::ScrollBar::Variable ); + mScrollBar.SetParentOrigin( ParentOrigin::TOP_RIGHT ); + mScrollBar.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); + mScrollBar.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT ); + mScrollBar.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::WIDTH ); + + // Register the scroll position property + Property::Index propertyScrollPosition = self.RegisterProperty( SCROLL_BAR_POSITION, scrollPosition ); + // Register the minimum scroll position property + Property::Index propertyMinScrollPosition = self.RegisterProperty( SCROLL_BAR_POSITION_MIN, 0.0f ); + // Register the maximum scroll position property + Property::Index propertyMaxScrollPosition = self.RegisterProperty( SCROLL_BAR_POSITION_MAX, (layoutSize - controlSize) ); + // Register the scroll content size property + Property::Index propertyScrollContentSize = self.RegisterProperty( SCROLL_BAR_CONTENT_SIZE, layoutSize ); + + mScrollBar.SetScrollPropertySource(self, propertyScrollPosition, propertyMinScrollPosition, propertyMaxScrollPosition, propertyScrollContentSize); + + self.Add( mScrollBar ); + } + else + { + Property::Index propertyScrollPosition = self.GetPropertyIndex( SCROLL_BAR_POSITION ); + Property::Index propertyMaxScrollPosition = self.GetPropertyIndex( SCROLL_BAR_POSITION_MAX ); + Property::Index propertyScrollContentSize = self.GetPropertyIndex( SCROLL_BAR_CONTENT_SIZE ); + + self.SetProperty( propertyScrollPosition, scrollPosition ); + self.SetProperty( propertyMaxScrollPosition, (layoutSize - controlSize) ); + self.SetProperty( propertyScrollContentSize, layoutSize ); + } + + Actor indicator = mScrollBar.GetScrollIndicator(); + if( mAnimation ) + { + mAnimation.Stop(); // Cancel any animation + } + else + { + mAnimation = Animation::New( mAnimationPeriod.durationSeconds ); + } + indicator.SetOpacity(1.0f); + mAnimation.AnimateTo( Property( indicator, Actor::Property::COLOR_ALPHA ), 0.0f, AlphaFunction::EASE_IN, mAnimationPeriod ); + mAnimation.Play(); +} + void TextEditor::OnStageConnect( Dali::Actor actor ) { if ( mHasBeenStaged ) @@ -1448,12 +1563,14 @@ void TextEditor::ApplyScrollPosition() TextEditor::TextEditor() : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ), + mAnimationPeriod( 0.0f, 0.0f ), mIdleCallback( NULL ), mAlignmentOffset( 0.f ), mScrollAnimationDuration( 0.f ), mRenderingBackend( DEFAULT_RENDERING_BACKEND ), mHasBeenStaged( false ), - mScrollAnimationEnabled( false ) + mScrollAnimationEnabled( false ), + mScrollBarEnabled( 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 40f5e03..cc864f1 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h @@ -20,9 +20,11 @@ // EXTERNAL INCLUDES #include +#include // INTERNAL INCLUDES #include +#include #include #include #include @@ -213,6 +215,13 @@ private: // Implementation void KeyboardStatusChanged( bool keyboardShown ); /** + * @brief update scroll bar position + * + * If text scroll is occurred, create or update scroll bar position + */ + void UpdateScrollBar(); + + /** * @brief Callback when TextEditor is touched * * @param[in] actor TextEditor touched @@ -257,7 +266,6 @@ private: // Implementation void OnStageConnect( Dali::Actor actor ); private: // Data - // Signals Toolkit::TextEditor::TextChangedSignalType mTextChangedSignal; Toolkit::TextEditor::InputStyleChangedSignalType mInputStyleChangedSignal; @@ -268,6 +276,9 @@ private: // Data Text::DecoratorPtr mDecorator; Text::TextVerticalScrollerPtr mTextVerticalScroller; Toolkit::Control mStencil; + Toolkit::ScrollBar mScrollBar; + Dali::Animation mAnimation; ///< Scroll indicator Show/Hide Animation. + Dali::TimePeriod mAnimationPeriod; std::vector mClippingDecorationActors; ///< Decoration actors which need clipping. Actor mRenderableActor; @@ -278,6 +289,7 @@ private: // Data int mRenderingBackend; bool mHasBeenStaged:1; bool mScrollAnimationEnabled:1; + bool mScrollBarEnabled:1; }; } // namespace Internal diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index ca201d3..047eb4b 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -1498,6 +1498,18 @@ float Controller::GetScrollAmountByUserInput() return scrollAmount; } +bool Controller::GetTextScrollInfo( float& scrollPosition, float& controlHeight, float& layoutHeight ) +{ + const Vector2& layout = mImpl->mModel->mVisualModel->GetLayoutSize(); + bool isScrolled; + + controlHeight = mImpl->mModel->mVisualModel->mControlSize.height; + layoutHeight = layout.height; + scrollPosition = mImpl->mModel->mScrollPosition.y; + isScrolled = !Equals( mImpl->mModel->mScrollPosition.y, mImpl->mModel->mScrollPositionLast.y, Math::MACHINE_EPSILON_1 ); + return isScrolled; +} + // public : Relayout. Controller::UpdateTextType Controller::Relayout( const Size& size ) diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index 4bb6f7c..9612b1a 100644 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -837,6 +837,18 @@ public: // Queries & retrieves. */ float GetScrollAmountByUserInput(); + /** + * @brief Get latest scroll amount, control size and layout size + * + * This method is used to get information of control's scroll + * @param[out] scrollPosition The current scrolled position + * @param[out] controlHeight The size of a UI control + * @param[out] layoutHeight The size of a bounding box to layout text within. + * + * @return Whether the text scroll position is changed or not after last update. + */ + bool GetTextScrollInfo( float& scrollPosition, float& controlHeight, float& layoutHeight ); + public: // Relayout. /** diff --git a/dali-toolkit/styles/1920x1080/dali-toolkit-default-theme.json b/dali-toolkit/styles/1920x1080/dali-toolkit-default-theme.json index bd48ca7..8179db5 100644 --- a/dali-toolkit/styles/1920x1080/dali-toolkit-default-theme.json +++ b/dali-toolkit/styles/1920x1080/dali-toolkit-default-theme.json @@ -205,7 +205,10 @@ "selectionHighlightColor":[0.75,0.96,1.0,1.0], "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png", "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" }, - "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" } + "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" }, + "enableScrollBar":true, + "scrollBarShowDuration":0.8, + "scrollBarFadeDuration":0.5 }, "ProgressBar": { diff --git a/dali-toolkit/styles/480x800/dali-toolkit-default-theme.json b/dali-toolkit/styles/480x800/dali-toolkit-default-theme.json index 43b99ea..95d2d01 100644 --- a/dali-toolkit/styles/480x800/dali-toolkit-default-theme.json +++ b/dali-toolkit/styles/480x800/dali-toolkit-default-theme.json @@ -212,7 +212,10 @@ "selectionHighlightColor":[0.75,0.96,1.0,1.0], "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png", "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" }, - "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" } + "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" }, + "enableScrollBar":true, + "scrollBarShowDuration":0.8, + "scrollBarFadeDuration":0.5 }, "Popup": { diff --git a/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json b/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json index aa735b3..fdd8182 100644 --- a/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json +++ b/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json @@ -178,7 +178,10 @@ "selectionHighlightColor":[0.75,0.96,1.0,1.0], "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png", "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" }, - "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" } + "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" }, + "enableScrollBar":true, + "scrollBarShowDuration":0.8, + "scrollBarFadeDuration":0.5 }, "Popup": { -- 2.7.4