From: JIYUN YANG Date: Fri, 26 Mar 2021 06:48:14 +0000 (+0000) Subject: Merge "Support mouse & wheel events in web view." into devel/master X-Git-Tag: graphics-backend-release-1~2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=f4f698788dc4952dba25d518face07c7d86ff96e;hp=fb222199e44a5352d8c7f6e1c715da1a995e41af Merge "Support mouse & wheel events in web view." into devel/master --- diff --git a/automated-tests/src/dali-toolkit/CMakeLists.txt b/automated-tests/src/dali-toolkit/CMakeLists.txt index ea6c3fc..47fb5a5 100755 --- a/automated-tests/src/dali-toolkit/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit/CMakeLists.txt @@ -45,6 +45,7 @@ SET(TC_SOURCES utc-Dali-Tooltip.cpp utc-Dali-TransitionData.cpp utc-Dali-Button.cpp + utc-Dali-CameraView.cpp utc-Dali-Control.cpp utc-Dali-ControlImpl.cpp utc-Dali-ItemLayout.cpp diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-video-player.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-video-player.cpp index 4a5e76c..9909164 100755 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-video-player.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-video-player.cpp @@ -109,6 +109,26 @@ public: } + void RaiseAbove(Dali::VideoPlayer target) + { + + } + + void LowerBelow(Dali::VideoPlayer target) + { + + } + + void RaiseToTop() + { + + } + + void LowerToBottom() + { + + } + public: std::string mUrl; @@ -325,5 +345,25 @@ void VideoPlayer::FinishSynchronization() Internal::Adaptor::GetImplementation( *this ).FinishSynchronization(); } +void VideoPlayer::RaiseAbove(Dali::VideoPlayer target) +{ + Internal::Adaptor::GetImplementation( *this ).RaiseAbove(target); +} + +void VideoPlayer::LowerBelow(Dali::VideoPlayer target) +{ + Internal::Adaptor::GetImplementation( *this ).LowerBelow(target); +} + +void VideoPlayer::RaiseToTop() +{ + Internal::Adaptor::GetImplementation( *this ).RaiseToTop(); +} + +void VideoPlayer::LowerToBottom() +{ + Internal::Adaptor::GetImplementation( *this ).LowerToBottom(); +} + } // namespace Dali; diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window-impl.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window-impl.h index 25e0a16..f443251 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window-impl.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window-impl.h @@ -44,6 +44,8 @@ public: virtual ~Window() = default; static Window* New(const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent); FocusChangeSignalType mFocusChangeSignal; + ResizeSignalType mResizeSignal; + int mRotationAngle; DevelWindow::VisibilityChangedSignalType mVisibilityChangedSignal; }; diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.cpp index 9e9ca35..9ab5021 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.cpp @@ -46,6 +46,8 @@ namespace Adaptor Window::Window( const PositionSize& positionSize ) : SceneHolder( positionSize ), mFocusChangeSignal(), + mResizeSignal(), + mRotationAngle(90), // dummy angle for test coverage mVisibilityChangedSignal() { } @@ -160,6 +162,11 @@ FocusChangeSignalType& Window::FocusChangeSignal() return GetImplementation( *this ).mFocusChangeSignal; } +ResizeSignalType& Window::ResizeSignal() +{ + return GetImplementation( *this ).mResizeSignal; +} + Window::KeyEventSignalType& Window::KeyEventSignal() { return GetImplementation( *this ).KeyEventSignal(); @@ -195,6 +202,17 @@ Window DownCast( BaseHandle handle ) return Dali::Window( windowImpl ); } +void SetPositionSize(Window window, PositionSize positionSize) +{ + Uint16Pair newSize(positionSize.width, positionSize.height); + GetImplementation( window ).mResizeSignal.Emit(window,newSize); +} + +int GetPhysicalOrientation(Window window) +{ + return GetImplementation( window ).mRotationAngle; +} + void AddFrameRenderedCallback( Window window, std::unique_ptr< CallbackBase > callback, int32_t frameId ) { CallbackBase::Execute( *callback, frameId ); diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.h index 2291139..a696684 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-window.h @@ -47,12 +47,16 @@ class Window; class Window; typedef Signal< void (Window,bool) > FocusChangeSignalType; +typedef Signal< void (Window,Uint16Pair) > ResizeSignalType; class Window : public BaseHandle { public: + using WindowSize = Uint16Pair; + using KeyEventSignalType = Signal< void (const KeyEvent&) >; using TouchEventSignalType = Signal< void (const TouchEvent&) >; + using ResizeSignalType = Signal; static Window New(PositionSize windowPosition, const std::string& name, bool isTransparent = false); static Window New(PositionSize windowPosition, const std::string& name, const std::string& className, bool isTransparent = false); @@ -76,6 +80,7 @@ public: FocusChangeSignalType& FocusChangeSignal(); KeyEventSignalType& KeyEventSignal(); TouchEventSignalType& TouchedSignal(); + ResizeSignalType& ResizeSignal(); public: explicit Window( Internal::Adaptor::Window* window ); @@ -93,6 +98,8 @@ typedef Signal< void ( Window, bool ) > VisibilityChangedSignalType; Dali::Window Get( Actor actor ); Dali::Window DownCast( BaseHandle handle ); +void SetPositionSize(Window window, PositionSize positionSize); +int GetPhysicalOrientation(Window window); void AddFrameRenderedCallback( Window window, std::unique_ptr< CallbackBase > callback, int32_t frameId ); void AddFramePresentedCallback( Window window, std::unique_ptr< CallbackBase > callback, int32_t frameId ); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp index 243a73b..c77b4ac 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -293,6 +293,52 @@ int UtcDaliAnimatedImageVisualGetPropertyMap04(void) END_TEST; } +int UtcDaliAnimatedImageVisualImageLoadingFail01(void) +{ + ToolkitTestApplication application; + TestGlAbstraction& gl = application.GetGlAbstraction(); + + { + Property::Map propertyMap; + propertyMap.Insert( Visual::Property::TYPE, Visual::ANIMATED_IMAGE ); + propertyMap.Insert( ImageVisual::Property::URL, "dummy.gif" ); + propertyMap.Insert( ImageVisual::Property::BATCH_SIZE, 2 ); + propertyMap.Insert( ImageVisual::Property::CACHE_SIZE, 2 ); + propertyMap.Insert( ImageVisual::Property::FRAME_DELAY, 20 ); + propertyMap.Insert( ImageVisual::Property::SYNCHRONOUS_LOADING, true ); + propertyMap.Insert( DevelVisual::Property::CORNER_RADIUS, 0.23f ); + propertyMap.Insert( DevelVisual::Property::CORNER_RADIUS_POLICY, Visual::Transform::Policy::ABSOLUTE ); + + VisualFactory factory = VisualFactory::Get(); + Visual::Base visual = factory.CreateVisual( propertyMap ); + + DummyControl dummyControl = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(dummyControl.GetImplementation()); + dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual ); + + dummyControl.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); + application.GetScene().Add( dummyControl ); + + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + application.SendNotification(); + application.Render(20); + + DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 1, TEST_LOCATION ); + + DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedImageVisual::Action::JUMP_TO, 6 ); + + application.SendNotification(); + application.Render(20); + + DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 1, TEST_LOCATION ); + + dummyControl.Unparent(); + } + + END_TEST; +} int UtcDaliAnimatedImageVisualSynchronousLoading(void) { diff --git a/automated-tests/src/dali-toolkit/utc-Dali-CameraView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-CameraView.cpp new file mode 100755 index 0000000..24149f5 --- /dev/null +++ b/automated-tests/src/dali-toolkit/utc-Dali-CameraView.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2021 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. + * + */ + +#include +#include +#include +#include +#include + +using namespace Dali; +using namespace Dali::Toolkit; + +// Negative test case for a method +int UtcDaliCameraViewUninitialized(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliCameraViewUninitialized"); + + Toolkit::CameraView view; + + try + { + // New() must be called to create a CameraView or it wont be valid. + Actor a = Actor::New(); + view.Add( a ); + DALI_TEST_CHECK( false ); + } + catch (Dali::DaliException& e) + { + // Tests that a negative test of an assertion succeeds + DALI_TEST_PRINT_ASSERT( e ); + DALI_TEST_CHECK(!view); + } + END_TEST; +} + +// Positive test case for a method +int UtcDaliCameraViewNew(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliCameraViewNew"); + Any dummy( 0 ); + Toolkit::CameraView view = Toolkit::CameraView::New(dummy); + DALI_TEST_CHECK( view ); + END_TEST; +} + +// Positive test case for a method +int UtcDaliCameraViewDownCast(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliCameraViewDownCast"); + + Any dummy( 0 ); + Toolkit::CameraView view = Toolkit::CameraView::New(dummy); + BaseHandle handle(view); + + Toolkit::CameraView view2 = Toolkit::CameraView::DownCast( handle ); + DALI_TEST_CHECK( view ); + DALI_TEST_CHECK( view2 ); + DALI_TEST_CHECK( view == view2 ); + END_TEST; +} + +int UtcDaliCameraViewCopyAndAssignment(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliCameraViewCopyAndAssignment"); + + Any dummy( 0 ); + CameraView view = Toolkit::CameraView::New(dummy); + DALI_TEST_CHECK( view ); + + CameraView copy( view ); + DALI_TEST_CHECK( view == copy ); + + CameraView assign; + DALI_TEST_CHECK( !assign ); + + assign = copy; + DALI_TEST_CHECK( assign == view ); + + END_TEST; +} + +int UtcDaliCameraViewMoveAssignment(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliCameraViewMoveAssignment"); + + Any dummy( 0 ); + CameraView view = Toolkit::CameraView::New(dummy); + DALI_TEST_EQUALS( 1, view.GetBaseObject().ReferenceCount(), TEST_LOCATION ); + + CameraView moved; + moved = std::move( view ); + DALI_TEST_CHECK( moved ); + DALI_TEST_EQUALS( 1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION ); + DALI_TEST_CHECK( !view ); + + END_TEST; +} + +int UtcDaliCameraViewTypeRegistry(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliCameraViewTypeRegistry"); + + TypeRegistry typeRegistry = TypeRegistry::Get(); + DALI_TEST_CHECK( typeRegistry ); + + TypeInfo typeInfo = typeRegistry.GetTypeInfo( "CameraView" ); + DALI_TEST_CHECK( typeInfo ); + + BaseHandle handle = typeInfo.CreateInstance(); + DALI_TEST_CHECK( handle ); + + CameraView view = CameraView::DownCast( handle ); + DALI_TEST_CHECK( view ); + + END_TEST; +} + +int UtcDaliCameraViewWindowDisplayType(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliCameraViewWindowDisplayType"); + + Any dummy( 0 ); + CameraView cameraView = CameraView::New(dummy, Dali::Toolkit::CameraView::DisplayType::WINDOW); + DALI_TEST_CHECK( cameraView ); + + application.GetScene().Add( cameraView ); + + try + { + cameraView.Update(); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( true ); + } + catch (Dali::DaliException& e) + { + DALI_TEST_PRINT_ASSERT( e ); + DALI_TEST_CHECK(false); + } + + END_TEST; +} + +int UtcDaliCameraViewImageDisplayType(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliCameraViewImageDisplayType"); + + Any dummy( 0 ); + CameraView cameraView = CameraView::New(dummy, Dali::Toolkit::CameraView::DisplayType::IMAGE); + DALI_TEST_CHECK( cameraView ); + + application.GetScene().Add( cameraView ); + + try + { + cameraView.Update(); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( true ); + } + catch (Dali::DaliException& e) + { + DALI_TEST_PRINT_ASSERT( e ); + DALI_TEST_CHECK(false); + } + + END_TEST; +} + +int UtcDaliCameraViewCoverUpdateDisplayArea1(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliCameraViewUpdateDisplayArea1"); + + Any dummy( 0 ); + CameraView view = CameraView::New(dummy, Dali::Toolkit::CameraView::DisplayType::WINDOW); + DALI_TEST_CHECK( view ); + + application.GetScene().Add( view ); + + application.SendNotification(); + application.Render(); + + Vector3 vector(100.0f, 100.0f, 0.0f); + view.SetProperty( Actor::Property::SIZE, vector ); + + application.SendNotification(); + application.Render(); + + // Check the size in the new frame + DALI_TEST_CHECK(vector == view.GetCurrentProperty< Vector3 >( Actor::Property::SIZE )); + + application.GetScene().Remove(view); + + END_TEST; +} + +int UtcDaliCameraViewCoverUpdateDisplayArea2(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliCameraViewUpdateDisplayArea2"); + + Any dummy( 0 ); + CameraView view = CameraView::New(dummy, Dali::Toolkit::CameraView::DisplayType::WINDOW); + DALI_TEST_CHECK( view ); + + application.GetScene().Add( view ); + + application.SendNotification(); + application.Render(); + + Vector3 vector(100.0f, 100.0f, 0.0f); + view.SetProperty( Actor::Property::SIZE, vector ); + + application.SendNotification(); + application.Render(); + + // Check the size in the new frame + DALI_TEST_CHECK(vector == view.GetCurrentProperty< Vector3 >( Actor::Property::SIZE )); + + application.GetScene().Remove(view); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp index d5a243c..b76a850 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -103,6 +103,7 @@ const char* const PROPERTY_NAME_ENABLE_GRAB_HANDLE = "enableGr const char* const PROPERTY_NAME_MATCH_SYSTEM_LANGUAGE_DIRECTION = "matchSystemLanguageDirection"; const char* const PROPERTY_NAME_MAX_LENGTH = "maxLength"; const char* const PROPERTY_NAME_FONT_SIZE_SCALE = "fontSizeScale"; +const char* const PROPERTY_NAME_GRAB_HANDLE_COLOR = "grabHandleColor"; const Vector4 PLACEHOLDER_TEXT_COLOR( 0.8f, 0.8f, 0.8f, 0.8f ); @@ -495,6 +496,7 @@ int UtcDaliTextEditorGetPropertyP(void) DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_ENABLE_GRAB_HANDLE ) == DevelTextEditor::Property::ENABLE_GRAB_HANDLE ); DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_MATCH_SYSTEM_LANGUAGE_DIRECTION ) == DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION ); DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_MAX_LENGTH ) == DevelTextEditor::Property::MAX_LENGTH ); + DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_COLOR ) == DevelTextEditor::Property::GRAB_HANDLE_COLOR ); END_TEST; @@ -910,6 +912,10 @@ int UtcDaliTextEditorSetPropertyP(void) editor.SetProperty( Actor::Property::LAYOUT_DIRECTION, LayoutDirection::RIGHT_TO_LEFT ); DALI_TEST_EQUALS( editor.GetProperty( Actor::Property::LAYOUT_DIRECTION ), static_cast( LayoutDirection::RIGHT_TO_LEFT ), TEST_LOCATION ); + // Check handle color + editor.SetProperty( DevelTextEditor::Property::GRAB_HANDLE_COLOR, Color::GREEN ); + DALI_TEST_EQUALS( editor.GetProperty( DevelTextEditor::Property::GRAB_HANDLE_COLOR ), Color::GREEN, TEST_LOCATION ); + application.SendNotification(); application.Render(); @@ -964,33 +970,113 @@ int utcDaliTextEditorTextChangedP(void) gTextChangedCallBackCalled = false; editor.SetProperty( TextEditor::Property::TEXT, "ABC" ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( gTextChangedCallBackCalled ); DALI_TEST_CHECK( textChangedSignal ); - application.SendNotification(); - editor.SetKeyInputFocus(); gTextChangedCallBackCalled = false; application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( gTextChangedCallBackCalled ); // Remove all text editor.SetProperty( TextField::Property::TEXT, "" ); + application.SendNotification(); + application.Render(); // Pressing backspace key: TextChangedCallback should not be called when there is no text in texteditor. gTextChangedCallBackCalled = false; application.ProcessEvent( GenerateKey( "", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( !gTextChangedCallBackCalled ); // Pressing delete key: TextChangedCallback should not be called when there is no text in texteditor. gTextChangedCallBackCalled = false; application.ProcessEvent( GenerateKey( "", "", "", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "Delete", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) ); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + + END_TEST; +} + +int utcDaliTextEditorTextChangedWithInputMethodContext(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorTextChangedWithInputMethodContext"); + TextEditor editor = TextEditor::New(); + DALI_TEST_CHECK( editor ); + + + application.GetScene().Add( editor ); + + // connect to the text changed signal. + ConnectionTracker* testTracker = new ConnectionTracker(); + editor.TextChangedSignal().Connect(&TestTextChangedCallback); + bool textChangedSignal = false; + editor.ConnectSignal( testTracker, "textChanged", CallbackFunctor(&textChangedSignal) ); + + + // get InputMethodContext + std::string text; + InputMethodContext::EventData imfEvent; + InputMethodContext inputMethodContext = DevelTextEditor::GetInputMethodContext( editor ); + + editor.SetKeyInputFocus(); + editor.SetProperty( DevelTextEditor::Property::ENABLE_EDITING, true ); + + // input text + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "ㅎ", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::TEXT ), std::string("ㅎ"), TEST_LOCATION ); + + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "호", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::TEXT ), std::string("호"), TEST_LOCATION ); + + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "혿", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::TEXT ), std::string("혿"), TEST_LOCATION ); + + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + + imfEvent = InputMethodContext::EventData( InputMethodContext::COMMIT, "호", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "두", 1, 2 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( editor.GetProperty( TextEditor::Property::TEXT ), std::string("호두"), TEST_LOCATION ); + END_TEST; } + int utcDaliTextEditorInputStyleChanged01(void) { // The text-editor emits signals when the input style changes. These changes of style are diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp index b535059..4808f00 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -105,6 +105,7 @@ const char* const PROPERTY_NAME_MATCH_SYSTEM_LANGUAGE_DIRECTION = "matchSys const char* const PROPERTY_NAME_ENABLE_GRAB_HANDLE_POPUP = "enableGrabHandlePopup"; const char* const PROPERTY_NAME_BACKGROUND = "textBackground"; const char* const PROPERTY_NAME_FONT_SIZE_SCALE = "fontSizeScale"; +const char* const PROPERTY_NAME_GRAB_HANDLE_COLOR = "grabHandleColor"; const Vector4 PLACEHOLDER_TEXT_COLOR( 0.8f, 0.8f, 0.8f, 0.8f ); const Dali::Vector4 LIGHT_BLUE( 0.75f, 0.96f, 1.f, 1.f ); // The text highlight color. @@ -510,6 +511,7 @@ int UtcDaliTextFieldGetPropertyP(void) DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_MATCH_SYSTEM_LANGUAGE_DIRECTION ) == DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION ); DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_GRAB_HANDLE_POPUP ) == DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP ); DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_BACKGROUND ) == DevelTextField::Property::BACKGROUND ); + DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_COLOR ) == DevelTextField::Property::GRAB_HANDLE_COLOR ); END_TEST; } @@ -980,6 +982,10 @@ int UtcDaliTextFieldSetPropertyP(void) field.SetProperty( DevelTextField::Property::BACKGROUND, Color::RED ); DALI_TEST_EQUALS( field.GetProperty( DevelTextField::Property::BACKGROUND ), Color::RED, TEST_LOCATION ); + //Check handle color + field.SetProperty( DevelTextField::Property::GRAB_HANDLE_COLOR, Color::GREEN ); + DALI_TEST_EQUALS( field.GetProperty( DevelTextField::Property::GRAB_HANDLE_COLOR ), Color::GREEN, TEST_LOCATION ); + application.SendNotification(); application.Render(); @@ -1034,33 +1040,113 @@ int utcDaliTextFieldTextChangedP(void) gTextChangedCallBackCalled = false; field.SetProperty( TextField::Property::TEXT, "ABC" ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( gTextChangedCallBackCalled ); DALI_TEST_CHECK( textChangedSignal ); - application.SendNotification(); - field.SetKeyInputFocus(); gTextChangedCallBackCalled = false; application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( gTextChangedCallBackCalled ); // Remove all text field.SetProperty( TextField::Property::TEXT, "" ); + application.SendNotification(); + application.Render(); // Pressing backspace key: TextChangedCallback should not be called when there is no text in textfield. gTextChangedCallBackCalled = false; application.ProcessEvent( GenerateKey( "", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( !gTextChangedCallBackCalled ); // Pressing delete key: TextChangedCallback should not be called when there is no text in textfield. gTextChangedCallBackCalled = false; application.ProcessEvent( GenerateKey( "", "", "", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "Delete", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) ); + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( !gTextChangedCallBackCalled ); END_TEST; } +int utcDaliTextFieldTextChangedWithInputMethodContext(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextFieldTextChangedWithInputMethodContext"); + TextField field = TextField::New(); + DALI_TEST_CHECK( field ); + + + application.GetScene().Add( field ); + + // connect to the text changed signal. + ConnectionTracker* testTracker = new ConnectionTracker(); + field.TextChangedSignal().Connect(&TestTextChangedCallback); + bool textChangedSignal = false; + field.ConnectSignal( testTracker, "textChanged", CallbackFunctor(&textChangedSignal) ); + + + // get InputMethodContext + std::string text; + InputMethodContext::EventData imfEvent; + InputMethodContext inputMethodContext = DevelTextField::GetInputMethodContext( field ); + + field.SetKeyInputFocus(); + field.SetProperty( DevelTextField::Property::ENABLE_EDITING, true ); + + // input text + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "ㅎ", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::TEXT ), std::string("ㅎ"), TEST_LOCATION ); + + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "호", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::TEXT ), std::string("호"), TEST_LOCATION ); + + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "혿", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::TEXT ), std::string("혿"), TEST_LOCATION ); + + gTextChangedCallBackCalled = false; + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + + imfEvent = InputMethodContext::EventData( InputMethodContext::COMMIT, "호", 0, 1 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + + imfEvent = InputMethodContext::EventData( InputMethodContext::PRE_EDIT, "두", 1, 2 ); + inputMethodContext.EventReceivedSignal().Emit(inputMethodContext, imfEvent); + DALI_TEST_CHECK( !gTextChangedCallBackCalled ); + + application.SendNotification(); + application.Render(); + DALI_TEST_CHECK( gTextChangedCallBackCalled ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::TEXT ), std::string("호두"), TEST_LOCATION ); + + END_TEST; +} + + // Negative test for the textChanged signal. int utcDaliTextFieldTextChangedN(void) { @@ -1079,6 +1165,8 @@ int utcDaliTextFieldTextChangedN(void) gTextChangedCallBackCalled = false; field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "ABC" ); // Setting placeholder, not TEXT + application.SendNotification(); + application.Render(); DALI_TEST_CHECK( !gTextChangedCallBackCalled ); DALI_TEST_CHECK( !textChangedSignal ); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp index b0aa75e..9a77bba 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include using namespace Dali; @@ -559,6 +560,65 @@ int UtcDaliVideoViewNew2(void) END_TEST; } +int UtcDaliVideoViewRaiseAboveLowerBelow(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliVideoViewRaiseAboveLowerBelow"); + + VideoView view = VideoView::New( true ); + DALI_TEST_CHECK( view ); + + application.GetScene().Add( view ); + view.Play(); + + application.SendNotification(); + application.Render(); + + VideoView view2 = VideoView::New( "", false ); + DALI_TEST_CHECK( view2 ); + + application.GetScene().Add( view2 ); + view2.Play(); + + application.SendNotification(); + application.Render(); + + view.RaiseAbove(view2); + view.LowerBelow(view2); + + END_TEST; +} + +int UtcDaliVideoViewRaiseTopLowerBottom(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliVideoViewRaiseTopLowerBottom"); + + VideoView view = VideoView::New( true ); + DALI_TEST_CHECK( view ); + + application.GetScene().Add( view ); + view.Play(); + + application.SendNotification(); + application.Render(); + + VideoView view2 = VideoView::New( "", false ); + DALI_TEST_CHECK( view2 ); + + application.GetScene().Add( view2 ); + view2.Play(); + + application.SendNotification(); + application.Render(); + + view.RaiseToTop(); + view.LowerToBottom(); + + END_TEST; +} + + int UtcDaliVideoViewPropertyDisplayMode(void) { ToolkitTestApplication application; @@ -787,3 +847,27 @@ int UtcDaliVideoViewResizeWithSynchronization(void) END_TEST; } + +// For coverage. +int UtcDaliVideoViewSynchronizationForWindowRotation(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliVideoViewSynchronizationForWindowRotation"); + + Window window = Window::New(PositionSize(0,0,100,100) ,"", false); + DALI_TEST_CHECK( window ); + + VideoView view = VideoView::New( true ); + DALI_TEST_CHECK( view ); + + window.Add( view ); + + view.Play(); + + DevelWindow::SetPositionSize(window,PositionSize(0,0,480, 240)); + + application.SendNotification(); + application.Render(); + + END_TEST; +} diff --git a/dali-toolkit/dali-toolkit.h b/dali-toolkit/dali-toolkit.h index 26f96a6..1cf4adc 100644 --- a/dali-toolkit/dali-toolkit.h +++ b/dali-toolkit/dali-toolkit.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_H /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/dali-toolkit/devel-api/controls/accessible-impl.cpp b/dali-toolkit/devel-api/controls/accessible-impl.cpp index f986bd4..be4735b 100644 --- a/dali-toolkit/devel-api/controls/accessible-impl.cpp +++ b/dali-toolkit/devel-api/controls/accessible-impl.cpp @@ -291,6 +291,9 @@ bool AccessibleImpl::GrabHighlight() highlight.SetProperty(Actor::Property::POSITION_Z, 1.0f); highlight.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); + // Remember the highlight actor, so that when the default is changed with + // SetHighlightActor(), the currently displayed highlight can still be cleared. + currentHighlightActor = highlight; EnsureSelfVisible(); self.Add(highlight); SetCurrentlyHighlightedActor(self); @@ -305,7 +308,8 @@ bool AccessibleImpl::ClearHighlight() return false; if(GetCurrentlyHighlightedActor() == self) { - self.Remove(GetHighlightActor()); + self.Remove(currentHighlightActor.GetHandle()); + currentHighlightActor = {}; SetCurrentlyHighlightedActor({}); EmitHighlighted(false); return true; diff --git a/dali-toolkit/devel-api/controls/accessible-impl.h b/dali-toolkit/devel-api/controls/accessible-impl.h index feffe75..ff31c1e 100644 --- a/dali-toolkit/devel-api/controls/accessible-impl.h +++ b/dali-toolkit/devel-api/controls/accessible-impl.h @@ -19,6 +19,7 @@ // EXTERNAL INCLUDES #include #include +#include // INTERNAL INCLUDES #include @@ -46,6 +47,7 @@ struct DALI_TOOLKIT_API AccessibleImpl : public virtual Dali::Accessibility::Acc public virtual Dali::Accessibility::Action { Dali::Actor self; + Dali::WeakHandle currentHighlightActor; bool modal = false, root = false; AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role, bool modal = false); 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 0b4334e..77ed805 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 @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXT_EDITOR_DEVEL_H /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -181,6 +181,12 @@ enum Type * @details Name "primaryCursorPosition", type Property::INTEGER. */ PRIMARY_CURSOR_POSITION, + + /** + * @brief The color of the grab color. + * @details Name "grabHandleColor", type Property::VECTOR4. + */ + GRAB_HANDLE_COLOR, }; } // namespace Property diff --git a/dali-toolkit/devel-api/controls/text-controls/text-field-devel.h b/dali-toolkit/devel-api/controls/text-controls/text-field-devel.h index 8c8229d..ac239ef 100644 --- a/dali-toolkit/devel-api/controls/text-controls/text-field-devel.h +++ b/dali-toolkit/devel-api/controls/text-controls/text-field-devel.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXT_FIELD_DEVEL_H /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -167,7 +167,13 @@ enum */ PRIMARY_CURSOR_POSITION, + /** + * @brief The color of the grab color. + * @details Name "grabHandleColor", type Property::VECTOR4. + */ + GRAB_HANDLE_COLOR, }; + } // namespace Property /** diff --git a/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp b/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp index e3f4209..3a20928 100644 --- a/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp +++ b/dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp @@ -132,9 +132,7 @@ Actor AccessibilityManager::GetActorByFocusOrder(const unsigned int order) bool AccessibilityManager::SetCurrentFocusActor(Actor actor) { - Dali::Accessibility::Accessible::SetCurrentlyHighlightedActor(actor); - - return true; + return Toolkit::DevelControl::GrabAccessibilityHighlight(actor); } Actor AccessibilityManager::GetCurrentFocusActor() diff --git a/dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp b/dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp index 3f4188b..c01b2f2 100644 --- a/dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp @@ -95,7 +95,8 @@ Dali::Accessibility::States CheckBoxButton::AccessibleImpl::CalculateStates() void CheckBoxButton::OnStateChange(State newState) { // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used - if(Dali::Accessibility::IsUp() && (newState == SELECTED_STATE || newState == UNSELECTED_STATE)) + if(Dali::Accessibility::IsUp() && (Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) + && (newState == SELECTED_STATE || newState == UNSELECTED_STATE)) { Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged( Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0); diff --git a/dali-toolkit/internal/controls/buttons/push-button-impl.cpp b/dali-toolkit/internal/controls/buttons/push-button-impl.cpp index b5a4233..ee9f9f1 100644 --- a/dali-toolkit/internal/controls/buttons/push-button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/push-button-impl.cpp @@ -205,7 +205,8 @@ Dali::Accessibility::States PushButton::AccessibleImpl::CalculateStates() void PushButton::OnStateChange(State newState) { // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used - if(Dali::Accessibility::IsUp() && (newState == SELECTED_STATE || newState == UNSELECTED_STATE)) + if(Dali::Accessibility::IsUp() && (Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) + && (newState == SELECTED_STATE || newState == UNSELECTED_STATE)) { Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged( Dali::Accessibility::State::PRESSED, newState == SELECTED_STATE ? 1 : 0, 0); diff --git a/dali-toolkit/internal/controls/buttons/radio-button-impl.cpp b/dali-toolkit/internal/controls/buttons/radio-button-impl.cpp index ba3348a..aae430b 100644 --- a/dali-toolkit/internal/controls/buttons/radio-button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/radio-button-impl.cpp @@ -104,7 +104,8 @@ void RadioButton::OnStateChange(State newState) } } // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used - if(Dali::Accessibility::IsUp() && (newState == SELECTED_STATE || newState == UNSELECTED_STATE)) + if(Dali::Accessibility::IsUp() && (Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) + && (newState == SELECTED_STATE || newState == UNSELECTED_STATE)) { Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged( Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0); diff --git a/dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp b/dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp index b141fbd..8ec931f 100644 --- a/dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp @@ -398,15 +398,12 @@ Property::Index ToggleButton::AccessibleImpl::GetDescriptionPropertyIndex() void ToggleButton::OnStateChange(State newState) { // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used - if(Dali::Accessibility::IsUp() && (newState == SELECTED_STATE || newState == UNSELECTED_STATE)) + if(Dali::Accessibility::IsUp() && (Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor()) + && (newState == SELECTED_STATE || newState == UNSELECTED_STATE)) { Dali::Accessibility::Accessible::Get(Self())->EmitStateChanged( Dali::Accessibility::State::CHECKED, mCurrentToggleIndex ? 1 : 0, 0); - - if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor()) - { Dali::Accessibility::Accessible::Get(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION); - } } } diff --git a/dali-toolkit/internal/controls/camera-view/camera-view-impl.cpp b/dali-toolkit/internal/controls/camera-view/camera-view-impl.cpp new file mode 100644 index 0000000..9ca121b --- /dev/null +++ b/dali-toolkit/internal/controls/camera-view/camera-view-impl.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2021 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 "camera-view-impl.h" + +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal +{ +namespace +{ +BaseHandle Create() +{ + return Toolkit::CameraView::New(NULL); +} + +DALI_TYPE_REGISTRATION_BEGIN(Toolkit::CameraView, Toolkit::Control, Create) +DALI_TYPE_REGISTRATION_END() +} // namespace + +CameraView::CameraView(Dali::Toolkit::CameraView::DisplayType displayType) +: Control(ControlBehaviour(ACTOR_BEHAVIOUR_DEFAULT | DISABLE_STYLE_CHANGE_SIGNALS)), + mDisplayType(displayType) +{ +} + +CameraView::~CameraView() +{ +} + +Toolkit::CameraView CameraView::New(Any cameraHandle, Dali::Toolkit::CameraView::DisplayType type) +{ + CameraView* impl = new CameraView(type); + Toolkit::CameraView handle = Toolkit::CameraView(*impl); + impl->mCameraPlayer = Dali::CameraPlayer::New(); + impl->Initialize(); + if(impl->mCameraPlayer) + { + impl->mCameraPlayer.SetCameraPlayer(cameraHandle); + } + return handle; +} + +void CameraView::Update() +{ + UpdateDisplayArea(mSizeUpdateNotification); +} + +void CameraView::OnSceneConnection(int depth) +{ + Control::OnSceneConnection(depth); + if(mDisplayType == Dali::Toolkit::CameraView::DisplayType::WINDOW) + { + SetWindowSurfaceTarget(); + } + else if(mDisplayType == Dali::Toolkit::CameraView::DisplayType::IMAGE) + { + SetNativeImageTarget(); + } + RelayoutRequest(); +} + +void CameraView::OnSceneDisconnection() +{ + Control::OnSceneDisconnection(); + Actor self = Self(); + if(mTextureRenderer) + { + self.RemoveRenderer(mTextureRenderer); + mTextureRenderer.Reset(); + } + + if(mOverlayRenderer) + { + self.RemoveRenderer(mOverlayRenderer); + mOverlayRenderer.Reset(); + } +} + +void CameraView::SetWindowSurfaceTarget() +{ + Actor self = Self(); + + mPositionUpdateNotification = self.AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f)); + mSizeUpdateNotification = self.AddPropertyNotification(Actor::Property::SIZE, StepCondition(1.0f, 1.0f)); + mScaleUpdateNotification = self.AddPropertyNotification(Actor::Property::WORLD_SCALE, StepCondition(0.1f, 1.0f)); + mPositionUpdateNotification.NotifySignal().Connect(this, &CameraView::UpdateDisplayArea); + mSizeUpdateNotification.NotifySignal().Connect(this, &CameraView::UpdateDisplayArea); + mScaleUpdateNotification.NotifySignal().Connect(this, &CameraView::UpdateDisplayArea); + + // For underlay rendering mode, camera display area have to be transparent. + Geometry geometry = VisualFactoryCache::CreateQuadGeometry(); + Shader shader = Shader::New(SHADER_VIDEO_VIEW_VERT, SHADER_VIDEO_VIEW_FRAG); + mOverlayRenderer = Renderer::New(geometry, shader); + mOverlayRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::OFF); + + Self().AddRenderer(mOverlayRenderer); + + // Note CameraPlayer::SetWindowRenderingTarget + mCameraPlayer.SetWindowRenderingTarget(DevelWindow::Get(self)); +} + +void CameraView::SetNativeImageTarget() +{ + Actor self(Self()); + + self.RemovePropertyNotification(mPositionUpdateNotification); + self.RemovePropertyNotification(mSizeUpdateNotification); + self.RemovePropertyNotification(mScaleUpdateNotification); + + Any source; + Dali::NativeImageSourcePtr nativeImageSourcePtr = Dali::NativeImageSource::New(source); + mNativeTexture = Dali::Texture::New(*nativeImageSourcePtr); + + Dali::Geometry geometry = VisualFactoryCache::CreateQuadGeometry(); + Dali::Shader shader = CreateShader(nativeImageSourcePtr->GetCustomFragmentPrefix()); + Dali::TextureSet textureSet = Dali::TextureSet::New(); + textureSet.SetTexture(0u, mNativeTexture); + + mTextureRenderer = Renderer::New(geometry, shader); + mTextureRenderer.SetTextures(textureSet); + + Self().AddRenderer(mTextureRenderer); + + // Note CameraPlayer::SetNativeImageRenderingTarget. + mCameraPlayer.SetNativeImageRenderingTarget(nativeImageSourcePtr); +} + +void CameraView::UpdateDisplayArea(Dali::PropertyNotification& source) +{ + if(mDisplayType != Dali::Toolkit::CameraView::DisplayType::WINDOW) + { + return; + } + + Actor self(Self()); + + bool positionUsesAnchorPoint = self.GetProperty(Actor::Property::POSITION_USES_ANCHOR_POINT).Get(); + Vector3 actorSize = self.GetCurrentProperty(Actor::Property::SIZE) * self.GetCurrentProperty(Actor::Property::WORLD_SCALE); + Vector3 anchorPointOffSet = actorSize * (positionUsesAnchorPoint ? self.GetCurrentProperty(Actor::Property::ANCHOR_POINT) : AnchorPoint::TOP_LEFT); + + Vector2 screenPosition = self.GetProperty(Actor::Property::SCREEN_POSITION).Get(); + + mDisplayArea.x = screenPosition.x - anchorPointOffSet.x; + mDisplayArea.y = screenPosition.y - anchorPointOffSet.y; + mDisplayArea.width = actorSize.x; + mDisplayArea.height = actorSize.y; + + mCameraPlayer.SetDisplayArea(mDisplayArea); +} + +Dali::Shader CameraView::CreateShader(const char* fragmentPrefix) +{ + std::string fragmentShader = fragmentPrefix; + std::string vertexShader; + + vertexShader = SHADER_VIDEO_VIEW_TEXTURE_VERT.data(); + fragmentShader += SHADER_VIDEO_VIEW_TEXTURE_FRAG.data(); + + return Dali::Shader::New(vertexShader, fragmentShader); +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali \ No newline at end of file diff --git a/dali-toolkit/internal/controls/camera-view/camera-view-impl.h b/dali-toolkit/internal/controls/camera-view/camera-view-impl.h new file mode 100644 index 0000000..6c77889 --- /dev/null +++ b/dali-toolkit/internal/controls/camera-view/camera-view-impl.h @@ -0,0 +1,144 @@ +#ifndef DALI_TOOLKIT_INTERNAL_CAMERA_VIEW_H +#define DALI_TOOLKIT_INTERNAL_CAMERA_VIEW_H + +/* + * Copyright (c) 2021 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 +#include +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +class CameraView; + +namespace Internal +{ +class CameraView : public Control +{ +protected: + /** + * @brief Constructor. + * @param[in] type Where it is an overlay type or a native image type + */ + CameraView(Dali::Toolkit::CameraView::DisplayType type); + + /** + * @brief Destructor + */ + virtual ~CameraView(); + +public: + /** + * @brief Creates an initialized CameraView. + * @param[in] handle Multimedia camera player handle + * @param[in] type Where it is an overlay type or a native image type + */ + static Toolkit::CameraView New(Any handle, Dali::Toolkit::CameraView::DisplayType type); + + /** + * @brief Update camera player. + */ + void Update(); + +private: // From Control + /** + * @copydoc Toolkit::Control::OnSceneConnection() + */ + void OnSceneConnection(int depth) override; + + /** + * @copydoc Toolkit::Control::OnSceneDisconnection() + */ + void OnSceneDisconnection() override; + +private: + /** + * @brief Construct a new CameraView. + */ + CameraView(const CameraView& cameraView); + + // Undefined assignment operator. + CameraView& operator=(const CameraView& cameraView); + + /** + * @brief Updates camera display area for window rendering target + * @param[in] source PropertyNotification + */ + void UpdateDisplayArea(Dali::PropertyNotification& source); + + /** + * @brief SetWindowSurfaceTarget for underlay camera preview. + */ + void SetWindowSurfaceTarget(); + + /** + * @brief SetNativeImageTarget for native image camera preview. + */ + void SetNativeImageTarget(); + + /** + * @brief CreateShader for native image target + * @param[in] fragmentPrefix prefix of fragment + * @return Returns the shader for NativeImage. + */ + Dali::Shader CreateShader(const char* fragmentPrefix); + +private: + Dali::CameraPlayer mCameraPlayer; + Dali::Texture mNativeTexture; + + Dali::DisplayArea mDisplayArea; + Dali::Renderer mOverlayRenderer; + Dali::Renderer mTextureRenderer; + + Dali::PropertyNotification mPositionUpdateNotification; + Dali::PropertyNotification mSizeUpdateNotification; + Dali::PropertyNotification mScaleUpdateNotification; + + Dali::Toolkit::CameraView::DisplayType mDisplayType; +}; + +} // namespace Internal + +inline Toolkit::Internal::CameraView& GetImpl(Toolkit::CameraView& handle) +{ + DALI_ASSERT_ALWAYS(handle); + Dali::RefObject& impl = handle.GetImplementation(); + return static_cast(impl); +} + +inline const Toolkit::Internal::CameraView& GetImpl(const Toolkit::CameraView& handle) +{ + DALI_ASSERT_ALWAYS(handle); + const Dali::RefObject& impl = handle.GetImplementation(); + return static_cast(impl); +} + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_INTERNAL_CAMERA_VIEW_H \ No newline at end of file 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 4e7d3f0..19c26c5 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp @@ -146,6 +146,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "enableEditing", DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY(Toolkit, TextEditor, "selectedText", STRING, SELECTED_TEXT ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "fontSizeScale", FLOAT, FONT_SIZE_SCALE ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "primaryCursorPosition", INTEGER, PRIMARY_CURSOR_POSITION ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "grabHandleColor", VECTOR4, GRAB_HANDLE_COLOR ) DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED ) DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED) @@ -764,6 +765,15 @@ void TextEditor::SetProperty(BaseObject* object, Property::Index index, const Pr } break; } + case Toolkit::DevelTextEditor::Property::GRAB_HANDLE_COLOR: + { + const Vector4 color = value.Get(); + DALI_LOG_INFO(gLogFilter, Debug::General, "TextEditor %p GRAB_HANDLE_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a); + + impl.mDecorator->SetHandleColor(color); + impl.RequestTextRelayout(); + break; + } } // switch } // texteditor } @@ -1120,6 +1130,11 @@ Property::Value TextEditor::GetProperty(BaseObject* object, Property::Index inde value = static_cast(impl.mController->GetPrimaryCursorPosition()); break; } + case Toolkit::DevelTextEditor::Property::GRAB_HANDLE_COLOR: + { + value = impl.mDecorator->GetHandleColor(); + break; + } } //switch } @@ -1384,7 +1399,7 @@ float TextEditor::GetHeightForWidth(float width) void TextEditor::ResizeActor(Actor& actor, const Vector2& size) { - if (actor.GetProperty(Dali::Actor::Property::SIZE).GetVectorXY() != size) + if(actor.GetProperty(Dali::Actor::Property::SIZE).GetVectorXY() != size) { actor.SetProperty(Actor::Property::SIZE, size); } @@ -1446,6 +1461,14 @@ void TextEditor::OnRelayout(const Vector2& size, RelayoutContainer& container) } RenderText(updateTextType); + + // If there is text changed, callback is called. + if(mTextChanged) + { + Dali::Toolkit::TextEditor handle(GetOwner()); + mTextChangedSignal.Emit(handle); + mTextChanged = false; + } } // The text-editor emits signals when the input style changes. These changes of style are @@ -1661,8 +1684,7 @@ void TextEditor::CaretMoved(unsigned int position) void TextEditor::TextChanged() { - Dali::Toolkit::TextEditor handle(GetOwner()); - mTextChangedSignal.Emit(handle); + mTextChanged = true; } void TextEditor::MaxLengthReached() @@ -1984,7 +2006,8 @@ TextEditor::TextEditor() mHasBeenStaged(false), mScrollAnimationEnabled(false), mScrollBarEnabled(false), - mScrollStarted(false) + mScrollStarted(false), + mTextChanged(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 866c444..4c408ca 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h @@ -362,7 +362,7 @@ private: // Implementation * @param[in] actor The actor to be resized. * @param[in] size Size to change. */ - void ResizeActor( Actor& actor, const Vector2& size ); + void ResizeActor(Actor& actor, const Vector2& size); /** * @brief Render view, create and attach actor(s) to this text editor. @@ -402,6 +402,7 @@ private: // Data bool mScrollAnimationEnabled : 1; bool mScrollBarEnabled : 1; bool mScrollStarted : 1; + bool mTextChanged : 1; struct AccessibleImpl : public DevelControl::AccessibleImpl, public virtual Dali::Accessibility::Text, diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp index 8b60fbe..d29bfad 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -137,6 +137,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "selectedTextEnd" DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "enableEditing", BOOLEAN, ENABLE_EDITING ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "fontSizeScale", FLOAT, FONT_SIZE_SCALE ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "primaryCursorPosition", INTEGER, PRIMARY_CURSOR_POSITION ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "grabHandleColor", VECTOR4, GRAB_HANDLE_COLOR ) DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "textChanged", SIGNAL_TEXT_CHANGED ) DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED ) @@ -754,6 +755,15 @@ void TextField::SetProperty(BaseObject* object, Property::Index index, const Pro } break; } + case Toolkit::DevelTextField::Property::GRAB_HANDLE_COLOR: + { + const Vector4 color = value.Get(); + DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p GRAB_HANDLE_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a); + + impl.mDecorator->SetHandleColor(color); + impl.RequestTextRelayout(); + break; + } } // switch } // textfield } @@ -1104,6 +1114,11 @@ Property::Value TextField::GetProperty(BaseObject* object, Property::Index index value = static_cast(impl.mController->GetPrimaryCursorPosition()); break; } + case Toolkit::DevelTextField::Property::GRAB_HANDLE_COLOR: + { + value = impl.mDecorator->GetHandleColor(); + break; + } } //switch } @@ -1335,7 +1350,7 @@ float TextField::GetHeightForWidth(float width) void TextField::ResizeActor(Actor& actor, const Vector2& size) { - if (actor.GetProperty(Dali::Actor::Property::SIZE).GetVectorXY() != size) + if(actor.GetProperty(Dali::Actor::Property::SIZE).GetVectorXY() != size) { actor.SetProperty(Actor::Property::SIZE, size); } @@ -1397,6 +1412,14 @@ void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container) } RenderText(updateTextType); + + // If there is text changed, callback is called. + if(mTextChanged) + { + Dali::Toolkit::TextField handle(GetOwner()); + mTextChangedSignal.Emit(handle); + mTextChanged = false; + } } // The text-field emits signals when the input style changes. These changes of style are @@ -1689,8 +1712,7 @@ void TextField::CaretMoved(unsigned int position) void TextField::TextChanged() { - Dali::Toolkit::TextField handle(GetOwner()); - mTextChangedSignal.Emit(handle); + mTextChanged = true; } void TextField::MaxLengthReached() @@ -1867,7 +1889,8 @@ TextField::TextField() mAlignmentOffset(0.f), mRenderingBackend(DEFAULT_RENDERING_BACKEND), mExceedPolicy(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP), - mHasBeenStaged(false) + mHasBeenStaged(false), + mTextChanged(false) { } diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.h b/dali-toolkit/internal/controls/text-controls/text-field-impl.h index 2fae0bb..07a7a37 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.h @@ -318,7 +318,7 @@ private: // Implementation * @param[in] actor The actor to be resized. * @param[in] size Size to change. */ - void ResizeActor( Actor& actor, const Vector2& size ); + void ResizeActor(Actor& actor, const Vector2& size); /** * @brief Render view, create and attach actor(s) to this Text Field. @@ -357,6 +357,7 @@ private: // Data int mRenderingBackend; int mExceedPolicy; bool mHasBeenStaged : 1; + bool mTextChanged : 1; protected: struct AccessibleImpl : public DevelControl::AccessibleImpl, diff --git a/dali-toolkit/internal/controls/video-view/video-view-impl.cpp b/dali-toolkit/internal/controls/video-view/video-view-impl.cpp index 5608105..85b219e 100644 --- a/dali-toolkit/internal/controls/video-view/video-view-impl.cpp +++ b/dali-toolkit/internal/controls/video-view/video-view-impl.cpp @@ -83,6 +83,8 @@ const char* const CUSTOM_FRAGMENT_SHADER("fragmentShader"); const char* const DEFAULT_SAMPLER_TYPE_NAME("sampler2D"); const char* const CUSTOM_SAMPLER_TYPE_NAME("samplerExternalOES"); +const char* const IS_VIDEO_VIEW_PROPERTY_NAME = "isVideoView"; + } // namespace VideoView::VideoView(Dali::VideoSyncMode syncMode) @@ -91,7 +93,8 @@ VideoView::VideoView(Dali::VideoSyncMode syncMode) mFrameID(0), mIsPlay(false), mIsUnderlay(true), - mSyncMode(syncMode) + mSyncMode(syncMode), + mSiblingOrder(0) { } @@ -111,12 +114,16 @@ Toolkit::VideoView VideoView::New(VideoSyncMode syncMode) void VideoView::OnInitialize() { + Actor self = Self(); mVideoPlayer.FinishedSignal().Connect(this, &VideoView::EmitSignalFinish); - DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) { + DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) { return std::unique_ptr( new DevelControl::AccessibleImpl(actor, Dali::Accessibility::Role::VIDEO)); }); + + //update self property + self.RegisterProperty(IS_VIDEO_VIEW_PROPERTY_NAME, true, Property::READ_WRITE); } void VideoView::SetUrl(const std::string& url) @@ -503,12 +510,15 @@ void VideoView::SetDepthIndex(int depthIndex) void VideoView::OnSceneConnection(int depth) { - Control::OnSceneConnection(depth); - + Actor self = Self(); if(mIsUnderlay) { + mSiblingOrder = self.GetProperty(Dali::DevelActor::Property::SIBLING_ORDER); + DevelActor::ChildOrderChangedSignal(self.GetParent()).Connect(this, &VideoView::OnChildOrderChanged); SetWindowSurfaceTarget(); } + + Control::OnSceneConnection(depth); } void VideoView::OnSceneDisconnection() @@ -526,6 +536,57 @@ void VideoView::OnSizeSet(const Vector3& targetSize) Control::OnSizeSet(targetSize); } +void VideoView::OnChildOrderChanged(Actor actor) +{ + Actor self = Self(); + int currentSiblingOrder = self.GetProperty(Dali::DevelActor::Property::SIBLING_ORDER); + if(currentSiblingOrder != mSiblingOrder) + { + Actor parent = self.GetParent(); + Actor child; + Actor upper; + Actor lower; + + int numChildren = static_cast(parent.GetChildCount()); + for(int i = 0; i < numChildren; i++) + { + child = parent.GetChildAt(i); + if(!IsVideoView(child)) + { + continue; + } + + if(child == self) + { + continue; + } + + if(i < currentSiblingOrder) + { + lower = child; + } + else if(i > currentSiblingOrder) + { + upper = child; + break; + } + } + + if(lower) + { + Toolkit::VideoView lowerView = Toolkit::VideoView::DownCast(lower); + mVideoPlayer.RaiseAbove(GetImpl(lowerView).GetVideoPlayer()); + } + + if(upper) + { + Toolkit::VideoView upperView = Toolkit::VideoView::DownCast(upper); + mVideoPlayer.LowerBelow(GetImpl(upperView).GetVideoPlayer()); + } + mSiblingOrder = currentSiblingOrder; + } +} + Vector3 VideoView::GetNaturalSize() { Vector3 size; @@ -577,6 +638,9 @@ void VideoView::SetWindowSurfaceTarget() return; } + Dali::Window window = DevelWindow::Get(self); + window.ResizeSignal().Connect(this, &VideoView::OnWindowResized); + int curPos = mVideoPlayer.GetPlayPosition(); if(mIsPlay) @@ -782,6 +846,17 @@ void VideoView::OnAnimationFinished(Animation& animation) SetFrameRenderCallback(); } +void VideoView::OnWindowResized(Dali::Window winHandle, Dali::Window::WindowSize size) +{ + Dali::VideoPlayerPlugin::DisplayRotation videoAngle = mVideoPlayer.GetDisplayRotation(); + int windowAngle = (DevelWindow::GetPhysicalOrientation(winHandle) / 90); + + if(windowAngle != videoAngle) + { + mVideoPlayer.SetDisplayRotation(static_cast(windowAngle)); + } +} + void VideoView::PlayAnimation(Dali::Animation animation) { if(mIsUnderlay && mSyncMode == Dali::VideoSyncMode::ENABLED) @@ -879,6 +954,28 @@ void VideoView::SetFrameRenderCallback() mFrameID); } +bool VideoView::IsVideoView(Actor actor) const +{ + // Check whether the actor is a VideoView + bool isVideoView = false; + + if(actor) + { + Property::Index propertyIsVideoView = actor.GetPropertyIndex(IS_VIDEO_VIEW_PROPERTY_NAME); + if(propertyIsVideoView != Property::INVALID_INDEX) + { + isVideoView = actor.GetProperty(propertyIsVideoView); + } + } + + return isVideoView; +} + +VideoPlayer VideoView::GetVideoPlayer() +{ + return mVideoPlayer; +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/video-view/video-view-impl.h b/dali-toolkit/internal/controls/video-view/video-view-impl.h index 4d76176..d1605ce 100644 --- a/dali-toolkit/internal/controls/video-view/video-view-impl.h +++ b/dali-toolkit/internal/controls/video-view/video-view-impl.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -262,6 +263,21 @@ public: */ void PlayAnimation(Dali::Animation animation); + /** + * @brief Checks whether the actor is set as a video view or not. + * + * @param[in] actor The actor to be checked + * @return True if actor is video view. + */ + bool IsVideoView(Actor actor) const; + + /** + * @brief Gets the Video Player. + * + * @return The return of video player. + */ + VideoPlayer GetVideoPlayer(); + private: // From Control /** * @copydoc Toolkit::Control::OnInitialize() @@ -365,6 +381,22 @@ private: */ void OnAnimationFinished(Dali::Animation& animation); + /* + * @brief window's resize callback function + * This function is called when window is resized. + * + * @param[in] winHandle The resized window's handle. + * @param[in] size The window's new size. + */ + void OnWindowResized(Dali::Window winHandle, Dali::Window::WindowSize size); + + /** + * @brief This signal is emitted when an actor's children change their sibling order + * + * @param[in] actor parent actor. + */ + void OnChildOrderChanged(Actor actor); + private: Dali::VideoPlayer mVideoPlayer; Dali::ImageDimensions mVideoSize; @@ -392,6 +424,7 @@ private: bool mIsUnderlay; Dali::VideoSyncMode mSyncMode; + int mSiblingOrder; }; } // namespace Internal diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index c26fc7c..4703752 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -106,6 +106,7 @@ SET( toolkit_src_files ${toolkit_src_dir}/controls/tooltip/tooltip.cpp ${toolkit_src_dir}/controls/video-view/video-view-impl.cpp ${toolkit_src_dir}/controls/web-view/web-view-impl.cpp + ${toolkit_src_dir}/controls/camera-view/camera-view-impl.cpp ${toolkit_src_dir}/accessibility-manager/accessibility-manager-impl.cpp ${toolkit_src_dir}/feedback/feedback-style.cpp diff --git a/dali-toolkit/internal/text/decorator/text-decorator.cpp b/dali-toolkit/internal/text/decorator/text-decorator.cpp index 237649a..c586deb 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.cpp +++ b/dali-toolkit/internal/text/decorator/text-decorator.cpp @@ -971,10 +971,7 @@ struct Decorator::Impl : public ConnectionTracker // The SetGrabHandleImage() method will change the orientation. const float yLocalPosition = grabHandle.verticallyFlipped ? grabHandle.position.y : grabHandle.position.y + grabHandle.lineHeight; - if(grabHandle.actor) - { - grabHandle.actor.SetProperty(Actor::Property::POSITION, Vector2(grabHandle.position.x + floor(0.5f * mCursorWidth) + (mSmoothHandlePanEnabled ? grabHandle.grabDisplacementX : 0.f), yLocalPosition + (mSmoothHandlePanEnabled ? grabHandle.grabDisplacementY : 0.f))); - } + ApplyDisplacement(grabHandle, yLocalPosition); } void SetSelectionHandlePosition(HandleType type) @@ -1063,10 +1060,47 @@ struct Decorator::Impl : public ConnectionTracker // The SetHandleImage() method will change the orientation. const float yLocalPosition = handle.verticallyFlipped ? handle.position.y : handle.position.y + handle.lineHeight; - if(handle.actor) + ApplyDisplacement(handle, yLocalPosition); + } + + void ApplyDisplacement(HandleImpl& handle, float yLocalPosition) + { + if( handle.actor ) + { + float adjustedDisplacementX = 0.0f; + float adjustedDisplacementY = 0.0f; + if (mSmoothHandlePanEnabled) + { + adjustedDisplacementX = CalculateAdjustedDisplacement(handle.position.x, handle.grabDisplacementX, mControlSize.x); + adjustedDisplacementY = CalculateAdjustedDisplacement(handle.position.y, handle.grabDisplacementY, (mControlSize.y - handle.lineHeight)); + } + handle.actor.SetProperty(Actor::Property::POSITION, + Vector2(handle.position.x + floor(0.5f * mCursorWidth) + adjustedDisplacementX, + yLocalPosition + adjustedDisplacementY)); + } + } + + float CalculateAdjustedDisplacement(float position, float displacement, float edge) + { + //Apply the displacement (on the X-axis & the Y-axis) + //as long as it does not exceed the control's edge. + float adjustedDisplacement = 0.0f; + if(position + displacement < 0.0f) + { + // -position to cancel it out and relocate to 0. + adjustedDisplacement = -position; + } + else if(position + displacement > edge) + { + // move in a displacement which is sufficient to reach the edge. + adjustedDisplacement = edge - position; + } + else { - handle.actor.SetProperty(Actor::Property::POSITION, Vector2(handle.position.x + (mSmoothHandlePanEnabled ? handle.grabDisplacementX : 0.f), yLocalPosition + (mSmoothHandlePanEnabled ? handle.grabDisplacementY : 0.f))); + // move normally in the displacement. + adjustedDisplacement = displacement; } + return adjustedDisplacement; } void SetHandleImage(HandleType type) diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp index 9952c55..c9623a6 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp @@ -265,8 +265,13 @@ void AnimatedImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const void AnimatedImageVisual::OnDoAction(const Dali::Property::Index actionId, const Dali::Property::Value& attributes) { - // Check if action is valid for this visual type and perform action if possible + // Make not set any action when the resource status is already failed. + if(mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::FAILED) + { + return; + } + // Check if action is valid for this visual type and perform action if possible switch(actionId) { case DevelAnimatedImageVisual::Action::PAUSE: @@ -322,7 +327,6 @@ void AnimatedImageVisual::OnDoAction(const Dali::Property::Index actionId, const void AnimatedImageVisual::DoSetProperties(const Property::Map& propertyMap) { // url[s] already passed in from constructor - for(Property::Map::SizeType iter = 0; iter < propertyMap.Count(); ++iter) { KeyValuePair keyValue = propertyMap.GetKeyValue(iter); @@ -491,6 +495,13 @@ void AnimatedImageVisual::DoSetOnScene(Actor& actor) mPlacementActor = actor; TextureSet textureSet = PrepareTextureSet(); + // Loading animated image file is failed. + if(!mImageCache || + (mAnimatedImageLoading && !mAnimatedImageLoading.HasLoadingSucceeded())) + { + textureSet = SetLoadingFailed(); + } + if(textureSet) // if the image loading is successful { StartFirstFrame(textureSet); @@ -632,8 +643,12 @@ void AnimatedImageVisual::StartFirstFrame(TextureSet& textureSet) mFrameDelayTimer.TickSignal().Connect(this, &AnimatedImageVisual::DisplayNextFrame); mFrameDelayTimer.Start(); } - DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "ResourceReady(ResourceStatus::READY)\n"); - ResourceReady(Toolkit::Visual::ResourceStatus::READY); + + if(mImpl->mResourceStatus != Toolkit::Visual::ResourceStatus::FAILED) + { + DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "ResourceReady(ResourceStatus::READY)\n"); + ResourceReady(Toolkit::Visual::ResourceStatus::READY); + } } TextureSet AnimatedImageVisual::PrepareTextureSet() @@ -667,32 +682,31 @@ void AnimatedImageVisual::SetImageSize(TextureSet& textureSet) void AnimatedImageVisual::FrameReady(TextureSet textureSet) { - if(textureSet) + // When image visual requested to load new frame to mImageCache and it is failed. + if(!textureSet) { - SetImageSize(textureSet); + textureSet = SetLoadingFailed(); + } - if(mStartFirstFrame) - { - StartFirstFrame(textureSet); - } - else - { - if(mImpl->mRenderer) - { - mImpl->mRenderer.SetTextures(textureSet); - } - } + SetImageSize(textureSet); + + if(mStartFirstFrame) + { + StartFirstFrame(textureSet); } else { - DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "ResourceReady(ResourceStatus::FAILED)\n"); - ResourceReady(Toolkit::Visual::ResourceStatus::FAILED); + if(mImpl->mRenderer) + { + mImpl->mRenderer.SetTextures(textureSet); + } } } bool AnimatedImageVisual::DisplayNextFrame() { - bool continueTimer = false; + TextureSet textureSet; + bool continueTimer = false; if(mImageCache) { @@ -756,7 +770,6 @@ bool AnimatedImageVisual::DisplayNextFrame() DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "AnimatedImageVisual::DisplayNextFrame(this:%p) CurrentFrameIndex:%d\n", this, frameIndex); - TextureSet textureSet; if(nextFrame) { textureSet = mImageCache->NextFrame(); @@ -766,21 +779,41 @@ bool AnimatedImageVisual::DisplayNextFrame() textureSet = mImageCache->Frame(frameIndex); } - if(textureSet) + continueTimer = (mActionStatus == DevelAnimatedImageVisual::Action::PLAY) ? true : false; + } + + if(textureSet) + { + SetImageSize(textureSet); + if(mImpl->mRenderer) { - SetImageSize(textureSet); - if(mImpl->mRenderer) - { - mImpl->mRenderer.SetTextures(textureSet); - } + mImpl->mRenderer.SetTextures(textureSet); } - - continueTimer = (mActionStatus == DevelAnimatedImageVisual::Action::PLAY) ? true : false; } return continueTimer; } +TextureSet AnimatedImageVisual::SetLoadingFailed() +{ + DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "ResourceReady(ResourceStatus::FAILED)\n"); + ResourceReady(Toolkit::Visual::ResourceStatus::FAILED); + + TextureSet textureSet = TextureSet::New(); + Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); + textureSet.SetTexture(0u, brokenImage); + + if(mFrameDelayTimer) + { + mFrameDelayTimer.Stop(); + mFrameDelayTimer.Reset(); + } + + SetImageSize(textureSet); + + return textureSet; +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h index 6ccdcbb..608b43f 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h @@ -228,6 +228,12 @@ private: */ void InitializeAnimatedImage(const VisualUrl& imageUrl); + /** + * Set the state of loading fail of an image or a frame. + * Returns TextureSet of broken image. + */ + TextureSet SetLoadingFailed(); + // Undefined AnimatedImageVisual(const AnimatedImageVisual& animatedImageVisual); diff --git a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp index 4e95dfe..bb8571d 100644 --- a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp +++ b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp @@ -22,6 +22,7 @@ #include #include #include +#include // INTERNAL INCLUDES #include @@ -364,7 +365,7 @@ NPatchVisual::NPatchVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFa NPatchVisual::~NPatchVisual() { - if((mId != NPatchData::INVALID_NPATCH_DATA_ID) && (mReleasePolicy != Toolkit::ImageVisual::ReleasePolicy::NEVER)) + if(Stage::IsInstalled() && (mId != NPatchData::INVALID_NPATCH_DATA_ID) && (mReleasePolicy != Toolkit::ImageVisual::ReleasePolicy::NEVER)) { mLoader.Remove(mId, this); mId = NPatchData::INVALID_NPATCH_DATA_ID; diff --git a/dali-toolkit/public-api/controls/camera-view/camera-view.cpp b/dali-toolkit/public-api/controls/camera-view/camera-view.cpp new file mode 100644 index 0000000..297521e --- /dev/null +++ b/dali-toolkit/public-api/controls/camera-view/camera-view.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 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 + +// INTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Toolkit +{ +CameraView::CameraView() +{ +} + +CameraView::CameraView(const CameraView& cameraView) = default; + +CameraView::CameraView(CameraView&& rhs) = default; + +CameraView& CameraView::operator=(const CameraView& cameraView) = default; + +CameraView& CameraView::operator=(CameraView&& rhs) = default; + +CameraView::~CameraView() +{ +} + +CameraView CameraView::New(Any handle, DisplayType type) +{ + return Internal::CameraView::New(handle, type); +} + +CameraView CameraView::DownCast(BaseHandle handle) +{ + return Control::DownCast(handle); +} + +void CameraView::Update() +{ + Dali::Toolkit::GetImpl(*this).Update(); +} + +CameraView::CameraView(Internal::CameraView& implementation) +: Control(implementation) +{ +} + +CameraView::CameraView(Dali::Internal::CustomActor* internal) +: Control(internal) +{ + VerifyCustomActorPointer(internal); +} + +} // namespace Toolkit + +} // namespace Dali \ No newline at end of file diff --git a/dali-toolkit/public-api/controls/camera-view/camera-view.h b/dali-toolkit/public-api/controls/camera-view/camera-view.h new file mode 100644 index 0000000..3cf9845 --- /dev/null +++ b/dali-toolkit/public-api/controls/camera-view/camera-view.h @@ -0,0 +1,152 @@ +#ifndef DALI_TOOLKIT_CAMERA_VIEW_H +#define DALI_TOOLKIT_CAMERA_VIEW_H + +/* + * Copyright (c) 2021 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 +{ +class Any; + +namespace Toolkit +{ +namespace Internal DALI_INTERNAL +{ +class CameraView; +} // namespace DALI_INTERNAL + +/** + * @addtogroup dali_toolkit_controls_camera_view + * @{ + */ + +/** + * @brief CameraView is a control for camera display. + * + * For working CameraView, a camera plugin for a platform should be provided. + */ +class DALI_TOOLKIT_API CameraView : public Control +{ +public: + /** + * @brief Camera display type + */ + enum class DisplayType + { + WINDOW = 0, // Overlay type + IMAGE // Native Image type + }; + + /** + * @brief Creates an initialized CameraView. + * @param[in] handle Multimedia camera player handle + * @param[in] type Where it is an overlay type or a native image type + * @return A handle to a newly allocated Dali ImageView + */ + static CameraView New(Any handle, DisplayType type = DisplayType::WINDOW); + + /** + * @brief Creates an uninitialized CameraView. + */ + CameraView(); + + /** + * @brief Destructor. + * + * This is non-virtual since derived Handel types must not contain data or virtual methods. + */ + ~CameraView(); + + /** + * @brief Copy constructor. + * + * @param[in] CameraView CameraView to copy. The copied CameraView will point at the same implementation + */ + CameraView(const CameraView& CameraView); + + /** + * @brief Move constructor + * + * @param[in] rhs A reference to the moved handle + */ + CameraView(CameraView&& rhs); + + /** + * @brief Update camera view + * + * Multimedia camera operation is work outside the view. + * So, This must be called when the view needs to be updated after camera operation. + */ + void Update(); + + /** + * @brief Assignment operator. + * + * @param[in] CameraView The CameraView to assign from + * @return The updated CameraView + */ + CameraView& operator=(const CameraView& CameraView); + + /** + * @brief Move assignment + * + * @param[in] rhs A reference to the moved handle + * @return A reference to this + */ + CameraView& operator=(CameraView&& rhs); + + /** + * @brief Downcasts a handle to CameraView handle. + * + * If handle points to a CameraView, the downcast produces valid handle. + * If not, the returned handle is left uninitialized. + * + * @param[in] handle Handle to an object + * @return Handle to a CameraView or an uninitialized handle + */ + static CameraView DownCast(BaseHandle handle); + +public: // Not intended for application developers + /// @cond internal + /** + * @brief Creates a handle using the Toolkit::Internal implementation. + * + * @param[in] implementation The CameraView implementation + */ + DALI_INTERNAL CameraView(Internal::CameraView& implementation); + + /** + * @brief Allows the creation of this CameraView from an Internal::CustomActor pointer. + * + * @param[in] internal A pointer to the internal CustomActor + */ + DALI_INTERNAL CameraView(Dali::Internal::CustomActor* internal); + /// @endcond +}; + +/** + * @} + */ + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_CAMERA_VIEW_H diff --git a/dali-toolkit/public-api/dali-toolkit-version.cpp b/dali-toolkit/public-api/dali-toolkit-version.cpp index 0f69e0d..5a75711 100644 --- a/dali-toolkit/public-api/dali-toolkit-version.cpp +++ b/dali-toolkit/public-api/dali-toolkit-version.cpp @@ -29,7 +29,7 @@ namespace Toolkit { const unsigned int TOOLKIT_MAJOR_VERSION = 2; const unsigned int TOOLKIT_MINOR_VERSION = 0; -const unsigned int TOOLKIT_MICRO_VERSION = 17; +const unsigned int TOOLKIT_MICRO_VERSION = 18; const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/dali-toolkit/public-api/file.list b/dali-toolkit/public-api/file.list index df039c8..76863a7 100644 --- a/dali-toolkit/public-api/file.list +++ b/dali-toolkit/public-api/file.list @@ -26,6 +26,7 @@ SET( public_api_src_files ${public_api_src_dir}/controls/text-controls/text-label.cpp ${public_api_src_dir}/controls/text-controls/text-field.cpp ${public_api_src_dir}/controls/video-view/video-view.cpp + ${public_api_src_dir}/controls/camera-view/camera-view.cpp ${public_api_src_dir}/image-loader/image.cpp ${public_api_src_dir}/image-loader/async-image-loader.cpp ${public_api_src_dir}/image-loader/sync-image-loader.cpp @@ -127,6 +128,10 @@ SET( public_api_video_view_header_files ${public_api_src_dir}/controls/video-view/video-view.h ) +SET( public_api_camera_view_header_files + ${public_api_src_dir}/controls/camera-view/camera-view.h +) + SET( public_api_visuals_header_files ${public_api_src_dir}/visuals/border-visual-properties.h ${public_api_src_dir}/visuals/color-visual-properties.h @@ -161,4 +166,5 @@ SET( PUBLIC_API_HEADERS ${PUBLIC_API_HEADERS} ${public_api_text_header_files} ${public_api_video_view_header_files} ${public_api_visuals_header_files} + ${public_api_camera_view_header_files} ) diff --git a/packaging/dali-toolkit.spec b/packaging/dali-toolkit.spec index 81bf0b7..12787c2 100644 --- a/packaging/dali-toolkit.spec +++ b/packaging/dali-toolkit.spec @@ -1,6 +1,6 @@ Name: dali2-toolkit Summary: Dali 3D engine Toolkit -Version: 2.0.17 +Version: 2.0.18 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT @@ -87,8 +87,7 @@ Application development package for Dali 3D engine toolkit - headers and package Summary: DLI scene loading library Group: System/Libraries License: Apache-2.0 - -BuildRequires: pkgconfig(dali2-toolkit) +Requires: dali2-toolkit %description -n %{dali2_scene_loader} Provides functionality for loading and displaying DLI format scenes. See README.md for more details.