Commit 8de20f070ca7d370a0b0ca8412ac29804623a016

Authored by Agnelo Vaz
1 parent 544747ea

TextLabel example uses ExpandingButtons

ExpandingButtons control created in demo, to aid re-use in future.
Can move to shared folded if needed in others examples.

Change-Id: I346da472362e17614bc744ff3b7c0417bc3f9fb0
examples/text-label/expanding-buttons-impl.cpp 0 → 100644
  1 +/*
  2 + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +#include <dali-toolkit/dali-toolkit.h>
  18 +#include <dali-toolkit/devel-api/controls/control-devel.h>
  19 +#include <dali-toolkit/devel-api/controls/buttons/button-devel.h>
  20 +#include <dali/public-api/animation/animation.h>
  21 +
  22 +#include "expanding-buttons-impl.h"
  23 +
  24 +using namespace Dali;
  25 +using namespace Dali::Toolkit;
  26 +
  27 +namespace Demo
  28 +{
  29 +namespace Internal
  30 +{
  31 +
  32 +namespace
  33 +{
  34 +
  35 +const unsigned int GAP_BETWEEN_BUTTONS = 3;
  36 +
  37 +const char* const STYLES_IMAGE = DEMO_IMAGE_DIR "FontStyleButton_Main.png";
  38 +const char* const TICK_IMAGE_IMAGE = DEMO_IMAGE_DIR "FontStyleButton_OK_02.png";
  39 +
  40 +/**
  41 + * Unparent the given number of registered controls from the supplied Vector of controls.
  42 + */
  43 +void ResetControls( std::vector< WeakHandle< Control > > controls, unsigned int numberOfButtons )
  44 +{
  45 + for( unsigned int index = 0; index < numberOfButtons; index++)
  46 + {
  47 + Dali::Toolkit::Control control = controls[index].GetHandle();
  48 + UnparentAndReset( control );
  49 + }
  50 +}
  51 +
  52 +} // anonymous namespace
  53 +
  54 +
  55 +Internal::ExpandingButtons::ExpandingButtons()
  56 +: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
  57 + mStyleButtonsHidden( false )
  58 +{
  59 +}
  60 +
  61 +Internal::ExpandingButtons::~ExpandingButtons()
  62 +{
  63 +}
  64 +
  65 +Demo::ExpandingButtons Internal::ExpandingButtons::New()
  66 +{
  67 + IntrusivePtr<Internal::ExpandingButtons> impl = new Internal::ExpandingButtons();
  68 + Demo::ExpandingButtons handle = Demo::ExpandingButtons( *impl );
  69 + impl->Initialize();
  70 + return handle;
  71 +}
  72 +
  73 +void ExpandingButtons::OnInitialize()
  74 +{
  75 + mExpandButton = PushButton::New();
  76 +
  77 + mExpandButton.ClickedSignal().Connect( this, &ExpandingButtons::OnExpandButtonClicked );
  78 + mExpandButton.SetProperty( Button::Property::TOGGLABLE, true );
  79 + mExpandButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, STYLES_IMAGE ); // Default for Styles
  80 + mExpandButton.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, TICK_IMAGE_IMAGE );
  81 + mExpandButton.SetProperty( Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
  82 + Self().Add( mExpandButton );
  83 +}
  84 +
  85 +void ExpandingButtons::OnRelayout( const Dali::Vector2& targetSize, Dali::RelayoutContainer& container )
  86 +{
  87 + mButtonSize = targetSize;
  88 + mExpandButton.SetSize( targetSize );
  89 +}
  90 +
  91 +void ExpandingButtons::RegisterButton( Dali::Toolkit::Control& control )
  92 +{
  93 + mExpandingControls.push_back( control );
  94 +}
  95 +
  96 +void ExpandingButtons::Expand()
  97 +{
  98 + if ( !mExpandCollapseAnimation )
  99 + {
  100 + mExpandCollapseAnimation = Animation::New( 0.2f );
  101 + mExpandCollapseAnimation.FinishedSignal().Connect( this, &ExpandingButtons::OnExpandAnimationFinished );
  102 + }
  103 +
  104 + unsigned int numberOfControls = mExpandingControls.size();
  105 +
  106 + for( unsigned int index = 0; index < numberOfControls; index++ )
  107 + {
  108 + Dali::Toolkit::Control control = mExpandingControls[index].GetHandle();
  109 + if ( control )
  110 + {
  111 + Self().Add( control );
  112 + AlphaFunction focusedAlphaFunction = AlphaFunction( Vector2 ( 0.32f, 0.08f ), Vector2( 0.38f, 1.72f ) );
  113 + mExpandCollapseAnimation.AnimateTo( Property( control, Actor::Property::POSITION_X ), mButtonSize.width + ( mButtonSize.width + GAP_BETWEEN_BUTTONS ) * (index) , focusedAlphaFunction );
  114 + }
  115 + }
  116 + Self().RaiseToTop();
  117 + mStyleButtonsHidden = false;
  118 + mExpandCollapseAnimation.Play();
  119 +}
  120 +
  121 +void ExpandingButtons::OnExpandAnimationFinished( Animation& animation )
  122 +{
  123 + if ( mStyleButtonsHidden )
  124 + {
  125 + unsigned int numberOfControls = mExpandingControls.size();
  126 + ResetControls( mExpandingControls, numberOfControls );
  127 + animation.Clear();
  128 + animation.Reset();
  129 + }
  130 +}
  131 +
  132 +void ExpandingButtons::Collapse()
  133 +{
  134 + Demo::ExpandingButtons handle( GetOwner() );
  135 + mCollapsedSignal.Emit( handle );
  136 +
  137 + mStyleButtonsHidden = true;
  138 + mExpandButton.SetProperty(Button::Property::SELECTED, false );
  139 +
  140 + if ( mExpandCollapseAnimation )
  141 + {
  142 + unsigned int numberOfControls = mExpandingControls.size();
  143 +
  144 + for ( unsigned int index = 0; index < numberOfControls; index++ )
  145 + {
  146 + Dali::Toolkit::Control control = mExpandingControls[index].GetHandle();
  147 + if ( control )
  148 + {
  149 + mExpandCollapseAnimation.AnimateTo( Property( control, Actor::Property::POSITION_X ), 0.0f );
  150 + }
  151 + }
  152 + mExpandCollapseAnimation.Play();
  153 + }
  154 +}
  155 +
  156 +// Hide or show (expand) buttons if expand button pressed
  157 +bool ExpandingButtons::OnExpandButtonClicked( Toolkit::Button button )
  158 +{
  159 + if ( button.GetProperty( Toolkit::Button::Property::SELECTED ).Get<bool>() )
  160 + {
  161 + Expand();
  162 + }
  163 + else
  164 + {
  165 + Collapse();
  166 + }
  167 +
  168 + return true;
  169 +}
  170 +
  171 +
  172 +Demo::ExpandingButtons::ExpandingButtonsSignalType& ExpandingButtons::CollapsingSignal()
  173 +{
  174 + return mCollapsedSignal;
  175 +}
  176 +
  177 +} // Internal
  178 +} // Demo
