diff options
38 files changed, 2607 insertions, 422 deletions
diff --git a/build/tizen/CMakeLists.txt b/build/tizen/CMakeLists.txt index 509afef2..a31ac186 100644 --- a/build/tizen/CMakeLists.txt +++ b/build/tizen/CMakeLists.txt @@ -109,6 +109,7 @@ CONFIGURE_FILE( resources-location.in ${DEMO_SHARED}/resources-location.cpp ) #Replace @DEMO_STYLE_IMAGE_DIR@ in following files CONFIGURE_FILE( ${LOCAL_STYLE_DIR}/demo-theme.json.in ${LOCAL_STYLE_DIR}/demo-theme.json ) +CONFIGURE_FILE( ${LOCAL_STYLE_DIR}/animated-gradient-call-active-style.json.in ${LOCAL_STYLE_DIR}/animated-gradient-call-active-style.json ) CONFIGURE_FILE( ${LOCAL_STYLE_DIR}/contact-cards-example-theme.json.in ${LOCAL_STYLE_DIR}/contact-cards-example-theme.json ) CONFIGURE_FILE( ${LOCAL_STYLE_DIR}/progress-bar-example-theme.json.in ${LOCAL_STYLE_DIR}/progress-bar-example-theme.json ) CONFIGURE_FILE( ${LOCAL_STYLE_DIR}/simple-example-theme.json.in ${LOCAL_STYLE_DIR}/simple-example-theme.json ) diff --git a/com.samsung.dali-demo.xml b/com.samsung.dali-demo.xml index 43f0ac19..f0155e0d 100644 --- a/com.samsung.dali-demo.xml +++ b/com.samsung.dali-demo.xml @@ -238,6 +238,12 @@ <ui-application appid="property-notification.example" exec="/usr/apps/com.samsung.dali-demo/bin/property-notification.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> <label>Property Notification</label> </ui-application> + <ui-application appid="animated-gradient-call-active.example" exec="/usr/apps/com.samsung.dali-demo/bin/animated-gradient-call-active.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> + <label>Call Active App</label> + </ui-application> + <ui-application appid="animated-gradient-card-active.example" exec="/usr/apps/com.samsung.dali-demo/bin/animated-gradient-card-active.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> + <label>Card Active App</label> + </ui-application> <ui-application appid="image-policies.example" exec="/usr/apps/com.samsung.dali-demo/bin/image-policies.example" nodisplay="true" multiple="false" taskmanage="true" type="c++app"> <label>Image Policies</label></ui-application> <privileges> diff --git a/demo/dali-demo.cpp b/demo/dali-demo.cpp index 4b7fc391..b1b45cd7 100644 --- a/demo/dali-demo.cpp +++ b/demo/dali-demo.cpp @@ -50,6 +50,8 @@ int DALI_EXPORT_API main(int argc, char **argv) demo.AddExample(Example("sparkle.example", DALI_DEMO_STR_TITLE_SPARKLE)); demo.AddExample(Example("rendering-skybox.example", DALI_DEMO_STR_TITLE_SKYBOX)); demo.AddExample(Example("rendering-basic-pbr.example", DALI_DEMO_STR_TITLE_PBR)); + demo.AddExample(Example("animated-gradient-call-active.example", DALI_DEMO_STR_TITLE_CALL_ACTIVE)); + demo.AddExample(Example("animated-gradient-card-active.example", DALI_DEMO_STR_TITLE_CARD_ACTIVE)); demo.SortAlphabetically( true ); diff --git a/examples/animated-gradient-call-active/animated-gradient-call-active.cpp b/examples/animated-gradient-call-active/animated-gradient-call-active.cpp new file mode 100644 index 00000000..84cd8a3c --- /dev/null +++ b/examples/animated-gradient-call-active/animated-gradient-call-active.cpp @@ -0,0 +1,410 @@ +/* +* Copyright (c) 2017 Samsung Electronics Co., Ltd. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ +#include <dali/dali.h> +#include <dali-toolkit/dali-toolkit.h> +#include <iostream> +#include <dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h> +#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h> +#include <dali/integration-api/debug.h> + +using namespace Dali; +using namespace Dali::Toolkit; + +// This example shows how to create and display animated-gradient-effect +// +namespace +{ +// The value for scale-change between wearable-mobile +// Can be changed on App-Create time +Vector2 STAGE_SIZE = Vector2( 360.0f, 360.0f ); +Vector2 SCALED_STAGE_SIZE = Vector2( 1.0f, 1.0f ); +Vector3 SCALED_STAGE_SIZE_3 = Vector3( 1.0f, 1.0f, 0.0f ); +float SCALED_WIDTH = 1.0f; +float SCALED_HEIGHT = 1.0f; +float FONT_SCALE = 0.25f; + +// const parameters for animations +const float CHANGE_DURATION = 0.2f; + +// const parameters for icon position and size when resolution is 360x360 +const Vector2 ICON_CALL_SIZE = Vector2( 54.0f, 54.0f ); +const Vector3 ICON_CALL_POSITION = Vector3( 0.0f, 0.0f, 0.0f ); +const Vector2 ICON_DECALL_SIZE = Vector2( 54.0f, 54.0f ); +const Vector3 ICON_DECALL_POSITION = Vector3( 141.0f, 0.0f, 0.0f ); +const Vector2 ICON_BATTERY_SIZE = Vector2( 14.0f, 23.0f ); +const Vector3 ICON_BATTERY_POSITION = Vector3( 0.0f, 25.5f, 0.0f ); +const Vector2 BUTTON_CALL_START_SIZE = Vector2( 54.0f, 54.0f ); +const Vector3 BUTTON_CALL_START_POSITION = Vector3( -141.0f, 0.0f, 0.0f ); + +const Vector2 BUTTON_DECALL_ICON_SIZE = Vector2( 62.0f, 62.0f ); +const Vector3 BUTTON_DECALL_ICON_POSITION = Vector3( 0.0f, 0.0f, 0.0f ); +const Vector2 BUTTON_DECALL_SIZE = Vector2( 360.0f, 82.0f ); +const Vector3 BUTTON_DECALL_CLIP_POSITION = Vector3( 0.0f, 82.0f, 0.0f ); +const Vector3 BUTTON_DECALL_POSITION = Vector3( 0.0f, 0.0f, 0.0f ); + +// icon image name +const char * const ICON_CALL_IMAGE( DEMO_IMAGE_DIR "Call_Accept.png" ); +const char * const ICON_DECALL_IMAGE( DEMO_IMAGE_DIR "Call_Decline.png" ); +const char * const ICON_BATTERY_IMAGE( DEMO_IMAGE_DIR "Call_Battery.png" ); +const char * const BUTTON_DECALL_ICON_IMAGE( DEMO_IMAGE_DIR "Call_Decline_wh.png" ); + +// const parameters for string position and size and font-size when resolution is 360x360 +const Vector2 LABEL_INCOMING_SIZE = Vector2( 156.0f, 26.0f ); +const Vector3 LABEL_INCOMING_POSITION = Vector3( 0.0f, -47.0f, 0.0f ); +const Vector4 LABEL_INCOMING_FONT_COLOR = Vector4( 0.98f, 0.98f, 0.98f, 1.0f ); +const float LABEL_INCOMING_FONT_SIZE = 21.39f; +const Vector2 LABEL_NAME_SIZE = Vector2( 230.0f, 45.0f ); +const Vector3 LABEL_NAME_POSITION = Vector3( 0.0f, -2.5f, 0.0f ); +const Vector4 LABEL_NAME_FONT_COLOR = Vector4( 0.98f, 0.98f, 0.98f, 1.0f ); +const float LABEL_NAME_FONT_SIZE = 37.71f; +const Vector2 LABEL_NUMBER_SIZE = Vector2( 196.0f, 25.0f ); +const Vector3 LABEL_NUMBER_POSITION = Vector3( 0.0f, 31.0f, 0.0f ); +const Vector4 LABEL_NUMBER_FONT_COLOR = Vector4( 0.98f, 0.98f, 0.98f, 1.0f ); +const float LABEL_NUMBER_FONT_SIZE = 20.55f; +const Vector2 LABEL_DECLINE_SIZE = Vector2( 203.0f, 25.0f ); +const Vector3 LABEL_DECLINE_POSITION = Vector3( 0.0f, -50.5f, 0.0f ); +const Vector4 LABEL_DECLINE_FONT_COLOR = Vector4( 0.98f, 0.98f, 0.98f, 1.0f ); +const float LABEL_DECLINE_FONT_SIZE = 20.55f; +const Vector2 LABEL_TIME_SIZE = Vector2( 91.0f, 26.0f ); +const Vector3 LABEL_TIME_POSITION = Vector3( 0.0f, -47.0f, 0.0f ); +const Vector4 LABEL_TIME_FONT_COLOR = Vector4( 0.98f, 0.98f, 0.98f, 1.0f ); +const float LABEL_TIME_FONT_SIZE = 21.39f; + +// string string +const char * const LABEL_INCOMING_STR( "Incoming Call" ); +const char * const LABEL_NAME_STR( "Sam Smith" ); +const char * const LABEL_NUMBER_STR( "+1 908-247-1695" ); +const char * const LABEL_DECLINE_STR( "Decline Message" ); +const char * const LABEL_TIME_STR( "1:03" ); + +// Set style from json +const char * const BACKGROUND_STYLE_JSON( DEMO_STYLE_DIR "animated-gradient-call-active-style.json" ); +const char * const BACKGROUND_INCOME_STYLE_STR( "IncomeBackground" ); +const char * const BACKGROUND_ACTIVE_STYLE_STR( "ActiveBackground" ); +const char * const DECLINE_BUTTON_STYLE_STR( "DeclineButton" ); + +} // unnamed namespace + +// This example shows how to render animated gradients +// +class CallController : public ConnectionTracker +{ +public: + CallController(Application& application) + : mApplication( application ), + mColorStart( 0.0f, 0.0f, 0.0f, 0.0f ), + mColorEnd( 0.0f, 0.0f, 0.0f, 0.0f ), + mColorReduce( 0.0f, 0.0f, 0.0f, 0.0f ), + mButtonColorStart( 0.0f, 0.0f, 0.0f, 0.0f ), + mButtonColorEnd( 0.0f, 0.0f, 0.0f, 0.0f ), + mDuration( 0.0f ), + mBackgroundDurationIncoming( 0.0f ), + mBackgroundDurationActive( 0.0f ), + mButtonDuration( 0.0f ), + mButtonDelay( 0.0f ) + { + // Connect to the Application's Init signal + mApplication.InitSignal().Connect( this, &CallController::Create ); + } + + ~CallController() + { + // Nothing to do here; + } + + // The Init signal is received once (only) during the Application lifetime + void Create(Application& application) + { + // Get a handle to the stage + mStage = Stage::GetCurrent(); + mStage.KeyEventSignal().Connect( this, &CallController::OnKeyEvent ); + + // Apply custom style for background and button. + StyleManager::Get().ApplyTheme( BACKGROUND_STYLE_JSON ); + + // Get current device's width and height. + STAGE_SIZE = mStage.GetSize(); + SCALED_STAGE_SIZE = STAGE_SIZE / 360.0f; + SCALED_STAGE_SIZE_3 = Vector3( SCALED_STAGE_SIZE.x, SCALED_STAGE_SIZE.y, 0.0f ); + SCALED_WIDTH = SCALED_STAGE_SIZE.x < SCALED_STAGE_SIZE.y ? SCALED_STAGE_SIZE.x : SCALED_STAGE_SIZE.y; + SCALED_HEIGHT = SCALED_WIDTH; + + // Note that this is heuristic value + FONT_SCALE = 0.25f * STAGE_SIZE.y / STAGE_SIZE.x; + + mBackground = Control::New(); + mBackground.SetParentOrigin( ParentOrigin::CENTER ); + mBackground.SetAnchorPoint( AnchorPoint::CENTER ); + mBackground.SetSize( STAGE_SIZE ); + + mStage.Add( mBackground ); + + BuildParameter(); + SetupActors(); + SetupAnimation(); + + Reset(); + } + + 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: + + // Setup const parameter values + void BuildParameter() + { + mDuration = CHANGE_DURATION; + } + + void SetupActors() + { + SetupComingActors(); + SetupActiveActors(); + } + + // Create and Add to stage when visible at call incomming + void SetupComingActors() + { + mButtonIconDecall = ImageView::New(); + mButtonIconDecall.SetImage( ICON_DECALL_IMAGE ); + mButtonIconDecall.SetParentOrigin( ParentOrigin::CENTER ); + mButtonIconDecall.SetAnchorPoint( AnchorPoint::CENTER ); + mButtonIconDecall.SetSize( ICON_DECALL_SIZE * SCALED_WIDTH ); + mButtonIconDecall.SetPosition( ICON_DECALL_POSITION * SCALED_WIDTH ); + + mButtonIconBattery = ImageView::New(); + mButtonIconBattery.SetImage( ICON_BATTERY_IMAGE ); + mButtonIconBattery.SetParentOrigin( ParentOrigin::TOP_CENTER ); + mButtonIconBattery.SetAnchorPoint( AnchorPoint::TOP_CENTER ); + mButtonIconBattery.SetSize( ICON_BATTERY_SIZE * SCALED_WIDTH ); + mButtonIconBattery.SetPosition( ICON_BATTERY_POSITION * SCALED_WIDTH ); + + mCallStartButton = PushButton::New(); + mCallStartButton.SetParentOrigin( ParentOrigin::CENTER ); + mCallStartButton.SetAnchorPoint( AnchorPoint::CENTER ); + mCallStartButton.SetSize( BUTTON_CALL_START_SIZE * SCALED_WIDTH ); + mCallStartButton.SetPosition( BUTTON_CALL_START_POSITION * SCALED_WIDTH ); + mCallStartButton.ClickedSignal().Connect( this, &CallController::OnButtonClicked ); + mCallStartButton.SetProperty( Button::Property::SELECTED_STATE_IMAGE, ICON_CALL_IMAGE ); + mCallStartButton.SetProperty( Button::Property::UNSELECTED_STATE_IMAGE, ICON_CALL_IMAGE ); + + mStage.Add( mCallStartButton ); + mStage.Add( mButtonIconDecall ); + mStage.Add( mButtonIconBattery ); + + mLabelIncoming = TextLabel::New( LABEL_INCOMING_STR ); + mLabelIncoming.SetParentOrigin( ParentOrigin::CENTER ); + mLabelIncoming.SetAnchorPoint( AnchorPoint::CENTER ); + mLabelIncoming.SetSize( LABEL_INCOMING_SIZE * SCALED_STAGE_SIZE ); + mLabelIncoming.SetPosition( LABEL_INCOMING_POSITION * SCALED_STAGE_SIZE_3 ); + mLabelIncoming.SetVisible( true ); + mLabelIncoming.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_INCOMING_FONT_COLOR ); + mLabelIncoming.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_INCOMING_FONT_SIZE * FONT_SCALE ); + mLabelIncoming.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" ); + mLabelIncoming.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); + + mLabelName = TextLabel::New( LABEL_NAME_STR ); + mLabelName.SetParentOrigin( ParentOrigin::CENTER ); + mLabelName.SetAnchorPoint( AnchorPoint::CENTER ); + mLabelName.SetSize( LABEL_NAME_SIZE * SCALED_STAGE_SIZE ); + mLabelName.SetPosition( LABEL_NAME_POSITION * SCALED_STAGE_SIZE_3 ); + mLabelName.SetVisible( true ); + mLabelName.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_NAME_FONT_COLOR ); + mLabelName.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_NAME_FONT_SIZE * FONT_SCALE ); + mLabelName.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" ); + mLabelName.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); + + mLabelNumber = TextLabel::New( LABEL_NUMBER_STR ); + mLabelNumber.SetParentOrigin( ParentOrigin::CENTER ); + mLabelNumber.SetAnchorPoint( AnchorPoint::CENTER ); + mLabelNumber.SetSize( LABEL_NUMBER_SIZE * SCALED_STAGE_SIZE ); + mLabelNumber.SetPosition( LABEL_NUMBER_POSITION * SCALED_STAGE_SIZE_3 ); + mLabelNumber.SetVisible( true ); + mLabelNumber.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_NUMBER_FONT_COLOR ); + mLabelNumber.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_NUMBER_FONT_SIZE * FONT_SCALE ); + mLabelNumber.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" ); + mLabelNumber.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); + + mLabelDecline = TextLabel::New( LABEL_DECLINE_STR ); + mLabelDecline.SetParentOrigin( ParentOrigin::BOTTOM_CENTER ); + mLabelDecline.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER ); + mLabelDecline.SetSize( LABEL_DECLINE_SIZE * SCALED_STAGE_SIZE ); + mLabelDecline.SetPosition( LABEL_DECLINE_POSITION * SCALED_WIDTH ); + mLabelDecline.SetVisible( true ); + mLabelDecline.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_DECLINE_FONT_COLOR ); + mLabelDecline.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_DECLINE_FONT_SIZE * FONT_SCALE ); + mLabelDecline.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" ); + mLabelDecline.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); + + mStage.Add( mLabelIncoming ); + mStage.Add( mLabelName ); + mStage.Add( mLabelNumber ); + mStage.Add( mLabelDecline ); + } + + // Create and Add to stage when visible at call active + void SetupActiveActors() + { + mButtonClip = Control::New(); + mButtonClip.SetParentOrigin( ParentOrigin::BOTTOM_CENTER ); + mButtonClip.SetAnchorPoint( ParentOrigin::BOTTOM_CENTER ); + mButtonClip.SetSize( BUTTON_DECALL_SIZE * SCALED_WIDTH ); + mButtonClip.SetPosition( BUTTON_DECALL_CLIP_POSITION * SCALED_WIDTH ); + + mButtonIcon = ImageView::New(); + mButtonIcon.SetImage( BUTTON_DECALL_ICON_IMAGE ); + mButtonIcon.SetParentOrigin( ParentOrigin::CENTER ); + mButtonIcon.SetAnchorPoint( AnchorPoint::CENTER ); + mButtonIcon.SetSize( BUTTON_DECALL_ICON_SIZE * SCALED_WIDTH ); + mButtonIcon.SetPosition( BUTTON_DECALL_ICON_POSITION * SCALED_WIDTH ); + + mCallEndButton = PushButton::New(); + mCallEndButton.SetParentOrigin( ParentOrigin::CENTER ); + mCallEndButton.SetAnchorPoint( AnchorPoint::CENTER ); + mCallEndButton.SetSize( BUTTON_DECALL_SIZE * SCALED_WIDTH ); + mCallEndButton.SetPosition( BUTTON_DECALL_POSITION * SCALED_WIDTH ); + mCallEndButton.ClickedSignal().Connect( this, &CallController::OnButtonClicked ); + mCallEndButton.SetProperty( Button::Property::SELECTED_STATE_IMAGE, "" ); + mCallEndButton.SetProperty( Button::Property::UNSELECTED_STATE_IMAGE, "" ); + mCallEndButton.SetStyleName( DECLINE_BUTTON_STYLE_STR ); + + mButtonClip.Add( mCallEndButton ); + mButtonClip.Add( mButtonIcon ); + + mLabelTime = TextLabel::New( LABEL_TIME_STR ); + mLabelTime.SetParentOrigin( ParentOrigin::CENTER ); + mLabelTime.SetAnchorPoint( AnchorPoint::CENTER ); + mLabelTime.SetSize( LABEL_TIME_SIZE * SCALED_STAGE_SIZE ); + mLabelTime.SetPosition( LABEL_TIME_POSITION * SCALED_STAGE_SIZE_3 ); + mLabelTime.SetVisible( false ); + mLabelTime.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_TIME_FONT_COLOR ); + mLabelTime.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_TIME_FONT_SIZE * FONT_SCALE ); + mLabelTime.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" ); + mLabelTime.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); + + mStage.Add( mLabelTime ); + } + + void SetupAnimation() + { + mMoveFront = Animation::New( mDuration ); + mMoveBack = Animation::New( mDuration ); + + mMoveFront.AnimateTo( Property( mButtonClip, Actor::Property::POSITION_Y ), 0.0f * SCALED_HEIGHT ); + mMoveBack.AnimateTo( Property( mButtonClip, Actor::Property::POSITION_Y ), BUTTON_DECALL_CLIP_POSITION.y * SCALED_HEIGHT ); + + mMoveFront.AnimateTo( Property( mCallStartButton, Actor::Property::VISIBLE ), false ); + mMoveFront.AnimateTo( Property( mButtonIconDecall, Actor::Property::VISIBLE ), false ); + mMoveBack.AnimateTo( Property( mCallStartButton, Actor::Property::VISIBLE ), true ); + mMoveBack.AnimateTo( Property( mButtonIconDecall, Actor::Property::VISIBLE ), true ); + + mMoveFront.AnimateTo( Property( mLabelIncoming, Actor::Property::VISIBLE ), false ); + mMoveFront.AnimateTo( Property( mLabelNumber, Actor::Property::VISIBLE ), false ); + mMoveFront.AnimateTo( Property( mLabelTime, Actor::Property::VISIBLE ), true ); + mMoveBack.AnimateTo( Property( mLabelIncoming, Actor::Property::VISIBLE ), true ); + mMoveBack.AnimateTo( Property( mLabelNumber, Actor::Property::VISIBLE ), true ); + mMoveBack.AnimateTo( Property( mLabelTime, Actor::Property::VISIBLE ), false ); + } + + bool OnButtonClicked(Button button) + { + if( button == mCallStartButton ) + { + mBackground.SetStyleName( BACKGROUND_ACTIVE_STYLE_STR ); + mStage.Add( mButtonClip ); + mMoveFront.Play(); + } + else if( button == mCallEndButton ) + { + mBackground.SetStyleName( BACKGROUND_INCOME_STYLE_STR ); + mTempTimer = Timer::New( mDuration * 1000.0f ); + mTempTimer.TickSignal().Connect( this, &CallController::smallTick ); + mTempTimer.Start(); + mMoveBack.Play(); + } + return true; + } + bool smallTick() + { + mButtonClip.Unparent(); + return false; + } + + void Reset() + { + mBackground.SetStyleName( BACKGROUND_INCOME_STYLE_STR ); + } + +private: + Application& mApplication; + Stage mStage; + + Control mBackground; + + // Show when call incommint + PushButton mCallStartButton; + ImageView mButtonIconDecall; + ImageView mButtonIconBattery; + TextLabel mLabelIncoming; + TextLabel mLabelName; + TextLabel mLabelNumber; + TextLabel mLabelDecline; + + // Show when call active + PushButton mCallEndButton; + ImageView mButtonIcon; + Control mButtonBackground; + Control mButtonClip; + TextLabel mLabelTime; + + Timer mTempTimer; + + Animation mMoveFront; + Animation mMoveBack; + + Vector4 mColorStart; + Vector4 mColorEnd; + Vector4 mColorReduce; + + Vector4 mButtonColorStart; + Vector4 mButtonColorEnd; + + float mDuration; + float mBackgroundDurationIncoming; + float mBackgroundDurationActive; + float mButtonDuration; + float mButtonDelay; +}; + +int main(int argc, char **argv) +{ + Application application = Application::New( &argc, &argv ); + + CallController test( application ); + + application.MainLoop(); + return 0; +} diff --git a/examples/animated-gradient-card-active/animated-gradient-card-active.cpp b/examples/animated-gradient-card-active/animated-gradient-card-active.cpp new file mode 100644 index 00000000..34143618 --- /dev/null +++ b/examples/animated-gradient-card-active/animated-gradient-card-active.cpp @@ -0,0 +1,836 @@ +/* +* 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. +* +*/ +#include <dali/dali.h> +#include <dali-toolkit/dali-toolkit.h> +#include <iostream> +#include <dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h> +#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h> +#include <dali/integration-api/debug.h> + +using namespace Dali; +using namespace Dali::Toolkit; + +// This example shows how to create and display animated-gradient-effect +// +namespace +{ +// The value for scale-change between wearable-mobile +// Can be changed on App-Create time +Vector2 STAGE_SIZE = Vector2( 360.0f, 360.0f ); +Vector2 SCALED_STAGE_SIZE = Vector2( 1.0f, 1.0f ); +Vector3 SCALED_STAGE_SIZE_3 = Vector3( 1.0f, 1.0f, 0.0f ); +float SCALED_WIDTH = 1.0f; +float SCALED_HEIGHT = 1.0f; +float FONT_SCALE = 0.25f; + +// const parameters for color and animation +const float CHANGE_DURATION = 0.2f; +const float CARD_MOVE_DURATION = 1.0f; +const float LOADING_ONE_CYCLE_DURATION = 2.0f; +const int LOADING_CYCLE_CNT = 4; +const int LOADING_CYCLE_DT = 10; +const Vector4 DEFAULT_COLOR = Vector4( 0.5f, 0.5f, 0.5f, 1.0f ); + +const float PSEUDO_SCROLL_TIME = 100.0f; +const float PSEUDO_SCROLL_OFFSET = 0.05f; + +// const static parameters for cards when resolution is 360x360 +const int CARD_NUM = 3; +const Vector2 CARD_SIZE = Vector2( 210.0f, 143.0f ); +const Vector2 CARD_OFFSET = Vector2( 0.0f, 12.5f ); +const Vector2 CARD_DIFF = Vector2( 240.0f, 0.0f ); +const float CARD_BOUNCE_ANIMATION_RATE = 0.3f; + +const Vector2 CARD_SIZE_BIG = Vector2( 292.0f, 199.0f ); +const Vector2 CARD_BIG_OFFSET = Vector2( 0.0f, -5.5f ); +const float CARD_MOVE_DIST = 40.0f; + +// const private parameters for each cards +const Vector4 CARD_COLOR_START_LIST[] = +{ + Vector4( 0x24, 0x2C, 0x93, 255.f ) / 255.f, + Vector4( 0x7A, 0x1C, 0x9E, 255.f ) / 255.f, + Vector4( 0xA9, 0x0C, 0x96, 255.f ) / 255.f, +}; +const Vector4 CARD_COLOR_END_LIST[] = +{ + Vector4( 0x04, 0x13, 0x23, 255.f ) / 255.f, + Vector4( 0x28, 0x01, 0x45, 255.f ) / 255.f, + Vector4( 0x37, 0x0A, 0x2E, 255.f ) / 255.f, +}; +const Vector4 CARD_COLOR_BACKGROUND_LIST[] = +{ + Vector4( 0x28, 0x2B, 0x6E, 255.f ) / 255.f, + Vector4( 0x4D, 0x15, 0x61, 255.f ) / 255.f, + Vector4( 0x70, 0x21, 0x61, 255.f ) / 255.f, +}; +const char * const CARD_IMAGE_LIST[] = +{ + ( DEMO_IMAGE_DIR "Card_01.png" ), + ( DEMO_IMAGE_DIR "Card_02.png" ), + ( DEMO_IMAGE_DIR "Card_03.png" ), +}; + +// const parameters for add button position and size when resolution is 360x360x +const Vector2 BUTTON_ADD_SIZE = Vector2( 292.0f, 52.0f ); +const Vector3 BUTTON_ADD_POSITION = Vector3( 0.0f, 0.0f, 0.0f ); +const char * const BUTTON_ADD_IMAGE( DEMO_IMAGE_DIR "Card_Add_Button.png" ); + +// const parameters for string position and size and font-size when resolution is 360x360 +const Vector2 LABEL_TICKET_SIZE = Vector2( 148.0f, 31.0f ); +const Vector3 LABEL_TICKET_POSITION = Vector3( 0.0f, 72.5f, 0.0f ); +const Vector4 LABEL_TICKET_FONT_COLOR = Vector4( 0.98f, 0.98f, 0.98f, 1.0f ); +const float LABEL_TICKET_FONT_SIZE = 25.0f; +const Vector2 LABEL_HOLD_SIZE = Vector2( 180.0f, 60.0f ); +const Vector3 LABEL_HOLD_POSITION = Vector3( 1.0f, 103.0f, 0.0f ); +const Vector4 LABEL_HOLD_FONT_COLOR = Vector4( 0.98f, 0.98f, 0.98f, 1.0f ); +const float LABEL_HOLD_FONT_SIZE = 25.0f; +const Vector2 LABEL_TERMINAL_SIZE = Vector2( 180.0f, 60.0f ); +const Vector3 LABEL_TERMINAL_POSITION = Vector3( 1.0f, 133.0f, 0.0f ); +const Vector4 LABEL_TERMINAL_FONT_COLOR = Vector4( 0.98f, 0.98f, 0.98f, 1.0f ); +const float LABEL_TERMINAL_FONT_SIZE = 25.0f; + +// string string +const char * const LABEL_TICKET_STR( "Select Ticket" ); +const char * const LABEL_HOLD_STR( "Hold near" ); +const char * const LABEL_TERMINAL_STR( "terminal" ); + +class CardManager +{ +public: + CardManager() + : mSize( 0.0f, 0.0f ), + mOffset( 0.0f, 0.0f), + mDiff( 0.0f, 0.0f), + mCurIndex( 0 ), + mCurState( 0 ) + { + } + ~CardManager() {} + + void Init(Stage& stage) + { + mSize = CARD_SIZE * SCALED_WIDTH; + mOffset = CARD_OFFSET * SCALED_WIDTH; + mDiff = CARD_DIFF * SCALED_WIDTH; + + mCurIndex = 0; + mCurState = 0; + + for( int k = 0; k < CARD_NUM; k++ ) + { + mPosition[k] = mOffset + mDiff * k; + + mColorStart[k] = CARD_COLOR_START_LIST[k]; + mColorEnd[k] = CARD_COLOR_END_LIST[k]; + mColorBackground[k] = CARD_COLOR_BACKGROUND_LIST[k]; + + mImageUrl[k] = CARD_IMAGE_LIST[k]; + + // Create an image view for this item + mCard[k] = ImageView::New(); + { + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, mImageUrl[k]); + propertyMap.Insert(DevelVisual::Property::VISUAL_FITTING_MODE, DevelVisual::FILL); + mCard[k].SetProperty(Toolkit::ImageView::Property::IMAGE, propertyMap); + } + + mCard[k].SetParentOrigin( ParentOrigin::CENTER ); + mCard[k].SetAnchorPoint( AnchorPoint::CENTER ); + mCard[k].SetSize( mSize.x, mSize.y ); + mCard[k].SetPosition( mPosition[k].x, mPosition[k].y ); + + stage.Add( mCard[k] ); + } + } + + bool MoveRight(float duration) + { + Animation anim = Animation::New( duration ); + for( int k = 0; k < CARD_NUM; k++ ) + { + if( mCurIndex == 0 ) + { + anim.AnimateBy( Property( mCard[k], Actor::Property::POSITION_X ), mDiff.x * CARD_BOUNCE_ANIMATION_RATE, AlphaFunction::BOUNCE ); + } + else + { + anim.AnimateBy( Property( mCard[k], Actor::Property::POSITION_X ), mDiff.x, AlphaFunction::EASE_OUT ); + } + } + bool res = false; + if( mCurIndex != 0 ) + { + mCurIndex = (mCurIndex - 1) % CARD_NUM; + res = true; + } + anim.Play(); + return res; + } + + bool MoveLeft(float duration) + { + Animation anim = Animation::New( duration ); + for( int k = 0; k < CARD_NUM; k++ ) + { + if( mCurIndex == CARD_NUM - 1 ) + { + anim.AnimateBy( Property( mCard[k], Actor::Property::POSITION_X ), -mDiff.x * CARD_BOUNCE_ANIMATION_RATE, AlphaFunction::BOUNCE ); + } + else + { + anim.AnimateBy( Property( mCard[k], Actor::Property::POSITION_X ), -mDiff.x, AlphaFunction::EASE_OUT ); + } + } + bool res = false; + if( mCurIndex != CARD_NUM - 1 ) + { + mCurIndex = (mCurIndex + 1) % CARD_NUM; + res = true; + } + anim.Play(); + return res; + } + + Vector4 GetColorStart(int index) + { + DALI_ASSERT_ALWAYS( index >= 0 && index < CARD_NUM ); + return mColorStart[index]; + } + + Vector4 GetColorEnd(int index) + { + DALI_ASSERT_ALWAYS( index >= 0 && index < CARD_NUM ); + return mColorEnd[index]; + } + + Vector4 GetColorBackground(int index) + { + DALI_ASSERT_ALWAYS( index >= 0 && index < CARD_NUM ); + return mColorBackground[index]; + } + + ImageView& operator [](int index) + { + DALI_ASSERT_ALWAYS( index >= 0 && index < CARD_NUM ); + return mCard[index]; + } + + ImageView mCard[CARD_NUM]; + std::string mImageUrl[CARD_NUM]; + Vector4 mColorStart[CARD_NUM]; + Vector4 mColorEnd[CARD_NUM]; + Vector4 mColorBackground[CARD_NUM]; + Vector2 mPosition[CARD_NUM]; + Vector2 mSize; + Vector2 mOffset; + Vector2 mDiff; + int mCurIndex; + int mCurState; +}; + +} // unnamed namespace + +// This example shows how to render animated gradients +// +class CardController : public ConnectionTracker +{ +public: + CardController(Application& application) + : mApplication( application ), + mNormalColor( 0.0f, 0.0f, 0.0f, 0.0f ), + mNormalStartColor( 0.0f, 0.0f, 0.0f, 0.0f ), + mNormalEndColor( 0.0f, 0.0f, 0.0f, 0.0f), + mFirstTouchPos( 0.0f, 0.0f ), + mLastTouchPos( 0.0f, 0.0f ), + mCardDuration( 0.0f ), + mDuration( 0.0f ), + mLoadingTime( 0.0f ), + mLoadingCount( 0 ), + mLoadingCountScale( 0 ), + mTickCount( 0 ), + mCancelSignal( false ), + mIsTouchedActor( false ) + { + // Connect to the Application's Init signal + mApplication.InitSignal().Connect( this, &CardController::Create ); + } + + ~CardController() + { + // Nothing to do here; + } + + // The Init signal is received once (only) during the Application lifetime + void Create(Application& application) + { + // Get a handle to the stage + mStage = Stage::GetCurrent(); + mStage.KeyEventSignal().Connect( this, &CardController::OnKeyEvent ); + + // Get current device's width and height. + STAGE_SIZE = mStage.GetSize(); + SCALED_STAGE_SIZE = STAGE_SIZE / 360.0f; + SCALED_STAGE_SIZE_3 = Vector3( SCALED_STAGE_SIZE.x, SCALED_STAGE_SIZE.y, 0.0f ); + SCALED_WIDTH = SCALED_STAGE_SIZE.x < SCALED_STAGE_SIZE.y ? SCALED_STAGE_SIZE.x : SCALED_STAGE_SIZE.y; + SCALED_HEIGHT = SCALED_WIDTH; + + // Note that this is heuristic value + FONT_SCALE = 0.25f * STAGE_SIZE.y / STAGE_SIZE.x; + + mBackground = Control::New(); + mBackground.SetParentOrigin( ParentOrigin::CENTER ); + mBackground.SetAnchorPoint( AnchorPoint::CENTER ); + mBackground.SetSize( STAGE_SIZE ); + + mStage.Add( mBackground ); + + BuildParameter(); + InitMap(); + SetupCards(); + SetupActors(); + SetupAnimation(); + + mStage.GetRootLayer().TouchSignal().Connect( this, &CardController::OnTouchLayer ); + Reset(); + } + + bool OnTouchCards(Actor actor, const TouchData &data) + { + if( data.GetPointCount() > 0 ) + { + if( data.GetState( 0 ) == PointState::DOWN ) + { + if( mCards.mCurState == 0 ) + { + mIsTouchedActor = false; + if( mCards[mCards.mCurIndex] == actor ) + { + mIsTouchedActor = true; + } + mCards.mCurState = 3; + mTempTimer = Timer::New( PSEUDO_SCROLL_TIME ); + mTempTimer.TickSignal().Connect( this, &CardController::OnDetectMotionLayer ); + mTempTimer.Start(); + + mFirstTouchPos = data.GetScreenPosition( 0 ); + mLastTouchPos = mFirstTouchPos; + } + else if( mCards.mCurState == 1 ) + { + mCancelSignal = true; + return false; + } + } + else + { + mLastTouchPos = data.GetScreenPosition( 0 ); + } + } + return true; + } + + bool OnTouchLayer(Actor actor, const TouchData &data) + { + if( data.GetPointCount() > 0 ) + { + if( data.GetState( 0 ) == PointState::DOWN ) + { + if( mCards.mCurState == 0 ) + { + mIsTouchedActor = false; + mCards.mCurState = 3; + mTempTimer = Timer::New( PSEUDO_SCROLL_TIME ); + mTempTimer.TickSignal().Connect( this, &CardController::OnDetectMotionLayer ); + mTempTimer.Start(); + + mFirstTouchPos = data.GetScreenPosition( 0 ); + mLastTouchPos = mFirstTouchPos; + } + } + else + { + mLastTouchPos = data.GetScreenPosition( 0 ); + } + } + return true; + } + + // Heuristic Scroll View + bool OnDetectMotionLayer() + { + if( mCards.mCurState == 3 ) + { + Vector2 diff = (mLastTouchPos - mFirstTouchPos); + float offset = PSEUDO_SCROLL_OFFSET; + // Scroll to right + if( diff.x > mStage.GetSize().x * offset ) + { + mCards.mCurState = 2; + MoveRight(); + mCardChanger = Timer::New( mCardDuration * 1000.0f ); + mCardChanger.TickSignal().Connect( this, &CardController::OnTickLayer ); + mCardChanger.Start(); + } + // Scroll to left + else if( diff.x < -mStage.GetSize().x * offset ) + { + mCards.mCurState = 2; + MoveLeft(); + mCardChanger = Timer::New( mCardDuration * 1000.0f ); + mCardChanger.TickSignal().Connect( this, &CardController::OnTickLayer ); + mCardChanger.Start(); + } + // Not a scroll input + else + { + // Run NFC Tag effect if we touch a card + if (mIsTouchedActor) + { + mCards.mCurState = 1; + RunAnimation( mCards.mCurIndex ); + } + else + { + Reset(); + } + } + } + return false; + } + + bool OnTickLayer() + { + Reset(); + return false; + } + + 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: + + // Utility function to make animation parameter map. return Property::Map + Property::Value BuildMap(const Property::Value &start, const Property::Value &target, int dir, float duration, float delay, int repeat, float repeat_delay, int motion, int easing) + { + Property::Map map; + + map.Clear(); + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::START, start ); + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET, target ); + if( dir == 0 ) + { + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD ); + } + else + { + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD ); + } + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION, duration ); + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY, delay ); + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT, repeat ); + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, repeat_delay ); + if( motion == 0 ) + { + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP ); + } + else + { + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR ); + } + if( easing == 0 ) + { + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR ); + } + else if( easing == 1 ) + { + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN ); + } + else if( easing == 2 ) + { + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT ); + } + else + { + map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT ); + } + + return Property::Value( map ); + } + + // Setup background visual property during nothing action + void InitMapNormal() + { + mBackgroundNormalMap.Clear(); + mBackgroundNormalMap.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT ); + + mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, Vector2( -0.5, -0.5 ) ); + mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION, Vector2( 0.5, 0.5 ) ); + mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR, mNormalColor ); + mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR, mNormalColor ); + mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Vector2( 0.0f, 0.0f ) ); + mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, 0.0f ); + mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::OFFSET, 0.0f ); + } + + // Setup background visual property during NFC tagging start + void InitMapStart() + { + mBackgroundMapStart.Clear(); + mBackgroundMapStart.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT ); + + mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, Vector2( -0.5, -0.5 ) ); + mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION, Vector2( 0.5, 0.5 ) ); + mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR, mNormalColor ); + mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR, mNormalColor ); + mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Vector2( 0.0f, 0.0f ) ); + mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, 0.0f ); + mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::OFFSET, BuildMap( 0.0f, 2.0f, 0, mLoadingTime, 0.0f, -1, 0.0f, 0, 0 ) ); + + mColorAnimationStartStart = *( BuildMap( mNormalColor, Vector4( 0, 0, 0, 0 ), 0, mDuration, 0.0f, 1, 0.0f, 0, 0 ).GetMap() ); + mColorAnimationStartEnd = *( BuildMap( mNormalColor, Vector4( 0, 0, 0, 0 ), 0, mDuration, 0.0f, 1, 0.0f, 0, 0 ).GetMap() ); + } + + // Setup background visual property during NFC tagging end + void InitMapEnd() + { + mBackgroundMapEnd.Clear(); + mBackgroundMapEnd.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT ); + + mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, Vector2( -0.5, -0.5 ) ); + mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION, Vector2( 0.5, 0.5 ) ); + mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR, mNormalColor ); + mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR, mNormalColor ); + mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Vector2( 0.0f, 0.0f ) ); + mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, 0.0f ); + mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::OFFSET, BuildMap( 0.0f, 2.0f, 0, mLoadingTime, 0.0f, -1, 0.0f, 0, 0 ) ); + + mColorAnimationEndStart = *( BuildMap( mNormalColor, Vector4( 0, 0, 0, 0 ), 1, mDuration, 0.0f, 1, 0.0f, 0, 0 ).GetMap() ); + mColorAnimationEndEnd = *( BuildMap( mNormalColor, Vector4( 0, 0, 0, 0 ), 1, mDuration, 0.0f, 1, 0.0f, 0, 0 ).GetMap() ); + } + + // Setup background visual property during card change + void InitMapMove() + { + mBackgroundMapMove.Clear(); + mBackgroundMapMove.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT); + mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::SPREAD_TYPE, Toolkit::DevelAnimatedGradientVisual::SpreadType::CLAMP); + + mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, Vector2( -0.5, 0.0 ) ); + mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION, Vector2( 0.5, 0.0 ) ); + mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR, mNormalStartColor ); + mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR, mNormalEndColor ); + mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Vector2( 0.0f, 0.0f ) ); + mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, 0.0f ); + mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::OFFSET, BuildMap( -1.0f, 1.0f, 0, mCardDuration, 0.0f, 1, 0.0f, 0, 2 ) ); + } + + void InitMap() + { + InitMapNormal(); + InitMapStart(); + InitMapEnd(); + InitMapMove(); + } + + // Setup const parameter values + void BuildParameter() + { + mNormalColor = DEFAULT_COLOR; + mCardDuration = CARD_MOVE_DURATION; + mDuration = CHANGE_DURATION; + mLoadingTime = LOADING_ONE_CYCLE_DURATION; + mLoadingCount = LOADING_CYCLE_CNT; + mLoadingCountScale = LOADING_CYCLE_DT; + + mNormalStartColor = mNormalColor; + mNormalEndColor = mNormalColor; + } + + void BuildAnimation() + { + InitMap(); + } + + void SetupCards() + { + mCards.Init( mStage ); + for( int k = 0; k < CARD_NUM; k++ ) + { + mCards[k].TouchSignal().Connect( this, &CardController::OnTouchCards ); + } + mNormalStartColor = mCards.GetColorBackground( mCards.mCurIndex ); + mNormalEndColor = mCards.GetColorBackground( mCards.mCurIndex ); + } + + // Create and Add to stage + void SetupActors() + { + mAddButton = ImageView::New(); + mAddButton.SetImage( BUTTON_ADD_IMAGE ); + mAddButton.SetParentOrigin( ParentOrigin::BOTTOM_CENTER ); + mAddButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER ); + mAddButton.SetSize( BUTTON_ADD_SIZE * SCALED_WIDTH ); + mAddButton.SetPosition( BUTTON_ADD_POSITION * SCALED_WIDTH ); + + mLabel1 = TextLabel::New( LABEL_TICKET_STR ); + mLabel1.SetParentOrigin( ParentOrigin::TOP_CENTER ); + mLabel1.SetAnchorPoint( AnchorPoint::TOP_CENTER ); + mLabel1.SetSize( LABEL_TICKET_SIZE * SCALED_WIDTH ); + mLabel1.SetPosition( LABEL_TICKET_POSITION * SCALED_WIDTH ); + mLabel1.SetVisible( true ); + mLabel1.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_TICKET_FONT_COLOR ); + mLabel1.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_TICKET_FONT_SIZE * FONT_SCALE ); + mLabel1.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" ); + mLabel1.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); + + mLabel2 = TextLabel::New( LABEL_HOLD_STR ); + mLabel2.SetParentOrigin( ParentOrigin::CENTER ); + mLabel2.SetAnchorPoint( AnchorPoint::CENTER ); + mLabel2.SetSize( LABEL_HOLD_SIZE * SCALED_WIDTH ); + mLabel2.SetPosition( LABEL_HOLD_POSITION * SCALED_WIDTH ); + mLabel2.SetVisible( false ); + mLabel2.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_HOLD_FONT_COLOR ); + mLabel2.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_HOLD_FONT_SIZE * FONT_SCALE ); + mLabel2.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" ); + mLabel2.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); + + mLabel3 = TextLabel::New( LABEL_TERMINAL_STR ); + mLabel3.SetParentOrigin( ParentOrigin::CENTER ); + mLabel3.SetAnchorPoint( AnchorPoint::CENTER ); + mLabel3.SetSize( LABEL_TERMINAL_SIZE * SCALED_WIDTH ); + mLabel3.SetPosition( LABEL_TERMINAL_POSITION * SCALED_WIDTH ); + mLabel3.SetVisible( false ); + mLabel3.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_TERMINAL_FONT_COLOR ); + mLabel3.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_TERMINAL_FONT_SIZE * FONT_SCALE ); + mLabel3.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" ); + mLabel3.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); + + mStage.Add( mAddButton ); + mStage.Add( mLabel1 ); + mStage.Add( mLabel2 ); + mStage.Add( mLabel3 ); + } + + void SetupAnimation() + { + mMoveFront = Animation::New( mDuration ); + mMoveBack = Animation::New( mDuration ); + } + + // Run animations when 'index' card active + void RunAnimation(int index) + { + //set animated background color here + mColorAnimationStartStart[DevelAnimatedGradientVisual::AnimationParameter::Property::START] = mNormalStartColor; + mColorAnimationStartEnd[DevelAnimatedGradientVisual::AnimationParameter::Property::START] = mNormalStartColor; + mColorAnimationEndStart[DevelAnimatedGradientVisual::AnimationParameter::Property::START] = mNormalStartColor; + mColorAnimationEndEnd[DevelAnimatedGradientVisual::AnimationParameter::Property::START] = mNormalStartColor; + + mColorAnimationStartStart[DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET] = mCards.GetColorStart( index ); + mColorAnimationStartEnd[DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET] = mCards.GetColorEnd( index ); + mColorAnimationEndStart[DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET] = mCards.GetColorStart( index ); + mColorAnimationEndEnd[DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET] = mCards.GetColorEnd( index ); + + mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mColorAnimationStartStart; + mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mColorAnimationStartEnd; + mBackgroundMapEnd[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mColorAnimationEndStart; + mBackgroundMapEnd[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mColorAnimationEndEnd; + + if( index == 1 ) + { + // Rotate background gradient + mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT] = BuildMap( 0.0f, Math::PI * 2.0f, 0, mLoadingTime, 0.0f, -1, 0.0f, 0, 0 ); + } + else if( index == 2 ) + { + // Rotate background gradient more slow + mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT] = BuildMap( 0.0f, Math::PI * 2.0f, 0, mLoadingTime * 2.0, 0.0f, -1, 0.0f, 0, 0 ); + } + else + { + mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT] = 0.0f; + } + + mBackground.SetProperty( Control::Property::BACKGROUND, mBackgroundMapStart ); + + mTickCount = 0; + mBackgroundChanger = Timer::New( mLoadingTime * 1000.0f / mLoadingCountScale ); + mBackgroundChanger.TickSignal().Connect( this, &CardController::OnTickBackground ); + mBackgroundChanger.Start(); + + mMoveFront.AnimateTo( Property( mCards[index], Actor::Property::SIZE_WIDTH ), CARD_SIZE_BIG.x * SCALED_WIDTH ); + mMoveFront.AnimateTo( Property( mCards[index], Actor::Property::SIZE_HEIGHT ), CARD_SIZE_BIG.y * SCALED_HEIGHT ); + mMoveFront.AnimateTo( Property( mCards[index], Actor::Property::POSITION_Y ), CARD_BIG_OFFSET.y * SCALED_HEIGHT ); + mMoveBack.AnimateTo( Property( mCards[index], Actor::Property::SIZE_WIDTH ), CARD_SIZE.x * SCALED_WIDTH ); + mMoveBack.AnimateTo( Property( mCards[index], Actor::Property::SIZE_HEIGHT ), CARD_SIZE.y * SCALED_HEIGHT ); + mMoveBack.AnimateTo( Property( mCards[index], Actor::Property::POSITION_Y ), CARD_OFFSET.y * SCALED_HEIGHT ); + for( int i = 0; i < index; i++ ) + { + mMoveFront.AnimateBy( Property( mCards[i], Actor::Property::POSITION_X ), -CARD_MOVE_DIST * SCALED_WIDTH ); + mMoveBack.AnimateBy( Property( mCards[i], Actor::Property::POSITION_X ), CARD_MOVE_DIST * SCALED_WIDTH ); + } + for( int i = index + 1; i < CARD_NUM; i++ ) + { + mMoveFront.AnimateBy( Property( mCards[i], Actor::Property::POSITION_X ), CARD_MOVE_DIST * SCALED_WIDTH ); + mMoveBack.AnimateBy( Property( mCards[i], Actor::Property::POSITION_X ), -CARD_MOVE_DIST * SCALED_WIDTH ); + } + mMoveFront.AnimateTo( Property( mAddButton, Actor::Property::POSITION_Y ), BUTTON_ADD_SIZE.y * SCALED_HEIGHT ); + mMoveBack.AnimateTo( Property( mAddButton, Actor::Property::POSITION_Y ), 0.f * SCALED_HEIGHT ); + + mMoveFront.AnimateTo( Property( mLabel1, Actor::Property::VISIBLE), false ); + mMoveFront.AnimateTo( Property( mLabel2, Actor::Property::VISIBLE), true ); + mMoveFront.AnimateTo( Property( mLabel3, Actor::Property::VISIBLE), true ); + mMoveBack.AnimateTo( Property( mLabel1, Actor::Property::VISIBLE), true ); + mMoveBack.AnimateTo( Property( mLabel2, Actor::Property::VISIBLE), false ); + mMoveBack.AnimateTo( Property( mLabel3, Actor::Property::VISIBLE), false ); + + mMoveFront.Play(); + } + bool OnTickBackground() + { + mTickCount++; + if( mCancelSignal || mTickCount >= mLoadingCount * mLoadingCountScale ) + { + if( mCards.mCurState == 1 ) + { + mCards.mCurState = 2; + mBackground.SetProperty( Control::Property::BACKGROUND, mBackgroundMapEnd ); + mMoveBack.Play(); + mBackgroundChanger.SetInterval( mDuration * 1000.0f ); + return true; + } + else + { + Reset(); + return false; + } + } + return true; + } + void MoveRight() + { + if( mCards.MoveRight( mCardDuration ) ) + { + // Set smooth background color change here + mNormalEndColor = mCards.GetColorBackground( mCards.mCurIndex ); + mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mNormalEndColor; + mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mNormalStartColor; + + (*mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET].GetMap())[DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION] = Property::Value( DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD ); + + mBackground.SetProperty( Control::Property::BACKGROUND, mBackgroundMapMove ); + } + } + void MoveLeft() + { + if( mCards.MoveLeft( mCardDuration ) ) + { + //Set smooth background color change here + mNormalEndColor = mCards.GetColorBackground( mCards.mCurIndex ); + mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mNormalStartColor; + mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mNormalEndColor; + + (*mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET].GetMap())[DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION] = Property::Value( DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD ); + + mBackground.SetProperty( Control::Property::BACKGROUND, mBackgroundMapMove ); + } + } + + void Reset() + { + mCards.mCurState = 0; + mCancelSignal = false; + mMoveFront.Clear(); + mMoveBack.Clear(); + + mNormalStartColor = mNormalEndColor; + mBackgroundNormalMap[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mNormalStartColor; + mBackgroundNormalMap[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mNormalEndColor; + mBackground.SetProperty(Control::Property::BACKGROUND, mBackgroundNormalMap); + } + +private: + Application& mApplication; + Stage mStage; + + CardManager mCards; + + Control mBackground; + + ImageView mAddButton; + TextLabel mLabel1; + TextLabel mLabel2; + TextLabel mLabel3; + + Timer mBackgroundChanger; + Timer mCardChanger; + Timer mTempTimer; + + Animation mMoveFront; + Animation mMoveBack; + + // Property for background animated gradient visual + Property::Map mBackgroundNormalMap; + Property::Map mBackgroundMapStart; + Property::Map mBackgroundMapEnd; + Property::Map mBackgroundMapMove; + + // Property for animation of color in animated gradient visual + Property::Map mColorAnimationStartStart; + Property::Map mColorAnimationStartEnd; + Property::Map mColorAnimationEndStart; + Property::Map mColorAnimationEndEnd; + + Vector4 mNormalColor; + Vector4 mNormalStartColor; + Vector4 mNormalEndColor; + + Vector2 mFirstTouchPos; + Vector2 mLastTouchPos; + + float mCardDuration; + float mDuration; + float mLoadingTime; + int mLoadingCount; + int mLoadingCountScale; + int mTickCount; + + bool mCancelSignal; + bool mIsTouchedActor; +}; + +int main(int argc, char **argv) +{ + Application application = Application::New( &argc, &argv ); + + CardController test( application ); + + application.MainLoop(); + + return 0; +} diff --git a/examples/animated-images/animated-images-example.cpp b/examples/animated-images/animated-images-example.cpp index fab53de8..925d754a 100644 --- a/examples/animated-images/animated-images-example.cpp +++ b/examples/animated-images/animated-images-example.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * 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. @@ -17,260 +17,278 @@ #include <dali-toolkit/dali-toolkit.h> #include <dali-toolkit/devel-api/controls/buttons/button-devel.h> -#include "shared/utility.h" +#include <dali-toolkit/devel-api/controls/control-devel.h> +#include <dali-toolkit/devel-api/visuals/animated-image-visual-actions-devel.h> using namespace Dali; using namespace Dali::Toolkit; namespace { -const char * const PLAY_ICON( DEMO_IMAGE_DIR "icon-play.png" ); +const char * const PLAY_ICON_UNSELECTED( DEMO_IMAGE_DIR "icon-play.png" ); const char * const PLAY_ICON_SELECTED( DEMO_IMAGE_DIR "icon-play-selected.png" ); -const char* const STATIC_GIF_DOG( DEMO_IMAGE_DIR "dog-static.gif" ); -const char* const ANIMATE_GIF_DOG( DEMO_IMAGE_DIR "dog-anim.gif" ); +const unsigned int ANIMATED_IMAGE_COUNT = 2; -const char* const STATIC_GIF_LOGO( DEMO_IMAGE_DIR "dali-logo-static.gif" ); -const char* const ANIMATE_GIF_LOGO( DEMO_IMAGE_DIR "dali-logo-anim.gif" ); +const char * ANIMATED_GIF_URLS[ ANIMATED_IMAGE_COUNT ] = +{ + DEMO_IMAGE_DIR "dog-anim.gif", + DEMO_IMAGE_DIR "dali-logo-anim.gif" +}; + +const char * ANIMATED_ARRAY_URL_FORMATS[ ANIMATED_IMAGE_COUNT ] = +{ + DEMO_IMAGE_DIR "dog-anim-%03d.png", // Images are named dog-anim-001.png, dog-anim-002.png, etc. + DEMO_IMAGE_DIR "dali-logo-anim-%03d.png" // Images are named dali-logo-anim-001.png, dali-logo-anim-002.png, etc. +}; -const char* const ANIMATE_PIXEL_AREA( "Animate PixelArea" ); -const char* const ANIMATE_PIXEL_AREA_AND_SCALE( "Animate PixelArea & Scale" ); +int ANIMATED_ARRAY_NUMBER_OF_FRAMES[ ANIMATED_IMAGE_COUNT ] = +{ + 8, + 15 +}; -const char* const STATIC_IMAGE_ARRAY_DOG( DEMO_IMAGE_DIR "dog-anim-001.png" ); -const char* const ANIMATE_IMAGE_ARRAY_DOG( DEMO_IMAGE_DIR "dog-anim-%03d.png" ); +const char * GIF_RADIO_BUTTON_NAME( "Gif" ); +const char * ARRAY_RADIO_BUTTON_NAME( "Array" ); -const char* const STATIC_IMAGE_ARRAY_LOGO( DEMO_IMAGE_DIR "dali-logo-anim-001.png" ); -const char* const ANIMATE_IMAGE_ARRAY_LOGO( DEMO_IMAGE_DIR "dali-logo-anim-%03d.png" ); +/// Structure to specify the layout information for the animated images views. +struct ImageLayoutInfo +{ + Vector3 anchorPoint; + Vector3 parentOrigin; + float yPosition; +}; +ImageLayoutInfo IMAGE_LAYOUT_INFO[ ANIMATED_IMAGE_COUNT ] = +{ + { AnchorPoint::BOTTOM_CENTER, ParentOrigin::CENTER, -80.0f }, + { AnchorPoint::TOP_CENTER, ParentOrigin::CENTER, 80.0f } +}; -const Vector4 DIM_COLOR( 0.85f, 0.85f, 0.85f, 0.85f ); -} +} // unnamed namespace -/* This example shows how to display a GIF image. - * First a static GIF image is loaded and then when the user presses on the "Play" icon, - * the static image is replaced by an animated one +/** + * @brief This demonstrates how to display and control Animated Images. + * + * - It displays two animated images, an animated dog and an animated DALi logo. + * - The images are loaded paused, a play button is overlayed on top of the images to play the animated image. + * - Radio buttons at the bottom allow the user to change between Animated GIFs and a collection of Image Arrays. */ - class AnimatedImageController : public ConnectionTracker { public: - enum ImageType - { - GIF, - IMAGE_ARRAY - }; - enum StateType - { - STATIC, - ANIMATED - }; + /** + * @brief Constructor. + * @param[in] application A reference to the Application class + */ AnimatedImageController( Application& application ) : mApplication( application ), - mImageType(GIF) + mImageType( ImageType::GIF ) { // Connect to the Application's Init signal mApplication.InitSignal().Connect( this, &AnimatedImageController::Create ); } - ~AnimatedImageController() +private: + + /** + * @brief The image types supported by the application. + */ + enum class ImageType { - // Nothing to do here; - } + GIF, ///< Displays Animated GIF Files. + IMAGE_ARRAY ///< Displays an array of URLs that are used as an animated image. + }; - // The Init signal is received once (only) during the Application lifetime + /** + * @brief Called to initialise the application content. + * @param[in] application A reference to the Application class + */ void Create( Application& application ) { - // Get a handle to the stage + // Set the stage background color and connect to the stage's key signal to allow Back and Escape to exit. Stage stage = Stage::GetCurrent(); stage.SetBackgroundColor( Color::WHITE ); - // Tie-in input event handlers: stage.KeyEventSignal().Connect( this, &AnimatedImageController::OnKeyEvent ); - CreateStaticImageView( 0 ); - CreateStaticImageView( 1 ); + // Create the animated image-views + CreateAnimatedImageViews(); + + // Create radio buttons to change between GIF images and Image Arrays + CreateRadioButtonLayout(); + + // Create a tap gesture detector to use to pause the animated images + mTapDetector = TapGestureDetector::New(); + mTapDetector.DetectedSignal().Connect( this, &AnimatedImageController::OnTap ); + } - mGifButton = Toolkit::RadioButton::New("Gif"); - mGifButton.SetProperty( Button::Property::SELECTED, true ); - mArrayButton = Toolkit::RadioButton::New("Array"); - mGifButton.ClickedSignal().Connect( this, &AnimatedImageController::OnTypeButtonClicked ); - mArrayButton.ClickedSignal().Connect( this, &AnimatedImageController::OnTypeButtonClicked ); + /** + * @brief Creates and lays out radio buttons to allow changing between the different image types. + */ + void CreateRadioButtonLayout() + { + mGifButton = CreateRadioButton( GIF_RADIO_BUTTON_NAME, true ); + mArrayButton = CreateRadioButton( ARRAY_RADIO_BUTTON_NAME, false ); - Toolkit::TableView radioButtonLayout = Toolkit::TableView::New(1, 2); - radioButtonLayout.SetName("RadioButtonsLayout"); + Toolkit::TableView radioButtonLayout = Toolkit::TableView::New( 1, 2 ); + radioButtonLayout.SetName( "RadioButtonsLayout" ); radioButtonLayout.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT ); radioButtonLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); radioButtonLayout.SetParentOrigin( ParentOrigin::BOTTOM_CENTER ); radioButtonLayout.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER ); - radioButtonLayout.SetFitHeight(0); - radioButtonLayout.AddChild( mGifButton, TableView::CellPosition(0,0) ); - radioButtonLayout.AddChild( mArrayButton, TableView::CellPosition(0,1) ); - radioButtonLayout.SetCellAlignment( TableView::CellPosition( 0, 0 ), HorizontalAlignment::CENTER, VerticalAlignment::CENTER ); - radioButtonLayout.SetCellAlignment( TableView::CellPosition( 0, 1 ), HorizontalAlignment::CENTER, VerticalAlignment::CENTER ); + radioButtonLayout.SetFitHeight( 0 ); + radioButtonLayout.AddChild( mGifButton, TableView::CellPosition( 0, 0 ) ); + radioButtonLayout.AddChild( mArrayButton, TableView::CellPosition( 0, 1 ) ); + radioButtonLayout.SetCellAlignment( TableView::CellPosition( 0, 0 ), + HorizontalAlignment::CENTER, + VerticalAlignment::CENTER ); + radioButtonLayout.SetCellAlignment( TableView::CellPosition( 0, 1 ), + HorizontalAlignment::CENTER, + VerticalAlignment::CENTER ); radioButtonLayout.SetY( -10.0f ); - stage.Add( radioButtonLayout ); - - mTapDetector = TapGestureDetector::New(); - mTapDetector.DetectedSignal().Connect( this, &AnimatedImageController::OnTap ); + Stage::GetCurrent().Add( radioButtonLayout ); } - void CreateStaticImageView( int index ) + /** + * @brief Creates a radio button. + * @param[in] name The name of the button + * @param[in] selected Whether the button is selected + * @return The created radio-button + */ + RadioButton CreateRadioButton( const char * const name, bool selected ) { - Actor& actor = (index==0) ? mActorDog : mActorLogo; - - Stage stage = Stage::GetCurrent(); - if( actor ) - { - stage.Remove( actor ); - } - - Property::Value viewSetup = SetupViewProperties( mImageType, STATIC, index, false ); - actor = CreateImageViewWithPlayButton( viewSetup ); - SetLayout(actor, index); - stage.Add( actor ); + RadioButton radioButton = Toolkit::RadioButton::New( name ); + radioButton.SetProperty( Button::Property::SELECTED, selected ); + radioButton.ClickedSignal().Connect( this, &AnimatedImageController::OnRadioButtonClicked ); + return radioButton; } - - void CreateAnimImageView( int index ) + /** + * @brief Creates the required animated image views. + */ + void CreateAnimatedImageViews() { - Actor& actor = (index==0) ? mActorDog : mActorLogo; - - Stage stage = Stage::GetCurrent(); - if( actor ) + for( unsigned int index = 0; index < ANIMATED_IMAGE_COUNT; ++index ) { - stage.Remove( actor ); - } + Stage stage = Stage::GetCurrent(); - const char* label = (index==0) ? ANIMATE_PIXEL_AREA_AND_SCALE : ANIMATE_PIXEL_AREA; + Control& control = ( index == 0 ) ? mActorDog : mActorLogo; + if( control ) + { + // Remove the previous control from the stage, it's resources (and children) will be deleted automatically + control.Unparent(); + } - Property::Value viewSetup = SetupViewProperties( mImageType, ANIMATED, index, true ); - actor = CreateImageViewWithAnimatePixelAreaButton( viewSetup, label); - SetLayout(actor, index); + // Create and lay out the image view according to the index + control = Toolkit::ImageView::New(); + control.SetProperty( Toolkit::ImageView::Property::IMAGE, SetupViewProperties( mImageType, index ) ); + control.SetAnchorPoint( IMAGE_LAYOUT_INFO[ index ].anchorPoint ); + control.SetParentOrigin( IMAGE_LAYOUT_INFO[ index ].parentOrigin ); + control.SetY( IMAGE_LAYOUT_INFO[ index ].yPosition ); - stage.Add( actor ); + // We do not want the animated image playing when it's added to the stage. + PauseAnimatedImage( control ); + + stage.Add( control ); + } } - void SetLayout( Actor actor, int index ) + /** + * @brief Plays the passed in animated image. + * @details Also sets up the control so it can be paused when tapped. + * @param[in] control The animated image to play + */ + void PlayAnimatedImage( Control& control ) { - if( index == 0 ) - { - actor.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER ); - actor.SetY( -80.f ); - } - else + DevelControl::DoAction( control, + ImageView::Property::IMAGE, + DevelAnimatedImageVisual::Action::PLAY, + Property::Value() ); + + if( mTapDetector ) { - actor.SetAnchorPoint( AnchorPoint::TOP_CENTER ); - actor.SetY( 80.f ); + mTapDetector.Attach( control ); } } /** - * Create the gif image view with an overlay play button. + * @brief Pauses the animated image. + * @details Adds a Play button to the control and sets both up so that the animated image can be played again when + * the button is tapped. + * @param[in] control The animated image to pause */ - Toolkit::ImageView CreateImageViewWithPlayButton( Property::Value& viewSetup ) + void PauseAnimatedImage( Control& control ) { - Toolkit::ImageView imageView = Toolkit::ImageView::New(); - imageView.SetProperty( ImageView::Property::IMAGE, viewSetup ); - imageView.SetParentOrigin( ParentOrigin::CENTER ); + DevelControl::DoAction( control, + ImageView::Property::IMAGE, + DevelAnimatedImageVisual::Action::PAUSE, + Property::Value() ); - // Create a push button, and add it as child of the image view + // Create a push button, and add it as child of the control Toolkit::PushButton animateButton = Toolkit::PushButton::New(); - animateButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, PLAY_ICON ); + animateButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, PLAY_ICON_UNSELECTED ); animateButton.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, PLAY_ICON_SELECTED ); animateButton.SetParentOrigin( ParentOrigin::CENTER ); animateButton.SetAnchorPoint( AnchorPoint::CENTER ); animateButton.ClickedSignal().Connect( this, &AnimatedImageController::OnPlayButtonClicked ); - imageView.Add( animateButton ); + control.Add( animateButton ); - // Apply dim color on the gif view and the play button - imageView.SetColor( DIM_COLOR ); - - return imageView; - } - - Toolkit::ImageView CreateImageViewWithAnimatePixelAreaButton( Property::Value& viewSetup, const std::string& buttonLabel ) - { - Toolkit::ImageView imageView = Toolkit::ImageView::New(); - imageView.SetProperty( Toolkit::ImageView::Property::IMAGE, viewSetup ); - imageView.SetParentOrigin( ParentOrigin::CENTER ); - - // Create a push button, and add it as child of the image view - Toolkit::PushButton animateButton = Toolkit::PushButton::New(); - animateButton.SetProperty( Toolkit::Button::Property::LABEL, buttonLabel ); - animateButton.SetParentOrigin( ParentOrigin::BOTTOM_CENTER ); - animateButton.SetAnchorPoint( AnchorPoint::TOP_CENTER ); - animateButton.SetY( 20.f ); - - animateButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS ); - animateButton.SetProperty( Actor::Property::INHERIT_SCALE, false ); - imageView.Add( animateButton ); - - mTapDetector.Attach( animateButton ); - mTapDetector.Attach( imageView ); - - return imageView; + if( mTapDetector ) + { + mTapDetector.Detach( control ); + } } + /** + * @brief Called when the play button is clicked. + * @details This method is used to start playing the parent image-view of the clicked button. + * @param[in] button The button that has been clicked + * @return We return true to state that we handled the event + */ bool OnPlayButtonClicked( Toolkit::Button button ) { - Stage stage = Stage::GetCurrent(); + Control control = ( button.GetParent() == mActorDog ) ? mActorDog : mActorLogo; + PlayAnimatedImage( control ); + + button.Unparent(); - // With play button clicked, the static gif is replaced with animated gif. - if( button.GetParent() == mActorDog ) - { - // remove the static gif view, the play button is also removed as its child. - CreateAnimImageView( 0 ); - } - else // button.GetParent() == mActorLogo - { - // remove the static gif view, the play button is also removed as its child. - CreateAnimImageView( 1 ); - } return true; } - void OnTap(Dali::Actor actor, const Dali::TapGesture& tap) + /** + * @brief Called when the animated image views are tapped. + * @details This method is used to pause the tapped animated image view. + * @param[in] actor The actor that's tapped + */ + void OnTap( Dali::Actor actor, const Dali::TapGesture& /* tap */ ) { - if( actor.GetParent() == mActorDog ) // "Animate Pixel Area" button is clicked - { - Animation animation = Animation::New( 3.f ); - animation.AnimateTo( Property( mActorDog, ImageView::Property::PIXEL_AREA ), Vector4( -1.0, 0.0, 3.f, 1.f ), AlphaFunction::SIN ); - animation.AnimateTo( Property( mActorDog, Actor::Property::SCALE_X ), 3.f, AlphaFunction::SIN ); - animation.Play(); - } - else if( actor.GetParent() == mActorLogo ) // "Animate Pixel Area" button is clicked - { - Animation animation = Animation::New( 3.f ); - animation.AnimateTo( Property( mActorLogo, ImageView::Property::PIXEL_AREA ), Vector4( 0.0, 1.0, 1.f, 1.f ), AlphaFunction::SIN ); - animation.Play(); - } - else if( actor == mActorDog ) // stop the animated gif, switch to static view - { - CreateStaticImageView( 0 ); - } - else if( actor == mActorLogo ) // stop the animated gif, switch to static view - { - CreateStaticImageView( 1 ); - } + Control control = ( actor == mActorDog ) ? mActorDog : mActorLogo; + PauseAnimatedImage( control ); } - bool OnTypeButtonClicked( Toolkit::Button button ) + /** + * @brief Called when a radio button is clicked. + * @details This method is used to change between the different image types. + * @param[in] button The clicked radio-button + * @return We return true to state that we handled the event. + * + */ + bool OnRadioButtonClicked( Toolkit::Button button ) { - if( button == mGifButton ) - { - mImageType = GIF; - } - else - { - mImageType = IMAGE_ARRAY; - } - Stage stage = Stage::GetCurrent(); - CreateStaticImageView( 0 ); - CreateStaticImageView( 1 ); + mImageType = ( button == mGifButton ) ? ImageType::GIF : ImageType::IMAGE_ARRAY; + + CreateAnimatedImageViews(); return true; } + /** + * @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) @@ -282,82 +300,60 @@ public: } } - Property::Value SetupViewProperties( ImageType type, StateType state, int index, bool wrap ) + /** + * @brief Sets up the view properties appropriately. + * @param[in] type The Image type + * @param[in] index The index + * @return The set up property value + */ + Property::Value SetupViewProperties( ImageType type, int index ) { Property::Map map; - AddUrl( map, type, state, index ); - AddWrap( map, wrap && state != 0, index ); + AddUrl( map, type, index ); AddCache( map, type, index ); return Property::Value(map); } - void AddUrl( Property::Map& map, ImageType type, StateType state, int index ) + /** + * @brief Adds the URL to the given map appropriately. + * @param[in/out] map The map to add the URL details to + * @param[in] type The Image type + * @param[in] index The index + */ + void AddUrl( Property::Map& map, ImageType type, int index ) { - const char* urls[2][2] = - { { STATIC_GIF_DOG, STATIC_GIF_LOGO }, - { ANIMATE_GIF_DOG, ANIMATE_GIF_LOGO } - }; - const char* urlFormats[2][2] = - { { STATIC_IMAGE_ARRAY_DOG, STATIC_IMAGE_ARRAY_LOGO } , - { ANIMATE_IMAGE_ARRAY_DOG, ANIMATE_IMAGE_ARRAY_LOGO } }; - - int numFrames[2] = { 8, 15 }; - - if( type == GIF ) + if( type == ImageType::GIF ) { - map.Add( Toolkit::ImageVisual::Property::URL, Property::Value( urls[state][index] ) ); + map.Add( Toolkit::ImageVisual::Property::URL, Property::Value( ANIMATED_GIF_URLS[ index ] ) ); } else { - if( state == STATIC ) + Property::Array frameUrls; + for( int i = 1; i <= ANIMATED_ARRAY_NUMBER_OF_FRAMES[ index ]; ++i ) { - Property::Array frameUrls; - frameUrls.Add(Property::Value( urlFormats[0][index] )); - map.Add( Toolkit::ImageVisual::Property::URL, frameUrls ); - } - else - { - Property::Array frameUrls; - for( int i=1; i<= numFrames[index]; ++i ) + char* buffer; + int len = asprintf( &buffer, ANIMATED_ARRAY_URL_FORMATS[ index ], i ); + if( len > 0 ) { - char* buffer; - int len = asprintf( &buffer, urlFormats[1][index], i); - if( len > 0 ) - { - std::string frameUrl(buffer); - free(buffer); - frameUrls.Add( Property::Value( frameUrl ) ); - } + std::string frameUrl( buffer ); + free( buffer ); + frameUrls.Add( Property::Value( frameUrl ) ); } - map.Add( Toolkit::ImageVisual::Property::URL, Property::Value( frameUrls ) ); } + map.Add( Toolkit::ImageVisual::Property::URL, Property::Value( frameUrls ) ); } } - void AddWrap( Property::Map& map, bool wrap, int index ) - { - WrapMode::Type wrapModes[2][2] = { - { WrapMode::REPEAT, WrapMode::DEFAULT }, - { WrapMode::DEFAULT, WrapMode::MIRRORED_REPEAT } }; - - if( wrap ) - { - map - .Add( Toolkit::ImageVisual::Property::WRAP_MODE_U, wrapModes[index][0] ) - .Add( Toolkit::ImageVisual::Property::WRAP_MODE_V, wrapModes[index][1] ); - } - else - { - map - .Add( Toolkit::ImageVisual::Property::WRAP_MODE_U, WrapMode::DEFAULT ) - .Add( Toolkit::ImageVisual::Property::WRAP_MODE_V, WrapMode::DEFAULT ); - } - } - + /** + * @brief Adds the cache properties, if required to the map. + * @param[in/out] map The map to add the URL details to + * @param[in] type The Image type + * @param[in] index The index + */ void AddCache( Property::Map& map, ImageType type, int index ) { - if( type == IMAGE_ARRAY ) + if( type == ImageType::IMAGE_ARRAY ) { map .Add( Toolkit::ImageVisual::Property::BATCH_SIZE, 4 ) @@ -367,16 +363,19 @@ public: } private: - Application& mApplication; - Toolkit::ImageView mActorDog; - Toolkit::ImageView mActorLogo; - Toolkit::RadioButton mGifButton; - Toolkit::RadioButton mArrayButton; - TapGestureDetector mTapDetector; - ImageType mImageType; + Application& mApplication; ///< A reference to the application. + + Toolkit::ImageView mActorDog; ///< The current dog image view. + Toolkit::ImageView mActorLogo; ///< The current logo image view. + + Toolkit::RadioButton mGifButton; ///< The Gif Radio Button. + Toolkit::RadioButton mArrayButton; ///< The Array Radio Button. + + TapGestureDetector mTapDetector; ///< The tap detector. + + ImageType mImageType; ///< The current Image type. }; -// int DALI_EXPORT_API main( int argc, char **argv ) { Application application = Application::New( &argc, &argv ); diff --git a/examples/blocks/blocks-example.cpp b/examples/blocks/blocks-example.cpp index dc3b2083..7cadbe25 100644 --- a/examples/blocks/blocks-example.cpp +++ b/examples/blocks/blocks-example.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * 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. @@ -23,6 +23,7 @@ #include <dali/dali.h> #include <dali-toolkit/dali-toolkit.h> +#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h> #include "shared/view.h" using namespace Dali; @@ -586,7 +587,12 @@ private: */ ImageView CreateImage(const std::string& filename) { - ImageView actor = ImageView::New(filename); + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, filename); + propertyMap.Insert(DevelVisual::Property::VISUAL_FITTING_MODE, DevelVisual::FILL); + ImageView actor = ImageView::New(); + actor.SetProperty(Toolkit::ImageView::Property::IMAGE, propertyMap); actor.SetParentOrigin(ParentOrigin::TOP_LEFT); actor.SetAnchorPoint(AnchorPoint::CENTER); return actor; diff --git a/examples/clipping/clipping-item-factory.cpp b/examples/clipping/clipping-item-factory.cpp index 1233831e..9d3b8860 100644 --- a/examples/clipping/clipping-item-factory.cpp +++ b/examples/clipping/clipping-item-factory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * 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. @@ -23,6 +23,8 @@ #include <dali-toolkit/public-api/controls/image-view/image-view.h> #include <dali-toolkit/public-api/visuals/border-visual-properties.h> #include <dali-toolkit/public-api/visuals/visual-properties.h> +#include <dali-toolkit/public-api/visuals/image-visual-properties.h> +#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h> using namespace Dali; using namespace Dali::Toolkit; @@ -102,7 +104,12 @@ unsigned int ClippingItemFactory::GetNumberOfItems() Actor ClippingItemFactory::NewItem( unsigned int itemId ) { // Create an image view for this item - ImageView actor = ImageView::New( IMAGE_PATHS[ itemId % NUM_IMAGES ] ); + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, IMAGE_PATHS[ itemId % NUM_IMAGES ] ); + propertyMap.Insert(DevelVisual::Property::VISUAL_FITTING_MODE, DevelVisual::FILL); + ImageView actor = ImageView::New(); + actor.SetProperty(Toolkit::ImageView::Property::IMAGE, propertyMap); // Add a border image child actor ImageView borderActor = ImageView::New(); diff --git a/examples/image-policies/image-policies-example.cpp b/examples/image-policies/image-policies-example.cpp index 7f7acc84..c96b7b39 100644 --- a/examples/image-policies/image-policies-example.cpp +++ b/examples/image-policies/image-policies-example.cpp @@ -98,16 +98,17 @@ class ImagePolicies: public ConnectionTracker * param[in] releasePolicy Which ReleasePolicy to use * param[in] synchronousLoading If the Image should be loaded synchronously * param[in] imageFilenameId Which image to load, referring to the array of filenames for this example. + * return An ImageView with the required set up */ - ImageView CreateImageView( bool correctionEnabled, DevelImageVisual::LoadPolicy::Type loadPolicy, DevelImageVisual::ReleasePolicy::Type releasePolicy, bool synchronousLoading, unsigned int imageFilenameId ) + ImageView CreateImageView( bool correctionEnabled, ImageVisual::LoadPolicy::Type loadPolicy, ImageVisual::ReleasePolicy::Type releasePolicy, bool synchronousLoading, unsigned int imageFilenameId ) { ImageView imageView = ImageView::New( ); Property::Map imagePropertyMap; imagePropertyMap.Insert( Visual::Property::TYPE, Visual::IMAGE ); imagePropertyMap.Insert( ImageVisual::Property::URL, IMAGE_PATH[imageFilenameId ] ); - imagePropertyMap.Insert( DevelImageVisual::Property::ORIENTATION_CORRECTION, correctionEnabled ); - imagePropertyMap.Insert( DevelImageVisual::Property::LOAD_POLICY, loadPolicy ); - imagePropertyMap.Insert( DevelImageVisual::Property::RELEASE_POLICY, releasePolicy ); + imagePropertyMap.Insert( ImageVisual::Property::ORIENTATION_CORRECTION, correctionEnabled ); + imagePropertyMap.Insert( ImageVisual::Property::LOAD_POLICY, loadPolicy ); + imagePropertyMap.Insert( ImageVisual::Property::RELEASE_POLICY, releasePolicy ); if( synchronousLoading ) { imagePropertyMap.Insert( DevelImageVisual::Property::SYNCHRONOUS_LOADING, true ); @@ -121,6 +122,7 @@ class ImagePolicies: public ConnectionTracker return imageView; } + /** * To prevent the next button being pressed before an Image has loaded the Button can br disabled. * This function will disable the next button. @@ -142,7 +144,7 @@ class ImagePolicies: public ConnectionTracker mInstructions.SetProperty( TextLabel::Property::TEXT, "Orientation Correction not applied"); mTable.RemoveChildAt( TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) ); DisableButtonWhilstLoading(); - ImageView imageView01 = CreateImageView( false, DevelImageVisual::LoadPolicy::ATTACHED, DevelImageVisual::ReleasePolicy::DESTROYED, false, 3 ); + ImageView imageView01 = CreateImageView( false, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 ); imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal ); mTable.AddChild( imageView01, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) ); @@ -156,7 +158,7 @@ class ImagePolicies: public ConnectionTracker mInstructions.SetProperty( TextLabel::Property::TEXT, "Orientation Correction applied based on Exif data, now shown in landscape"); mTable.RemoveChildAt( TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) ); DisableButtonWhilstLoading(); - ImageView imageView01 = CreateImageView( true, DevelImageVisual::LoadPolicy::ATTACHED, DevelImageVisual::ReleasePolicy::DESTROYED, false, 3 ); + ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 ); imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal ); mTable.AddChild( imageView01, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) ); } @@ -185,7 +187,9 @@ class ImagePolicies: public ConnectionTracker dualImageViewTable.AddChild( immediate, TableView::CellPosition( 0, 1 ) ); mTable.AddChild( dualImageViewTable, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) ); - mPersistantImageView = CreateImageView( true, DevelImageVisual::LoadPolicy::IMMEDIATE, DevelImageVisual::ReleasePolicy::DESTROYED, false, 4 ); + DisableButtonWhilstLoading(); + mPersistantImageView = CreateImageView( true, ImageVisual::LoadPolicy::IMMEDIATE, ImageVisual::ReleasePolicy::DESTROYED, false, 4 ); + mPersistantImageView.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal ); } /** @@ -212,7 +216,7 @@ class ImagePolicies: public ConnectionTracker mTable.AddChild( dualImageViewTable, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) ); - ImageView imageView02 = CreateImageView( true, DevelImageVisual::LoadPolicy::ATTACHED, DevelImageVisual::ReleasePolicy::DESTROYED, false, 3 ); + ImageView imageView02 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 ); imageView02.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal ); dualImageViewTable.AddChild( imageView02, TableView::CellPosition( 0, 0 ) ); dualImageViewTable.AddChild( mPersistantImageView, TableView::CellPosition( 0, 1 ) ); @@ -236,7 +240,7 @@ class ImagePolicies: public ConnectionTracker mTable.AddChild( dualImageViewTable, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) ); - ImageView imageView01 = CreateImageView( true, DevelImageVisual::LoadPolicy::ATTACHED, DevelImageVisual::ReleasePolicy::DESTROYED, false, 3 ); + ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 ); imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal ); dualImageViewTable.AddChild( imageView01, TableView::CellPosition( 0, 0 ) ); @@ -259,7 +263,7 @@ class ImagePolicies: public ConnectionTracker mTable.AddChild( dualImageViewTable, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) ); - ImageView imageView01 = CreateImageView( true, DevelImageVisual::LoadPolicy::ATTACHED, DevelImageVisual::ReleasePolicy::DESTROYED, false, 3 ); + ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 ); imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal ); dualImageViewTable.AddChild( imageView01, TableView::CellPosition( 0, 1 ) ); @@ -282,7 +286,7 @@ class ImagePolicies: public ConnectionTracker mTable.AddChild( dualImageViewTable, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) ); - ImageView imageView01 = CreateImageView( true, DevelImageVisual::LoadPolicy::ATTACHED, DevelImageVisual::ReleasePolicy::DESTROYED, false, 3 ); + ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 ); imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal ); dualImageViewTable.AddChild( imageView01, TableView::CellPosition( 0, 0 ) ); @@ -299,7 +303,7 @@ class ImagePolicies: public ConnectionTracker ImageView imageViewDetached = ImageView::DownCast( dualImageViewTable.GetChildAt( TableView::CellPosition( 0, 0 ) ) ); dualImageViewTable.RemoveChildAt( TableView::CellPosition( 0, 0 ) ); - ImageView imageView01 = CreateImageView( true, DevelImageVisual::LoadPolicy::ATTACHED, DevelImageVisual::ReleasePolicy::DESTROYED, false, 3 ); + ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 ); imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal ); dualImageViewTable.AddChild( imageView01, TableView::CellPosition( 0, 1 ) ); @@ -322,7 +326,7 @@ class ImagePolicies: public ConnectionTracker mTable.AddChild( dualImageViewTable, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) ); - ImageView imageView01 = CreateImageView( true, DevelImageVisual::LoadPolicy::ATTACHED, DevelImageVisual::ReleasePolicy::DETACHED, false, 3 ); + ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DETACHED, false, 3 ); imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal ); dualImageViewTable.AddChild( imageView01, TableView::CellPosition( 0, 0 ) ); @@ -340,7 +344,7 @@ class ImagePolicies: public ConnectionTracker ImageView imageViewDetached = ImageView::DownCast( dualImageViewTable.GetChildAt( TableView::CellPosition( 0, 0 ) ) ); dualImageViewTable.RemoveChildAt( TableView::CellPosition( 0, 0 ) ); - ImageView imageView01 = CreateImageView( true, DevelImageVisual::LoadPolicy::ATTACHED, DevelImageVisual::ReleasePolicy::DESTROYED, false, 3 ); + ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 ); imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal ); dualImageViewTable.AddChild( imageView01, TableView::CellPosition( 0, 1 ) ); diff --git a/examples/image-view-alpha-blending/image-view-alpha-blending-example.cpp b/examples/image-view-alpha-blending/image-view-alpha-blending-example.cpp index 011e7c6c..bf6067c2 100644 --- a/examples/image-view-alpha-blending/image-view-alpha-blending-example.cpp +++ b/examples/image-view-alpha-blending/image-view-alpha-blending-example.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * 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. @@ -16,6 +16,8 @@ */ #include <dali-toolkit/dali-toolkit.h> +#include <dali-toolkit/devel-api/image-loader/texture-manager.h> +#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h> using namespace Dali; @@ -48,28 +50,28 @@ private: Stage stage = Stage::GetCurrent(); stage.KeyEventSignal().Connect(this, &ImageViewAlphaBlendApp::OnKeyEvent); - Vector4 green0 = Vector4( 0.f, 1.f, 0.f, 0.25f ); - Vector4 green1 = Vector4( 0.f, 0.25f, 0.f, 0.25f ); - BufferImage redGreen0 = CreateBufferImage( Color::RED, green0 ); - BufferImage redGreen1 = CreateBufferImage( Color::RED, green1 ); + auto green0 = Vector4( 0.f, 1.f, 0.f, 0.25f ); + auto green1 = Vector4( 0.f, 0.25f, 0.f, 0.25f ); + auto redGreen0 = CreateTexture( Color::RED, green0 ); + auto redGreen1 = CreateTexture( Color::RED, green1 ); float imageSize = 512.f; - Toolkit::ImageView imageView0 = Toolkit::ImageView::New( IMAGE_PATH ); + Toolkit::ImageView imageView0 = CreateImageView( IMAGE_PATH ); imageView0.SetSize(imageSize, imageSize); imageView0.SetParentOrigin( ParentOrigin::CENTER ); imageView0.SetY( -imageSize*0.5f ); stage.Add(imageView0); - Toolkit::ImageView imageView1 = Toolkit::ImageView::New( redGreen0 ); + Toolkit::ImageView imageView1 = CreateImageView( redGreen0 ); imageView1.SetParentOrigin( ParentOrigin::CENTER ); imageView1.SetSize(imageSize, imageSize); imageView0.Add(imageView1); - Toolkit::ImageView imageView2 = Toolkit::ImageView::New( IMAGE_PATH ); + Toolkit::ImageView imageView2 = CreateImageView( IMAGE_PATH ); imageView2.SetSize(imageSize, imageSize); imageView2.SetParentOrigin( ParentOrigin::CENTER ); imageView2.SetY( imageSize*0.5f ); stage.Add(imageView2); - Toolkit::ImageView imageView3 = Toolkit::ImageView::New( redGreen1); + Toolkit::ImageView imageView3 = CreateImageView( redGreen1); imageView3.SetParentOrigin( ParentOrigin::CENTER ); imageView3.SetSize(imageSize, imageSize); imageView2.Add(imageView3); @@ -95,22 +97,41 @@ private: } } - BufferImage CreateBufferImage( const Vector4& color1, const Vector4& color2 ) + std::string CreateTexture( const Vector4& color1, const Vector4& color2 ) { - BufferImage image = BufferImage::New( 2, 1, Pixel::RGBA8888 ); - PixelBuffer* pixelBuffer = image.GetBuffer(); - pixelBuffer[0]=0xFF * color1.x; - pixelBuffer[1]=0xFF * color1.y; - pixelBuffer[2]=0xFF * color1.z; - pixelBuffer[3]=0xFF * color1.w; - pixelBuffer[4]=0xFF * color2.x; - pixelBuffer[5]=0xFF * color2.y; - pixelBuffer[6]=0xFF * color2.z; - pixelBuffer[7]=0xFF * color2.w; - image.Update(); - return image; + const auto width = 2u; + const auto height = 1u; + auto size = width * height * 4; + auto pixelBuffer = new unsigned char[size]; + pixelBuffer[0] = 0xFF * color1.x; + pixelBuffer[1] = 0xFF * color1.y; + pixelBuffer[2] = 0xFF * color1.z; + pixelBuffer[3] = 0xFF * color1.w; + pixelBuffer[4] = 0xFF * color2.x; + pixelBuffer[5] = 0xFF * color2.y; + pixelBuffer[6] = 0xFF * color2.z; + pixelBuffer[7] = 0xFF * color2.w; + + auto pixelData = PixelData::New(pixelBuffer, size, width, height, Pixel::RGBA8888, PixelData::ReleaseFunction::DELETE_ARRAY); + auto texture = Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height ); + texture.Upload(pixelData); + + return Toolkit::TextureManager::AddTexture(texture); } + template<typename TextT> + Toolkit::ImageView CreateImageView(TextT&& filename) + { + auto imageView = Toolkit::ImageView::New(); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::ImageVisual::Property::URL, std::forward<TextT>(filename)); + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE); + propertyMap.Insert(Toolkit::DevelVisual::Property::VISUAL_FITTING_MODE, Toolkit::DevelVisual::FILL); + imageView.SetProperty(Toolkit::ImageView::Property::IMAGE, propertyMap ); + + return imageView; + } private: Application& mApplication; diff --git a/examples/image-view-url/image-view-url-example.cpp b/examples/image-view-url/image-view-url-example.cpp index ce98781c..59ebda9a 100644 --- a/examples/image-view-url/image-view-url-example.cpp +++ b/examples/image-view-url/image-view-url-example.cpp @@ -58,7 +58,8 @@ class ImageViewUrlApp : public ConnectionTracker { public: ImageViewUrlApp( Application& application ) - : mApplication( application ) + : mApplication( application ), + mDeltaPropertyIndex( Property::INVALID_INDEX ) { // Connect to the Application's Init signal mApplication.InitSignal().Connect( this, &ImageViewUrlApp::Create ); diff --git a/examples/item-view/item-view-example.cpp b/examples/item-view/item-view-example.cpp index d7e7b9be..6172a73e 100644 --- a/examples/item-view/item-view-example.cpp +++ b/examples/item-view/item-view-example.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * 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. @@ -21,6 +21,7 @@ #include <dali/dali.h> #include <dali-toolkit/dali-toolkit.h> #include <dali-toolkit/devel-api/controls/buttons/button-devel.h> +#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h> using namespace Dali; using namespace Dali::Toolkit; @@ -866,7 +867,12 @@ public: // From ItemFactory virtual Actor NewItem(unsigned int itemId) { // Create an image view for this item - ImageView actor = ImageView::New( IMAGE_PATHS[ itemId % NUM_IMAGES ] ); + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, IMAGE_PATHS[ itemId % NUM_IMAGES ] ); + propertyMap.Insert(DevelVisual::Property::VISUAL_FITTING_MODE, DevelVisual::FILL); + ImageView actor = ImageView::New(); + actor.SetProperty( Toolkit::ImageView::Property::IMAGE, propertyMap ); actor.SetZ( 0.0f ); actor.SetPosition( INITIAL_OFFSCREEN_POSITION ); diff --git a/examples/perf-scroll/perf-scroll.cpp b/examples/perf-scroll/perf-scroll.cpp index 6740eee0..beedecfb 100644 --- a/examples/perf-scroll/perf-scroll.cpp +++ b/examples/perf-scroll/perf-scroll.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * 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. @@ -16,7 +16,7 @@ */ #include <dali-toolkit/dali-toolkit.h> - +#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h> #include "shared/utility.h" using namespace Dali; @@ -278,7 +278,13 @@ public: for( size_t i(0); i<actorCount; ++i ) { - mImageView[i] = ImageView::New( ImagePath(i) ); + mImageView[i] = ImageView::New(); + Property::Map propertyMap; + propertyMap.Insert(Toolkit::ImageVisual::Property::URL, ImagePath(i)); + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE); + propertyMap.Insert(Toolkit::DevelVisual::Property::VISUAL_FITTING_MODE, Toolkit::DevelVisual::FILL); + mImageView[i].SetProperty(Toolkit::ImageView::Property::IMAGE, propertyMap); + mImageView[i].SetSize( Vector3(0.0f,0.0f,0.0f) ); mImageView[i].SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS ); mParent.Add( mImageView[i] ); diff --git a/examples/ray-marching/ray-marching-example.cpp b/examples/ray-marching/ray-marching-example.cpp index 6bf0c202..d6382173 100644 --- a/examples/ray-marching/ray-marching-example.cpp +++ b/examples/ray-marching/ray-marching-example.cpp @@ -41,20 +41,30 @@ bool LoadShaderCode( const char* path, const char* filename, std::vector<char>& { std::string fullpath( path ); fullpath += filename; - FILE* f = fopen( fullpath.c_str(), "rb" ); - if( !f ) + FILE* file = fopen( fullpath.c_str(), "rb" ); + if( ! file ) { return false; } - fseek( f, 0, SEEK_END ); - size_t size = ftell( f ); - fseek( f, 0, SEEK_SET ); - output.resize( size + 1 ); - std::fill( output.begin(), output.end(), 0 ); - ssize_t result = fread( output.data(), size, 1, f ); - fclose( f ); - - return ( result >= 0 ); + + bool retValue = false; + if( ! fseek( file, 0, SEEK_END ) ) + { + long int size = ftell( file ); + + if( ( size != -1L ) && + ( ! fseek( file, 0, SEEK_SET ) ) ) + { + output.resize( size + 1 ); + std::fill( output.begin(), output.end(), 0 ); + ssize_t result = fread( output.data(), size, 1, file ); + + retValue = ( result >= 0 ); + } + } + + fclose( file ); + return retValue; } /** @@ -69,9 +79,13 @@ Shader LoadShaders( const std::string& shaderName ) std::string shaderFSH( shaderName ); shaderVSH += ".vsh"; shaderFSH += ".fsh"; - LoadShaderCode( DEMO_SHADER_DIR, shaderVSH.c_str(), bufV ); - LoadShaderCode( DEMO_SHADER_DIR, shaderFSH.c_str(), bufF ); - Shader shader = Shader::New( bufV.data(), bufF.data() ); + + Shader shader; + if( LoadShaderCode( DEMO_SHADER_DIR, shaderVSH.c_str(), bufV ) && + LoadShaderCode( DEMO_SHADER_DIR, shaderFSH.c_str(), bufF ) ) + { + shader = Shader::New( bufV.data(), bufF.data() ); + } return shader; } diff --git a/examples/rendering-basic-pbr/ktx-loader.cpp b/examples/rendering-basic-pbr/ktx-loader.cpp index b54704c9..175d6c3a 100644 --- a/examples/rendering-basic-pbr/ktx-loader.cpp +++ b/examples/rendering-basic-pbr/ktx-loader.cpp @@ -104,6 +104,7 @@ bool LoadCubeMapFromKtxFile( const std::string& path, CubeData& cubedata ) int result = fread(&header,1,sizeof(KtxFileHeader),fp); if( 0 == result ) { + fclose( fp ); return false; } @@ -112,14 +113,27 @@ bool LoadCubeMapFromKtxFile( const std::string& path, CubeData& cubedata ) // Skip the key-values: const long int imageSizeOffset = sizeof(KtxFileHeader) + header.bytesOfKeyValueData; - fseek(fp, imageSizeOffset, SEEK_END); + if( fseek(fp, imageSizeOffset, SEEK_END) ) + { + fclose( fp ); + return false; + } + lSize = ftell(fp); + if( lSize == -1L ) + { + fclose( fp ); + return false; + } + rewind(fp); - if(fseek(fp, imageSizeOffset, SEEK_SET)) + if( fseek(fp, imageSizeOffset, SEEK_SET) ) { + fclose( fp ); return false; } + cubedata.img.resize(header.numberOfFaces); for(unsigned int face=0; face < header.numberOfFaces; ++face) //array_element must be 0 or 1 @@ -133,13 +147,15 @@ bool LoadCubeMapFromKtxFile( const std::string& path, CubeData& cubedata ) unsigned int imgSize[6]; unsigned char* imgPointer = buffer; result = fread(buffer,1,lSize,fp); + + fclose(fp); + if( 0 == result ) { + free( buffer ); return false; } - fclose(fp); - if( 0 == header.numberOfMipmapLevels ) { header.numberOfMipmapLevels = 1u; diff --git a/examples/rendering-basic-pbr/rendering-basic-pbr-example.cpp b/examples/rendering-basic-pbr/rendering-basic-pbr-example.cpp index 920a7b8a..931f5fbd 100644 --- a/examples/rendering-basic-pbr/rendering-basic-pbr-example.cpp +++ b/examples/rendering-basic-pbr/rendering-basic-pbr-example.cpp @@ -390,21 +390,29 @@ public: */ bool LoadShaderCode( const std::string& fullpath, std::vector<char>& output ) { - FILE* f = fopen( fullpath.c_str(), "rb" ); - - if( NULL == f ) + FILE* file = fopen( fullpath.c_str(), "rb" ); + if( NULL == file ) { return false; } - fseek( f, 0, SEEK_END ); - size_t size = ftell( f ); - fseek( f, 0, SEEK_SET ); - output.resize( size + 1 ); - std::fill( output.begin(), output.end(), 0 ); - ssize_t result = fread( output.data(), size, 1, f ); - fclose( f ); - return ( result >= 0 ); + bool retValue = false; + if( ! fseek( file, 0, SEEK_END ) ) + { + long int size = ftell( file ); + + if( ( size != -1L ) && + ( ! fseek( file, 0, SEEK_SET ) ) ) + { + output.resize( size + 1 ); + std::fill( output.begin(), output.end(), 0 ); + ssize_t result = fread( output.data(), size, 1, file ); + + retValue = ( result >= 0 ); + } + } + fclose( file ); + return retValue; } /** diff --git a/examples/text-label/expanding-buttons-impl.cpp b/examples/text-label/expanding-buttons-impl.cpp new file mode 100644 index 00000000..8c259d6b --- /dev/null +++ b/examples/text-label/expanding-buttons-impl.cpp @@ -0,0 +1,178 @@ +/* + * 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. + */ + +#include <dali-toolkit/dali-toolkit.h> +#include <dali-toolkit/devel-api/controls/control-devel.h> +#include <dali-toolkit/devel-api/controls/buttons/button-devel.h> +#include <dali/public-api/animation/animation.h> + +#include "expanding-buttons-impl.h" + +using namespace Dali; +using namespace Dali::Toolkit; + +namespace Demo +{ +namespace Internal +{ + +namespace +{ + +const unsigned int GAP_BETWEEN_BUTTONS = 3; + +const char* const STYLES_IMAGE = DEMO_IMAGE_DIR "FontStyleButton_Main.png"; +const char* const TICK_IMAGE_IMAGE = DEMO_IMAGE_DIR "FontStyleButton_OK_02.png"; + +/** + * Unparent the given number of registered controls from the supplied Vector of controls. + */ +void ResetControls( std::vector< WeakHandle< Control > > controls, unsigned int numberOfButtons ) +{ + for( unsigned int index = 0; index < numberOfButtons; index++) + { + Dali::Toolkit::Control control = controls[index].GetHandle(); + UnparentAndReset( control ); + } +} + +} // anonymous namespace + + +Internal::ExpandingButtons::ExpandingButtons() +: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ), + mStyleButtonsHidden( false ) +{ +} + +Internal::ExpandingButtons::~ExpandingButtons() +{ +} + +Demo::ExpandingButtons Internal::ExpandingButtons::New() +{ + IntrusivePtr<Internal::ExpandingButtons> impl = new Internal::ExpandingButtons(); + Demo::ExpandingButtons handle = Demo::ExpandingButtons( *impl ); + impl->Initialize(); + return handle; +} + +void ExpandingButtons::OnInitialize() +{ + mExpandButton = PushButton::New(); + + mExpandButton.ClickedSignal().Connect( this, &ExpandingButtons::OnExpandButtonClicked ); + mExpandButton.SetProperty( Button::Property::TOGGLABLE, true ); + mExpandButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, STYLES_IMAGE ); // Default for Styles + mExpandButton.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, TICK_IMAGE_IMAGE ); + mExpandButton.SetProperty( Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT ); + Self().Add( mExpandButton ); +} + +void ExpandingButtons::OnRelayout( const Dali::Vector2& targetSize, Dali::RelayoutContainer& container ) +{ + mButtonSize = targetSize; + mExpandButton.SetSize( targetSize ); +} + +void ExpandingButtons::RegisterButton( Dali::Toolkit::Control& control ) +{ + mExpandingControls.push_back( control ); +} + +void ExpandingButtons::Expand() +{ + if ( !mExpandCollapseAnimation ) + { + mExpandCollapseAnimation = Animation::New( 0.2f ); + mExpandCollapseAnimation.FinishedSignal().Connect( this, &ExpandingButtons::OnExpandAnimationFinished ); + } + + unsigned int numberOfControls = mExpandingControls.size(); + + for( unsigned int index = 0; index < numberOfControls; index++ ) + { + Dali::Toolkit::Control control = mExpandingControls[index].GetHandle(); + if ( control ) + { + Self().Add( control ); + AlphaFunction focusedAlphaFunction = AlphaFunction( Vector2 ( 0.32f, 0.08f ), Vector2( 0.38f, 1.72f ) ); + mExpandCollapseAnimation.AnimateTo( Property( control, Actor::Property::POSITION_X ), mButtonSize.width + ( mButtonSize.width + GAP_BETWEEN_BUTTONS ) * (index) , focusedAlphaFunction ); + } + } + Self().RaiseToTop(); + mStyleButtonsHidden = false; + mExpandCollapseAnimation.Play(); +} + +void ExpandingButtons::OnExpandAnimationFinished( Animation& animation ) +{ + if ( mStyleButtonsHidden ) + { + unsigned int numberOfControls = mExpandingControls.size(); + ResetControls( mExpandingControls, numberOfControls ); + animation.Clear(); + animation.Reset(); + } +} + +void ExpandingButtons::Collapse() +{ + Demo::ExpandingButtons handle( GetOwner() ); + mCollapsedSignal.Emit( handle ); + + mStyleButtonsHidden = true; + mExpandButton.SetProperty(Button::Property::SELECTED, false ); + + if ( mExpandCollapseAnimation ) + { + unsigned int numberOfControls = mExpandingControls.size(); + + for ( unsigned int index = 0; index < numberOfControls; index++ ) + { + Dali::Toolkit::Control control = mExpandingControls[index].GetHandle(); + if ( control ) + { + mExpandCollapseAnimation.AnimateTo( Property( control, Actor::Property::POSITION_X ), 0.0f ); + } + } + mExpandCollapseAnimation.Play(); + } +} + +// Hide or show (expand) buttons if expand button pressed +bool ExpandingButtons::OnExpandButtonClicked( Toolkit::Button button ) +{ + if ( button.GetProperty( Toolkit::Button::Property::SELECTED ).Get<bool>() ) + { + Expand(); + } + else + { + Collapse(); + } + + return true; +} + + +Demo::ExpandingButtons::ExpandingButtonsSignalType& ExpandingButtons::CollapsingSignal() +{ + return mCollapsedSignal; +} + +} // Internal +} // Demo diff --git a/examples/text-label/expanding-buttons-impl.h b/examples/text-label/expanding-buttons-impl.h new file mode 100644 index 00000000..a432914e --- /dev/null +++ b/examples/text-label/expanding-buttons-impl.h @@ -0,0 +1,124 @@ +#ifndef DALI_DEMO_INTERNAL_EXPANDING_BUTTONS_IMPL_H +#define DALI_DEMO_INTERNAL_EXPANDING_BUTTONS_IMPL_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. + */ + +#include "expanding-buttons.h" +#include <dali-toolkit/public-api/controls/control-impl.h> +#include <dali/public-api/object/weak-handle.h> + +namespace Demo +{ + +namespace Internal // To use TypeRegistry, handle and body classes need the same name +{ + +class ExpandingButtons : public Dali::Toolkit::Internal::Control +{ +public: + + /** + * Instantiate a new ExpandingButtons object + */ + static Demo::ExpandingButtons New(); + + /** + * Constructor + */ + ExpandingButtons(); + + /** + * Destructor + */ + ~ExpandingButtons(); + +public: // API + + void RegisterButton( Dali::Toolkit::Control& control ); + + void Expand(); + + void Collapse(); + +public: // Signals + + Demo::ExpandingButtons::ExpandingButtonsSignalType& CollapsingSignal(); + +private: // From Control + + /** + * @copydoc Toolkit::Control::OnInitialize() + */ + virtual void OnInitialize() override; + + /** + * @copydoc Toolkit::Control::OnRelayout() + */ + virtual void OnRelayout( const Dali::Vector2& targetSize, Dali::RelayoutContainer& container ) override; + +private: + + /** + * Callback when expand or collapse animation ends. + */ + void OnExpandAnimationFinished( Dali::Animation& animation ); + + /** + * Called when the main button clicked. + */ + bool OnExpandButtonClicked( Dali::Toolkit::Button button ); + + +private: + //undefined + ExpandingButtons( const ExpandingButtons& ); + ExpandingButtons& operator=( const ExpandingButtons& ); + +private: + + std::vector< Dali::WeakHandle< Dali::Toolkit::Control> > mExpandingControls; + + Dali::Animation mExpandCollapseAnimation; + + bool mStyleButtonsHidden; + + Dali::Size mButtonSize; // Size of the buttons, used in animation calculations. + + Dali::Toolkit::PushButton mExpandButton; // Main button that is clicked to expand/collapse. + + Demo::ExpandingButtons::ExpandingButtonsSignalType mCollapsedSignal; +}; + +} // Internal + +inline Internal::ExpandingButtons& GetImpl( Demo::ExpandingButtons& handle ) +{ + DALI_ASSERT_ALWAYS( handle ); + Dali::RefObject& object = handle.GetImplementation(); + return static_cast<Internal::ExpandingButtons&>(object); +} + +inline const Internal::ExpandingButtons& GetImpl( const Demo::ExpandingButtons& handle ) +{ + DALI_ASSERT_ALWAYS( handle ); + const Dali::RefObject& object = handle.GetImplementation(); + return static_cast<const Internal::ExpandingButtons&>(object); +} + +} // Demo + +#endif // DALI_DEMO_INTERNAL_EXPANDING_BUTTONS_IMPL_H diff --git a/examples/text-label/expanding-buttons.cpp b/examples/text-label/expanding-buttons.cpp new file mode 100644 index 00000000..d7331822 --- /dev/null +++ b/examples/text-label/expanding-buttons.cpp @@ -0,0 +1,87 @@ +/* + * 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. + */ + +#include "expanding-buttons-impl.h" +#include "expanding-buttons.h" + +namespace Demo +{ + +ExpandingButtons::ExpandingButtons() +{ +} + +ExpandingButtons::ExpandingButtons( const ExpandingButtons& expandingButtons ) +: Control( expandingButtons ) +{ +} + +ExpandingButtons& ExpandingButtons::operator= ( const ExpandingButtons& rhs ) +{ + if( &rhs != this ) + { + Control::operator=( rhs ); + } + return *this; +} + +ExpandingButtons::~ExpandingButtons() +{ +} + +ExpandingButtons ExpandingButtons::New() +{ + ExpandingButtons expandingButtons = Internal::ExpandingButtons::New(); + return expandingButtons; +} + +ExpandingButtons ExpandingButtons::DownCast( BaseHandle handle ) +{ + return Control::DownCast< ExpandingButtons, Internal::ExpandingButtons > ( handle ); +} + +void ExpandingButtons::RegisterButton( Control& control ) +{ + GetImpl(*this).RegisterButton( control ); +} + +void ExpandingButtons::Expand() +{ + GetImpl(*this).Expand(); +} +void ExpandingButtons::Collapse() +{ + GetImpl(*this).Collapse(); +} + +Demo::ExpandingButtons::ExpandingButtonsSignalType& ExpandingButtons::CollapsingSignal() +{ + return GetImpl(*this).CollapsingSignal(); +} + +ExpandingButtons::ExpandingButtons( Internal::ExpandingButtons& implementation ) +: Control( implementation ) +{ +} + +ExpandingButtons::ExpandingButtons( Dali::Internal::CustomActor* internal ) +: Control( internal ) +{ + VerifyCustomActorPointer< Internal::ExpandingButtons >( internal ) ; +} + + +} //namespace Demo diff --git a/examples/text-label/expanding-buttons.h b/examples/text-label/expanding-buttons.h new file mode 100644 index 00000000..1ccede88 --- /dev/null +++ b/examples/text-label/expanding-buttons.h @@ -0,0 +1,114 @@ +#ifndef DALI_DEMO_EXPANDING_BUTTONS_CONTROL_H +#define DALI_DEMO_EXPANDING_BUTTONS_CONTROL_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. + */ + +#include <dali-toolkit/dali-toolkit.h> + +namespace Demo +{ + +namespace Internal +{ +class ExpandingButtons; +} + +/** + * Control which toggles between showing and hiding a set of buttons. + */ +class ExpandingButtons : public Dali::Toolkit::Control +{ + + +public: // Construction / destruction + + /** + * Create an uninitialized handle + */ + ExpandingButtons(); + + /** + * Create an ExpandingButton control with the default pressed and released visual. + */ + static ExpandingButtons New(); + + /** + * Destructor. This is non-virtual since derived Handle types must not + * contain data or virtual methods + */ + ~ExpandingButtons(); + + /** + * Copy Constructor + */ + ExpandingButtons( const ExpandingButtons& expandingButtons ); + + /** + * Assignment Operator + */ + ExpandingButtons& operator=( const ExpandingButtons& expandingButtons ); + + /** + * Downcast + */ + static ExpandingButtons DownCast( BaseHandle handle ); + +public: // API + + /** + * Add a control (button) to the Expanding button bar. Will be displayed in order of addition. + */ + void RegisterButton( Control& control ); + + /** + * Expand the registered buttons out from the main button. + */ + void Expand(); + + /** + * Collapse the expanded buttons back behind the main button. + */ + void Collapse(); + +public: // Signals + + /** + * ExpandingButtons signal type + */ + typedef Dali::Signal< bool ( ExpandingButtons ) > ExpandingButtonsSignalType; + + /** + * This signal is emitted when the button is going to collapse. + */ + ExpandingButtonsSignalType& CollapsingSignal(); + +public: // Not for public use + + /** + * Create a handle from an implementation + */ + ExpandingButtons( Internal::ExpandingButtons& implementation ); + + /** + * Allow the creation of an ExpandingButtons handle from an internal CustomActor pointer + */ + ExpandingButtons( Dali::Internal::CustomActor* internal ); +}; + +} // namespace Demo + +#endif // DALI_DEMO_EXPANDING_BUTTONS_CONTROL_H diff --git a/examples/text-label/text-label-example.cpp b/examples/text-label/text-label-example.cpp index ef80cedb..893698bf 100644 --- a/examples/text-label/text-label-example.cpp +++ b/examples/text-label/text-label-example.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * 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. @@ -17,7 +17,7 @@ /** * @file text-label-example.cpp - * @brief Basic usage of TextLabel control + * @brief Usage of TextLabel control with style application. */ // EXTERNAL INCLUDES @@ -30,6 +30,7 @@ // INTERNAL INCLUDES #include "shared/multi-language-strings.h" #include "shared/view.h" +#include "expanding-buttons.h" using namespace Dali; using namespace Dali::Toolkit; @@ -38,8 +39,6 @@ using namespace MultiLanguageStrings; namespace { const char* const BACKGROUND_IMAGE = DEMO_IMAGE_DIR "grab-handle.png"; -const char* const STYLES_IMAGE = DEMO_IMAGE_DIR "FontStyleButton_Main.png"; -const char* const TICK_IMAGE_IMAGE = DEMO_IMAGE_DIR "FontStyleButton_OK_02.png"; const char* const STYLE_SELECTED_IMAGE = DEMO_IMAGE_DIR "FontStyleButton_OK_03.png"; const char* BUTTON_IMAGES[] = @@ -93,7 +92,8 @@ const Vector4 AVAILABLE_COLORS[] = Color::GREEN, Color::BLUE, Color::RED, - Color::CYAN + Color::CYAN, + Color::WHITE // Used as clear }; const unsigned int NUMBER_OF_COLORS = sizeof( AVAILABLE_COLORS ) / sizeof( AVAILABLE_COLORS[0u] ); @@ -133,6 +133,7 @@ const float STYLE_BUTTON_POSTION_RELATIVE_TO_STAGE = 0.9f; const float BUTTON_SIZE_RATIO_TO_STAGE = 0.1f; const float OUTLINE_WIDTH = 2.0f; const Vector2 SHADOW_OFFSET = Vector2( 2.0f, 2.0f ); +const int GAP_BETWEEN_BUTTONS = 3; } // anonymous namespace @@ -147,9 +148,8 @@ public: TextLabelExample( Application& application ) : mApplication( application ), mLabel(), - mShadowActive( false ), - mOutlineActive( false ), mSelectedColor(AVAILABLE_COLORS[0]), + mStyleActivatedForColor( NUMBER_OF_STYLES ), mContainer(), mGrabCorner(), mBorder(), @@ -158,11 +158,19 @@ public: mLanguageId( 0u ), mAlignment( 0u ), mHueAngleIndex( Property::INVALID_INDEX ), - mOverrideMixColorIndex( Property::INVALID_INDEX ) - + mOverrideMixColorIndex( Property::INVALID_INDEX ), + mColorButtonsHidden( true ), + mCollapseColorsAndStyles( false ) { // Connect to the Application's Init signal mApplication.InitSignal().Connect( this, &TextLabelExample::Create ); + + // Set Style flags to inactive + for ( unsigned int i = OUTLINE; i < NUMBER_OF_STYLES; i++ ) + { + mStyleActiveState[ i ] = false; + mCurrentStyleColor[i] = AVAILABLE_COLORS[ NUMBER_OF_COLORS - 1 ]; + } } ~TextLabelExample() @@ -170,6 +178,23 @@ public: // Nothing to do here. } + // Clicking the expanding button shows the registered style buttons. + void SetUpExpandingStyleButtons( Vector2 position ) + { + mExpandingButtons = Demo::ExpandingButtons::New(); + mExpandingButtons.SetPosition( mButtonSize.width, mStageSize.height * STYLE_BUTTON_POSTION_RELATIVE_TO_STAGE ); + mExpandingButtons.CollapsingSignal().Connect( this, &TextLabelExample::OnExpandingButtonCollapsing ); + mExpandingButtons.SetSize( mButtonSize ); + // Creates the buttons to be expanded + CreateStyleButtons(); + + // Register the created buttons with the ExpandingButtons. + for ( unsigned int index = 0; index < NUMBER_OF_STYLES; index++ ) + { + mExpandingButtons.RegisterButton( mStyleButtons[index] ); + } + } + /** * One-time setup in response to Application InitSignal. */ @@ -179,15 +204,13 @@ public: stage.KeyEventSignal().Connect(this, &TextLabelExample::OnKeyEvent); mStageSize = stage.GetSize(); - - mButtonSize = Size( mStageSize.height * 0.1, mStageSize.height * 0.1 ); // Button size 1/10 of stage height + mButtonSize = Size( mStageSize.height * 0.12, mStageSize.height * 0.12 ); // Button size 1/12 of stage height mContainer = Control::New(); mContainer.SetName( "Container" ); mContainer.SetParentOrigin( ParentOrigin::CENTER ); mLayoutSize = Vector2(mStageSize.width*0.6f, mStageSize.width*0.6f); mContainer.SetSize( mLayoutSize ); - mContainer.SetDrawMode( DrawMode::OVERLAY_2D ); stage.Add( mContainer ); // Resize the center layout when the corner is grabbed @@ -212,16 +235,10 @@ public: mLabel.SetBackgroundColor( Color::WHITE ); mContainer.Add( mLabel ); - // Create style activate button - mStyleMenuButton = PushButton::New(); - mStyleMenuButton.SetPosition( mButtonSize.width, mStageSize.height * STYLE_BUTTON_POSTION_RELATIVE_TO_STAGE ); - mStyleMenuButton.SetSize( mButtonSize ); - mStyleMenuButton.SetProperty( Button::Property::TOGGLABLE, true ); - mStyleMenuButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, STYLES_IMAGE ); - mStyleMenuButton.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, TICK_IMAGE_IMAGE ); - - mStyleMenuButton.ClickedSignal().Connect( this, &TextLabelExample::OnStyleButtonClicked ); - stage.Add( mStyleMenuButton ); + // Clicking ExpandingButton shows the Registered Style buttons, clicking again hides them. + Vector2 expandingButtonPosition( mButtonSize.width, mStageSize.height * STYLE_BUTTON_POSTION_RELATIVE_TO_STAGE ); + SetUpExpandingStyleButtons( expandingButtonPosition ); + stage.Add( mExpandingButtons ); // Add a border for the container so you can see the container is being resized while grabbing the handle. mBorder = Control::New(); @@ -232,11 +249,10 @@ public: Dali::Property::Map border; border.Insert( Toolkit::Visual::Property::TYPE, Visual::BORDER ); border.Insert( BorderVisual::Property::COLOR, Color::WHITE ); - border.Insert( BorderVisual::Property::SIZE, 2.f ); + border.Insert( BorderVisual::Property::SIZE, 3.f ); mBorder.SetProperty( Control::Property::BACKGROUND, border ); mContainer.Add( mBorder ); mBorder.SetVisible(false); - mGrabCorner.RaiseToTop(); mHueAngleIndex = mLabel.RegisterProperty( "hue", 0.0f ); @@ -253,147 +269,275 @@ public: anim.SetLooping(true); anim.Play(); - // Animate the text color 3 times from source color to Yellow - Animation animation = Animation::New( 2.f ); - animation.AnimateTo( Property( mLabel, TextLabel::Property::TEXT_COLOR ), Color::YELLOW, AlphaFunction::SIN ); - animation.SetLoopCount( 3 ); - animation.Play(); + mContainer.RaiseToTop(); + mGrabCorner.RaiseToTop(); Property::Value labelText = mLabel.GetProperty( TextLabel::Property::TEXT ); std::cout << "Displaying text: \"" << labelText.Get< std::string >() << "\"" << std::endl; } - // Depending on button pressed, apply the style to the text label - bool OnStyleSelected( Toolkit::Button button ) + // If the styling buttons should colapse (hide) then the color buttons should also hide. + bool OnExpandingButtonCollapsing( Demo::ExpandingButtons button ) { - if( button == mStyleButtons[ StyleType::TEXT_COLOR ] ) + mCollapseColorsAndStyles = true; + HideColorButtons(); + return true; + } + + // Get the style type from the given button + StyleType GetStyleTypeFromButton( Toolkit::Button button ) + { + StyleType style = StyleType::TEXT_COLOR; + + if( button == mStyleButtons[ StyleType::OUTLINE ] ) { - Animation animation = Animation::New( 2.f ); - animation.AnimateTo( Property( mLabel, TextLabel::Property::TEXT_COLOR ), mSelectedColor, AlphaFunction::LINEAR ); - animation.Play(); + style = StyleType::OUTLINE; } - else if( button == mStyleButtons[ StyleType::OUTLINE ] ) + else if( button == mStyleButtons[ StyleType::SHADOW ] ) { - Property::Map outlineMap; - float outlineWidth = OUTLINE_WIDTH; + style = StyleType::SHADOW; + } + return style; + } - if( mOutlineActive ) + // Style selected, show color buttons + bool OnStyleButtonClicked( Toolkit::Button button ) + { + StyleType selectedStyle = GetStyleTypeFromButton( button ); + if ( mStyleActivatedForColor == selectedStyle ) + { + HideColorButtons(); + } + else + { + ResetColorButtons( mColorButtons, NUMBER_OF_COLORS ); + ShowColorButtons( selectedStyle); + } + return true; + } + + // Set style to selected color + bool OnColorSelected( Toolkit::Button button ) + { + for( unsigned int index = 0; index < NUMBER_OF_COLORS; index++) + { + if ( mColorButtons[index] == button ) { - outlineWidth = ( mOutlineColor == mSelectedColor ) ? 0.0f : OUTLINE_WIDTH ; // toggles outline on/off + mSelectedColor = AVAILABLE_COLORS[ index ]; } - mOutlineActive = ( outlineWidth > 0.0f ) ? true : false; - - mOutlineColor = mSelectedColor; - outlineMap["color"] = mOutlineColor; - outlineMap["width"] = outlineWidth; - mLabel.SetProperty( TextLabel::Property::OUTLINE, outlineMap ); } - else if( button == mStyleButtons[ StyleType::SHADOW ] ) - { - Vector2 shadowOffset( SHADOW_OFFSET ); // Will be set to zeros if color already set - Property::Value value = mLabel.GetProperty( TextLabel::Property::SHADOW_COLOR ); - Vector4 currentShadowColor; - value.Get( currentShadowColor ); - if ( mShadowActive ) + switch ( mStyleActivatedForColor ) + { + case TEXT_COLOR : { - // toggle shadow off ( zero offset ) if color is already set - shadowOffset = ( currentShadowColor == mSelectedColor ) ? Vector2::ZERO : Vector2( SHADOW_OFFSET ); + Animation animation = Animation::New( 1.f ); + animation.AnimateTo( Property( mLabel, TextLabel::Property::TEXT_COLOR ), mSelectedColor, AlphaFunction::LINEAR ); + mCurrentStyleColor[ TEXT_COLOR ] = mSelectedColor; + animation.Play(); + break; } + case OUTLINE : + { + Property::Map outlineMap; + float outlineWidth = OUTLINE_WIDTH; - mShadowActive = ( shadowOffset == Vector2::ZERO ) ? false : true; + if( mStyleActiveState[ OUTLINE ] ) + { + outlineWidth = ( Color::WHITE == mSelectedColor ) ? 0.0f : OUTLINE_WIDTH ; // toggles outline on/off + } + mStyleActiveState[ OUTLINE ] = ( outlineWidth > 0.0f ) ? true : false; - Property::Map shadowMap; - shadowMap.Insert( "offset", shadowOffset ); - shadowMap.Insert( "color", mSelectedColor ); - shadowMap.Insert( "blurRadius", 2.0f ); - mLabel.SetProperty( TextLabel::Property::SHADOW, shadowMap ); + outlineMap["color"] = mSelectedColor; + outlineMap["width"] = outlineWidth; + mCurrentStyleColor[ OUTLINE ] = mSelectedColor; + mLabel.SetProperty( TextLabel::Property::OUTLINE, outlineMap ); + break; + } + case SHADOW : + { + Vector2 shadowOffset( SHADOW_OFFSET ); // Will be set to zeros if color already set + Property::Value value = mLabel.GetProperty( TextLabel::Property::SHADOW_COLOR ); + Vector4 currentShadowColor; + value.Get( currentShadowColor ); + + if ( mStyleActiveState[ SHADOW ] ) + { + // toggle shadow off ( zero offset ) if color is already set + shadowOffset = ( Color::WHITE == mSelectedColor ) ? Vector2::ZERO : Vector2( SHADOW_OFFSET ); + } + + mStyleActiveState[ SHADOW ] = ( shadowOffset == Vector2::ZERO ) ? false : true; + mCurrentStyleColor[ SHADOW ] = mSelectedColor; + + mLabel.SetProperty( TextLabel::Property::SHADOW_OFFSET, shadowOffset ); + mLabel.SetProperty( TextLabel::Property::SHADOW_COLOR, mSelectedColor ); + break; + } + default : + break; } + return true; } - bool OnColorSelected( Toolkit::Button button ) + // Set the inital color button that should be be selected. + // If the style already has a color set then that should be used + void SetInitialSelectedColorButton( StyleType styleButtonIndex ) { - for( unsigned int index = 0; index < NUMBER_OF_COLORS; index++) + Vector4 selectedColor = mCurrentStyleColor[ styleButtonIndex ]; + + for ( unsigned int i = 0; i < NUMBER_OF_COLORS; i++ ) { - if ( mColorButtons[index] == button ) + if ( AVAILABLE_COLORS[i] == selectedColor ) { - mSelectedColor = AVAILABLE_COLORS[ index ]; - return true; + if ( mColorButtons[i] ) + { + mColorButtons[ i ].SetProperty( Toolkit::DevelButton::Property::SELECTED, true ); + } + break; } } - return true; } - void ShowColorButtons() + // Create a bar of color buttons that the user can select. + void ShowColorButtons( StyleType styleButtonIndex ) { + mCollapseColorsAndStyles = false; // Request to show colors so reset flag + mStyleActivatedForColor = styleButtonIndex; + for( unsigned int index = 0; index < NUMBER_OF_COLORS; index++) { - mColorButtons[index] = RadioButton::New(); - mColorButtons[index].SetPosition( mButtonSize.width, mStageSize.height * STYLE_BUTTON_POSTION_RELATIVE_TO_STAGE - ( mButtonSize.width * (index+1) ) ); - mColorButtons[index].SetSize( mButtonSize ); - mColorButtons[index].ClickedSignal().Connect( this, &TextLabelExample::OnColorSelected ); - mColorButtons[index].SetProperty( Button::Property::TOGGLABLE, true ); - Property::Map propertyMap; - propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR); - propertyMap.Insert(ColorVisual::Property::MIX_COLOR, AVAILABLE_COLORS[ index ]); - mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, propertyMap ); - mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::UNSELECTED_VISUAL, propertyMap ); - - propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR); - propertyMap.Insert(ColorVisual::Property::MIX_COLOR, AVAILABLE_COLORS[ index ]); - mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, propertyMap ); - - mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::SELECTED_VISUAL, - Property::Map().Add( Toolkit::Visual::Property::TYPE, Visual::BORDER ) - .Add( BorderVisual::Property::COLOR, Color::WHITE ) - .Add( BorderVisual::Property::SIZE, 2.0f ) - .Add( BorderVisual::Property::ANTI_ALIASING, true ) ); - - Stage::GetCurrent().Add( mColorButtons[index] ); + if( !mColorButtonsAnimation ) + { + mColorButtonsAnimation = Animation::New( 0.15f ); + mColorButtonsAnimation.FinishedSignal().Connect( this, &TextLabelExample::OnColorButtonAnimationFinished ); + } + + // Create a color button + if ( ! mColorButtons[index] ) + { + mColorButtons[index] = RadioButton::New(); + mColorButtons[index].SetSize( mButtonSize ); + mColorButtons[index].ClickedSignal().Connect( this, &TextLabelExample::OnColorSelected ); + mColorButtons[index].SetProperty( Button::Property::TOGGLABLE, true ); + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR); + propertyMap.Insert(ColorVisual::Property::MIX_COLOR, AVAILABLE_COLORS[ index ]); + mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, propertyMap ); + mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::UNSELECTED_VISUAL, propertyMap ); + mColorButtons[index].SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER ); + mColorButtons[index].SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER ); + + + propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR); + propertyMap.Insert(ColorVisual::Property::MIX_COLOR, AVAILABLE_COLORS[ index ]); + mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, propertyMap ); + + mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::SELECTED_VISUAL, + Property::Map().Add( Visual::Property::TYPE, Visual::BORDER ) + .Add( BorderVisual::Property::COLOR, Color::WHITE ) + .Add( BorderVisual::Property::SIZE, 4.0f ) + .Add( BorderVisual::Property::ANTI_ALIASING, true ) ); + + // Use a white button with 50% transparency as a clear color button + if ( Color::WHITE == AVAILABLE_COLORS[ index ] && styleButtonIndex != StyleType::TEXT_COLOR ) + { + mColorButtons[index].SetOpacity(0.5f); + + mColorButtons[index].SetProperty( Toolkit::Button::Property::LABEL, + Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT ) + .Add( Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT, HorizontalAlignment::CENTER ) + .Add( Toolkit::TextVisual::Property::TEXT, "off") ); + + } + } + + SetInitialSelectedColorButton( mStyleActivatedForColor ); + + mColorButtons[index].Unparent(); + + mStyleButtons[styleButtonIndex].Add( mColorButtons[index] ); + mColorButtons[index].Lower(); + + // Position button using nice animation + mColorButtons[index].SetY( -GAP_BETWEEN_BUTTONS ); + float desiredPosition = -( mButtonSize.height + GAP_BETWEEN_BUTTONS ) * (index); + AlphaFunction focusedAlphaFunction = AlphaFunction( Vector2 ( 0.32f, 0.08f ), Vector2( 0.38f, 1.72f ) ); + mColorButtonsAnimation.AnimateBy( Property( mColorButtons[index], Actor::Property::POSITION_Y ), desiredPosition, focusedAlphaFunction ); } - } + mColorButtonsHidden = false; + mColorButtonsAnimation.Play(); + } - void HideColorButtons() + // Remove the color buttons when not being shown. + void ResetColorButtons( Button buttons[], unsigned int numberOfButtons ) { - for( unsigned int index = 0; index < NUMBER_OF_COLORS; index++) + for( unsigned int index = 0; index < numberOfButtons; index++) { - UnparentAndReset( mColorButtons[index] ); + UnparentAndReset( buttons[index] ); } } - void HideStyleButtons() + void OnColorButtonAnimationFinished( Animation& animation ) { - for( unsigned int index = 0; index < NUMBER_OF_STYLES; index++) + animation.Clear(); + if ( mColorButtonsHidden ) { - UnparentAndReset( mStyleButtons[index] ); + ResetColorButtons( mColorButtons, NUMBER_OF_COLORS ); + animation.Reset(); // Handle reset + if ( mCollapseColorsAndStyles ) + { + mExpandingButtons.Collapse(); + } } } - bool OnStyleButtonClicked( Toolkit::Button button ) + // Create the style buttons that will expand from the expanding button. + void CreateStyleButtons() { - if ( button.GetProperty( Toolkit::Button::Property::SELECTED ).Get<bool>() ) + for ( unsigned int index = 0; index < NUMBER_OF_STYLES; index++ ) { - for ( unsigned int index = 0; index < NUMBER_OF_STYLES; index++ ) + if ( ! mStyleButtons[index] ) { mStyleButtons[index] = PushButton::New(); - mStyleButtons[index].SetPosition( mButtonSize.width + ( mButtonSize.width * (index+1) ), mStageSize.height * STYLE_BUTTON_POSTION_RELATIVE_TO_STAGE ); - mStyleButtons[index].SetSize( mButtonSize ); mStyleButtons[index].SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, BUTTON_IMAGES[ index ] ); mStyleButtons[index].SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, STYLE_SELECTED_IMAGE ); - mStyleButtons[index].ClickedSignal().Connect( this, &TextLabelExample::OnStyleSelected ); - Stage::GetCurrent().Add( mStyleButtons[index] ); + mStyleButtons[index].SetProperty( Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT ); + mStyleButtons[index].SetSize( mButtonSize ); + mStyleButtons[index].ClickedSignal().Connect( this, &TextLabelExample::OnStyleButtonClicked ); + } + } + } + + // Animate away the color bar. + void HideColorButtons() + { + if ( ! mColorButtonsHidden ) + { + for( unsigned int index = 0; index < NUMBER_OF_COLORS; index++) + { + mColorButtonsAnimation.AnimateTo( Property( mColorButtons[index], Actor::Property::POSITION_Y ), 0.0f ); } - ShowColorButtons(); + mColorButtonsHidden = true; + mColorButtonsAnimation.Play(); + } + mStyleActivatedForColor = NUMBER_OF_STYLES; + } + + // Request the expanding button to collapse. + void HideStyleAndColorButtons() + { + mCollapseColorsAndStyles = true; + if ( mColorButtonsHidden ) + { + mExpandingButtons.Collapse(); } else { - // hide menu and colors HideColorButtons(); - HideStyleButtons(); } - return true; } // Resize the text-label with pan gesture @@ -414,6 +558,8 @@ public: // Only show the border during the panning mBorder.SetVisible(true); + + HideStyleAndColorButtons(); } mLayoutSize.x += gesture.displacement.x * 2.0f; @@ -560,14 +706,18 @@ private: TextLabel mLabel; - PushButton mStyleMenuButton; + Demo::ExpandingButtons mExpandingButtons; PushButton mStyleButtons[ NUMBER_OF_STYLES ]; - bool mShadowActive; - bool mOutlineActive; + bool mStyleActiveState[ NUMBER_OF_STYLES ]; + + Vector4 mCurrentStyleColor[NUMBER_OF_STYLES ]; + Vector4 mSelectedColor; - Vector4 mOutlineColor; // Store outline as Vector4 whilst TextLabel Outline Property returns a string when using GetProperty + Button mColorButtons[ NUMBER_OF_COLORS ]; + StyleType mStyleActivatedForColor; // The style that the color bar is connected to + Control mContainer; Control mGrabCorner; Control mBorder; @@ -576,6 +726,8 @@ private: Vector2 mLayoutSize; + Animation mColorButtonsAnimation; + Size mStageSize; Size mButtonSize; @@ -583,6 +735,9 @@ private: unsigned int mAlignment; Property::Index mHueAngleIndex; Property::Index mOverrideMixColorIndex; + + bool mColorButtonsHidden; + bool mCollapseColorsAndStyles; }; int DALI_EXPORT_API main( int argc, char **argv ) diff --git a/examples/text-memory-profiling/text-memory-profiling-example.cpp b/examples/text-memory-profiling/text-memory-profiling-example.cpp index 09e6f691..eae8319f 100644 --- a/examples/text-memory-profiling/text-memory-profiling-example.cpp +++ b/examples/text-memory-profiling/text-memory-profiling-example.cpp @@ -45,6 +45,7 @@ enum TextType MULTI_COLOR_TEXT_WITH_STYLE, MULTI_COLOR_TEXT_WITH_EMOJI, MULTI_COLOR_TEXT_WITH_STYLE_EMOJI, + SMALL_TEXT_IN_LARGE_TEXT_LABEL, NUMBER_OF_TYPES }; @@ -57,7 +58,8 @@ std::string TEXT_TYPE_STRING[ NUMBER_OF_TYPES ] = "Multi color text", "Multi color text with style", "Multi color text with emoji", - "Multi color text with style and emoji" + "Multi color text with style and emoji", + "Small text in large Text Label" }; const int NUMBER_OF_LABELS = 500; @@ -156,6 +158,13 @@ public: label.SetProperty( TextLabel::Property::SHADOW_OFFSET, Vector2( 2.0f, 2.0f ) ); break; } + case SMALL_TEXT_IN_LARGE_TEXT_LABEL: + { + label.SetProperty( TextLabel::Property::TEXT, "A Quick Brown Fox Jumps Over The Lazy Dog" ); + label.SetProperty( TextLabel::Property::SHADOW_OFFSET, Vector2( 0.0f, 0.0f ) ); + label.SetSize(stageSize.x, stageSize.y * 0.25f); // Set the text label in larger size + break; + } default: break; } diff --git a/packaging/com.samsung.dali-demo.spec b/packaging/com.samsung.dali-demo.spec index 5b0b244c..277b409d 100755 --- a/packaging/com.samsung.dali-demo.spec +++ b/packaging/com.samsung.dali-demo.spec @@ -2,7 +2,7 @@ Name: com.samsung.dali-demo Summary: The OpenGLES Canvas Core Demo -Version: 1.2.65 +Version: 1.3.9 Release: 1 Group: System/Libraries License: Apache-2.0 diff --git a/resources/images/Call_Accept.png b/resources/images/Call_Accept.png Binary files differnew file mode 100644 index 00000000..e640a41a --- /dev/null +++ b/resources/images/Call_Accept.png diff --git a/resources/images/Call_Battery.png b/resources/images/Call_Battery.png Binary files differnew file mode 100644 index 00000000..06f1e35a --- /dev/null +++ b/resources/images/Call_Battery.png diff --git a/resources/images/Call_Decline.png b/resources/images/Call_Decline.png Binary files differnew file mode 100644 index 00000000..69983223 --- /dev/null +++ b/resources/images/Call_Decline.png diff --git a/resources/images/Call_Decline_wh.png b/resources/images/Call_Decline_wh.png Binary files differnew file mode 100644 index 00000000..7022548a --- /dev/null +++ b/resources/images/Call_Decline_wh.png diff --git a/resources/images/Card_01.png b/resources/images/Card_01.png Binary files differnew file mode 100644 index 00000000..799cb122 --- /dev/null +++ b/resources/images/Card_01.png diff --git a/resources/images/Card_02.png b/resources/images/Card_02.png Binary files differnew file mode 100644 index 00000000..796705ab --- /dev/null +++ b/resources/images/Card_02.png diff --git a/resources/images/Card_03.png b/resources/images/Card_03.png Binary files differnew file mode 100644 index 00000000..33fcb247 --- /dev/null +++ b/resources/images/Card_03.png diff --git a/resources/images/Card_Add_Button.png b/resources/images/Card_Add_Button.png Binary files differnew file mode 100644 index 00000000..a0f9d535 --- /dev/null +++ b/resources/images/Card_Add_Button.png diff --git a/resources/po/en_GB.po b/resources/po/en_GB.po index 4664da66..5962ca49 100755 --- a/resources/po/en_GB.po +++ b/resources/po/en_GB.po @@ -19,6 +19,12 @@ msgstr "Bubbles" msgid "DALI_DEMO_STR_TITLE_BUTTONS" msgstr "Buttons" +msgid "DALI_DEMO_STR_TITLE_CALL_ACTIVE" +msgstr "Call Active" + +msgid "DALI_DEMO_STR_TITLE_CARD_ACTIVE" +msgstr "Card Active" + msgid "DALI_DEMO_STR_TITLE_CLIPPING" msgstr "Clipping" diff --git a/resources/po/en_US.po b/resources/po/en_US.po index 604da3a1..e6767f0b 100755 --- a/resources/po/en_US.po +++ b/resources/po/en_US.po @@ -19,6 +19,12 @@ msgstr "Bubbles" msgid "DALI_DEMO_STR_TITLE_BUTTONS" msgstr "Buttons" +msgid "DALI_DEMO_STR_TITLE_CALL_ACTIVE" +msgstr "Call Active" + +msgid "DALI_DEMO_STR_TITLE_CARD_ACTIVE" +msgstr "Card Active" + msgid "DALI_DEMO_STR_TITLE_CLIPPING" msgstr "Clipping" diff --git a/resources/po/ko.po b/resources/po/ko.po index cece01b8..0ea0613e 100755 --- a/resources/po/ko.po +++ b/resources/po/ko.po @@ -16,6 +16,12 @@ msgstr "방울" msgid "DALI_DEMO_STR_TITLE_BUTTONS" msgstr "버튼" +msgid "DALI_DEMO_STR_TITLE_CALL_ACTIVE" +msgstr "통화 수신" + +msgid "DALI_DEMO_STR_TITLE_CARD_ACTIVE" +msgstr "NFC 카드 태깅" + msgid "DALI_DEMO_STR_TITLE_CLIPPING" msgstr "깎는" diff --git a/resources/style/.gitignore b/resources/style/.gitignore index dd5d4674..74584685 100644 --- a/resources/style/.gitignore +++ b/resources/style/.gitignore @@ -1,4 +1,5 @@ demo-theme.json +animated-gradient-call-active-style.json contact-cards-example-theme.json progress-bar-example-theme.json simple-example-theme.json diff --git a/resources/style/animated-gradient-call-active-style.json.in b/resources/style/animated-gradient-call-active-style.json.in new file mode 100644 index 00000000..d73dc385 --- /dev/null +++ b/resources/style/animated-gradient-call-active-style.json.in @@ -0,0 +1,76 @@ +{ + "styles": { + "IncomeBackground": { + "background": { + "visualType": "ANIMATED_GRADIENT", + "gradientType": "RADIAL", + "unitType": "USER_SPACE", + "startPosition": [0.0, 0.0], + "endPosition": [180.0, 0.0], + "startColor": [0.1333, 0.1647, 0.2941, 1.0], + "endColor": [0.0784, 0.3961, 0.4863, 1.0], + "rotateCenter": [0.0, 0.0], + "rotateAmount": 0.0, + "offset": { + "startValue": 0.0, + "targetValue": 2.0, + "directionType": "BACKWARD", + "duration": 1.25, + "delay": 0.0, + "repeat": -1, + "repeatDelay": 0.0, + "motionType": "LOOP", + "easingType": "LINEAR" + } + } + }, + "ActiveBackground":{ + "background":{ + "visualType": "ANIMATED_GRADIENT", + "gradientType": "RADIAL", + "unitType": "USER_SPACE", + "startPosition": [0.0, 0.0], + "endPosition": [180.0, 0.0], + "startColor": [0.1066, 0.1318, 0.2353, 1.0], + "endColor": [0.0627, 0.3169, 0.3890, 1.0], + "rotateCenter": [0.0, 0.0], + "rotateAmount": 0.0, + "offset": { + "startValue": 0.0, + "targetValue": 2.0, + "directionType": "BACKWARD", + "duration": 4.0, + "delay": 0.0, + "repeat": -1, + "repeatDelay": 0.0, + "motionType": "LOOP", + "easingType": "LINEAR" + } + } + }, + "DeclineButton":{ + "background":{ + "visualType": "ANIMATED_GRADIENT", + "gradientType": "LINEAR", + "unitType": "USER_SPACE", + "startPosition": [-180.0, 0.0], + "endPosition": [180.0, 0.0], + "startColor": [0.8941, 0.0078, 0.0078, 1.0], + "endColor": [1.0000, 0.5961, 0.0000, 1.0], + "rotateCenter": [0.0, 0.0], + "rotateAmount": 0.78539816, + "offset": { + "startValue": 0.0, + "targetValue": 2.0, + "directionType": "FORWARD", + "duration": 1.8, + "delay": -1.2, + "repeat": -1, + "repeatDelay": 1.2, + "motionType": "LOOP", + "easingType": "IN_OUT" + } + } + } + } +} diff --git a/resources/style/mobile/animated-gradient-call-active-style.json.in b/resources/style/mobile/animated-gradient-call-active-style.json.in new file mode 100644 index 00000000..d73dc385 --- /dev/null +++ b/resources/style/mobile/animated-gradient-call-active-style.json.in @@ -0,0 +1,76 @@ +{ + "styles": { + "IncomeBackground": { + "background": { + "visualType": "ANIMATED_GRADIENT", + "gradientType": "RADIAL", + "unitType": "USER_SPACE", + "startPosition": [0.0, 0.0], + "endPosition": [180.0, 0.0], + "startColor": [0.1333, 0.1647, 0.2941, 1.0], + "endColor": [0.0784, 0.3961, 0.4863, 1.0], + "rotateCenter": [0.0, 0.0], + "rotateAmount": 0.0, + "offset": { + "startValue": 0.0, + "targetValue": 2.0, + "directionType": "BACKWARD", + "duration": 1.25, + "delay": 0.0, + "repeat": -1, + "repeatDelay": 0.0, + "motionType": "LOOP", + "easingType": "LINEAR" + } + } + }, + "ActiveBackground":{ + "background":{ + "visualType": "ANIMATED_GRADIENT", + "gradientType": "RADIAL", + "unitType": "USER_SPACE", + "startPosition": [0.0, 0.0], + "endPosition": [180.0, 0.0], + "startColor": [0.1066, 0.1318, 0.2353, 1.0], + "endColor": [0.0627, 0.3169, 0.3890, 1.0], + "rotateCenter": [0.0, 0.0], + "rotateAmount": 0.0, + "offset": { + "startValue": 0.0, + "targetValue": 2.0, + "directionType": "BACKWARD", + "duration": 4.0, + "delay": 0.0, + "repeat": -1, + "repeatDelay": 0.0, + "motionType": "LOOP", + "easingType": "LINEAR" + } + } + }, + "DeclineButton":{ + "background":{ + "visualType": "ANIMATED_GRADIENT", + "gradientType": "LINEAR", + "unitType": "USER_SPACE", + "startPosition": [-180.0, 0.0], + "endPosition": [180.0, 0.0], + "startColor": [0.8941, 0.0078, 0.0078, 1.0], + "endColor": [1.0000, 0.5961, 0.0000, 1.0], + "rotateCenter": [0.0, 0.0], + "rotateAmount": 0.78539816, + "offset": { + "startValue": 0.0, + "targetValue": 2.0, + "directionType": "FORWARD", + "duration": 1.8, + "delay": -1.2, + "repeat": -1, + "repeatDelay": 1.2, + "motionType": "LOOP", + "easingType": "IN_OUT" + } + } + } + } +} diff --git a/shared/dali-demo-strings.h b/shared/dali-demo-strings.h index b73ac73f..613b2952 100644 --- a/shared/dali-demo-strings.h +++ b/shared/dali-demo-strings.h @@ -39,6 +39,8 @@ extern "C" #define DALI_DEMO_STR_TITLE_BLOCKS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BLOCKS") #define DALI_DEMO_STR_TITLE_BUBBLES dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BUBBLES") #define DALI_DEMO_STR_TITLE_BUTTONS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_BUTTONS") +#define DALI_DEMO_STR_TITLE_CALL_ACTIVE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CALL_ACTIVE") +#define DALI_DEMO_STR_TITLE_CARD_ACTIVE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CARD_ACTIVE") #define DALI_DEMO_STR_TITLE_CLIPPING dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CLIPPING") #define DALI_DEMO_STR_TITLE_CLIPPING_DRAW_ORDER dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_CLIPPING_DRAW_ORDER") #define DALI_DEMO_STR_TITLE_COLOR_GRADIENT dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_COLOR_GRADIENT") @@ -110,6 +112,8 @@ extern "C" #define DALI_DEMO_STR_TITLE_BLOCKS "Blocks" #define DALI_DEMO_STR_TITLE_BUBBLES "Bubbles" #define DALI_DEMO_STR_TITLE_BUTTONS "Buttons" +#define DALI_DEMO_STR_TITLE_CALL_ACTIVE "Call Active" +#define DALI_DEMO_STR_TITLE_CARD_ACTIVE "Card Active" #define DALI_DEMO_STR_TITLE_CLIPPING "Clipping" #define DALI_DEMO_STR_TITLE_CLIPPING_DRAW_ORDER "Clipping Draw Order" #define DALI_DEMO_STR_TITLE_COLOR_GRADIENT "Color Gradient" |