2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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
8 // http://floralicense.org/license/
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.
17 #include <dali/dali.h>
18 #include <dali-toolkit/dali-toolkit.h>
19 #include "../shared/view.h"
25 const char * const TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" );
26 const char * const APPLICATION_TITLE( "Bubble Effect" );
27 const char * const CHANGE_BACKGROUND_ICON( DALI_IMAGE_DIR "icon-change.png" );
28 const char * const CHANGE_BUBBLE_SHAPE_ICON( DALI_IMAGE_DIR "icon-replace.png" );
30 const char* BACKGROUND_IMAGES[]=
32 DALI_IMAGE_DIR "background-1.jpg",
33 DALI_IMAGE_DIR "background-2.jpg",
34 DALI_IMAGE_DIR "background-3.jpg",
35 DALI_IMAGE_DIR "background-4.jpg",
36 DALI_IMAGE_DIR "background-5.jpg",
38 const unsigned int NUM_BACKGROUND_IMAGES( sizeof( BACKGROUND_IMAGES ) / sizeof( BACKGROUND_IMAGES[0] ) );
40 const char* BUBBLE_SHAPE_IMAGES[] =
42 DALI_IMAGE_DIR "blocks-ball.png",
43 DALI_IMAGE_DIR "icon-item-view-layout-spiral.png",
44 DALI_IMAGE_DIR "icon-replace.png",
45 DALI_IMAGE_DIR "icon-effect-cross.png"
47 const unsigned int NUM_BUBBLE_SHAPE_IMAGES( sizeof( BUBBLE_SHAPE_IMAGES ) / sizeof( BUBBLE_SHAPE_IMAGES[0] ) );
49 const Vector2 DEFAULT_BUBBLE_SIZE( 10.f, 30.f );
50 const unsigned int DEFAULT_NUMBER_OF_BUBBLES( 1000 );
53 // This example shows the usage of BubbleEmitter which displays lots of moving bubbles on the stage.
54 class BubbleEffectExample : public ConnectionTracker
57 BubbleEffectExample(Application &app)
59 mHSVDelta( Vector3( 0.f, 0.f, 0.5f ) ),
60 mNeedNewAnimation( true ),
62 mCurrentBackgroundImageId( 0 ),
63 mCurrentBubbleShapeImageId( 0 )
65 // Connect to the Application's Init signal
66 app.InitSignal().Connect(this, &BubbleEffectExample::Create);
69 ~BubbleEffectExample()
75 // The Init signal is received once (only) during the Application lifetime
76 void Create(Application& app)
78 Stage stage = Stage::GetCurrent();
79 Vector2 stageSize = stage.GetSize();
81 stage.KeyEventSignal().Connect(this, &BubbleEffectExample::OnKeyEvent);
83 // Creates a default view with a default tool bar.
84 // The view is added to the stage.
85 Toolkit::ToolBar toolBar;
87 Layer content = DemoHelper::CreateView( app,
94 // Add a button to change background. (right of toolbar)
95 mChangeBackgroundButton = Toolkit::PushButton::New();
96 mChangeBackgroundButton.SetBackgroundImage( Image::New( CHANGE_BACKGROUND_ICON ) );
97 mChangeBackgroundButton.ClickedSignal().Connect( this, &BubbleEffectExample::OnChangeIconClicked );
98 toolBar.AddControl( mChangeBackgroundButton,
99 DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage,
100 Toolkit::Alignment::HorizontalRight,
101 DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
102 // Add a button to change bubble shape. ( left of bar )
103 mChangeBubbleShapeButton = Toolkit::PushButton::New();
104 mChangeBubbleShapeButton.SetBackgroundImage( Image::New( CHANGE_BUBBLE_SHAPE_ICON ) );
105 mChangeBubbleShapeButton.ClickedSignal().Connect( this, &BubbleEffectExample::OnChangeIconClicked );
106 toolBar.AddControl( mChangeBubbleShapeButton,
107 DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage,
108 Toolkit::Alignment::HorizontalLeft,
109 DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
111 // Create and initialize the BubbleEmitter object
112 mBubbleEmitter = Toolkit::BubbleEmitter::New( stageSize,
113 Image::New( BUBBLE_SHAPE_IMAGES[mCurrentBubbleShapeImageId] ),
114 DEFAULT_NUMBER_OF_BUBBLES,
115 DEFAULT_BUBBLE_SIZE);
116 mBackgroundImage = Image::New( BACKGROUND_IMAGES[mCurrentBackgroundImageId] );
117 mBubbleEmitter.SetBackground( mBackgroundImage, mHSVDelta );
119 // Get the root actor of all bubbles, and add it to stage.
120 Actor bubbleRoot = mBubbleEmitter.GetRootActor();
121 bubbleRoot.SetParentOrigin(ParentOrigin::CENTER);
122 bubbleRoot.SetZ(0.1f); // Make sure the bubbles displayed on top og the background.
123 content.Add( bubbleRoot );
125 // Add the background image actor to stage
126 mBackgroundActor = ImageActor::New( mBackgroundImage );
127 view.SetBackground( mBackgroundActor );
129 // Set up the timer to emit bubble regularly when the finger is touched down but not moved
130 mTimerForBubbleEmission = Timer::New( mTimerInterval );
131 mTimerForBubbleEmission.TickSignal().Connect(this, &BubbleEffectExample::OnTimerTick);
133 // Connect the callback to the touch signal on the background
134 mBackgroundActor.TouchedSignal().Connect( this, &BubbleEffectExample::OnTouch );
142 // Set up the animation of emitting bubbles, to be efficient, every animation controls multiple bubbles ( 4 here )
143 void SetUpAnimation( Vector2 emitPosition, Vector2 direction )
145 if( mNeedNewAnimation )
147 float duration = Random::Range(1.f, 1.5f);
148 mEmitAnimation = Animation::New( duration );
149 mNeedNewAnimation = false;
150 mAnimateComponentCount = 0;
153 mBubbleEmitter.EmitBubble( mEmitAnimation, emitPosition, direction + Vector2(0.f, 30.f) /* upwards */, Vector2(300, 600) );
155 mAnimateComponentCount++;
157 if( mAnimateComponentCount % 4 ==0 )
159 mEmitAnimation.Play();
160 mNeedNewAnimation = true;
164 // Emit bubbles when the finger touches down but keep stationary.
165 // And stops emitting new bubble after being stationary for 2 seconds
168 if(mEmitPosition == mCurrentTouchPosition) // finger is not moving
171 if(mNonMovementCount < (1000 / mTimerInterval)) // 1 seconds
173 for(int i = 0; i < 4; i++) // emit 4 bubbles every timer tick
175 SetUpAnimation( mCurrentTouchPosition+Vector2(rand()%5, rand()%5), Vector2(rand()%60-30, rand()%100-50) );
181 mNonMovementCount = 0;
182 mEmitPosition = mCurrentTouchPosition;
188 // Callback function of the touch signal on the background
189 bool OnTouch(Dali::Actor actor, const Dali::TouchEvent& event)
191 const TouchPoint &point = event.GetPoint(0);
194 case TouchPoint::Down:
196 mCurrentTouchPosition = point.screen;
197 mEmitPosition = point.screen;
198 mTimerForBubbleEmission.Start();
199 mNonMovementCount = 0;
203 case TouchPoint::Motion:
205 Vector2 displacement = point.screen - mCurrentTouchPosition;
206 mCurrentTouchPosition = point.screen;
207 //emit multiple bubbles along the moving direction when the finger moves quickly
208 float step = std::min(5.f, displacement.Length());
209 for( float i=0.25f; i<step; i=i+1.f)
211 SetUpAnimation( mCurrentTouchPosition+displacement*(i/step), displacement );
216 case TouchPoint::Leave:
217 case TouchPoint::Interrupted:
219 mTimerForBubbleEmission.Stop();
222 case TouchPoint::Stationary:
223 case TouchPoint::Last:
233 bool OnChangeIconClicked( Toolkit::Button button )
235 if(button == mChangeBackgroundButton)
237 mBackgroundImage = Image::New( BACKGROUND_IMAGES[ ++mCurrentBackgroundImageId % NUM_BACKGROUND_IMAGES ] );
239 mBubbleEmitter.SetBackground( mBackgroundImage, mHSVDelta );
241 mBackgroundActor.SetImage( mBackgroundImage );
243 else if( button == mChangeBubbleShapeButton )
245 mBubbleEmitter.SetShapeImage( Image::New( BUBBLE_SHAPE_IMAGES[ ++mCurrentBubbleShapeImageId % NUM_BUBBLE_SHAPE_IMAGES ] ) );
251 * Main key event handler
253 void OnKeyEvent(const KeyEvent& event)
255 if(event.state == KeyEvent::Down)
257 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
267 Image mBackgroundImage;
268 ImageActor mBackgroundActor;
270 Toolkit::BubbleEmitter mBubbleEmitter;
273 Animation mEmitAnimation;
274 unsigned int mAnimateComponentCount;
275 bool mNeedNewAnimation;
277 Timer mTimerForBubbleEmission;
278 unsigned int mNonMovementCount;
279 unsigned int mTimerInterval;
281 Vector2 mCurrentTouchPosition;
282 Vector2 mEmitPosition;
284 Toolkit::PushButton mChangeBackgroundButton;
285 Toolkit::PushButton mChangeBubbleShapeButton;
286 unsigned int mCurrentBackgroundImageId;
287 unsigned int mCurrentBubbleShapeImageId;
290 /*****************************************************************************/
293 RunTest(Application& app)
295 BubbleEffectExample theApp(app);
299 /*****************************************************************************/
302 main(int argc, char **argv)
304 Application app = Application::New(&argc, &argv);