... ...
examples/text-label/expanding-buttons-impl.h 0 → 100644
  1 +#ifndef DALI_DEMO_INTERNAL_EXPANDING_BUTTONS_IMPL_H
  2 +#define DALI_DEMO_INTERNAL_EXPANDING_BUTTONS_IMPL_H
  3 +
  4 +/*
  5 + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + *
  11 + * http://www.apache.org/licenses/LICENSE-2.0
  12 + *
  13 + * Unless required by applicable law or agreed to in writing, software
  14 + * distributed under the License is distributed on an "AS IS" BASIS,
  15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 + * See the License for the specific language governing permissions and
  17 + * limitations under the License.
  18 + */
  19 +
  20 +#include "expanding-buttons.h"
  21 +#include <dali-toolkit/public-api/controls/control-impl.h>
  22 +#include <dali/public-api/object/weak-handle.h>
  23 +
  24 +namespace Demo
  25 +{
  26 +
  27 +namespace Internal // To use TypeRegistry, handle and body classes need the same name
  28 +{
  29 +
  30 +class ExpandingButtons : public Dali::Toolkit::Internal::Control
  31 +{
  32 +public:
  33 +
  34 + /**
  35 + * Instantiate a new ExpandingButtons object
  36 + */
  37 + static Demo::ExpandingButtons New();
  38 +
  39 + /**
  40 + * Constructor
  41 + */
  42 + ExpandingButtons();
  43 +
  44 + /**
  45 + * Destructor
  46 + */
  47 + ~ExpandingButtons();
  48 +
  49 +public: // API
  50 +
  51 + void RegisterButton( Dali::Toolkit::Control& control );
  52 +
  53 + void Expand();
  54 +
  55 + void Collapse();
  56 +
  57 +public: // Signals
  58 +
  59 + Demo::ExpandingButtons::ExpandingButtonsSignalType& CollapsingSignal();
  60 +
  61 +private: // From Control
  62 +
  63 + /**
  64 + * @copydoc Toolkit::Control::OnInitialize()
  65 + */
  66 + virtual void OnInitialize() override;
  67 +
  68 + /**
  69 + * @copydoc Toolkit::Control::OnRelayout()
  70 + */
  71 + virtual void OnRelayout( const Dali::Vector2& targetSize, Dali::RelayoutContainer& container ) override;
  72 +
  73 +private:
  74 +
  75 + /**
  76 + * Callback when expand or collapse animation ends.
  77 + */
  78 + void OnExpandAnimationFinished( Dali::Animation& animation );
  79 +
  80 + /**
  81 + * Called when the main button clicked.
  82 + */
  83 + bool OnExpandButtonClicked( Dali::Toolkit::Button button );
  84 +
  85 +
  86 +private:
  87 + //undefined
  88 + ExpandingButtons( const ExpandingButtons& );
  89 + ExpandingButtons& operator=( const ExpandingButtons& );
  90 +
  91 +private:
  92 +
  93 + std::vector< Dali::WeakHandle< Dali::Toolkit::Control> > mExpandingControls;
  94 +
  95 + Dali::Animation mExpandCollapseAnimation;
  96 +
  97 + bool mStyleButtonsHidden;
  98 +
  99 + Dali::Size mButtonSize; // Size of the buttons, used in animation calculations.
  100 +
  101 + Dali::Toolkit::PushButton mExpandButton; // Main button that is clicked to expand/collapse.
  102 +
  103 + Demo::ExpandingButtons::ExpandingButtonsSignalType mCollapsedSignal;
  104 +};
  105 +
  106 +} // Internal
  107 +
  108 +inline Internal::ExpandingButtons& GetImpl( Demo::ExpandingButtons& handle )
  109 +{
  110 + DALI_ASSERT_ALWAYS( handle );
  111 + Dali::RefObject& object = handle.GetImplementation();
  112 + return static_cast<Internal::ExpandingButtons&>(object);
  113 +}
  114 +
  115 +inline const Internal::ExpandingButtons& GetImpl( const Demo::ExpandingButtons& handle )
  116 +{
  117 + DALI_ASSERT_ALWAYS( handle );
  118 + const Dali::RefObject& object = handle.GetImplementation();
  119 + return static_cast<const Internal::ExpandingButtons&>(object);
  120 +}
  121 +
  122 +} // Demo
  123 +
  124 +#endif // DALI_DEMO_INTERNAL_EXPANDING_BUTTONS_IMPL_H
