From: Adeel Kazmi Date: Thu, 20 Jul 2017 18:14:01 +0000 (+0100) Subject: Added FrameCallback example X-Git-Tag: dali_1.3.40~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F40%2F139840%2F7;p=platform%2Fcore%2Fuifw%2Fdali-demo.git Added FrameCallback example Change-Id: I5b0f866084c75757f3dab94666b61b0f7b37eada --- diff --git a/com.samsung.dali-demo.xml b/com.samsung.dali-demo.xml index 7154829..eca92ec 100644 --- a/com.samsung.dali-demo.xml +++ b/com.samsung.dali-demo.xml @@ -266,6 +266,9 @@ + + + http://tizen.org/privilege/mediastorage diff --git a/examples-reel/dali-examples-reel.cpp b/examples-reel/dali-examples-reel.cpp index e415e49..32d2995 100644 --- a/examples-reel/dali-examples-reel.cpp +++ b/examples-reel/dali-examples-reel.cpp @@ -46,6 +46,7 @@ int DALI_EXPORT_API main(int argc, char **argv) demo.AddExample(Example("dissolve-effect.example", DALI_DEMO_STR_TITLE_DISSOLVE_TRANSITION)); demo.AddExample(Example("effects-view.example", DALI_DEMO_STR_TITLE_EFFECTS_VIEW)); demo.AddExample(Example("flex-container.example", DALI_DEMO_STR_TITLE_FLEXBOX_PLAYGROUND)); + demo.AddExample(Example("frame-callback.example", DALI_DEMO_STR_TITLE_FRAME_CALLBACK)); demo.AddExample(Example("focus-integration.example", DALI_DEMO_STR_TITLE_FOCUS_INTEGRATION)); demo.AddExample(Example("gradients.example", DALI_DEMO_STR_TITLE_COLOR_GRADIENT)); demo.AddExample(Example("hello-world.example", DALI_DEMO_STR_TITLE_HELLO_WORLD)); diff --git a/examples/frame-callback/frame-callback-example.cpp b/examples/frame-callback/frame-callback-example.cpp new file mode 100644 index 0000000..978d087 --- /dev/null +++ b/examples/frame-callback/frame-callback-example.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include "frame-callback.h" + +using namespace Dali; +using namespace Dali::Toolkit; + +namespace +{ +const char * IMAGE_NAME = DEMO_IMAGE_DIR "application-icon-1.png"; + +const char * TEXT_ENABLED( "FrameCallback: ON" ); +const char * TEXT_DISABLED( "FrameCallback: OFF" ); +Vector4 TEXT_COLOR_ENABLED( Color::BLACK ); +Vector4 TEXT_COLOR_DISABLED( Color::RED ); + +float ANIMATION_TIME( 4.0f ); +float ANIMATION_PROGRESS_MULTIPLIER( 0.02f ); +} // unnamed namespace + +/** + * @brief An example of how to set/unset the FrameCallbackInterface in DALi. + * + * Creates a scene with several image-views which are animated from side-to-side. + * With the frame-callback enabled, the image-views' sizes expand as they hits the sides and the opacity + * changes to transparent as they go to the middle. + */ +class FrameCallbackController : public ConnectionTracker +{ +public: + + /** + * @brief Constructor. + * @param[in] application The application. + */ + FrameCallbackController( Application& application ) + : mApplication( application ), + mStage(), + mFrameCallback(), + mTextLabel(), + mTapDetector(), + mFrameCallbackEnabled( false ) + { + // Connect to the Application's Init signal + mApplication.InitSignal().Connect( this, &FrameCallbackController::Create ); + } + +private: + + /** + * @brief Creates the scene. + * + * Creates several image-views and places them appropriately. + * Animate all image-views. + * Set the FrameCallbackInterface on the stage. + * Tapping on the stage enables/disables the FrameCallback. + */ + void Create( Application& /* application */ ) + { + // Hide the indicator bar. + mApplication.GetWindow().ShowIndicator( Dali::Window::INVISIBLE ); + + // Set the stage background color and connect to the stage's key signal to allow Back and Escape to exit. + mStage = Stage::GetCurrent(); + mStage.SetBackgroundColor( Color::WHITE ); + mStage.KeyEventSignal().Connect( this, &FrameCallbackController::OnKeyEvent ); + + // Notify mFrameCallback about the stage width. + // Can call methods in mFrameCallback directly as we have not set it on the stage yet. + Vector2 stageSize = mStage.GetSize(); + mFrameCallback.SetStageWidth( stageSize.width ); + + // Detect taps on the root layer. + mTapDetector = TapGestureDetector::New(); + mTapDetector.Attach( mStage.GetRootLayer() ); + mTapDetector.DetectedSignal().Connect( this, &FrameCallbackController::OnTap ); + + // Create some key-frames to be used by all animations. + KeyFrames keyFrames = KeyFrames::New(); + keyFrames.Add( 0.0f, 0.0f ); + keyFrames.Add( 0.25f, stageSize.width * 0.5f ); + keyFrames.Add( 0.75f, -stageSize.width * 0.5f ); + keyFrames.Add( 1.0f, 0.0f ); + + float yPos = 0.0f; + for( int i = 0; yPos < stageSize.height; ++i ) + { + ImageView imageView = ImageView::New( IMAGE_NAME ); + imageView.SetAnchorPoint( AnchorPoint::TOP_CENTER ); + imageView.SetParentOrigin( ParentOrigin::TOP_CENTER ); + imageView.SetY( yPos ); + yPos += imageView.GetNaturalSize().height; + + // Add the ID of the created ImageView to mFrameCallback. + // Again, can call methods in mFrameCallback directly as we have not set it on the stage yet. + mFrameCallback.AddId( imageView.GetId() ); + + mStage.Add( imageView ); + + // Create an animation and set the progress so that each image starts at a different point. + Animation animation = Animation::New( ANIMATION_TIME ); + animation.SetLooping( true ); + animation.AnimateBetween( Property( imageView, Actor::Property::POSITION_X ), keyFrames ); + animation.SetCurrentProgress( std::min( 1.0f, ANIMATION_PROGRESS_MULTIPLIER * i ) ); + animation.Play(); + } + + // Create a text-label to display whether the FrameCallback is enabled/disabled. + mTextLabel = TextLabel::New( TEXT_ENABLED ); + mTextLabel.SetProperty( TextLabel::Property::TEXT_COLOR, TEXT_COLOR_ENABLED ); + mTextLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); + mTextLabel.SetAnchorPoint( AnchorPoint::CENTER ); + mTextLabel.SetParentOrigin( ParentOrigin::CENTER ); + mStage.Add( mTextLabel ); + + // Set the FrameCallbackInterface on the root layer. + DevelStage::AddFrameCallback( mStage, mFrameCallback, mStage.GetRootLayer() ); + mFrameCallbackEnabled = true; + } + + /** + * @brief Called when a tap on the stage occurs. + * + * Toggle enabling/disabling of the FrameCallbackInterface + */ + void OnTap( Actor /* actor */, const TapGesture& /* tap */ ) + { + if( mFrameCallbackEnabled ) + { + DevelStage::RemoveFrameCallback( mStage, mFrameCallback ); + mTextLabel.SetProperty( TextLabel::Property::TEXT, TEXT_DISABLED ); + mTextLabel.SetProperty( TextLabel::Property::TEXT_COLOR, TEXT_COLOR_DISABLED ); + } + else + { + DevelStage::AddFrameCallback( mStage, mFrameCallback, mStage.GetRootLayer() ); + mTextLabel.SetProperty( TextLabel::Property::TEXT, TEXT_ENABLED ); + mTextLabel.SetProperty( TextLabel::Property::TEXT_COLOR, TEXT_COLOR_ENABLED ); + } + + mFrameCallbackEnabled = !mFrameCallbackEnabled; + } + + /** + * @brief Called when any key event is received + * + * Will use this to quit the application if Back or the Escape key is received + * @param[in] event The key event information + */ + void OnKeyEvent( const KeyEvent& event ) + { + if( event.state == KeyEvent::Down ) + { + if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) ) + { + mApplication.Quit(); + } + } + } + +private: + Application& mApplication; ///< A reference to the application instance. + Stage mStage; ///< The stage we enable the FrameCallback on. + FrameCallback mFrameCallback; ///< An instance of our implementation of the FrameCallbackInterface. + TextLabel mTextLabel; ///< Text label which shows whether the frame-callback is enabled/disabled. + TapGestureDetector mTapDetector; ///< Tap detector to enable/disable the FrameCallbackInterface. + bool mFrameCallbackEnabled; ///< Stores whether the FrameCallbackInterface is enabled/disabled. +}; + +int DALI_EXPORT_API main( int argc, char **argv ) +{ + Application application = Application::New( &argc, &argv ); + FrameCallbackController controller( application ); + application.MainLoop(); + return 0; +} diff --git a/examples/frame-callback/frame-callback.cpp b/examples/frame-callback/frame-callback.cpp new file mode 100644 index 0000000..27c4466 --- /dev/null +++ b/examples/frame-callback/frame-callback.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018 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 "frame-callback.h" + +#include + +using namespace Dali; + +FrameCallback::FrameCallback() +: mActorIdContainer(), + stageHalfWidth( 0.0f ) +{ +} + +void FrameCallback::SetStageWidth( float stageWidth ) +{ + stageHalfWidth = stageWidth * 0.5f; +} + +void FrameCallback::AddId( unsigned int id ) +{ + mActorIdContainer.PushBack( id ); +} + +void FrameCallback::Update( Dali::UpdateProxy& updateProxy, float /* elapsedSeconds */ ) +{ + // Go through Actor ID container and check if we've hit the sides. + for( auto&& i : mActorIdContainer ) + { + Vector3 position; + Vector3 size; + updateProxy.GetPositionAndSize( i, position, size ); // Retrieve the position and size using the Actor ID. + + float halfWidthPoint = stageHalfWidth - size.width * 0.5f; + float xTranslation = std::abs( position.x ); + if( xTranslation > halfWidthPoint ) + { + // Actor has hit the edge, adjust the size accordingly. + float adjustment = xTranslation - halfWidthPoint; + size.width += adjustment * SIZE_MULTIPLIER; + size.height += adjustment * SIZE_MULTIPLIER; + + updateProxy.SetSize( i, size ); // Set the size using the UpdateProxy. + } + + // Retrieve the actor's position and set make it more transparent the closer it is to the middle. + Vector4 color = updateProxy.GetWorldColor( i ); + color.a = xTranslation / halfWidthPoint; + updateProxy.SetWorldColor( i, color ); + } +} diff --git a/examples/frame-callback/frame-callback.h b/examples/frame-callback/frame-callback.h new file mode 100644 index 0000000..c46a517 --- /dev/null +++ b/examples/frame-callback/frame-callback.h @@ -0,0 +1,70 @@ +#ifndef DEMO_FRAME_CALLBACK_H +#define DEMO_FRAME_CALLBACK_H + +/* + * Copyright (c) 2018 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 + +/** + * @brief Implementation of the FrameCallbackInterface. + * + * When this is used, it will expand the size of the actors the closer they get to the horizontal edge + * and make the actor transparent the closer it gets to the middle. + */ +class FrameCallback : public Dali::FrameCallbackInterface +{ +public: + + /** + * @brief Constructor. + */ + FrameCallback(); + + /** + * @brief Sets the stage width. + * @param[in] stageWidth The stage width. + */ + void SetStageWidth( float stageWidth ); + + /** + * @brief The actor with the specified ID will be changed when Update() is called. + * @param[in] id Actor ID of actor which should be changed by the FrameCallback. + */ + void AddId( unsigned int id ); + +private: + + /** + * @brief Called when every frame is updated. + * @param[in] updateProxy Used to set the world-matrix and sizes. + * @param[in] elapsedSeconds Time elapsed time since the last frame (in seconds) + */ + virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds ); + +private: + + Dali::Vector< unsigned int > mActorIdContainer; ///< Container of Actor IDs. + float stageHalfWidth; ///< Half the width of the stage. Center is 0,0 in the world matrix. + + constexpr static float SIZE_MULTIPLIER = 2.0f; ///< Multiplier for the size to set as the actors hit the edge. +}; + +#endif // DEMO_FRAME_CALLBACK_H diff --git a/resources/po/en_GB.po b/resources/po/en_GB.po index 13b73cf..964aa9c 100755 --- a/resources/po/en_GB.po +++ b/resources/po/en_GB.po @@ -61,6 +61,9 @@ msgstr "Emoji Text" msgid "DALI_DEMO_STR_TITLE_FLEXBOX_PLAYGROUND" msgstr "Flexbox Playground" +msgid "DALI_DEMO_STR_TITLE_FRAME_CALLBACK" +msgstr "Frame Callback" + msgid "DALI_DEMO_STR_TITLE_HELLO_WORLD" msgstr "Hello World" diff --git a/resources/po/en_US.po b/resources/po/en_US.po index 116ba89..fad8741 100755 --- a/resources/po/en_US.po +++ b/resources/po/en_US.po @@ -61,6 +61,9 @@ msgstr "Emoji Text" msgid "DALI_DEMO_STR_TITLE_FLEXBOX_PLAYGROUND" msgstr "Flexbox Playground" +msgid "DALI_DEMO_STR_TITLE_FRAME_CALLBACK" +msgstr "Frame Callback" + msgid "DALI_DEMO_STR_TITLE_HELLO_WORLD" msgstr "Hello World" diff --git a/shared/dali-demo-strings.h b/shared/dali-demo-strings.h index 25d69f1..8cd9b38 100644 --- a/shared/dali-demo-strings.h +++ b/shared/dali-demo-strings.h @@ -55,6 +55,7 @@ extern "C" #define DALI_DEMO_STR_TITLE_FPP_GAME dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_FPP_GAME") #define DALI_DEMO_STR_TITLE_FLEXBOX_PLAYGROUND dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_FLEXBOX_PLAYGROUND") #define DALI_DEMO_STR_TITLE_FOCUS_INTEGRATION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_FOCUS_INTEGRATION") +#define DALI_DEMO_STR_TITLE_FRAME_CALLBACK dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_FRAME_CALLBACK") #define DALI_DEMO_STR_TITLE_HELLO_WORLD dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_HELLO_WORLD") #define DALI_DEMO_STR_TITLE_HOMESCREEN dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_HOMESCREEN") #define DALI_DEMO_STR_TITLE_IMAGE_POLICIES dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_IMAGE_POLICIES") @@ -138,6 +139,7 @@ extern "C" #define DALI_DEMO_STR_TITLE_FPP_GAME "First Person Game" #define DALI_DEMO_STR_TITLE_FLEXBOX_PLAYGROUND "Flexbox Playground" #define DALI_DEMO_STR_TITLE_FOCUS_INTEGRATION "Focus Integration" +#define DALI_DEMO_STR_TITLE_FRAME_CALLBACK "Frame Callback" #define DALI_DEMO_STR_TITLE_HELLO_WORLD "Hello World" #define DALI_DEMO_STR_TITLE_HOMESCREEN "Homescreen Benchmark" #define DALI_DEMO_STR_TITLE_IMAGE_POLICIES "Image Policies"