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 const Dali::TouchPoint pointDownInside( 0, TouchPoint::Down, 240, 400 );
42 const Dali::TouchPoint pointUpInside( 0, TouchPoint::Up, 240, 400 );
43 const Dali::TouchPoint pointLeave( 0, TouchPoint::Leave, 240, 400 );
44 const Dali::TouchPoint pointEnter( 0, TouchPoint::Motion, 240, 400 );
45 const Dali::TouchPoint pointMotionOut( 0, TouchPoint::Motion, 10, 10 );
46 const Dali::TouchPoint pointDownOutside( 0, TouchPoint::Down, 10, 10 );
47 const Dali::TouchPoint pointUpOutside( 0, TouchPoint::Up, 10, 10 );
51 //////////////////////////////////////////////////////////
55 static bool gOnTouchPointInterrupted = false;
70 * Creates a PushButton to test if interrupt events are handled correctly.
72 class TETButton : public PushButton
76 typedef Signal< bool ( PushButton ) > ButtonSignalType;
78 ButtonSignalType& PressedSignal();
81 * Default constructor.
88 TETButton( const PushButton& button );
91 * Assignment operator.
93 TETButton& operator=( const TETButton& button );
96 * Creates and initializes a new button.
98 static TETButton New();
101 * Down cast to TETButton.
103 static TETButton DownCast( BaseHandle handle );
106 * Creates a handle using the Toolkit::Internal implementation.
107 * @param[in] implementation The Control implementation.
109 TETButton( Internal::TETButton& implementation );
112 * Allows the creation of this Control from an Internal::CustomActor pointer.
113 * @param[in] internal A pointer to the internal CustomActor.
115 TETButton( Dali::Internal::CustomActor* internal );
122 * Internal implementation
124 class TETButton : public PushButton
128 * Construct a new Button.
133 * A reference counted object may only be deleted by calling Unreference()
135 virtual ~TETButton();
138 * Creates an internal button.
140 static Toolkit::TETButton New();
143 * @return the pressed signal.
145 Toolkit::TETButton::ButtonSignalType& PressedSignal();
148 * Callback called when an interrupt events is received.
150 void OnTouchPointInterrupted();
153 * Callback received when a down event is received.
157 Toolkit::TETButton::ButtonSignalType mPressedSignal; ///< Signal emitted when the button is pressed.
160 } // namespace Internal
162 TETButton::TETButton()
166 TETButton::TETButton( const PushButton& button )
167 : PushButton( button )
171 TETButton& TETButton::operator=( const TETButton& button )
173 if( &button != this )
175 PushButton::operator=( button );
180 TETButton TETButton::New()
182 return Internal::TETButton::New();
185 TETButton TETButton::DownCast( BaseHandle handle )
187 return Control::DownCast<TETButton, Internal::TETButton>(handle);
190 TETButton::ButtonSignalType& TETButton::PressedSignal()
192 TETButton button( *this );
193 DALI_ASSERT_ALWAYS( button );
195 Dali::RefObject& handle = button.GetImplementation();
197 return static_cast<Toolkit::Internal::TETButton&>( handle ).PressedSignal();
200 TETButton::TETButton( Internal::TETButton& implementation )
201 : PushButton( implementation )
204 TETButton::TETButton( Dali::Internal::CustomActor* internal )
205 : PushButton( internal )
207 VerifyCustomActorPointer<Internal::TETButton>(internal);
213 TETButton::TETButton()
219 TETButton::~TETButton()
223 Toolkit::TETButton TETButton::New()
225 // Create the implementation, temporarily owned on stack
226 IntrusivePtr< TETButton > internalTETButton = new TETButton();
228 // Pass ownership to CustomActor
229 Dali::Toolkit::TETButton tetButton( *internalTETButton );
231 // Second-phase init of the implementation
232 // This can only be done after the CustomActor connection has been made...
233 internalTETButton->Initialize();
238 Toolkit::TETButton::ButtonSignalType& TETButton::PressedSignal()
240 return mPressedSignal;
243 void TETButton::OnButtonDown()
245 Toolkit::TETButton handle( GetOwner() );
248 mPressedSignal.Emit( handle );
251 void TETButton::OnTouchPointInterrupted()
253 gOnTouchPointInterrupted = true;
256 } // namespace Internal
258 } // namespace Toolkit
265 class TETButtonPressed : public Dali::ConnectionTracker
274 TETButtonPressed( Actor actor, Test test )
280 bool Callback( PushButton button )
286 mActor.SetSensitive( false );
291 std::cout <<"VISIBILITY false" << std::endl;
292 mActor.SetVisible( false );
307 static bool TestCallback(Actor actor, const TouchEvent& event)
314 //////////////////////////////////////////////////////////
316 int UtcDaliPushButtonDownCast(void)
318 ToolkitTestApplication application;
319 tet_infoline(" UtcDaliPushButtonDownCast");
321 TETButton tetButton= Toolkit::TETButton::New();
323 BaseHandle object(tetButton);
325 TETButton tetButton2 = TETButton::DownCast( object );
326 DALI_TEST_CHECK(tetButton2);
328 TETButton tetButton3 = DownCast< TETButton >(object);
329 DALI_TEST_CHECK(tetButton3);
333 int UtcDaliPushButtonInterruptEventWhenInsensitive(void)
335 ToolkitTestApplication application;
336 tet_infoline(" UtcDaliPushButtonInterruptEventWhenInsensitive");
338 // * Creates an actor which contains a button.
339 // * The size of the actor is bigger than the button.
340 // * The button's boundary is contained in the actor's one.
341 Actor actor = Actor::New();
342 TETButton tetButton= Toolkit::TETButton::New();
344 actor.SetName( "Actor" );
345 tetButton.SetName( "TETButton" );
347 actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
348 actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
349 actor.SetPosition( 0, 0 );
350 actor.SetSize( 400, 800 );
352 tetButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
353 tetButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
354 tetButton.SetPosition( 240, 400 );
355 tetButton.SetSize( 100, 100 );
357 actor.Add( tetButton );
358 Stage::GetCurrent().Add( actor );
360 // * Actor's touch event is connected to a callback function
361 // and this callback function consumes the event.
362 actor.TouchedSignal().Connect( &TestCallback );
364 // * Button's pressed signal is connected to a callback function
365 // which also consumes the event.
366 // * Changes the sensitiveness of the button to false.
367 TETButtonPressed tetButtonPressed( actor, TETButtonPressed::SENSITIVENESS );
368 tetButton.PressedSignal().Connect( &tetButtonPressed, &TETButtonPressed::Callback );
370 // Initializes TET state.
371 gOnTouchPointInterrupted = false;
372 tetButton.SetSensitive( true );
374 Dali::Integration::TouchEvent event;
378 // Test a down point inside the button which is also consumed by the actor, and an up point
379 // consumed only by the actor. gOnTouchPointInterrupted should be true (Button receives an
382 application.SendNotification();
383 application.Render();
385 // A down event is sent inside the button's boundary.
387 event = Dali::Integration::TouchEvent();
388 event.AddPoint( pointDownInside );
390 // flush the queue and render once
391 application.SendNotification();
392 application.Render();
393 application.ProcessEvent( event );
395 // An up event is sent outside the button's boundary but inside the actor's one.
397 event = Dali::Integration::TouchEvent();
398 event.AddPoint( pointUpOutside );
400 // flush the queue and render once
401 application.SendNotification();
402 application.Render();
403 application.ProcessEvent( event );
405 DALI_TEST_CHECK( gOnTouchPointInterrupted );
407 // Test a down point inside the button which is also consumed by the actor, and a motion point
408 // consumed only by the actor. gOnTouchPointInterrupted should be true (Button receives an
411 // Initializes TET state.
412 gOnTouchPointInterrupted = false;
413 actor.SetSensitive( true );
414 tetButton.SetSensitive( true );
416 application.SendNotification();
417 application.Render();
419 // A down event is sent inside the button's boundary.
421 event = Dali::Integration::TouchEvent();
422 event.AddPoint( pointDownInside );
424 // flush the queue and render once
425 application.SendNotification();
426 application.Render();
427 application.ProcessEvent( event );
429 // A motion event is sent outside the button's boundary but inside the actor's one.
431 event = Dali::Integration::TouchEvent();
432 event.AddPoint( pointMotionOut );
434 // flush the queue and render once
435 application.SendNotification();
436 application.Render();
437 application.ProcessEvent( event );
439 DALI_TEST_CHECK( gOnTouchPointInterrupted );
441 // Test a down point inside the button which is also consumed by the actor, and an up point
442 // also inside the button and consumed by the actor. gOnTouchPointInterrupted should be false.
444 // Initializes TET state.
445 gOnTouchPointInterrupted = false;
446 actor.SetSensitive( true );
447 tetButton.SetSensitive( true );
449 // A down event is sent inside the button's boundary.
451 event = Dali::Integration::TouchEvent();
452 event.AddPoint( pointDownInside );
454 // flush the queue and render once
455 application.SendNotification();
456 application.Render();
457 application.ProcessEvent( event );
459 actor.SetSensitive( true );
460 // An up event is sent inside the button's boundary.
462 event = Dali::Integration::TouchEvent();
463 event.AddPoint( pointUpInside );
465 // flush the queue and render once
466 application.SendNotification();
467 application.Render();
468 application.ProcessEvent( event );
470 DALI_TEST_CHECK( !gOnTouchPointInterrupted );
474 int UtcDaliPushButtonInterruptEventWhenNonVisible(void)
476 ToolkitTestApplication application;
477 tet_infoline(" UtcDaliPushButtonInterruptEventWhenNonVisible");
479 // Does same test as above but changing the visibility instead the sensitiveness.
481 // * Creates an actor which contains a button.
482 // * The size of the actor is bigger than the button.
483 // * The button's boundary is contained in the actor's one.
484 Actor actor = Actor::New();
485 TETButton tetButton = Toolkit::TETButton::New();
487 actor.SetName( "Actor" );
488 tetButton.SetName( "TETButton" );
490 actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
491 actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
492 actor.SetPosition( 0, 0 );
493 actor.SetSize( 400, 800 );
495 tetButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
496 tetButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
497 tetButton.SetPosition( 240, 400 );
498 tetButton.SetSize( 100, 100 );
500 actor.Add( tetButton );
501 Stage::GetCurrent().Add( actor );
503 // * Actor's touch event is connected to a callback function
504 // and this callback function consumes the event.
505 actor.TouchedSignal().Connect( &TestCallback );
507 // * Button's pressed signal is connected to a callback function
508 // which also consumes the event.
509 // * Changes the visibility of the button to false.
510 TETButtonPressed tetButtonPressed( tetButton, TETButtonPressed::VISIBILITY );
511 tetButton.PressedSignal().Connect( &tetButtonPressed, &TETButtonPressed::Callback );
513 // Initializes TET state.
514 gOnTouchPointInterrupted = false;
515 tetButton.SetVisible( true );
517 Dali::Integration::TouchEvent event;
521 // Test a down point inside the button which is also consumed by the actor, and an up point
522 // consumed only by the actor. gOnTouchPointInterrupted should be true (Button receives an
525 application.SendNotification();
526 application.Render();
528 // A down event is sent inside the button's boundary.
530 event = Dali::Integration::TouchEvent();
531 event.AddPoint( pointDownInside );
533 // flush the queue and render once
534 application.SendNotification();
535 application.Render();
536 application.ProcessEvent( event );
538 // More renders are needed in order to allow the node of the actor to become invisible.
539 application.SendNotification();
540 application.Render();
541 application.SendNotification();
542 application.Render();
543 application.SendNotification();
544 application.Render();
546 // An up event is sent outside the button's boundary but inside the actor's one.
548 event = Dali::Integration::TouchEvent();
549 event.AddPoint( pointUpOutside );
551 // flush the queue and render once
552 application.SendNotification();
553 application.Render();
554 application.ProcessEvent( event );
556 DALI_TEST_CHECK( gOnTouchPointInterrupted );
558 // Test a down point inside the button which is also consumed by the actor, and a motion point
559 // consumed only by the actor. gOnTouchPointInterrupted should be true (Button receives an
562 // Initializes TET state.
563 gOnTouchPointInterrupted = false;
564 tetButton.SetVisible( true );
566 application.SendNotification();
567 application.Render();
568 application.SendNotification();
569 application.Render();
570 application.SendNotification();
571 application.Render();
573 // A down event is sent inside the button's boundary.
575 event = Dali::Integration::TouchEvent();
576 event.AddPoint( pointDownInside );
578 // flush the queue and render once
579 application.SendNotification();
580 application.Render();
581 application.ProcessEvent( event );
583 // More renders are needed in order to allow the node of the actor to become invisible.
584 application.SendNotification();
585 application.Render();
586 application.SendNotification();
587 application.Render();
588 application.SendNotification();
589 application.Render();
591 // A motion event is sent outside the button's boundary but inside the actor's one.
593 event = Dali::Integration::TouchEvent();
594 event.AddPoint( pointMotionOut );
596 // flush the queue and render once
597 application.SendNotification();
598 application.Render();
599 application.ProcessEvent( event );
601 DALI_TEST_CHECK( gOnTouchPointInterrupted );
603 // Test a down point inside the button which is also consumed by the actor, and an up point
604 // also inside the button and consumed by the actor. gOnTouchPointInterrupted should be false.
606 // Initializes TET state.
607 gOnTouchPointInterrupted = false;
608 tetButton.SetVisible( true );
610 application.SendNotification();
611 application.Render();
612 application.SendNotification();
613 application.Render();
614 application.SendNotification();
615 application.Render();
617 // A down event is sent inside the button's boundary.
619 event = Dali::Integration::TouchEvent();
620 event.AddPoint( pointDownInside );
622 // flush the queue and render once
623 application.SendNotification();
624 application.Render();
625 application.ProcessEvent( event );
627 tetButton.SetVisible( true );
629 application.SendNotification();
630 application.Render();
631 application.SendNotification();
632 application.Render();
633 application.SendNotification();
634 application.Render();
636 // An up event is sent inside the button's boundary.
638 event = Dali::Integration::TouchEvent();
639 event.AddPoint( pointUpInside );
641 // flush the queue and render once
642 application.SendNotification();
643 application.Render();
644 application.ProcessEvent( event );
646 DALI_TEST_CHECK( !gOnTouchPointInterrupted );
650 int UtcDaliPushButtonProperties(void)
652 ToolkitTestApplication application;
654 PushButton button = PushButton::New();
655 Stage::GetCurrent().Add( button );
657 // Button::PROPERTY_AUTO_REPEATING
658 button.SetAutoRepeating( false );
659 DALI_TEST_CHECK( ! button.GetProperty< bool >( Button::Property::AUTO_REPEATING ) );
660 button.SetProperty( Button::Property::AUTO_REPEATING, true );
661 DALI_TEST_CHECK( button.IsAutoRepeating() ) ;
662 DALI_TEST_CHECK( button.GetProperty< bool >( Button::Property::AUTO_REPEATING ) );
664 // Button::PROPERTY_INITIAL_AUTO_REPEATING_DELAY
665 button.SetInitialAutoRepeatingDelay( 10.0f );
666 DALI_TEST_EQUALS( 10.0f, button.GetProperty< float >( Button::Property::INITIAL_AUTO_REPEATING_DELAY ), TEST_LOCATION );
667 button.SetProperty( Button::Property::INITIAL_AUTO_REPEATING_DELAY, 25.0f );
668 DALI_TEST_EQUALS( 25.0f, button.GetInitialAutoRepeatingDelay(), TEST_LOCATION );
669 DALI_TEST_EQUALS( 25.0f, button.GetProperty< float >( Button::Property::INITIAL_AUTO_REPEATING_DELAY ), TEST_LOCATION );
671 // Button::PROPERTY_NEXT_AUTO_REPEATING_DELAY
672 button.SetNextAutoRepeatingDelay( 3.0f );
673 DALI_TEST_EQUALS( 3.0f, button.GetProperty< float >( Button::Property::NEXT_AUTO_REPEATING_DELAY ), TEST_LOCATION );
674 button.SetProperty( Button::Property::NEXT_AUTO_REPEATING_DELAY, 4.0f );
675 DALI_TEST_EQUALS( 4.0f, button.GetNextAutoRepeatingDelay(), TEST_LOCATION );
676 DALI_TEST_EQUALS( 4.0f, button.GetProperty< float >( Button::Property::NEXT_AUTO_REPEATING_DELAY ), TEST_LOCATION );
678 // Button::PROPERTY_TOGGLABLE
679 button.SetTogglableButton( false );
680 DALI_TEST_CHECK( ! button.GetProperty< bool >( Button::Property::TOGGLABLE ) );
681 button.SetProperty( Button::Property::TOGGLABLE, true );
682 DALI_TEST_CHECK( button.IsTogglableButton() ) ;
683 DALI_TEST_CHECK( button.GetProperty< bool >( Button::Property::TOGGLABLE ) );
685 // Button::PROPERTY_SELECTED
686 button.SetSelected( false );
687 DALI_TEST_CHECK( ! button.GetProperty< bool >( Button::Property::SELECTED ) );
688 button.SetProperty( Button::Property::SELECTED, true );
689 DALI_TEST_CHECK( button.IsSelected() ) ;
690 DALI_TEST_CHECK( button.GetProperty< bool >( Button::Property::SELECTED ) );