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 <dali-toolkit/internal/controls/buttons/push-button-impl.h>
22 #include <dali-toolkit-test-suite-utils.h>
23 #include <dali-toolkit/dali-toolkit.h>
24 #include <dali/integration-api/events/touch-event-integ.h>
28 using namespace Toolkit;
33 static bool gPushButtonSelectedState = false;
34 bool PushButtonSelected( Button button, bool selected )
36 gPushButtonSelectedState = selected && ( selected == static_cast<PushButton&>( button ).IsSelected() );
41 Dali::Integration::Point GetPointDownInside()
43 Dali::Integration::Point point;
44 point.SetState( PointState::DOWN );
45 point.SetScreenPosition( Vector2( 240, 400 ) );
49 Dali::Integration::Point GetPointUpInside()
51 Dali::Integration::Point point;
52 point.SetState( PointState::UP );
53 point.SetScreenPosition( Vector2( 240, 400 ) );
57 Dali::Integration::Point GetPointMotionOut()
59 Dali::Integration::Point point;
60 point.SetState( PointState::MOTION );
61 point.SetScreenPosition( Vector2( 10, 10 ) );
65 Dali::Integration::Point GetPointUpOutside()
67 Dali::Integration::Point point;
68 point.SetState( PointState::UP );
69 point.SetScreenPosition( Vector2( 10, 10 ) );
76 //////////////////////////////////////////////////////////
80 static bool gOnTouchPointInterrupted = false;
95 * Creates a PushButton to test if interrupt events are handled correctly.
97 class TETButton : public PushButton
100 // PushButton Pressed
101 typedef Signal< bool ( PushButton ) > ButtonSignalType;
103 ButtonSignalType& PressedSignal();
106 * Default constructor.
113 TETButton( const PushButton& button );
116 * Assignment operator.
118 TETButton& operator=( const TETButton& button );
121 * Creates and initializes a new button.
123 static TETButton New();
126 * Down cast to TETButton.
128 static TETButton DownCast( BaseHandle handle );
131 * Creates a handle using the Toolkit::Internal implementation.
132 * @param[in] implementation The Control implementation.
134 TETButton( Internal::TETButton& implementation );
137 * Allows the creation of this Control from an Internal::CustomActor pointer.
138 * @param[in] internal A pointer to the internal CustomActor.
140 TETButton( Dali::Internal::CustomActor* internal );
147 * Internal implementation
149 class TETButton : public PushButton
153 * Construct a new Button.
158 * A reference counted object may only be deleted by calling Unreference()
160 virtual ~TETButton();
163 * Creates an internal button.
165 static Toolkit::TETButton New();
168 * @return the pressed signal.
170 Toolkit::TETButton::ButtonSignalType& PressedSignal();
173 * Callback called when an interrupt events is received.
175 void OnTouchPointInterrupted();
178 * Callback received when a down event is received.
182 Toolkit::TETButton::ButtonSignalType mPressedSignal; ///< Signal emitted when the button is pressed.
185 } // namespace Internal
187 TETButton::TETButton()
191 TETButton::TETButton( const PushButton& button )
192 : PushButton( button )
196 TETButton& TETButton::operator=( const TETButton& button )
198 if( &button != this )
200 PushButton::operator=( button );
205 TETButton TETButton::New()
207 return Internal::TETButton::New();
210 TETButton TETButton::DownCast( BaseHandle handle )
212 return Control::DownCast<TETButton, Internal::TETButton>(handle);
215 TETButton::ButtonSignalType& TETButton::PressedSignal()
217 TETButton button( *this );
218 DALI_ASSERT_ALWAYS( button );
220 Dali::RefObject& handle = button.GetImplementation();
222 return static_cast<Toolkit::Internal::TETButton&>( handle ).PressedSignal();
225 TETButton::TETButton( Internal::TETButton& implementation )
226 : PushButton( implementation )
229 TETButton::TETButton( Dali::Internal::CustomActor* internal )
230 : PushButton( internal )
232 VerifyCustomActorPointer<Internal::TETButton>(internal);
238 TETButton::TETButton()
244 TETButton::~TETButton()
248 Toolkit::TETButton TETButton::New()
250 // Create the implementation, temporarily owned on stack
251 IntrusivePtr< TETButton > internalTETButton = new TETButton();
253 // Pass ownership to CustomActor
254 Dali::Toolkit::TETButton tetButton( *internalTETButton );
256 // Second-phase init of the implementation
257 // This can only be done after the CustomActor connection has been made...
258 internalTETButton->Initialize();
263 Toolkit::TETButton::ButtonSignalType& TETButton::PressedSignal()
265 return mPressedSignal;
268 void TETButton::OnButtonDown()
270 Toolkit::TETButton handle( GetOwner() );
273 mPressedSignal.Emit( handle );
276 void TETButton::OnTouchPointInterrupted()
278 gOnTouchPointInterrupted = true;
281 } // namespace Internal
283 } // namespace Toolkit
290 class TETButtonPressed : public Dali::ConnectionTracker
299 TETButtonPressed( Actor actor, Test test )
305 bool Callback( PushButton button )
311 mActor.SetSensitive( false );
316 std::cout <<"VISIBILITY false" << std::endl;
317 mActor.SetVisible( false );
332 static bool TestCallback(Actor actor, const TouchData& event)
339 //////////////////////////////////////////////////////////
341 int UtcDaliPushButtonDownCast(void)
343 ToolkitTestApplication application;
344 tet_infoline(" UtcDaliPushButtonDownCast");
346 TETButton tetButton= Toolkit::TETButton::New();
348 BaseHandle object(tetButton);
350 TETButton tetButton2 = TETButton::DownCast( object );
351 DALI_TEST_CHECK(tetButton2);
353 TETButton tetButton3 = DownCast< TETButton >(object);
354 DALI_TEST_CHECK(tetButton3);
358 int UtcDaliPushButtonInterruptEventWhenInsensitive(void)
360 ToolkitTestApplication application;
361 tet_infoline(" UtcDaliPushButtonInterruptEventWhenInsensitive");
363 // * Creates an actor which contains a button.
364 // * The size of the actor is bigger than the button.
365 // * The button's boundary is contained in the actor's one.
366 Actor actor = Actor::New();
367 TETButton tetButton= Toolkit::TETButton::New();
369 actor.SetName( "Actor" );
370 tetButton.SetName( "TETButton" );
372 actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
373 actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
374 actor.SetPosition( 0, 0 );
375 actor.SetSize( 400, 800 );
377 tetButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
378 tetButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
379 tetButton.SetPosition( 240, 400 );
380 tetButton.SetSize( 100, 100 );
382 actor.Add( tetButton );
383 Stage::GetCurrent().Add( actor );
385 // * Actor's touch event is connected to a callback function
386 // and this callback function consumes the event.
387 actor.TouchSignal().Connect( &TestCallback );
389 // * Button's pressed signal is connected to a callback function
390 // which also consumes the event.
391 // * Changes the sensitiveness of the button to false.
392 TETButtonPressed tetButtonPressed( actor, TETButtonPressed::SENSITIVENESS );
393 tetButton.PressedSignal().Connect( &tetButtonPressed, &TETButtonPressed::Callback );
395 // Initializes TET state.
396 gOnTouchPointInterrupted = false;
397 tetButton.SetSensitive( true );
399 Dali::Integration::TouchEvent event;
403 // Test a down point inside the button which is also consumed by the actor, and an up point
404 // consumed only by the actor. gOnTouchPointInterrupted should be true (Button receives an
407 application.SendNotification();
408 application.Render();
410 // A down event is sent inside the button's boundary.
412 event = Dali::Integration::TouchEvent();
413 event.AddPoint( GetPointDownInside() );
415 // flush the queue and render once
416 application.SendNotification();
417 application.Render();
418 application.ProcessEvent( event );
420 // An up event is sent outside the button's boundary but inside the actor's one.
422 event = Dali::Integration::TouchEvent();
423 event.AddPoint( GetPointUpOutside() );
425 // flush the queue and render once
426 application.SendNotification();
427 application.Render();
428 application.ProcessEvent( event );
430 DALI_TEST_CHECK( gOnTouchPointInterrupted );
432 // Test a down point inside the button which is also consumed by the actor, and a motion point
433 // consumed only by the actor. gOnTouchPointInterrupted should be true (Button receives an
436 // Initializes TET state.
437 gOnTouchPointInterrupted = false;
438 actor.SetSensitive( true );
439 tetButton.SetSensitive( true );
441 application.SendNotification();
442 application.Render();
444 // A down event is sent inside the button's boundary.
446 event = Dali::Integration::TouchEvent();
447 event.AddPoint( GetPointDownInside() );
449 // flush the queue and render once
450 application.SendNotification();
451 application.Render();
452 application.ProcessEvent( event );
454 // A motion event is sent outside the button's boundary but inside the actor's one.
456 event = Dali::Integration::TouchEvent();
457 event.AddPoint( GetPointMotionOut() );
459 // flush the queue and render once
460 application.SendNotification();
461 application.Render();
462 application.ProcessEvent( event );
464 DALI_TEST_CHECK( gOnTouchPointInterrupted );
466 // Test a down point inside the button which is also consumed by the actor, and an up point
467 // also inside the button and consumed by the actor. gOnTouchPointInterrupted should be false.
469 // Initializes TET state.
470 gOnTouchPointInterrupted = false;
471 actor.SetSensitive( true );
472 tetButton.SetSensitive( true );
474 // A down event is sent inside the button's boundary.
476 event = Dali::Integration::TouchEvent();
477 event.AddPoint( GetPointDownInside() );
479 // flush the queue and render once
480 application.SendNotification();
481 application.Render();
482 application.ProcessEvent( event );
484 actor.SetSensitive( true );
485 // An up event is sent inside the button's boundary.
487 event = Dali::Integration::TouchEvent();
488 event.AddPoint( GetPointUpInside() );
490 // flush the queue and render once
491 application.SendNotification();
492 application.Render();
493 application.ProcessEvent( event );
495 DALI_TEST_CHECK( !gOnTouchPointInterrupted );
499 int UtcDaliPushButtonInterruptEventWhenNonVisible(void)
501 ToolkitTestApplication application;
502 tet_infoline(" UtcDaliPushButtonInterruptEventWhenNonVisible");
504 // Does same test as above but changing the visibility instead the sensitiveness.
506 // * Creates an actor which contains a button.
507 // * The size of the actor is bigger than the button.
508 // * The button's boundary is contained in the actor's one.
509 Actor actor = Actor::New();
510 TETButton tetButton = Toolkit::TETButton::New();
512 actor.SetName( "Actor" );
513 tetButton.SetName( "TETButton" );
515 actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
516 actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
517 actor.SetPosition( 0, 0 );
518 actor.SetSize( 400, 800 );
520 tetButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
521 tetButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
522 tetButton.SetPosition( 240, 400 );
523 tetButton.SetSize( 100, 100 );
525 actor.Add( tetButton );
526 Stage::GetCurrent().Add( actor );
528 // * Actor's touch event is connected to a callback function
529 // and this callback function consumes the event.
530 actor.TouchSignal().Connect( &TestCallback );
532 // * Button's pressed signal is connected to a callback function
533 // which also consumes the event.
534 // * Changes the visibility of the button to false.
535 TETButtonPressed tetButtonPressed( tetButton, TETButtonPressed::VISIBILITY );
536 tetButton.PressedSignal().Connect( &tetButtonPressed, &TETButtonPressed::Callback );
538 // Initializes TET state.
539 gOnTouchPointInterrupted = false;
540 tetButton.SetVisible( true );
542 Dali::Integration::TouchEvent event;
546 // Test a down point inside the button which is also consumed by the actor, and an up point
547 // consumed only by the actor. gOnTouchPointInterrupted should be true (Button receives an
550 application.SendNotification();
551 application.Render();
553 // A down event is sent inside the button's boundary.
555 event = Dali::Integration::TouchEvent();
556 event.AddPoint( GetPointDownInside() );
558 // flush the queue and render once
559 application.SendNotification();
560 application.Render();
561 application.ProcessEvent( event );
563 // More renders are needed in order to allow the node of the actor to become invisible.
564 application.SendNotification();
565 application.Render();
566 application.SendNotification();
567 application.Render();
568 application.SendNotification();
569 application.Render();
571 // An up event is sent outside the button's boundary but inside the actor's one.
573 event = Dali::Integration::TouchEvent();
574 event.AddPoint( GetPointUpOutside() );
576 // flush the queue and render once
577 application.SendNotification();
578 application.Render();
579 application.ProcessEvent( event );
581 DALI_TEST_CHECK( gOnTouchPointInterrupted );
583 // Test a down point inside the button which is also consumed by the actor, and a motion point
584 // consumed only by the actor. gOnTouchPointInterrupted should be true (Button receives an
587 // Initializes TET state.
588 gOnTouchPointInterrupted = false;
589 tetButton.SetVisible( true );
591 application.SendNotification();
592 application.Render();
593 application.SendNotification();
594 application.Render();
595 application.SendNotification();
596 application.Render();
598 // A down event is sent inside the button's boundary.
600 event = Dali::Integration::TouchEvent();
601 event.AddPoint( GetPointDownInside() );
603 // flush the queue and render once
604 application.SendNotification();
605 application.Render();
606 application.ProcessEvent( event );
608 // More renders are needed in order to allow the node of the actor to become invisible.
609 application.SendNotification();
610 application.Render();
611 application.SendNotification();
612 application.Render();
613 application.SendNotification();
614 application.Render();
616 // A motion event is sent outside the button's boundary but inside the actor's one.
618 event = Dali::Integration::TouchEvent();
619 event.AddPoint( GetPointMotionOut() );
621 // flush the queue and render once
622 application.SendNotification();
623 application.Render();
624 application.ProcessEvent( event );
626 DALI_TEST_CHECK( gOnTouchPointInterrupted );
628 // Test a down point inside the button which is also consumed by the actor, and an up point
629 // also inside the button and consumed by the actor. gOnTouchPointInterrupted should be false.
631 // Initializes TET state.
632 gOnTouchPointInterrupted = false;
633 tetButton.SetVisible( true );
635 application.SendNotification();
636 application.Render();
637 application.SendNotification();
638 application.Render();
639 application.SendNotification();
640 application.Render();
642 // A down event is sent inside the button's boundary.
644 event = Dali::Integration::TouchEvent();
645 event.AddPoint( GetPointDownInside() );
647 // flush the queue and render once
648 application.SendNotification();
649 application.Render();
650 application.ProcessEvent( event );
652 tetButton.SetVisible( true );
654 application.SendNotification();
655 application.Render();
656 application.SendNotification();
657 application.Render();
658 application.SendNotification();
659 application.Render();
661 // An up event is sent inside the button's boundary.
663 event = Dali::Integration::TouchEvent();
664 event.AddPoint( GetPointUpInside() );
666 // flush the queue and render once
667 application.SendNotification();
668 application.Render();
669 application.ProcessEvent( event );
671 DALI_TEST_CHECK( !gOnTouchPointInterrupted );
675 int UtcDaliPushButtonProperties(void)
677 ToolkitTestApplication application;
679 PushButton button = PushButton::New();
680 Stage::GetCurrent().Add( button );
682 // Button::PROPERTY_AUTO_REPEATING
683 button.SetAutoRepeating( false );
684 DALI_TEST_CHECK( ! button.GetProperty< bool >( Button::Property::AUTO_REPEATING ) );
685 button.SetProperty( Button::Property::AUTO_REPEATING, true );
686 DALI_TEST_CHECK( button.IsAutoRepeating() ) ;
687 DALI_TEST_CHECK( button.GetProperty< bool >( Button::Property::AUTO_REPEATING ) );
689 // Button::PROPERTY_INITIAL_AUTO_REPEATING_DELAY
690 button.SetInitialAutoRepeatingDelay( 10.0f );
691 DALI_TEST_EQUALS( 10.0f, button.GetProperty< float >( Button::Property::INITIAL_AUTO_REPEATING_DELAY ), TEST_LOCATION );
692 button.SetProperty( Button::Property::INITIAL_AUTO_REPEATING_DELAY, 25.0f );
693 DALI_TEST_EQUALS( 25.0f, button.GetInitialAutoRepeatingDelay(), TEST_LOCATION );
694 DALI_TEST_EQUALS( 25.0f, button.GetProperty< float >( Button::Property::INITIAL_AUTO_REPEATING_DELAY ), TEST_LOCATION );
696 // Button::PROPERTY_NEXT_AUTO_REPEATING_DELAY
697 button.SetNextAutoRepeatingDelay( 3.0f );
698 DALI_TEST_EQUALS( 3.0f, button.GetProperty< float >( Button::Property::NEXT_AUTO_REPEATING_DELAY ), TEST_LOCATION );
699 button.SetProperty( Button::Property::NEXT_AUTO_REPEATING_DELAY, 4.0f );
700 DALI_TEST_EQUALS( 4.0f, button.GetNextAutoRepeatingDelay(), TEST_LOCATION );
701 DALI_TEST_EQUALS( 4.0f, button.GetProperty< float >( Button::Property::NEXT_AUTO_REPEATING_DELAY ), TEST_LOCATION );
703 // Button::PROPERTY_TOGGLABLE
704 button.SetTogglableButton( false );
705 DALI_TEST_CHECK( ! button.GetProperty< bool >( Button::Property::TOGGLABLE ) );
706 button.SetProperty( Button::Property::TOGGLABLE, true );
707 DALI_TEST_CHECK( button.IsTogglableButton() ) ;
708 DALI_TEST_CHECK( button.GetProperty< bool >( Button::Property::TOGGLABLE ) );
710 // Button::PROPERTY_SELECTED
711 button.SetSelected( false );
712 DALI_TEST_CHECK( ! button.GetProperty< bool >( Button::Property::SELECTED ) );
713 button.SetProperty( Button::Property::SELECTED, true );
714 DALI_TEST_CHECK( button.IsSelected() ) ;
715 DALI_TEST_CHECK( button.GetProperty< bool >( Button::Property::SELECTED ) );