[dali_1.0.52] Merge branch 'devel/master' 72/45472/1
authorXiangyin Ma <x1.ma@samsung.com>
Thu, 6 Aug 2015 10:06:09 +0000 (11:06 +0100)
committerXiangyin Ma <x1.ma@samsung.com>
Thu, 6 Aug 2015 10:06:09 +0000 (11:06 +0100)
Change-Id: I2bdc9df503a612a753d4902869d88036640dacf7

63 files changed:
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-timer.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-timer.h
automated-tests/src/dali-toolkit/utc-Dali-Button.cpp
automated-tests/src/dali-toolkit/utc-Dali-ConfirmationPopup.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-Popup.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextSelectionPopup.cpp
build/tizen/configure.ac
dali-toolkit/devel-api/controls/popup/confirmation-popup.cpp [new file with mode: 0644]
dali-toolkit/devel-api/controls/popup/confirmation-popup.h [new file with mode: 0644]
dali-toolkit/devel-api/controls/popup/popup.cpp
dali-toolkit/devel-api/controls/popup/popup.h
dali-toolkit/devel-api/controls/text-controls/text-selection-popup.cpp
dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h
dali-toolkit/devel-api/controls/text-controls/text-selection-toolbar.cpp
dali-toolkit/devel-api/controls/text-controls/text-selection-toolbar.h
dali-toolkit/devel-api/file.list
dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp
dali-toolkit/internal/atlas-manager/atlas-manager-impl.h
dali-toolkit/internal/atlas-manager/atlas-manager.cpp
dali-toolkit/internal/atlas-manager/atlas-manager.h
dali-toolkit/internal/controls/popup/confirmation-popup-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/popup/confirmation-popup-impl.h [new file with mode: 0644]
dali-toolkit/internal/controls/popup/popup-impl.cpp
dali-toolkit/internal/controls/popup/popup-impl.h
dali-toolkit/internal/controls/popup/popup-style-impl.cpp [deleted file]
dali-toolkit/internal/controls/popup/popup-style-impl.h [deleted file]
dali-toolkit/internal/controls/table-view/table-view-impl.cpp
dali-toolkit/internal/controls/table-view/table-view-impl.h
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h
dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/text/decorator/text-decorator.cpp
dali-toolkit/internal/text/glyph-run.h [new file with mode: 0644]
dali-toolkit/internal/text/layouts/layout-engine.cpp
dali-toolkit/internal/text/line-run.h
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-definitions.h
dali-toolkit/internal/text/text-io.cpp
dali-toolkit/internal/text/text-view-interface.h
dali-toolkit/internal/text/text-view.cpp
dali-toolkit/internal/text/text-view.h
dali-toolkit/internal/text/visual-model-impl.cpp
dali-toolkit/internal/text/visual-model-impl.h
dali-toolkit/public-api/controls/default-controls/solid-color-actor.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/styles/480x800/dali-toolkit-default-theme.json [moved from dali-toolkit/styles/mobile/dali-toolkit-default-theme.json with 82% similarity]
dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json [moved from dali-toolkit/styles/dali-toolkit-default-theme.json with 60% similarity]
docs/content/images/popup/popup-example.png [new file with mode: 0644]
docs/content/images/popup/popup-fields.png [new file with mode: 0644]
docs/content/images/popup/popup-image-content.png [new file with mode: 0644]
docs/content/images/popup/popup-toast.png [new file with mode: 0644]
docs/content/main.md
docs/content/shared-javascript-and-cpp-documentation/popup.md [new file with mode: 0644]
packaging/dali-toolkit.spec
plugins/dali-script-v8/src/actors/actor-api.cpp
plugins/dali-script-v8/src/actors/actor-api.h
plugins/dali-script-v8/src/actors/actor-wrapper.cpp

index 2b1858e..8f40f82 100644 (file)
@@ -12,6 +12,7 @@ SET(TC_SOURCES
    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
index 864e41e..2f1ce14 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -34,12 +34,17 @@ class Timer;
 
 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();
@@ -63,7 +68,6 @@ private: // Implementation
 
 private: // Data
 
-  Dali::Timer::TimerSignalType mTickSignal;
   unsigned int mInterval;
 };
 
@@ -87,7 +91,7 @@ inline const Timer& GetImplementation(const Dali::Timer& timer)
 
 TimerPtr Timer::New( unsigned int milliSec )
 {
-  TimerPtr timerImpl = new Timer(10);
+  TimerPtr timerImpl = new Timer( milliSec );
   return timerImpl;
 }
 
@@ -130,9 +134,17 @@ bool Timer::Tick()
 
 Dali::Timer::TimerSignalType& Timer::TickSignal()
 {
-  return mTickSignal;
+  return gTickSignal;
+}
+
+// Mock setup functions:
+
+void Timer::MockEmitSignal()
+{
+  gTickSignal.Emit();
 }
 
+
 } // namespace Adaptor
 
 } // namespace Internal
@@ -206,5 +218,12 @@ Timer::Timer(Internal::Adaptor::Timer* timer)
 {
 }
 
+// Mock setup functions:
+
+void Timer::MockEmitSignal()
+{
+  Internal::Adaptor::GetImplementation( *this ).MockEmitSignal();
+}
+
 } // namespace Dali
 
index a7397e6..e0c886c 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -40,6 +40,9 @@ class Timer;
 class Timer : public BaseHandle
 {
 public:
+  void MockEmitSignal();
+
+public:
   typedef Signal< bool () > TimerSignalType;
   Timer();
   static Timer New( unsigned int milliSec );
index 990be9c..f290cb2 100644 (file)
@@ -346,7 +346,6 @@ int UtcDaliButtonSetUnselectedImageP(void)
   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 );
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ConfirmationPopup.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ConfirmationPopup.cpp
new file mode 100644 (file)
index 0000000..0d3dec9
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * 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;
+}
+
+
+
index 294bec2..990c20a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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>
 
@@ -50,18 +51,18 @@ static void TestCallback(BaseHandle handle)
 }
 
 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)
 {
@@ -87,30 +88,65 @@ bool HasAncestor(Actor child, Actor ancestor)
   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 );
@@ -119,11 +155,11 @@ int UtcDaliPopupNew(void)
 
   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 );
 
@@ -136,9 +172,13 @@ int UtcDaliPopupNew(void)
   END_TEST;
 }
 
-int UtcDaliPopupDestructor(void)
+/*
+ * This test checks popup destruction.
+ */
+int UtcDaliPopupDestructorP( void )
 {
   ToolkitTestApplication application;
+  tet_infoline( " UtcDaliPopupDestructorP" );
 
   Popup* popup = new Popup();
   delete popup;
@@ -147,9 +187,10 @@ int UtcDaliPopupDestructor(void)
   END_TEST;
 }
 
-int UtcDaliPopupDownCast(void)
+int UtcDaliPopupDownCastP(void)
 {
   ToolkitTestApplication application;
+  tet_infoline( " UtcDaliPopupDownCastP" );
 
   Handle handle = Popup::New();
 
@@ -159,132 +200,292 @@ int UtcDaliPopupDownCast(void)
   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
@@ -292,40 +493,32 @@ int UtcDaliPopupShowHide(void)
 
   // 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++)
@@ -334,12 +527,11 @@ int UtcDaliPopupShowHide(void)
     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");
@@ -347,37 +539,48 @@ int UtcDaliPopupShowHideTail(void)
   // 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();
@@ -399,6 +602,113 @@ int UtcDaliPopupOnTouchedOutside(void)
   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;
+}
+
index 7aeb471..f6f9730 100644 (file)
@@ -41,7 +41,7 @@ int UtcDaliToolkitTextSelectionPopupNewP(void)
 
   DALI_TEST_CHECK( !textSelectionPopup );
 
-  textSelectionPopup = TextSelectionPopup::New( TextSelectionPopup::COPY, NULL );
+  textSelectionPopup = TextSelectionPopup::New( NULL );
 
   DALI_TEST_CHECK( textSelectionPopup );
   END_TEST;
@@ -61,7 +61,7 @@ int UtcDaliToolkitTextSelectionPopupCopyConstructorP(void)
   ToolkitTestApplication application;
   TextSelectionPopup textSelectionPopup;
 
-  textSelectionPopup = TextSelectionPopup::New( TextSelectionPopup::COPY, NULL );
+  textSelectionPopup = TextSelectionPopup::New( NULL );
   TextSelectionPopup copy( textSelectionPopup );
 
   DALI_TEST_CHECK( copy == textSelectionPopup );
