2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include "shared/view.h"
23 #include <dali-toolkit/dali-toolkit.h>
29 const char* BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-magnifier.jpg" );
30 const char* TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" );
31 const char* APPLICATION_TITLE( "Magnifier Example" );
32 const Vector3 MAGNIFIER_SIZE(0.25f, 0.25f, 0.0f); ///< Magnifier sides should be 25% of the width of the stage
33 const float ANIMATION_DURATION(60.0f); ///< Run animation for a minute before repeating.
34 const float MAGNIFIER_DISPLAY_DURATION(0.125f); ///< Duration in seconds for show/hide manual magnifier animation
36 const float MAGNIFICATION_FACTOR(2.0f); ///< Amount to magnify by.
37 const float MAGNIFIER_INDENT(10.0f); ///< Indentation around edge of stage to define where magnifiers may move.
38 const float FINGER_RADIUS_INCHES(0.25f); ///< Average finger radius in inches from the center of index finger to edge.
41 * MagnifierPathConstraint
42 * This constraint governs the position of the
43 * animating magnifier in a swirly pattern around
46 struct MagnifierPathConstraint
49 * Constraint constructor
50 * @param[in] stageSize The stage size so that the constraint can create a path
51 * within stage bounds.
53 MagnifierPathConstraint(const Vector3& stageSize,
54 Vector3 offset = Vector3::ZERO)
55 : mStageSize(stageSize),
60 Vector3 operator()(const Vector3& current,
61 const PropertyInput& sizeProperty,
62 const PropertyInput& animationTimeProperty)
64 float time = animationTimeProperty.GetFloat();
65 const Vector3& size = sizeProperty.GetVector3();
67 Vector3 range(mStageSize - size - Vector3::ONE * MAGNIFIER_INDENT * 2.0f);
68 Vector3 position(mOffset);
70 position.x += 0.5f * sinf(time * 0.471f) * range.width;
71 position.y += 0.5f * sinf(time * 0.8739f) * range.height;
76 Vector3 mStageSize; ///< Keep track of the stage size for determining path within stage bounds
77 Vector3 mOffset; ///< Amount to offset magnifier path
81 * Confine Actor to boundaries of reference actor (e.g. Parent)
82 * Actor bounds (top-left position + size) are confined to reference Actor's
85 struct ConfinementConstraint
88 * Confinement constraint constructor.
89 * @param[in] offsetOrigin (optional) Whether to offset the parent origin or not.
90 * @param[in] topLeftMargin (optional) Top-Left margins (defaults to 0.0f, 0.0f)
91 * @param[in] bottomRightMargin (optional) Bottom-Right margins (defaults to 0.0f, 0.0f)
92 * @param[in] flipHorizontal (optional) whether to flip Actor to the other side X if near edge, and by
93 * how much (defaults to 0.0f i.e. no flip)
94 * @param[in] flipVertical (optional) whether to flip Actor to the other side Y if near edge, and by
95 * how much (defaults to 0.0f i.e. no flip)
97 ConfinementConstraint(Vector3 offsetOrigin = Vector3::ZERO, Vector2 topLeftMargin = Vector2::ZERO, Vector2 bottomRightMargin = Vector2::ZERO, bool flipHorizontal = false, bool flipVertical = false)
98 : mOffsetOrigin(offsetOrigin),
99 mMinIndent(topLeftMargin),
100 mMaxIndent(bottomRightMargin),
101 mFlipHorizontal(flipHorizontal),
102 mFlipVertical(flipVertical)
106 Vector3 operator()(const Vector3& constPosition,
107 const PropertyInput& sizeProperty,
108 const PropertyInput& parentOriginProperty,
109 const PropertyInput& anchorPointProperty,
110 const PropertyInput& referenceSizeProperty)
112 const Vector3& size = sizeProperty.GetVector3();
113 const Vector3 origin = parentOriginProperty.GetVector3();
114 const Vector3& anchor = anchorPointProperty.GetVector3();
115 const Vector3& referenceSize = referenceSizeProperty.GetVector3();
117 Vector3 offset(mOffsetOrigin * referenceSize);
119 Vector3 newPosition( constPosition + offset );
121 // Get actual position of Actor relative to parent's Top-Left.
122 Vector3 position(constPosition + offset + origin * referenceSize);
124 // if top-left corner is outside of Top-Left bounds, then push back in screen.
125 Vector3 corner(position - size * anchor - mMinIndent);
127 if(mFlipHorizontal && corner.x < 0.0f)
130 newPosition.x += size.width;
133 if(mFlipVertical && corner.y < 0.0f)
136 newPosition.y += size.height;
139 newPosition.x -= std::min(corner.x, 0.0f);
140 newPosition.y -= std::min(corner.y, 0.0f);
142 // if bottom-right corner is outside of Bottom-Right bounds, then push back in screen.
143 corner += size - referenceSize + mMinIndent + mMaxIndent;
145 if(mFlipHorizontal && corner.x > 0.0f)
148 newPosition.x -= size.width;
151 if(mFlipVertical && corner.y > 0.0f)
154 newPosition.y -= size.height;
157 newPosition.x -= std::max(corner.x, 0.0f);
158 newPosition.y -= std::max(corner.y, 0.0f);
163 Vector3 mOffsetOrigin; ///< Manual Parent Offset Origin.
164 Vector3 mMinIndent; ///< Top-Left Margin
165 Vector3 mMaxIndent; ///< Bottom-Right Margin.
166 bool mFlipHorizontal; ///< Whether to flip actor's position if exceeds horizontal screen bounds
167 bool mFlipVertical; ///< Whether to flip actor's position if exceeds vertical screen bounds
172 // This example shows how to use the Magnifier component.
174 class ExampleController : public ConnectionTracker
179 * The example controller constructor.
180 * @param[in] application The application instance
182 ExampleController( Application& application )
183 : mApplication( application ),
185 mAnimationTime(0.0f),
186 mMagnifierShown(false)
188 // Connect to the Application's Init signal
189 mApplication.InitSignal().Connect( this, &ExampleController::Create );
193 * The example controller destructor
197 // Nothing to do here;
201 * Invoked upon creation of application
202 * @param[in] application The application instance
204 void Create( Application& application )
206 DemoHelper::RequestThemeChange();
208 Stage::GetCurrent().KeyEventSignal().Connect(this, &ExampleController::OnKeyEvent);
210 mStageSize = Stage::GetCurrent().GetSize();
212 // The Init signal is received once (only) during the Application lifetime
214 // Hide the indicator bar
215 application.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
217 // Creates a default view with a default tool bar.
218 // The view is added to the stage.
219 Toolkit::ToolBar toolBar;
220 mContent = DemoHelper::CreateView( application,
227 mContent.SetLeaveRequired(true);
228 mContent.TouchedSignal().Connect( this, &ExampleController::OnTouched );
230 // Create magnifier (controlled by human touch)
231 Layer overlay = Layer::New();
232 overlay.SetRelayoutEnabled( false );
233 overlay.SetSensitive(false);
234 overlay.SetParentOrigin( ParentOrigin::CENTER );
235 overlay.SetSize(mStageSize);
236 Stage::GetCurrent().Add(overlay);
238 mMagnifier = Toolkit::Magnifier::New();
239 mMagnifier.SetRelayoutEnabled( false );
240 mMagnifier.SetSourceActor( mView.GetBackgroundLayer() );
241 mMagnifier.SetSize( MAGNIFIER_SIZE * mStageSize.width ); // Size of magnifier is in relation to stage width
242 mMagnifier.SetMagnificationFactor( MAGNIFICATION_FACTOR );
243 mMagnifier.SetScale(Vector3::ZERO);
244 overlay.Add( mMagnifier );
246 // Apply constraint to animate the position of the magnifier.
247 Constraint constraint = Constraint::New<Vector3>(Actor::Property::POSITION,
248 LocalSource(Actor::Property::SIZE),
249 LocalSource(Actor::Property::PARENT_ORIGIN),
250 LocalSource(Actor::Property::ANCHOR_POINT),
251 ParentSource(Actor::Property::SIZE),
252 ConfinementConstraint(ParentOrigin::CENTER, Vector2::ONE * MAGNIFIER_INDENT, Vector2::ONE * MAGNIFIER_INDENT));
253 constraint.SetRemoveAction(Constraint::Discard);
254 mMagnifier.ApplyConstraint( constraint );
256 // Create bouncing magnifier automatically bounces around screen.
257 mBouncingMagnifier = Toolkit::Magnifier::New();
258 mBouncingMagnifier.SetRelayoutEnabled( false );
259 mBouncingMagnifier.SetSourceActor( mView.GetBackgroundLayer() );
260 mBouncingMagnifier.SetSize( MAGNIFIER_SIZE * mStageSize.width ); // Size of magnifier is in relation to stage width
261 mBouncingMagnifier.SetMagnificationFactor( MAGNIFICATION_FACTOR );
262 overlay.Add( mBouncingMagnifier );
264 mAnimationTimeProperty = mBouncingMagnifier.RegisterProperty("animation-time", 0.0f);
267 // Apply constraint to animate the position of the magnifier.
268 constraint = Constraint::New<Vector3>(Actor::Property::POSITION,
269 LocalSource(Actor::Property::SIZE),
270 LocalSource(mAnimationTimeProperty),
271 MagnifierPathConstraint(mStageSize, mStageSize * 0.5f));
272 mBouncingMagnifier.ApplyConstraint( constraint );
274 // Apply constraint to animate the source of the magnifier.
275 constraint = Constraint::New<Vector3>(mBouncingMagnifier.GetPropertyIndex( Toolkit::Magnifier::SOURCE_POSITION_PROPERTY_NAME ),
276 LocalSource(Actor::Property::SIZE),
277 LocalSource(mAnimationTimeProperty),
278 MagnifierPathConstraint(mStageSize));
279 mBouncingMagnifier.ApplyConstraint( constraint );
283 * Invoked whenever the animation finishes (every 60 seconds)
284 * @param[in] animation The animation
286 void OnAnimationFinished( Animation& animation )
288 animation.FinishedSignal().Disconnect(this, &ExampleController::OnAnimationFinished);
294 * Resumes animation for another ANIMATION_DURATION seconds.
296 void ContinueAnimation()
298 Animation animation = Animation::New(ANIMATION_DURATION);
299 mAnimationTime += ANIMATION_DURATION;
300 animation.AnimateTo( Property(mBouncingMagnifier, mAnimationTimeProperty), mAnimationTime );
302 animation.FinishedSignal().Connect(this, &ExampleController::OnAnimationFinished);
306 * Invoked whenever the quit button is clicked
307 * @param[in] button the quit button
309 bool OnQuitButtonClicked( Toolkit::Button button )
311 // quit the application
317 * Invoked whenever the content (screen) is touched
318 * @param[in] actor The actor that received the touch
319 * @param[in] event The touch-event information
321 bool OnTouched( Actor actor, const TouchEvent& event )
323 if(event.GetPointCount() > 0)
325 const TouchPoint& point = event.GetPoint(0);
328 case TouchPoint::Down:
329 case TouchPoint::Motion:
335 case TouchPoint::Leave:
336 case TouchPoint::Interrupted:
347 Vector3 touchPoint(point.screen);
349 SetMagnifierPosition(touchPoint - mStageSize * 0.5f);
356 * Shows the magnifier
362 Animation animation = Animation::New(MAGNIFIER_DISPLAY_DURATION);
363 animation.AnimateTo(Property(mMagnifier, Actor::Property::SCALE), Vector3::ONE, AlphaFunctions::EaseIn);
365 mMagnifierShown = true;
370 * Hides the magnifier
376 Animation animation = Animation::New(MAGNIFIER_DISPLAY_DURATION);
377 animation.AnimateTo(Property(mMagnifier, Actor::Property::SCALE), Vector3::ZERO, AlphaFunctions::EaseOut);
379 mMagnifierShown = false;
384 * Manually sets the magnifier position
385 * @param[in] position The magnifier's position relative to center of stage
387 void SetMagnifierPosition(const Vector3 position)
389 mMagnifier.SetSourcePosition( position );
391 // position magnifier glass such that bottom edge is touching/near top of finger.
392 Vector3 glassPosition(position);
393 glassPosition.y -= mStageSize.width * MAGNIFIER_SIZE.height * 0.5f + Stage::GetCurrent().GetDpi().height * FINGER_RADIUS_INCHES;
395 mMagnifier.SetPosition( glassPosition );
398 void OnKeyEvent(const KeyEvent& event)
400 if(event.state == KeyEvent::Down)
402 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
411 Application& mApplication; ///< Application instance
412 Toolkit::View mView; ///< The view
413 Layer mContent; ///< The content layer
414 Toolkit::Magnifier mMagnifier; ///< The manually controlled magnifier
415 Toolkit::Magnifier mBouncingMagnifier; ///< The animating magnifier (swirly animation)
416 Vector3 mStageSize; ///< The size of the stage
417 float mAnimationTime; ///< Keep track of start animation time.
418 Property::Index mAnimationTimeProperty; ///< Animation time property (responsible for swirly animation)
419 bool mMagnifierShown; ///< Flag indicating whether the magnifier is being shown or not.
423 void RunTest( Application& application )
425 ExampleController test( application );
427 application.MainLoop();
430 // Entry point for Linux & Tizen applications
432 int main( int argc, char **argv )
434 Application application = Application::New( &argc, &argv );
436 RunTest( application );