From e2ee6baaa8dcfe20f708b17a51e4303b8cfc3824 Mon Sep 17 00:00:00 2001 From: David Steele Date: Tue, 20 Dec 2016 19:45:22 +0000 Subject: [PATCH 1/1] Added application to test visual transition framework This application shows a possible implementation of a shadowed button, with transition animation defined by the style sheet. Change-Id: Ib764dacdeed2381d96474059ef830e17a2cb9fff Signed-off-by: David Steele --- build/tizen/.gitignore | 1 + examples/styling/image-channel-control-impl.cpp | 3 +- examples/styling/styling-application.cpp | 17 +- examples/transitions/beat-control-impl.cpp | 280 ----------- examples/transitions/beat-control-impl.h | 145 ------ examples/transitions/beat-control.cpp | 89 ---- examples/transitions/beat-control.h | 121 ----- examples/transitions/shadow-button-impl.cpp | 548 +++++++++++++++++++++ examples/transitions/shadow-button-impl.h | 220 +++++++++ examples/transitions/shadow-button.cpp | 94 ++++ examples/transitions/shadow-button.h | 148 ++++++ examples/transitions/transition-application.cpp | 91 ++-- examples/transitions/transition-application.h | 24 +- examples/transitions/transition-example.cpp | 2 +- resources/images/preMultAlpha.png | Bin 0 -> 4615 bytes resources/style/images/CheckBg.png | Bin 0 -> 1261 bytes resources/style/images/Tick.png | Bin 0 -> 1713 bytes resources/style/images/shadowButtonBg.9.png | Bin 0 -> 1600 bytes resources/style/mobile/images/CheckBg.png | Bin 0 -> 1261 bytes resources/style/mobile/images/Tick.png | Bin 0 -> 1713 bytes resources/style/mobile/images/shadowButtonBg.9.png | Bin 0 -> 1600 bytes .../style/mobile/style-example-theme-one.json.in | 213 ++++++-- .../style/mobile/style-example-theme-three.json.in | 20 +- .../style/mobile/style-example-theme-two.json.in | 114 ++++- resources/style/style-example-theme-one.json.in | 213 ++++++-- resources/style/style-example-theme-three.json.in | 20 +- resources/style/style-example-theme-two.json.in | 99 +++- 27 files changed, 1661 insertions(+), 801 deletions(-) delete mode 100644 examples/transitions/beat-control-impl.cpp delete mode 100644 examples/transitions/beat-control-impl.h delete mode 100644 examples/transitions/beat-control.cpp delete mode 100644 examples/transitions/beat-control.h create mode 100644 examples/transitions/shadow-button-impl.cpp create mode 100644 examples/transitions/shadow-button-impl.h create mode 100644 examples/transitions/shadow-button.cpp create mode 100644 examples/transitions/shadow-button.h create mode 100644 resources/images/preMultAlpha.png create mode 100644 resources/style/images/CheckBg.png create mode 100644 resources/style/images/Tick.png create mode 100644 resources/style/images/shadowButtonBg.9.png create mode 100644 resources/style/mobile/images/CheckBg.png create mode 100644 resources/style/mobile/images/Tick.png create mode 100644 resources/style/mobile/images/shadowButtonBg.9.png diff --git a/build/tizen/.gitignore b/build/tizen/.gitignore index 9425618..d9f6684 100644 --- a/build/tizen/.gitignore +++ b/build/tizen/.gitignore @@ -11,3 +11,4 @@ install_manifest.txt /builder/dali-builder /examples/*.demo /mo +compile_commands.json diff --git a/examples/styling/image-channel-control-impl.cpp b/examples/styling/image-channel-control-impl.cpp index a6b41c7..c805e39 100644 --- a/examples/styling/image-channel-control-impl.cpp +++ b/examples/styling/image-channel-control-impl.cpp @@ -37,11 +37,12 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( varying mediump vec2 vTexCoord;\n uniform sampler2D sTexture;\n uniform mediump vec4 uColor;\n + uniform mediump vec4 mixColor;\n uniform mediump vec3 uChannels;\n \n void main()\n {\n - gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor * vec4(uChannels, 1.0) ;\n + gl_FragColor = texture2D( sTexture, vTexCoord ) * mixColor * uColor * vec4(uChannels, 1.0) ;\n }\n ); diff --git a/examples/styling/styling-application.cpp b/examples/styling/styling-application.cpp index 19a1411..b5b876e 100644 --- a/examples/styling/styling-application.cpp +++ b/examples/styling/styling-application.cpp @@ -24,8 +24,9 @@ // External includes #include -//#include #include +#include +#include #include "image-channel-control.h" #include #include @@ -212,7 +213,7 @@ void StylingApplication::Create( Application& application ) mIcc1.SetSizeScalePolicy( SizeScalePolicy::FIT_WITH_ASPECT_RATIO ); mIcc1.SetParentOrigin( ParentOrigin::CENTER ); mIcc1.SetVisibility( true ); - + mImagePlacement.Add( mIcc1 ); mIcc2 = ImageChannelControl::New( BIG_IMAGE_2 ); @@ -484,20 +485,20 @@ bool StylingApplication::OnButtonStateChange( Button button ) // Todo: save / restore slider states per image - if( button.GetProperty( Toolkit::Button::Property::SELECTED ).Get() ) + if( button.GetProperty(Button::Property::SELECTED) ) { ImageChannelControl prevIcc = mImageChannelControl; - if( mRadioButtons[0].GetProperty( Toolkit::Button::Property::SELECTED ).Get() ) + if( mRadioButtons[0].GetProperty(Button::Property::SELECTED) ) { mImageChannelControl = mIcc1; } - else if( mRadioButtons[1].GetProperty( Toolkit::Button::Property::SELECTED ).Get() ) + else if( mRadioButtons[1].GetProperty(Button::Property::SELECTED) ) { mImageChannelControl = mIcc2; } - else if( mRadioButtons[2].GetProperty( Toolkit::Button::Property::SELECTED ).Get() ) + else if( mRadioButtons[2].GetProperty(Button::Property::SELECTED) ) { mImageChannelControl = mIcc3; } @@ -523,7 +524,7 @@ bool StylingApplication::OnCheckButtonChange( Button button ) { int channel = button.GetProperty( index ); float value = mChannelSliders[channel].GetProperty( Slider::Property::VALUE ); - if( !button.IsSelected() ) + if( !button.GetProperty(Button::Property::SELECTED) ) { // "Turn off" the channel's contribution value = 0.0f; @@ -600,7 +601,7 @@ bool StylingApplication::OnSliderChanged( Slider slider, float value ) if( index != Property::INVALID_INDEX ) { int channel = slider.GetProperty( index ); - if( mCheckButtons[channel].IsSelected() ) + if( mCheckButtons[channel].GetProperty(Button::Property::SELECTED) ) { Property::Index channelIndex = GetChannelProperty( channel ); mImageChannelControl.SetProperty(channelIndex, value/100.0f); diff --git a/examples/transitions/beat-control-impl.cpp b/examples/transitions/beat-control-impl.cpp deleted file mode 100644 index 6b0f3e6..0000000 --- a/examples/transitions/beat-control-impl.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) 2016 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 "beat-control-impl.h" -#include -#include -#include -#include -#include - -#include - -using namespace Dali; // Needed for macros -using namespace Dali::Toolkit; - -namespace Demo -{ -namespace Internal -{ - -namespace -{ - - -Dali::BaseHandle Create() -{ - return Demo::BeatControl::New(); -} - -DALI_TYPE_REGISTRATION_BEGIN( BeatControl, Dali::Toolkit::Control, Create ); - -DALI_PROPERTY_REGISTRATION( Demo, BeatControl, "bounceTransition", STRING, BOUNCE_TRANSITION ); -DALI_PROPERTY_REGISTRATION( Demo, BeatControl, "leftTransition", STRING, LEFT_TRANSITION ); -DALI_PROPERTY_REGISTRATION( Demo, BeatControl, "upTransition", STRING, UP_TRANSITION ); -DALI_PROPERTY_REGISTRATION( Demo, BeatControl, "beatVisual", MAP, BEAT_VISUAL ); -DALI_TYPE_REGISTRATION_END(); - - -Toolkit::TransitionData ConvertPropertyToTransition( const Property::Value& value ) -{ - Toolkit::TransitionData transitionData; - - if( value.GetType() == Property::ARRAY ) - { - transitionData = Toolkit::TransitionData::New( *value.GetArray()); - } - else if( value.GetType() == Property::MAP ) - { - transitionData = Toolkit::TransitionData::New( *value.GetMap() ); - } - return transitionData; -} - -} // anonymous namespace - - -Internal::BeatControl::BeatControl() -: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ) -{ -} - -Internal::BeatControl::~BeatControl() -{ -} - -Demo::BeatControl Internal::BeatControl::New() -{ - IntrusivePtr impl = new Internal::BeatControl(); - Demo::BeatControl handle = Demo::BeatControl( *impl ); - impl->Initialize(); - return handle; -} - - -void BeatControl::StartBounceAnimation() -{ - if( mAnimation ) - { - mAnimation.Stop(); - mAnimation.FinishedSignal().Disconnect( this, &BeatControl::OnBounceAnimationFinished ); - OnBounceAnimationFinished(mAnimation); - } - - mAnimation = CreateTransition( mBounceTransition ); - mAnimation.FinishedSignal().Connect( this, &BeatControl::OnBounceAnimationFinished ); - mAnimation.Play(); -} - - -void BeatControl::StartXAnimation() -{ - if( mXAnimation ) - { - mXAnimation.Stop(); - mXAnimation.FinishedSignal().Disconnect( this, &BeatControl::OnXAnimationFinished ); - OnXAnimationFinished(mXAnimation); - } - - mXAnimation = CreateTransition( mLeftTransition ); - mXAnimation.FinishedSignal().Connect( this, &BeatControl::OnXAnimationFinished ); - mXAnimation.Play(); -} - -void BeatControl::StartYAnimation() -{ - if( mYAnimation ) - { - mYAnimation.Stop(); - mYAnimation.FinishedSignal().Disconnect( this, &BeatControl::OnYAnimationFinished ); - OnYAnimationFinished(mYAnimation); - } - - mYAnimation = CreateTransition( mUpTransition ); - mYAnimation.FinishedSignal().Connect( this, &BeatControl::OnYAnimationFinished ); - mYAnimation.Play(); -} - - -void BeatControl::OnBounceAnimationFinished( Animation& src ) -{ - // Do stuff -} -void BeatControl::OnXAnimationFinished( Animation& src ) -{ - // Do stuff -} -void BeatControl::OnYAnimationFinished( Animation& src ) -{ - // Do stuff -} - -void BeatControl::OnInitialize() -{ - Actor self = Self(); -} - -void BeatControl::OnStageConnection( int depth ) -{ - Control::OnStageConnection( depth ); -} - -void BeatControl::OnStageDisconnection() -{ - Control::OnStageDisconnection(); -} - -void BeatControl::OnSizeSet( const Vector3& targetSize ) -{ - Control::OnSizeSet( targetSize ); - RelayoutVisuals( Vector2( targetSize ) ); -} - -void BeatControl::OnRelayout( const Vector2& targetSize, RelayoutContainer& container ) -{ - RelayoutVisuals( targetSize ); -} - -void BeatControl::RelayoutVisuals( const Vector2& targetSize ) -{ - if( mVisual ) - { - Vector2 size( targetSize ); - Property::Map transformMap; - // Make the visual half the size of the control, but leave - // origin and anchor point at center, position is relative, but Zer0 - transformMap[ DevelVisual::Transform::Property::SIZE ] = Vector2(0.5, 0.5); - mVisual.SetTransformAndSize( transformMap, size ); - - // @todo We must stop this clashing with a transform animation - } -} - -Vector3 BeatControl::GetNaturalSize() -{ - if( mVisual ) - { - Vector2 naturalSize; - mVisual.GetNaturalSize(naturalSize); - return Vector3(naturalSize); - } - return Vector3::ZERO; -} - -void BeatControl::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change ) -{ - // Chain up. - Control::OnStyleChange( styleManager, change ); -} - - -/////////////////////////////////////////////////////////// -// -// Properties -// - -void BeatControl::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value ) -{ - Demo::BeatControl beatControl = Demo::BeatControl::DownCast( Dali::BaseHandle( object ) ); - - if( beatControl ) - { - BeatControl& impl = GetImpl( beatControl ); - Actor self = impl.Self(); - switch ( index ) - { - case Demo::BeatControl::Property::BEAT_VISUAL: - { - Property::Map* map = value.GetMap(); - if( map ) - { - impl.mVisual = Toolkit::VisualFactory::Get().CreateVisual( *map ); - impl.RegisterVisual( Demo::BeatControl::Property::BEAT_VISUAL, impl.mVisual ); - } - break; - } - case Demo::BeatControl::Property::BOUNCE_TRANSITION: - { - impl.mBounceTransition = ConvertPropertyToTransition( value ); - break; - } - case Demo::BeatControl::Property::LEFT_TRANSITION: - { - impl.mLeftTransition = ConvertPropertyToTransition( value ); - break; - } - case Demo::BeatControl::Property::UP_TRANSITION: - { - impl.mUpTransition = ConvertPropertyToTransition( value ); - break; - } - } - } -} - -Property::Value BeatControl::GetProperty( BaseObject* object, Property::Index propertyIndex ) -{ - Property::Value value; - - Demo::BeatControl beatControl = Demo::BeatControl::DownCast( Dali::BaseHandle( object ) ); - - if ( beatControl ) - { - BeatControl& impl = GetImpl( beatControl ); - switch ( propertyIndex ) - { - case Demo::BeatControl::Property::BEAT_VISUAL: - { - if( impl.mVisual ) - { - Property::Map map; - impl.mVisual.CreatePropertyMap(map); - value = map; - } - break; - } - case Demo::BeatControl::Property::BOUNCE_TRANSITION: - default: - break; - } - } - - return value; -} - - -} // Internal -} // Demo diff --git a/examples/transitions/beat-control-impl.h b/examples/transitions/beat-control-impl.h deleted file mode 100644 index e4f9a99..0000000 --- a/examples/transitions/beat-control-impl.h +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef DALI_DEMO_INTERNAL_BEAT_CONTROL_IMPL_H -#define DALI_DEMO_INTERNAL_BEAT_CONTROL_IMPL_H - -/* - * Copyright (c) 2016 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 "beat-control.h" -#include -#include -#include -#include - -namespace Demo -{ - -namespace Internal // To use TypeRegistry, handle and body classes need the same name -{ - -class BeatControl : public Dali::Toolkit::Internal::Control -{ -public: - /** - * Instantiate a new BeatControl object - */ - static Demo::BeatControl New(); - BeatControl(); - ~BeatControl(); - -public: // API - void StartBounceAnimation(); - - void StartXAnimation(); - - void StartYAnimation(); - -public: // Properties - /** - * Called when a property of an object of this type is set. - * @param[in] object The object whose property is set. - * @param[in] index The property index. - * @param[in] value The new property value. - */ - static void SetProperty( Dali::BaseObject* object, Dali::Property::Index index, const Dali::Property::Value& value ); - - /** - * Called to retrieve a property of an object of this type. - * @param[in] object The object whose property is to be retrieved. - * @param[in] index The property index. - * @return The current value of the property. - */ - static Dali::Property::Value GetProperty( Dali::BaseObject* object, Dali::Property::Index propertyIndex ); - -private: // From Control - /** - * @copydoc Toolkit::Control::OnInitialize() - */ - virtual void OnInitialize(); - - /** - * @copydoc Toolkit::Control::OnStageConnect() - */ - virtual void OnStageConnection( int depth ); - - /** - * @copydoc Toolkit::Control::OnStageDisconnection() - */ - virtual void OnStageDisconnection(); - - /** - * @copydoc Toolkit::Control::OnSizeSet() - */ - virtual void OnSizeSet( const Dali::Vector3& targetSize ); - - /** - * @copydoc Toolkit::Control::OnRelayout() - */ - virtual void OnRelayout( const Dali::Vector2& targetSize, Dali::RelayoutContainer& container ); - /** - * @copydoc Toolkit::Control::GetNaturalSize - */ - virtual Dali::Vector3 GetNaturalSize(); - - /** - * @copydoc Toolkit::Control::OnStyleChange - */ - virtual void OnStyleChange( Dali::Toolkit::StyleManager styleManager, Dali::StyleChange::Type change ); - -private: - void OnBounceAnimationFinished( Dali::Animation& handle ); - void OnXAnimationFinished( Dali::Animation& src ); - void OnYAnimationFinished( Dali::Animation& src ); - - /** - * Relayout the visuals as a result of size negotiation - */ - void RelayoutVisuals( const Dali::Vector2& targetSize ); - -private: - //undefined - BeatControl( const BeatControl& ); - BeatControl& operator=( const BeatControl& ); - -private: - // Implementation details - Dali::Toolkit::Visual::Base mVisual; - Dali::Toolkit::TransitionData mBounceTransition; - Dali::Toolkit::TransitionData mLeftTransition; - Dali::Toolkit::TransitionData mUpTransition; - Dali::Animation mAnimation; - Dali::Animation mXAnimation; - Dali::Animation mYAnimation; -}; - -} // Internal - -inline Internal::BeatControl& GetImpl( Demo::BeatControl& handle ) -{ - DALI_ASSERT_ALWAYS( handle ); - Dali::RefObject& object = handle.GetImplementation(); - return static_cast(object); -} - -inline const Internal::BeatControl& GetImpl( const Demo::BeatControl& handle ) -{ - DALI_ASSERT_ALWAYS( handle ); - const Dali::RefObject& object = handle.GetImplementation(); - return static_cast(object); -} - -} // Demo - -#endif // DALI_DEMO_BEAT_CONTROL_IMPL_H diff --git a/examples/transitions/beat-control.cpp b/examples/transitions/beat-control.cpp deleted file mode 100644 index c145b5e..0000000 --- a/examples/transitions/beat-control.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016 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 "beat-control.h" -#include "beat-control-impl.h" - -namespace Demo -{ - -BeatControl::BeatControl() -{ -} - -BeatControl::BeatControl( const BeatControl& beatControl ) -: Control( beatControl ) -{ -} - -BeatControl& BeatControl::operator= ( const BeatControl& rhs ) -{ - if( &rhs != this ) - { - Control::operator=( rhs ); - } - return *this; -} - -BeatControl::~BeatControl() -{ -} - -BeatControl BeatControl::New() -{ - BeatControl beatControl = Internal::BeatControl::New(); - return beatControl; -} - -BeatControl BeatControl::New( const std::string& url ) -{ - BeatControl beatControl = Internal::BeatControl::New(); - return beatControl; -} - -BeatControl BeatControl::DownCast( BaseHandle handle ) -{ - return Control::DownCast< BeatControl, Internal::BeatControl > ( handle ); -} - -void BeatControl::StartBounceAnimation() -{ - GetImpl(*this).StartBounceAnimation(); -} - -void BeatControl::StartXAnimation() -{ - GetImpl(*this).StartXAnimation(); -} -void BeatControl::StartYAnimation() -{ - GetImpl(*this).StartYAnimation(); -} - - -BeatControl::BeatControl( Internal::BeatControl& implementation ) -: Control( implementation ) -{ -} - -BeatControl::BeatControl( Dali::Internal::CustomActor* internal ) -: Control( internal ) -{ - VerifyCustomActorPointer< Internal::BeatControl >( internal ) ; -} - - -} //namespace Demo diff --git a/examples/transitions/beat-control.h b/examples/transitions/beat-control.h deleted file mode 100644 index c424d89..0000000 --- a/examples/transitions/beat-control.h +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef DALI_DEMO_BEAT_CONTROL_H -#define DALI_DEMO_BEAT_CONTROL_H - -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -namespace Demo -{ - -namespace Internal -{ -// All type registered types need to have the same name for the body and the handle -class BeatControl; -} - -/** - * Control that allows the RGB channels of an image to be altered. - */ -class BeatControl : public Dali::Toolkit::Control -{ -public: - /** - * The start and end property ranges for this control - */ - enum PropertyRange - { - PROPERTY_START_INDEX = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1, - PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000, - ANIMATABLE_PROPERTY_START_INDEX = Dali::ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX, - ANIMATABLE_PROPERTY_END_INDEX = ANIMATABLE_PROPERTY_START_INDEX+1000 - }; - - struct Property - { - enum - { - BOUNCE_TRANSITION = PROPERTY_START_INDEX, - LEFT_TRANSITION, - UP_TRANSITION, - BEAT_VISUAL - }; - }; - -public: // Construction / destruction - - /** - * Create an uninitialized handle - */ - BeatControl(); - - /** - * Create a new image channel control without an image. Use - * SetImage to give this control an image - */ - static BeatControl New(); - - /** - * Create a new image channel control from a given URL - */ - static BeatControl New( const std::string& url ); - - /** - * Destructor. This is non-virtual since derived Handle types must not - * contain data or virtual methods - */ - ~BeatControl(); - - /** - * Copy Constructor - */ - BeatControl( const BeatControl& beatControl ); - - /** - * Assignment Operator - */ - BeatControl& operator=( const BeatControl& beatControl ); - - /** - * Downcast - */ - static BeatControl DownCast( BaseHandle handle ); - -public: // API - - void StartBounceAnimation(); - - void StartXAnimation(); - - void StartYAnimation(); - -public: // Not for public use - /** - * Create a handle from an implementation - */ - BeatControl( Internal::BeatControl& implementation ); - - /** - * Allow the creation of an BeatControl handle from an internal CustomActor pointer - */ - BeatControl( Dali::Internal::CustomActor* internal ); -}; - -} // namespace Demo - -#endif // DALI_DEMO_BEAT_CONTROL_H diff --git a/examples/transitions/shadow-button-impl.cpp b/examples/transitions/shadow-button-impl.cpp new file mode 100644 index 0000000..aa82ce1 --- /dev/null +++ b/examples/transitions/shadow-button-impl.cpp @@ -0,0 +1,548 @@ +/* + * 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 "shadow-button-impl.h" +#include +#include +#include +#include +#include +#include + +#include + +using namespace Dali; // Needed for macros +using namespace Dali::Toolkit; + +namespace Demo +{ +namespace Internal +{ + +namespace +{ + + +Dali::BaseHandle Create() +{ + return Demo::ShadowButton::New(); +} + +DALI_TYPE_REGISTRATION_BEGIN( ShadowButton, Dali::Toolkit::Button, Create ); + +DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "activeTransition", ARRAY, ACTIVE_TRANSITION ); +DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "inactiveTransition", ARRAY, INACTIVE_TRANSITION ); +DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "clickTransition", ARRAY, CLICK_TRANSITION ); +DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "backgroundVisual", MAP, BACKGROUND_VISUAL ); +DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkboxBgVisual", MAP, CHECKBOX_BG_VISUAL ); +DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkboxFgVisual", MAP, CHECKBOX_FG_VISUAL ); +DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "labelVisual", MAP, LABEL_VISUAL ); +DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkState", BOOLEAN, ACTIVE_STATE ); +DALI_PROPERTY_REGISTRATION( Demo, ShadowButton, "checkState", BOOLEAN, CHECK_STATE ); + +DALI_TYPE_REGISTRATION_END(); + +DALI_ENUM_TO_STRING_TABLE_BEGIN( VISUAL_PROPERTIES ) +{ "backgroundVisual", Demo::ShadowButton::Property::BACKGROUND_VISUAL }, +{ "checkboxBgVisual", Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL}, +{ "checkboxFgVisual", Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL}, +{ "labelVisual", Demo::ShadowButton::Property::LABEL_VISUAL} +DALI_ENUM_TO_STRING_TABLE_END( VISUAL_PROPERTIES ) + +Toolkit::TransitionData ConvertPropertyToTransition( const Property::Value& value ) +{ + Toolkit::TransitionData transitionData; + + if( value.GetType() == Property::ARRAY ) + { + transitionData = Toolkit::TransitionData::New( *value.GetArray()); + } + else if( value.GetType() == Property::MAP ) + { + transitionData = Toolkit::TransitionData::New( *value.GetMap() ); + } + return transitionData; +} + +} // anonymous namespace + + +Internal::ShadowButton::ShadowButton() +: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ), + mCheckState(false), + mActiveState(false) +{ +} + +Internal::ShadowButton::~ShadowButton() +{ +} + +Demo::ShadowButton Internal::ShadowButton::New() +{ + IntrusivePtr impl = new Internal::ShadowButton(); + Demo::ShadowButton handle = Demo::ShadowButton( *impl ); + impl->Initialize(); + return handle; +} + +void ShadowButton::SetActiveState( bool active ) +{ + if( active != mActiveState ) + { + mActiveState = active; + if( active ) + { + StartTransition( Demo::ShadowButton::Property::ACTIVE_TRANSITION ); + } + else + { + StartTransition( Demo::ShadowButton::Property::INACTIVE_TRANSITION ); + } + } +} + +bool ShadowButton::GetActiveState() +{ + return mActiveState; +} + +void ShadowButton::SetCheckState( bool checkState ) +{ + mCheckState = checkState; + EnableVisual( Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL, mCheckState ); + RelayoutRequest(); +} + +bool ShadowButton::GetCheckState() +{ + return mCheckState; +} + +void ShadowButton::StartTransition( Property::Index transitionId ) +{ + Transitions::iterator iter = FindTransition( transitionId ); + if( iter != mTransitions.end() ) + { + if( iter->mAnimation ) + { + iter->mAnimation.Stop(); + iter->mPlaying = false; + + iter->mAnimation.FinishedSignal().Disconnect( this, &ShadowButton::OnTransitionFinished ); + } + + iter->mAnimation = CreateTransition( iter->mTransitionData ); + StoreTargetLayouts( iter->mTransitionData ); + + iter->mAnimation.FinishedSignal().Connect( this, &ShadowButton::OnTransitionFinished ); + iter->mAnimation.Play(); + iter->mPlaying = true; + } +} + +void ShadowButton::OnTransitionFinished( Animation& src ) +{ + ShadowButton::Transitions::iterator iter = mTransitions.begin(); + for( ; iter != mTransitions.end(); ++iter ) + { + if( iter->mAnimation == src ) + { + iter->mPlaying = false; + iter->mAnimation.Reset(); // Remove the animation when it's finished. + switch( iter->mTransitionId ) + { + case Demo::ShadowButton::Property::ACTIVE_TRANSITION: + { + // Consider relayouting the text. + break; + } + case Demo::ShadowButton::Property::INACTIVE_TRANSITION: + { + // Consider relayouting the text. + break; + } + } + break; + } + } +} + +void ShadowButton::OnInitialize() +{ + Actor self = Self(); +} + +void ShadowButton::OnStageConnection( int depth ) +{ + Control::OnStageConnection( depth ); +} + +void ShadowButton::OnStageDisconnection() +{ + Control::OnStageDisconnection(); +} + +void ShadowButton::OnSizeSet( const Vector3& targetSize ) +{ + Control::OnSizeSet( targetSize ); + RelayoutVisuals( Vector2( targetSize ) ); +} + +void ShadowButton::OnRelayout( const Vector2& targetSize, RelayoutContainer& container ) +{ + RelayoutVisuals( targetSize ); +} + +void ShadowButton::RelayoutVisuals( const Vector2& targetSize ) +{ + bool transitioning = false; + ShadowButton::Transitions::iterator iter = mTransitions.begin(); + for( ; iter != mTransitions.end(); ++iter ) + { + if( iter->mPlaying == true ) + { + transitioning = true; + break; + } + } + + if( ! transitioning ) + { + for( ShadowButton::Transforms::iterator iter = mTransforms.begin(); + iter != mTransforms.end(); ++iter ) + { + switch( iter->mTransformId ) + { + case Demo::ShadowButton::Property::BACKGROUND_VISUAL: + { + mBackgroundVisual.SetTransformAndSize( iter->mTransform, targetSize ); + break; + } + case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL: + { + mCheckboxBgVisual.SetTransformAndSize( iter->mTransform, targetSize ); + break; + } + case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL: + { + mCheckboxFgVisual.SetTransformAndSize( iter->mTransform, targetSize ); + break; + } + case Demo::ShadowButton::Property::LABEL_VISUAL: + { + mLabelVisual.SetTransformAndSize( iter->mTransform, targetSize ); + break; + } + } + } + } +} + +Vector3 ShadowButton::GetNaturalSize() +{ + int width; + int height; + + Vector2 checkboxBgSize; + Vector2 checkboxFgSize; + Vector2 labelSize; + mCheckboxBgVisual.GetNaturalSize( checkboxBgSize ); + mCheckboxFgVisual.GetNaturalSize( checkboxFgSize ); + mLabelVisual.GetNaturalSize( labelSize ); + + width = std::max( checkboxBgSize.x, checkboxFgSize.x ) + labelSize.x; + height = std::max( std::max( checkboxFgSize.y, checkboxBgSize.y ), labelSize.y ); + + return Vector3( width, height, height ); +} + +void ShadowButton::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change ) +{ + // Chain up. + Control::OnStyleChange( styleManager, change ); +} + +ShadowButton::Transitions::iterator ShadowButton::FindTransition( Property::Index index ) +{ + bool found = false; + ShadowButton::Transitions::iterator iter = mTransitions.begin(); + for( ; iter != mTransitions.end(); ++iter ) + { + if( iter->mTransitionId == index ) + { + found = true; + break; + } + } + if( ! found ) + { + iter = mTransitions.end(); + } + return iter; +} + +ShadowButton::Transforms::iterator ShadowButton::FindTransform( Property::Index index ) +{ + bool found = false; + ShadowButton::Transforms::iterator iter = mTransforms.begin(); + for( ; iter != mTransforms.end(); ++iter ) + { + if( iter->mTransformId == index ) + { + found = true; + break; + } + } + if( ! found ) + { + iter = mTransforms.end(); + } + return iter; +} + +void ShadowButton::ResetVisual( + Property::Index index, + Visual::Base& visual, + const Property::Value& value ) +{ + if( visual ) + { + // we are replacing an existing visual, so force relayout + RelayoutRequest(); + } + Property::Map* map = value.GetMap(); + if( map ) + { + visual = Toolkit::VisualFactory::Get().CreateVisual( *map ); + RegisterVisual( index, visual ); + + // Set the appropriate depth index. + // @todo Should be able to set this from the style sheet + switch( index ) + { + case Demo::ShadowButton::Property::BACKGROUND_VISUAL: + { + visual.SetDepthIndex(0.0f); + break; + } + case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL: + { + visual.SetDepthIndex(1.0f); + break; + } + case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL: + { + visual.SetDepthIndex(2.0f); + break; + } + case Demo::ShadowButton::Property::LABEL_VISUAL: + { + visual.SetDepthIndex(1.0f); + break; + } + } + + // Extract transform maps out of the visual definition and store them + Property::Value* value = map->Find( DevelVisual::Property::TRANSFORM, "transform"); + if( value ) + { + Property::Map* transformMap = value->GetMap(); + if( transformMap ) + { + ShadowButton::Transforms::iterator iter = FindTransform( index ); + if( iter != mTransforms.end() ) + { + iter->mTransform = *transformMap; + } + else + { + mTransforms.push_back( Transform( index, *transformMap ) ); + } + } + } + } +} + +bool IsTransformProperty( const std::string& property ) +{ + const char* transformProperties[]= { "size", "offset", "origin", "anchorPoint", "offsetSizeMode" }; + const int NUM_TRANSFORM_PROPERTIES = sizeof( transformProperties ) / sizeof( const char * ); + + bool found=false; + for( int i=0; i{animator{"property"}} = animator{"targetValue"} + + + for( unsigned int i=0; i < transitionData.Count(); ++i ) + { + Property::Map animator = transitionData.GetAnimatorAt(i); + Property::Value* target = animator.Find( "target" ); + if( target ) + { + // Convert to index + Property::Index index; + if( Scripting::GetEnumerationProperty( *target, VISUAL_PROPERTIES_TABLE, VISUAL_PROPERTIES_TABLE_COUNT, index ) ) + { + ShadowButton::Transforms::iterator iter = FindTransform( index ); + if( iter != mTransforms.end() ) + { + Property::Value* property = animator.Find( "property" ); + if( property ) + { + std::string propertyString; + property->Get(propertyString); + if( IsTransformProperty( propertyString ) ) + { + Property::Value* targetValue = animator.Find( "targetValue" ); + if( targetValue ) + { + iter->mTransform[ propertyString ] = *targetValue; + } + } + } + } + } + } + } +} + +void ShadowButton::ResetTransition( + Property::Index index, + const Property::Value& value) +{ + ShadowButton::Transitions::iterator iter = FindTransition( index ); + if( iter != mTransitions.end() ) + { + // Already exists + iter->mTransitionData = ConvertPropertyToTransition( value ); + iter->mAnimation.Stop(); + iter->mAnimation.Clear(); + } + else + { + mTransitions.push_back( Transition( index, ConvertPropertyToTransition( value ) ) ); + } +} + + +void ShadowButton::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value ) +{ + Demo::ShadowButton shadowButton = Demo::ShadowButton::DownCast( Dali::BaseHandle( object ) ); + + if( shadowButton ) + { + ShadowButton& impl = GetImpl( shadowButton ); + switch ( index ) + { + case Demo::ShadowButton::Property::BACKGROUND_VISUAL: + { + impl.ResetVisual( index, impl.mBackgroundVisual, value ); + break; + } + case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL: + { + impl.ResetVisual( index, impl.mCheckboxBgVisual, value ); + break; + } + case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL: + { + impl.ResetVisual( index, impl.mCheckboxFgVisual, value ); + impl.EnableVisual( Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL, impl.mCheckState ); + break; + } + case Demo::ShadowButton::Property::LABEL_VISUAL: + { + impl.ResetVisual( index, impl.mLabelVisual, value ); + break; + } + case Demo::ShadowButton::Property::ACTIVE_TRANSITION: + case Demo::ShadowButton::Property::INACTIVE_TRANSITION: + case Demo::ShadowButton::Property::CLICK_TRANSITION: + { + impl.ResetTransition( index, value ); + break; + } + } + } +} + +Property::Value ShadowButton::GetProperty( BaseObject* object, Property::Index propertyIndex ) +{ + Property::Value value; + + Demo::ShadowButton shadowButton = Demo::ShadowButton::DownCast( Dali::BaseHandle( object ) ); + + if ( shadowButton ) + { + ShadowButton& impl = GetImpl( shadowButton ); + switch ( propertyIndex ) + { + case Demo::ShadowButton::Property::BACKGROUND_VISUAL: + { + Property::Map map; + impl.mBackgroundVisual.CreatePropertyMap(map); + value = map; + break; + } + case Demo::ShadowButton::Property::CHECKBOX_BG_VISUAL: + { + Property::Map map; + impl.mCheckboxBgVisual.CreatePropertyMap(map); + value = map; + break; + } + case Demo::ShadowButton::Property::CHECKBOX_FG_VISUAL: + { + Property::Map map; + impl.mCheckboxFgVisual.CreatePropertyMap(map); + value = map; + break; + } + case Demo::ShadowButton::Property::LABEL_VISUAL: + { + Property::Map map; + impl.mLabelVisual.CreatePropertyMap(map); + value = map; + break; + } + + default: + break; + } + } + + return value; +} + + +} // Internal +} // Demo diff --git a/examples/transitions/shadow-button-impl.h b/examples/transitions/shadow-button-impl.h new file mode 100644 index 0000000..cbf146e --- /dev/null +++ b/examples/transitions/shadow-button-impl.h @@ -0,0 +1,220 @@ +#ifndef DALI_DEMO_INTERNAL_SHADOW_BUTTON_IMPL_H +#define DALI_DEMO_INTERNAL_SHADOW_BUTTON_IMPL_H + +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "shadow-button.h" +#include +#include +#include +#include + +namespace Demo +{ + +namespace Internal // To use TypeRegistry, handle and body classes need the same name +{ + +class ShadowButton : public Dali::Toolkit::Internal::Control +{ +public: + /** + * Instantiate a new ShadowButton object + */ + static Demo::ShadowButton New(); + ShadowButton(); + ~ShadowButton(); + +public: // API + /** + * @brief Set the button to be active or inactive. + * + * The button will perform a transition if there is a state change. + * @param[in] active The active state + */ + void SetActiveState( bool active ); + + /** + * Get the active state + * @return the active state + */ + bool GetActiveState(); + + /** + * Set the check state + * @param[in] checkState The state of the checkbox + */ + void SetCheckState( bool checkState ); + + /** + * Get the check state + * @return the check state + */ + bool GetCheckState(); + +public: // Properties + /** + * Called when a property of an object of this type is set. + * @param[in] object The object whose property is set. + * @param[in] index The property index. + * @param[in] value The new property value. + */ + static void SetProperty( Dali::BaseObject* object, Dali::Property::Index index, const Dali::Property::Value& value ); + + /** + * Called to retrieve a property of an object of this type. + * @param[in] object The object whose property is to be retrieved. + * @param[in] index The property index. + * @return The current value of the property. + */ + static Dali::Property::Value GetProperty( Dali::BaseObject* object, Dali::Property::Index propertyIndex ); + +private: // From Control + /** + * @copydoc Toolkit::Button::OnInitialize() + */ + virtual void OnInitialize(); + + /** + * @copydoc Toolkit::Button::OnStageConnect() + */ + virtual void OnStageConnection( int depth ); + + /** + * @copydoc Toolkit::Button::OnStageDisconnection() + */ + virtual void OnStageDisconnection(); + + /** + * @copydoc Toolkit::Button::OnSizeSet() + */ + virtual void OnSizeSet( const Dali::Vector3& targetSize ); + + /** + * @copydoc Toolkit::Button::OnRelayout() + */ + virtual void OnRelayout( const Dali::Vector2& targetSize, Dali::RelayoutContainer& container ); + /** + * @copydoc Toolkit::Button::GetNaturalSize + */ + virtual Dali::Vector3 GetNaturalSize(); + + /** + * @copydoc Toolkit::Button::OnStyleChange + */ + virtual void OnStyleChange( Dali::Toolkit::StyleManager styleManager, Dali::StyleChange::Type change ); + +private: + struct Transition + { + Dali::Property::Index mTransitionId; + Dali::Toolkit::TransitionData mTransitionData; + Dali::Animation mAnimation; + bool mPlaying; + + Transition( Dali::Property::Index index, Dali::Toolkit::TransitionData transitionData ) + : mTransitionId( index ), + mTransitionData( transitionData ), + mPlaying(false) + { + } + private: + Transition(); + }; + + typedef std::vector Transitions; + + struct Transform + { + Dali::Property::Index mTransformId; + Dali::Property::Map mTransform; + + Transform( Dali::Property::Index index, Dali::Property::Map& map ) + : mTransformId(index), + mTransform( map ) + { + } + }; + typedef std::vector Transforms; + +private: + void StartTransition( Dali::Property::Index transitionId ); + + void OnTransitionFinished( Dali::Animation& handle ); + + Transitions::iterator FindTransition( Dali::Property::Index index ); + + Transforms::iterator FindTransform( Dali::Property::Index index ); + + /** + * Relayout the visuals as a result of size negotiation using + * the transforms provided in the stylesheet + */ + void RelayoutVisuals( const Dali::Vector2& targetSize ); + + /** + * Relayout the visuals as a result of size negotiation using + * programmatically generated transforms + */ + void RelayoutVisualsManually( const Dali::Vector2& targetSize ); + + void ResetVisual( Dali::Property::Index index, + Dali::Toolkit::Visual::Base& visual, + const Dali::Property::Value& value ); + + void ResetTransition( Dali::Property::Index index, + const Dali::Property::Value& value ); + + void StoreTargetLayouts( Dali::Toolkit::TransitionData transitionData ); + +private: + // undefined + ShadowButton( const ShadowButton& ); + ShadowButton& operator=( const ShadowButton& ); + +private: + // Data + Dali::Toolkit::Visual::Base mBackgroundVisual; + Dali::Toolkit::Visual::Base mCheckboxBgVisual; + Dali::Toolkit::Visual::Base mCheckboxFgVisual; + Dali::Toolkit::Visual::Base mLabelVisual; + + Transitions mTransitions; + Transforms mTransforms; + bool mCheckState; + bool mActiveState; +}; + +} // Internal + +inline Internal::ShadowButton& GetImpl( Demo::ShadowButton& handle ) +{ + DALI_ASSERT_ALWAYS( handle ); + Dali::RefObject& object = handle.GetImplementation(); + return static_cast(object); +} + +inline const Internal::ShadowButton& GetImpl( const Demo::ShadowButton& handle ) +{ + DALI_ASSERT_ALWAYS( handle ); + const Dali::RefObject& object = handle.GetImplementation(); + return static_cast(object); +} + +} // Demo + +#endif // DALI_DEMO_SHADOW_BUTTON_IMPL_H diff --git a/examples/transitions/shadow-button.cpp b/examples/transitions/shadow-button.cpp new file mode 100644 index 0000000..13de599 --- /dev/null +++ b/examples/transitions/shadow-button.cpp @@ -0,0 +1,94 @@ +/* + * 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 "shadow-button.h" +#include "shadow-button-impl.h" + +namespace Demo +{ + +ShadowButton::ShadowButton() +{ +} + +ShadowButton::ShadowButton( const ShadowButton& control ) +: Control( control ) +{ +} + +ShadowButton& ShadowButton::operator= ( const ShadowButton& rhs ) +{ + if( &rhs != this ) + { + Control::operator=( rhs ); + } + return *this; +} + +ShadowButton::~ShadowButton() +{ +} + +ShadowButton ShadowButton::New() +{ + ShadowButton control = Internal::ShadowButton::New(); + return control; +} + +ShadowButton ShadowButton::New( const std::string& url ) +{ + ShadowButton control = Internal::ShadowButton::New(); + return control; +} + +ShadowButton ShadowButton::DownCast( BaseHandle handle ) +{ + return Control::DownCast< ShadowButton, Internal::ShadowButton > ( handle ); +} + +void ShadowButton::SetActiveState( bool active ) +{ + GetImpl(*this).SetActiveState( active ); +} + +bool ShadowButton::GetActiveState() +{ + return GetImpl(*this).GetActiveState(); +} + +void ShadowButton::SetCheckState( bool checkState ) +{ + GetImpl(*this).SetCheckState( checkState ); +} + +bool ShadowButton::GetCheckState() +{ + return GetImpl(*this).GetCheckState(); +} + +ShadowButton::ShadowButton( Internal::ShadowButton& implementation ) +: Control( implementation ) +{ +} + +ShadowButton::ShadowButton( Dali::Internal::CustomActor* internal ) +: Control( internal ) +{ + VerifyCustomActorPointer< Internal::ShadowButton >( internal ) ; +} + + +} //namespace Demo diff --git a/examples/transitions/shadow-button.h b/examples/transitions/shadow-button.h new file mode 100644 index 0000000..4df3e27 --- /dev/null +++ b/examples/transitions/shadow-button.h @@ -0,0 +1,148 @@ +#ifndef DALI_DEMO_SHADOW_BUTTON_H +#define DALI_DEMO_SHADOW_BUTTON_H + +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +namespace Demo +{ + +// All type registered controls need to have the same name for the body +// and the handle +namespace Internal +{ +class ShadowButton; +} + +/** + * Button that allows the RGB channels of an image to be altered. + */ +class ShadowButton : public Dali::Toolkit::Control +{ +public: + /** + * The start and end property ranges for this Control + */ + enum PropertyRange + { + PROPERTY_START_INDEX = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1, + PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000, + ANIMATABLE_PROPERTY_START_INDEX = Dali::ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX, + ANIMATABLE_PROPERTY_END_INDEX = ANIMATABLE_PROPERTY_START_INDEX+1000 + }; + + struct Property + { + enum + { + ACTIVE_TRANSITION = PROPERTY_START_INDEX, + INACTIVE_TRANSITION, + CLICK_TRANSITION, + BACKGROUND_VISUAL, + CHECKBOX_BG_VISUAL, + CHECKBOX_FG_VISUAL, + LABEL_VISUAL, + ACTIVE_STATE, + CHECK_STATE, + }; + }; + +public: // Construction / destruction + + /** + * Create an uninitialized handle + */ + ShadowButton(); + + /** + * Create a new image channel button without an image. Use + * SetImage to give this button an image + */ + static ShadowButton New(); + + /** + * Create a new image channel button from a given URL + */ + static ShadowButton New( const std::string& url ); + + /** + * Destructor. This is non-virtual since derived Handle types must not + * contain data or virtual methods + */ + ~ShadowButton(); + + /** + * Copy Constructor + */ + ShadowButton( const ShadowButton& shadowButton ); + + /** + * Assignment Operator + */ + ShadowButton& operator=( const ShadowButton& shadowButton ); + + /** + * Downcast + */ + static ShadowButton DownCast( BaseHandle handle ); + +public: // API + + /** + * @brief Set the button to be active or inactive. + * + * The button will perform a transition if there is a state change. + * @param[in] active The active state + */ + void SetActiveState( bool active ); + + /** + * @brief Get the button's active state + * + * @return The active state + */ + bool GetActiveState(); + + /** + * Set the check state + * @param[in] checkState The state of the checkbox + */ + void SetCheckState( bool checkState ); + + /** + * Get the check state + * @return the check state + */ + bool GetCheckState(); + +public: // Not for public use + /** + * Create a handle from an implementation + */ + ShadowButton( Internal::ShadowButton& implementation ); + + /** + * Allow the creation of an ShadowButton handle from an internal CustomActor pointer + */ + ShadowButton( Dali::Internal::CustomActor* internal ); +}; + +} // namespace Demo + +#endif // DALI_DEMO_SHADOW_BUTTON_H diff --git a/examples/transitions/transition-application.cpp b/examples/transitions/transition-application.cpp index cf4312b..03799bf 100644 --- a/examples/transitions/transition-application.cpp +++ b/examples/transitions/transition-application.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -24,7 +24,9 @@ // External includes #include -#include "beat-control.h" +#include +#include +#include "shadow-button.h" #include #include @@ -33,16 +35,27 @@ using namespace Dali; using namespace Dali::Toolkit; +namespace +{ + +void SetLabelText( Button button, const char* label ) +{ + button.SetProperty( Toolkit::Button::Property::LABEL, label ); +} + +} + namespace Demo { const char* TransitionApplication::DEMO_THEME_ONE_PATH( DEMO_STYLE_DIR "style-example-theme-one.json" ); +const char* TransitionApplication::DEMO_THEME_TWO_PATH( DEMO_STYLE_DIR "style-example-theme-two.json" ); TransitionApplication::TransitionApplication( Application& application ) : mApplication( application ), mTitle(), - mBeatControl(), + mShadowButton(), mActionButtons(), mActionIndex( Property::INVALID_INDEX ) { @@ -68,8 +81,8 @@ void TransitionApplication::Create( Application& application ) contentLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); contentLayout.SetAnchorPoint( AnchorPoint::TOP_LEFT ); contentLayout.SetParentOrigin( ParentOrigin::TOP_LEFT ); - contentLayout.SetCellPadding( Size( 10, 10 ) ); - + contentLayout.SetCellPadding( Vector2( 0.0f, 5.0f ) ); + contentLayout.SetBackgroundColor( Vector4(0.949, 0.949, 0.949, 1.0) ); // Assign all rows the size negotiation property of fitting to children stage.Add( contentLayout ); @@ -77,63 +90,58 @@ void TransitionApplication::Create( Application& application ) mTitle = TextLabel::New( "Custom Control Transition Example" ); mTitle.SetName( "Title" ); mTitle.SetStyleName("Title"); - mTitle.SetAnchorPoint( AnchorPoint::TOP_CENTER ); - mTitle.SetParentOrigin( ParentOrigin::TOP_CENTER ); mTitle.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); mTitle.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT ); mTitle.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); contentLayout.Add( mTitle ); - contentLayout.SetFitHeight(0); - - mBeatControl = BeatControl::New(); - mBeatControl.SetName("BeatControl"); - mBeatControl.SetAnchorPoint( AnchorPoint::CENTER ); - mBeatControl.SetParentOrigin( ParentOrigin::CENTER ); - mBeatControl.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); - contentLayout.Add( mBeatControl ); - // beat control should fill the tableview cell, so no change to default parameters - - TableView actionButtonLayout = TableView::New( 1, 4 ); + contentLayout.SetFitHeight(0); // Fill width + + // Provide some padding around the center cell + TableView buttonLayout = TableView::New( 3, 3 ); + buttonLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); + buttonLayout.SetFixedHeight(1, 100 ); + buttonLayout.SetFixedWidth(1, 350 ); + contentLayout.Add( buttonLayout ); + + mShadowButton = ShadowButton::New(); + mShadowButton.SetName("ShadowButton"); + mShadowButton.SetActiveState( false ); + mShadowButton.SetCheckState( false ); + mShadowButton.SetAnchorPoint( AnchorPoint::CENTER ); + mShadowButton.SetParentOrigin( ParentOrigin::CENTER ); + mShadowButton.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); + buttonLayout.AddChild( mShadowButton, TableView::CellPosition(1, 1) ); + + TableView actionButtonLayout = TableView::New( 1, NUMBER_OF_ACTION_BUTTONS+1 ); actionButtonLayout.SetName("ThemeButtonsLayout"); - actionButtonLayout.SetCellPadding( Vector2( 6.0f, 0.0f ) ); - - actionButtonLayout.SetAnchorPoint( AnchorPoint::CENTER ); - actionButtonLayout.SetParentOrigin( ParentOrigin::CENTER ); actionButtonLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); actionButtonLayout.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT ); - actionButtonLayout.SetCellPadding( Size( 10, 10 ) ); actionButtonLayout.SetFitHeight( 0 ); TextLabel label = TextLabel::New( "Action: "); label.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS ); label.SetStyleName("ActionLabel"); - label.SetAnchorPoint( AnchorPoint::TOP_CENTER ); - label.SetParentOrigin( ParentOrigin::TOP_CENTER ); actionButtonLayout.AddChild( label, TableView::CellPosition( 0, 0 ) ); actionButtonLayout.SetCellAlignment( TableView::CellPosition( 0, 0 ), HorizontalAlignment::LEFT, VerticalAlignment::CENTER ); - for( int i=0; i<3; ++i ) + for( int i=0; i( mActionIndex ); @@ -141,17 +149,30 @@ bool TransitionApplication::OnActionButtonClicked( Button button ) { case 0: { - mBeatControl.StartBounceAnimation(); + bool activeState = mShadowButton.GetActiveState(); + mShadowButton.SetActiveState( ! activeState ); + if( activeState ) + { + SetLabelText( button, "Activate" ); + } + else + { + SetLabelText( button, "Deactivate" ); + } break; } case 1: { - mBeatControl.StartXAnimation(); + bool checkState = mShadowButton.GetCheckState(); + mShadowButton.SetCheckState( ! checkState ); break; } case 2: { - mBeatControl.StartYAnimation(); + break; + } + case 3: + { break; } } diff --git a/examples/transitions/transition-application.h b/examples/transitions/transition-application.h index 9d692db..f694c8d 100644 --- a/examples/transitions/transition-application.h +++ b/examples/transitions/transition-application.h @@ -2,7 +2,7 @@ #define DALI_DEMO_TRANSITION_APPLICATION_H /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -19,9 +19,7 @@ // External includes #include -//#include -#include -#include "beat-control.h" +#include "shadow-button.h" #include #include @@ -36,6 +34,9 @@ namespace Demo class TransitionApplication : public ConnectionTracker { public: + static const int NUMBER_OF_ACTION_BUTTONS=2; + +public: // Constructor TransitionApplication( Application& application ); @@ -52,15 +53,24 @@ public: // Key event handler void OnKeyEvent( const KeyEvent& event ); - bool OnActionButtonClicked(Button button); + bool OnActionButtonClicked( Button button ); static const char* DEMO_THEME_ONE_PATH; + static const char* DEMO_THEME_TWO_PATH; private: + + /** Create a visual map + * + * @param[in] index The index of the visual to create + * @param[out] map The map to generate + */ + Application& mApplication; TextLabel mTitle; - BeatControl mBeatControl; - PushButton mActionButtons[3]; + ShadowButton mShadowButton; + PushButton mActionButtons[NUMBER_OF_ACTION_BUTTONS]; + Property::Index mVisualIndex; Property::Index mActionIndex; }; diff --git a/examples/transitions/transition-example.cpp b/examples/transitions/transition-example.cpp index adc4563..9bf3cd2 100644 --- a/examples/transitions/transition-example.cpp +++ b/examples/transitions/transition-example.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. diff --git a/resources/images/preMultAlpha.png b/resources/images/preMultAlpha.png new file mode 100644 index 0000000000000000000000000000000000000000..3cf8ab1e5359a50e58c16712e5f1afc0373fed5a GIT binary patch literal 4615 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 XRF-I&NzzAu00000NkvXXu0mjfI>kK9 literal 0 HcmV?d00001 diff --git a/resources/style/images/Tick.png b/resources/style/images/Tick.png new file mode 100644 index 0000000000000000000000000000000000000000..72bf93e73b7ab4b0f74e86389c13ac24189e2df9 GIT binary patch literal 1713 zcmV;i22S~jP)VGd000McNliru;0zTHCMOjyiu?co02y>e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00tRJL_t(o!_}DIZ&T+P$G_)2 zK0h2g4lSx3JN|KOOhOT;WuaMFBGQ#XgVIhaxuD&}q)p0I)tg@KFId%TS5q$r+NAZS zl}M4MEsDVN0MmBR(4deOImv8e$3K(c#CCjqj?a1DUeLfwp(O+d`bfTd&-?hJufFf| zzR$xk#_&@Mf}ddAhNhIlG|iU&+1lC~>h(HQRfVqWKlts{bQ&oD|BOVww`N%fHVgxr zra{v*G@DIOO3@1Ia2y9h2zZ`{)9L))dODp(#plPR2LIQo=;ZJAJ>B)UjN1IY&nn!> zK`BME*@UX9XfzrS1Oc)vgXj5{DNZSc)oR6w6DQzsIB@*<@!M;US9>+GOi@JyAC{0#8&a#%AW(;z}9PQuQxo zP5%vc`hU5nUEZ*V-M<>bxl}P1O=R7xst%FxP$YswzGsGi9#+QbVjesD`ZoVGrHsK~ z40R$PZvvm+$h{Per()B!jd{g=WC+p!<&qa?6Yi3#LjXfSA~+ZhygA?y#^=tRg-AE{ zy1WI=ef#^r*y-SL?73YozoQKt;ZdN#x%|>VB%YYRw%T~0Iy`LxXJ@n3|D+a_B~6C} zilEG6IM{jk@Gk#He!m|>Lqm_Q3Gf2wb=gXmycgb=ft9_!;V`w-9W(eM!(-3^F4x_ z;ek?wI6!yV&vLZu*m-7t@^!g}tY+XsVdWK*q$jzsfB(~V2{$PaoiD^=nPT_NwFV>( z2-{^0`a2Kq_j_VK>Hc-N(P%)Hd0t1YPs^>_Ie_{T3f?PO@+Yo2)2nB^gc7(=XZ}Q(!Gz)!}g#XcGzwL@SdkWG&thX z5}7}ym&(ZL3~ccx0HB=%yjB4R0-f*tB5;4;mV5f{=-~l)JKhx-OPy&pKe}Gk05I@i z=n^;_>e@cqAM~A6q}DVQ4}F$<0PtPgK5np}uR1gL-de2!n=IjlF6U=2?NmIv(SRgL8&dik6T+<8qppkK00000NkvXX Hu0mjfc)vF+ literal 0 HcmV?d00001 diff --git a/resources/style/images/shadowButtonBg.9.png b/resources/style/images/shadowButtonBg.9.png new file mode 100644 index 0000000000000000000000000000000000000000..996f9652e8bd25d26727c94dd52436a12918933c GIT binary patch literal 1600 zcmV-G2EX}7UTz zA5i*Ug3vGWP)bc&Y77P47OF8e8kKA*eH4)dndhoSjXZ;)To1?%bW3 z-=42~&$$3Q-#9#P*)_~yEDG09G9E1@$`#-7Ml=Ca!l42VC6F>`3M2b0gXFG|m=aC} zrs^gMnz{_!3et0c(*ZHXIVx0`Yv5wVxk^P*2Z@ewOgK^?Mmh@PWs($MJQje&E&~SP z$W4;;9Gnb=s~>X&EGHSm6cVHmF#tpa5`=4v9F5JhlpadpM4+4imLu0}07WP!fJQ`O z;&rr9RT~>rsiFwvkz-CFO|en6jD#L4Oav4X1Q;B3eO@;Q2SHCwbmi~2aojh^}Rm+Vxc(VdHzd?=u0C!=Rp_*531F*8~5)o z&D^`QSSEI>n$p$nkV~X!jDw=bq&7#@u@2S>0Im6a+Y2WqPMt4ybWTj3dJD&nk6Oi_ zx%m=&`SrKFvi8^P_diU3x>2dD1HcoZ*AmHw!ZFf>6r)pN2}BD3Q1As#Sa0CF3=JRc1lcztpdHKpUp0-`Sa*a>E^Zu=TzHJNujwbg$lsv0Dd3I;= zE^W!XwIuHsQT; z#%7MXWp-i{=w%_o2LQi+V5p~~W8aBJ;OcGc_$U-R_Ko)s4D|>$t_nNGX(zJ)Qw8~_ zHrd-ZIDYobNtV?j_3W9GthaA)T(EZ;9Mde(j1r{w2%71cSJ+b=J~ld%*(&_l=m-?{ z6o&~Mo%4dq?rc>Q$v9L@(LB%dyRuF-B=;0!sc!0rwkm20^wOY@h+fu!$vvs`bZbs) z38I5nWeQK6Rm(}9$24H*B0F0fU{nutALnhi6qWL zo7Gy#Q-zINl@~Z&g{1r*Sg$ zN3!bA(}Zmp1`o0Z48!1|kPwc@v#E1)PC8LH4J7}#rBJe7S-WwybUib;tEKButyUIE z{!^9%ja_Y!TZ9A=Fa&_0T)s0ib#Xc~Z#s2xIxer=zNAU=>Ou#%RZ$A6ssshgOAF=I z)km{)^QDI2=H^SVy838#d1;{x&uSHs#?ffwp(*i;V6Mp{0N|g0ly7d6$sCUpAQ<4b{TX2x@ZVSN{`7b~DE>HCI=FXl z5nt_o#oFdRy6_4Ax%A8I%*VGd000McNliru;0zTH8ZT%Edoch202y>e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00dP@L_t(o!_AjZZ_`K^#-Evt z~a)rt?n7l2Q|g-dT7IIg(C0hX@RDq^cd zq@q>RCUNZ4acpPCGka-QECTIiTlXi;!9L79e%{ybW0N~~?v$=yzpiau?BuArBg73gNSDL1g<7?0JR2;{uR4New*xTEauItLVxw(wz zc`^(`b^G>h9RQv@dD3M7P_Nf>mSu6J6m7TLoKi~n_xF>9g$1)-uN&2BHD4?i^OMOW z27rFQKelZ<2LRjK+oM*i6&i*?g%AJ$UDs*3T*l(!Vs1DbasVh43L;68q}^`Ex~|iW zjg8najA^6M&;Wq-dOi8##f!s-4j${pZi0H+#LF1OO~8Em@0;i}wBd_ZQmj_Ol=e5-FvU zQmT`Hb1q%i<)1%)e%)*~e|_-aK?MMqX_|CrXNNp`^k}tOt^TI#IytuZBp`$k(=?fs z^5;w@Q@(fa-tRA8zUG1VPa1cDn-rpswqxTCIjK43k!?_3WfeL2T3E|YvdKfZYJVz|D(J`_Ui zce`Ec`@ZlzFFDF0!WbjDT#k&#W9j>TB7{(`>;BVNwrx|!7|}G1gkdNFAP53^tcwt$ zE?l@kq9{^3J3EJsMgtog8v+2>+qZAyUau#8-;YP5k#b#EIgaBVZ*Ex@snu#U2m<9e z&cC8yG#aU|8j$F^P5@wbc9sA@KA$HmD=Vy4t7(ieqU$;>l}h^i_wS);8j0hW;4JYs XRF-I&NzzAu00000NkvXXu0mjfI>kK9 literal 0 HcmV?d00001 diff --git a/resources/style/mobile/images/Tick.png b/resources/style/mobile/images/Tick.png new file mode 100644 index 0000000000000000000000000000000000000000..72bf93e73b7ab4b0f74e86389c13ac24189e2df9 GIT binary patch literal 1713 zcmV;i22S~jP)VGd000McNliru;0zTHCMOjyiu?co02y>e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00tRJL_t(o!_}DIZ&T+P$G_)2 zK0h2g4lSx3JN|KOOhOT;WuaMFBGQ#XgVIhaxuD&}q)p0I)tg@KFId%TS5q$r+NAZS zl}M4MEsDVN0MmBR(4deOImv8e$3K(c#CCjqj?a1DUeLfwp(O+d`bfTd&-?hJufFf| zzR$xk#_&@Mf}ddAhNhIlG|iU&+1lC~>h(HQRfVqWKlts{bQ&oD|BOVww`N%fHVgxr zra{v*G@DIOO3@1Ia2y9h2zZ`{)9L))dODp(#plPR2LIQo=;ZJAJ>B)UjN1IY&nn!> zK`BME*@UX9XfzrS1Oc)vgXj5{DNZSc)oR6w6DQzsIB@*<@!M;US9>+GOi@JyAC{0#8&a#%AW(;z}9PQuQxo zP5%vc`hU5nUEZ*V-M<>bxl}P1O=R7xst%FxP$YswzGsGi9#+QbVjesD`ZoVGrHsK~ z40R$PZvvm+$h{Per()B!jd{g=WC+p!<&qa?6Yi3#LjXfSA~+ZhygA?y#^=tRg-AE{ zy1WI=ef#^r*y-SL?73YozoQKt;ZdN#x%|>VB%YYRw%T~0Iy`LxXJ@n3|D+a_B~6C} zilEG6IM{jk@Gk#He!m|>Lqm_Q3Gf2wb=gXmycgb=ft9_!;V`w-9W(eM!(-3^F4x_ z;ek?wI6!yV&vLZu*m-7t@^!g}tY+XsVdWK*q$jzsfB(~V2{$PaoiD^=nPT_NwFV>( z2-{^0`a2Kq_j_VK>Hc-N(P%)Hd0t1YPs^>_Ie_{T3f?PO@+Yo2)2nB^gc7(=XZ}Q(!Gz)!}g#XcGzwL@SdkWG&thX z5}7}ym&(ZL3~ccx0HB=%yjB4R0-f*tB5;4;mV5f{=-~l)JKhx-OPy&pKe}Gk05I@i z=n^;_>e@cqAM~A6q}DVQ4}F$<0PtPgK5np}uR1gL-de2!n=IjlF6U=2?NmIv(SRgL8&dik6T+<8qppkK00000NkvXX Hu0mjfc)vF+ literal 0 HcmV?d00001 diff --git a/resources/style/mobile/images/shadowButtonBg.9.png b/resources/style/mobile/images/shadowButtonBg.9.png new file mode 100644 index 0000000000000000000000000000000000000000..996f9652e8bd25d26727c94dd52436a12918933c GIT binary patch literal 1600 zcmV-G2EX}7UTz zA5i*Ug3vGWP)bc&Y77P47OF8e8kKA*eH4)dndhoSjXZ;)To1?%bW3 z-=42~&$$3Q-#9#P*)_~yEDG09G9E1@$`#-7Ml=Ca!l42VC6F>`3M2b0gXFG|m=aC} zrs^gMnz{_!3et0c(*ZHXIVx0`Yv5wVxk^P*2Z@ewOgK^?Mmh@PWs($MJQje&E&~SP z$W4;;9Gnb=s~>X&EGHSm6cVHmF#tpa5`=4v9F5JhlpadpM4+4imLu0}07WP!fJQ`O z;&rr9RT~>rsiFwvkz-CFO|en6jD#L4Oav4X1Q;B3eO@;Q2SHCwbmi~2aojh^}Rm+Vxc(VdHzd?=u0C!=Rp_*531F*8~5)o z&D^`QSSEI>n$p$nkV~X!jDw=bq&7#@u@2S>0Im6a+Y2WqPMt4ybWTj3dJD&nk6Oi_ zx%m=&`SrKFvi8^P_diU3x>2dD1HcoZ*AmHw!ZFf>6r)pN2}BD3Q1As#Sa0CF3=JRc1lcztpdHKpUp0-`Sa*a>E^Zu=TzHJNujwbg$lsv0Dd3I;= zE^W!XwIuHsQT; z#%7MXWp-i{=w%_o2LQi+V5p~~W8aBJ;OcGc_$U-R_Ko)s4D|>$t_nNGX(zJ)Qw8~_ zHrd-ZIDYobNtV?j_3W9GthaA)T(EZ;9Mde(j1r{w2%71cSJ+b=J~ld%*(&_l=m-?{ z6o&~Mo%4dq?rc>Q$v9L@(LB%dyRuF-B=;0!sc!0rwkm20^wOY@h+fu!$vvs`bZbs) z38I5nWeQK6Rm(}9$24H*B0F0fU{nutALnhi6qWL zo7Gy#Q-zINl@~Z&g{1r*Sg$ zN3!bA(}Zmp1`o0Z48!1|kPwc@v#E1)PC8LH4J7}#rBJe7S-WwybUib;tEKButyUIE z{!^9%ja_Y!TZ9A=Fa&_0T)s0ib#Xc~Z#s2xIxer=zNAU=>Ou#%RZ$A6ssshgOAF=I z)km{)^QDI2=H^SVy838#d1;{x&uSHs#?ffwp(*i;V6Mp{0N|g0ly7d6$sCUpAQ<4b{TX2x@ZVSN{`7b~DE>HCI=FXl z5nt_o#oFdRy6_4Ax%A8I%*