@@ -85,7 +85,7 @@ int UtcDaliToolkitTextSelectionPopupAssignmentOperatorP(void)
 {
   ToolkitTestApplication application;
   TextSelectionPopup textSelectionPopup;
-  textSelectionPopup = TextSelectionPopup::New( TextSelectionPopup::COPY, NULL );
+  textSelectionPopup = TextSelectionPopup::New(  NULL );
   TextSelectionPopup copy;
   copy = textSelectionPopup;
 
@@ -97,7 +97,7 @@ int UtcDaliToolkitTextSelectionPopupDownCastP(void)
 {
   ToolkitTestApplication application;
   TextSelectionPopup textSelectionPopup;
-  textSelectionPopup = TextSelectionPopup::New( TextSelectionPopup::COPY, NULL );
+  textSelectionPopup = TextSelectionPopup::New( NULL );
 
   TextSelectionPopup cast = TextSelectionPopup::DownCast( textSelectionPopup );
 
index a0b795d..9378eed 100644 (file)
@@ -84,6 +84,13 @@ AC_ARG_ENABLE([profile],
               [dali_profile=$enableval],
               [dali_profile=UBUNTU])
 
+# Tizen Style Folder
+AC_ARG_WITH(style,
+              [AC_HELP_STRING([--with-style],
+                            [Select the style folder to use])],
+              [dali_style=$withval],
+              [dali_style=480x800])
+
 # Ensure valid profile selected
 if test "x$dali_profile" != "xUBUNTU" -a "x$dali_profile" != "xMOBILE" -a "x$dali_profile" != "xWEARABLE" -a "x$dali_profile" != "xTV" ; then
   AC_MSG_ERROR([$enable_profile is an invalid profile])
@@ -103,14 +110,9 @@ fi
 
 DALI_TOOLKIT_CFLAGS="$DALI_TOOLKIT_CFLAGS -DDALI_PROFILE_${dali_profile}"
 
-# Style paths
-if test "x$dali_profile" = "xUBUNTU"; then
-  STYLE_DIR=../../../dali-toolkit/styles
-fi
-
-if test "x$dali_profile" = "xMOBILE"; then
-  STYLE_DIR=../../../dali-toolkit/styles/mobile
-fi
+# Style folder
+STYLE_DIR=../../../dali-toolkit/styles
+STYLE_DIR=$STYLE_DIR/$dali_style
 
 AC_SUBST(STYLE_DIR)
 
@@ -177,4 +179,6 @@ Configuration
   Profile:                          $dali_profile
   Data Dir (Read/Write):            $dataReadWriteDir
   Data Dir (Read Only):             $dataReadOnlyDir
+  Style Dir                         $STYLE_DIR
+  Style                             $dali_style
 "
diff --git a/dali-toolkit/devel-api/controls/popup/confirmation-popup.cpp b/dali-toolkit/devel-api/controls/popup/confirmation-popup.cpp
new file mode 100644 (file)
index 0000000..de7e116
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 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
diff --git a/dali-toolkit/devel-api/controls/popup/confirmation-popup.h b/dali-toolkit/devel-api/controls/popup/confirmation-popup.h
new file mode 100644 (file)
index 0000000..621eaec
--- /dev/null
@@ -0,0 +1,148 @@
+#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__
index 9b74a3d..f3669fa 100644 (file)
@@ -20,7 +20,6 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/controls/popup/popup-impl.h>
-#include <dali-toolkit/public-api/controls/buttons/button.h>
 
 using namespace Dali;
 
@@ -77,69 +76,73 @@ Popup Popup::DownCast( BaseHandle handle )
   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
index 32322e2..40b4df3 100644 (file)
@@ -32,40 +32,24 @@ namespace Internal DALI_INTERNAL
 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
@@ -74,27 +58,80 @@ 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:
 
@@ -104,6 +141,20 @@ 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
@@ -121,20 +172,6 @@ public:
   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
@@ -147,102 +184,108 @@ public:
 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
 
@@ -251,7 +294,7 @@ 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.
index 4b9f548..28a5819 100644 (file)
@@ -29,11 +29,9 @@ namespace Dali
 namespace Toolkit
 {
 
-TextSelectionPopup TextSelectionPopup::New( Buttons enabledButtons,
-                                            TextSelectionPopupCallbackInterface* callbackInterface )
+TextSelectionPopup TextSelectionPopup::New( TextSelectionPopupCallbackInterface* callbackInterface )
 {
-  return Internal::TextSelectionPopup::New( enabledButtons,
-                                            callbackInterface );
+  return Internal::TextSelectionPopup::New( callbackInterface );
 }
 
 TextSelectionPopup::TextSelectionPopup()
@@ -63,6 +61,11 @@ TextSelectionPopup TextSelectionPopup::DownCast( BaseHandle handle )
   return Control::DownCast<TextSelectionPopup, Internal::TextSelectionPopup>(handle);
 }
 
+void TextSelectionPopup::EnableButtons( Toolkit::TextSelectionPopup::Buttons buttonsToEnable )
+{
+  GetImpl(*this).EnableButtons( buttonsToEnable );
+}
+
 void TextSelectionPopup::RaiseAbove( Layer target )
 {
   GetImpl(*this).RaiseAbove( target );
@@ -73,6 +76,11 @@ void TextSelectionPopup::ShowPopup()
   GetImpl(*this).ShowPopup();
 }
 
+void TextSelectionPopup::HidePopup()
+{
+  GetImpl(*this).HidePopup();
+}
+
 TextSelectionPopup::TextSelectionPopup( Internal::TextSelectionPopup& implementation )
 : Control(implementation)
 {
index fd473ad..4eec4c1 100644 (file)
@@ -89,18 +89,18 @@ public:
       POPUP_DIVIDER_COLOR,                      ///< name "popup-divider-color",           The color of the divider between options,       type VECTOR4
       POPUP_ICON_COLOR,                         ///< name "popup-icon-color",              The color of the icons (if supplied),           type VECTOR4
       POPUP_PRESSED_COLOR,                      ///< name "popup-pressed-color",           The color of the option when pressed,           type VECTOR4
-      POPUP_PRESSED_IMAGE                       ///< name "popup-pressed-image",           The image to use for the option when pressed,   type STRING
+      POPUP_PRESSED_IMAGE,                      ///< name "popup-pressed-image",           The image to use for the option when pressed,   type STRING
+      POPUP_FADE_IN_DURATION,                   ///< name "popup-fade-in-duration",        The duration of the fade-in animation,          type FLOAT
+      POPUP_FADE_OUT_DURATION,                  ///< name "popup-fade-out-duration",       The duration of the fade-out animation,         type FLOAT
     };
   };
 
   /**
-   * Create the TextSelectionPopup control with the given set of buttons.
-   * @param[in] enabledButtons The given set of buttons to enable
+   * Create the TextSelectionPopup control.
    * @param[in] callbackInterface The text popup callback interface which receives the button click callbacks.
    * @return A handle to the TextSelectionPopup control.
    */
-  static TextSelectionPopup New( Buttons enabledButtons,
-                                 TextSelectionPopupCallbackInterface* callbackInterface );
+  static TextSelectionPopup New( TextSelectionPopupCallbackInterface* callbackInterface );
 
   /**
    * @brief Creates an empty handle.
@@ -141,6 +141,12 @@ public:
   static TextSelectionPopup DownCast( BaseHandle handle );
 
   /**
+   * @brief Specify which buttons to show in Popup
+   * @param[in] buttonsToEnable Buttons to enable
+   */
+  void EnableButtons( Toolkit::TextSelectionPopup::Buttons buttonsToEnable );
+
+  /**
    * @brief Raises the toolbar's layer above the given @e target layer.
    *
    * @param[in] target The layer to get above of.
@@ -148,10 +154,15 @@ public:
   void RaiseAbove( Layer target );
 
   /**
-   * @brief Show the Popup
+   * @brief Show the Popup if not being shown
    */
   void ShowPopup();
 
+  /**
+   * @brief Hide the Popup if shown
+   */
+  void HidePopup();
+
 public: // Not intended for application developers
 
   /**
index df103cf..46c32c8 100644 (file)
@@ -61,7 +61,6 @@ void TextSelectionToolbar::AddOption( Actor& option )
   GetImpl(*this).AddOption(option);
 }
 
-
 void TextSelectionToolbar::AddDivider( Actor& divider )
 {
   GetImpl(*this).AddDivider( divider );
index d0c5976..2fbf611 100644 (file)
@@ -62,7 +62,7 @@ public:
   {
     enum
     {
-      MAX_SIZE =  PROPERTY_START_INDEX   ///< name "popup-max-size",                The maximum size the Popup can be,              type VECTOR2
+      MAX_SIZE =  PROPERTY_START_INDEX   ///< name "max-size",                The maximum size the Popup can be,              type VECTOR2
     };
   };
 
index 71202e2..c5187c3 100755 (executable)
@@ -12,6 +12,7 @@ devel_api_src_files = \
   $(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 \
@@ -53,6 +54,7 @@ devel_api_page_turn_view_header_files = \
   $(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 = \
index 3e69856..bfcf1fa 100644 (file)
@@ -489,16 +489,22 @@ void AtlasManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
                                const Toolkit::AtlasManager::Mesh2D& second,
                                bool optimize )
 {
-  uint32_t vc = first.mVertices.Size();
+  const uint32_t verticesCount = first.mVertices.Size();
+  first.mVertices.Insert( first.mVertices.End(),
+                          second.mVertices.Begin(),
+                          second.mVertices.End() );
 
-  for ( uint32_t v = 0; v < second.mVertices.Size(); ++v )
-  {
-    first.mVertices.PushBack( second.mVertices[ v ] );
-  }
+  const uint32_t indicesCount = first.mIndices.Size();
+  first.mIndices.Insert( first.mIndices.End(),
+                         second.mIndices.Begin(),
+                         second.mIndices.End() );
 
-  for ( uint32_t i = 0; i < second.mIndices.Size(); ++i )
+  for( Vector<unsigned int>::Iterator it = first.mIndices.Begin() + indicesCount,
+         endIt = first.mIndices.End();
+       it != endIt;
+       ++it )
   {
-    first.mIndices.PushBack( second.mIndices[ i ] + vc );
+    *it += verticesCount;
   }
 
   if ( optimize )
@@ -509,41 +515,6 @@ void AtlasManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first,
   }
 }
 
-void AtlasManager::StitchMesh( const Toolkit::AtlasManager::Mesh2D& first,
-                               const Toolkit::AtlasManager::Mesh2D& second,
-                               Toolkit::AtlasManager::Mesh2D& out,
-                               bool optimize )
-{
-  uint32_t vc = first.mVertices.Size();
-
-  for ( uint32_t v = 0; v < vc; ++v )
-  {
-    out.mVertices.PushBack( first.mVertices[ v ] );
-  }
-
-  for ( uint32_t v = 0; v < second.mVertices.Size(); ++v )
-  {
-    out.mVertices.PushBack( second.mVertices[ v ] );
-  }
-
-  for ( uint32_t i = 0; i < first.mIndices.Size(); ++i )
-  {
-    out.mIndices.PushBack( first.mIndices[ i ] );
-  }
-
-  for ( uint32_t i = 0; i < second.mIndices.Size(); ++i )
-  {
-    out.mIndices.PushBack( second.mIndices[ i ] + vc );
-  }
-
-  if ( optimize )
-  {
-    Toolkit::AtlasManager::Mesh2D optimizedMesh;
-    OptimizeMesh( out, optimizedMesh );
-    out = optimizedMesh;
-  }
-}
-
 void AtlasManager::UploadImage( const BufferImage& image,
                                 const AtlasSlotDescriptor& desc )
 {
index b22f709..5b301f0 100644 (file)
@@ -122,14 +122,6 @@ public:
                    bool optimize );
 
   /**
-   * @copydoc Toolkit::AtlasManager::StitchMesh
-   */
-  void StitchMesh(  const Toolkit::AtlasManager::Mesh2D& first,
-                    const Toolkit::AtlasManager::Mesh2D& second,
-                    Toolkit::AtlasManager::Mesh2D& out,
-                    bool optimize );
-
-  /**
    * @copydoc Toolkit::AtlasManager::Remove
    */
   bool Remove( ImageId id );
@@ -249,4 +241,4 @@ inline Internal::AtlasManager& GetImplementation(Toolkit::AtlasManager& manager)
 } // namespace Dali
 
 
- #endif // __DALI_TOOLKIT_ATLAS_MANAGER_IMPL_H__
\ No newline at end of file
+ #endif // __DALI_TOOLKIT_ATLAS_MANAGER_IMPL_H__
index e6b041c..849b27d 100644 (file)
@@ -85,14 +85,6 @@ void AtlasManager::StitchMesh( Mesh2D& first,
   GetImplementation(*this).StitchMesh( first, second, optimize );
 }
 