... ...
examples/text-label/expanding-buttons.cpp 0 → 100644
  1 +/*
  2 + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +#include "expanding-buttons-impl.h"
  18 +#include "expanding-buttons.h"
  19 +
  20 +namespace Demo
  21 +{
  22 +
  23 +ExpandingButtons::ExpandingButtons()
  24 +{
  25 +}
  26 +
  27 +ExpandingButtons::ExpandingButtons( const ExpandingButtons& expandingButtons )
  28 +: Control( expandingButtons )
  29 +{
  30 +}
  31 +
  32 +ExpandingButtons& ExpandingButtons::operator= ( const ExpandingButtons& rhs )
  33 +{
  34 + if( &rhs != this )
  35 + {
  36 + Control::operator=( rhs );
  37 + }
  38 + return *this;
  39 +}
  40 +
  41 +ExpandingButtons::~ExpandingButtons()
  42 +{
  43 +}
  44 +
  45 +ExpandingButtons ExpandingButtons::New()
  46 +{
  47 + ExpandingButtons expandingButtons = Internal::ExpandingButtons::New();
  48 + return expandingButtons;
  49 +}
  50 +
  51 +ExpandingButtons ExpandingButtons::DownCast( BaseHandle handle )
  52 +{
  53 + return Control::DownCast< ExpandingButtons, Internal::ExpandingButtons > ( handle );
  54 +}
  55 +
  56 +void ExpandingButtons::RegisterButton( Control& control )
  57 +{
  58 + GetImpl(*this).RegisterButton( control );
  59 +}
  60 +
  61 +void ExpandingButtons::Expand()
  62 +{
  63 + GetImpl(*this).Expand();
  64 +}
  65 +void ExpandingButtons::Collapse()
  66 +{
  67 + GetImpl(*this).Collapse();
  68 +}
  69 +
  70 +Demo::ExpandingButtons::ExpandingButtonsSignalType& ExpandingButtons::CollapsingSignal()
  71 +{
  72 + return GetImpl(*this).CollapsingSignal();
  73 +}
  74 +
  75 +ExpandingButtons::ExpandingButtons( Internal::ExpandingButtons& implementation )
  76 +: Control( implementation )
  77 +{
  78 +}
  79 +
  80 +ExpandingButtons::ExpandingButtons( Dali::Internal::CustomActor* internal )
  81 +: Control( internal )
  82 +{
  83 + VerifyCustomActorPointer< Internal::ExpandingButtons >( internal ) ;
  84 +}
  85 +
  86 +
  87 +} //namespace Demo
... ...
examples/text-label/expanding-buttons.h 0 → 100644
  1 +#ifndef DALI_DEMO_EXPANDING_BUTTONS_CONTROL_H
  2 +#define DALI_DEMO_EXPANDING_BUTTONS_CONTROL_H
  3 +
  4 +/*
  5 + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + *
  11 + * http://www.apache.org/licenses/LICENSE-2.0
  12 + *
  13 + * Unless required by applicable law or agreed to in writing, software
  14 + * distributed under the License is distributed on an "AS IS" BASIS,
  15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 + * See the License for the specific language governing permissions and
  17 + * limitations under the License.
  18 + */
  19 +
  20 +#include <dali-toolkit/dali-toolkit.h>
  21 +
  22 +namespace Demo
  23 +{
  24 +
  25 +namespace Internal
  26 +{
  27 +class ExpandingButtons;
  28 +}
  29 +
  30 +/**
  31 + * Control which toggles between showing and hiding a set of buttons.
  32 + */
  33 +class ExpandingButtons : public Dali::Toolkit::Control
  34 +{
  35 +
  36 +
  37 +public: // Construction / destruction
  38 +
  39 + /**
  40 + * Create an uninitialized handle
  41 + */
  42 + ExpandingButtons();
  43 +
  44 + /**
  45 + * Create an ExpandingButton control with the default pressed and released visual.
  46 + */
  47 + static ExpandingButtons New();
  48 +
  49 + /**
  50 + * Destructor. This is non-virtual since derived Handle types must not
  51 + * contain data or virtual methods
  52 + */
  53 + ~ExpandingButtons();
  54 +
  55 + /**
  56 + * Copy Constructor
  57 + */
  58 + ExpandingButtons( const ExpandingButtons& expandingButtons );
  59 +
  60 + /**
  61 + * Assignment Operator
  62 + */
  63 + ExpandingButtons& operator=( const ExpandingButtons& expandingButtons );
  64 +
  65 + /**
  66 + * Downcast
  67 + */
  68 + static ExpandingButtons DownCast( BaseHandle handle );
  69 +
  70 +public: // API
  71 +
  72 + /**
  73 + * Add a control (button) to the Expanding button bar. Will be displayed in order of addition.
  74 + */
  75 + void RegisterButton( Control& control );
  76 +
  77 + /**
  78 + * Expand the registered buttons out from the main button.
  79 + */
  80 + void Expand();
  81 +
  82 + /**
  83 + * Collapse the expanded buttons back behind the main button.
  84 + */
  85 + void Collapse();
  86 +
  87 +public: // Signals
  88 +
  89 + /**
  90 + * ExpandingButtons signal type
  91 + */
  92 + typedef Dali::Signal< bool ( ExpandingButtons ) > ExpandingButtonsSignalType;
  93 +
  94 + /**
  95 + * This signal is emitted when the button is going to collapse.
  96 + */
  97 + ExpandingButtonsSignalType& CollapsingSignal();
  98 +
  99 +public: // Not for public use
  100 +
  101 + /**
  102 + * Create a handle from an implementation
  103 + */
  104 + ExpandingButtons( Internal::ExpandingButtons& implementation );
  105 +
  106 + /**
  107 + * Allow the creation of an ExpandingButtons handle from an internal CustomActor pointer
  108 + */
  109 + ExpandingButtons( Dali::Internal::CustomActor* internal );
  110 +};
  111 +
  112 +} // namespace Demo
  113 +
  114 +#endif // DALI_DEMO_EXPANDING_BUTTONS_CONTROL_H
