utc-Dali-BubbleEmitter.cpp
utc-Dali-Builder.cpp
utc-Dali-CheckBoxButton.cpp
+ utc-Dali-ConfirmationPopup.cpp
utc-Dali-CubeTransitionEffect.cpp
utc-Dali-EffectsView.cpp
utc-Dali-GaussianBlurView.cpp
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
typedef IntrusivePtr<Timer> TimerPtr;
+Dali::Timer::TimerSignalType gTickSignal;
+
/**
* Implementation of the timer
*/
class Timer : public BaseObject
{
public:
+ void MockEmitSignal();
+
+public:
static TimerPtr New( unsigned int milliSec );
Timer( unsigned int milliSec );
virtual ~Timer();
private: // Data
- Dali::Timer::TimerSignalType mTickSignal;
unsigned int mInterval;
};
TimerPtr Timer::New( unsigned int milliSec )
{
- TimerPtr timerImpl = new Timer(10);
+ TimerPtr timerImpl = new Timer( milliSec );
return timerImpl;
}
Dali::Timer::TimerSignalType& Timer::TickSignal()
{
- return mTickSignal;
+ return gTickSignal;
+}
+
+// Mock setup functions:
+
+void Timer::MockEmitSignal()
+{
+ gTickSignal.Emit();
}
+
} // namespace Adaptor
} // namespace Internal
{
}
+// Mock setup functions:
+
+void Timer::MockEmitSignal()
+{
+ Internal::Adaptor::GetImplementation( *this ).MockEmitSignal();
+}
+
} // namespace Dali
#define __DALI_TOOLKIT_TOOLKIT_TIMER_H__
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
class Timer : public BaseHandle
{
public:
+ void MockEmitSignal();
+
+public:
typedef Signal< bool () > TimerSignalType;
Timer();
static Timer New( unsigned int milliSec );
application.Render();
Vector3 size = pushButton.GetCurrentSize();
- tet_printf( "todor: size: %f,%f", size.width, size.height );
DALI_TEST_EQUALS( size.width, 20.f, TEST_LOCATION );
DALI_TEST_EQUALS( size.height, 20.f, TEST_LOCATION );
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdlib.h>
+
+// Need to override adaptor classes for toolkit test harness, so include
+// test harness headers before dali headers.
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/popup/confirmation-popup.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+void utc_dali_toolkit_confirmation_popup_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_confirmation_popup_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+namespace
+{
+
+static bool gObjectCreatedCallBackCalled;
+
+static void TestCallback(BaseHandle handle)
+{
+ gObjectCreatedCallBackCalled = true;
+}
+
+static bool gSignalReceivedOK;
+static bool gSignalReceivedCancel;
+
+/**
+ * A connection tracker is required when connecting to a signal with a functor.
+ */
+class TestConnectionTrackerObject : public ConnectionTracker
+{
+};
+
+/**
+ * This functor is used to test the confirmation popup's OK signal connection.
+ */
+struct ConfirmationPopupOKTestFunctor
+{
+ ConfirmationPopupOKTestFunctor()
+ {
+ }
+
+ void operator()()
+ {
+ gSignalReceivedOK = true;
+ }
+};
+
+/**
+ * This functor is used to test the confirmation popup's Cancel signal connection.
+ */
+struct ConfirmationPopupCancelTestFunctor
+{
+ ConfirmationPopupCancelTestFunctor()
+ {
+ }
+
+ void operator()()
+ {
+ gSignalReceivedCancel = true;
+ }
+};
+
+} // unnamed namespace.
+
+
+int UtcDaliConfirmationPopupNewP( void )
+{
+ ToolkitTestApplication application;
+ tet_infoline( " UtcDaliConfirmationPopupNewP" );
+
+ // Create the ConfirmationPopup.
+ ConfirmationPopup popup;
+
+ DALI_TEST_CHECK( !popup );
+
+ popup = ConfirmationPopup::New();
+
+ DALI_TEST_CHECK( popup );
+
+ ConfirmationPopup popup2( popup );
+
+ DALI_TEST_CHECK( popup2 == popup );
+
+ // Additional check to ensure object is created by checking if it's registered.
+ ObjectRegistry registry = Stage::GetCurrent().GetObjectRegistry();
+ DALI_TEST_CHECK( registry );
+
+ gObjectCreatedCallBackCalled = false;
+ registry.ObjectCreatedSignal().Connect( &TestCallback );
+ {
+ ConfirmationPopup popup = ConfirmationPopup::New();
+ }
+ DALI_TEST_CHECK( gObjectCreatedCallBackCalled );
+ END_TEST;
+}
+
+int UtcDaliConfirmationPopupDestructorP( void )
+{
+ ToolkitTestApplication application;
+ tet_infoline( " UtcDaliConfirmationPopupDestructorP" );
+
+ ConfirmationPopup* popup = new ConfirmationPopup();
+ delete popup;
+
+ DALI_TEST_CHECK( true );
+ END_TEST;
+}
+
+int UtcDaliConfirmationPopupDownCastP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( " UtcDaliConfirmationPopupDownCastP" );
+
+ Handle handle = ConfirmationPopup::New();
+
+ ConfirmationPopup popup = ConfirmationPopup::DownCast( handle );
+
+ DALI_TEST_CHECK( popup == handle );
+ END_TEST;
+}
+
+int UtcDaliConfirmationPopupDynamicSignalGenerationP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( " UtcDaliConfirmationPopupDynamicSignalGenerationP" );
+
+ ConfirmationPopup popup = ConfirmationPopup::New();
+
+ TextLabel titleActor = TextLabel::New( "Title" );
+ popup.SetTitle( titleActor );
+
+ TextLabel contentActor = TextLabel::New( "Content" );
+ popup.SetContent( contentActor );
+
+ Actor footerActor = Actor::New();
+
+ // The confirmation popup can use any control type for the ok or cancel buttons.
+ // It requires that the name is "control-ok" to provide the "control-signal-ok" signal.
+ PushButton buttonOK = PushButton::New();
+ buttonOK.SetName( "control-ok" );
+ footerActor.Add( buttonOK );
+
+ PushButton buttonCancel = PushButton::New();
+ buttonCancel.SetName( "control-cancel" );
+ footerActor.Add( buttonCancel );
+
+ popup.SetFooter( footerActor );
+
+ // Tell the confirmation popup to connect to the signal in our button called "on-stage".
+ popup.SetProperty( Toolkit::ConfirmationPopup::Property::CONNECT_SIGNAL_OK_SELECTED, "on-stage" );
+
+ // Connect to the confirmation popup's OK signal. This signal is dynamically created upon connection.
+ gSignalReceivedOK = false;
+ gSignalReceivedCancel = false;
+ TestConnectionTrackerObject* testTracker = new TestConnectionTrackerObject();
+ popup.ConnectSignal( testTracker, "control-signal-ok", ConfirmationPopupOKTestFunctor() );
+
+ // Check no signal has occurred yet.
+ DALI_TEST_CHECK( !gSignalReceivedOK );
+ DALI_TEST_CHECK( !gSignalReceivedCancel );
+
+ // Provoke the signal.
+ Stage::GetCurrent().Add( popup );
+
+ // Check the signal has occurred.
+ DALI_TEST_CHECK( gSignalReceivedOK );
+ DALI_TEST_CHECK( !gSignalReceivedCancel );
+
+ // Remove the popup from the stage, and connect the cancel signal.
+ popup.Unparent();
+ popup.SetProperty( Toolkit::ConfirmationPopup::Property::CONNECT_SIGNAL_CANCEL_SELECTED, "on-stage" );
+ popup.ConnectSignal( testTracker, "control-signal-cancel", ConfirmationPopupCancelTestFunctor() );
+
+ // Check the cancel signal has not occurred yet.
+ DALI_TEST_CHECK( gSignalReceivedOK );
+ DALI_TEST_CHECK( !gSignalReceivedCancel );
+
+ // Provoke the signal.
+ Stage::GetCurrent().Add( popup );
+
+ // Check the cancel signal has occurred.
+ DALI_TEST_CHECK( gSignalReceivedOK );
+ DALI_TEST_CHECK( gSignalReceivedCancel );
+
+ END_TEST;
+}
+
+int UtcDaliConfirmationPopupDynamicSignalGenerationN(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( " UtcDaliConfirmationPopupDynamicSignalGenerationN" );
+
+ ConfirmationPopup popup = ConfirmationPopup::New();
+
+ TextLabel titleActor = TextLabel::New( "Title" );
+ popup.SetTitle( titleActor );
+
+ TextLabel contentActor = TextLabel::New( "Content" );
+ popup.SetContent( contentActor );
+
+ Actor footerActor = Actor::New();
+
+ PushButton buttonOK = PushButton::New();
+ buttonOK.SetName( "control-ok-misnamed" );
+ popup.SetFooter( buttonOK );
+
+ // Tell the confirmation popup to connect to the signal in our button called "on-stage".
+ popup.SetProperty( Toolkit::ConfirmationPopup::Property::CONNECT_SIGNAL_OK_SELECTED, "on-stage" );
+
+ // Connect to the confirmation popup's OK signal.
+ gSignalReceivedOK = false;
+
+ // The connection will fail at this point as no actor with the name "control-ok" will be located.
+ TestConnectionTrackerObject* testTracker = new TestConnectionTrackerObject();
+ popup.ConnectSignal( testTracker, "control-signal-ok", ConfirmationPopupOKTestFunctor() );
+
+ // Check no signal has occurred yet.
+ DALI_TEST_CHECK( !gSignalReceivedOK );
+
+ // Provoke the signal.
+ Stage::GetCurrent().Add( popup );
+
+ // Check the signal has still not occurred, as our button was incorrectly named.
+ DALI_TEST_CHECK( !gSignalReceivedOK );
+
+ END_TEST;
+}
+
+
+
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
*/
-#include <iostream>
#include <stdlib.h>
// Need to override adaptor classes for toolkit test harness, so include
// test harness headers before dali headers.
#include <dali-toolkit-test-suite-utils.h>
+#include "dali-toolkit-test-utils/toolkit-timer.h"
#include <dali.h>
#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/devel-api/scripting/scripting.h>
#include <dali-toolkit/dali-toolkit.h>
#include <dali-toolkit/devel-api/controls/popup/popup.h>
}
const int RENDER_FRAME_INTERVAL = 10; ///< Duration of each frame in ms.
-const int RENDER_ANIMATION_TEST_DURATION_MS = 1000; ///< 1000ms to test animation
+const int RENDER_ANIMATION_TEST_DURATION_MS = 2000; ///< 2000ms to test animation.
const int RENDER_ANIMATION_TEST_DURATION_FRAMES = RENDER_ANIMATION_TEST_DURATION_MS / RENDER_FRAME_INTERVAL; ///< equivalent frames.
const Vector3 DEFAULT_BUTTON_SIZE(100.0f, 50.0f, 0.0f);
const Dali::TouchPoint pointDownOutside( 0, TouchPoint::Down, 10.0f, 10.0f );
const Dali::TouchPoint pointUpOutside( 0, TouchPoint::Up, 10.0f, 10.0f );
/**
- * Counts how many descendents root Actor has, including
+ * Counts how many descendants root Actor has, including
* itself.
*
* @param[in] root The root actor to count from.
- * @return The number of descendents including root actor itself.
+ * @return The number of descendants including root actor itself.
*/
int DescendentCount(const Actor& root)
{
return (child == ancestor);
}
+static Toolkit::Popup::DisplayState gPopupState = Toolkit::Popup::HIDDEN;
+static bool gTouchedOutside;
-static bool gHidden = false;
+// Signal callbacks
-static void OnPopupHidden()
+static void OnPopupTouchedOutside()
{
- gHidden = true;
+ gTouchedOutside = true;
}
-static bool gTouchedOutside;
+static void OnPopupShowing()
+{
+ gPopupState = Toolkit::Popup::SHOWING;
+}
-static void OnPopupTouchedOutside()
+static void OnPopupShown()
{
- gTouchedOutside = true;
+ gPopupState = Toolkit::Popup::SHOWN;
+}
+
+static void OnPopupHiding()
+{
+ gPopupState = Toolkit::Popup::HIDING;
+}
+
+static void OnPopupHidden()
+{
+ gPopupState = Toolkit::Popup::HIDDEN;
}
+void ConnectStateSignals( Toolkit::Popup popup )
+{
+ popup.ShowingSignal().Connect( &OnPopupShowing );
+ popup.ShownSignal().Connect( &OnPopupShown );
+ popup.HidingSignal().Connect( &OnPopupHiding );
+ popup.HiddenSignal().Connect( &OnPopupHidden );
+}
+
+void WaitAnimation( ToolkitTestApplication& application )
+{
+ // Wait for a while (allow animation to complete), and then check state.
+ for( int i = 0; i < RENDER_ANIMATION_TEST_DURATION_FRAMES; i++ )
+ {
+ application.SendNotification();
+ application.Render( RENDER_FRAME_INTERVAL );
+ }
+}
-} // anon namespace
+} // Anonymous namespace
-int UtcDaliPopupNew(void)
+/*
+ * This test checks popup creation.
+ */
+int UtcDaliPopupNewP( void )
{
ToolkitTestApplication application;
- tet_infoline(" UtcDaliPopupNew");
+ tet_infoline( " UtcDaliPopupNewP" );
- // Create the Popup actor
+ // Create the Popup actor.
Popup popup;
DALI_TEST_CHECK( !popup );
DALI_TEST_CHECK( popup );
- Popup popup2(popup);
+ Popup popup2( popup );
DALI_TEST_CHECK( popup2 == popup );
- //Additional check to ensure object is created by checking if it's registered
+ // Additional check to ensure object is created by checking if it's registered.
ObjectRegistry registry = Stage::GetCurrent().GetObjectRegistry();
DALI_TEST_CHECK( registry );
END_TEST;
}
-int UtcDaliPopupDestructor(void)
+/*
+ * This test checks popup destruction.
+ */
+int UtcDaliPopupDestructorP( void )
{
ToolkitTestApplication application;
+ tet_infoline( " UtcDaliPopupDestructorP" );
Popup* popup = new Popup();
delete popup;
END_TEST;
}
-int UtcDaliPopupDownCast(void)
+int UtcDaliPopupDownCastP(void)
{
ToolkitTestApplication application;
+ tet_infoline( " UtcDaliPopupDownCastP" );
Handle handle = Popup::New();
END_TEST;
}
-int UtcDaliPopoupSetProperty(void)
+int UtcDaliPopupSetPropertyP(void)
{
- tet_infoline("UtcDaliPopoupSetProperty: ");
ToolkitTestApplication application;
+ tet_infoline( " UtcDaliPopupSetProperty" );
Popup popup = Popup::New();
//Test properties
std::string testString = "Hello World";
- popup.SetProperty(popup.GetPropertyIndex("title"), testString);
- DALI_TEST_EQUALS( testString, popup.GetTitle(), TEST_LOCATION );
+
+ TextLabel textActorIn = TextLabel::New( testString );
+ Property::Map map;
+ Scripting::CreatePropertyMap( textActorIn, map );
+ popup.SetProperty( popup.GetPropertyIndex( "title" ), map );
+ TextLabel textActorOut = TextLabel::DownCast( popup.GetTitle() );
+ std::string resultText;
+ DALI_TEST_CHECK( textActorOut.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get( resultText ) );
+ DALI_TEST_EQUALS( testString, resultText, TEST_LOCATION );
+
END_TEST;
}
+int UtcDaliPopupSetTitleP(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+ tet_infoline( " UtcDaliPopupSetTitleP" );
+
+ // Create the Popup actor
+ Popup popup = Popup::New();
+
+ // Put in show state so it's layer is connected to popup (for ancestor check).
+ popup.SetDisplayState( Popup::SHOWN );
+
+ TextLabel titleActor = TextLabel::New();
+ titleActor.SetProperty( Toolkit::TextLabel::Property::TEXT, "title" );
+
+ DALI_TEST_CHECK( !popup.GetTitle() );
+ popup.SetTitle( titleActor );
+ TextLabel textActor = TextLabel::DownCast( popup.GetTitle() );
+ DALI_TEST_CHECK( textActor == titleActor );
+
+ std::string resultText;
+ DALI_TEST_CHECK( textActor.GetProperty( Toolkit::TextLabel::Property::TEXT ).Get( resultText ) );
+
+ DALI_TEST_CHECK( ( popup.GetTitle() ) && ( resultText == "title" ) );
+ // verify titleActor is actually inside popup, and not elsewhere on stage, or off even.
+ DALI_TEST_CHECK( HasAncestor( titleActor, popup ) );
-int UtcDaliPopupSetBackgroundImage(void)
+ TextLabel titleActor2 = TextLabel::New();
+ titleActor2.SetProperty( Toolkit::TextLabel::Property::TEXT, "anothertitle" );
+ popup.SetTitle( titleActor2 );
+ DALI_TEST_CHECK( popup.GetTitle() != titleActor );
+ DALI_TEST_CHECK( popup.GetTitle() == titleActor2 );
+ DALI_TEST_CHECK( TextLabel::DownCast( popup.GetTitle() ).GetProperty( Toolkit::TextLabel::Property::TEXT ).Get( resultText ) );
+
+ DALI_TEST_CHECK( ( popup.GetTitle() ) && ( resultText == "anothertitle" ) );
+
+ // verify titleActor is actually inside popup, and not elsewhere on stage, or off even.
+ DALI_TEST_CHECK( HasAncestor( titleActor2, popup ) );
+ END_TEST;
+}
+
+int UtcDaliPopupSetTitleN(void)
{
ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
- tet_infoline(" UtcDaliPopupSetBackgroundImage");
+ tet_infoline( " UtcDaliPopupSetTitleN" );
// Create the Popup actor
Popup popup = Popup::New();
- Stage::GetCurrent().Add( popup );
- ImageActor image = CreateSolidColorActor( Color::RED );
- DALI_TEST_CHECK( !image.GetParent() );
- popup.SetBackgroundImage(image);
- DALI_TEST_CHECK( image.GetParent() );
+ TextLabel titleActor = TextLabel::New( "text" );
+ popup.SetTitle( titleActor );
+
+ DALI_TEST_CHECK( popup.GetTitle() );
+
+ // Set a bad title value.
+ // Confirm this has disabled the title.
+ Actor badActor;
+ popup.SetTitle( badActor );
+
+ DALI_TEST_CHECK( !popup.GetTitle() );
+
END_TEST;
}
-int UtcDaliPopupSetTitle(void)
+int UtcDaliPopupSetContentP(void)
{
ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
- tet_infoline(" UtcDaliPopupSetTitle");
+ tet_infoline( " UtcDaliPopupSetContentP" );
// Create the Popup actor
Popup popup = Popup::New();
Stage::GetCurrent().Add( popup );
+ popup.SetProperty( Toolkit::Popup::Property::ANIMATION_DURATION, 0.0f );
+
// Put in show state so it's layer is connected to popup (for ancestor check).
- popup.SetState(Popup::POPUP_SHOW, 0.0f);
+ popup.SetDisplayState( Popup::SHOWN );
+
+ PushButton button = PushButton::New();
+ DALI_TEST_CHECK( !HasAncestor( button, popup ) );
+ popup.SetFooter( button );
+ // Hide and then re-show popup to cause button to be rearranged and added to popup.
+ popup.SetDisplayState( Popup::HIDDEN );
+ popup.SetDisplayState( Popup::SHOWN );
+ DALI_TEST_CHECK( HasAncestor( button, popup ) );
+ END_TEST;
+}
+
+int UtcDaliPopupSetContentN(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+ tet_infoline( " UtcDaliPopupSetContentN" );
+
+ // Create the Popup actor
+ Popup popup = Popup::New();
- popup.SetTitle("title");
+ TextLabel content = TextLabel::New( "text" );
+ popup.SetContent( content );
- DALI_TEST_CHECK( popup.GetTitle() == "title" );
+ DALI_TEST_CHECK( popup.GetContent() );
+
+ // Set a bad title value.
+ Actor badActor;
+ popup.SetContent( badActor );
+
+ DALI_TEST_CHECK( !popup.GetContent() );
END_TEST;
}
-int UtcDaliPopupAddButton(void)
+int UtcDaliPopupSetFooterP(void)
{
ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
- tet_infoline(" UtcDaliPopupAddButton");
+ tet_infoline(" UtcDaliPopupSetFooterP");
// Create the Popup actor
Popup popup = Popup::New();
Stage::GetCurrent().Add( popup );
+ popup.SetProperty( Toolkit::Popup::Property::ANIMATION_DURATION, 0.0f );
// Put in show state so it's layer is connected to popup (for ancestor check).
- popup.SetState(Popup::POPUP_SHOW, 0.0f);
+ popup.SetDisplayState( Popup::SHOWN );
PushButton button = PushButton::New();
DALI_TEST_CHECK( !HasAncestor(button, popup) );
- popup.AddButton(button);
+ popup.SetFooter( button );
+ // Hide and then re-show popup to cause button to be rearranged and added to popup.
+ popup.SetDisplayState( Popup::HIDDEN );
+ popup.SetDisplayState( Popup::SHOWN );
+ DALI_TEST_CHECK( HasAncestor( button, popup ) );
+ END_TEST;
+}
+
+int UtcDaliPopupSetFooterN(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+ tet_infoline(" UtcDaliPopupSetFooterN");
+
+ // Create the Popup actor
+ Popup popup = Popup::New();
+
+ PushButton button = PushButton::New();
+ popup.SetFooter( button );
+
+ DALI_TEST_CHECK( popup.GetFooter() );
+
+ // Set a bad title value.
+ Actor badActor;
+ popup.SetFooter( badActor );
+
+ DALI_TEST_CHECK( !popup.GetFooter() );
+
+ END_TEST;
+}
+
+int UtcDaliPopupSetControlFooterMultiple(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+ tet_infoline(" UtcDaliPopupSetControlFooterMultiple");
+
+ // Create the Popup actor
+ Popup popup = Popup::New();
+ Stage::GetCurrent().Add( popup );
+ popup.SetProperty( Toolkit::Popup::Property::ANIMATION_DURATION, 0.0f );
+ // Put in show state so it's layer is connected to popup (for ancestor check).
+ popup.SetDisplayState( Popup::SHOWN );
+
+ Actor container = Actor::New();
+ PushButton button1 = PushButton::New();
+ PushButton button2 = PushButton::New();
+ DALI_TEST_CHECK( !HasAncestor( button1, popup ) );
+ DALI_TEST_CHECK( !HasAncestor( button2, popup ) );
+ container.Add( button1 );
+ container.Add( button2 );
+ popup.SetFooter( container );
+
// Hide and then re-show popup to cause button to be rearranged and added to popup.
- popup.SetState( Popup::POPUP_HIDE, 0.0f );
- popup.SetState( Popup::POPUP_SHOW, 0.0f );
- DALI_TEST_CHECK( HasAncestor(button, popup) );
+ popup.SetDisplayState( Popup::HIDDEN );
+ popup.SetDisplayState( Popup::SHOWN );
+ DALI_TEST_CHECK( HasAncestor( button1, popup ) );
+ DALI_TEST_CHECK( HasAncestor( button2, popup ) );
+ END_TEST;
+}
+
+int UtcDaliPopupSetStateP(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+ tet_infoline(" UtcDaliPopupSetStateP");
+
+ // Create the Popup actor
+ Popup popup = Popup::New();
+
+ popup.SetProperty( Toolkit::Popup::Property::ANIMATION_DURATION, 0.0f );
+
+ DALI_TEST_EQUALS( popup.GetDisplayState(), Popup::HIDDEN, TEST_LOCATION );
+
+ popup.SetDisplayState( Popup::SHOWN );
+ DALI_TEST_EQUALS( Popup::SHOWN, popup.GetDisplayState(), TEST_LOCATION );
+
+ popup.SetDisplayState( Popup::HIDDEN );
+ DALI_TEST_EQUALS( Popup::HIDDEN, popup.GetDisplayState(), TEST_LOCATION );
END_TEST;
}
-int UtcDaliPopupSetState(void)
+int UtcDaliPopupSetStateN(void)
{
ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
- tet_infoline(" UtcDaliPopupSetState");
+ tet_infoline(" UtcDaliPopupSetStateN");
// Create the Popup actor
Popup popup = Popup::New();
- ImageActor backgroundImage = CreateSolidColorActor( Color::RED );
- popup.SetBackgroundImage(backgroundImage);
-
- // Showing/Hiding popup, results in all child Actors being
- // connected/disconnected from the stage.
- DALI_TEST_CHECK( !backgroundImage.OnStage() );
- popup.SetState(Popup::POPUP_SHOW, 0.0f);
- DALI_TEST_CHECK( backgroundImage.OnStage() );
- DALI_TEST_EQUALS( Popup::POPUP_SHOW, popup.GetState(), TEST_LOCATION );
- popup.SetState(Popup::POPUP_HIDE, 0.0f);
- DALI_TEST_CHECK( !backgroundImage.OnStage() );
- DALI_TEST_EQUALS( Popup::POPUP_HIDE, popup.GetState(), TEST_LOCATION );
+ popup.SetProperty( Toolkit::Popup::Property::ANIMATION_DURATION, 1.0f );
+
+ DALI_TEST_EQUALS( popup.GetDisplayState(), Popup::HIDDEN, TEST_LOCATION );
+
+ popup.SetDisplayState( Popup::SHOWN );
+ DALI_TEST_EQUALS( Popup::SHOWING, popup.GetDisplayState(), TEST_LOCATION );
+
+ // Test cancelling a show before it has finished.
+ popup.SetDisplayState( Popup::HIDDEN );
+ DALI_TEST_EQUALS( Popup::HIDING, popup.GetDisplayState(), TEST_LOCATION );
END_TEST;
}
-int UtcDaliPopupSetStateSlow(void)
+int UtcDaliPopupDisplayStateSignal(void)
{
ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
- tet_infoline(" UtcDaliPopupSetStateSlow");
+ tet_infoline( " UtcDaliPopupDisplayStateSignal" );
// Create the Popup actor
Popup popup = Popup::New();
+ ConnectStateSignals( popup );
- ImageActor backgroundImage = CreateSolidColorActor( Color::RED );
- popup.SetBackgroundImage(backgroundImage);
+ popup.SetProperty( Toolkit::Popup::Property::ANIMATION_DURATION, 1.0f );
+ popup.SetDisplayState( Popup::SHOWN );
+ DALI_TEST_EQUALS( Popup::SHOWING, popup.GetDisplayState(), TEST_LOCATION );
+ DALI_TEST_EQUALS( gPopupState, Popup::SHOWING, TEST_LOCATION );
- // Showing/Hiding popup, results in all child Actors being
- // connected/disconnected from the stage.
- DALI_TEST_CHECK( !backgroundImage.OnStage() );
- popup.SetState(Popup::POPUP_SHOW, 0.0f);
- DALI_TEST_CHECK( backgroundImage.OnStage() );
+ // Wait for a while (allow animation to complete), and then check state.
+ for( int i = 0; i < RENDER_ANIMATION_TEST_DURATION_FRAMES; i++)
+ {
+ application.SendNotification();
+ application.Render( RENDER_FRAME_INTERVAL );
+ }
+
+ DALI_TEST_EQUALS( Popup::SHOWN, popup.GetDisplayState(), TEST_LOCATION );
+ DALI_TEST_EQUALS( gPopupState, Popup::SHOWN, TEST_LOCATION );
// Hide slowly
- popup.SetState(Popup::POPUP_HIDE);
+ popup.SetDisplayState( Popup::HIDDEN );
+ DALI_TEST_EQUALS( Popup::HIDING, popup.GetDisplayState(), TEST_LOCATION );
+ DALI_TEST_EQUALS( gPopupState, Popup::HIDING, TEST_LOCATION );
// Wait for a while (allow animation to complete), and then check state.
- for(int i = 0; i < RENDER_ANIMATION_TEST_DURATION_FRAMES; i++)
+ for( int i = 0; i < RENDER_ANIMATION_TEST_DURATION_FRAMES; i++)
{
application.SendNotification();
- application.Render(RENDER_FRAME_INTERVAL);
+ application.Render( RENDER_FRAME_INTERVAL );
}
- DALI_TEST_CHECK( !backgroundImage.OnStage() );
+ DALI_TEST_EQUALS( Popup::HIDDEN, popup.GetDisplayState(), TEST_LOCATION );
+ DALI_TEST_EQUALS( gPopupState, Popup::HIDDEN, TEST_LOCATION );
+
END_TEST;
}
-
-
int UtcDaliPopupShowHide(void)
{
ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
// Create the Popup actor
Popup popup = Popup::New();
- popup.HiddenSignal().Connect( &OnPopupHidden );
-
- ImageActor backgroundImage = CreateSolidColorActor( Color::RED );
- popup.SetBackgroundImage(backgroundImage);
+ ConnectStateSignals( popup );
+ Actor container = Actor::New();
PushButton button1 = PushButton::New();
PushButton button2 = PushButton::New();
- button1.SetSize(DEFAULT_BUTTON_SIZE.GetVectorXY());
- popup.AddButton(button1);
- button2.SetSize(DEFAULT_BUTTON_SIZE.GetVectorXY());
- popup.AddButton(button2);
-
- // Showing/Hiding popup, results in all child Actors being
- // connected/disconnected from the stage.
- DALI_TEST_CHECK( !backgroundImage.OnStage() );
+ button1.SetSize( DEFAULT_BUTTON_SIZE.GetVectorXY() );
+ button2.SetSize( DEFAULT_BUTTON_SIZE.GetVectorXY() );
+ container.Add( button1 );
+ container.Add( button2 );
+ popup.SetFooter( container );
// Show
// Note: in most popup animation implementations show would result in
// popup being onstage immediately following Show(). However we can't
// assume for all. e.g. If one creates a animation with a delay.
- popup.Show();
+ popup.SetDisplayState( Popup::SHOWN );
// Wait for a while (allow animation to complete), and then check state.
for(int i = 0; i < RENDER_ANIMATION_TEST_DURATION_FRAMES; i++)
{
application.SendNotification();
- application.Render(RENDER_FRAME_INTERVAL);
+ application.Render( RENDER_FRAME_INTERVAL );
}
- DALI_TEST_CHECK( backgroundImage.OnStage() );
-
// Hide
- gHidden = false;
- popup.Hide();
+ popup.SetDisplayState( Popup::HIDDEN );
// Wait for a while (allow animation to complete), and then check state.
for(int i = 0; i < RENDER_ANIMATION_TEST_DURATION_FRAMES; i++)
application.Render(RENDER_FRAME_INTERVAL);
}
- DALI_TEST_CHECK( !backgroundImage.OnStage() );
- DALI_TEST_CHECK( gHidden );
+ DALI_TEST_EQUALS( gPopupState, Popup::HIDDEN, TEST_LOCATION );
END_TEST;
}
-int UtcDaliPopupShowHideTail(void)
+int UtcDaliPopupPropertyTailVisibility(void)
{
ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
tet_infoline(" UtcDaliPopupShowHideTail");
// Create the Popup actor
Popup popup = Popup::New();
Stage::GetCurrent().Add( popup );
- popup.SetState(Popup::POPUP_SHOW, 0.0f);
- popup.HideTail();
- int withoutTailCount = DescendentCount(popup);
+ popup.SetProperty( Popup::Property::TAIL_VISIBILITY, false );
+ popup.SetDisplayState( Popup::SHOWN );
+
+ int withoutTailCount = DescendentCount( popup );
+
+ popup.SetDisplayState( Popup::HIDDEN );
- popup.ShowTail(ParentOrigin::BOTTOM_CENTER);
- int withTailCount = DescendentCount(popup);
+ popup.SetProperty( Popup::Property::TAIL_POSITION, "BOTTOM_CENTER" );
+ popup.SetProperty( Popup::Property::TAIL_VISIBILITY, true );
+ popup.SetDisplayState( Popup::SHOWN );
+
+ int withTailCount = DescendentCount( popup );
// There should be more actors if the Tail has been added.
DALI_TEST_CHECK( withTailCount > withoutTailCount );
// Hide again
- popup.HideTail();
+ popup.SetDisplayState( Popup::HIDDEN );
+ popup.SetProperty( Popup::Property::TAIL_VISIBILITY, false );
+ popup.SetDisplayState( Popup::SHOWN );
int withoutTailCount2 = DescendentCount(popup);
DALI_TEST_CHECK( withTailCount > withoutTailCount2 );
END_TEST;
}
-int UtcDaliPopupOnTouchedOutside(void)
+int UtcDaliPopupOnTouchedOutsideSignal(void)
{
ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
tet_infoline(" UtcDaliPopupOnTouchedOutside");
// Create the Popup actor
Popup popup = Popup::New();
+ popup.SetParentOrigin( ParentOrigin::CENTER );
+ popup.SetAnchorPoint( ParentOrigin::CENTER );
+ popup.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+ popup.SetSize( 50.0f, 50.0f );
+ popup.SetProperty( Popup::Property::ANIMATION_DURATION, 0.0f );
Stage::GetCurrent().Add( popup );
- popup.SetParentOrigin(ParentOrigin::CENTER);
- popup.SetAnchorPoint(ParentOrigin::CENTER);
- popup.SetState(Popup::POPUP_SHOW, 0.0f);
popup.OutsideTouchedSignal().Connect( &OnPopupTouchedOutside );
+ popup.SetDisplayState( Popup::SHOWN );
application.SendNotification();
application.Render();
application.SendNotification();
application.Render();
- DALI_TEST_CHECK(gTouchedOutside);
+ DALI_TEST_CHECK( gTouchedOutside );
END_TEST;
}
+
+int UtcDaliPopupPropertyAutoHide(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+ tet_infoline( " UtcDaliPopupPropertyAutoHide" );
+
+ // Create the Popup actor
+ Popup popup = Popup::New();
+ ConnectStateSignals( popup );
+
+ Actor container = Actor::New();
+ PushButton button1 = PushButton::New();
+ button1.SetSize( DEFAULT_BUTTON_SIZE.GetVectorXY() );
+ container.Add( button1 );
+ popup.SetFooter( container );
+
+ popup.SetProperty( Popup::Property::ANIMATION_DURATION, 0.0f );
+ popup.SetProperty( Popup::Property::AUTO_HIDE_DELAY, 200 );
+
+ Stage::GetCurrent().Add( popup );
+
+ DALI_TEST_EQUALS( gPopupState, Popup::HIDDEN, TEST_LOCATION );
+
+ // Show
+ // Note: in most popup animation implementations show would result in
+ // popup being onstage immediately following Show(). However we can't
+ // assume for all. e.g. If one creates a animation with a delay.
+ popup.SetDisplayState( Popup::SHOWN );
+
+ DALI_TEST_EQUALS( gPopupState, Popup::SHOWN, TEST_LOCATION );
+
+ for( int i = 0; i < RENDER_ANIMATION_TEST_DURATION_FRAMES; i++ )
+ {
+ application.SendNotification();
+ application.Render( RENDER_FRAME_INTERVAL );
+ }
+
+ // Force the timer used by the popup to expire,
+ // this will cause the popup to hide automatically.
+ Dali::Timer timer = Timer::New( 0 );
+ timer.MockEmitSignal();
+
+ DALI_TEST_EQUALS( gPopupState, Popup::HIDDEN, TEST_LOCATION );
+
+ END_TEST;
+}
+
+/*
+ * This test checks all animation modes to confirm they all trigger all display states at the expected times.
+ */
+int UtcDaliPopupPropertyAnimationMode(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+ tet_infoline( " UtcDaliPopupPropertyAnimationMode" );
+
+ // Create the Popup actor
+ Popup popup = Popup::New();
+ ConnectStateSignals( popup );
+ popup.SetTitle( TextLabel::New( "Title" ) );
+ Stage::GetCurrent().Add( popup );
+
+ std::string animationModes[] = { "NONE", "ZOOM", "FADE", "CUSTOM" };
+
+ // Try both default and zero animation duration, as zero has a special case for some animation types.
+ for( int j = 0; j <= 1; j++ )
+ {
+ // On the second loop, set duration to zero.
+ if( j == 1 )
+ {
+ popup.SetProperty( Popup::Property::ANIMATION_DURATION, 0.0f );
+ }
+
+ // Loop through 4 animation modes.
+ for( int i = 0; i < 4; i++ )
+ {
+ popup.SetProperty( Popup::Property::ANIMATION_MODE, animationModes[i] );
+
+ std::string checkMode;
+ DALI_TEST_CHECK( popup.GetProperty( Popup::Property::ANIMATION_MODE ).Get( checkMode ) )
+
+ DALI_TEST_EQUALS( checkMode, animationModes[i], TEST_LOCATION );
+
+ popup.SetDisplayState( Popup::SHOWN );
+
+ // Only wait for animation if it isn't instant.
+ if( j == 0 )
+ {
+ DALI_TEST_EQUALS( gPopupState, Popup::SHOWING, TEST_LOCATION );
+ WaitAnimation( application );
+ }
+
+ DALI_TEST_EQUALS( gPopupState, Popup::SHOWN, TEST_LOCATION );
+ popup.SetDisplayState( Popup::HIDDEN );
+
+ if( j == 0 )
+ {
+ DALI_TEST_EQUALS( gPopupState, Popup::HIDING, TEST_LOCATION );
+ WaitAnimation( application );
+ }
+
+ DALI_TEST_EQUALS( gPopupState, Popup::HIDDEN, TEST_LOCATION );
+ }
+ }
+
+ END_TEST;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+
+#include <dali-toolkit/devel-api/controls/popup/confirmation-popup.h>
+
+// INTERNAL INCLUDES
+
+#include <dali-toolkit/internal/controls/popup/confirmation-popup-impl.h>
+#include <dali/public-api/actors/image-actor.h>
+
+using namespace Dali;
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+
+ConfirmationPopup::ConfirmationPopup()
+: Popup()
+{
+}
+
+ConfirmationPopup::ConfirmationPopup( Internal::ConfirmationPopup& implementation )
+: Popup( implementation )
+{
+}
+
+ConfirmationPopup::ConfirmationPopup( const ConfirmationPopup& confirmationPopup )
+: Popup( confirmationPopup )
+{
+}
+
+ConfirmationPopup& ConfirmationPopup::operator=( const ConfirmationPopup& confirmationPopup )
+{
+ if( &confirmationPopup != this )
+ {
+ Popup::operator=( confirmationPopup );
+ }
+ return *this;
+}
+
+ConfirmationPopup::ConfirmationPopup( Dali::Internal::CustomActor* internal )
+: Popup( internal )
+{
+ VerifyCustomActorPointer<Internal::ConfirmationPopup>( internal );
+}
+
+ConfirmationPopup::~ConfirmationPopup()
+{
+}
+
+ConfirmationPopup ConfirmationPopup::New()
+{
+ return Internal::ConfirmationPopup::New();
+}
+
+ConfirmationPopup ConfirmationPopup::DownCast( BaseHandle handle )
+{
+ return Control::DownCast<ConfirmationPopup, Internal::ConfirmationPopup>( handle );
+}
+
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_CONFIRMATION_POPUP_H__
+#define __DALI_TOOLKIT_CONFIRMATION_POPUP_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "popup.h"
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+// Forward declarations
+namespace Internal DALI_INTERNAL
+{
+class ConfirmationPopup;
+}
+
+/**
+ * @brief The ConfirmationPopup widget provides a simple interface to the Popup widget in which to
+ * create common use-case popups.
+ *
+ * ConfirmationPopup will automatically provide signals for 1 or 2 buttons.
+ * These signals are dynamically created. The controls (typically PushButtons) must be named as per the example below.
+ *
+ * Please see the programming guide for a detailed description of the ConfirmationPopup including examples.
+ *
+ * Signals (these are dynamically created upon connect).
+ * | %Signal Name | Actor name to connect to | Property to set signal type (eg clicked) |
+ * |-----------------------|--------------------------|------------------------------------------|
+ * | control-signal-ok | control-ok | connect-signal-ok-selected |
+ * | control-signal-cancel | control-cancel | connect-signal-cancel-selected |
+ */
+class DALI_IMPORT_API ConfirmationPopup : public Popup
+{
+public:
+
+ /**
+ * @brief The start and end property ranges for this control.
+ */
+ enum PropertyRange
+ {
+ PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1 + DEFAULT_PROPERTY_MAX_COUNT_PER_DERIVATION + 1,
+ PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000 ///< Reserve property indices
+ };
+
+ /**
+ * @brief An enumeration of properties belonging to the ConfirmationPopup class.
+ */
+ struct Property
+ {
+ enum
+ {
+ CONNECT_SIGNAL_OK_SELECTED = PROPERTY_START_INDEX, ///< name "connect-signal-ok-selected", type std::string
+ CONNECT_SIGNAL_CANCEL_SELECTED ///< name "connect-signal-cancel-selected", type std::string
+ };
+ };
+
+ /**
+ * @brief An enumeration to use as indices to reference buttons.
+ */
+ enum ControlIndex
+ {
+ CONTROL_OK = 0, ///< Index of control 1
+ CONTROL_CANCEL, ///< Index of control 2
+ };
+
+ /**
+ * @brief Create an uninitialized ConfirmationPopup; this can be initialized with ConfirmationPopup::New().
+ *
+ * Calling member functions with an uninitialized Dali::Object is not allowed.
+ */
+ ConfirmationPopup();
+
+ /**
+ * @brief Copy constructor.
+ */
+ ConfirmationPopup( const ConfirmationPopup& confirmationPopup );
+
+ /**
+ * @brief Assignment operator.
+ */
+ ConfirmationPopup& operator=( const ConfirmationPopup& confirmationPopup );
+
+ /**
+ * @brief Destructor.
+ *
+ * This is non-virtual since derived types must not contain data or virtual methods.
+ */
+ ~ConfirmationPopup();
+
+ /**
+ * @brief Create an initialized ConfirmationPopup.
+ *
+ * @return A handle to a newly allocated Dali resource.
+ */
+ static ConfirmationPopup New();
+
+ /**
+ * @brief Downcast an Object handle to ConfirmationPopup.
+ *
+ * If handle points to a ConfirmationPopup the downcast produces valid
+ * handle. If not the returned handle is left uninitialized.
+ *
+ * @param[in] handle Handle to an object
+ * @return handle to a ConfirmationPopup or an uninitialized handle
+ */
+ static ConfirmationPopup DownCast( BaseHandle handle );
+
+public: // Not intended for application developers
+
+ /**
+ * @brief Creates a handle using the Toolkit::Internal implementation.
+ *
+ * @param[in] implementation The Control implementation.
+ */
+ DALI_INTERNAL ConfirmationPopup( Internal::ConfirmationPopup& implementation );
+
+ /**
+ * @brief Allows the creation of this Control from an Internal::CustomActor pointer.
+ *
+ * @param[in] internal A pointer to the internal CustomActor.
+ */
+ DALI_INTERNAL ConfirmationPopup( Dali::Internal::CustomActor* internal );
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_CONFIRMATION_POPUP_H__
// INTERNAL INCLUDES
#include <dali-toolkit/internal/controls/popup/popup-impl.h>
-#include <dali-toolkit/public-api/controls/buttons/button.h>
using namespace Dali;
return Control::DownCast<Popup, Internal::Popup>(handle);
}
-void Popup::SetBackgroundImage( Actor image )
+// Properties:
+
+void Popup::SetTitle( Actor titleActor )
{
- GetImpl(*this).SetBackgroundImage( image );
+ GetImpl( *this ).SetTitle( titleActor );
}
-void Popup::SetTitle( const std::string& text )
+Actor Popup::GetTitle() const
{
- GetImpl(*this).SetTitle( text );
+ return GetImpl( *this ).GetTitle();
}
-std::string Popup::GetTitle() const
+void Popup::SetContent( Actor content )
{
- return GetImpl(*this).GetTitle();
+ GetImpl( *this ).SetContent( content );
}
-void Popup::AddButton( Button button )
+Actor Popup::GetContent() const
{
- GetImpl(*this).AddButton( button );
+ return GetImpl( *this ).GetContent();
}
-void Popup::SetState( PopupState state )
+void Popup::SetFooter( Actor footer )
{
- GetImpl(*this).SetState( state );
+ GetImpl( *this ).SetFooter( footer );
}
-void Popup::SetState( PopupState state, float duration )
+Actor Popup::GetFooter() const
{
- GetImpl(*this).SetState( state, duration );
+ return GetImpl( *this ).GetFooter();
}
-Popup::PopupState Popup::GetState() const
+void Popup::SetDisplayState( Toolkit::Popup::DisplayState displayState )
{
- return GetImpl(*this).GetState();
+ GetImpl( *this ).SetDisplayState( displayState );
}
-void Popup::Show()
+Toolkit::Popup::DisplayState Popup::GetDisplayState() const
{
- GetImpl(*this).SetState( POPUP_SHOW );
+ return GetImpl( *this ).GetDisplayState();
}
-void Popup::Hide()
+// Signals:
+
+Popup::TouchedOutsideSignalType& Popup::OutsideTouchedSignal()
{
- GetImpl(*this).SetState( POPUP_HIDE );
+ return GetImpl( *this ).OutsideTouchedSignal();
}
-void Popup::ShowTail(const Vector3& position)
+Popup::DisplayStateChangeSignalType& Popup::ShowingSignal()
{
- GetImpl(*this).ShowTail( position );
+ return GetImpl( *this ).ShowingSignal();
}
-void Popup::HideTail()
+Popup::DisplayStateChangeSignalType& Popup::ShownSignal()
{
- GetImpl(*this).HideTail();
+ return GetImpl( *this ).ShownSignal();
}
-Popup::TouchedOutsideSignalType& Popup::OutsideTouchedSignal()
+Popup::DisplayStateChangeSignalType& Popup::HidingSignal()
{
- return GetImpl(*this).OutsideTouchedSignal();
+ return GetImpl( *this ).HidingSignal();
}
-Popup::HiddenSignalType& Popup::HiddenSignal()
+Popup::DisplayStateChangeSignalType& Popup::HiddenSignal()
{
- return GetImpl(*this).HiddenSignal();
+ return GetImpl( *this ).HiddenSignal();
}
} // namespace Toolkit
class Popup;
}
-class Button;
-
/**
- * @brief Popup contains content that can come into focus when activated, and out of focus when deactivated.
- *
- * Content:
- *
- * The content within a popup consists of:
- *
- * 1. Title
- * 2. Buttons
- * 3. Background/Frame (i.e. Scale-9 image)
- * 4. Custom Content (Actors)
- *
- * All of which are optional.
+ * @brief The Popup widget provides a configurable pop-up dialog with built-in layout of three main fields.
*
- * States:
+ * Fields:
+ * - Background Image
+ * - Title
+ * - Content
+ * - Footer
*
- * A popup can be in a number of states:
- *
- * 1. HIDE (invisible)
- * 2. SHOW (visible at normal size)
- * 3. SHOW_MAXIMIZED (visible occupying full parent size)
- * 4. Or custom defined.
- *
- * Transition Effects:
- *
- * A popup can use various custom transition effects, e.g.
- * Alpha fade, Scaling transition, position/rotation, shader effects.
+ * Please see the programming guide for a detailed description of the Popup including examples.
*
* Signals
* | %Signal Name | Method |
* |-------------------|------------------------------|
* | touched-outside | @ref OutsideTouchedSignal() |
+ * | showing | @ref ShowingSignal() |
+ * | shown | @ref ShownSignal() |
+ * | hiding | @ref HidingSignal() |
* | hidden | @ref HiddenSignal() |
*/
class DALI_IMPORT_API Popup : public Control
public:
/**
- * @brief Current popup state.
+ * @brief The start and end property ranges for this control.
*/
- enum PopupState
+ enum PropertyRange
{
- POPUP_NONE, ///< Init status
- POPUP_HIDE, ///< Hidden (not visible)
- POPUP_SHOW, ///< Shown (visible in default size)
+ PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
+ PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000 ///< Reserve property indices
};
- typedef Signal< void () > TouchedOutsideSignalType; ///< Touched outside signal type.
- typedef Signal< void () > HiddenSignalType; ///< Hidden signal type.
+ /**
+ * @brief An enumeration of properties belonging to the Popup class.
+ */
+ struct Property
+ {
+ enum
+ {
+ TITLE = PROPERTY_START_INDEX, ///< name "title", type Property::Map
+ CONTENT, ///< name "content", type Property::Map
+ FOOTER, ///< name "footer", type Property::Map
+ DISPLAY_STATE, ///< name "display-state", type std::string
+ TOUCH_TRANSPARENT, ///< name "touch-transparent", type bool
+ TAIL_VISIBILITY, ///< name "tail-visibility", type bool
+ TAIL_POSITION, ///< name "tail-position", type Vector3
+ CONTEXTUAL_MODE, ///< name "contextual-mode", type std::string
+ ANIMATION_DURATION, ///< name "animation-duration", type float
+ ANIMATION_MODE, ///< name "animation-mode", type std::string
+ ENTRY_ANIMATION, ///< name "entry-animation", type Property::Map
+ EXIT_ANIMATION, ///< name "exit-animation", type Property::Map
+ AUTO_HIDE_DELAY, ///< name "auto-hide-delay", type int
+ BACKING_ENABLED, ///< name "backing-enabled", type bool
+ BACKING_COLOR, ///< name "backing-color", type Vector4
+ POPUP_BACKGROUND_IMAGE, ///< name "popup-background-image", type std::string
+ TAIL_UP_IMAGE, ///< name "tail-up-image", type std::string
+ TAIL_DOWN_IMAGE, ///< name "tail-down-image", type std::string
+ TAIL_LEFT_IMAGE, ///< name "tail-left-image", type std::string
+ TAIL_RIGHT_IMAGE, ///< name "tail-right-image", type std::string
+ };
+ };
/**
- * @brief Signal emitted when user has touched outside of the Dialog.
+ * The display states of the Popup.
*/
- TouchedOutsideSignalType& OutsideTouchedSignal();
+ enum DisplayState
+ {
+ SHOWING, ///< The popup is transitioning in
+ SHOWN, ///< The popup is fully shown
+ HIDING, ///< The popup is transitioning out
+ HIDDEN ///< The popup is fully hidden
+ };
/**
- * @brief Signal emitted when popup has been hidden.
+ * The animation mode within popup.
+ * Choose from a predefined mode or "CUSTOM" to use the ANIMATION_IN and ANIMATION_OUT properties.
*/
- HiddenSignalType& HiddenSignal();
+ enum AnimationMode
+ {
+ NONE, ///< No animation.
+ ZOOM, ///< Popup zooms in and out animating the scale property.
+ FADE, ///< Popup fades in and out.
+ CUSTOM ///< Use the EntryAnimation and ExitAnimation animation properties.
+ };
+
+ /**
+ * Types of contextual layout.
+ * The Popup is positioned adjacent to it's parent in the direction specified by this mode.
+ * NON_CONTEXTUAL disables any contextual positioning.
+ */
+ enum ContextualMode
+ {
+ NON_CONTEXTUAL,
+ ABOVE,
+ RIGHT,
+ BELOW,
+ LEFT
+ };
public:
Popup();
/**
+ * @brief Create the Popup control.
+ *
+ * @return A handle to the Popup control.
+ */
+ static Popup New();
+
+ /**
+ * @brief Destructor
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~Popup();
+
+ /**
* @brief Copy constructor.
*
* Creates another handle that points to the same real object
Popup& operator=( const Popup& handle );
/**
- * @brief Destructor
- *
- * This is non-virtual since derived Handle types must not contain data or virtual methods.
- */
- ~Popup();
-
- /**
- * @brief Create the Poup control.
- *
- * @return A handle to the Popup control.
- */
- static Popup New();
-
- /**
* @brief Downcast an Object handle to Popup.
*
* If handle points to a Popup the
public:
/**
- * @brief Sets the background image for this Popup.
- *
- * The background is resized (stretched according to scale settings),
- * to the size of the Popup.
+ * @brief Sets a title for this Popup.
*
- * @param[in] image The Background ImageActor to cover background
+ * @param[in] titleActor Any actor can be specified when using this method.
*/
- void SetBackgroundImage( Actor image );
+ void SetTitle( Actor titleActor );
/**
- * @brief Sets a title for this Popup.
+ * @brief Gets the title actor for this Popup.
*
- * By default a TextView is created with following settings: black color, split-by-word multi-line policy and split exceed policy.
- *
- * @param[in] text The text to appear as the heading for this Popup
+ * @return The actor representing the title is returned.
*/
- void SetTitle( const std::string& text );
+ Actor GetTitle() const;
/**
- * @brief Gets the text (TextView) for this Popup.
+ * @brief Sets the content actor.
+ * This can any actor type or heirarchy of actors.
*
- * @return The text to appear as the heading for this Popup
+ * @param[in] content The actor to use.
*/
- std::string GetTitle() const;
+ void SetContent( Actor content );
/**
- * @brief Adds a button to this Popup.
+ * @brief Gets the actor currently used for the content.
*
- * Buttons are added to the bottom of the Popup and Centered.
+ * @return The content actor.
+ */
+ Actor GetContent() const;
+
+ /**
+ * @brief Sets the actor to use for a footer in this Popup.
*
- * By default the first button added will have the focus, and the focus will
- * shift to other buttons based on the sequence in which they are added to the popup.
+ * @param[in] control The footer actor to be added to this Popup
+ */
+ void SetFooter( Actor footer );
+
+ /**
+ * @brief Gets the footer actor.
*
- * @param[in] button The button to be added to this Popup
+ * @return The footer actor.
*/
- void AddButton( Button button );
+ Actor GetFooter() const;
/**
- * @brief Sets state of Popup, such as HIDE, and SHOW.
+ * @brief Sets the display state of Popup.
+ *
+ * There are 4 total display states.
+ * Only 2 can be set, but all four can be read for better inspection of the current popup state.
+ *
+ * The other two states are getable, but not setable and are there for consistency.
*
- * The Popup will instantaneously jump to this state.
+ * | Value | Setting the state | Getting the state |
+ * |----------|--------------------------------|--------------------------------|
+ * | SHOWN | Show the popup | The popup is fully shown |
+ * | HIDDEN | Hide the popup | The popup is fully hidden |
+ * | SHOWING | | The popup is transitioning in |
+ * | HIDING | | The popup is transitioning out |
*
- * @param[in] state The state of the popup
+ * All 4 state changes cause notifications via 4 respective signals that can be connected to.
+ * @see GetDisplayState()
+ *
+ * @param[in] displayState The desired display state to change to.
*/
- void SetState( PopupState state );
+ void SetDisplayState( Toolkit::Popup::DisplayState displayState );
/**
- * @brief Sets state of Popup, such as HIDE, and SHOW.
+ * @brief Gets the current state of the popup.
*
- * The Popup will smoothly animate to this state.
+ * This will also show if the popup is in the process of showing or hiding.
*
- * @param[in] state The state of the popup
- * @param[in] duration The time to animate to this new state.
+ * @return The current state of the popup.
*/
- void SetState( PopupState state, float duration );
+ Toolkit::Popup::DisplayState GetDisplayState() const;
+
+public:
+
+ typedef Signal< void () > TouchedOutsideSignalType; ///< Touched outside signal type.
+ typedef Signal< void () > DisplayStateChangeSignalType; ///< Used for signals emitted when the displayed state changes.
/**
- * @brief Gets the state of the popup.
- *
- * @return The state of the popup.
+ * @brief Signal emitted when user has touched outside of the Dialog.
*/
- PopupState GetState() const;
+ TouchedOutsideSignalType& OutsideTouchedSignal();
/**
- * @brief Shows the popup.
- *
- * The Popup will animate to the SHOW state
+ * @brief Signal emitted when the Popup is starting to be shown.
*/
- void Show();
+ DisplayStateChangeSignalType& ShowingSignal();
/**
- * @brief Hides the popup.
- *
- * The Popup will animate to the HIDE state
+ * @brief Signal emitted when the Popup has been fully displayed.
*/
- void Hide();
+ DisplayStateChangeSignalType& ShownSignal();
/**
- * @brief Shows the tail.
- *
- * The tail position is specified relative to it's Parent.
- * To display at top center for instace, pass:
- *
- * ParentOrigin::TOP_CENTER
- *
- * @note The tail images are defined inside PopupStyle as
- * tailUpImage, tailDownImage, tailLeftImage, and tailRightImage
- *
- * @param[in] position A position around the perimeter of the Parent.
+ * @brief Signal emitted when the Popup is starting to be hidden.
*/
- void ShowTail(const Vector3& position);
+ DisplayStateChangeSignalType& HidingSignal();
/**
- * @brief Hides the tail.
+ * @brief Signal emitted when the Popup has been completely hidden.
*/
- void HideTail();
+ DisplayStateChangeSignalType& HiddenSignal();
public: // Not intended for application developers
*
* @param[in] implementation The Control implementation.
*/
- DALI_INTERNAL Popup(Internal::Popup& implementation);
+ DALI_INTERNAL Popup( Internal::Popup& implementation );
/**
* @brief Allows the creation of this Control from an Internal::CustomActor pointer.
$(devel_api_src_dir)/controls/page-turn-view/page-turn-landscape-view.cpp \
$(devel_api_src_dir)/controls/page-turn-view/page-turn-portrait-view.cpp \
$(devel_api_src_dir)/controls/page-turn-view/page-turn-view.cpp \
+ $(devel_api_src_dir)/controls/popup/confirmation-popup.cpp \
$(devel_api_src_dir)/controls/popup/popup.cpp \
$(devel_api_src_dir)/controls/shadow-view/shadow-view.cpp \
$(devel_api_src_dir)/controls/slider/slider.cpp \
$(devel_api_src_dir)/controls/page-turn-view/page-turn-view.h
devel_api_popup_header_files = \
+ $(devel_api_src_dir)/controls/popup/confirmation-popup.h \
$(devel_api_src_dir)/controls/popup/popup.h
devel_api_shadow_view_header_files = \
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "confirmation-popup-impl.h"
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/actors/image-actor.h>
+#include <dali/public-api/images/resource-image.h>
+#include <dali/public-api/object/type-registry.h>
+#include <dali/devel-api/object/type-registry-helper.h>
+#include <cstring>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+/*
+ * This struct is used to define all details required about a dynamically created signal.
+ */
+struct ControlDetailType
+{
+ const char* signalName;
+ const char* controlName;
+ const char* connectSignalPropertyName;
+};
+
+/* A table of all control details. These details are kept in one place for maintainability.
+ * Name of the signal | Name of the control | Name of the property which lets the
+ * the app-developer | which will provide | app developer choose which signal
+ * can connect to. | the signal. | within the control to connect to. */
+const ControlDetailType ControlDetails[] = {
+ { "control-signal-ok", "control-ok", "connect-signal-ok-selected" },
+ { "control-signal-cancel", "control-cancel", "connect-signal-cancel-selected" },
+};
+const unsigned int ControlDetailsCount = sizeof( ControlDetails ) / sizeof( ControlDetails[0] );
+
+// To give sensible default behaviour to save the connect signal properties being set.
+const char* const DEFAULT_CONNECT_SIGNAL_NAME = "clicked";
+
+BaseHandle Create()
+{
+ return Toolkit::ConfirmationPopup::New();
+}
+
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ConfirmationPopup, Toolkit::Popup, Create )
+
+DALI_PROPERTY_REGISTRATION( Toolkit, ConfirmationPopup, ControlDetails[0].connectSignalPropertyName, STRING, CONNECT_SIGNAL_OK_SELECTED )
+DALI_PROPERTY_REGISTRATION( Toolkit, ConfirmationPopup, ControlDetails[1].connectSignalPropertyName, STRING, CONNECT_SIGNAL_CANCEL_SELECTED )
+
+// Note: We do not use the macros for signal registration as we do not want to redefine the signal name strings.
+// We have predefined them for optimal signal name to control name lookup.
+SignalConnectorType signalConnector1( typeRegistration, ControlDetails[0].signalName, &Toolkit::Internal::ConfirmationPopup::DoConnectSignal );
+SignalConnectorType signalConnector2( typeRegistration, ControlDetails[1].signalName, &Toolkit::Internal::ConfirmationPopup::DoConnectSignal );
+
+DALI_TYPE_REGISTRATION_END()
+
+} // Unnamed namespace
+
+Dali::Toolkit::ConfirmationPopup ConfirmationPopup::New()
+{
+ // Create the implementation, temporarily owned on stack.
+ IntrusivePtr< ConfirmationPopup > internalConfirmationPopup = new ConfirmationPopup();
+
+ // Pass ownership to CustomActor
+ Dali::Toolkit::ConfirmationPopup confirmationPopup( *internalConfirmationPopup );
+
+ // Second-phase initialisation of the implementation.
+ // This can only be done after the CustomActor connection has been made...
+ internalConfirmationPopup->Initialize();
+
+ return confirmationPopup;
+}
+
+ConfirmationPopup::ConfirmationPopup()
+: Toolkit::Internal::Popup()
+{
+ mControlSignals.reserve( MAXIMUM_NUMBER_OF_CONTROLS );
+ mControlSignalNames[ Toolkit::ConfirmationPopup::CONTROL_OK ] = DEFAULT_CONNECT_SIGNAL_NAME;
+ mControlSignalNames[ Toolkit::ConfirmationPopup::CONTROL_CANCEL ] = DEFAULT_CONNECT_SIGNAL_NAME;
+}
+
+ConfirmationPopup::~ConfirmationPopup()
+{
+ for( SignalContainerType::iterator i = mControlSignals.begin(); i != mControlSignals.end(); ++i )
+ {
+ delete ( i->second );
+ }
+ mControlSignals.clear();
+}
+
+void ConfirmationPopup::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
+{
+ Toolkit::ConfirmationPopup popup = Toolkit::ConfirmationPopup::DownCast( Dali::BaseHandle( object ) );
+
+ if ( popup )
+ {
+ ConfirmationPopup& popupImpl( GetDerivedImplementation( popup ) );
+
+ switch ( propertyIndex )
+ {
+ case Toolkit::ConfirmationPopup::Property::CONNECT_SIGNAL_OK_SELECTED:
+ {
+ popupImpl.SetControlSignalName( Toolkit::ConfirmationPopup::CONTROL_OK, value.Get< std::string >() );
+ break;
+ }
+ case Toolkit::ConfirmationPopup::Property::CONNECT_SIGNAL_CANCEL_SELECTED:
+ {
+ popupImpl.SetControlSignalName( Toolkit::ConfirmationPopup::CONTROL_CANCEL, value.Get< std::string >() );
+ break;
+ }
+ }
+ }
+}
+
+Property::Value ConfirmationPopup::GetProperty( BaseObject* object, Property::Index propertyIndex )
+{
+ Property::Value value;
+
+ Toolkit::ConfirmationPopup popup = Toolkit::ConfirmationPopup::DownCast( Dali::BaseHandle( object ) );
+
+ if ( popup )
+ {
+ ConfirmationPopup& popupImpl( GetDerivedImplementation( popup ) );
+
+ switch ( propertyIndex )
+ {
+ case Toolkit::ConfirmationPopup::Property::CONNECT_SIGNAL_OK_SELECTED:
+ {
+ value = popupImpl.GetControlSignalName( Toolkit::ConfirmationPopup::CONTROL_OK );
+ break;
+ }
+ case Toolkit::ConfirmationPopup::Property::CONNECT_SIGNAL_CANCEL_SELECTED:
+ {
+ value = popupImpl.GetControlSignalName( Toolkit::ConfirmationPopup::CONTROL_CANCEL );
+ break;
+ }
+ }
+ }
+
+ return value;
+}
+
+void ConfirmationPopup::SetControlSignalName( const unsigned int controlNumber, const std::string& signalName )
+{
+ if( controlNumber < ControlDetailsCount )
+ {
+ mControlSignalNames[ controlNumber ] = signalName;
+ }
+}
+
+std::string ConfirmationPopup::GetControlSignalName( unsigned int controlNumber ) const
+{
+ if( controlNumber < ControlDetailsCount )
+ {
+ return mControlSignalNames[ controlNumber ];
+ }
+
+ return "";
+}
+
+bool ConfirmationPopup::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
+{
+ Dali::BaseHandle handle( object );
+ Toolkit::ConfirmationPopup popup = Toolkit::ConfirmationPopup::DownCast( handle );
+
+ // Look up the requested signal, attempting to create it dynamically if it doesn't exist.
+ SignalDelegate* signalDelegate = Dali::Toolkit::GetDerivedImplementation( popup ).GetControlSignal( signalName );
+ if( signalDelegate )
+ {
+ // The signal delegate was created successfully, attempt to connect it to a callback if specified.
+ // If none is specified, the creation is still successful as the signal delegate can connect at a later time.
+ if( functor )
+ {
+ signalDelegate->Connect( tracker, functor );
+ }
+ return true;
+ }
+
+ // The signal could not be created.
+ return false;
+}
+
+SignalDelegate* ConfirmationPopup::GetControlSignal( const std::string& signalName )
+{
+ // Check if the specified signal name already exists.
+ SignalContainerType::iterator end = mControlSignals.end();
+ for( SignalContainerType::iterator iter = mControlSignals.begin(); iter != end; ++iter )
+ {
+ // Find the first non-connected signal by matching signal name.
+ if( ( signalName == iter->first ) && ( !iter->second->IsConnected() ) )
+ {
+ // The requested signal (delegate) already exists, just return it.
+ return iter->second;
+ }
+ }
+
+ // The signal doesn't exist, or it does but it's already connected to something else.
+ // To make a new connection to an existing signal, we need a new delegate,
+ // as delegates house a signal connection functor each.
+ // Check the signal name is valid and if so create the signal dynamically.
+ for( unsigned int i = 0; i < ControlDetailsCount; ++i )
+ {
+ if( 0 == strcmp( signalName.c_str(), ControlDetails[ i ].signalName ) )
+ {
+ // The signal name is valid, check the respective actor to connect to exists.
+ Actor connectActor = Self().FindChildByName( ControlDetails[ i ].controlName );
+ if( connectActor )
+ {
+ // The actor exists, set up a signal delegate that will allow the application developer
+ // to connect the actor signal directly to their callback.
+ // Note: We don't use the GetControlSignalName() here for speedup, as we know the array bound is capped.
+ SignalDelegate* signalDelegate = new SignalDelegate( connectActor, mControlSignalNames[ i ] );
+
+ // Store the delegate with the signal name so we know what signals have been dynamically created so far.
+ mControlSignals.push_back( std::make_pair( signalName, signalDelegate ) );
+
+ // Return the delegate to allow connection to the newly created signal.
+ return signalDelegate;
+ }
+
+ // Signal name valid but could not connect to the control,
+ return NULL;
+ }
+ }
+
+ // Signal name was not found (invalid).
+ return NULL;
+}
+
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_CONFIRMATION_POPUP_H__
+#define __DALI_TOOLKIT_INTERNAL_CONFIRMATION_POPUP_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/animation/animation.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/devel-api/signals/signal-delegate.h>
+
+// INTERNAL INCLUDES
+#include "popup-impl.h"
+#include <dali-toolkit/devel-api/controls/popup/confirmation-popup.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+#define MAXIMUM_NUMBER_OF_CONTROLS 2
+
+}
+
+/**
+ * ConfirmationPopup implementation class.
+ *
+ * \sa Dali::Toolkit::ConfirmationPopup
+ */
+class ConfirmationPopup : public Dali::Toolkit::Internal::Popup
+{
+public:
+
+ /**
+ * Create a new ConfirmationPopup.
+ * @return A smart-pointer to the newly allocated ConfirmationPopup.
+ */
+ static Dali::Toolkit::ConfirmationPopup New();
+
+protected:
+
+ /**
+ * Construct a new ConfirmationPopup.
+ */
+ ConfirmationPopup();
+
+ /**
+ * A reference counted object may only be deleted by calling Unreference()
+ */
+ virtual ~ConfirmationPopup();
+
+public:
+
+ /**
+ * Called when a property of an object of this type is set.
+ * @param[in] object The object whose property is set.
+ * @param[in] propertyIndex The property index.
+ * @param[in] value The new property value.
+ */
+ static void SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value );
+
+ /**
+ * Called to retrieve a property of an object of this type.
+ * @param[in] object The object whose property is to be retrieved.
+ * @param[in] propertyIndex The property index.
+ * @return The current value of the property.
+ */
+ static Property::Value GetProperty( BaseObject* object, Property::Index propertyIndex );
+
+ /**
+ * Connects a callback function with the object's signals.
+ * @param[in] object The object providing the signal.
+ * @param[in] tracker Used to disconnect the signal.
+ * @param[in] signalName The signal to connect to.
+ * @param[in] functor A newly allocated FunctorDelegate.
+ * @return True if the signal was connected.
+ * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
+ */
+ static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
+
+private:
+
+ /**
+ * This type houses a list of dynamically created signals.
+ */
+ typedef std::vector< std::pair< std::string, SignalDelegate* > > SignalContainerType;
+
+private:
+
+ /**
+ * Sets the name of the signal to connect to within the specified actor.
+ *
+ * @param[in] controlNumber The index of the control.
+ * @param[in] signalName The name of the signal to connect to.
+ */
+ void SetControlSignalName( const unsigned int controlNumber, const std::string& signalName );
+
+ /**
+ * Gets the name of the signal to connect to within the specified actor.
+ *
+ * @param[in] controlNumber The index of the control.
+ * @return The name of the signal to connect to.
+ */
+ std::string GetControlSignalName( unsigned int controlNumber ) const;
+
+ /**
+ * @copydoc Control::GetControlSignal()
+ */
+ SignalDelegate* GetControlSignal( const std::string& signalName );
+
+private:
+
+ // Undefined
+ ConfirmationPopup( const ConfirmationPopup& );
+
+ // Undefined
+ ConfirmationPopup& operator=( const ConfirmationPopup& );
+
+private:
+
+ // Properties:
+
+ std::string mControlSignalNames[ MAXIMUM_NUMBER_OF_CONTROLS ]; ///< Stores the names of the signals to connect to per control.
+
+ // Internal variables:
+
+ SignalContainerType mControlSignals; ///< Stores the dynamically created signals.
+
+};
+
+} // namespace Internal
+
+
+// Helpers for public-api forwarding methods
+
+inline Toolkit::Internal::ConfirmationPopup& GetDerivedImplementation( Toolkit::ConfirmationPopup& popup )
+{
+ DALI_ASSERT_ALWAYS( popup );
+
+ Dali::RefObject& handle = popup.GetImplementation();
+
+ return static_cast<Toolkit::Internal::ConfirmationPopup&>( handle );
+}
+
+inline const Toolkit::Internal::ConfirmationPopup& GetDerivedImplementation( const Toolkit::ConfirmationPopup& popup )
+{
+ DALI_ASSERT_ALWAYS( popup );
+
+ const Dali::RefObject& handle = popup.GetImplementation();
+
+ return static_cast<const Toolkit::Internal::ConfirmationPopup&>( handle );
+}
+
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_CONFIRMATION_POPUP_H__
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// EXTERNAL INCLUDES
#include <cstring> // for strcmp
-#include <dali/public-api/adaptor-framework/key.h>
#include <dali/devel-api/adaptor-framework/physical-keyboard.h>
+#include <dali/devel-api/object/type-registry-helper.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/adaptor-framework/key.h>
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/common/stage.h>
#include <dali/public-api/events/key-event.h>
#include <dali/public-api/events/touch-event.h>
#include <dali/public-api/images/resource-image.h>
#include <dali/public-api/object/type-registry.h>
-#include <dali/devel-api/object/type-registry-helper.h>
+#include <dali/devel-api/scripting/scripting.h>
#include <dali/public-api/size-negotiation/relayout-container.h>
-#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/buttons/button.h>
+#include <dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
-#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
#include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
#include <dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h>
-#include <dali-toolkit/internal/controls/buttons/button-impl.h>
using namespace Dali;
namespace
{
+/**
+ * Creation function for main Popup type.
+ * @return Handle to the new popup object.
+ */
BaseHandle Create()
{
return Toolkit::Popup::New();
}
-// Setup properties, signals and actions using the type-registry.
-DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Popup, Toolkit::Control, Create )
+// Toast style defaults.
+const int DEFAULT_TOAST_AUTO_HIDE_DELAY = 3000; ///< Toast will auto-hide after 3000ms (3 seconds)
+const float DEFAULT_TOAST_TRANSITION_TIME = 0.65f; ///< Default time the toast Popup will take to show and hide.
+const Vector3 DEFAULT_TOAST_BOTTOM_PARENT_ORIGIN( 0.5f, 0.94f, 0.5f ); ///< This is similar to BOTTOM_CENTER, but vertically higher up, as a ratio of parent height.
+const Vector3 DEFAULT_TOAST_WIDTH_OF_STAGE_RATIO( 0.75f, 0.75f, 0.75f ); ///< Amount of the stage's width that the toast popup will take up.
-DALI_SIGNAL_REGISTRATION( Toolkit, Popup, "touched-outside", SIGNAL_TOUCHED_OUTSIDE )
-DALI_SIGNAL_REGISTRATION( Toolkit, Popup, "hidden", SIGNAL_HIDDEN )
+/**
+ * Creation function for named type "popup-toast".
+ * @return Handle to the new toast popup object.
+ */
+BaseHandle CreateToast()
+{
+ Toolkit::Popup popup = Toolkit::Popup::New();
-DALI_TYPE_REGISTRATION_END()
+ // Setup for Toast Popup type.
+ popup.SetSizeModeFactor( DEFAULT_TOAST_WIDTH_OF_STAGE_RATIO );
+ popup.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::WIDTH );
+ popup.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
+ popup.SetProperty( Toolkit::Popup::Property::CONTEXTUAL_MODE, Toolkit::Popup::NON_CONTEXTUAL );
+ popup.SetProperty( Toolkit::Popup::Property::ANIMATION_DURATION, DEFAULT_TOAST_TRANSITION_TIME );
+ popup.SetProperty( Toolkit::Popup::Property::TAIL_VISIBILITY, false );
-// Properties
-const char* const PROPERTY_TITLE = "title";
-const char* const PROPERTY_STATE = "state";
+ // Disable the dimmed backing.
+ popup.SetProperty( Toolkit::Popup::Property::BACKING_ENABLED, false );
-const float POPUP_ANIMATION_DURATION = 0.45f; ///< Duration of hide/show animations
+ // The toast popup should fade in (not zoom).
+ popup.SetProperty( Toolkit::Popup::Property::ANIMATION_MODE, Toolkit::Popup::FADE );
-const float POPUP_WIDTH = 720.0f; ///< Width of Popup
-const float POPUP_OUT_MARGIN_WIDTH = 16.f; ///< Space between the screen edge and the popup edge in the horizontal dimension.
-const float POPUP_OUT_MARGIN_HEIGHT = 36.f; ///< Space between the screen edge and the popup edge in the vertical dimension.
-const float POPUP_TITLE_WIDTH = 648.0f; ///<Width of Popup Title
-const float POPUP_BUTTON_BG_HEIGHT = 96.f; ///< Height of Button Background.
-const Vector3 DEFAULT_DIALOG_SIZE = Vector3(POPUP_TITLE_WIDTH/POPUP_WIDTH, 0.5f, 0.0f);
-const Vector3 DEFAULT_BOTTOM_SIZE = Vector3(1.0f, 0.2f, 0.0f);
+ // The toast popup should auto-hide.
+ popup.SetProperty( Toolkit::Popup::Property::AUTO_HIDE_DELAY, DEFAULT_TOAST_AUTO_HIDE_DELAY );
-} // unnamed namespace
+ // Align to the bottom of the screen.
+ popup.SetParentOrigin( DEFAULT_TOAST_BOTTOM_PARENT_ORIGIN );
+ popup.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Popup
-///////////////////////////////////////////////////////////////////////////////////////////////////
+ // Let events pass through the toast popup.
+ popup.SetProperty( Toolkit::Popup::Property::TOUCH_TRANSPARENT, true );
+
+ return popup;
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Popup, Toolkit::Control, Create )
+
+// Main content related properties.
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "title", MAP, TITLE )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "content", MAP, CONTENT )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "footer", MAP, FOOTER )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "display-state", STRING, DISPLAY_STATE )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "touch-transparent", BOOLEAN, TOUCH_TRANSPARENT )
+
+// Contextual related properties.
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "tail-visibility", BOOLEAN, TAIL_VISIBILITY )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "tail-position", VECTOR3, TAIL_POSITION )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "contextual-mode", STRING, CONTEXTUAL_MODE )
+
+// Animation related properties.
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "animation-duration", FLOAT, ANIMATION_DURATION )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "animation-mode", STRING, ANIMATION_MODE )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "entry-animation", MAP, ENTRY_ANIMATION )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "exit-animation", MAP, EXIT_ANIMATION )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "auto-hide-delay", INTEGER, AUTO_HIDE_DELAY )
+
+// Style related properties.
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "backing-enabled", BOOLEAN, BACKING_ENABLED )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "backing-color", VECTOR4, BACKING_COLOR )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "popup-background-image", STRING, POPUP_BACKGROUND_IMAGE )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "tail-up-image", STRING, TAIL_UP_IMAGE )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "tail-down-image", STRING, TAIL_DOWN_IMAGE )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "tail-left-image", STRING, TAIL_LEFT_IMAGE )
+DALI_PROPERTY_REGISTRATION( Toolkit, Popup, "tail-right-image", STRING, TAIL_RIGHT_IMAGE )
+
+// Signals.
+DALI_SIGNAL_REGISTRATION( Toolkit, Popup, "touched-outside", SIGNAL_TOUCHED_OUTSIDE )
+DALI_SIGNAL_REGISTRATION( Toolkit, Popup, "showing", SIGNAL_SHOWING )
+DALI_SIGNAL_REGISTRATION( Toolkit, Popup, "shown", SIGNAL_SHOWN )
+DALI_SIGNAL_REGISTRATION( Toolkit, Popup, "hiding", SIGNAL_HIDING )
+DALI_SIGNAL_REGISTRATION( Toolkit, Popup, "hidden", SIGNAL_HIDDEN )
+
+DALI_TYPE_REGISTRATION_END()
+
+// Named type registration.
+
+// Toast Popup: Non-modal popup that displays information at the bottom of the screen.
+TypeRegistration typeRegistrationToast( "popup-toast", typeid( Toolkit::Popup ), CreateToast );
+
+// Enumeration to / from string conversion tables
+
+const Scripting::StringEnum DisplayStateTable[] = {
+ { "SHOWING", Toolkit::Popup::SHOWING },
+ { "SHOWN", Toolkit::Popup::SHOWN },
+ { "HIDING", Toolkit::Popup::HIDING },
+ { "HIDDEN", Toolkit::Popup::HIDDEN },
+}; const unsigned int DisplayStateTableCount = sizeof( DisplayStateTable ) / sizeof( DisplayStateTable[0] );
+
+const Scripting::StringEnum AnimationModeTable[] = {
+ { "NONE", Toolkit::Popup::NONE },
+ { "ZOOM", Toolkit::Popup::ZOOM },
+ { "FADE", Toolkit::Popup::FADE },
+ { "CUSTOM", Toolkit::Popup::CUSTOM },
+}; const unsigned int AnimationModeTableCount = sizeof( AnimationModeTable ) / sizeof( AnimationModeTable[0] );
+
+const Scripting::StringEnum ContextualModeTable[] = {
+ { "NON_CONTEXTUAL", Toolkit::Popup::NON_CONTEXTUAL },
+ { "ABOVE", Toolkit::Popup::ABOVE },
+ { "RIGHT", Toolkit::Popup::RIGHT },
+ { "BELOW", Toolkit::Popup::BELOW },
+ { "LEFT", Toolkit::Popup::LEFT },
+}; const unsigned int ContextualModeTableCount = sizeof( ContextualModeTable ) / sizeof( ContextualModeTable[0] );
+
+// Popup defaults.
+const Vector3 DEFAULT_POPUP_PARENT_RELATIVE_SIZE( 0.75f, 1.0f, 1.0f ); ///< Default size percentage of parent.
+const float DEFAULT_POPUP_ANIMATION_DURATION = 0.6f; ///< Duration of hide/show animations.
+const float POPUP_OUT_MARGIN_WIDTH = 16.f; ///< Space between the screen edge and the popup edge in the horizontal dimension.
+const float POPUP_OUT_MARGIN_HEIGHT = 36.f; ///< Space between the screen edge and the popup edge in the vertical dimension.
+const Vector3 DEFAULT_TAIL_POSITION( 0.5f, 1.0f, 0.0f ); ///< Position the tail will be displayed when enabled without setting the position.
+
+// Contextual defaults.
+const Vector2 DEFAULT_CONTEXTUAL_ADJACENCY_MARGIN( 10.0f, 10.0f ); ///< How close the Popup will be to it's contextual parent.
+const Vector2 DEFAULT_CONTEXTUAL_STAGE_BORDER( 15.0f, 15.0f ); ///< How close the Popup can be to the stage edges.
+
+// Popup style defaults.
+const char* DEFAULT_BACKGROUND_IMAGE_PATH = DALI_IMAGE_DIR "00_popup_bg.9.png"; ///< Background image.
+const char* DEFAULT_TAIL_UP_IMAGE_PATH = DALI_IMAGE_DIR "popup_tail_up.png"; ///< Tail up image.
+const char* DEFAULT_TAIL_DOWN_IMAGE_PATH = DALI_IMAGE_DIR "popup_tail_down.png"; ///< Tail down image.
+const char* DEFAULT_TAIL_LEFT_IMAGE_PATH = DALI_IMAGE_DIR "popup_tail_left.png"; ///< Tail left image.
+const char* DEFAULT_TAIL_RIGHT_IMAGE_PATH = DALI_IMAGE_DIR "popup_tail_right.png"; ///< Tail right image.
+
+const Vector4 DEFAULT_BACKING_COLOR( 0.0f, 0.0f, 0.0f, 0.5f ); ///< Color of the dimmed backing.
+const Vector3 BACKGROUND_OUTER_BORDER( 40.0f, 30.0f, 0.0f ); ///< External border.
+const Rect<float> DEFAULT_TITLE_PADDING( 20.0f, 20.0f, 20.0f, 20.0f ); ///< Title padding used on popups with content and/or controls (from Tizen GUI UX).
+const Rect<float> DEFAULT_TITLE_ONLY_PADDING( 8.0f, 8.0f, 8.0f, 8.0f ); ///< Title padding used on popups with a title only (like toast popups).
+const Vector3 FOOTER_SIZE( 620.0f, 96.0f,0.0f ); ///< Default size of the bottom control area.
+const float DEFAULT_RELATIVE_PARENT_WIDTH = 0.75f; ///< If width is not fixed, relative size to parent is used by default.
+
+} // Unnamed namespace
+
+/*
+ * Implementation.
+ */
Dali::Toolkit::Popup Popup::New()
{
- PopupStylePtr style = PopupStyleDefault::New();
-
// Create the implementation
- PopupPtr popup(new Popup(*style));
+ PopupPtr popup( new Popup() );
- // Pass ownership to CustomActor via derived handle
- Dali::Toolkit::Popup handle(*popup);
+ // Pass ownership to CustomActor via derived handle.
+ Dali::Toolkit::Popup handle( *popup );
- // Second-phase init of the implementation
- // This can only be done after the CustomActor connection has been made...
+ // Second-phase initialisation of the implementation.
+ // This can only be done after the CustomActor connection has been made.
popup->Initialize();
return handle;
}
-Popup::Popup(PopupStyle& style)
+Popup::Popup()
: Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS ) ),
- mShowing(false),
- mState(Toolkit::Popup::POPUP_NONE), // Initially, the popup state should not be set, it's set in OnInitialize
- mAlterAddedChild(false),
- mPopupStyle(PopupStylePtr(&style)),
- mPropertyTitle(Property::INVALID_INDEX),
- mPropertyState(Property::INVALID_INDEX)
+ // Main variables:
+ mAlterAddedChild( false ),
+ mLayoutDirty( true ),
+ mTouchTransparent( false ),
+
+ // Property variables:
+ mDisplayState( Toolkit::Popup::HIDDEN ), // Hidden until shown with SetDisplayState()
+ mTailVisible( false ),
+ mTailPosition( DEFAULT_TAIL_POSITION ),
+ mContextualMode( Toolkit::Popup::NON_CONTEXTUAL ),
+ mAnimationDuration( DEFAULT_POPUP_ANIMATION_DURATION ),
+ mAnimationMode( Toolkit::Popup::FADE ),
+ mAutoHideDelay( 0 ),
+ mBackingEnabled( true ),
+ mBackingColor( DEFAULT_BACKING_COLOR ),
+ mTailUpImage( DEFAULT_TAIL_UP_IMAGE_PATH ),
+ mTailDownImage( DEFAULT_TAIL_DOWN_IMAGE_PATH ),
+ mTailLeftImage( DEFAULT_TAIL_LEFT_IMAGE_PATH ),
+ mTailRightImage( DEFAULT_TAIL_RIGHT_IMAGE_PATH )
{
SetKeyboardNavigationSupport( true );
}
void Popup::OnInitialize()
{
- Dali::Stage stage = Dali::Stage::GetCurrent();
-
Actor self = Self();
- self.SetSensitive(false);
- // Reisize to fit the height of children
- self.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT );
+ self.SetName( "popup" );
- // Create Layer
+ // Apply some default resizing rules.
+ self.SetParentOrigin( ParentOrigin::CENTER );
+ self.SetAnchorPoint( AnchorPoint::CENTER );
+
+ self.SetSizeModeFactor( DEFAULT_POPUP_PARENT_RELATIVE_SIZE );
+ self.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::WIDTH );
+ self.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
+
+ // Create a new layer so all Popup components can appear above all other actors.
mLayer = Layer::New();
- mLayer.SetName( "POPUP_LAYER" );
- mLayer.SetDepthTestDisabled( true );
- mLayer.SetParentOrigin(ParentOrigin::CENTER);
- mLayer.SetAnchorPoint(AnchorPoint::CENTER);
+ mLayer.SetName( "popup-layer" );
+
+ mLayer.SetParentOrigin( ParentOrigin::CENTER );
+ mLayer.SetAnchorPoint( AnchorPoint::CENTER );
mLayer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
- // Any content after this point which is added to Self() will be reparented to
- // mContent.
- mAlterAddedChild = true;
- // Add Backing (Dim effect)
- CreateBacking();
- mAlterAddedChild = false;
+ // Important to set as invisible as otherwise, if the popup is parented,
+ // but not shown yet it will appear statically on the screen.
+ mLayer.SetVisible( false );
+
+ // Add the layer to the hierarchy.
+ self.Add( mLayer );
- // Add Dialog ( background image, title, content container, button container and tail )
- CreateDialog();
+ // Add Backing (Dimmed effect).
+ mLayer.Add( CreateBacking() );
- mLayer.Add( self );
+ mPopupContainer = Actor::New();
+ mPopupContainer.SetName( "popup-container" );
+ mPopupContainer.SetParentOrigin( ParentOrigin::CENTER );
+ mPopupContainer.SetAnchorPoint( AnchorPoint::CENTER );
+ mPopupContainer.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
+ mLayer.Add( mPopupContainer );
+ // Create the Popup layout to contain all main content.
mPopupLayout = Toolkit::TableView::New( 3, 1 );
- mPopupLayout.SetName( "POPUP_LAYOUT_TABLE" );
- mPopupLayout.SetParentOrigin(ParentOrigin::CENTER);
- mPopupLayout.SetAnchorPoint(AnchorPoint::CENTER);
- mPopupLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
+
+ // Adds the default background image.
+ SetPopupBackgroundImage( ImageActor::New( ResourceImage::New( DEFAULT_BACKGROUND_IMAGE_PATH ) ) );
+
+ mPopupLayout.SetName( "popup-layout-table" );
+ mPopupLayout.SetParentOrigin( ParentOrigin::CENTER );
+ mPopupLayout.SetAnchorPoint( AnchorPoint::CENTER );
+
+ mPopupLayout.SetResizePolicy( ResizePolicy::USE_ASSIGNED_SIZE, Dimension::WIDTH );
mPopupLayout.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
- mPopupLayout.SetFitHeight( 0 ); // Set row to fit
- mPopupLayout.SetFitHeight( 1 ); // Set row to fit
- self.Add( mPopupLayout );
+ mPopupLayout.SetSize( Stage::GetCurrent().GetSize().x * DEFAULT_RELATIVE_PARENT_WIDTH, 0.0f );
+
+ mPopupLayout.SetFitHeight( 0 ); // Set row to fit.
+ mPopupLayout.SetFitHeight( 1 ); // Set row to fit.
- // Any content after this point which is added to Self() will be reparented to
- // mContent.
+ mPopupLayout.TouchedSignal().Connect( this, &Popup::OnDialogTouched );
+
+ mPopupContainer.Add( mPopupLayout );
+
+ // Any content after this point which is added to Self() will be re-parented to mContent.
mAlterAddedChild = true;
- // Default content.
-// ShowTail(ParentOrigin::BOTTOM_CENTER);
+ // Make self keyboard focusable and a focus group.
+ self.SetKeyboardFocusable( true );
+ SetAsKeyboardFocusGroup( true );
+}
+
+Popup::~Popup()
+{
+ mEntryAnimationData.Clear();
+ mExitAnimationData.Clear();
+}
- // Hide content by default.
- SetState( Toolkit::Popup::POPUP_HIDE, 0.0f );
+void Popup::LayoutAnimation()
+{
+ // Perform setup based on the currently selected animation.
+ switch( mAnimationMode )
+ {
+ case Toolkit::Popup::ZOOM:
+ {
+ // Zoom animations start fully zoomed out.
+ mPopupContainer.SetScale( Vector3::ZERO );
+ break;
+ }
- mPropertyTitle = self.RegisterProperty( PROPERTY_TITLE, "", Property::READ_WRITE );
- mPropertyState = self.RegisterProperty( PROPERTY_STATE, "POPUP_HIDE", Property::READ_WRITE );
+ case Toolkit::Popup::FADE:
+ {
+ // Fade animations start transparent.
+ mPopupContainer.SetOpacity( 0.0f );
+ break;
+ }
- // Make self as keyboard focusable and focus group
- self.SetKeyboardFocusable(true);
- SetAsKeyboardFocusGroup(true);
+ case Toolkit::Popup::CUSTOM:
+ {
+ // Initialise the custom animation by playing to the end of it's exit animation instantly.
+ // EG. If it was zooming in, then we zoom out fully instantly so the zoom in works.
+ StartTransitionAnimation( false, true );
+ break;
+ }
+
+ case Toolkit::Popup::NONE:
+ {
+ break;
+ }
+ }
}
-void Popup::OnPropertySet( Property::Index index, Property::Value propertyValue )
+void Popup::StartTransitionAnimation( bool transitionIn, bool instantaneous /* false */ )
{
- if( index == mPropertyTitle )
+ // Stop and recreate animation.
+ if ( mAnimation )
{
- SetTitle(propertyValue.Get<std::string>());
+ mAnimation.Stop();
+ mAnimation.Clear();
+ mAnimation.Reset();
}
- else if ( index == mPropertyState )
+ float duration = GetAnimationDuration();
+
+ // Setup variables ready to start the animations.
+ // If we are performing the animation instantaneously, we do not want to emit a signal.
+ if( !instantaneous )
{
- std::string value( propertyValue.Get<std::string>() );
- if(value == "POPUP_SHOW")
+ if( transitionIn )
{
- SetState( Toolkit::Popup::POPUP_SHOW, 0.0f );
+ // Setup variables and signal that we are starting the transition.
+ // Note: We signal even if the transition is instant so signal order is consistent.
+ mShowingSignal.Emit();
}
- else if( value == "POPUP_HIDE")
+ else
{
- SetState( Toolkit::Popup::POPUP_HIDE, 0.0f );
+ mHidingSignal.Emit();
}
}
-}
-Popup::~Popup()
-{
- mLayer.Unparent();
+ // Perform chosen animation for the Popup.
+ switch( mAnimationMode )
+ {
+ case Toolkit::Popup::NONE:
+ {
+ mAnimation = Animation::New( 0.0f );
+ break;
+ }
+
+ case Toolkit::Popup::ZOOM:
+ {
+ mAnimation = Animation::New( duration );
+ if( duration > Math::MACHINE_EPSILON_0 )
+ {
+ if( transitionIn )
+ {
+ mAnimation.AnimateTo( Property( mPopupContainer, Actor::Property::SCALE ), Vector3::ONE, AlphaFunction::EASE_IN_OUT, TimePeriod( duration * 0.25f, duration * 0.75f ) );
+ }
+ else
+ {
+ // Zoom out animation is twice the speed. Modify the duration variable so the backing animation speed is modified also.
+ duration /= 2.0f;
+ mAnimation.SetDuration( duration );
+ mAnimation.AnimateTo( Property( mPopupContainer, Actor::Property::SCALE ), Vector3::ZERO, AlphaFunction::EASE_IN_OUT, TimePeriod( 0.0f, duration ) );
+ }
+ }
+ else
+ {
+ mPopupContainer.SetScale( transitionIn ? Vector3::ONE : Vector3::ZERO );
+ }
+ break;
+ }
+
+ case Toolkit::Popup::FADE:
+ {
+ mAnimation = Animation::New( duration );
+ if( duration > Math::MACHINE_EPSILON_0 )
+ {
+ if( transitionIn )
+ {
+ mAnimation.AnimateTo( Property( mPopupContainer, Actor::Property::COLOR_ALPHA ), 1.0f, AlphaFunction::EASE_IN_OUT, TimePeriod( 0.30f, duration * 0.70f ) );
+ }
+ else
+ {
+ mAnimation.AnimateTo( Property( mPopupContainer, Actor::Property::COLOR_ALPHA ), 0.0f, AlphaFunction::EASE_IN_OUT, TimePeriod( 0.0f, duration * 0.70f ) );
+ }
+ }
+ else
+ {
+ mPopupContainer.SetOpacity( transitionIn ? 1.0f : 0.0f );
+ }
+ break;
+ }
+
+ case Toolkit::Popup::CUSTOM:
+ {
+ // Use a user specified animation for in and out.
+ // Read the correct animation depending on entry or exit.
+ // Attempt to use animation data defined from script data.
+ Dali::AnimationData* animationData = transitionIn ? &mEntryAnimationData : &mExitAnimationData;
+
+ // Create a new animation from the pre-defined data in the AnimationData class.
+ // If there is no data, mAnimation is invalidated.
+ mAnimation = animationData->CreateAnimation( mPopupContainer, duration );
+
+ // If we don't have a valid animation, provide a blank one so play() can still function generically.
+ if( !mAnimation )
+ {
+ // No animation was configured (even though custom mode was specified). Create a dummy animation to avoid an exception.
+ mAnimation = Animation::New( 0.0f );
+ }
+
+ break;
+ }
+ }
+
+ // Animate the backing, if enabled.
+ // This is set up last so that different animation modes can have an effect on the backing animation speed.
+ if( mBackingEnabled )
+ {
+ if( duration > Math::MACHINE_EPSILON_0 )
+ {
+ if( transitionIn )
+ {
+ mAnimation.AnimateTo( Property( mBacking, Actor::Property::COLOR_ALPHA ), 1.0f, AlphaFunction::EASE_IN_OUT, TimePeriod( 0.0f, duration * 0.70f ) );
+ }
+ else
+ {
+ mAnimation.AnimateTo( Property( mBacking, Actor::Property::COLOR_ALPHA ), 0.0f, AlphaFunction::EASE_IN_OUT, TimePeriod( 0.30f, duration * 0.70f ) );
+ }
+ }
+ else
+ {
+ mBacking.SetOpacity( transitionIn ? 1.0f : 0.0f );
+ }
+ }
+
+ // If we are performing the animation instantaneously, jump to the position directly and do not signal.
+ if( instantaneous )
+ {
+ mAnimation.SetCurrentProgress( 1.0f );
+ mAnimation.Play();
+ }
+ else if( duration > Math::MACHINE_EPSILON_0 )
+ {
+ // Run the animation.
+ mAnimation.FinishedSignal().Connect( this, &Popup::OnDisplayChangeAnimationFinished );
+ mAnimation.Play();
+ }
+ else
+ {
+ // We did not use an animation to achive the transition.
+ // Trigger the state change directly.
+ DisplayStateChangeComplete();
+ }
}
-size_t Popup::GetButtonCount() const
+void Popup::OnDisplayChangeAnimationFinished( Animation& source )
{
- return mButtons.size();
+ DisplayStateChangeComplete();
}
-void Popup::SetBackgroundImage( Actor image )
+void Popup::DisplayStateChangeComplete()
{
- // Removes any previous background.
- if( mBackgroundImage && mPopupLayout )
+ // Remove contents from stage if completely hidden.
+ if( mDisplayState == Toolkit::Popup::HIDING )
{
- mPopupLayout.Remove( mBackgroundImage );
- }
+ mDisplayState = Toolkit::Popup::HIDDEN;
- // Adds new background to the dialog.
- mBackgroundImage = image;
+ mLayer.SetVisible( false );
+ mPopupLayout.SetSensitive( false );
- mBackgroundImage.SetName( "POPUP_BACKGROUND_IMAGE" );
+ // Guard against destruction during signal emission.
+ Toolkit::Popup handle( GetOwner() );
+ mHiddenSignal.Emit();
+ }
+ else if( mDisplayState == Toolkit::Popup::SHOWING )
+ {
+ mDisplayState = Toolkit::Popup::SHOWN;
+ Toolkit::Popup handle( GetOwner() );
+ mShownSignal.Emit();
+
+ // Start a timer to auto-hide if enabled.
+ if( mAutoHideDelay > 0u )
+ {
+ mAutoHideTimer = Timer::New( mAutoHideDelay );
+ mAutoHideTimer.TickSignal().Connect( this, &Popup::OnAutoHideTimeReached );
+ mAutoHideTimer.Start();
+ }
+ }
+}
- // OnDialogTouched only consume the event. It prevents the touch event to be caught by the backing.
- mBackgroundImage.TouchedSignal().Connect( this, &Popup::OnDialogTouched );
+bool Popup::OnAutoHideTimeReached()
+{
+ // Display timer has expired, auto hide the popup exactly as if the user had clicked outside.
+ SetDisplayState( Toolkit::Popup::HIDDEN );
- mBackgroundImage.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS );
- mBackgroundImage.SetAnchorPoint( AnchorPoint::CENTER );
- mBackgroundImage.SetParentOrigin( ParentOrigin::CENTER );
+ if( mAutoHideTimer )
+ {
+ mAutoHideTimer.Stop();
+ mAutoHideTimer.TickSignal().Disconnect( this, &Popup::OnAutoHideTimeReached );
+ mAutoHideTimer.Reset();
+ }
+ return true;
+}
- if ( ImageActor imageActor = DownCast< ImageActor >( image ) )
+void Popup::SetPopupBackgroundImage( Actor image )
+{
+ // Removes any previous background.
+ if( mPopupBackgroundImage )
{
- imageActor.SetSortModifier( BACKGROUND_DEPTH_INDEX );
+ mPopupContainer.Remove( mPopupBackgroundImage );
}
- Vector3 border( mPopupStyle->backgroundOuterBorder.x, mPopupStyle->backgroundOuterBorder.z, 0.0f );
- mBackgroundImage.SetSizeModeFactor( border );
+ // Adds new background to the dialog.
+ mPopupBackgroundImage = image;
+ mPopupBackgroundImage.SetName( "popup-background-image" );
+ mPopupBackgroundImage.SetAnchorPoint( AnchorPoint::CENTER );
+ mPopupBackgroundImage.SetParentOrigin( ParentOrigin::CENTER );
+
+ // OnDialogTouched only consumes the event. It prevents the touch event to be caught by the backing.
+ mPopupBackgroundImage.TouchedSignal().Connect( this, &Popup::OnDialogTouched );
+
+ // Set the popup border to be slightly larger than the layout contents.
+ mPopupBackgroundImage.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS );
+ mPopupBackgroundImage.SetSizeModeFactor( BACKGROUND_OUTER_BORDER );
const bool prevAlter = mAlterAddedChild;
mAlterAddedChild = false;
- Self().Add( mBackgroundImage );
+ mPopupContainer.Add( mPopupBackgroundImage );
mAlterAddedChild = prevAlter;
+
+ mLayoutDirty = true;
+}
+
+Actor Popup::GetPopupBackgroundImage() const
+{
+ return mPopupBackgroundImage;
}
-void Popup::SetButtonAreaImage( Actor image )
+void Popup::SetTitle( Actor titleActor )
{
- // Removes any previous area image.
- if( mButtonAreaImage && mPopupLayout )
+ // Replaces the current title actor.
+ if( !mPopupLayout )
{
- mPopupLayout.Remove( mButtonAreaImage );
+ return;
}
- // Adds new area image to the dialog.
- mButtonAreaImage = image;
-
- if ( ImageActor imageActor = DownCast< ImageActor >( image ) )
+ if( mTitle )
{
- imageActor.SetSortModifier( BACKGROUND_DEPTH_INDEX + 1 );
+ mPopupLayout.RemoveChildAt( Toolkit::TableView::CellPosition( 0, 0) );
}
+ mTitle = titleActor;
- // OnDialogTouched only consume the event. It prevents the touch event to be caught by the backing.
- mButtonAreaImage.TouchedSignal().Connect( this, &Popup::OnDialogTouched );
-
- mButtonAreaImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
- mButtonAreaImage.SetAnchorPoint( AnchorPoint::CENTER );
- mButtonAreaImage.SetParentOrigin( ParentOrigin::CENTER );
-
- if( GetButtonCount() > 0 )
+ if( mTitle )
{
- mBottomBg.Add( mButtonAreaImage );
+ // Set up padding to give sensible default behaviour
+ // (an application developer can later override this if they wish).
+ mTitle.SetPadding( DEFAULT_TITLE_PADDING );
+
+ mPopupLayout.AddChild( mTitle, Toolkit::TableView::CellPosition( 0, 0 ) );
}
+
+ mLayoutDirty = true;
+ RelayoutRequest();
}
-void Popup::SetTitle( const std::string& text )
+Actor Popup::GetTitle() const
{
- // Replaces the current title actor.
+ return mTitle;
+}
+
+void Popup::SetContent( Actor content )
+{
+ // Remove previous content actor.
if( mPopupLayout )
{
- mPopupLayout.RemoveChildAt( Toolkit::TableView::CellPosition( 0, 0 ) );
+ mPopupLayout.RemoveChildAt( Toolkit::TableView::CellPosition( 1, 0 ) );
}
+ // Keep a handle to the new content.
+ mContent = content;
- mTitle = Toolkit::TextLabel::New( text );
- mTitle.SetName( "POPUP_TITLE" );
- mTitle.SetProperty( Toolkit::TextLabel::Property::MULTI_LINE, true );
- mTitle.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
-
- if( mPopupLayout )
+ if( mContent )
{
- mTitle.SetPadding( Padding( 0.0f, 0.0f, mPopupStyle->margin, mPopupStyle->margin ) );
- mTitle.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
- mTitle.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
- mPopupLayout.AddChild( mTitle, Toolkit::TableView::CellPosition( 0, 0 ) );
+ mContent.SetName( "popup-content" );
+
+ mPopupLayout.AddChild( mContent, Toolkit::TableView::CellPosition( 1, 0 ) );
}
+ mLayoutDirty = true;
RelayoutRequest();
}
-std::string Popup::GetTitle() const
+Actor Popup::GetContent() const
{
- if( mTitle )
+ return mContent;
+}
+
+void Popup::SetFooter( Actor footer )
+{
+ // Remove previous content actor.
+ if( mPopupLayout )
{
- return mTitle.GetProperty<std::string>( Toolkit::TextLabel::Property::TEXT );
+ mPopupLayout.RemoveChildAt( Toolkit::TableView::CellPosition( 2, 0 ) );
}
- return std::string();
-}
+ // Keep a handle to the new content.
+ mFooter = footer;
-void Popup::CreateFooter()
-{
- if( !mBottomBg )
+ if( mFooter )
{
- // Adds bottom background
- mBottomBg = Actor::New();
- mBottomBg.SetName( "POPUP_BOTTOM_BG" );
- mBottomBg.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+ mFooter.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
- mPopupLayout.SetFixedHeight( 2, mPopupStyle->bottomSize.height ); // Buttons
- mPopupLayout.AddChild( mBottomBg, Toolkit::TableView::CellPosition( 2, 0 ) );
+ // The control container has a fixed height.
+ mPopupLayout.SetFitHeight( 2u );
+ mPopupLayout.AddChild( footer, Toolkit::TableView::CellPosition( 2, 0 ) );
}
+
+ mLayoutDirty = true;
+ RelayoutRequest();
}
-void Popup::AddButton( Toolkit::Button button )
+Actor Popup::GetFooter() const
{
- mButtons.push_back( button );
- button.SetResizePolicy( ResizePolicy::USE_ASSIGNED_SIZE, Dimension::ALL_DIMENSIONS ); // Size will be assigned to it
+ return mFooter;
+}
+
+void Popup::SetDisplayState( Toolkit::Popup::DisplayState displayState )
+{
+ // Convert the 4-way state to a bool, true for show, false for hide.
+ bool display = ( displayState == Toolkit::Popup::SHOWING ) || ( displayState == Toolkit::Popup::SHOWN );
+
+ // Ignore if we are already at the target display state.
+ if( display == ( ( mDisplayState == Toolkit::Popup::SHOWING ) || ( mDisplayState == Toolkit::Popup::SHOWN ) ) )
+ {
+ return;
+ }
+
+ // Convert the bool state to the actual display state to use.
+ mDisplayState = display ? Toolkit::Popup::SHOWING : Toolkit::Popup::HIDING;
- // If this is the first button added
- if( mButtons.size() == 1 )
+ if ( display )
{
- CreateFooter();
+ // Update the state to indicate the current intent.
+ mDisplayState = Toolkit::Popup::SHOWING;
- if( mButtonAreaImage )
+ // We are displaying so bring the popup layer to the front, and set it visible so it is rendered.
+ mLayer.RaiseToTop();
+ mLayer.SetVisible( true );
+
+ // Set up the layout if this is the first display or the layout has become dirty.
+ if( mLayoutDirty )
{
- mBottomBg.Add( mButtonAreaImage );
+ // Bake-in any style and layout options to create the Popup layout.
+ LayoutPopup();
+ }
+
+ // Allow the popup to catch events.
+ mPopupLayout.SetSensitive( true );
+ SetKeyInputFocus();
+
+ // Handle the keyboard focus when popup is shown.
+ Dali::Toolkit::KeyboardFocusManager keyboardFocusManager = Dali::Toolkit::KeyboardFocusManager::Get();
+ if( keyboardFocusManager )
+ {
+ mPreviousFocusedActor = keyboardFocusManager.GetCurrentFocusActor();
+
+ if( mContent && mContent.IsKeyboardFocusable() )
+ {
+ // If content is focusable, move the focus to content.
+ keyboardFocusManager.SetCurrentFocusActor( mContent );
+ }
+ else
+ {
+ DALI_LOG_WARNING( "There is no focusable in popup\n" );
+ }
}
}
+ else // Not visible.
+ {
+ mDisplayState = Toolkit::Popup::HIDING;
+ ClearKeyInputFocus();
- mBottomBg.Add( button );
+ // Restore the keyboard focus when popup is hidden.
+ if( mPreviousFocusedActor && mPreviousFocusedActor.IsKeyboardFocusable() )
+ {
+ Dali::Toolkit::KeyboardFocusManager keyboardFocusManager = Dali::Toolkit::KeyboardFocusManager::Get();
+ if( keyboardFocusManager )
+ {
+ keyboardFocusManager.SetCurrentFocusActor( mPreviousFocusedActor );
+ }
+ }
+ }
- RelayoutRequest();
+ // Perform animation.
+ StartTransitionAnimation( display );
}
-void Popup::SetState( Toolkit::Popup::PopupState state )
+Toolkit::Popup::DisplayState Popup::GetDisplayState() const
{
- SetState( state, POPUP_ANIMATION_DURATION );
+ return mDisplayState;
}
-void Popup::SetState( Toolkit::Popup::PopupState state, float duration )
+void Popup::LayoutPopup()
{
- // default animation behaviour.
- HandleStateChange(state, duration);
-}
+ mLayoutDirty = false;
+
+ /* When animating in, we want to respect the origin applied to Self().
+ * For example, if zooming, not only will the final result be anchored to the
+ * selected point, but the zoom will originate from this point also.
+ *
+ * EG: ParentOrigin::TOP_LEFT, AnchorPoint::TOP_LEFT :
+ *
+ * -------- --------
+ * |X| |XXX|
+ * |`` Animates |XXX|
+ * | to: |XXX|
+ * | |````
+ * | |
+ */
+ mPopupContainer.SetParentOrigin( Self().GetCurrentParentOrigin() );
+ mPopupContainer.SetAnchorPoint( Self().GetCurrentAnchorPoint() );
+
+ // If there is only a title, use less padding.
+ if( mTitle )
+ {
+ if( !mContent && !mFooter )
+ {
+ mTitle.SetPadding( DEFAULT_TITLE_ONLY_PADDING );
+ }
+ else
+ {
+ mTitle.SetPadding( DEFAULT_TITLE_PADDING );
+ }
+ }
-Toolkit::Popup::PopupState Popup::GetState() const
-{
- return mState;
+ // Allow derived classes to perform any layout they may need to do.
+ OnLayoutSetup();
+
+ // Update background visibility.
+ mPopupContainer.SetVisible( !( !mFooter && mPopupLayout.GetChildCount() == 0 ) );
+
+ // Create / destroy / position the tail as needed.
+ LayoutTail();
+
+ // Setup any layout and initialisation required for the selected animation.
+ LayoutAnimation();
+
+ RelayoutRequest();
}
-void Popup::ShowTail(const Vector3& position)
+void Popup::LayoutTail()
{
- // Replaces the tail actor.
- if(mTailImage && mTailImage.GetParent())
+ // Removes the tail actor.
+ if( mTailImage && mTailImage.GetParent() )
{
mTailImage.GetParent().Remove( mTailImage );
mTailImage.Reset();
}
- std::string image = "";
+ if( !mTailVisible )
+ {
+ return;
+ }
+
+ const Vector3& position = GetTailPosition();
+ std::string image;
// depending on position of tail around ParentOrigin, a different tail image is used...
- if(position.y < Math::MACHINE_EPSILON_1)
+ if( position.y < Math::MACHINE_EPSILON_1 )
{
- image = mPopupStyle->tailUpImage;
+ image = mTailUpImage;
}
- else if(position.y > 1.0f - Math::MACHINE_EPSILON_1)
+ else if( position.y > 1.0f - Math::MACHINE_EPSILON_1 )
{
- image = mPopupStyle->tailDownImage;
+ image = mTailDownImage;
}
- else if(position.x < Math::MACHINE_EPSILON_1)
+ else if( position.x < Math::MACHINE_EPSILON_1 )
{
- image = mPopupStyle->tailLeftImage;
+ image = mTailLeftImage;
}
- else if(position.x > 1.0f - Math::MACHINE_EPSILON_1)
+ else if( position.x > 1.0f - Math::MACHINE_EPSILON_1 )
{
- image = mPopupStyle->tailRightImage;
+ image = mTailRightImage;
}
- if(image != "")
+ if( !image.empty() )
{
+ // Adds the tail actor.
Image tail = ResourceImage::New( image );
- mTailImage = ImageActor::New(tail);
+ mTailImage = ImageActor::New( tail );
+ mTailImage.SetName( "tail-image" );
const Vector3 anchorPoint = AnchorPoint::BOTTOM_RIGHT - position;
+ mTailImage.SetParentOrigin( position );
+ mTailImage.SetAnchorPoint( anchorPoint );
- mTailImage.SetParentOrigin(position);
- mTailImage.SetAnchorPoint(anchorPoint);
+ mLayer.Add( mTailImage );
+ }
+}
- CreateFooter();
+void Popup::SetContextualMode( Toolkit::Popup::ContextualMode mode )
+{
+ mContextualMode = mode;
+ mLayoutDirty = true;
+}
- mBottomBg.Add(mTailImage);
- }
+Toolkit::Popup::ContextualMode Popup::GetContextualMode() const
+{
+ return mContextualMode;
+}
+
+ImageActor Popup::CreateBacking()
+{
+ mBacking = Dali::Toolkit::CreateSolidColorActor( mBackingColor );
+ mBacking.SetName( "popup-backing" );
+
+ // Must always be positioned top-left of stage, regardless of parent.
+ mBacking.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
+ mBacking.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ // Always the full size of the stage.
+ mBacking.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
+ mBacking.SetSize( Stage::GetCurrent().GetSize() );
+
+ // Catch events.
+ mBacking.SetSensitive( true );
+
+ // Default to being transparent.
+ mBacking.SetOpacity( 0.0f );
+ mBacking.TouchedSignal().Connect( this, &Popup::OnBackingTouched );
+ mBacking.WheelEventSignal().Connect( this, &Popup::OnBackingWheelEvent );
+ return mBacking;
}
-void Popup::HideTail()
+Toolkit::Popup::TouchedOutsideSignalType& Popup::OutsideTouchedSignal()
{
- ShowTail(ParentOrigin::CENTER);
+ return mTouchedOutsideSignal;
}
-void Popup::SetStyle(PopupStyle& style)
+Toolkit::Popup::DisplayStateChangeSignalType& Popup::ShowingSignal()
{
- mPopupStyle = PopupStylePtr(&style);
- // update //
+ return mShowingSignal;
}
-PopupStylePtr Popup::GetStyle() const
+Toolkit::Popup::DisplayStateChangeSignalType& Popup::ShownSignal()
{
- return mPopupStyle;
+ return mShownSignal;
}
-void Popup::SetDefaultBackgroundImage()
+Toolkit::Popup::DisplayStateChangeSignalType& Popup::HidingSignal()
{
- Image buttonBg = ResourceImage::New( mPopupStyle->buttonAreaImage );
- ImageActor buttonBgImage = ImageActor::New( buttonBg );
- buttonBgImage.SetStyle( ImageActor::STYLE_NINE_PATCH );
- buttonBgImage.SetNinePatchBorder( mPopupStyle->buttonArea9PatchBorder );
+ return mHidingSignal;
+}
- SetBackgroundImage( ImageActor::New( ResourceImage::New( mPopupStyle->backgroundImage ) ) );
- SetButtonAreaImage( buttonBgImage );
+Toolkit::Popup::DisplayStateChangeSignalType& Popup::HiddenSignal()
+{
+ return mHiddenSignal;
}
-void Popup::CreateBacking()
+void Popup::SetTailVisibility( bool visible )
{
- mBacking = Dali::Toolkit::CreateSolidColorActor( mPopupStyle->backingColor );
- mBacking.SetName( "POPUP_BACKING" );
- mBacking.SetSortModifier( BACKGROUND_DEPTH_INDEX - 1 );
- mBacking.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
- mBacking.SetSensitive(true);
+ mTailVisible = visible;
+ mLayoutDirty = true;
+}
- mLayer.Add( mBacking );
- mBacking.SetOpacity(0.0f);
- mBacking.TouchedSignal().Connect( this, &Popup::OnBackingTouched );
- mBacking.WheelEventSignal().Connect(this, &Popup::OnBackingWheelEvent);
+const bool Popup::IsTailVisible() const
+{
+ return mTailVisible;
}
-void Popup::CreateDialog()
+void Popup::SetTailPosition( Vector3 position )
{
- // Adds default background image.
- SetDefaultBackgroundImage();
+ mTailPosition = position;
+ mLayoutDirty = true;
}
-void Popup::HandleStateChange( Toolkit::Popup::PopupState state, float duration )
+const Vector3& Popup::GetTailPosition() const
{
- Vector3 targetSize;
- float targetBackingAlpha;
+ return mTailPosition;
+}
- if(mState == state)
- {
- return;
- }
- mState = state;
- switch(state)
+void Popup::SetAnimationDuration( float duration )
+{
+ mAnimationDuration = duration;
+ mLayoutDirty = true;
+}
+
+float Popup::GetAnimationDuration() const
+{
+ return mAnimationDuration;
+}
+
+void Popup::SetAnimationMode( Toolkit::Popup::AnimationMode animationMode )
+{
+ mAnimationMode = animationMode;
+ mLayoutDirty = true;
+}
+
+Toolkit::Popup::AnimationMode Popup::GetAnimationMode() const
+{
+ return mAnimationMode;
+}
+
+void Popup::SetEntryAnimationData( const Property::Map& map )
+{
+ mEntryAnimationData.Clear();
+ Scripting::NewAnimation( map, mEntryAnimationData );
+}
+
+void Popup::SetExitAnimationData( const Property::Map& map )
+{
+ mExitAnimationData.Clear();
+ Scripting::NewAnimation( map, mExitAnimationData );
+}
+
+void Popup::SetAutoHideDelay( int delay )
+{
+ mAutoHideDelay = delay;
+}
+
+int Popup::GetAutoHideDelay() const
+{
+ return mAutoHideDelay;
+}
+
+void Popup::SetBackingEnabled( bool enabled )
+{
+ mBackingEnabled = enabled;
+ mLayoutDirty = true;
+}
+
+const bool Popup::IsBackingEnabled() const
+{
+ return mBackingEnabled;
+}
+
+void Popup::SetBackingColor( Vector4 color )
+{
+ mBackingColor = color;
+ mLayoutDirty = true;
+}
+
+const Vector4& Popup::GetBackingColor() const
+{
+ return mBackingColor;
+}
+
+void Popup::SetTailUpImage( std::string image )
+{
+ mTailUpImage = image;
+ mLayoutDirty = true;
+}
+
+const std::string& Popup::GetTailUpImage() const
+{
+ return mTailUpImage;
+}
+
+void Popup::SetTailDownImage( std::string image )
+{
+ mTailDownImage = image;
+ mLayoutDirty = true;
+}
+
+const std::string& Popup::GetTailDownImage() const
+{
+ return mTailDownImage;
+}
+
+void Popup::SetTailLeftImage( std::string image )
+{
+ mTailLeftImage = image;
+ mLayoutDirty = true;
+}
+
+const std::string& Popup::GetTailLeftImage() const
+{
+ return mTailLeftImage;
+}
+
+void Popup::SetTailRightImage( std::string image )
+{
+ mTailRightImage = image;
+ mLayoutDirty = true;
+}
+
+const std::string& Popup::GetTailRightImage() const
+{
+ return mTailRightImage;
+}
+
+void Popup::SetTouchTransparent( bool enabled )
+{
+ mTouchTransparent = enabled;
+}
+
+const bool Popup::IsTouchTransparent() const
+{
+ return mTouchTransparent;
+}
+
+void Popup::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
+{
+ Toolkit::Popup popup = Toolkit::Popup::DownCast( Dali::BaseHandle( object ) );
+
+ if ( popup )
{
- case Toolkit::Popup::POPUP_HIDE:
- {
- targetSize = Vector3(0.0f, 0.0f, 1.0f);
- targetBackingAlpha = 0.0f;
- mShowing = false;
- ClearKeyInputFocus();
+ Popup& popupImpl( GetImpl( popup ) );
- // Retore the keyboard focus when popup is hidden
- if(mPreviousFocusedActor && mPreviousFocusedActor.IsKeyboardFocusable() )
+ switch ( propertyIndex )
+ {
+ case Toolkit::Popup::Property::TITLE:
{
- Dali::Toolkit::KeyboardFocusManager keyboardFocusManager = Dali::Toolkit::KeyboardFocusManager::Get();
- if( keyboardFocusManager )
+ Property::Map valueMap;
+ if( value.Get( valueMap ) )
{
- keyboardFocusManager.SetCurrentFocusActor(mPreviousFocusedActor);
+ popupImpl.SetTitle( Scripting::NewActor( valueMap ) );
}
+ break;
}
-
- break;
- }
-
- case Toolkit::Popup::POPUP_SHOW:
- default:
- {
- targetSize = Vector3(1.0f, 1.0f, 1.0f);
- targetBackingAlpha = 1.0f;
- mShowing = true;
-
- // Add contents to stage for showing.
- if( !mLayer.GetParent() )
+ case Toolkit::Popup::Property::CONTENT:
+ {
+ Property::Map valueMap;
+ if( value.Get( valueMap ) )
+ {
+ popupImpl.SetContent( Scripting::NewActor( valueMap ) );
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::FOOTER:
+ {
+ Property::Map valueMap;
+ if( value.Get( valueMap ) )
+ {
+ popupImpl.SetFooter( Scripting::NewActor( valueMap ) );
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::DISPLAY_STATE:
+ {
+ std::string valueString;
+ if( value.Get( valueString ) )
+ {
+ Toolkit::Popup::DisplayState displayState( Toolkit::Popup::HIDDEN );
+ if( Scripting::GetEnumeration< Toolkit::Popup::DisplayState >( valueString.c_str(), DisplayStateTable, DisplayStateTableCount, displayState ) )
+ {
+ popupImpl.SetDisplayState( displayState );
+ }
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::TOUCH_TRANSPARENT:
+ {
+ bool valueBool;
+ if( value.Get( valueBool ) )
+ {
+ popupImpl.SetTouchTransparent( valueBool );
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::TAIL_VISIBILITY:
+ {
+ bool valueBool;
+ if( value.Get( valueBool ) )
+ {
+ popupImpl.SetTailVisibility( valueBool );
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::TAIL_POSITION:
+ {
+ Vector3 valueVector3;
+ if( value.Get( valueVector3 ) )
+ {
+ popupImpl.SetTailPosition( valueVector3 );
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::CONTEXTUAL_MODE:
+ {
+ std::string valueString;
+ if( value.Get( valueString ) )
+ {
+ Toolkit::Popup::ContextualMode contextualMode( Toolkit::Popup::BELOW );
+ if( Scripting::GetEnumeration< Toolkit::Popup::ContextualMode >( valueString.c_str(), ContextualModeTable, ContextualModeTableCount, contextualMode ) )
+ {
+ popupImpl.SetContextualMode( contextualMode );
+ }
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::ANIMATION_DURATION:
+ {
+ float valueFloat;
+ if( value.Get( valueFloat ) )
+ {
+ popupImpl.SetAnimationDuration( valueFloat );
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::ANIMATION_MODE:
+ {
+ std::string valueString;
+ if( value.Get( valueString ) )
+ {
+ Toolkit::Popup::AnimationMode animationMode( Toolkit::Popup::FADE );
+ if( Scripting::GetEnumeration< Toolkit::Popup::AnimationMode >( valueString.c_str(), AnimationModeTable, AnimationModeTableCount, animationMode ) )
+ {
+ popupImpl.SetAnimationMode( animationMode );
+ }
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::ENTRY_ANIMATION:
+ {
+ Property::Map valueMap;
+ if( value.Get( valueMap ) )
+ {
+ popupImpl.SetEntryAnimationData( valueMap );
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::EXIT_ANIMATION:
+ {
+ Property::Map valueMap;
+ if( value.Get( valueMap ) )
+ {
+ popupImpl.SetExitAnimationData( valueMap );
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::AUTO_HIDE_DELAY:
+ {
+ int valueInt;
+ if( value.Get( valueInt ) )
+ {
+ popupImpl.SetAutoHideDelay( valueInt );
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::BACKING_ENABLED:
+ {
+ bool valueBool;
+ if( value.Get( valueBool ) )
+ {
+ popupImpl.SetBackingEnabled( valueBool );
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::BACKING_COLOR:
+ {
+ Vector4 valueVector4;
+ if( value.Get( valueVector4 ) )
+ {
+ popupImpl.SetBackingColor( valueVector4 );
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::POPUP_BACKGROUND_IMAGE:
+ {
+ std::string valueString;
+ if( value.Get( valueString ) )
+ {
+ Image image = ResourceImage::New( valueString );
+ if( image )
+ {
+ ImageActor actor = ImageActor::New( image );
+ popupImpl.SetPopupBackgroundImage( actor );
+ }
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::TAIL_UP_IMAGE:
{
- Dali::Stage stage = Dali::Stage::GetCurrent();
- stage.Add( mLayer );
- mLayer.RaiseToTop();
+ std::string valueString;
+ if( value.Get( valueString ) )
+ {
+ popupImpl.SetTailUpImage( valueString );
+ }
+ break;
}
-
- Self().SetSensitive(true);
- SetKeyInputFocus();
-
- // Handle the keyboard focus when popup is shown
- Dali::Toolkit::KeyboardFocusManager keyboardFocusManager = Dali::Toolkit::KeyboardFocusManager::Get();
- if( keyboardFocusManager )
+ case Toolkit::Popup::Property::TAIL_DOWN_IMAGE:
{
- mPreviousFocusedActor = keyboardFocusManager.GetCurrentFocusActor();
-
- if( mContent && mContent.IsKeyboardFocusable() )
+ std::string valueString;
+ if( value.Get( valueString ) )
{
- // If content is focusable, move the focus to content
- keyboardFocusManager.SetCurrentFocusActor(mContent);
+ popupImpl.SetTailDownImage( valueString );
}
- else if( !mButtons.empty() )
+ break;
+ }
+ case Toolkit::Popup::Property::TAIL_LEFT_IMAGE:
+ {
+ std::string valueString;
+ if( value.Get( valueString ) )
{
- // Otherwise, movethe focus to the first button
- keyboardFocusManager.SetCurrentFocusActor(mButtons[0]);
+ popupImpl.SetTailLeftImage( valueString );
}
- else
+ break;
+ }
+ case Toolkit::Popup::Property::TAIL_RIGHT_IMAGE:
+ {
+ std::string valueString;
+ if( value.Get( valueString ) )
{
- DALI_LOG_WARNING("There is no focusable in popup\n");
+ popupImpl.SetTailRightImage( valueString );
}
+ break;
}
- break;
- }
- }
-
- Actor self = Self();
- if(duration > Math::MACHINE_EPSILON_1)
- {
- if ( mAnimation )
- {
- mAnimation.Stop();
- mAnimation.Clear();
- mAnimation.Reset();
- }
- mAnimation = Animation::New(duration);
-
- if(mShowing)
- {
- mAnimation.AnimateTo( Property(mBacking, Actor::Property::COLOR_ALPHA), targetBackingAlpha, AlphaFunction::EASE_IN_OUT, TimePeriod(0.0f, duration * 0.5f) );
- mAnimation.AnimateTo( Property(self, Actor::Property::SCALE), targetSize, AlphaFunction::EASE_IN_OUT, TimePeriod(duration * 0.5f, duration * 0.5f) );
- }
- else
- {
- mAnimation.AnimateTo( Property(mBacking, Actor::Property::COLOR_ALPHA), targetBackingAlpha, AlphaFunction::EASE_IN_OUT, TimePeriod(0.0f, duration * 0.5f) );
- mAnimation.AnimateTo( Property(self, Actor::Property::SCALE), targetSize, AlphaFunction::EASE_IN_OUT, TimePeriod(0.0f, duration * 0.5f) );
}
- mAnimation.Play();
- mAnimation.FinishedSignal().Connect(this, &Popup::OnStateAnimationFinished);
- }
- else
- {
- mBacking.SetOpacity( targetBackingAlpha );
- self.SetScale( targetSize );
-
- HandleStateChangeComplete();
}
}
-void Popup::HandleStateChangeComplete()
+Property::Value Popup::GetProperty( BaseObject* object, Property::Index propertyIndex )
{
- // Remove contents from stage if completely hidden.
- if( ( mState == Toolkit::Popup::POPUP_HIDE ) && mLayer.GetParent() )
+ Property::Value value;
+
+ Toolkit::Popup popup = Toolkit::Popup::DownCast( Dali::BaseHandle( object ) );
+
+ if ( popup )
{
- mLayer.Unparent();
- Self().SetSensitive( false );
+ Popup& popupImpl( GetImpl( popup ) );
- // Guard against destruction during signal emission
- Toolkit::Popup handle( GetOwner() );
- mHiddenSignal.Emit();
+ switch ( propertyIndex )
+ {
+ case Toolkit::Popup::Property::TITLE:
+ {
+ Property::Map map;
+ Scripting::CreatePropertyMap( popupImpl.GetTitle(), map );
+ value = map;
+ break;
+ }
+ case Toolkit::Popup::Property::CONTENT:
+ {
+ Property::Map map;
+ Scripting::CreatePropertyMap( popupImpl.GetContent(), map );
+ value = map;
+ break;
+ }
+ case Toolkit::Popup::Property::FOOTER:
+ {
+ Property::Map map;
+ Scripting::CreatePropertyMap( popupImpl.GetFooter(), map );
+ value = map;
+ break;
+ }
+ case Toolkit::Popup::Property::DISPLAY_STATE:
+ {
+ value = Scripting::GetLinearEnumerationName< Toolkit::Popup::DisplayState >( popupImpl.GetDisplayState(), DisplayStateTable, DisplayStateTableCount );
+ break;
+ }
+ case Toolkit::Popup::Property::TOUCH_TRANSPARENT:
+ {
+ value = popupImpl.IsTouchTransparent();
+ break;
+ }
+ case Toolkit::Popup::Property::TAIL_VISIBILITY:
+ {
+ value = popupImpl.IsTailVisible();
+ break;
+ }
+ case Toolkit::Popup::Property::TAIL_POSITION:
+ {
+ value = popupImpl.GetTailPosition();
+ break;
+ }
+ case Toolkit::Popup::Property::CONTEXTUAL_MODE:
+ {
+ value = Scripting::GetLinearEnumerationName< Toolkit::Popup::ContextualMode >( popupImpl.GetContextualMode(), ContextualModeTable, ContextualModeTableCount );
+ break;
+ }
+ case Toolkit::Popup::Property::ANIMATION_DURATION:
+ {
+ value = popupImpl.GetAnimationDuration();
+ break;
+ }
+ case Toolkit::Popup::Property::ANIMATION_MODE:
+ {
+ value = Scripting::GetLinearEnumerationName< Toolkit::Popup::AnimationMode >( popupImpl.GetAnimationMode(), AnimationModeTable, AnimationModeTableCount );
+ break;
+ }
+ case Toolkit::Popup::Property::ENTRY_ANIMATION:
+ {
+ // Note: Cannot retrieve property map from animation.
+ Property::Map map;
+ value = map;
+ break;
+ }
+ case Toolkit::Popup::Property::EXIT_ANIMATION:
+ {
+ // Note: Cannot retrieve property map from animation.
+ Property::Map map;
+ value = map;
+ break;
+ }
+ case Toolkit::Popup::Property::AUTO_HIDE_DELAY:
+ {
+ value = popupImpl.GetAutoHideDelay();
+ break;
+ }
+ case Toolkit::Popup::Property::BACKING_ENABLED:
+ {
+ value = popupImpl.IsBackingEnabled();
+ break;
+ }
+ case Toolkit::Popup::Property::BACKING_COLOR:
+ {
+ value = popupImpl.GetBackingColor();
+ break;
+ }
+ case Toolkit::Popup::Property::POPUP_BACKGROUND_IMAGE:
+ {
+ ResourceImage image = ResourceImage::DownCast( popupImpl.GetPopupBackgroundImage() );
+ if( image )
+ {
+ value = image.GetUrl();
+ }
+ break;
+ }
+ case Toolkit::Popup::Property::TAIL_UP_IMAGE:
+ {
+ value = popupImpl.GetTailUpImage();
+ break;
+ }
+ case Toolkit::Popup::Property::TAIL_DOWN_IMAGE:
+ {
+ value = popupImpl.GetTailDownImage();
+ break;
+ }
+ case Toolkit::Popup::Property::TAIL_LEFT_IMAGE:
+ {
+ value = popupImpl.GetTailLeftImage();
+ break;
+ }
+ case Toolkit::Popup::Property::TAIL_RIGHT_IMAGE:
+ {
+ value = popupImpl.GetTailRightImage();
+ break;
+ }
+ }
}
-}
-
-Toolkit::Popup::TouchedOutsideSignalType& Popup::OutsideTouchedSignal()
-{
- return mTouchedOutsideSignal;
-}
-Toolkit::Popup::HiddenSignalType& Popup::HiddenSignal()
-{
- return mHiddenSignal;
+ return value;
}
bool Popup::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
{
popup.OutsideTouchedSignal().Connect( tracker, functor );
}
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_SHOWING ) )
+ {
+ popup.ShowingSignal().Connect( tracker, functor );
+ }
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_SHOWN ) )
+ {
+ popup.ShownSignal().Connect( tracker, functor );
+ }
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_HIDING ) )
+ {
+ popup.HidingSignal().Connect( tracker, functor );
+ }
else if( 0 == strcmp( signalName.c_str(), SIGNAL_HIDDEN ) )
{
popup.HiddenSignal().Connect( tracker, functor );
return connected;
}
-void Popup::OnStateAnimationFinished( Animation& source )
+bool Popup::OnBackingTouched( Actor actor, const TouchEvent& event )
{
- HandleStateChangeComplete();
-}
+ // Allow events to pass through if touch transparency is enabled.
+ if( mTouchTransparent )
+ {
+ return false;
+ }
-bool Popup::OnBackingTouched(Actor actor, const TouchEvent& event)
-{
- if(event.GetPointCount()>0)
+ if( event.GetPointCount() > 0 )
{
- const TouchPoint& point = event.GetPoint(0);
+ const TouchPoint& point = event.GetPoint( 0 );
- if(point.state == TouchPoint::Down)
+ if( point.state == TouchPoint::Down )
{
- // Guard against destruction during signal emission
+ // Guard against destruction during signal emission.
Toolkit::Popup handle( GetOwner() );
mTouchedOutsideSignal.Emit();
}
}
+ // Block anything behind backing becoming touched.
+ mLayer.SetTouchConsumed( true );
return true;
}
-bool Popup::OnBackingWheelEvent(Actor actor, const WheelEvent& event)
+bool Popup::OnBackingWheelEvent( Actor actor, const WheelEvent& event )
{
- // consume wheel event in dimmed backing actor
+ // Allow events to pass through if touch transparency is enabled.
+ if( mTouchTransparent )
+ {
+ return false;
+ }
+
+ // Consume wheel event in dimmed backing actor.
+ mLayer.SetTouchConsumed( true );
return true;
}
bool Popup::OnDialogTouched(Actor actor, const TouchEvent& event)
{
- // consume event (stops backing actor receiving touch events)
+ // Allow events to pass through if touch transparency is enabled.
+ if( mTouchTransparent )
+ {
+ return false;
+ }
+
+ // Consume event (stops backing actor receiving touch events)
+ mLayer.SetTouchConsumed( true );
return true;
}
+void Popup::OnControlStageConnection()
+{
+ mLayoutDirty = true;
+ RelayoutRequest();
+}
+
void Popup::OnControlChildAdd( Actor& child )
{
- // reparent any children added by user to the body layer.
+ // Re-parent any children added by user to the body layer.
if( mAlterAddedChild )
{
- // Removes previously added content.
- if( mContent )
- {
- mPopupLayout.RemoveChildAt( Toolkit::TableView::CellPosition( 1, 0 ) );
- }
-
- // keep a handle to the new content.
- mContent = child;
-
- mPopupLayout.AddChild( mContent, Toolkit::TableView::CellPosition( 1, 0 ) );
+ SetContent( child );
+ }
+ else
+ {
+ mLayoutDirty = true;
+ RelayoutRequest();
}
}
-void Popup::OnRelayout( const Vector2& size, RelayoutContainer& container )
+void Popup::LayoutContext( const Vector2& size )
{
- // Hide the background image
- mBackgroundImage.SetVisible( !( mButtons.empty() && mPopupLayout.GetChildCount() == 0 ) );
-
- // Relayout All buttons
- if( !mButtons.empty() )
+ // Do nothing if not in a contextual mode (or there is no parent context).
+ Actor self = Self();
+ Actor parent = self.GetParent();
+ if( ( mContextualMode == Toolkit::Popup::NON_CONTEXTUAL ) || !parent )
{
- // All buttons should be the same size and fill the button area. The button spacing needs to be accounted for as well.
- Vector2 buttonSize( ( ( size.width - mPopupStyle->buttonSpacing * ( mButtons.size() + 1 ) ) / mButtons.size() ),
- mPopupStyle->bottomSize.height - mPopupStyle->margin );
-
- Vector3 buttonPosition( mPopupStyle->buttonSpacing, 0.0f, 0.0f );
-
- for( std::vector< Actor >::iterator iter = mButtons.begin(), endIter = mButtons.end();
- iter != endIter;
- ++iter, buttonPosition.x += mPopupStyle->buttonSpacing + buttonSize.width )
- {
- Actor button = *iter;
-
- // If there is only one button, it needs to be laid out on center.
- if ( mButtons.size() == 1 )
- {
- buttonPosition.x = 0.0f;
- button.SetAnchorPoint( AnchorPoint::CENTER );
- button.SetParentOrigin( ParentOrigin::CENTER );
- }
- else
- {
- button.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
- button.SetParentOrigin( ParentOrigin::CENTER_LEFT );
- }
+ return;
+ }
- button.SetPosition( buttonPosition );
+ mPopupContainer.SetParentOrigin( ParentOrigin::CENTER );
+ // We always anchor to the CENTER, rather than a different anchor point for each contextual
+ // mode to allow code-reuse of the bound checking code (for maintainability).
+ mPopupContainer.SetAnchorPoint( AnchorPoint::CENTER );
- //Todo: Use the size negotiation pass instead of SetSize directly
- button.SetSize( buttonSize );
- }
- }
-}
+ // Setup with some pre-calculations for speed.
+ Vector3 halfStageSize( Stage().GetCurrent().GetSize() / 2.0f );
+ Vector3 parentPosition( parent.GetCurrentPosition() );
+ Vector2 halfSize( size / 2.0f );
+ Vector2 halfParentSize( parent.GetRelayoutSize( Dimension::WIDTH ) / 2.0f, parent.GetRelayoutSize( Dimension::HEIGHT ) / 2.0f );
+ Vector3 newPosition( Vector3::ZERO );
-void Popup::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
-{
- if( mPopupLayout )
+ // Perform different positioning based on the specified contextual layout mode.
+ switch( mContextualMode )
{
- if( policy == ResizePolicy::FIT_TO_CHILDREN )
+ case Toolkit::Popup::BELOW:
{
- mPopupLayout.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, dimension );
- if( dimension & Dimension::HEIGHT )
- {
- mPopupLayout.SetFitHeight( 1 );
- }
+ newPosition.x += halfSize.x - halfParentSize.x;
+ newPosition.y += halfSize.y + halfParentSize.y + DEFAULT_CONTEXTUAL_ADJACENCY_MARGIN.y;
+ break;
}
- else
+ case Toolkit::Popup::ABOVE:
{
- mPopupLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, dimension );
- // Make the content cell fill the whole of the available space
- if( dimension & Dimension::HEIGHT )
- {
- mPopupLayout.SetRelativeHeight( 1, 1.0f );
- }
+ newPosition.x += halfSize.x - halfParentSize.x;
+ newPosition.y -= halfSize.y + halfParentSize.y + DEFAULT_CONTEXTUAL_ADJACENCY_MARGIN.y;
+ break;
+ }
+ case Toolkit::Popup::RIGHT:
+ {
+ newPosition.x += halfSize.x + halfParentSize.x + DEFAULT_CONTEXTUAL_ADJACENCY_MARGIN.x;
+ newPosition.y += halfSize.y - halfParentSize.y;
+ break;
+ }
+ case Toolkit::Popup::LEFT:
+ {
+ newPosition.x -= halfSize.x + halfParentSize.x + DEFAULT_CONTEXTUAL_ADJACENCY_MARGIN.x;
+ newPosition.y += halfSize.y - halfParentSize.y;
+ break;
+ }
+ case Toolkit::Popup::NON_CONTEXTUAL:
+ {
+ // Code won't reach here (caught earlier).
+ break;
}
}
-}
-
-bool Popup::OnKeyEvent(const KeyEvent& event)
-{
- bool consumed = false;
- if(event.state == KeyEvent::Down)
+ // On-screen position checking.
+ // Check new position is not too far right. If so, correct it.
+ // Note: Check for right rather than left first, so if popup is too wide, the left check overrides
+ // the right check and we at least see the left portion of the popup (as this is more useful).
+ if( newPosition.x >= ( halfStageSize.x - parentPosition.x - halfSize.x - DEFAULT_CONTEXTUAL_STAGE_BORDER.x ) )
{
- if (event.keyCode == Dali::DALI_KEY_ESCAPE || event.keyCode == Dali::DALI_KEY_BACK)
- {
- SetState(Toolkit::Popup::POPUP_HIDE);
- consumed = true;
- }
+ newPosition.x = halfStageSize.x - parentPosition.x - halfSize.x - DEFAULT_CONTEXTUAL_STAGE_BORDER.x;
+ }
+ // Check new position is not too far left. If so, correct it.
+ if( newPosition.x < halfSize.x - ( parentPosition.x + halfStageSize.x ) + DEFAULT_CONTEXTUAL_STAGE_BORDER.x )
+ {
+ newPosition.x = halfSize.x - ( parentPosition.x + halfStageSize.x ) + DEFAULT_CONTEXTUAL_STAGE_BORDER.x;// - parentSize.x;
+ }
+ // Check new position is not too far down. If so, correct it.
+ if( newPosition.y >= ( halfStageSize.y - parentPosition.y - halfSize.y - DEFAULT_CONTEXTUAL_STAGE_BORDER.y ) )
+ {
+ newPosition.y = halfStageSize.y - parentPosition.y - halfSize.y - DEFAULT_CONTEXTUAL_STAGE_BORDER.y;
+ }
+ // Check new position is not too far up. If so, correct it.
+ if( newPosition.y < halfSize.y - ( parentPosition.y + halfStageSize.y ) + DEFAULT_CONTEXTUAL_STAGE_BORDER.y )
+ {
+ newPosition.y = halfSize.y - ( parentPosition.y + halfStageSize.y ) + DEFAULT_CONTEXTUAL_STAGE_BORDER.y;
}
- return consumed;
+ // Set the final position.
+ mPopupContainer.SetPosition( newPosition );
}
-Vector3 Popup::GetNaturalSize()
+void Popup::OnRelayout( const Vector2& size, RelayoutContainer& container )
{
- float margin = 2.0f * ( POPUP_OUT_MARGIN_WIDTH + mPopupStyle->margin );
- const float maxWidth = Stage::GetCurrent().GetSize().width - margin;
+ Vector2 useSize( size );
+
+ // Use the Popup layouts size, unless requested to use a fixed size.
+ // In which case take the size set for the Popup itself.
+ ResizePolicy::Type widthPolicy = Self().GetResizePolicy( Dimension::WIDTH );
+ ResizePolicy::Type heightPolicy = Self().GetResizePolicy( Dimension::HEIGHT );
- Vector3 naturalSize( 0.0f, 0.0f, 0.0f );
+ // Width calculations:
+ if( widthPolicy == ResizePolicy::USE_NATURAL_SIZE || widthPolicy == ResizePolicy::FIT_TO_CHILDREN )
+ {
+ // If we using a child-based policy, take the size from the popup layout.
+ mPopupLayout.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::WIDTH );
+ useSize.width = mPopupLayout.GetRelayoutSize( Dimension::WIDTH );
- if ( mTitle )
+ mPopupLayout.SetFitWidth( 0u );
+ }
+ else
{
- Vector3 titleNaturalSize = mTitle.GetImplementation().GetNaturalSize();
- // Buffer to avoid errors. The width of the popup could potentially be the width of the title text.
- // It was observed in this case that text wrapping was then inconsistent when seen on device
- const float titleBuffer = 0.5f;
- titleNaturalSize.width += titleBuffer;
+ // If we using a parent-based policy, take the size from the popup object itself (self).
+ mPopupLayout.SetResizePolicy( ResizePolicy::USE_ASSIGNED_SIZE, Dimension::WIDTH );
+
+ mPopupLayout.SetFixedWidth( 0u, useSize.width );
+ }
+
+ // Height calculations:
+ // Title: Let the title be as high as it needs to be.
+ mPopupLayout.SetFitHeight( 0u );
- // As TextLabel GetNaturalSize does not take wrapping into account, limit the width
- // to that of the stage
- if( titleNaturalSize.width >= maxWidth)
+ // Footer: Convert the footer's resize policy to a TableView row policy.
+ if( mFooter )
+ {
+ ResizePolicy::Type footerHeightPolicy = mFooter.GetResizePolicy( Dimension::HEIGHT );
+ if( ( footerHeightPolicy == ResizePolicy::USE_NATURAL_SIZE ) ||
+ ( footerHeightPolicy == ResizePolicy::FIT_TO_CHILDREN ) )
+ {
+ mPopupLayout.SetFitHeight( 2u );
+ }
+ else if( footerHeightPolicy == ResizePolicy::FIXED )
{
- naturalSize.width = maxWidth;
- naturalSize.height = mTitle.GetImplementation().GetHeightForWidth( naturalSize.width );
+ mPopupLayout.SetFixedHeight( 2u, mFooter.GetRelayoutSize( Dimension::HEIGHT) );
}
else
{
- naturalSize += titleNaturalSize;
+ mPopupLayout.SetRelativeHeight( 2u, 1.0f );
}
+ }
+ else
+ {
+ mPopupLayout.SetFixedHeight( 2u, 0.0f );
+ }
+
+ // Popup contents: Adjust the tableview's policies based on the popup's policies.
+ if( heightPolicy == ResizePolicy::USE_NATURAL_SIZE || heightPolicy == ResizePolicy::FIT_TO_CHILDREN )
+ {
+ mPopupLayout.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
+
+ // Let both the contents expand as necessary.
+ mPopupLayout.SetFitHeight( 1u );
+ useSize.height = mPopupLayout.GetRelayoutSize( Dimension::HEIGHT );
+ }
+ else
+ {
+ mPopupLayout.SetResizePolicy( heightPolicy, Dimension::HEIGHT );
- naturalSize.height += mPopupStyle->margin;
+ // Let the content expand to fill the remaining space.
+ mPopupLayout.SetRelativeHeight( 1u, 1.0f );
+ mPopupLayout.SetResizePolicy( ResizePolicy::USE_ASSIGNED_SIZE, Dimension::HEIGHT );
}
+ // Relayout the popup-layout to give it it's new size this frame.
+ container.Add( mPopupLayout, useSize );
+
if( mContent )
{
- Vector3 contentSize = mContent.GetNaturalSize();
- // Choose the biggest width
- naturalSize.width = std::max( naturalSize.width, contentSize.width );
- if( naturalSize.width > maxWidth )
- {
- naturalSize.width = maxWidth;
- contentSize.height = mContent.GetHeightForWidth( maxWidth );
- }
- naturalSize.height += contentSize.height + mPopupStyle->margin;
+ container.Add( mContent, Vector2( mContent.GetRelayoutSize( Dimension::WIDTH ), mContent.GetRelayoutSize( Dimension::HEIGHT ) ) );
}
- if( !mButtons.empty() )
+ // Perform contextual layout setup if required.
+ // This is done each time in case the parent moves.
+ // This will have no effect if no contextual mode is selected.
+ LayoutContext( useSize );
+}
+
+void Popup::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
+{
+ // To get the popup to emulate fit-to-children, we need to actually set use-natural-size.
+ if( ( dimension & Dimension::HEIGHT ) && ( policy == ResizePolicy::FIT_TO_CHILDREN ) )
{
- naturalSize.height += mPopupStyle->bottomSize.height;
+ Self().SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
}
- // Add the margins
- naturalSize.width += margin;
- naturalSize.height += margin;
+ mLayoutDirty = true;
+ return;
+}
- return naturalSize;
+Vector3 Popup::GetNaturalSize()
+{
+ return mPopupLayout.GetNaturalSize();
}
float Popup::GetHeightForWidth( float width )
{
- float height( 0.0f );
- float popupWidth( width - 2.f * ( POPUP_OUT_MARGIN_WIDTH + mPopupStyle->margin ) );
+ return mPopupLayout.GetHeightForWidth( width );
+}
- if ( mTitle )
- {
- height += mTitle.GetImplementation().GetHeightForWidth( popupWidth );
- height += mPopupStyle->margin;
- }
+float Popup::GetWidthForHeight( float height )
+{
+ return mPopupLayout.GetWidthForHeight( height );
+}
- if( mContent )
+bool Popup::OnKeyEvent( const KeyEvent& event )
+{
+ // Allow events to pass through if touch transparency is enabled.
+ if( mTouchTransparent )
{
- height += mContent.GetHeightForWidth( popupWidth ) + mPopupStyle->margin;
+ return false;
}
- if( !mButtons.empty() )
+ bool consumed = false;
+
+ if( event.state == KeyEvent::Down )
{
- height += mPopupStyle->bottomSize.height;
+ if (event.keyCode == Dali::DALI_KEY_ESCAPE || event.keyCode == Dali::DALI_KEY_BACK)
+ {
+ SetDisplayState( Toolkit::Popup::HIDDEN );
+ consumed = true;
+ }
}
- // Add the margins
- float margin( 2.0f * ( POPUP_OUT_MARGIN_WIDTH + mPopupStyle->margin ) );
- height += margin;
-
- return height;
-}
-
-float Popup::GetWidthForHeight( float height )
-{
- return GetNaturalSize().width;
+ return consumed;
}
-Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
+Actor Popup::GetNextKeyboardFocusableActor( Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled )
{
Actor nextFocusableActor( currentFocusedActor );
// TODO: Needs to be optimised
-
- if ( !currentFocusedActor || ( currentFocusedActor && KeyboardFocusManager::Get().GetFocusGroup(currentFocusedActor) != Self() ) )
+ if( !currentFocusedActor || ( currentFocusedActor && KeyboardFocusManager::Get().GetFocusGroup( currentFocusedActor ) != Self() ) )
{
// The current focused actor is not within popup
if( mContent && mContent.IsKeyboardFocusable() )
// If content is focusable, move the focus to content
nextFocusableActor = mContent;
}
- else if( !mButtons.empty() )
- {
- // Otherwise, movethe focus to the first button
- nextFocusableActor = mButtons[0];
- }
}
else
{
- // Rebuild the focus chain because button or content can be added or removed dynamically
+ // Rebuild the focus chain because controls or content can be added or removed dynamically
std::vector< Actor > focusableActors;
if( mContent && mContent.IsKeyboardFocusable() )
{
- focusableActors.push_back(mContent);
- }
-
- for(unsigned int i = 0; i < mButtons.size(); i++)
- {
- if( mButtons[i] && mButtons[i].IsKeyboardFocusable() )
- {
- focusableActors.push_back(mButtons[i]);
- }
+ focusableActors.push_back( mContent );
}
for( std::vector< Actor >::iterator iter = focusableActors.begin(), end = focusableActors.end(); iter != end; ++iter )
{
- if ( currentFocusedActor == *iter )
+ if( currentFocusedActor == *iter )
{
- switch ( direction )
+ switch( direction )
{
case Toolkit::Control::KeyboardFocus::LEFT:
{
- if ( iter == focusableActors.begin() )
+ if( iter == focusableActors.begin() )
{
nextFocusableActor = *( focusableActors.end() - 1 );
}
}
case Toolkit::Control::KeyboardFocus::RIGHT:
{
- if ( iter == focusableActors.end() - 1 )
+ if( iter == focusableActors.end() - 1 )
{
nextFocusableActor = *( focusableActors.begin() );
}
case Toolkit::Control::KeyboardFocus::UP:
{
- if ( *iter == mContent )
+ if( mContent && *iter == mContent )
{
nextFocusableActor = *( focusableActors.end() - 1 );
}
else
{
- if ( mContent && mContent.IsKeyboardFocusable() )
+ if( mContent && mContent.IsKeyboardFocusable() )
{
nextFocusableActor = mContent;
}
case Toolkit::Control::KeyboardFocus::DOWN:
{
- if ( mContent && mContent.IsKeyboardFocusable() )
+ if( mContent && mContent.IsKeyboardFocusable() )
{
nextFocusableActor = mContent;
}
else
{
- if ( iter == focusableActors.end() - 1 )
+ if( iter == focusableActors.end() - 1 )
{
nextFocusableActor = *( focusableActors.begin() );
}
nextFocusableActor = *( iter + 1 );
}
}
-
- if ( *iter == mContent && !mButtons.empty() )
- {
- nextFocusableActor = mButtons[0];
- }
break;
}
}
- if(!nextFocusableActor)
+ if( !nextFocusableActor )
{
- DALI_LOG_WARNING("Can not decide next focusable actor\n");
+ DALI_LOG_WARNING( "Can not decide next focusable actor\n" );
}
break;
#define __DALI_TOOLKIT_INTERNAL_POPUP_H__
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// EXTERNAL INCLUDES
#include <dali/public-api/actors/image-actor.h>
#include <dali/public-api/actors/layer.h>
+#include <dali/public-api/adaptor-framework/timer.h>
#include <dali/public-api/animation/animation.h>
+#include <dali/devel-api/animation/animation-data.h>
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/controls/table-view/table-view.h>
-#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
#include <dali-toolkit/devel-api/controls/popup/popup.h>
-#include <dali-toolkit/internal/controls/popup/popup-style-impl.h>
namespace Dali
{
namespace Toolkit
{
-class Button;
-
namespace Internal
{
class Popup;
-class PopupStyle;
-typedef IntrusivePtr<Popup> PopupPtr;
-typedef IntrusivePtr<PopupStyle> PopupStylePtr;
+typedef IntrusivePtr< Popup > PopupPtr;
/**
* @copydoc Toolkit::Popup
public:
/**
- * Returns number of buttons added to Popup
- *
- * @return Number of buttons
+ * @copydoc Toolkit::Popup::SetPopupBackgroundImage
*/
- size_t GetButtonCount() const;
+ void SetPopupBackgroundImage( Actor image );
/**
- * @copydoc Toolkit::Popup::SetBackgroundImage
+ * @copydoc Toolkit::Popup::GetPopupBackgroundImage
*/
- void SetBackgroundImage( Actor image );
+ Actor GetPopupBackgroundImage() const;
/**
- * @copydoc Toolkit::Popup::SetButtonAreaImage
+ * @copydoc Toolkit::Popup::SetTitle( Actor titleActor )
*/
- void SetButtonAreaImage( Actor image );
+ void SetTitle( Actor titleActor );
/**
- * @copydoc Toolkit::Popup::SetTitle( const std::string& text );
+ * @copydoc Toolkit::Popup::GetTitle
*/
- void SetTitle( const std::string& text );
+ Actor GetTitle() const;
/**
- * @copydoc Toolkit::Popup::GetTitle
+ * @copydoc Toolkit::Popup::SetContent
+ */
+ void SetContent( Actor content );
+
+ /**
+ * @copydoc Toolkit::Popup::GetContent
+ */
+ Actor GetContent() const;
+
+ /**
+ * @copydoc Toolkit::Popup::SetFooter
+ */
+ void SetFooter( Actor control );
+
+ /**
+ * @copydoc Toolkit::Popup::GetFooter
+ */
+ Actor GetFooter() const;
+
+ /**
+ * @copydoc Toolkit::Popup::SetDisplayState
+ */
+ void SetDisplayState( Toolkit::Popup::DisplayState displayState );
+
+ /**
+ * @copydoc Toolkit::Popup::GetDisplayState
+ */
+ Toolkit::Popup::DisplayState GetDisplayState() const;
+
+ /**
+ * @copydoc Toolkit::Popup::SetTailVisibility
+ */
+ void SetTailVisibility( bool visible );
+
+ /**
+ * @copydoc Toolkit::Popup::IsTailVisible
+ */
+ const bool IsTailVisible() const;
+
+ /**
+ * @copydoc Toolkit::Popup::SetTailPosition
+ */
+ void SetTailPosition( Vector3 position );
+
+ /**
+ * @copydoc Toolkit::Popup::GetTailPosition
+ */
+ const Vector3& GetTailPosition() const;
+
+ /**
+ * @copydoc Toolkit::Popup::SetContextualMode
+ */
+ void SetContextualMode( Toolkit::Popup::ContextualMode mode );
+
+ /**
+ * @copydoc Toolkit::Popup::GetContextualMode
+ */
+ Toolkit::Popup::ContextualMode GetContextualMode() const;
+
+ /**
+ * @copydoc Toolkit::Popup::SetAnimationDuration
+ */
+ void SetAnimationDuration( float duration );
+
+ /**
+ * @copydoc Toolkit::Popup::GetAnimationDuration
+ */
+ float GetAnimationDuration() const;
+
+ /**
+ * @copydoc Toolkit::Popup::SetAnimationMode
+ */
+ void SetAnimationMode( Toolkit::Popup::AnimationMode animationMode );
+
+ /**
+ * @copydoc Toolkit::Popup::GetAnimationMode
+ */
+ Toolkit::Popup::AnimationMode GetAnimationMode() const;
+
+ /**
+ * @copydoc Toolkit::Popup::SetAutoHideDelay
+ */
+ void SetAutoHideDelay( int delay );
+
+ /**
+ * @copydoc Toolkit::Popup::GetAutoHideDelay
+ */
+ int GetAutoHideDelay() const;
+
+ /**
+ * @copydoc Toolkit::Popup::SetBackingEnabled
+ */
+ void SetBackingEnabled( bool enabled );
+
+ /**
+ * @copydoc Toolkit::Popup::IsBackingEnabled
+ */
+ const bool IsBackingEnabled() const;
+
+ /**
+ * @copydoc Toolkit::Popup::SetBackingColor
+ */
+ void SetBackingColor( Vector4 color );
+
+ /**
+ * @copydoc Toolkit::Popup::GetBackingColor
*/
- std::string GetTitle() const;
+ const Vector4& GetBackingColor() const;
/**
- * @copydoc Toolkit::Popup::AddButton
+ * @copydoc Toolkit::Popup::SetTailUpImage
*/
- void AddButton( Toolkit::Button button );
+ void SetTailUpImage( std::string image );
/**
- * @copydoc Toolkit::Popup::SetState( PopupState state )
+ * @copydoc Toolkit::Popup::GetTailUpImage
*/
- void SetState( Toolkit::Popup::PopupState state );
+ const std::string& GetTailUpImage() const;
/**
- * @copydoc Toolkit::Popup::SetState( PopupState state, float duration )
+ * @copydoc Toolkit::Popup::SetTailDownImage
*/
- void SetState( Toolkit::Popup::PopupState state, float duration );
+ void SetTailDownImage( std::string image );
/**
- * @copydoc Toolkit::Popup::GetState( )
+ * @copydoc Toolkit::Popup::GetTailDownImage
*/
- Toolkit::Popup::PopupState GetState() const;
+ const std::string& GetTailDownImage() const;
/**
- * @copydoc Toolkit::Popup::ShowTail
+ * @copydoc Toolkit::Popup::SetTailLeftImage
*/
- void ShowTail(const Vector3& position);
+ void SetTailLeftImage( std::string image );
/**
- * @copydoc Toolkit::Popup::HideTail
+ * @copydoc Toolkit::Popup::GetTailLeftImage
*/
- void HideTail();
+ const std::string& GetTailLeftImage() const;
/**
- * Sets the style of the popup
- * @param[in] style The style of the popup
+ * @copydoc Toolkit::Popup::SetTailRightImage
*/
- void SetStyle(PopupStyle& style);
+ void SetTailRightImage( std::string image );
/**
- * Gets the style of the popup
- * @return style of the popup
+ * @copydoc Toolkit::Popup::GetTailRightImage
*/
- PopupStylePtr GetStyle() const;
+ const std::string& GetTailRightImage() const;
+
+ /**
+ * Called when a property of an object of this type is set.
+ * @param[in] object The object whose property is set.
+ * @param[in] propertyIndex The property index.
+ * @param[in] value The new property value.
+ */
+ static void SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value );
+
+ /**
+ * Called to retrieve a property of an object of this type.
+ * @param[in] object The object whose property is to be retrieved.
+ * @param[in] propertyIndex The property index.
+ * @return The current value of the property.
+ */
+ static Property::Value GetProperty( BaseObject* object, Property::Index propertyIndex );
protected:
/**
* Construct a new Popup.
- * @param[in] style of the popup
*/
- Popup(PopupStyle& style);
+ Popup();
/**
* A reference counted object may only be deleted by calling Unreference()
private:
/**
- * Creates and applies the default background image.
+ * @brief Creates the layout of the popup, to be done just before showing for the first time.
+ * Also calls OnLayoutSetup() to allow derived classes to perform layout at this stage.
+ */
+ void LayoutPopup();
+
+ /**
+ * @brief Creates or destroys the popup tail based on the current TAIL_DISPLAYED property.
+ * Also uses the TAIL_POSITION property to position it.
*/
- void SetDefaultBackgroundImage();
+ void LayoutTail();
/**
- * Create Dim Backing
- * (covers all content behind the dialog)
+ * @brief Performs any relative positioning required based on the current contextual mode, if set.
+ * If contextual mode is not enabled, this method has no effect.
+ * @param[in] size The Popups current size (can be accessed from within the OnRelayout() method).
+ */
+ void LayoutContext( const Vector2& size );
+
+ /**
+ * @brief All transition-in animation setup and layout is done here.
+ * Different types of animation mode require different layouts to work,
+ * this function encapsulates anything animation-mode specific.
+ * This is called once for multiple displays/hides of the pops.
+ * It is only re-called when the layout becomes dirty.
+ */
+ void LayoutAnimation();
+
+ /**
+ * @brief Initiates a transition-in or transition-out animation based
+ * on the current animation settings.
+ * @param[in] transitionIn True to perform a transition-in, false for transition out.
+ * @param[in] instantaneous Optional - If set to true will override the duration to provide an instant animation.
+ */
+ void StartTransitionAnimation( bool transitionIn, bool instantaneous = false );
+
+ /**
+ * @brief Invoked once a display state change has completed.
+ */
+ void DisplayStateChangeComplete();
+
+ /**
+ * @brief This is called when the auto-hide timer finishes.
+ * It performs a display-state change to HIDDEN.
+ * @return True as signal is consumed.
+ */
+ bool OnAutoHideTimeReached();
+
+ /**
+ * @brief Create Dimmed Backing (covers all content behind the dialog).
+ *
+ * @return The backing actor.
+ */
+ ImageActor CreateBacking();
+
+ /**
+ * @brief Creates the lower area within the popup.
+ */
+ void CreateFooter();
+
+ /**
+ * @brief Sets if the popup allows touch events to pass through or not.
+ *
+ * @param[in] enabled Set to true to make the popup touch-transparent.
*/
- void CreateBacking();
+ void SetTouchTransparent( bool enabled );
/**
- * Create Dialog
- * (dialog content resides inside this - buttons, title etc.)
+ * @brief Returns if the popup allows touch events to pass through or not.
+ *
+ * @return True if the popup is touch-transparent.
*/
- void CreateDialog();
+ const bool IsTouchTransparent() const;
/**
- * Animate Popup by scaling uniformally from 0 to 100% and vice versa (default behaviour)
- * @param[in] state The desired state to change into.
- * @param[in] duration The time for this animation to take.
+ * @brief Allows the popup entry animation to be setup from a Property::Map that could
+ * originate, for example, from a JSON file.
+ *
+ * @param[in] map A Property::Map containing a description of an animation
*/
- void HandleStateChange( Toolkit::Popup::PopupState state, float duration );
+ void SetEntryAnimationData( const Property::Map& map );
/**
- * Invoked once StateChange has completed.
+ * @brief Allows the popup exit animation to be setup from a Property::Map that could
+ * originate, for example, from a JSON file.
+ *
+ * @param[in] map A Property::Map containing a description of an animation
*/
- void HandleStateChangeComplete();
+ void SetExitAnimationData( const Property::Map& map );
public: // Signals
Toolkit::Popup::TouchedOutsideSignalType& OutsideTouchedSignal();
/**
+ * @copydoc Dali::Toolkit::Popup::ShowingSignal()
+ */
+ Toolkit::Popup::DisplayStateChangeSignalType& ShowingSignal();
+
+ /**
+ * @copydoc Dali::Toolkit::Popup::ShownSignal()
+ */
+ Toolkit::Popup::DisplayStateChangeSignalType& ShownSignal();
+
+ /**
+ * @copydoc Dali::Toolkit::Popup::HidingSignal()
+ */
+ Toolkit::Popup::DisplayStateChangeSignalType& HidingSignal();
+
+ /**
* @copydoc Dali::Toolkit::Popup::HiddenSignal()
*/
- Toolkit::Popup::HiddenSignalType& HiddenSignal();
+ Toolkit::Popup::DisplayStateChangeSignalType& HiddenSignal();
/**
* Connects a callback function with the object's signals.
private:
/**
- * Signal occurs when the State animation (transition from hide<->show) finishes
+ * Signal occurs when the State animation (transition from hide <-> show) finishes.
* @param[in] source The animation that just finished.
*/
- void OnStateAnimationFinished( Animation& source );
+ void OnDisplayChangeAnimationFinished( Animation& source );
/**
* Signal occurs when the dimmed backing for the Popup is touched.
bool OnBackingTouched(Actor actor, const TouchEvent& event);
/**
- * Signal occurs when the wheel event is occured on dimmed backing for the Popup.
- * @param[in] actor The Actor got wheel
+ * Signal occurs when a mouse wheel event occurs on the dimmed backing.
+ * @param[in] actor The Actor that got the wheel event.
* @param[in] event The Wheel Event.
* @return Whether to consume event or not.
*/
virtual void OnInitialize();
/**
- * @copydoc Dali::CustomActorImpl::OnPropertySet()
+ * Called whenever the popup layout is re-set up.
+ * Normally due to a change in contents.
+ * Note: This is only done when the popup is shown.
+ */
+ virtual void OnLayoutSetup() {}
+
+ /**
+ * Called when the popup is directly or indirectly parented to the stage.
*/
- virtual void OnPropertySet( Property::Index index, Property::Value propertyValue );
+ virtual void OnControlStageConnection();
/**
* From Control; called after a child has been added to the owning actor.
virtual void OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension );
/**
- * @copydoc Control::OnKeyEvent()
- */
- virtual bool OnKeyEvent(const KeyEvent& event);
-
- /**
* @copydoc Control::GetNaturalSize()
*/
virtual Vector3 GetNaturalSize();
/**
* @copydoc Control::GetHeightForWidth()
*/
- float GetHeightForWidth( float width );
+ virtual float GetHeightForWidth( float width );
/**
* @copydoc Control::GetWidthForHeight()
*/
- float GetWidthForHeight( float height );
+ virtual float GetWidthForHeight( float height );
/**
- * @copydoc Control::GetNextKeyboardFocusableActor()
+ * @copydoc Control::OnKeyEvent()
*/
- Actor GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled);
+ virtual bool OnKeyEvent( const KeyEvent& event );
/**
- * Create the root actor for the footer
+ * @copydoc Control::GetNextKeyboardFocusableActor()
*/
- void CreateFooter();
+ Actor GetNextKeyboardFocusableActor( Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled );
private:
- // Undefined
+ // Undefined.
Popup(const Popup&);
- // Undefined
+ // Undefined.
Popup& operator=(const Popup& rhs);
private:
- struct LayoutInfo
- {
- Vector3 mTitleSize;
- Vector3 mContentSize;
- Vector3 mButtonBgSize;
- std::vector<Vector3> mButtonSize;
- };
-
-private:
-
- bool mShowing; ///< Popup is showing or not
-
- Layer mLayer; ///< Popup Layer (i.e. Dim backing and PopupBg reside in this)
- Toolkit::TableView mPopupLayout; ///< Popup layout (i.e. dialog reside in this)
- ImageActor mBacking; ///< Backing actor (dim effect)
-
- Actor mPreviousFocusedActor; ///< Store the previous focused actor to restore the focus when popup hide
-
- Actor mBackgroundImage; ///< Stores the background image.
- Actor mButtonAreaImage; ///< Stores the button background image.
- Toolkit::TextLabel mTitle; ///< Stores the text title.
- Actor mContent; ///< Stores popup's content.
- Actor mBottomBg; ///< bottom button bar background. ImageActor is replaced with Actor due to hidden image.
- Actor mTailImage; ///< Stores the tail image
-
- std::vector< Actor > mButtons; ///< Keeps track of the buttons added to this popup.
- Toolkit::Popup::PopupState mState; ///< Popup current state.
- Animation mAnimation; ///< The animation instance managing state changing.
- bool mAlterAddedChild; ///< Flag used to control whether children are reparented or not.
- PopupStylePtr mPopupStyle; ///< The style to be used for this popup.
-
- LayoutInfo mLayoutInfo; ///< Stores sizes of all popup components.
-
- Toolkit::Popup::TouchedOutsideSignalType mTouchedOutsideSignal;
- Toolkit::Popup::HiddenSignalType mHiddenSignal;
-
- Property::Index mPropertyTitle; ///< Property index for Title.
- Property::Index mPropertyState; ///< Property index for popup state.
+ Toolkit::Popup::TouchedOutsideSignalType mTouchedOutsideSignal;
+ Toolkit::Popup::DisplayStateChangeSignalType mShowingSignal;
+ Toolkit::Popup::DisplayStateChangeSignalType mShownSignal;
+ Toolkit::Popup::DisplayStateChangeSignalType mHidingSignal;
+ Toolkit::Popup::DisplayStateChangeSignalType mHiddenSignal;
+
+ Layer mLayer; ///< Popup Layer (i.e. Dim backing and PopupBg reside in this).
+ Toolkit::TableView mPopupLayout; ///< Popup Background (i.e. dialog reside in this).
+ ImageActor mBacking; ///< Backing actor (dim effect).
+ Actor mPreviousFocusedActor; ///< Store the previous focused actor to restore the focus when popup hide.
+ Actor mTailImage; ///< Stores the tail image.
+ Actor mPopupContainer; ///< This actor is used to house the background image and the main popup layout.
+ Animation mAnimation; ///< The current animation in use used to manage display state changing.
+ bool mAlterAddedChild; ///< Flag used to control whether children are reparented or not.
+ bool mLayoutDirty; ///< Set to true whenever any property that would require a layout update is modified.
+ Timer mAutoHideTimer; ///< Used to perform an auto-hide of the popup if desired.
+ bool mTouchTransparent; ///< Allows all events to pass through the popup.
+
+ // Main Content related properties:
+ Actor mTitle; ///< Stores the text title.
+ Actor mContent; ///< Stores the unselected content.
+ Actor mFooter; ///< Stores the footer content (typically controls).
+
+ // Display related properties.
+ Toolkit::Popup::DisplayState mDisplayState; ///< The current display state of the popup.
+ bool mTailVisible; ///< True if the popup tail should be visible.
+ Vector3 mTailPosition; ///< The position of the tail.
+ Toolkit::Popup::ContextualMode mContextualMode; ///< Allows the popup to be layed out adjacent to its parent in different directions.
+ float mAnimationDuration; ///< The duration of the transition in and out animations.
+ Toolkit::Popup::AnimationMode mAnimationMode; ///< The animation to use to transition in and out.
+ Dali::AnimationData mEntryAnimationData; ///< Stores description data that can be used for generating a custom entry animation.
+ Dali::AnimationData mExitAnimationData; ///< Stores description data that can be used for generating a custom exit animation.
+ unsigned int mAutoHideDelay; ///< If set, will auto-hide the popup after a specified amount of time.
+
+ // Style related properties:
+ bool mBackingEnabled; ///< True if a dimmed backing will be used.
+ Vector4 mBackingColor; ///< The color of the backing.
+ Actor mPopupBackgroundImage; ///< Stores the background image.
+ Vector4 mBackgroundOuterBorder; ///< Background external border margin size
+ float mMargin; ///< Internal margin for popup contents.
+ std::string mTailUpImage; ///< Image used for the tail for the up direction.
+ std::string mTailDownImage; ///< Image used for the tail for the down direction.
+ std::string mTailLeftImage; ///< Image used for the tail for the left direction.
+ std::string mTailRightImage; ///< Image used for the tail for the right direction.
};
} // namespace Internal
// Helpers for public-api forwarding methods
-inline Toolkit::Internal::Popup& GetImpl(Toolkit::Popup& pub)
+inline Toolkit::Internal::Popup& GetImpl( Toolkit::Popup& publicObject )
{
- DALI_ASSERT_ALWAYS(pub);
+ DALI_ASSERT_ALWAYS( publicObject );
- Dali::RefObject& handle = pub.GetImplementation();
+ Dali::RefObject& handle = publicObject.GetImplementation();
- return static_cast<Toolkit::Internal::Popup&>(handle);
+ return static_cast<Toolkit::Internal::Popup&>( handle );
}
-inline const Toolkit::Internal::Popup& GetImpl(const Toolkit::Popup& pub)
+inline const Toolkit::Internal::Popup& GetImpl( const Toolkit::Popup& publicObject )
{
- DALI_ASSERT_ALWAYS(pub);
+ DALI_ASSERT_ALWAYS( publicObject );
- const Dali::RefObject& handle = pub.GetImplementation();
+ const Dali::RefObject& handle = publicObject.GetImplementation();
- return static_cast<const Toolkit::Internal::Popup&>(handle);
+ return static_cast<const Toolkit::Internal::Popup&>( handle );
}
} // namespace Toolkit
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali-toolkit/internal/controls/popup/popup-style-impl.h>
-
-using namespace Dali;
-using namespace Dali::Toolkit;
-
-namespace // unnamed namespace
-{
-// Popup style default
-const Vector4 DEFAULT_BACKING_COLOR = Vector4(0.0f, 0.0f, 0.0f, 0.5f);
-const float DEFAULT_MARGIN = 20.0f; //From Tizen GUI UX
-const float DEFAULT_BUTTON_SPACING = 10.0f; //From Tizen GUI UX
-const Vector3 DEFAULT_BUTTON_SIZE(275.0f, 74.0f, 0.0f);
-const char* DEFAULT_BACKGROUND_IMAGE_PATH = DALI_IMAGE_DIR "00_popup_bg.9.png";
-const char* DEFAULT_BUTTON_AREA_IMAGE_PATH = DALI_IMAGE_DIR "00_popup_button_bg.png";
-const char* DEFAULT_TAIL_UP_IMAGE_PATH = DALI_IMAGE_DIR "popup_tail_up.png";
-const char* DEFAULT_TAIL_DOWN_IMAGE_PATH = DALI_IMAGE_DIR "popup_tail_down.png";
-const char* DEFAULT_TAIL_LEFT_IMAGE_PATH = DALI_IMAGE_DIR "popup_tail_left.png";
-const char* DEFAULT_TAIL_RIGHT_IMAGE_PATH = DALI_IMAGE_DIR "popup_tail_right.png";
-const Vector3 DEFAULT_BOTTOM_SIZE(620.0f,96.0f,0.0f);
-const Vector2 DEFAULT_BACKGROUND_SIZE(620.0f, 236.0f);
-const Vector4 DEFAULT_BACKGROUND_STYLE_9_BORDER( 25.0f, 25.0f, 26.0f, 50.0f );
-const Vector4 DEFAULT_BACKGROUND_OUTER_BORDER( 40.0f, 0.0f, 30.0f, 0.0f );
-const Vector4 DEFAULT_BUTTON_AREA_9_PATCH_BORDER( 13.0f, 8.0f, 13.0f, 8.0f );
-}
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-///////////////////////////////////////////////////////////////////////////////
-// Popup Style (base class)
-///////////////////////////////////////////////////////////////////////////////
-
-PopupStyle::PopupStyle()
-: backingColor(),
- backgroundImage(),
- buttonAreaImage(),
- backgroundSize(),
- backgroundScale9Border(),
- backgroundOuterBorder(),
- buttonArea9PatchBorder(),
- margin(0.0f),
- buttonSpacing(0.0f),
- buttonSize(),
- tailUpImage(),
- tailDownImage(),
- tailLeftImage(),
- tailRightImage()
-{
-}
-
-PopupStyle::~PopupStyle()
-{
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Popup style: Default
-///////////////////////////////////////////////////////////////////////////////
-
-PopupStyleDefault::PopupStyleDefault()
-{
- backingColor = DEFAULT_BACKING_COLOR;
- backgroundImage = DEFAULT_BACKGROUND_IMAGE_PATH;
- buttonAreaImage = DEFAULT_BUTTON_AREA_IMAGE_PATH;
- margin = DEFAULT_MARGIN;
- buttonSpacing = DEFAULT_BUTTON_SPACING;
- buttonSize = DEFAULT_BUTTON_SIZE;
- tailUpImage = DEFAULT_TAIL_UP_IMAGE_PATH;
- tailDownImage = DEFAULT_TAIL_DOWN_IMAGE_PATH;
- tailLeftImage = DEFAULT_TAIL_LEFT_IMAGE_PATH;
- tailRightImage = DEFAULT_TAIL_RIGHT_IMAGE_PATH;
- backgroundSize = DEFAULT_BACKGROUND_SIZE;
- backgroundScale9Border = DEFAULT_BACKGROUND_STYLE_9_BORDER;
- backgroundOuterBorder = DEFAULT_BACKGROUND_OUTER_BORDER;
- buttonArea9PatchBorder = DEFAULT_BUTTON_AREA_9_PATCH_BORDER;
- bottomSize = DEFAULT_BOTTOM_SIZE;
-}
-
-PopupStyleDefaultPtr PopupStyleDefault::New()
-{
- return PopupStyleDefaultPtr(new PopupStyleDefault());
-}
-
-PopupStyleDefault::~PopupStyleDefault()
-{
-}
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_TOOLKIT_INTERNAL_POPUP_STYLE_H__
-#define __DALI_TOOLKIT_INTERNAL_POPUP_STYLE_H__
-
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/common/intrusive-ptr.h>
-#include <dali/public-api/math/vector2.h>
-#include <dali/public-api/math/vector3.h>
-#include <dali/public-api/math/vector4.h>
-#include <dali/public-api/object/ref-object.h>
-
-#include <string>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-class PopupStyle;
-
-typedef IntrusivePtr<PopupStyle> PopupStylePtr;
-
-/**
- * A PopupStyle describes the images, positions, sizes, and various other metrics
- * which define how the popup should look.
- */
-class PopupStyle : public RefObject
-{
-public:
-
- /**
- * Virtual destructor.
- */
- virtual ~PopupStyle();
-
-public:
-
- Vector4 backingColor; ///< Color of backing layer (covers entire screen)
- std::string backgroundImage; ///< Background image path
- std::string buttonAreaImage; ///< This image is for the back ground area common for all the buttons in the popup
- Vector2 backgroundSize; ///< Background image size.
- Vector4 backgroundScale9Border; ///< Background scale-9 border settings.
- Vector4 backgroundOuterBorder; ///< Background outer border settings.
- Vector4 buttonArea9PatchBorder; ///< 9 patch border constants for buttonAreaImage
- float margin; ///< Margin for all contents (body, title, button)
- float buttonSpacing; ///< Horizontal spacing for buttons.
- Vector3 buttonSize; ///< Size of Buttons.
- Vector3 bottomSize; ///< size of bottom button bar.
- std::string bottomBackgroundImage; ///< bottom background image path.
- std::string tailUpImage; ///< Tail Up-side image path.
- std::string tailDownImage; ///< Tail Down-side image path.
- std::string tailLeftImage; ///< Tail Left-side image path.
- std::string tailRightImage; ///< Tail Right-side image path.
-
-protected:
-
- /**
- * Create a new PopupStyle; Only derived versions are instantiable.
- */
- PopupStyle();
-};
-
-class PopupStyleDefault;
-
-typedef IntrusivePtr<PopupStyleDefault> PopupStyleDefaultPtr;
-
-/**
- * This is the default popup style.
- */
-class PopupStyleDefault : public PopupStyle
-{
-public:
-
- /**
- * Create a new PopupStyle
- */
- static PopupStyleDefaultPtr New();
-
- /**
- * Virtual destructor.
- */
- virtual ~PopupStyleDefault();
-
-private:
-
-protected:
-
- /**
- * Protected constructor; see also PopupStyleDefault::New()
- */
- PopupStyleDefault();
-};
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // __DALI_TOOLKIT_INTERNAL_POPUP_STYLE_H__
}
}
+void TableView::OnSizeSet( const Vector3& size )
+{
+ // If this table view is size negotiated by another actor or control, then the
+ // rows and columns must be recalculated or the new size will not take effect.
+ mRowDirty = mColumnDirty = true;
+ RelayoutRequest();
+}
+
void TableView::OnRelayout( const Vector2& size, RelayoutContainer& container )
{
// Go through the layout data
*/
virtual void OnLayoutNegotiated( float size, Dimension::Type dimension );
+ /**
+ * @copydoc CustomActorImpl::OnSizeSet( const Vector3& size )
+ */
+ virtual void OnSizeSet( const Vector3& size );
+
private: // Implementation
/**
$(toolkit_src_dir)/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp \
$(toolkit_src_dir)/controls/image-view/image-view-impl.cpp \
$(toolkit_src_dir)/controls/magnifier/magnifier-impl.cpp \
+ $(toolkit_src_dir)/controls/popup/confirmation-popup-impl.cpp \
$(toolkit_src_dir)/controls/popup/popup-impl.cpp \
- $(toolkit_src_dir)/controls/popup/popup-style-impl.cpp \
$(toolkit_src_dir)/controls/page-turn-view/page-turn-portrait-view-impl.cpp \
$(toolkit_src_dir)/controls/page-turn-view/page-turn-effect.cpp \
$(toolkit_src_dir)/controls/page-turn-view/page-turn-landscape-view-impl.cpp \
+ [Accessibility](@ref accessibility)
### UI Components
- + [Text Label](@ref text-label)
- + [Text Field](@ref text-field)
+ Buttons
- + TableView
- + [Scroll View](@ref scroll-view)
+ [ItemView](@ref item-view)
+ + [Popup](@ref popup)
+ + [Scroll View](@ref scroll-view)
+ + TableView
+ + [Text Field](@ref text-field)
+ + [Text Label](@ref text-label)
### RenderTasks
--- /dev/null
+<!--
+/**-->
+
+[TOC]
+
+# Popup {#popup}
+
+![ ](../assets/img/popup/popup-example.png) ![ ](./popup-example.png)
+
+## Description {#popupdescription}
+
+The Popup control provides a generic way of displaying modal content.
+
+The content is displayed until it is dismissed by hiding the Popup.
+
+While the Popup is visible, it is displayed within a layer that is placed above any other actors.
+
+Content behind the Popup is dimmed by default, although this is configurable.
+
+
+## Contents {#popupcontents}
+
+
+The Popup is designed to be generic, but provide the necessary layout functionality to achieve this.
+
+The Popup window is broken down into the following areas:
+
+PopupBackgroundImage: This is the frame that appears around the edge of the Popup.
+
+Within the Popup there are three main fields:
+
+- Title
+- Content
+- Footer
+
+![ ](../assets/img/popup/popup-fields.png) ![ ](./popup-fields.png)
+
+Each field can contain any Actor.
+
+Note: All actor properties are optional, allowing any combination of content areas.
+Example: Image only popup (using the content field):
+![ ](../assets/img/popup/popup-image-content.png) ![ ](./popup-image-content.png)
+
+### Example content: {#popupfieldexample}
+
+- Title: TextLabel
+- Content: ImageActor or TextLabel
+- Footer: PushButton or Actor containing two PushButtons
+
+## Setting and getting the display state {#popupdisplaystate}
+
+The popup will not be shown immediately upon parenting it / adding it to the stage. First the display state must be set.
+The display state is represented by the property DISPLAY_STATE. It can be set with SHOWN and HIDDEN to show or hide the Popup.
+However, when getting the state, you will also be told if the Popup is in the process of SHOWING or HIDING.
+
+ | Value | Setting the state | Getting the state |
+ |----------|--------------------------------|--------------------------------|
+ | SHOWN | Show the popup | The popup is fully shown |
+ | HIDDEN | Hide the popup | The popup is fully hidden |
+ | SHOWING | | The popup is transitioning in |
+ | HIDING | | The popup is transitioning out |
+
+
+## Signals {#popupsignals}
+
+### Display State Signals {#popupdisplaystatesignals}
+
+All four state changes cause notifications via four respective signals that can be connected to.
+
+### OutsideTouched Signal {#popupoutsidetouched}
+
+This signal is emitted whenever a touch is received outside of the popups area.
+This is typically used to hide / dismiss the popup, but can be ignored if it is desired to force the user to make a selection using the controls within the Popup.
+
+
+## Transition effects {#popuptransitioneffects}
+
+The Popup object has built-in transitional animation effects.
+These can be user-defined by setting ANIMATION_MODE to CUSTOM, and setting the ENTRY_ANIMATION and
+EXIT_ANIMATION properties accordingly.
+
+The default to fading in and out.
+
+
+## Types of Popup {#popuptypes}
+
+The Popup can be configured to a preset type by using named types within the type-registry.
+
+These types are modifications / specialisations of a Popup. They provide the library user with a shortcut way of creating a specific type of Popup.
+
+
+The Popup control features a "Toast" popup type. This is a Popup that appears at the bottom of the screen, typically with some text. They are normally for informational purposes only.
+
+
+### Key differences of the Toast popup {#popuptoastdifferences}
+
+- The Popup will auto-hide itself after a few seconds.
+- It is touch-transparent. This means touch events go through the Popup to Actors below, giving it non-modal behaviour.
+- The backing is not dimmed. This allows the user to continue their actions without distraction.
+
+Note: All the above features can be set or unset manually on the Popup control if desired.
+
+Popup types can be created with the TypeRegistry (as they are not separate classes).
+
+
+### Example: {#popuptoastexample}
+
+![ ](../assets/img/popup/popup-toast.png) ![ ](./popup-toast.png)
+
+Here is the code to produce the above example:
+
+C++
+~~~{.cpp}
+TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo( "popup-toast" );
+if( typeInfo )
+{
+ BaseHandle baseHandle = typeInfo.CreateInstance();
+ if( baseHandle )
+ {
+ Toolkit::Popup popup = Toolkit::Popup::DownCast( baseHandle );
+ popup.SetTitle( Toolkit::TextLabel::New( "This is a Toast Popup.\nIt will auto-hide itself" ) );
+ Stage::GetCurrent().Add( popup );
+ popup.SetDisplayState( Toolkit::Popup::SHOWN );
+ }
+}
+~~~
+
+
+## Contextual Mode {#popupcontextualmode}
+
+Contextual Mode allows the popup can appear adjacent to it's parent in screen space.
+
+If disabled, the Popup will ignore it's parent and appear centered on the stage (user positioning can override this).
+
+If enabled, the contextual mode can be set to four directions. The Popup will be made adjacent on the selected axis.
+
+EG:
+~~~{.cpp}
+myPopup.SetProperty( Toolkit::Popup::Properties::CONTEXTUAL_MODE, "BELOW" );
+~~~
+
+Will make the top of the Popup appear just below the bottom of the parent object (plus a margin).
+
+The default is: NON_CONTEXTUAL which means no layout or positioning is performed.
+
+| ContextualMode | Layout |
+|-------------------|---------------------------------------------------------|
+| NON_CONTEXTUAL | No contextual layout is performed |
+| ABOVE | Popup is above vertically, centered horizontally |
+| RIGHT | Popup is to the right horizontally, centered vertically |
+| BELOW | Popup is below vertically, centered horizontally |
+| LEFT | Popup is to the left horizontally, centered vertically |
+
+
+## Properties {#popupproperties}
+
+Various properties provide more configuration on the Popup's styling.
+
+This is a breakdown of remaining properties not described in detail above.
+
+
+| Property | Type | Description |
+|------------------------|---------|--------------------------------------------------------------------------|
+| TOUCH_TRANSPARENT | bool | If true, allow touch events to travel through the popup. |
+| TAIL_VISIBILITY | bool | If true, display a tail image on one of the edges of the popup. |
+| TAIL_POSITION | Vector3 | Describes the position of the tail image. Orientation is inferred. |
+| ANIMATION_DURATION | float | Duration used for entry and exit transition animations. |
+| AUTO_HIDE_DELAY | int | If non-zero, the number of milliseconds before the popup will auto-hide. |
+| BACKING_ENABLED | bool | True if backing (dimmed background) is enabled. |
+| BACKING_COLOR | Vector4 | The color of the dimmed background. |
+| TAIL_UP_IMAGE | string | The image to use for the tail if above the popup. |
+| TAIL_DOWN_IMAGE | string | The image to use for the tail if below the popup. |
+| TAIL_LEFT_IMAGE | string | The image to use for the tail if to the left of the popup. |
+| TAIL_RIGHT_IMAGE | string | The image to use for the tail if to the right of the popup. |
+
+
+# ConfirmationPopup Control {#popupconfirmation}
+
+The ConfirmationPopup control provides a simple interface for providing automatic connection to control signals for common-use Popup use-cases.
+
+ConfirmationPopup will automatically provide signals for 1 or 2 controls.
+Note: The controls do not need to be PushButtons.
+These signals are dynamically created. The controls (typically PushButtons) must be specifially named so the ConfirmationPopup can locate them.
+
+## Step 1 {#popupconfirmationstep1}
+Name your controls.
+
+- Name your first control, or OK control: "control-ok"
+- Name your second control, or Cancel control: "control-cancel"
+
+## Step 2 {#popupconfirmationstep2}
+Tell the ConfirmationPopup the names of the signals to connect to for each control.
+For example, if we are using PushButtons as controls, the signal name would be "clicked".
+This allows us to use different control types.
+
+- Set property "connect-signal-ok-selected" with the name of the signal to connect to within the first control.
+- Set property "connect-signal-cancel-selected" with the name of the signal to connect to within the second control.
+
+## Step 3 {#popupconfirmationstep3}
+Connect to the following respective signals within ConfirmationPopup:
+
+- Connect to signal "control-signal-ok" to be signalled for the first control.
+- Connect to signal "control-signal-cancel" to be signalled for the second control.
+
+The ConfirmationPopup will dynamically make the connection between the signalling control, and your signal handler.
+
+This allows connection of signals within both C++, JSON and Javascript APIs.
+If more manual control or customisable layout is needed, then it is recommended to use the Popup widget directly for full control.
+
+The JSON code example at the bottom of this document uses the ConfirmationPopup to allow signal connection from within the JSON description.
+
+
+# C++ example of a Popup with two buttons {#popupexamplec}
+
+This example creates a Popup with:
+
+- Title: TextLabel
+- Content: TextLabel
+- Footer: ImageActor (an image border around the buttons)
+ - PushButton (OK control)
+ - PushButton (Cancel control)
+
+The example connects signals to the two buttons, and to the OutsideTouched signal.
+
+~~~{.cpp}
+Toolkit::Popup popup = Toolkit::Popup::New();
+
+Toolkit::TextLabel titleActor = Toolkit::TextLabel::New( "Title" );
+titleActor.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, Color::WHITE );
+titleActor.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
+popup.SetTitle( titleActor );
+
+Toolkit::TextLabel contentActor = Toolkit::TextLabel::New( "Content text" );
+contentActor.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, Color::WHITE );
+contentActor.SetProperty( Toolkit::TextLabel::Property::MULTI_LINE, true );
+contentActor.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
+popup.SetContent( contentActor );
+
+// Create the footer: Two buttons surrounded by an image.
+ImageActor footer = ImageActor::New( ResourceImage::New( DEFAULT_CONTROL_AREA_IMAGE_PATH ) );
+footer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
+footer.SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT );
+footer.SetSize( 0.0f, 80.0f );
+footer.SetAnchorPoint( AnchorPoint::CENTER );
+footer.SetParentOrigin( ParentOrigin::CENTER );
+
+Toolkit::PushButton okButton = Toolkit::PushButton::New();
+okButton.SetLabelText( "OK" );
+okButton.SetParentOrigin( ParentOrigin::CENTER );
+okButton.SetAnchorPoint( AnchorPoint::CENTER );
+okButton.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS );
+okButton.SetSizeModeFactor( Vector3( -20.0f, -20.0f, 0.0 ) );
+okButton.ClickedSignal().Connect( this, &MyExample::OnOKButtonClicked );
+
+Toolkit::PushButton cancelButton = Toolkit::PushButton::New();
+cancelButton.SetLabelText( "Cancel" );
+cancelButton.SetParentOrigin( ParentOrigin::CENTER );
+cancelButton.SetAnchorPoint( AnchorPoint::CENTER );
+cancelButton.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS );
+cancelButton.SetSizeModeFactor( Vector3( -20.0f, -20.0f, 0.0 ) );
+cancelButton.ClickedSignal().Connect( this, &MyExample::OnCancelButtonClicked );
+
+// Set up the footer's layout.
+Toolkit::TableView controlLayout = Toolkit::TableView::New( 1, 2 );
+controlLayout.SetParentOrigin( ParentOrigin::CENTER );
+controlLayout.SetAnchorPoint( AnchorPoint::CENTER );
+controlLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+controlLayout.SetCellPadding( Size( 10.0f, 10.0f ) );
+controlLayout.SetRelativeWidth( 0, 0.5f );
+controlLayout.SetRelativeWidth( 1, 0.5f );
+controlLayout.SetCellAlignment( Toolkit::TableView::CellPosition( 0, 0 ), HorizontalAlignment::CENTER, VerticalAlignment::CENTER );
+controlLayout.SetCellAlignment( Toolkit::TableView::CellPosition( 0, 1 ), HorizontalAlignment::CENTER, VerticalAlignment::CENTER );
+controlLayout.AddChild( okButton, Toolkit::TableView::CellPosition( 0, 0 ) );
+controlLayout.AddChild( cancelButton, Toolkit::TableView::CellPosition( 0, 1 ) );
+footer.Add( controlLayout );
+popup.SetFooter( footer );
+
+popup.OutsideTouchedSignal().Connect( this, &MyExample::OnPopupOutsideTouched );
+
+// Add to stage (the popup is still invisible at this point).
+Stage::GetCurrent().Add( popup );
+
+// Display the popup.
+mPopup.SetDisplayState( Toolkit::Popup::SHOWN );
+~~~
+
+
+# JSON example of a Popup with two buttons {#popupexamplejson}
+
+This example creates a Popup with:
+
+- Title: TextLabel
+- Content: TextLabel
+- Footer: Control
+ - PushButton (OK control)
+ - PushButton (Cancel control)
+
+The example connects signals to the two buttons, and to the OutsideTouched signal.
+This time without an image around the buttons. This could be added in the same way as the C++ example however.
+
+
+~~~{.json}
+{
+ "constants": {
+ "CONFIG_SCRIPT_LOG_LEVEL": "Verbose"
+ },
+ "stage": [
+ {
+ "type": "ConfirmationPopup",
+ "name": "confirmation-popup",
+ "parent-origin": [0.5, 0.55, 0.5],
+ "anchor-point": "CENTER",
+ "width-resize-policy": "SIZE_RELATIVE_TO_PARENT",
+ "height-resize-policy": "USE_NATURAL_SIZE",
+ "size-mode-factor": [0.65, 1.0, 1.0],
+ "tail-visibility": false,
+ "display-change-animation-duration": 1.0,
+ "contextual-mode": "NON_CONTEXTUAL",
+ "animation-mode": "ZOOM",
+ "connect-signal-ok-selected": "clicked",
+ "connect-signal-cancel-selected": "clicked",
+ "title": {
+ "type": "TextLabel",
+ "text": "Title text",
+ "text-color": [1, 1, 1, 1]
+ },
+ "content": {
+ "type": "TextLabel",
+ "text": "Content text",
+ "padding": [20, 20, 20, 0],
+ "text-color": [1, 1, 1, 1]
+ },
+ "footer": {
+ "type": "Control",
+ "size": [0, 80, 0],
+ "width-resize-policy": "FILL_TO_PARENT",
+ "height-resize-policy": "FIXED",
+ "parent-origin": "CENTER",
+ "anchor-point": "CENTER",
+ "actors": [
+ {
+ "type": "PushButton",
+ "name": "control-ok",
+ "parent-origin": "CENTER_LEFT",
+ "anchor-point": "CENTER_LEFT",
+ "position": [20, 0, 0],
+ "size": [0, 0, 0],
+ "label-text": "OK"
+ },
+ {
+ "type": "PushButton",
+ "name": "control-cancel",
+ "parent-origin": "CENTER_RIGHT",
+ "anchor-point": "CENTER_RIGHT",
+ "position": [-20, 0, 0],
+ "size": [0, 0, 0],
+ "label-text": "Cancel"
+ }
+ ]
+ },
+ "signals": [
+ {
+ "name": "control-signal-ok",
+ "action": "set",
+ "actor": "confirmation-popup",
+ "property": "display-state",
+ "value": "HIDDEN"
+ },
+ {
+ "name": "control-signal-cancel",
+ "action": "set",
+ "actor": "confirmation-popup",
+ "property": "display-state",
+ "value": "HIDDEN"
+ },
+ {
+ "name": "touched-outside",
+ "action": "set",
+ "actor": "confirmation-popup",
+ "property": "display-state",
+ "value": "HIDDEN"
+ }
+ ]
+ }
+ ]
+}
+~~~
+
+
+@class _Guide_Popup
+*/
+