-void AtlasManager::StitchMesh( const Mesh2D& first,
-                               const Mesh2D& second,
-                               Mesh2D& out,
-                               bool optimize )
-{
-  GetImplementation(*this).StitchMesh( first, second, out, optimize );
-}
-
 Dali::Atlas AtlasManager::GetAtlasContainer( AtlasId atlas ) const
 {
   return GetImplementation(*this).GetAtlasContainer( atlas );
index 532be6f..2c7f192 100644 (file)
@@ -313,19 +313,6 @@ public:
                    bool optimize = false );
 
   /**
-   * @brief Combine two meshes, outputting the result into a new mesh
-   *
-   * @param[in] first First mesh
-   * @param[in] second Second mesh
-   * @param[in] optimize should we optimize vertex data
-   * @param[out] out resulting mesh
-   */
-  void StitchMesh( const Mesh2D& first,
-                   const Mesh2D& second,
-                   Mesh2D& out,
-                   bool optimize = false );
-
-  /**
    * @brief Get the BufferImage containing an atlas
    *
    * @param[in] atlas AtlasId returned when atlas was created
diff --git a/dali-toolkit/internal/controls/popup/confirmation-popup-impl.cpp b/dali-toolkit/internal/controls/popup/confirmation-popup-impl.cpp
new file mode 100644 (file)
index 0000000..cb0c9e9
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * 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
diff --git a/dali-toolkit/internal/controls/popup/confirmation-popup-impl.h b/dali-toolkit/internal/controls/popup/confirmation-popup-impl.h
new file mode 100644 (file)
index 0000000..45f23a9
--- /dev/null
@@ -0,0 +1,180 @@
+#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__
index d4fcc43..cc7ae5d 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * 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;
 
@@ -55,524 +54,1332 @@ namespace Internal
 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 )
@@ -586,6 +1393,18 @@ bool Popup::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra
   {
     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 );
@@ -599,235 +1418,302 @@ bool Popup::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra
   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() )
@@ -835,38 +1721,25 @@ Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::C
       // 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 );
             }
@@ -878,7 +1751,7 @@ Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::C
           }
           case Toolkit::Control::KeyboardFocus::RIGHT:
           {
-            if ( iter == focusableActors.end() - 1 )
+            if( iter == focusableActors.end() - 1 )
             {
               nextFocusableActor = *( focusableActors.begin() );
             }
@@ -891,13 +1764,13 @@ Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::C
 
           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;
               }
@@ -918,13 +1791,13 @@ Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::C
 
           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() );
               }
@@ -933,18 +1806,13 @@ Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::C
                 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;
index 099e5e6..c40811c 100755 (executable)
@@ -2,7 +2,7 @@
 #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
 {
@@ -36,16 +36,12 @@ 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
@@ -63,81 +59,197 @@ public:
 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()
@@ -147,33 +259,94 @@ protected:
 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
 
@@ -183,9 +356,24 @@ 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.
@@ -201,10 +389,10 @@ public: // 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.
@@ -215,8 +403,8 @@ private:
   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.
    */
@@ -236,9 +424,16 @@ private:
   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.
@@ -257,11 +452,6 @@ private:
   virtual void OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension );
 
   /**
-   * @copydoc Control::OnKeyEvent()
-   */
-  virtual bool OnKeyEvent(const KeyEvent& event);
-
-  /**
    * @copydoc Control::GetNaturalSize()
    */
   virtual Vector3 GetNaturalSize();
@@ -269,93 +459,99 @@ private:
   /**
    * @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
diff --git a/dali-toolkit/internal/controls/popup/popup-style-impl.cpp b/dali-toolkit/internal/controls/popup/popup-style-impl.cpp
deleted file mode 100644 (file)
index 4dba00b..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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
diff --git a/dali-toolkit/internal/controls/popup/popup-style-impl.h b/dali-toolkit/internal/controls/popup/popup-style-impl.h
deleted file mode 100644 (file)
index 34d051a..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-#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__
index ae35484..f482fdd 100644 (file)
@@ -798,6 +798,14 @@ void TableView::OnLayoutNegotiated( float size, Dimension::Type dimension )
   }
 }
 
+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
index 2543b5e..d6ccf4b 100644 (file)
@@ -261,6 +261,11 @@ private: // From Control
    */
   virtual void OnLayoutNegotiated( float size, Dimension::Type dimension );
 
+  /**
+   * @copydoc CustomActorImpl::OnSizeSet( const Vector3& size )
+   */
+  virtual void OnSizeSet( const Vector3& size );
+
 private: // Implementation
 
   /**
index 728a3be..5c72c40 100644 (file)
@@ -240,6 +240,17 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         }
         break;
       }
+      case Toolkit::TextField::Property::MAX_LENGTH:
+      {
+        if( impl.mController )
+        {
+          const int max = value.Get< int >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p MAX_LENGTH %d\n", impl.mController.Get(), max );
+
+          impl.mController->SetMaximumNumberOfCharacters( max );
+        }
+        break;
+      }
       case Toolkit::TextField::Property::EXCEED_POLICY:
       {
         // TODO
@@ -250,7 +261,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         if( impl.mController )
         {
           const std::string alignStr = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %f\n", impl.mController.Get(), alignStr.c_str() );
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
 
           LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
           if( Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
@@ -268,7 +279,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         if( impl.mController )
         {
           const std::string alignStr = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %f\n", impl.mController.Get(), alignStr.c_str() );
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
 
           LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
           if( Scripting::GetEnumeration< LayoutEngine::VerticalAlignment >( alignStr.c_str(),
@@ -346,7 +357,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         if( impl.mDecorator )
         {
           const Vector4 color = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_COLOR %f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
           impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
           impl.RequestTextRelayout();
@@ -358,7 +369,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         if( impl.mDecorator )
         {
           const Vector4 color = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SECONDARY_CURSOR_COLOR %f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
           impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
           impl.RequestTextRelayout();
@@ -393,7 +404,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         if( impl.mDecorator )
         {
           const float duration = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), duration );
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration );
 
           impl.mDecorator->SetCursorBlinkDuration( duration );
         }
@@ -448,7 +459,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
       {
         const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
-        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_IMAGE_LEFT %f\n", impl.mController.Get(), image.GetUrl().c_str() );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_IMAGE_LEFT %s\n", impl.mController.Get(), image.GetUrl().c_str() );
 
         if( impl.mDecorator )
         {
@@ -460,7 +471,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
       {
         const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
-        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_IMAGE_RIGHT %f\n", impl.mController.Get(), image.GetUrl().c_str() );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_IMAGE_RIGHT %s\n", impl.mController.Get(), image.GetUrl().c_str() );
 
         if( impl.mDecorator )
         {
@@ -472,7 +483,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
       {
         const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
-        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_PRESSED_IMAGE_LEFT %f\n", impl.mController.Get(), image.GetUrl().c_str() );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_PRESSED_IMAGE_LEFT %s\n", impl.mController.Get(), image.GetUrl().c_str() );
 
         if( impl.mDecorator )
         {
@@ -484,7 +495,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
       {
         const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
-        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_PRESSED_IMAGE_RIGHT %f\n", impl.mController.Get(), image.GetUrl().c_str() );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_PRESSED_IMAGE_RIGHT %s\n", impl.mController.Get(), image.GetUrl().c_str() );
 
         if( impl.mDecorator )
         {
@@ -496,7 +507,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
       {
         const Vector4 color = value.Get< Vector4 >();
-        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SELECTION_HIGHLIGHT_COLOR %f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SELECTION_HIGHLIGHT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
         if( impl.mDecorator )
         {
@@ -517,17 +528,6 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         }
         break;
       }
-      case Toolkit::TextField::Property::MAX_LENGTH:
-      {
-        if( impl.mController )
-        {
-          const int max = value.Get< int >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p MAX_LENGTH %d\n", impl.mController.Get(), max );
-
-          impl.mController->SetMaximumNumberOfCharacters( max );
-        }
-        break;
-      }
       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
       {
         const Property::Map map = value.Get<Property::Map>();
@@ -610,6 +610,14 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         }
         break;
       }
+      case Toolkit::TextField::Property::MAX_LENGTH:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetMaximumNumberOfCharacters();
+        }
+        break;
+      }
       case Toolkit::TextField::Property::EXCEED_POLICY:
       {
         value = impl.mExceedPolicy;
@@ -816,14 +824,6 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         }
         break;
       }
-      case Toolkit::TextField::Property::MAX_LENGTH:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->GetMaximumNumberOfCharacters();
-        }
-        break;
-      }
       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
       {
         break;
index bc54dca..0c47877 100644 (file)
 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/animation/animation.h>
 #include <dali/public-api/images/nine-patch-image.h>
 #include <dali/public-api/images/resource-image.h>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/math/vector4.h>
 #include <dali/devel-api/object/type-registry-helper.h>
+
 #include <libintl.h>
 #include <cfloat>
 
@@ -79,7 +81,7 @@ const char* const OPTION_CLIPBOARD("option-clipboard");
 
 BaseHandle Create()
 {
-  return Toolkit::TextSelectionPopup::New( Toolkit::TextSelectionPopup::NONE, NULL );
+  return Toolkit::TextSelectionPopup::New( NULL );
 }
 
 // Setup properties, signals and actions using the type-registry.
@@ -101,14 +103,15 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-divider-color",
 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-icon-color", VECTOR4, POPUP_ICON_COLOR )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-pressed-color", VECTOR4, POPUP_PRESSED_COLOR )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-pressed-image", STRING, POPUP_PRESSED_IMAGE )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-fade-in-duration", FLOAT, POPUP_FADE_IN_DURATION )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popup-fade-out-duration", FLOAT, POPUP_FADE_OUT_DURATION )
 
 DALI_TYPE_REGISTRATION_END()
 
 } // namespace
 
 
-Dali::Toolkit::TextSelectionPopup TextSelectionPopup::New( Toolkit::TextSelectionPopup::Buttons buttonsToEnable,
-                                                           TextSelectionPopupCallbackInterface* callbackInterface )
+Dali::Toolkit::TextSelectionPopup TextSelectionPopup::New( TextSelectionPopupCallbackInterface* callbackInterface )
 {
    // Create the implementation, temporarily owned by this handle on stack
   IntrusivePtr< TextSelectionPopup > impl = new TextSelectionPopup( callbackInterface );
@@ -116,7 +119,6 @@ Dali::Toolkit::TextSelectionPopup TextSelectionPopup::New( Toolkit::TextSelectio
   // Pass ownership to CustomActor handle
   Dali::Toolkit::TextSelectionPopup handle( *impl );
 
-  impl->mEnabledButtons = buttonsToEnable;
   // Second-phase init of the implementation
   // This can only be done after the CustomActor connection has been made...
   impl->Initialize();
@@ -210,6 +212,16 @@ void TextSelectionPopup::SetProperty( BaseObject* object, Property::Index index,
         impl.SetPressedImage( value.Get< std::string >() );
         break;
       }
+      case Toolkit::TextSelectionPopup::Property::POPUP_FADE_IN_DURATION:
+      {
+        impl.mFadeInDuration = value.Get < float >();
+        break;
+      }
+      case Toolkit::TextSelectionPopup::Property::POPUP_FADE_OUT_DURATION:
+      {
+        impl.mFadeOutDuration = value.Get < float >();
+        break;
+      }
     } // switch
   } // TextSelectionPopup
 }
@@ -305,11 +317,27 @@ Property::Value TextSelectionPopup::GetProperty( BaseObject* object, Property::I
         value = impl.GetPressedImage();
         break;
       }
+      case Toolkit::TextSelectionPopup::Property::POPUP_FADE_IN_DURATION:
+      {
+        value = impl.mFadeInDuration;
+        break;
+      }
+      case Toolkit::TextSelectionPopup::Property::POPUP_FADE_OUT_DURATION:
+      {
+        value = impl.mFadeOutDuration;
+        break;
+      }
     } // switch
   }
   return value;
 }
 
+void TextSelectionPopup::EnableButtons( Toolkit::TextSelectionPopup::Buttons buttonsToEnable )
+{
+  mEnabledButtons = buttonsToEnable;
+  mButtonsChanged = true;
+}
+
 void TextSelectionPopup::RaiseAbove( Layer target )
 {
   if( mToolbar )
@@ -320,12 +348,36 @@ void TextSelectionPopup::RaiseAbove( Layer target )
 
 void TextSelectionPopup::ShowPopup()
 {
-  AddPopupOptionsToToolbar( mShowIcons, mShowCaptions );
+  if ( !mPopupShowing || mButtonsChanged )
+  {
+    Actor self = Self();
+    AddPopupOptionsToToolbar( mShowIcons, mShowCaptions );
+
+    Animation animation = Animation::New( mFadeInDuration );
+    animation.AnimateTo( Property(self, Actor::Property::COLOR_ALPHA), 1.0f  );
+    animation.Play();
+    mPopupShowing = true;
+  }
+}
+
+void TextSelectionPopup::HidePopup()
+{
+  if ( mPopupShowing )
+  {
+    mPopupShowing = false;
+    Actor self = Self();
+    Animation animation = Animation::New( mFadeOutDuration );
+    animation.AnimateTo( Property(self, Actor::Property::COLOR_ALPHA), 0.0f  );
+    animation.FinishedSignal().Connect( this, &TextSelectionPopup::HideAnimationFinished );
+    animation.Play();
+  }
 }
 
 void TextSelectionPopup::OnInitialize()
 {
-  CreatePopup();
+  Actor self = Self();
+  self.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
+  self.SetProperty( Actor::Property::COLOR_ALPHA, 0.0f );
 }
 
 void TextSelectionPopup::OnStageConnection( int depth )
@@ -336,6 +388,15 @@ void TextSelectionPopup::OnStageConnection( int depth )
   // TextSelectionToolbar::OnStageConnection() will set the depths of all the popup's components.
 }
 
+void TextSelectionPopup::HideAnimationFinished( Animation& animation )
+{
+  Actor self = Self();
+  if ( !mPopupShowing ) // During the Hide/Fade animation there could be a call to Show the Popup again, mPopupShowing will be true in this case.
+  {
+    UnparentAndReset( self );  // Popup needs to be shown so do not unparent
+  }
+}
+
 bool TextSelectionPopup::OnCutButtonPressed( Toolkit::Button button )
 {
   if( mCallbackInterface )
@@ -402,6 +463,7 @@ void TextSelectionPopup::SetDimensionToCustomise( const PopupCustomisations& set
   {
     case POPUP_MAXIMUM_SIZE :
     {
+      mPopupMaxSize = dimension;
       if ( mToolbar )
       {
         mToolbar.SetProperty( Toolkit::TextSelectionToolbar::Property::MAX_SIZE, dimension );
@@ -438,7 +500,14 @@ Size TextSelectionPopup::GetDimensionToCustomise( const PopupCustomisations& set
   {
     case POPUP_MAXIMUM_SIZE :
     {
-      return mToolbar.GetProperty( Toolkit::TextSelectionToolbar::Property::MAX_SIZE ).Get< Vector2 >();
+      if ( mToolbar )
+      {
+        return mToolbar.GetProperty( Toolkit::TextSelectionToolbar::Property::MAX_SIZE ).Get< Vector2 >();
+      }
+      else
+      {
+        return mPopupMaxSize;
+      }
     }
     case OPTION_MAXIMUM_SIZE :
     {
@@ -677,6 +746,26 @@ std::string TextSelectionPopup::GetPressedImage() const
 
  void TextSelectionPopup::AddPopupOptionsToToolbar( bool showIcons, bool showCaptions )
  {
+   CreateOrderedListOfPopupOptions();
+
+   mButtonsChanged = false;
+   UnparentAndReset( mToolbar);
+
+   if( !mToolbar )
+   {
+     Actor self = Self();
+     mToolbar = Toolkit::TextSelectionToolbar::New();
+     if ( mPopupMaxSize != Vector2::ZERO ) // If PopupMaxSize property set then apply to Toolbar. Toolbar currently is not retriving this from json
+     {
+       mToolbar.SetProperty( Toolkit::TextSelectionToolbar::Property::MAX_SIZE, mPopupMaxSize );
+     }
+     mToolbar.SetParentOrigin( ParentOrigin::CENTER );
+#ifdef DECORATOR_DEBUG
+     mToolbar.SetName("TextSelectionToolbar");
+#endif
+     self.Add( mToolbar );
+   }
+
    // Iterate list of buttons and add active ones to Toolbar
    std::size_t numberOfOptionsRequired =  GetNumberOfEnabledOptions();
    std::size_t numberOfOptionsAdded = 0u;
@@ -691,23 +780,12 @@ std::string TextSelectionPopup::GetPressedImage() const
    }
  }
 
- void TextSelectionPopup::CreatePopup()
- {
-   Actor self = Self();
-   CreateOrderedListOfPopupOptions();
-   self.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
-
-   if( !mToolbar )
-   {
-     mToolbar = Toolkit::TextSelectionToolbar::New();
-     mToolbar.SetParentOrigin( ParentOrigin::CENTER );
-     self.Add( mToolbar );
-   }
- }
-
 TextSelectionPopup::TextSelectionPopup( TextSelectionPopupCallbackInterface* callbackInterface )
 : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
   mToolbar(),
+  mPopupMaxSize(),
+  mOptionMaxSize(),
+  mOptionMinSize(),
   mOptionDividerSize(),
   mEnabledButtons( Toolkit::TextSelectionPopup::NONE ),
   mCallbackInterface( callbackInterface ),
@@ -720,8 +798,12 @@ TextSelectionPopup::TextSelectionPopup( TextSelectionPopupCallbackInterface* cal
   mCopyOptionPriority ( 3 ),
   mPasteOptionPriority ( 5 ),
   mClipboardOptionPriority( 6 ),
+  mFadeInDuration(0.0f),
+  mFadeOutDuration(0.0f),
   mShowIcons( false ),
-  mShowCaptions( true )
+  mShowCaptions( true ),
+  mPopupShowing( false ),
+  mButtonsChanged( false )
 {
 }
 
index 8e0141a..e4cef74 100644 (file)
@@ -97,12 +97,10 @@ public:
 
   /**
    * @brief New constructor with provided buttons to enable.
-   * @param[in] buttonsToEnable bit mask of buttons to enable
    * @param[in] callbackInterface The text popup callback interface which receives the button click callbacks.
    * @return A handle to the TextSelectionPopup control.
    */