... ...
examples/text-label/text-label-example.cpp
1 1 /*
2   - * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  2 + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3 3 *
4 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 5 * you may not use this file except in compliance with the License.
... ... @@ -17,7 +17,7 @@
17 17  
18 18 /**
19 19 * @file text-label-example.cpp
20   - * @brief Basic usage of TextLabel control
  20 + * @brief Usage of TextLabel control with style application.
21 21 */
22 22  
23 23 // EXTERNAL INCLUDES
... ... @@ -30,6 +30,7 @@
30 30 // INTERNAL INCLUDES
31 31 #include "shared/multi-language-strings.h"
32 32 #include "shared/view.h"
  33 +#include "expanding-buttons.h"
33 34  
34 35 using namespace Dali;
35 36 using namespace Dali::Toolkit;
... ... @@ -38,8 +39,6 @@ using namespace MultiLanguageStrings;
38 39 namespace
39 40 {
40 41 const char* const BACKGROUND_IMAGE = DEMO_IMAGE_DIR "grab-handle.png";
41   -const char* const STYLES_IMAGE = DEMO_IMAGE_DIR "FontStyleButton_Main.png";
42   -const char* const TICK_IMAGE_IMAGE = DEMO_IMAGE_DIR "FontStyleButton_OK_02.png";
43 42 const char* const STYLE_SELECTED_IMAGE = DEMO_IMAGE_DIR "FontStyleButton_OK_03.png";
44 43  
45 44 const char* BUTTON_IMAGES[] =
... ... @@ -93,7 +92,8 @@ const Vector4 AVAILABLE_COLORS[] =
93 92 Color::GREEN,
94 93 Color::BLUE,
95 94 Color::RED,
96   - Color::CYAN
  95 + Color::CYAN,
  96 + Color::WHITE // Used as clear
97 97 };
98 98  
99 99 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;
133 133 const float BUTTON_SIZE_RATIO_TO_STAGE = 0.1f;
134 134 const float OUTLINE_WIDTH = 2.0f;
135 135 const Vector2 SHADOW_OFFSET = Vector2( 2.0f, 2.0f );
  136 +const int GAP_BETWEEN_BUTTONS = 3;
136 137  
137 138  
138 139 } // anonymous namespace
... ... @@ -147,9 +148,8 @@ public:
147 148 TextLabelExample( Application& application )
148 149 : mApplication( application ),
149 150 mLabel(),
150   - mShadowActive( false ),
151   - mOutlineActive( false ),
152 151 mSelectedColor(AVAILABLE_COLORS[0]),
  152 + mStyleActivatedForColor( NUMBER_OF_STYLES ),
153 153 mContainer(),
154 154 mGrabCorner(),
155 155 mBorder(),
... ... @@ -158,11 +158,19 @@ public:
158 158 mLanguageId( 0u ),
159 159 mAlignment( 0u ),
160 160 mHueAngleIndex( Property::INVALID_INDEX ),
161   - mOverrideMixColorIndex( Property::INVALID_INDEX )
162   -
  161 + mOverrideMixColorIndex( Property::INVALID_INDEX ),
  162 + mColorButtonsHidden( true ),
  163 + mCollapseColorsAndStyles( false )
163 164 {
164 165 // Connect to the Application's Init signal
165 166 mApplication.InitSignal().Connect( this, &TextLabelExample::Create );
  167 +
  168 + // Set Style flags to inactive
  169 + for ( unsigned int i = OUTLINE; i < NUMBER_OF_STYLES; i++ )
  170 + {
  171 + mStyleActiveState[ i ] = false;
  172 + mCurrentStyleColor[i] = AVAILABLE_COLORS[ NUMBER_OF_COLORS - 1 ];
  173 + }
166 174 }
167 175  
168 176 ~TextLabelExample()
... ... @@ -170,6 +178,23 @@ public:
170 178 // Nothing to do here.
171 179 }
172 180  
  181 + // Clicking the expanding button shows the registered style buttons.
  182 + void SetUpExpandingStyleButtons( Vector2 position )
  183 + {
  184 + mExpandingButtons = Demo::ExpandingButtons::New();
  185 + mExpandingButtons.SetPosition( mButtonSize.width, mStageSize.height * STYLE_BUTTON_POSTION_RELATIVE_TO_STAGE );
  186 + mExpandingButtons.CollapsingSignal().Connect( this, &TextLabelExample::OnExpandingButtonCollapsing );
  187 + mExpandingButtons.SetSize( mButtonSize );
  188 + // Creates the buttons to be expanded
  189 + CreateStyleButtons();
  190 +
  191 + // Register the created buttons with the ExpandingButtons.
  192 + for ( unsigned int index = 0; index < NUMBER_OF_STYLES; index++ )
  193 + {
  194 + mExpandingButtons.RegisterButton( mStyleButtons[index] );
  195 + }
  196 + }
  197 +
173 198 /**
174 199 * One-time setup in response to Application InitSignal.
175 200 */
... ... @@ -179,15 +204,13 @@ public:
179 204  
180 205 stage.KeyEventSignal().Connect(this, &TextLabelExample::OnKeyEvent);
181 206 mStageSize = stage.GetSize();
182   -
183   - mButtonSize = Size( mStageSize.height * 0.1, mStageSize.height * 0.1 ); // Button size 1/10 of stage height
  207 + mButtonSize = Size( mStageSize.height * 0.12, mStageSize.height * 0.12 ); // Button size 1/12 of stage height