-  static Toolkit::TextSelectionPopup New( Toolkit::TextSelectionPopup::Buttons buttonsToEnable,
-                                          TextSelectionPopupCallbackInterface* callbackInterface );
+  static Toolkit::TextSelectionPopup New( TextSelectionPopupCallbackInterface* callbackInterface );
 
   // Properties
 
@@ -124,6 +122,11 @@ public:
   static Property::Value GetProperty( BaseObject* object, Property::Index index );
 
   /**
+   * @copydoc Toolkit::EnableButtons
+   */
+  void EnableButtons( Toolkit::TextSelectionPopup::Buttons buttonsToEnable );
+
+  /**
    * @copydoc Toolkit::TextSelectionPopup::RaiseAbove()
    */
   void RaiseAbove( Layer target );
@@ -133,6 +136,11 @@ public:
    */
   void ShowPopup();
 
+  /**
+   * @copydoc Toolkiut::TextSelectionPopup::HidePopup()
+   */
+  void HidePopup();
+
 private: // From Control
 
   /**
@@ -147,6 +155,8 @@ private: // From Control
 
 private: // Implementation
 
+  void HideAnimationFinished( Animation& animation );
+
   /**
    * @brief When the cut button is pressed.
    * @param[in] button the button pressed
@@ -242,8 +252,6 @@ private: // Implementation
 
   void AddPopupOptionsToToolbar(  bool showIcons, bool showCaptions );
 
-  void CreatePopup();
-
   /**
    * Construct a new TextField.
    */
@@ -275,6 +283,7 @@ private: // Data
   Image mSelectIconImage;
   Image mSelectAllIconImage;
 
+  Size mPopupMaxSize;                   // Maximum size of the Popup
   Size mOptionMaxSize;                  // Maximum size of an Option button
   Size mOptionMinSize;                  // Minimum size of an Option button
   Size mOptionDividerSize;              // Size of divider line
@@ -296,9 +305,13 @@ private: // Data
   std::size_t mCopyOptionPriority;      // Position of Copy button
   std::size_t mPasteOptionPriority;     // Position of Paste button
   std::size_t mClipboardOptionPriority; // Position of Clipboard button
+  float mFadeInDuration;                // Duration of the animation to fade in the Popup
+  float mFadeOutDuration;               // Duration of the animation to fade out the Popup
 
   bool mShowIcons:1; // Flag to show icons
   bool mShowCaptions:1; // Flag to show text captions
+  bool mPopupShowing:1; // Flag to indicate Popup showing
+  bool mButtonsChanged:1; // Flag to indicate the Popup Buttons have changed
 
 };
 
index 78d8f5f..eb6efe4 100644 (file)
@@ -255,7 +255,7 @@ void TextSelectionToolbar::RaiseAbove( Layer target )
 }
 
 TextSelectionToolbar::TextSelectionToolbar()
-: Control( ControlBehaviour( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ) ),
+: Control( ControlBehaviour( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ) ),
   mMaxSize (),
   mIndexInTable( 0 ),
   mDividerIndexes()
index a93f983..3b04cf6 100644 (file)
@@ -24,8 +24,8 @@ toolkit_src_files = \
    $(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 \
index ed67d72..bdfc356 100644 (file)
@@ -322,7 +322,7 @@ struct Decorator::Impl : public ConnectionTracker
         CreateGrabHandle();
 
         grabHandle.actor.SetPosition( position.x,
-                                      grabHandle.lineHeight ); // TODO : Fix for multiline.
+                                      position.y + grabHandle.lineHeight ); // TODO : Fix for multiline.
       }
       grabHandle.actor.SetVisible( isVisible );
     }
@@ -351,13 +351,13 @@ struct Decorator::Impl : public ConnectionTracker
         if( isPrimaryVisible )
         {
           primary.actor.SetPosition( primaryPosition.x,
-                                     primary.lineHeight ); // TODO : Fix for multiline.
+                                     primaryPosition.y + primary.lineHeight ); // TODO : Fix for multiline.
         }
 
         if( isSecondaryVisible )
         {
           secondary.actor.SetPosition( secondaryPosition.x,
-                                       secondary.lineHeight ); // TODO : Fix for multiline.
+                                       secondaryPosition.y + secondary.lineHeight ); // TODO : Fix for multiline.
         }
       }
       primary.actor.SetVisible( isPrimaryVisible );
@@ -384,18 +384,13 @@ struct Decorator::Impl : public ConnectionTracker
 
     if( mActiveCopyPastePopup )
     {
-      if( !mCopyPastePopup.actor.GetParent() )
-      {
-        mActiveLayer.Add( mCopyPastePopup.actor );
-      }
-
-      mCopyPastePopup.actor.RaiseAbove( mActiveLayer );
+      ShowPopup();
     }
     else
     {
       if( mCopyPastePopup.actor )
       {
-        mCopyPastePopup.actor.Unparent();
+        mCopyPastePopup.actor.HidePopup();
       }
     }
   }
@@ -411,6 +406,22 @@ struct Decorator::Impl : public ConnectionTracker
     DeterminePositionPopup();
   }
 
+  void ShowPopup()
+  {
+    if ( !mCopyPastePopup.actor )
+    {
+      return;
+    }
+
+    if( !mCopyPastePopup.actor.GetParent() )
+    {
+      mActiveLayer.Add( mCopyPastePopup.actor );
+    }
+
+    mCopyPastePopup.actor.RaiseAbove( mActiveLayer );
+    mCopyPastePopup.actor.ShowPopup();
+  }
+
   void DeterminePositionPopup()
   {
     if ( !mActiveCopyPastePopup )
@@ -445,7 +456,6 @@ struct Decorator::Impl : public ConnectionTracker
   void PopupRelayoutComplete( Actor actor )
   {
     // Size negotiation for CopyPastePopup complete so can get the size and constrain position within bounding box.
-    mCopyPastePopup.actor.OnRelayoutSignal().Disconnect( this, &Decorator::Impl::PopupRelayoutComplete  );
 
     DeterminePositionPopup();
   }
@@ -1498,20 +1508,17 @@ void Decorator::SetEnabledPopupButtons( TextSelectionPopup::Buttons& enabledButt
 {
    mImpl->mEnabledPopupButtons = enabledButtonsBitMask;
 
-   UnparentAndReset( mImpl->mCopyPastePopup.actor );
-   mImpl->mCopyPastePopup.actor = TextSelectionPopup::New( mImpl->mEnabledPopupButtons,
-                                                           &mImpl->mTextSelectionPopupCallbackInterface );
+   if ( !mImpl->mCopyPastePopup.actor )
+   {
+     mImpl->mCopyPastePopup.actor = TextSelectionPopup::New( &mImpl->mTextSelectionPopupCallbackInterface );
 #ifdef DECORATOR_DEBUG
-   mImpl->mCopyPastePopup.actor.SetName("mCopyPastePopup");
+     mImpl->mCopyPastePopup.actor.SetName("mCopyPastePopup");
 #endif
-   mImpl->mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER );
-   mImpl->mCopyPastePopup.actor.OnRelayoutSignal().Connect( mImpl,  &Decorator::Impl::PopupRelayoutComplete  ); // Position popup after size negotiation
-
-   if( mImpl->mActiveLayer )
-   {
-     mImpl->mActiveLayer.Add( mImpl->mCopyPastePopup.actor );
-     mImpl->mCopyPastePopup.actor.ShowPopup();
+     mImpl->mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER );
+     mImpl->mCopyPastePopup.actor.OnRelayoutSignal().Connect( mImpl,  &Decorator::Impl::PopupRelayoutComplete  ); // Position popup after size negotiation
    }
+
+   mImpl->mCopyPastePopup.actor.EnableButtons( mImpl->mEnabledPopupButtons );
 }
 
 TextSelectionPopup::Buttons& Decorator::GetEnabledPopupButtons()
diff --git a/dali-toolkit/internal/text/glyph-run.h b/dali-toolkit/internal/text/glyph-run.h
new file mode 100644 (file)
index 0000000..47ebfb8
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef __DALI_TOOLKIT_TEXT_GLYPH_RUN_H__
+#define __DALI_TOOLKIT_TEXT_GLYPH_RUN_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 <dali-toolkit/internal/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief A run of consecutive glyphs.
+ */
+struct GlyphRun
+{
+  GlyphIndex glyphIndex;     ///< Index to the first glyph.
+  Length     numberOfGlyphs; ///< Number of glyphs in the run.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_GLYPH_RUN_H__
index 25ea95a..5a28904 100644 (file)
@@ -527,11 +527,11 @@ struct LayoutEngine::Impl
 
           penY -= layout.ascender - lineRun.descender;
 
-          ellipsisLayout.glyphIndex = lineRun.glyphIndex;
+          ellipsisLayout.glyphIndex = lineRun.glyphRun.glyphIndex;
         }
         else
         {
-          lineRun.glyphIndex = 0u;
+          lineRun.glyphRun.glyphIndex = 0u;
           ellipsisLayout.glyphIndex = 0u;
         }
 
@@ -540,7 +540,7 @@ struct LayoutEngine::Impl
                              currentParagraphDirection,
                              true );
 
-        lineRun.numberOfGlyphs = ellipsisLayout.numberOfGlyphs;
+        lineRun.glyphRun.numberOfGlyphs = ellipsisLayout.numberOfGlyphs;
         lineRun.characterRun.characterIndex = ellipsisLayout.characterIndex;
         lineRun.characterRun.numberOfCharacters = ellipsisLayout.numberOfCharacters;
         lineRun.width = ellipsisLayout.length;
@@ -553,10 +553,10 @@ struct LayoutEngine::Impl
         actualSize.width = layoutParameters.boundingBox.width;
         actualSize.height += ( lineRun.ascender + -lineRun.descender );
 
-        SetGlyphPositions( layoutParameters.glyphsBuffer + lineRun.glyphIndex,
+        SetGlyphPositions( layoutParameters.glyphsBuffer + lineRun.glyphRun.glyphIndex,
                            ellipsisLayout.numberOfGlyphs,
                            penY,
-                           glyphPositions.Begin() + lineRun.glyphIndex );
+                           glyphPositions.Begin() + lineRun.glyphRun.glyphIndex );
 
         if( 0u != numberOfLines )
         {
@@ -576,8 +576,8 @@ struct LayoutEngine::Impl
         const bool isLastLine = index + layout.numberOfGlyphs == layoutParameters.totalNumberOfGlyphs;
 
         LineRun lineRun;
-        lineRun.glyphIndex = index;
-        lineRun.numberOfGlyphs = layout.numberOfGlyphs;
+        lineRun.glyphRun.glyphIndex = index;
+        lineRun.glyphRun.numberOfGlyphs = layout.numberOfGlyphs;
         lineRun.characterRun.characterIndex = layout.characterIndex;
         lineRun.characterRun.numberOfCharacters = layout.numberOfCharacters;
         if( isLastLine && !layoutParameters.isLastNewParagraph )
@@ -635,8 +635,8 @@ struct LayoutEngine::Impl
           mFontClient.GetFontMetrics( glyphInfo.fontId, fontMetrics );
 
           LineRun lineRun;
-          lineRun.glyphIndex = 0u;
-          lineRun.numberOfGlyphs = 0u;
+          lineRun.glyphRun.glyphIndex = 0u;
+          lineRun.glyphRun.numberOfGlyphs = 0u;
           lineRun.characterRun.characterIndex = 0u;
           lineRun.characterRun.numberOfCharacters = 0u;
           lineRun.width = 0.f;
index 6909182..52df79e 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/character-run.h>
+#include <dali-toolkit/internal/text/glyph-run.h>
 
 namespace Dali
 {
@@ -35,9 +36,8 @@ namespace Text
  */
 struct LineRun
 {
-  GlyphIndex         glyphIndex;      ///< The initial glyph index.
-  Length             numberOfGlyphs;  ///< The number of glyphs of the run.
-  CharacterRun       characterRun;    ///< The initial character and the number of characters.
+  GlyphRun           glyphRun;        ///< The initial glyph index and the number of glyphs of the run.
+  CharacterRun       characterRun;    ///< The initial character index and the number of characters of the run.
   float              width;           ///< The line's width.
   float              ascender;        ///< The line's ascender.
   float              descender;       ///< The line's descender.
index ce937a8..5ba6740 100644 (file)
@@ -1,4 +1,3 @@
-
 #ifndef __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
 #define __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
 
@@ -185,5 +184,4 @@ inline Internal::AtlasGlyphManager& GetImplementation(Toolkit::AtlasGlyphManager
 
 } // namespace Dali
 
-
- #endif // __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
+#endif // __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
index 2e94ce1..a4fc1d8 100644 (file)
@@ -30,6 +30,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/internal/text/glyph-run.h>
 #include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h>
 #include <dali-toolkit/internal/text/text-view.h>
 
@@ -72,6 +73,10 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     FrameBufferImage mBuffer;
   };
 
+  /**
+   * brief Struct used to generate the underline mesh.
+   * There is one Extent per line of text.
+   */
   struct Extent
   {
     Extent()
@@ -143,8 +148,30 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     mQuadIndexFormat[ "indices" ] = Property::INTEGER;
   }
 
+  bool IsGlyphUnderlined( GlyphIndex index,
+                          const Vector<GlyphRun>& underlineRuns )
+  {
+    // TODO: At the moment it works because we always traverse the glyphs starting from the beginning
+    //       and there is only one glyph run! If there are more they should be ordered.
+
+    for( Vector<GlyphRun>::ConstIterator it = underlineRuns.Begin(),
+           endIt = underlineRuns.End();
+           it != endIt;
+         ++it )
+    {
+      const GlyphRun& run = *it;
+
+      if( ( run.glyphIndex <= index ) && ( index < run.glyphIndex + run.numberOfGlyphs ) )
+      {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
   void AddGlyphs( Text::ViewInterface& view,
-                  const std::vector<Vector2>& positions,
+                  const Vector<Vector2>& positions,
                   const Vector<GlyphInfo>& glyphs,
                   int depth )
   {
@@ -155,18 +182,29 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     mDepth = depth;
 
     const Vector2& actorSize( view.GetControlSize() );
-    Vector2 halfActorSize( actorSize * 0.5f );
+    const Vector2 halfActorSize( actorSize * 0.5f );
     const Vector4& textColor( view.GetTextColor() );
     const Vector2& shadowOffset( view.GetShadowOffset() );
     const Vector4& shadowColor( view.GetShadowColor() );
-    bool underlineEnabled( view.IsUnderlineEnabled() );
+    const bool underlineEnabled( view.IsUnderlineEnabled() );
     const Vector4& underlineColor( view.GetUnderlineColor() );
-    float underlineHeight( view.GetUnderlineHeight() );
+    const float underlineHeight( view.GetUnderlineHeight() );
+
+    // Get the underline runs.
+    const Length numberOfUnderlineRuns = view.GetNumberOfUnderlineRuns();
+    Vector<GlyphRun> underlineRuns;
+    underlineRuns.Resize( numberOfUnderlineRuns );
+    view.GetUnderlineRuns( underlineRuns.Begin(),
+                           0u,
+                           numberOfUnderlineRuns );
+
+    bool thereAreUnderlinedGlyphs = false;
 
     float currentUnderlinePosition = ZERO;
     float currentUnderlineThickness = underlineHeight;
     uint32_t currentBlockSize = 0;
     FontId lastFontId = 0;
+    FontId lastUnderlinedFontId = 0;
     Style style = STYLE_NORMAL;
 
     if ( fabsf( shadowOffset.x ) > Math::MACHINE_EPSILON_1 || fabsf( shadowOffset.y ) > Math::MACHINE_EPSILON_1 )
@@ -179,16 +217,20 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     // Avoid emptying mTextCache (& removing references) until after incremented references for the new text
     Vector< TextCacheEntry > newTextCache;
     const GlyphInfo* const glyphsBuffer = glyphs.Begin();
+    const Vector2* const positionsBuffer = positions.Begin();
 
     for( uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i )
     {
       const GlyphInfo& glyph = *( glyphsBuffer + i );
 
+      const bool underlineGlyph = underlineEnabled || IsGlyphUnderlined( i, underlineRuns );
+      thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || underlineGlyph;
+
       // No operation for white space
       if ( glyph.width && glyph.height )
       {
         // Are we still using the same fontId as previous
-        if ( glyph.fontId != lastFontId )
+        if ( underlineGlyph && ( glyph.fontId != lastUnderlinedFontId ) )
         {
           // We need to fetch fresh font underline metrics
           FontMetrics fontMetrics;
@@ -221,7 +263,9 @@ struct AtlasRenderer::Impl : public ConnectionTracker
             // Move offset down by one ( EFL behavior )
             currentUnderlinePosition = ONE;
           }
-        }
+
+          lastUnderlinedFontId = glyph.fontId;
+        } // underline
 
         if ( !mGlyphManager.Cached( glyph.fontId, glyph.index, slot ) )
         {
@@ -277,7 +321,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
         }
 
         // Move the origin (0,0) of the mesh to the center of the actor
-        Vector2 position = positions[ i ] - halfActorSize;
+        Vector2 position = *( positionsBuffer + i ) - halfActorSize;
 
         // Generate mesh data for this quad, plugging in our supplied position
         AtlasManager::Mesh2D newMesh;
@@ -293,6 +337,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
                         extents,
                         textColor,
                         position.y + glyph.yBearing,
+                        underlineGlyph,
                         currentUnderlinePosition,
                         currentUnderlineThickness,
                         slot );
@@ -304,7 +349,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     RemoveText();
     mTextCache.Swap( newTextCache );
 
-    if ( underlineEnabled )
+    if( thereAreUnderlinedGlyphs )
     {
       // Check to see if any of the text needs an underline
       GenerateUnderlines( meshContainer, extents, underlineColor, textColor );
@@ -320,7 +365,9 @@ struct AtlasRenderer::Impl : public ConnectionTracker
         // Create an effect if necessary
         if ( style == STYLE_DROP_SHADOW )
         {
-          actor.Add( GenerateShadow( *mIt, actorSize, shadowOffset, shadowColor ) );
+          Actor shadowActor = GenerateShadow( *mIt, actorSize, shadowOffset, shadowColor );
+          shadowActor.Add( actor );
+          actor = shadowActor;
         }
 
         if( mActor )
@@ -396,6 +443,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
                        Vector< Extent >& extents,
                        const Vector4& color,
                        float baseLine,
+                       bool underlineGlyph,
                        float underlinePosition,
                        float underlineThickness,
                        AtlasManager::AtlasSlot& slot )
@@ -416,14 +464,19 @@ struct AtlasRenderer::Impl : public ConnectionTracker
         {
           // Stitch the mesh to the existing mesh and adjust any extents
           mGlyphManager.StitchMesh( mIt->mMesh, newMesh );
-          AdjustExtents( extents,
-                         meshContainer,
-                         index,
-                         left,
-                         right,
-                         baseLine,
-                         underlinePosition,
-                         underlineThickness );
+
+          if( underlineGlyph )
+          {
+            AdjustExtents( extents,
+                           meshContainer,
+                           index,
+                           left,
+                           right,
+                           baseLine,
+                           underlinePosition,
+                           underlineThickness );
+          }
+
           return;
         }
       }
@@ -435,16 +488,18 @@ struct AtlasRenderer::Impl : public ConnectionTracker
       meshRecord.mColor = color;
       meshContainer.push_back( meshRecord );
 
-      // Adjust extents for this new meshrecord
-      AdjustExtents( extents,
-                     meshContainer,
-                     meshContainer.size() - 1u,
-                     left,
-                     right,
-                     baseLine,
-                     underlinePosition,
-                     underlineThickness );
-
+      if( underlineGlyph )
+      {
+        // Adjust extents for this new meshrecord
+        AdjustExtents( extents,
+                       meshContainer,
+                       meshContainer.size() - 1u,
+                       left,
+                       right,
+                       baseLine,
+                       underlinePosition,
+                       underlineThickness );
+      }
     }
   }
 
@@ -659,7 +714,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     Dali::Renderer renderer = Dali::Renderer::New( quadGeometry, material );
 
     // Ensure shadow is behind the text...
-    renderer.SetDepthIndex( CONTENT_DEPTH_INDEX + mDepth - 1 );
+    renderer.SetDepthIndex( CONTENT_DEPTH_INDEX + mDepth );
     Actor actor = Actor::New();
     actor.AddRenderer( renderer );
     actor.SetParentOrigin( ParentOrigin::CENTER ); // Keep all of the origins aligned
@@ -692,7 +747,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     subActor.AddRenderer( normRenderer );
     subActor.SetParentOrigin( ParentOrigin::CENTER ); // Keep all of the origins aligned
     subActor.SetSize( actorSize );
-    subActor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
     subActor.SetColor( shadowColor );
 
     // Create a render task to render the effect
@@ -756,15 +810,15 @@ Actor AtlasRenderer::Render( Text::ViewInterface& view, int depth )
     Vector<GlyphInfo> glyphs;
     glyphs.Resize( numberOfGlyphs );
 
-    std::vector<Vector2> positions;
-    positions.resize( numberOfGlyphs );
+    Vector<Vector2> positions;
+    positions.Resize( numberOfGlyphs );
 
     numberOfGlyphs = view.GetGlyphs( glyphs.Begin(),
-                                     &positions[0],
+                                     positions.Begin(),
                                      0u,
                                      numberOfGlyphs );
     glyphs.Resize( numberOfGlyphs );
-    positions.resize( numberOfGlyphs );
+    positions.Resize( numberOfGlyphs );
 
     mImpl->AddGlyphs( view,
                       positions,
index 6552ce8..9d53ae6 100644 (file)
@@ -1000,7 +1000,7 @@ void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart
       mEventData->mDecorator->AddHighlight( xPosition,
                                             offset.y,
                                             xPosition + static_cast<float>( numberOfCharacters ) * glyphAdvance,
-                                            height );
+                                            offset.y + height );
 
       splitStartGlyph = false;
       continue;
@@ -1025,14 +1025,17 @@ void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart
       mEventData->mDecorator->AddHighlight( xPosition,
                                             offset.y,
                                             xPosition + static_cast<float>( interGlyphIndex ) * glyphAdvance,
-                                            height );
+                                            offset.y + height );
 
       splitEndGlyph = false;
       continue;
     }
 
     const float xPosition = position.x - glyph.xBearing + offset.x;