184 208  
185 209 mContainer = Control::New();
186 210 mContainer.SetName( "Container" );
187 211 mContainer.SetParentOrigin( ParentOrigin::CENTER );
188 212 mLayoutSize = Vector2(mStageSize.width*0.6f, mStageSize.width*0.6f);
189 213 mContainer.SetSize( mLayoutSize );
190   - mContainer.SetDrawMode( DrawMode::OVERLAY_2D );
191 214 stage.Add( mContainer );
192 215  
193 216 // Resize the center layout when the corner is grabbed
... ... @@ -212,16 +235,10 @@ public:
212 235 mLabel.SetBackgroundColor( Color::WHITE );
213 236 mContainer.Add( mLabel );
214 237  
215   - // Create style activate button
216   - mStyleMenuButton = PushButton::New();
217   - mStyleMenuButton.SetPosition( mButtonSize.width, mStageSize.height * STYLE_BUTTON_POSTION_RELATIVE_TO_STAGE );
218   - mStyleMenuButton.SetSize( mButtonSize );
219   - mStyleMenuButton.SetProperty( Button::Property::TOGGLABLE, true );
220   - mStyleMenuButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, STYLES_IMAGE );
221   - mStyleMenuButton.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, TICK_IMAGE_IMAGE );
222   -
223   - mStyleMenuButton.ClickedSignal().Connect( this, &TextLabelExample::OnStyleButtonClicked );
224   - stage.Add( mStyleMenuButton );
  238 + // Clicking ExpandingButton shows the Registered Style buttons, clicking again hides them.
  239 + Vector2 expandingButtonPosition( mButtonSize.width, mStageSize.height * STYLE_BUTTON_POSTION_RELATIVE_TO_STAGE );
  240 + SetUpExpandingStyleButtons( expandingButtonPosition );
  241 + stage.Add( mExpandingButtons );
225 242  
226 243 // Add a border for the container so you can see the container is being resized while grabbing the handle.
227 244 mBorder = Control::New();
... ... @@ -232,11 +249,10 @@ public:
232 249 Dali::Property::Map border;
233 250 border.Insert( Toolkit::Visual::Property::TYPE, Visual::BORDER );
234 251 border.Insert( BorderVisual::Property::COLOR, Color::WHITE );
235   - border.Insert( BorderVisual::Property::SIZE, 2.f );
  252 + border.Insert( BorderVisual::Property::SIZE, 3.f );
236 253 mBorder.SetProperty( Control::Property::BACKGROUND, border );
237 254 mContainer.Add( mBorder );
238 255 mBorder.SetVisible(false);
239   -
240 256 mGrabCorner.RaiseToTop();
241 257  
242 258 mHueAngleIndex = mLabel.RegisterProperty( "hue", 0.0f );
... ... @@ -253,147 +269,275 @@ public:
253 269 anim.SetLooping(true);
254 270 anim.Play();
255 271  
256   - // Animate the text color 3 times from source color to Yellow
257   - Animation animation = Animation::New( 2.f );
258   - animation.AnimateTo( Property( mLabel, TextLabel::Property::TEXT_COLOR ), Color::YELLOW, AlphaFunction::SIN );
259   - animation.SetLoopCount( 3 );
260   - animation.Play();
  272 + mContainer.RaiseToTop();
  273 + mGrabCorner.RaiseToTop();
261 274  
262 275 Property::Value labelText = mLabel.GetProperty( TextLabel::Property::TEXT );
263 276 std::cout << "Displaying text: \"" << labelText.Get< std::string >() << "\"" << std::endl;
264 277 }
265 278  
266   - // Depending on button pressed, apply the style to the text label
267   - bool OnStyleSelected( Toolkit::Button button )
  279 + // If the styling buttons should colapse (hide) then the color buttons should also hide.
  280 + bool OnExpandingButtonCollapsing( Demo::ExpandingButtons button )
268 281 {
269   - if( button == mStyleButtons[ StyleType::TEXT_COLOR ] )
  282 + mCollapseColorsAndStyles = true;
  283 + HideColorButtons();
  284 + return true;
  285 + }
  286 +
  287 + // Get the style type from the given button
  288 + StyleType GetStyleTypeFromButton( Toolkit::Button button )
  289 + {
  290 + StyleType style = StyleType::TEXT_COLOR;
  291 +
  292 + if( button == mStyleButtons[ StyleType::OUTLINE ] )
270 293 {
271   - Animation animation = Animation::New( 2.f );
272   - animation.AnimateTo( Property( mLabel, TextLabel::Property::TEXT_COLOR ), mSelectedColor, AlphaFunction::LINEAR );
273   - animation.Play();
  294 + style = StyleType::OUTLINE;
274 295 }
275   - else if( button == mStyleButtons[ StyleType::OUTLINE ] )
  296 + else if( button == mStyleButtons[ StyleType::SHADOW ] )
276 297 {
277   - Property::Map outlineMap;
278   - float outlineWidth = OUTLINE_WIDTH;
  298 + style = StyleType::SHADOW;
  299 + }
  300 + return style;
  301 + }