-    mEventData->mDecorator->AddHighlight( xPosition, offset.y, xPosition + glyph.advance, height );
+    mEventData->mDecorator->AddHighlight( xPosition,
+                                          offset.y,
+                                          xPosition + glyph.advance,
+                                          offset.y + height );
   }
 
   CursorInfo primaryCursorInfo;
index 9d0cf87..a843feb 100644 (file)
@@ -1198,6 +1198,9 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
                  this, text.c_str(), (COMMIT == type ? "COMMIT" : "PRE_EDIT"),
                  mImpl->mEventData->mPrimaryCursorPosition, mImpl->mEventData->mPreEditFlag, mImpl->mEventData->mPreEditStartPosition, mImpl->mEventData->mPreEditLength );
 
+  // TODO: At the moment the underline runs are only for pre-edit.
+  mImpl->mVisualModel->mUnderlineRuns.Clear();
+
   Vector<Character> utf32Characters;
   Length characterCount( 0u );
 
@@ -1255,7 +1258,7 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
       }
       else // PRE_EDIT
       {
-        if( ! mImpl->mEventData->mPreEditFlag )
+        if( !mImpl->mEventData->mPreEditFlag )
         {
           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Entered PreEdit state" );
 
@@ -1266,6 +1269,22 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
         mImpl->mEventData->mPreEditLength = utf32Characters.Count();
         mImpl->mEventData->mPreEditFlag = true;
 
+        // Add the underline for the pre-edit text.
+        const GlyphIndex* const charactersToGlyphBuffer = mImpl->mVisualModel->mCharactersToGlyph.Begin();
+        const Length* const glyphsPerCharacterBuffer = mImpl->mVisualModel->mGlyphsPerCharacter.Begin();
+
+        const GlyphIndex glyphStart = *( charactersToGlyphBuffer + mImpl->mEventData->mPreEditStartPosition );
+        const CharacterIndex lastPreEditCharacter = mImpl->mEventData->mPreEditStartPosition + ( ( mImpl->mEventData->mPreEditLength > 0u ) ? mImpl->mEventData->mPreEditLength - 1u : 0u );
+        const Length numberOfGlyphsLastCharacter = *( glyphsPerCharacterBuffer + lastPreEditCharacter );
+        const GlyphIndex glyphEnd = *( charactersToGlyphBuffer + lastPreEditCharacter ) + ( numberOfGlyphsLastCharacter > 1u ? numberOfGlyphsLastCharacter - 1u : 0u );
+
+        GlyphRun underlineRun;
+        underlineRun.glyphIndex = glyphStart;
+        underlineRun.numberOfGlyphs = 1u + glyphEnd - glyphStart;
+
+        // TODO: At the moment the underline runs are only for pre-edit.
+        mImpl->mVisualModel->mUnderlineRuns.PushBack( underlineRun );
+
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "mPreEditStartPosition %d mPreEditLength %d\n", mImpl->mEventData->mPreEditStartPosition, mImpl->mEventData->mPreEditLength );
       }
     }
index f93ffd7..85888b0 100644 (file)
@@ -51,6 +51,7 @@ typedef TextAbstraction::CharacterDirection CharacterDirection; ///< The charact
 typedef uint32_t                         GlyphIndex;            ///< An index into an array of glyphs.
 typedef uint32_t                         ScriptRunIndex;        ///< An index into an array of script runs.
 typedef uint32_t                         FontRunIndex;          ///< An index into an array of font runs.
+typedef uint32_t                         UnderlineRunIndex;     ///< An index into an array of underline runs.
 typedef uint32_t                         BidirectionalRunIndex; ///< An index into an array of font runs.
 typedef uint32_t                         LineIndex;             ///< An index into an array of lines.
 
index f4bd3f2..99f8a8c 100644 (file)
@@ -93,7 +93,7 @@ std::ostream& operator<< (std::ostream& o, const Vector<LineRun>& lineRuns)
   for( unsigned int i=0; i<lineRuns.Count(); ++i )
   {
     // e.g. Print "Line 0 Glyphs: 0->9 Characters: 0->9 (10)" for a ten character run staring from beginning of the model
-    o << "Line " << i << " Glyphs: " << lineRuns[i].glyphIndex << "->" << (lineRuns[i].glyphIndex + lineRuns[i].numberOfGlyphs );
+    o << "Line " << i << " Glyphs: " << lineRuns[i].glyphRun.glyphIndex << "->" << (lineRuns[i].glyphRun.glyphIndex + lineRuns[i].glyphRun.numberOfGlyphs );
     o << " Characters: " << lineRuns[i].characterRun.characterIndex << "->" << (lineRuns[i].characterRun.characterIndex + lineRuns[i].characterRun.numberOfCharacters );
     o << " Width: " << lineRuns[i].width;
     o << " Ascender: " << lineRuns[i].ascender;
index bcc7f22..56439d2 100644 (file)
@@ -33,6 +33,8 @@ namespace Toolkit
 namespace Text
 {
 
+struct GlyphRun;
+
 /**
  * @brief Abstract interface to provide the information necessary displaying text.
  *
@@ -129,6 +131,23 @@ public:
    */
   virtual float GetUnderlineHeight() const = 0;
 
+  /**
+   * @brief Retrieves the number of underline runs.
+   *
+   * @return The number of underline runs.
+   */
+  virtual Length GetNumberOfUnderlineRuns() const = 0;
+
+  /**
+   * @brief Retrieves the underline runs.
+   *
+   * @param[out] underlineRuns Pointer to a buffer where the underline runs are copied.
+   * @param[in] index Index of the first underline run to be copied.
+   * @param[in] numberOfRuns Number of underline runs to be copied.
+   */
+  virtual void GetUnderlineRuns( GlyphRun* underlineRuns,
+                                 UnderlineRunIndex index,
+                                 Length numberOfRuns ) const = 0;
 };
 
 } // namespace Text
index 4bee1c2..ea074fa 100644 (file)
@@ -103,7 +103,7 @@ Length View::GetGlyphs( GlyphInfo* glyphs,
       // Otherwise use the given number of glyphs.
       if( lastLine.ellipsis )
       {
-        numberOfLaidOutGlyphs = lastLine.glyphIndex + lastLine.numberOfGlyphs;
+        numberOfLaidOutGlyphs = lastLine.glyphRun.glyphIndex + lastLine.glyphRun.numberOfGlyphs;
       }
       else
       {
@@ -141,7 +141,7 @@ Length View::GetGlyphs( GlyphInfo* glyphs,
       LineRun* line = lineBuffer + lineIndex;
 
       // Index of the last glyph of the line.
-      GlyphIndex lastGlyphIndexOfLine = line->glyphIndex + line->numberOfGlyphs - 1u;
+      GlyphIndex lastGlyphIndexOfLine = line->glyphRun.glyphIndex + line->glyphRun.numberOfGlyphs - 1u;
 
       // Add the alignment offset to the glyph's position.
       for( Length index = 0u; index < numberOfLaidOutGlyphs; ++index )
@@ -156,7 +156,7 @@ Length View::GetGlyphs( GlyphInfo* glyphs,
           if( lineIndex < numberOfLines )
           {
             line = lineBuffer + lineIndex;
-            lastGlyphIndexOfLine = line->glyphIndex + line->numberOfGlyphs - 1u;
+            lastGlyphIndexOfLine = line->glyphRun.glyphIndex + line->glyphRun.numberOfGlyphs - 1u;
           }
         }
       }
@@ -317,6 +317,27 @@ float View::GetUnderlineHeight() const
   return 0.0f;
 }
 
+Length View::GetNumberOfUnderlineRuns() const
+{
+  if( mImpl->mVisualModel )
+  {
+    return mImpl->mVisualModel->mUnderlineRuns.Count();
+  }
+
+  return 0u;
+}
+
+void View::GetUnderlineRuns( GlyphRun* underlineRuns,
+                             UnderlineRunIndex index,
+                             Length numberOfRuns ) const
+{
+  if( mImpl->mVisualModel )
+  {
+    mImpl->mVisualModel->GetUnderlineRuns( underlineRuns,
+                                           index,
+                                           numberOfRuns );
+  }
+}
 
 } // namespace Text
 
index 2ab19b1..058ca9c 100644 (file)
@@ -103,6 +103,18 @@ public:
    */
   virtual float GetUnderlineHeight() const;
 
+  /**
+   * @copydoc Dali::Toolkit::Text::ViewInterface::GetNumberOfUnderlineRuns()
+   */
+  virtual Length GetNumberOfUnderlineRuns() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::ViewInterface::GetUnderlineRuns()
+   */
+  virtual void GetUnderlineRuns( GlyphRun* underlineRuns,
+                                 UnderlineRunIndex index,
+                                 Length numberOfRuns ) const;
+
 private:
 
   // Undefined