279 302  
280   - if( mOutlineActive )
  303 + // Style selected, show color buttons
  304 + bool OnStyleButtonClicked( Toolkit::Button button )
  305 + {
  306 + StyleType selectedStyle = GetStyleTypeFromButton( button );
  307 + if ( mStyleActivatedForColor == selectedStyle )
  308 + {
  309 + HideColorButtons();
  310 + }
  311 + else
  312 + {
  313 + ResetColorButtons( mColorButtons, NUMBER_OF_COLORS );
  314 + ShowColorButtons( selectedStyle);
  315 + }
  316 + return true;
  317 + }
  318 +
  319 + // Set style to selected color
  320 + bool OnColorSelected( Toolkit::Button button )
  321 + {
  322 + for( unsigned int index = 0; index < NUMBER_OF_COLORS; index++)
  323 + {
  324 + if ( mColorButtons[index] == button )
281 325 {
282   - outlineWidth = ( mOutlineColor == mSelectedColor ) ? 0.0f : OUTLINE_WIDTH ; // toggles outline on/off
  326 + mSelectedColor = AVAILABLE_COLORS[ index ];
283 327 }
284   - mOutlineActive = ( outlineWidth > 0.0f ) ? true : false;
285   -
286   - mOutlineColor = mSelectedColor;
287   - outlineMap["color"] = mOutlineColor;
288   - outlineMap["width"] = outlineWidth;
289   - mLabel.SetProperty( TextLabel::Property::OUTLINE, outlineMap );
290 328 }
291   - else if( button == mStyleButtons[ StyleType::SHADOW ] )
292   - {
293   - Vector2 shadowOffset( SHADOW_OFFSET ); // Will be set to zeros if color already set
294   - Property::Value value = mLabel.GetProperty( TextLabel::Property::SHADOW_COLOR );
295   - Vector4 currentShadowColor;
296   - value.Get( currentShadowColor );
297 329  
298   - if ( mShadowActive )
  330 + switch ( mStyleActivatedForColor )
  331 + {
  332 + case TEXT_COLOR :
299 333 {
300   - // toggle shadow off ( zero offset ) if color is already set
301   - shadowOffset = ( currentShadowColor == mSelectedColor ) ? Vector2::ZERO : Vector2( SHADOW_OFFSET );
  334 + Animation animation = Animation::New( 1.f );
  335 + animation.AnimateTo( Property( mLabel, TextLabel::Property::TEXT_COLOR ), mSelectedColor, AlphaFunction::LINEAR );
  336 + mCurrentStyleColor[ TEXT_COLOR ] = mSelectedColor;
  337 + animation.Play();
  338 + break;
302 339 }
  340 + case OUTLINE :
  341 + {
  342 + Property::Map outlineMap;
  343 + float outlineWidth = OUTLINE_WIDTH;
303 344  
304   - mShadowActive = ( shadowOffset == Vector2::ZERO ) ? false : true;
  345 + if( mStyleActiveState[ OUTLINE ] )
  346 + {
  347 + outlineWidth = ( Color::WHITE == mSelectedColor ) ? 0.0f : OUTLINE_WIDTH ; // toggles outline on/off
  348 + }
  349 + mStyleActiveState[ OUTLINE ] = ( outlineWidth > 0.0f ) ? true : false;
305 350  
306   - Property::Map shadowMap;
307   - shadowMap.Insert( "offset", shadowOffset );
308   - shadowMap.Insert( "color", mSelectedColor );
309   - shadowMap.Insert( "blurRadius", 2.0f );
310   - mLabel.SetProperty( TextLabel::Property::SHADOW, shadowMap );
  351 + outlineMap["color"] = mSelectedColor;
  352 + outlineMap["width"] = outlineWidth;
  353 + mCurrentStyleColor[ OUTLINE ] = mSelectedColor;
  354 + mLabel.SetProperty( TextLabel::Property::OUTLINE, outlineMap );
  355 + break;
  356 + }
  357 + case SHADOW :
  358 + {
  359 + Vector2 shadowOffset( SHADOW_OFFSET ); // Will be set to zeros if color already set
  360 + Property::Value value = mLabel.GetProperty( TextLabel::Property::SHADOW_COLOR );
  361 + Vector4 currentShadowColor;
  362 + value.Get( currentShadowColor );
  363 +
  364 + if ( mStyleActiveState[ SHADOW ] )
  365 + {
  366 + // toggle shadow off ( zero offset ) if color is already set
  367 + shadowOffset = ( Color::WHITE == mSelectedColor ) ? Vector2::ZERO : Vector2( SHADOW_OFFSET );
  368 + }
  369 +
  370 + mStyleActiveState[ SHADOW ] = ( shadowOffset == Vector2::ZERO ) ? false : true;
  371 + mCurrentStyleColor[ SHADOW ] = mSelectedColor;
  372 +
  373 + mLabel.SetProperty( TextLabel::Property::SHADOW_OFFSET, shadowOffset );
  374 + mLabel.SetProperty( TextLabel::Property::SHADOW_COLOR, mSelectedColor );
  375 + break;
  376 + }
  377 + default :
  378 + break;
311 379 }
  380 +
312 381 return true;
313 382 }
314 383  
315   - bool OnColorSelected( Toolkit::Button button )
  384 + // Set the inital color button that should be be selected.
  385 + // If the style already has a color set then that should be used
  386 + void SetInitialSelectedColorButton( StyleType styleButtonIndex )
316 387 {
317   - for( unsigned int index = 0; index < NUMBER_OF_COLORS; index++)
  388 + Vector4 selectedColor = mCurrentStyleColor[ styleButtonIndex ];
  389 +
  390 + for ( unsigned int i = 0; i < NUMBER_OF_COLORS; i++ )
318 391 {
319   - if ( mColorButtons[index] == button )
  392 + if ( AVAILABLE_COLORS[i] == selectedColor )
320 393 {
321   - mSelectedColor = AVAILABLE_COLORS[ index ];
322   - return true;
  394 + if ( mColorButtons[i] )
  395 + {
  396 + mColorButtons[ i ].SetProperty( Toolkit::DevelButton::Property::SELECTED, true );
  397 + }
  398 + break;
323 399 }
324 400 }
325   - return true;
326 401 }
327 402  
328   - void ShowColorButtons()
  403 + // Create a bar of color buttons that the user can select.
  404 + void ShowColorButtons( StyleType styleButtonIndex )
329 405 {
  406 + mCollapseColorsAndStyles = false; // Request to show colors so reset flag
  407 + mStyleActivatedForColor = styleButtonIndex;
  408 +
330 409 for( unsigned int index = 0; index < NUMBER_OF_COLORS; index++)
331 410 {
332   - mColorButtons[index] = RadioButton::New();
333   - mColorButtons[index].SetPosition( mButtonSize.width, mStageSize.height * STYLE_BUTTON_POSTION_RELATIVE_TO_STAGE - ( mButtonSize.width * (index+1) ) );
334   - mColorButtons[index].SetSize( mButtonSize );
335   - mColorButtons[index].ClickedSignal().Connect( this, &TextLabelExample::OnColorSelected );
336   - mColorButtons[index].SetProperty( Button::Property::TOGGLABLE, true );
337   - Property::Map propertyMap;
338   - propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR);
339   - propertyMap.Insert(ColorVisual::Property::MIX_COLOR, AVAILABLE_COLORS[ index ]);
340   - mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, propertyMap );
341   - mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::UNSELECTED_VISUAL, propertyMap );
342   -
343   - propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR);
344   - propertyMap.Insert(ColorVisual::Property::MIX_COLOR, AVAILABLE_COLORS[ index ]);
345   - mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, propertyMap );
346   -
347   - mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::SELECTED_VISUAL,
348   - Property::Map().Add( Toolkit::Visual::Property::TYPE, Visual::BORDER )
349   - .Add( BorderVisual::Property::COLOR, Color::WHITE )
350   - .Add( BorderVisual::Property::SIZE, 2.0f )
351   - .Add( BorderVisual::Property::ANTI_ALIASING, true ) );
352   -
353   - Stage::GetCurrent().Add( mColorButtons[index] );
  411 + if( !mColorButtonsAnimation )
  412 + {
  413 + mColorButtonsAnimation = Animation::New( 0.15f );
  414 + mColorButtonsAnimation.FinishedSignal().Connect( this, &TextLabelExample::OnColorButtonAnimationFinished );
  415 + }
  416 +
  417 + // Create a color button
  418 + if ( ! mColorButtons[index] )
  419 + {
  420 + mColorButtons[index] = RadioButton::New();
  421 + mColorButtons[index].SetSize( mButtonSize );
  422 + mColorButtons[index].ClickedSignal().Connect( this, &TextLabelExample::OnColorSelected );
  423 + mColorButtons[index].SetProperty( Button::Property::TOGGLABLE, true );
  424 + Property::Map propertyMap;
  425 + propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR);
  426 + propertyMap.Insert(ColorVisual::Property::MIX_COLOR, AVAILABLE_COLORS[ index ]);
  427 + mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, propertyMap );
  428 + mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::UNSELECTED_VISUAL, propertyMap );
  429 + mColorButtons[index].SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER );
  430 + mColorButtons[index].SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER );
  431 +
  432 +
  433 + propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR);
  434 + propertyMap.Insert(ColorVisual::Property::MIX_COLOR, AVAILABLE_COLORS[ index ]);
  435 + mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, propertyMap );
  436 +
  437 + mColorButtons[index].SetProperty( Toolkit::DevelButton::Property::SELECTED_VISUAL,
  438 + Property::Map().Add( Visual::Property::TYPE, Visual::BORDER )
  439 + .Add( BorderVisual::Property::COLOR, Color::WHITE )
  440 + .Add( BorderVisual::Property::SIZE, 4.0f )
  441 + .Add( BorderVisual::Property::ANTI_ALIASING, true ) );
  442 +
  443 + // Use a white button with 50% transparency as a clear color button
  444 + if ( Color::WHITE == AVAILABLE_COLORS[ index ] && styleButtonIndex != StyleType::TEXT_COLOR )
  445 + {
  446 + mColorButtons[index].SetOpacity(0.5f);
  447 +
  448 + mColorButtons[index].SetProperty( Toolkit::Button::Property::LABEL,
  449 + Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT )
  450 + .Add( Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT, HorizontalAlignment::CENTER )
  451 + .Add( Toolkit::TextVisual::Property::TEXT, "off") );
  452 +
  453 + }
  454 + }
  455 +
  456 + SetInitialSelectedColorButton( mStyleActivatedForColor );
  457 +
  458 + mColorButtons[index].Unparent();
  459 +
  460 + mStyleButtons[styleButtonIndex].Add( mColorButtons[index] );
  461 + mColorButtons[index].Lower();
  462 +
  463 + // Position button using nice animation
  464 + mColorButtons[index].SetY( -GAP_BETWEEN_BUTTONS );
  465 + float desiredPosition = -( mButtonSize.height + GAP_BETWEEN_BUTTONS ) * (index);
  466 + AlphaFunction focusedAlphaFunction = AlphaFunction( Vector2 ( 0.32f, 0.08f ), Vector2( 0.38f, 1.72f ) );
  467 + mColorButtonsAnimation.AnimateBy( Property( mColorButtons[index], Actor::Property::POSITION_Y ), desiredPosition, focusedAlphaFunction );