index bb7cdde..561beee 100644 (file)
@@ -149,13 +149,13 @@ void VisualModel::GetNumberOfLines( GlyphIndex glyphIndex,
   {
     const LineRun& line = *it;
 
-    if( ( line.glyphIndex + line.numberOfGlyphs > glyphIndex ) &&
-        ( lastGlyphIndex > line.glyphIndex ) )
+    if( ( line.glyphRun.glyphIndex + line.glyphRun.numberOfGlyphs > glyphIndex ) &&
+        ( lastGlyphIndex > line.glyphRun.glyphIndex ) )
     {
       firstLineFound = true;
       ++numberOfLines;
     }
-    else if( lastGlyphIndex <= line.glyphIndex )
+    else if( lastGlyphIndex <= line.glyphRun.glyphIndex )
     {
       // nothing else to do.
       break;
@@ -216,6 +216,15 @@ LineIndex VisualModel::GetLineOfCharacter( CharacterIndex characterIndex )
   return index;
 }
 
+void VisualModel::GetUnderlineRuns( GlyphRun* underlineRuns,
+                                    UnderlineRunIndex index,
+                                    Length numberOfRuns ) const
+{
+  memcpy( underlineRuns,
+          mUnderlineRuns.Begin() + index,
+          numberOfRuns * sizeof( GlyphRun ) );
+}
+
 void VisualModel::SetNaturalSize( const Vector2& size  )
 {
   mNaturalSize = size;
index 32ab386..0717582 100644 (file)
@@ -152,6 +152,19 @@ public:
    */
   LineIndex GetLineOfCharacter( CharacterIndex characterIndex );
 
+  // Underline runs
+
+  /**
+   * @brief Retrieves the underline runs.
+   *
+   * @param[out] underlineRuns Pointer to a buffer where the underline runs are copied.
+   * @param[in] index Index of the first underline run to be copied.
+   * @param[in] numberOfRuns Number of underline runs to be copied.
+   */
+  void GetUnderlineRuns( GlyphRun* underlineRuns,
+                         UnderlineRunIndex index,
+                         Length numberOfRuns ) const;
+
   // Size interface
 
   /**
@@ -300,6 +313,7 @@ public:
   Vector<Length>         mGlyphsPerCharacter;   ///< For each character, the number of glyphs that are shaped.
   Vector<Vector2>        mGlyphPositions;       ///< For each glyph, the position.
   Vector<LineRun>        mLines;                ///< The laid out lines.
+  Vector<GlyphRun>       mUnderlineRuns;        ///< Runs of glyphs that are underlined.
 
   Vector2                mControlSize;           ///< The size of the UI control the decorator is adding it's decorations to.
   Vector4                mTextColor;            ///< The text color
index 5bf8561..2f849bb 100644 (file)
@@ -42,7 +42,16 @@ ImageActor CreateSolidColorActor( const Vector4& color, bool border, const Vecto
   }
 
   const unsigned int bitmapWidth = borderSize * 2 + 2;
-  BufferImage imageData = BufferImage::New( bitmapWidth, bitmapWidth, Pixel::RGBA8888 );
+  bool needAlphaChannel = (color.a < 1.0f) || ( border && borderColor.a < 1.0f );
+  BufferImage imageData;
+  if( needAlphaChannel )
+  {
+    imageData = BufferImage::New( bitmapWidth, bitmapWidth, Pixel::RGBA8888 );
+  }
+  else
+  {
+    imageData = BufferImage::New( bitmapWidth, bitmapWidth, Pixel::RGB888 );
+  }
 
   // Create the image
   PixelBuffer* pixbuf = imageData.GetBuffer();
@@ -65,24 +74,48 @@ ImageActor CreateSolidColorActor( const Vector4& color, bool border, const Vecto
   const unsigned int bottomLeft = bitmapWidth * (borderSize + 1) + borderSize;
   const unsigned int bottomRight = bottomLeft + 1;
 
-  for( size_t i = 0; i < bitmapSize; ++i )
+  if( needAlphaChannel )
   {
-    if( i == topLeft ||
-        i == topRight ||
-        i == bottomLeft ||
-        i == bottomRight )
+    for( size_t i = 0; i < bitmapSize; ++i )
     {
-      pixbuf[i*4+0] = 0xFF * color.r;
-      pixbuf[i*4+1] = 0xFF * color.g;
-      pixbuf[i*4+2] = 0xFF * color.b;
-      pixbuf[i*4+3] = 0xFF * color.a;
+      if( i == topLeft ||
+          i == topRight ||
+          i == bottomLeft ||
+          i == bottomRight )
+      {
+        pixbuf[i*4+0] = 0xFF * color.r;
+        pixbuf[i*4+1] = 0xFF * color.g;
+        pixbuf[i*4+2] = 0xFF * color.b;
+        pixbuf[i*4+3] = 0xFF * color.a;
+      }
+      else
+      {
+        pixbuf[i*4+0] = 0xFF * outerColor.r;
+        pixbuf[i*4+1] = 0xFF * outerColor.g;
+        pixbuf[i*4+2] = 0xFF * outerColor.b;
+        pixbuf[i*4+3] = 0xFF * outerColor.a;
+      }
     }
-    else
+  }
+  else
+  {
+    for( size_t i = 0; i < bitmapSize; ++i )
     {
-      pixbuf[i*4+0] = 0xFF * outerColor.r;
-      pixbuf[i*4+1] = 0xFF * outerColor.g;
-      pixbuf[i*4+2] = 0xFF * outerColor.b;
-      pixbuf[i*4+3] = 0xFF * outerColor.a;
+      if( i == topLeft ||
+          i == topRight ||
+          i == bottomLeft ||
+          i == bottomRight )
+      {
+        pixbuf[i*3+0] = 0xFF * color.r;
+        pixbuf[i*3+1] = 0xFF * color.g;
+        pixbuf[i*3+2] = 0xFF * color.b;
+      }
+      else
+      {
+        pixbuf[i*3+0] = 0xFF * outerColor.r;
+        pixbuf[i*3+1] = 0xFF * outerColor.g;
+        pixbuf[i*3+2] = 0xFF * outerColor.b;
+      }
     }
   }
 
index 0a55f22..aa6bd32 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 51;
+const unsigned int TOOLKIT_MICRO_VERSION = 52;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
@@ -23,8 +23,9 @@ distributing this software or its derivatives.
 
 //******************************************************************************
 //
-// Default style theme for Tizen dark theme, The values should come from
-// UX design document.
+// Default Reference style theme for a 480x800 resolution, The values determined by UX design specification.
+// This file can be copied to a new folder within the styles/ directory and amended with new default values.
+// Can be overriden if StyleManager applies another style sheet.
 //
 //******************************************************************************
 
@@ -33,8 +34,7 @@ distributing this software or its derivatives.
   {
     "textlabel":
     {
-      "font-family":"SamsungSans",
-      "font-style":"Regular"
+      "point-size":18
     },
 
     "textlabel-font-size-0":
@@ -58,13 +58,11 @@ distributing this software or its derivatives.
       "point-size":25
     },
 
-
     "textfield":
     {
-      "font-family":"SamsungSans",
-      "font-style":"Regular",
-      "primary-cursor-color":[1.0,0.71,0.9,1.0],
-      "secondary-cursor-color":[1.0,0.71,0.9,1.0],
+      "point-size":18,
+      "primary-cursor-color":[0.0,0.72,0.9,1.0],
+      "secondary-cursor-color":[0.0,0.72,0.9,1.0],
       "selection-highlight-color":[0.75,0.96,1.0,1.0],
       "grab-handle-image":"{DALI_IMAGE_DIR}cursor_handler_center.png",
       "selection-handle-image-left":"{DALI_IMAGE_DIR}selection_handle_left.png",
@@ -91,10 +89,6 @@ distributing this software or its derivatives.
     {
       "point-size":10
     },
-    "textselectionpopuplabel":
-    {
-      "point-size":8
-    },
     "textselectionpopup":
     {
       "popup-max-size":[400,100],
@@ -104,7 +98,9 @@ distributing this software or its derivatives.
       "popup-pressed-color":[0.24,0.72,0.8,0.11],
       "background-image": {
         "filename": "{DALI_IMAGE_DIR}selection-popup-bg.9.png"
-        }
+        },
+      "popup-fade-in-duration":0.25,
+      "popup-fade-out-duration":0.25
     },
     "scrollview":
     {
@@ -23,8 +23,9 @@ distributing this software or its derivatives.
 
 //******************************************************************************
 //
-// Default style theme for Tizen dark theme, The values should come from
-// UX design document.
+// Default Reference style theme for a 720x1280 resolution, The values determined by UX design specification.
+// This file can be copied to a new folder within the styles/ directory and amended with new default values.
+// Can be overriden if StyleManager applies another style sheet.
 //
 //******************************************************************************
 
@@ -33,37 +34,74 @@ distributing this software or its derivatives.
   {
     "textlabel":
     {
-      "font-family":"HelveticaNeue",
-      "font-style":"Regular",
       "point-size":18
     },
-    "textselectionpopuplabel":
+
+    "textlabel-font-size-0":
     {
-      "point-size":18
+      "point-size":8
     },
-    "textselectionpopup":
+    "textlabel-font-size-1":
     {
-      "popup-max-size":[400,100],
-      "option-divider-size":[2,0],
-      "popup-divider-color":[0.23,0.72,0.8,0.11],
-      "popup-icon-color":[1.0,1.0,1.0,1.0],
-      "popup-pressed-color":[0.24,0.72,0.8,0.11],
-      "background-image": {
-        "filename": "{DALI_IMAGE_DIR}selection-popup-bg.9.png"
-        }
+      "point-size":10
     },
+    "textlabel-font-size-2":
+    {
+      "point-size":15
+    },
+    "textlabel-font-size-3":
+    {
+      "point-size":19
+    },
+    "textlabel-font-size-4":
+    {
+      "point-size":25
+    },
+
     "textfield":
     {
-      "font-family":"HelveticaNeue",
-      "font-style":"Regular",
-      "point-size":18,
-      "primary-cursor-color":[0.0,0.71,0.9,1.0],
-      "secondary-cursor-color":[0.0,0.71,0.9,1.0],
+      "point-size":28,
+      "primary-cursor-color":[0.0,0.72,0.9,1.0],
+      "secondary-cursor-color":[0.0,0.72,0.9,1.0],
       "selection-highlight-color":[0.75,0.96,1.0,1.0],
       "grab-handle-image":"{DALI_IMAGE_DIR}cursor_handler_center.png",
       "selection-handle-image-left":"{DALI_IMAGE_DIR}selection_handle_left.png",
       "selection-handle-image-right":"{DALI_IMAGE_DIR}selection_handle_right.png"
     },
+
+    "textfield-font-size-0":
+    {
+      "point-size":10
+    },
+    "textfield-font-size-1":
+    {
+      "point-size":10
+    },
+    "textfield-font-size-2":
+    {
+      "point-size":10
+    },
+    "textfield-font-size-3":
+    {
+      "point-size":10
+    },
+    "textfield-font-size-4":
+    {
+      "point-size":10
+    },
+    "textselectionpopup":
+    {
+      "popup-max-size":[656,72],
+      "option-divider-size":[2,0],
+      "popup-divider-color":[0.23,0.72,0.8,0.11],
+      "popup-icon-color":[1.0,1.0,1.0,1.0],
+      "popup-pressed-color":[0.24,0.72,0.8,0.11],
+      "background-image": {
+        "filename": "{DALI_IMAGE_DIR}selection-popup-bg.9.png"
+        },
+      "popup-fade-in-duration":0.25,
+      "popup-fade-out-duration":0.25
+    },
     "scrollview":
     {
       "overshoot-effect-color":"B018"
diff --git a/docs/content/images/popup/popup-example.png b/docs/content/images/popup/popup-example.png
new file mode 100644 (file)
index 0000000..352a2e0
Binary files /dev/null and b/docs/content/images/popup/popup-example.png differ
diff --git a/docs/content/images/popup/popup-fields.png b/docs/content/images/popup/popup-fields.png
new file mode 100644 (file)
index 0000000..8555dcf
Binary files /dev/null and b/docs/content/images/popup/popup-fields.png differ
diff --git a/docs/content/images/popup/popup-image-content.png b/docs/content/images/popup/popup-image-content.png
new file mode 100644 (file)
index 0000000..7876811
Binary files /dev/null and b/docs/content/images/popup/popup-image-content.png differ
diff --git a/docs/content/images/popup/popup-toast.png b/docs/content/images/popup/popup-toast.png
new file mode 100644 (file)
index 0000000..25e07b1
Binary files /dev/null and b/docs/content/images/popup/popup-toast.png differ
index cf99aeb..fefb8a3 100644 (file)
  + [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
 
diff --git a/docs/content/shared-javascript-and-cpp-documentation/popup.md b/docs/content/shared-javascript-and-cpp-documentation/popup.md
new file mode 100644 (file)
index 0000000..c302f82
--- /dev/null
@@ -0,0 +1,392 @@
+<!--
+/**-->
+
+[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
+*/
+
index ffecd5f..9bcd7e1 100644 (file)
@@ -1,9 +1,9 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.0.51
+Version:    1.0.52
 Release:    1
 Group:      System/Libraries
-License:    Apache-2.0
+License:    Apache-2.0, BSD-2.0, MIT
 URL:        https://review.tizen.org/git/?p=platform/core/uifw/dali-toolkit.git;a=summary
 Source0:    %{name}-%{version}.tar.gz
 
@@ -21,6 +21,12 @@ BuildRequires:  pkgconfig(dali-core)
 #############################
 
 %define dali_toolkit_profile MOBILE
+%define dali_style_folder 720x1280
+# dali_style to be provided by build system as with dali_toolkit_profile or by passing --define 'dali_style 470x800' to the rpm build command
+
+%if "%{?dali_style}"
+  %define dali_style_folder %{dali_style}
+%endif
 
 # Further resource locations profiles can be provided here otherwise MOBILE will be used
 %if "%{tizen_profile_name}" == "mobile"
@@ -67,7 +73,7 @@ cd %{_builddir}/dali-toolkit-%{version}/build/tizen
 autoreconf --install
 DALI_DATA_RW_DIR="%{dali_data_rw_dir}" ; export DALI_DATA_RW_DIR
 DALI_DATA_RO_DIR="%{dali_data_ro_dir}" ; export DALI_DATA_RO_DIR
-%configure --enable-profile=%{dali_toolkit_profile}
+%configure --enable-profile=%{dali_toolkit_profile} --with-style=%{dali_style_folder}
 make %{?jobs:-j%jobs}
 
 ##############################
index b36f68a..f712893 100644 (file)
@@ -499,6 +499,93 @@ void ActorApi::GetActorType( const v8::FunctionCallbackInfo<v8::Value>& args )
   args.GetReturnValue().Set( v8String );
 }
 /**
+ * Return the natural size of the actor.
+ *
+ * @for Actor
+ * @method getNaturalSize
+ * @return {Object} { x, y, z }
+ */
+void ActorApi::GetNaturalSize( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+  Actor actor = GetActor( isolate, args );
+
+  Vector3 size( actor.GetNaturalSize() );
+
+  v8::Local<v8::Object> sizeObject = v8::Object::New( isolate );
+
+  sizeObject->Set( v8::String::NewFromUtf8( isolate, "x" ), v8::Integer::New( isolate, size.width ) );
+  sizeObject->Set( v8::String::NewFromUtf8( isolate, "y" ), v8::Integer::New( isolate, size.height ) );
+  sizeObject->Set( v8::String::NewFromUtf8( isolate, "z" ), v8::Integer::New( isolate, size.depth ) );
+
+  args.GetReturnValue().Set( sizeObject );
+}
+
+/**
+ *  Calculate the width of the actor given a height
+ *
+ * The natural size is used for default calculation.
+ * size 0 is treated as aspect ratio 1:1.
+ * @for Actor
+ * @method getWidthForHeight
+ * @param {Float} height to use
+ * @return {Float} Return the width based on the height
+ * @example
+ *   myTextLabel.getWidthForHeight(40);
+ *
+ * // DALi uses this formula internally
+ * // width = naturalSize.width * height / naturalSize.height;
+ *
+ *
+ */
+void ActorApi::GetWidthForHeight( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+  Actor actor = GetActor( isolate, args );
+
+  bool found;
+  float height = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "missing height parameter");
+    return;
+  }
+  args.GetReturnValue().Set( v8::Number::New( isolate, actor.GetWidthForHeight( height ) ) );
+}
+
+/**
+ *  Calculate the height of the actor given a width
+ *
+ * The natural size is used for default calculation.
+ * size 0 is treated as aspect ratio 1:1.
+ * @for Actor
+ * @method getHeightForWidth
+ * @param {Float} width to use
+ * @return {Float} Return the height based on the width
+ * @example
+ *   myTextLabel.getHeightForWidth(250);
+ *
+ * // DALi uses this formula internally
+ * // height = naturalSize.height * width / naturalSize.width
+ */
+void ActorApi::GetHeightForWidth( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+  v8::Isolate* isolate = args.GetIsolate();
+  v8::HandleScope handleScope( isolate );
+  Actor actor = GetActor( isolate, args );
+
+  bool found;
+  float width = V8Utils::GetFloatParameter( PARAMETER_0, found, isolate, args, 0.f );
+  if( !found )
+  {
+    DALI_SCRIPT_EXCEPTION( isolate, "missing width parameter");
+    return;
+  }
+  args.GetReturnValue().Set( v8::Number::New( isolate, actor.GetHeightForWidth( width ) ) );
+}
+/**
  * Move an actor relative to its existing position.
  * @example
  *
index 8543f11..82f41d3 100644 (file)
@@ -64,6 +64,9 @@ namespace ActorApi
   void ScreenToLocal( const v8::FunctionCallbackInfo< v8::Value >& args );
   void SetKeyboardFocusable( const v8::FunctionCallbackInfo< v8::Value >& args );
   void IsKeyboardFocusable( const v8::FunctionCallbackInfo< v8::Value >& args );
+  void GetNaturalSize( const v8::FunctionCallbackInfo< v8::Value >& args );
+  void GetWidthForHeight( const v8::FunctionCallbackInfo<v8::Value>& args );
+  void GetHeightForWidth( const v8::FunctionCallbackInfo<v8::Value>& args );
   void TranslateBy( const v8::FunctionCallbackInfo< v8::Value >& args );
   void RotateBy( const v8::FunctionCallbackInfo< v8::Value >& args );
   void ScaleBy( const v8::FunctionCallbackInfo< v8::Value >& args );
index b242721..9b81f41 100644 (file)
@@ -183,6 +183,9 @@ const ActorFunctions ActorFunctionTable[]=
     // ignore. GetCurrentAnchorPoint()  use Actor.anchorPoint
     // ignore. SetSize() use Actor.size
     // ignore. GetCurrentSize() use Actor.size
+    { "GetNaturalSize",   ActorApi::GetNaturalSize,    ACTOR_API },
+    { "GetWidthForHeight",ActorApi::GetWidthForHeight, ACTOR_API },
+    { "GetHeightForWidth",ActorApi::GetHeightForWidth, ACTOR_API },
     // ignore. SetPosition(....) use Actor.position
     // ignore. SetX, SetY, SetZ,  use Actor.position.x, Actor.position.y, Actor.position.z
     { "TranslateBy",         ActorApi::TranslateBy,              ACTOR_API },