354 468 }
355   - }
356 469  
  470 + mColorButtonsHidden = false;
  471 + mColorButtonsAnimation.Play();
  472 + }
357 473  
358   - void HideColorButtons()
  474 + // Remove the color buttons when not being shown.
  475 + void ResetColorButtons( Button buttons[], unsigned int numberOfButtons )
359 476 {
360   - for( unsigned int index = 0; index < NUMBER_OF_COLORS; index++)
  477 + for( unsigned int index = 0; index < numberOfButtons; index++)
361 478 {
362   - UnparentAndReset( mColorButtons[index] );
  479 + UnparentAndReset( buttons[index] );
363 480 }
364 481 }
365 482  
366   - void HideStyleButtons()
  483 + void OnColorButtonAnimationFinished( Animation& animation )
367 484 {
368   - for( unsigned int index = 0; index < NUMBER_OF_STYLES; index++)
  485 + animation.Clear();
  486 + if ( mColorButtonsHidden )
369 487 {
370   - UnparentAndReset( mStyleButtons[index] );
  488 + ResetColorButtons( mColorButtons, NUMBER_OF_COLORS );
  489 + animation.Reset(); // Handle reset
  490 + if ( mCollapseColorsAndStyles )
  491 + {
  492 + mExpandingButtons.Collapse();
  493 + }
371 494 }
372 495 }
373 496  
374   - bool OnStyleButtonClicked( Toolkit::Button button )
  497 + // Create the style buttons that will expand from the expanding button.
  498 + void CreateStyleButtons()
375 499 {
376   - if ( button.GetProperty( Toolkit::Button::Property::SELECTED ).Get<bool>() )
  500 + for ( unsigned int index = 0; index < NUMBER_OF_STYLES; index++ )
377 501 {
378   - for ( unsigned int index = 0; index < NUMBER_OF_STYLES; index++ )
  502 + if ( ! mStyleButtons[index] )
379 503 {
380 504 mStyleButtons[index] = PushButton::New();
381   - mStyleButtons[index].SetPosition( mButtonSize.width + ( mButtonSize.width * (index+1) ), mStageSize.height * STYLE_BUTTON_POSTION_RELATIVE_TO_STAGE );
382   - mStyleButtons[index].SetSize( mButtonSize );
383 505 mStyleButtons[index].SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, BUTTON_IMAGES[ index ] );
384 506 mStyleButtons[index].SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, STYLE_SELECTED_IMAGE );
385   - mStyleButtons[index].ClickedSignal().Connect( this, &TextLabelExample::OnStyleSelected );
386   - Stage::GetCurrent().Add( mStyleButtons[index] );
  507 + mStyleButtons[index].SetProperty( Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
  508 + mStyleButtons[index].SetSize( mButtonSize );
  509 + mStyleButtons[index].ClickedSignal().Connect( this, &TextLabelExample::OnStyleButtonClicked );
  510 + }
  511 + }
  512 + }
  513 +
  514 + // Animate away the color bar.
  515 + void HideColorButtons()
  516 + {
  517 + if ( ! mColorButtonsHidden )
  518 + {
  519 + for( unsigned int index = 0; index < NUMBER_OF_COLORS; index++)
  520 + {
  521 + mColorButtonsAnimation.AnimateTo( Property( mColorButtons[index], Actor::Property::POSITION_Y ), 0.0f );
387 522 }
388   - ShowColorButtons();
  523 + mColorButtonsHidden = true;
  524 + mColorButtonsAnimation.Play();
  525 + }
  526 + mStyleActivatedForColor = NUMBER_OF_STYLES;
  527 + }
  528 +
  529 + // Request the expanding button to collapse.
  530 + void HideStyleAndColorButtons()
  531 + {
  532 + mCollapseColorsAndStyles = true;
  533 + if ( mColorButtonsHidden )
  534 + {
  535 + mExpandingButtons.Collapse();
389 536 }
390 537 else
391 538 {
392   - // hide menu and colors
393 539 HideColorButtons();
394   - HideStyleButtons();
395 540 }
396   - return true;
397 541 }
398 542  
399 543 // Resize the text-label with pan gesture
... ... @@ -414,6 +558,8 @@ public:
414 558  
415 559 // Only show the border during the panning
416 560 mBorder.SetVisible(true);
  561 +
  562 + HideStyleAndColorButtons();
417 563 }
418 564  
419 565 mLayoutSize.x += gesture.displacement.x * 2.0f;
... ... @@ -560,14 +706,18 @@ private:
560 706  
561 707 TextLabel mLabel;
562 708  
563   - PushButton mStyleMenuButton;
  709 + Demo::ExpandingButtons mExpandingButtons;
564 710 PushButton mStyleButtons[ NUMBER_OF_STYLES ];
565   - bool mShadowActive;
566   - bool mOutlineActive;
  711 + bool mStyleActiveState[ NUMBER_OF_STYLES ];
  712 +
  713 + Vector4 mCurrentStyleColor[NUMBER_OF_STYLES ];
  714 +
567 715 Vector4 mSelectedColor;
568   - Vector4 mOutlineColor; // Store outline as Vector4 whilst TextLabel Outline Property returns a string when using GetProperty
  716 +
569 717 Button mColorButtons[ NUMBER_OF_COLORS ];
570 718  
  719 + StyleType mStyleActivatedForColor; // The style that the color bar is connected to
  720 +
571 721 Control mContainer;
572 722 Control mGrabCorner;
573 723 Control mBorder;
... ... @@ -576,6 +726,8 @@ private:
576 726  
577 727 Vector2 mLayoutSize;
578 728  
  729 + Animation mColorButtonsAnimation;
  730 +
579 731 Size mStageSize;
580 732 Size mButtonSize;
581 733  
... ... @@ -583,6 +735,9 @@ private:
583 735 unsigned int mAlignment;
584 736 Property::Index mHueAngleIndex;
585 737 Property::Index mOverrideMixColorIndex;
  738 +
  739 + bool mColorButtonsHidden;
  740 + bool mCollapseColorsAndStyles;
586 741 };
587 742  
588 743 int DALI_EXPORT_API main( int argc, char **argv )
... ...