Removed the DPI hacks
[platform/core/uifw/dali-demo.git] / demo / dali-table-view.cpp
index d77c3dc..e0e02d7 100644 (file)
 
 // CLASS HEADER
 #include "dali-table-view.h"
+#include "examples/shared/view.h"
 
 // EXTERNAL INCLUDES
 #include <algorithm>
 #include <sstream>
-
-#ifdef USE_AUL
-#include <aul.h>
-#else
 #include<unistd.h>
-#endif // USE_AUL
 
 using namespace Dali;
 using namespace Dali::Toolkit;
-using namespace std;
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -58,18 +53,17 @@ const int MAX_PAGES = 256;                                      ///< Maximum pag
 const int EXAMPLES_PER_ROW = 3;
 const int ROWS_PER_PAGE = 3;
 const int EXAMPLES_PER_PAGE = EXAMPLES_PER_ROW * ROWS_PER_PAGE;
-const float TOP_ROW_HEIGHT = 35.0f;
-const float BOTTOM_ROW_HEIGHT = 35.0f;
-const int BOTTOM_PADDING_HEIGHT = 40;
-const int LOGO_BOTTOM_PADDING_HEIGHT = 30;
-const Vector3 TABLE_RELATIVE_SIZE(0.9f, 1.0f, 0.8f );          ///< TableView's relative size to the entire stage.
+const float LOGO_MARGIN_RATIO = 0.5f / 0.9f;
+const float BOTTOM_PADDING_RATIO = 0.4f / 0.9f;
+const Vector3 SCROLLVIEW_RELATIVE_SIZE(0.9f, 1.0f, 0.8f );     ///< ScrollView's relative size to its parent
+const Vector3 TABLE_RELATIVE_SIZE(0.9f, 0.9f, 0.8f );          ///< TableView's relative size to the entire stage. The Y value means sum of the logo and table relative heights.
 const float STENCIL_RELATIVE_SIZE = 1.0f;
 
 const float EFFECT_SNAP_DURATION = 0.66f;                       ///< Scroll Snap Duration for Effects
 const float EFFECT_FLICK_DURATION = 0.5f;                       ///< Scroll Flick Duration for Effects
 const Vector3 ANGLE_CUBE_PAGE_ROTATE(Math::PI * 0.5f, Math::PI * 0.5f, 0.0f);
 
-const int NUM_BACKGROUND_IMAGES = 20;
+const int NUM_BACKGROUND_IMAGES = 18;
 const float BACKGROUND_SWIPE_SCALE = 0.025f;
 const float BACKGROUND_SPREAD_SCALE = 1.5f;
 const float SCALE_MOD = 1000.0f * Math::PI * 2.0f;
@@ -78,52 +72,42 @@ const float SCALE_SPEED_SIN = 0.1f;
 
 const unsigned int BACKGROUND_ANIMATION_DURATION = 15000; // 15 secs
 
-const float BACKGROUND_Z = -1000.0f;
-const float BACKGROUND_SIZE_SCALE = 2.0f;
+const float BACKGROUND_Z = -1.0f;
+const float BACKGROUND_SIZE_SCALE = 1.0f;
 const Vector4 BACKGROUND_COLOR( 1.0f, 1.0f, 1.0f, 1.0f );
 
+const float BUBBLE_MIN_Z = -1.0;
+const float BUBBLE_MAX_Z = 0.0f;
 
-const std::string             DEFAULT_TEXT_STYLE_FONT_FAMILY("HelveticaNeue");
-const std::string             DEFAULT_TEXT_STYLE_FONT_STYLE("Regular");
-const Dali::PointSize         DEFAULT_TEXT_STYLE_POINT_SIZE( 8.0f );
-const Dali::TextStyle::Weight DEFAULT_TEXT_STYLE_WEIGHT(Dali::TextStyle::REGULAR);
-const Dali::Vector4           DEFAULT_TEXT_STYLE_COLOR(0.7f, 0.7f, 0.7f, 1.0f);
+// 3D Effect constants
+const Vector2 ANGLE_SWING_3DEFFECT( Math::PI_2 * 0.75, Math::PI_2 * 0.75f ); ///< Angle Swing in radians
+const Vector2 POSITION_SWING_3DEFFECT( 0.55f, 0.4f );             ///< Position Swing relative to stage size.
+const Vector3 ANCHOR_3DEFFECT_STYLE0( -105.0f, 30.0f, -240.0f ); ///< Rotation Anchor position for 3D Effect (Style 0)
+const Vector3 ANCHOR_3DEFFECT_STYLE1( 65.0f, -70.0f, -500.0f );  ///< Rotation Anchor position for 3D Effect (Style 1)
 
-const std::string             TABLE_TEXT_STYLE_FONT_FAMILY("HelveticaNeue");
-const std::string             TABLE_TEXT_STYLE_FONT_STYLE("Regular");
-const Dali::PointSize         TABLE_TEXT_STYLE_POINT_SIZE( 8.0f );
-const Dali::TextStyle::Weight TABLE_TEXT_STYLE_WEIGHT(Dali::TextStyle::LIGHT);
-const Dali::Vector4           TABLE_TEXT_STYLE_COLOR(0.0f, 0.0f, 0.0f, 1.0f);
+//const std::string             DEFAULT_TEXT_STYLE_FONT_FAMILY("HelveticaNeue");
+//const std::string             DEFAULT_TEXT_STYLE_FONT_STYLE("Regular");
+//const Dali::Vector4           DEFAULT_TEXT_STYLE_COLOR(0.7f, 0.7f, 0.7f, 1.0f);
 
-TextStyle GetDefaultTextStyle()
-{
-  TextStyle textStyle;
-  textStyle.SetFontName(DEFAULT_TEXT_STYLE_FONT_FAMILY);
-  textStyle.SetFontStyle(DEFAULT_TEXT_STYLE_FONT_STYLE);
-  textStyle.SetFontPointSize(DEFAULT_TEXT_STYLE_POINT_SIZE);
-  textStyle.SetWeight(DEFAULT_TEXT_STYLE_WEIGHT);
-  textStyle.SetTextColor(DEFAULT_TEXT_STYLE_COLOR);
-  textStyle.SetShadow( true );
-  return textStyle;
-}
+//const std::string             TABLE_TEXT_STYLE_FONT_FAMILY("HelveticaNeue");
+//const std::string             TABLE_TEXT_STYLE_FONT_STYLE("Regular");
+//const Dali::PointSize         TABLE_TEXT_STYLE_POINT_SIZE( 8.0f );
+//const Dali::TextStyle::Weight TABLE_TEXT_STYLE_WEIGHT(Dali::TextStyle::LIGHT);
+//const Dali::Vector4           TABLE_TEXT_STYLE_COLOR(0.0f, 0.0f, 0.0f, 1.0f);
 
-TextStyle GetTableTextStyle()
+Vector3 ScalePointSize(const Vector3& vec)
 {
-  TextStyle textStyle;
-  textStyle.SetFontName(TABLE_TEXT_STYLE_FONT_FAMILY);
-  textStyle.SetFontStyle(TABLE_TEXT_STYLE_FONT_STYLE);
-  textStyle.SetFontPointSize(TABLE_TEXT_STYLE_POINT_SIZE);
-  textStyle.SetWeight(TABLE_TEXT_STYLE_WEIGHT);
-  textStyle.SetTextColor(TABLE_TEXT_STYLE_COLOR);
-  return textStyle;
+  return Vector3( DemoHelper::ScalePointSize( vec.x ), DemoHelper::ScalePointSize( vec.y ), DemoHelper::ScalePointSize( vec.z ) );
 }
 
+#define DP(x) DemoHelper::ScalePointSize(x)
+
 /**
  * Creates the background image
  */
 ImageActor CreateBackground( std::string imagePath )
 {
-  Image image = Image::New( imagePath );
+  Image image = ResourceImage::New( imagePath );
   ImageActor background = ImageActor::New( image );
 
   background.SetAnchorPoint( AnchorPoint::CENTER );
@@ -140,99 +124,40 @@ const float IMAGE_BORDER_TOP = IMAGE_BORDER_LEFT;
 const float IMAGE_BORDER_BOTTOM = IMAGE_BORDER_LEFT;
 
 /**
- * TableViewVisibilityConstraint
- */
-struct TableViewVisibilityConstraint
-{
-  bool operator()( const bool& current,
-              const PropertyInput& pagePositionProperty,
-              const PropertyInput& pageSizeProperty )
-  {
-    // Only the tableview in the current page should be visible.
-    const Vector3& pagePosition = pagePositionProperty.GetVector3();
-    const Vector3& pageSize = pageSizeProperty.GetVector3();
-    return fabsf( pagePosition.x ) < pageSize.x;
-  }
-};
-
-/**
- * Constraint to wrap an actor in y that is moving vertically
+ * Constraint to return a position for a bubble based on the scroll value and vertical wrapping.
  */
-Vector3 ShapeMovementConstraint( const Vector3& current,
-                         const PropertyInput& shapeSizeProperty,
-                         const PropertyInput& parentSizeProperty )
-{
-  const Vector3& shapeSize = shapeSizeProperty.GetVector3();
-  const Vector3& parentSize = parentSizeProperty.GetVector3();
-
-  Vector3 pos( current );
-  if( pos.y + shapeSize.y * 0.5f < -parentSize.y * 0.5f )
-  {
-    pos.y += parentSize.y + shapeSize.y;
-  }
-
-  return pos;
-}
-
-/**
- * Constraint to return a bool value based on the alpha channel value
- */
-bool AlphaVisibleConstraint( bool current, const PropertyInput& alphaProperty )
-{
-  Vector4 colour = alphaProperty.GetVector4();
-  return ( colour.a > Math::MACHINE_EPSILON_10000 );
-}
-
-/**
- * Constraint to return a position for the background based on the scroll value
- */
-struct AnimScrollConstraint
+struct AnimateBubbleConstraint
 {
 public:
-
-  AnimScrollConstraint( const Vector3& initialPos, float scale )
-      : mInitialPos( initialPos ),
-        mScale( scale )
+  AnimateBubbleConstraint( const Vector3& initialPos, float scale, float size )
+      : mInitialX( initialPos.x ),
+        mScale( scale ),
+        mShapeSize( size )
   {
-
-  }
-
-  Vector3 operator()( const Vector3& current, const PropertyInput& scrollProperty )
-  {
-    float scrollPos = scrollProperty.GetVector3().x;
-
-    return mInitialPos + Vector3( -scrollPos * mScale, 0.0f, 0.0f );
   }
 
-private:
-  Vector3 mInitialPos;
-  float mScale;
-};
-
-/**
- * Constraint to return a tracked world position added to the constant local position
- */
-struct TranslateLocalConstraint
-{
-public:
-
-  TranslateLocalConstraint( const Vector3& localPos )
-      : mLocalPos( localPos )
+  Vector3 operator()( const Vector3& current, const PropertyInput& scrollProperty, const PropertyInput& parentSize )
   {
-  }
+    Vector3 pos( current );
 
-  Vector3 operator()( const Vector3& current, const PropertyInput& pagePosProperty )
-  {
-    Vector3 worldPos = pagePosProperty.GetVector3();
+    // Wrap bubbles verically.
+    if( pos.y + mShapeSize * 0.5f < -parentSize.GetVector3().y * 0.5f )
+    {
+      pos.y += parentSize.GetVector3().y + mShapeSize;
+    }
 
-    return ( worldPos + mLocalPos );
+    // Bubbles X position moves parallax to horizontal
+    // panning by a scale factor unique to each bubble.
+    pos.x = mInitialX + ( scrollProperty.GetVector3().x * mScale );
+    return pos;
   }
 
 private:
-  Vector3 mLocalPos;
+  float mInitialX;
+  float mScale;
+  float mShapeSize;
 };
 
-
 bool CompareByTitle( const Example& lhs, const Example& rhs )
 {
   return lhs.title < rhs.title;
@@ -274,7 +199,7 @@ void DaliTableView::Initialize( Application& application )
 {
   Stage::GetCurrent().KeyEventSignal().Connect( this, &DaliTableView::OnKeyEvent );
 
-  Vector2 stageSize = Stage::GetCurrent().GetSize();
+  const Vector2 stageSize = Stage::GetCurrent().GetSize();
 
   // Background
   mBackground = CreateBackground( mBackgroundImagePath );
@@ -286,14 +211,30 @@ void DaliTableView::Initialize( Application& application )
   mRootActor = TableView::New( 4, 1 );
   mRootActor.SetAnchorPoint( AnchorPoint::CENTER );
   mRootActor.SetParentOrigin( ParentOrigin::CENTER );
-  mRootActor.SetFixedHeight( 3, BOTTOM_PADDING_HEIGHT );
   Stage::GetCurrent().Add( mRootActor );
 
   // Toolbar at top
-  CreateToolbar( mRootActor, DEFAULT_TOOLBAR_TEXT, DEFAULT_TOOLBAR_IMAGE_PATH );
+  Dali::Toolkit::ToolBar toolbar;
+  Dali::Layer toolBarLayer = DemoHelper::CreateToolbar(toolbar,
+                                                       DEFAULT_TOOLBAR_IMAGE_PATH,
+                                                       DEFAULT_TOOLBAR_TEXT,
+                                                       DemoHelper::DEFAULT_VIEW_STYLE);
+
+  mRootActor.AddChild( toolBarLayer, TableView::CellPosition( 0, 0 ) );
+  const float toolbarHeight = DemoHelper::DEFAULT_VIEW_STYLE.mToolBarHeight;
+  mRootActor.SetFixedHeight( 0, toolbarHeight );
 
   // Add logo
   mLogo = CreateLogo( LOGO_PATH );
+  const float paddingHeight = ( ( 1.f-TABLE_RELATIVE_SIZE.y ) * stageSize.y );
+  const float logoMargin = paddingHeight * LOGO_MARGIN_RATIO;
+  const float logoHeight = mLogo.GetImage().GetHeight() + logoMargin;
+  mRootActor.SetFixedHeight( 1, logoHeight );
+
+  const float bottomMargin = paddingHeight * BOTTOM_PADDING_RATIO;
+  mButtonsPageRelativeSize = Vector3( TABLE_RELATIVE_SIZE.x, 1.f - ( toolbarHeight + logoHeight + bottomMargin) / stageSize.height, TABLE_RELATIVE_SIZE.z );
+  mRootActor.SetFixedHeight( 2, mButtonsPageRelativeSize.y * stageSize.height );
+
   Alignment alignment = Alignment::New();
   alignment.Add(mLogo);
   mRootActor.AddChild( alignment, TableView::CellPosition( 1, 0 ) );
@@ -303,7 +244,9 @@ void DaliTableView::Initialize( Application& application )
 
   mScrollView.SetAnchorPoint( AnchorPoint::CENTER );
   mScrollView.SetParentOrigin( ParentOrigin::CENTER );
-  mScrollView.ApplyConstraint( Dali::Constraint::New<Dali::Vector3>( Dali::Actor::SIZE, Dali::ParentSource( Dali::Actor::SIZE ), Dali::RelativeToConstraint( TABLE_RELATIVE_SIZE ) ) );
+  // Note: Currently, changing mScrollView to use SizeMode RELATIVE_TO_PARENT
+  // will cause scroll ends to appear in the wrong position.
+  mScrollView.ApplyConstraint( Dali::Constraint::New<Dali::Vector3>( Dali::Actor::SIZE, Dali::ParentSource( Dali::Actor::SIZE ), Dali::RelativeToConstraint( SCROLLVIEW_RELATIVE_SIZE ) ) );
   mScrollView.SetAxisAutoLock( true );
   mScrollView.ScrollCompletedSignal().Connect( this, &DaliTableView::OnScrollComplete );
   mScrollView.ScrollStartedSignal().Connect( this, &DaliTableView::OnScrollStart );
@@ -312,37 +255,22 @@ void DaliTableView::Initialize( Application& application )
   mScrollViewLayer = Layer::New();
   mScrollViewLayer.SetAnchorPoint( AnchorPoint::CENTER );
   mScrollViewLayer.SetParentOrigin( ParentOrigin::CENTER );
-  mScrollViewLayer.SetSize( stageSize );
+  mScrollViewLayer.SetDrawMode( DrawMode::OVERLAY );
+
+  // Populate background and bubbles - needs to be scrollViewLayer so scroll ends show
+  SetupBackground( mScrollView, mScrollViewLayer, stageSize );
+
   mScrollViewLayer.Add( mScrollView );
   mRootActor.AddChild( mScrollViewLayer, TableView::CellPosition( 2, 0 ) );
 
-  // Setup the scenegraph
-  // 1) Add scroll view effect and setup constraints on pages
+  // Add scroll view effect and setup constraints on pages
   ApplyScrollViewEffect();
 
-  // 2) Add pages and tiles
+  // Add pages and tiles
   Populate();
 
-  // 3) Populate scrollview with background so constraints on background layers can work with scrollview
-  SetupBackground( mScrollView, stageSize );
-
-  // 4) Remove constraints for inner cube effect
-  for( TableViewListIter pageIter = mTableViewList.begin(); pageIter != mTableViewList.end(); ++pageIter )
-  {
-    TableView page = *pageIter;
-
-    unsigned int numChildren = page.GetChildCount();
-    Actor pageActor = page;
-    for( unsigned int i=0; i<numChildren; ++i)
-    {
-      // Remove old effect's manual constraints.
-      Actor child = pageActor.GetChildAt(i);
-      if( child )
-      {
-        child.RemoveConstraints();
-      }
-    }
-  }
+  // Remove constraints for inner cube effect
+  ApplyCubeEffectToActors();
 
   // Set initial orientation
   unsigned int degrees = application.GetOrientation().GetDegrees();
@@ -357,7 +285,7 @@ void DaliTableView::Initialize( Application& application )
   Dali::Orientation orientation = winHandle.GetOrientation();
   orientation.ChangedSignal().Connect( this, &DaliTableView::OrientationChanged );
 
-  winHandle.ShowIndicator( false );
+  winHandle.ShowIndicator( Dali::Window::INVISIBLE );
 
   //
   mAnimationTimer = Timer::New( BACKGROUND_ANIMATION_DURATION );
@@ -369,67 +297,29 @@ void DaliTableView::Initialize( Application& application )
   KeyboardFocusManager::Get().FocusedActorActivatedSignal().Connect( this, &DaliTableView::OnFocusedActorActivated );
 }
 
-void DaliTableView::CreateToolbar( TableView root, const std::string& title, const std::string& toolbarImagePath,
-                              const ViewStyle& style )
+void DaliTableView::ApplyCubeEffectToActors()
 {
-  // Create default ToolBar
-  Dali::Stage stage = Dali::Stage::GetCurrent();
-  Dali::Vector2 dpi = stage.GetDpi();
-
-  // Create toolbar layer.
-  Dali::Layer toolBarLayer = Dali::Layer::New();
-  toolBarLayer.SetAnchorPoint( Dali::AnchorPoint::TOP_CENTER );
-  toolBarLayer.SetParentOrigin( Dali::ParentOrigin::TOP_CENTER );
-  toolBarLayer.ApplyConstraint( Dali::Constraint::New<Dali::Vector3>( Dali::Actor::SIZE, Dali::ParentSource( Dali::Actor::SIZE ), Dali::SourceWidthFixedHeight( style.mToolBarHeight * dpi.y / style.mDpi ) ) );
-  float toolBarLayerHeight = style.mToolBarHeight * dpi.y / style.mDpi;
-  toolBarLayer.SetSize( 0.0f, toolBarLayerHeight );
-
-  // Add tool bar layer to the view.
-  root.AddChild( toolBarLayer, TableView::CellPosition( 0, 0 ) );
-  root.SetFixedHeight( 0, toolBarLayerHeight );
-
-  // Raise tool bar layer to the top.
-  toolBarLayer.RaiseToTop();
-
-  // Tool bar
-  Dali::Image image = Dali::Image::New( toolbarImagePath );
-  Dali::ImageActor toolBarBackground = Dali::ImageActor::New( image );
-  Dali::Toolkit::ToolBar toolBar = Dali::Toolkit::ToolBar::New();
-  toolBar.SetBackground( toolBarBackground );
-  toolBar.SetParentOrigin( Dali::ParentOrigin::TOP_CENTER );
-  toolBar.SetAnchorPoint( Dali::AnchorPoint::TOP_CENTER );
-  toolBar.ApplyConstraint( Dali::Constraint::New<Dali::Vector3>( Dali::Actor::SIZE, Dali::ParentSource( Dali::Actor::SIZE ), Dali::EqualToConstraint() ) );
-  toolBar.SetSize( 0.0f, style.mToolBarHeight * dpi.y / style.mDpi );
-  toolBarBackground.SetZ( -1.0f );
-
-  // Add the tool bar to the too bar layer.
-  toolBarLayer.Add( toolBar );
-
-  Dali::Font font = Dali::Font::New();
-
-  // Tool bar text.
-  if( !title.empty() )
+  for( ActorIter pageIter = mPages.begin(); pageIter != mPages.end(); ++pageIter )
   {
-    Dali::Toolkit::TextView titleActor = Dali::Toolkit::TextView::New();
-    titleActor.SetName( "ToolbarTitle" );
-    titleActor.SetText( title );
-    titleActor.SetSize( font.MeasureText( title ) );
-    titleActor.SetStyleToCurrentText( GetDefaultTextStyle() );
-    titleActor.SetZ( 1.0f );
-
-    // Add title to the tool bar.
-    const float padding( style.mToolBarPadding * dpi.x / style.mDpi );
-    toolBar.AddControl( titleActor, style.mToolBarTitlePercentage, Dali::Toolkit::Alignment::HorizontalCenter,
-                        Dali::Toolkit::Alignment::Padding( padding, padding, padding, padding ) );
+    Actor page = *pageIter;
+
+    unsigned int numChildren = page.GetChildCount();
+    Actor pageActor = page;
+    for( unsigned int i=0; i<numChildren; ++i)
+    {
+      // Remove old effect's manual constraints.
+      Actor child = pageActor.GetChildAt(i);
+      if( child )
+      {
+        ApplyCubeEffectToActor( child );
+      }
+    }
   }
 }
-
 void DaliTableView::Populate()
 {
   const Vector2 stageSize = Stage::GetCurrent().GetSize();
 
-  const Size demoTileSize( 0.25f * stageSize.width, 0.25f * stageSize.height );
-
   mTotalPages = ( mExampleList.size() + EXAMPLES_PER_PAGE - 1 ) / EXAMPLES_PER_PAGE;
 
   // Populate ScrollView.
@@ -442,41 +332,32 @@ void DaliTableView::Populate()
 
     unsigned int exampleCount = 0;
     ExampleListConstIter iter = mExampleList.begin();
+
     for( int t = 0; t < mTotalPages; t++ )
     {
       // Create Table. (contains up to 9 Examples)
-      TableView tableView = TableView::New( 4, 3 );
+      Actor page = Actor::New();
+
       // Add tableView to container.
-      mScrollView.Add( tableView );
-      ApplyEffectToPage( tableView, TABLE_RELATIVE_SIZE );
-
-      tableView.SetAnchorPoint( AnchorPoint::CENTER );
-      tableView.SetParentOrigin( ParentOrigin::CENTER );
-      // 2 pixels of padding
-      tableView.SetCellPadding( Size( 2.0f, 2.0f ) );
-
-      Constraint constraint = Constraint::New<Vector3>( Actor::SCALE,
-                                                        LocalSource( Actor::SIZE ),
-                                                        ParentSource( Actor::SIZE ),
-                                                        ScaleToFitConstraint() );
-      tableView.ApplyConstraint(constraint);
-
-      // Apply visibility constraint to table view
-      Constraint visibleConstraint = Constraint::New< bool >( Actor::VISIBLE,
-                                                              LocalSource( Actor::POSITION ),
-                                                              ParentSource( Actor::SIZE ),
-                                                              TableViewVisibilityConstraint() );
-      visibleConstraint.SetRemoveAction( Constraint::Discard );
-      tableView.ApplyConstraint( visibleConstraint );
+      mScrollView.Add( page );
+
+      page.SetAnchorPoint( AnchorPoint::CENTER );
+      page.SetParentOrigin( ParentOrigin::CENTER );
+      page.SetSizeMode( SIZE_EQUAL_TO_PARENT );
 
       // add cells to table
-      for( int y = 0; y < ROWS_PER_PAGE; y++ )
+      const float margin = 4.0f;
+
+      // Calculate the number of images going across (columns) within a page, according to the screen resolution and dpi.
+      const Size tileSize((stageSize.x * mButtonsPageRelativeSize.x / EXAMPLES_PER_ROW) - margin, (stageSize.y * mButtonsPageRelativeSize.y / ROWS_PER_PAGE) - margin );
+
+      for(int row = 0; row < ROWS_PER_PAGE; row++)
       {
-        for( int x = 0; x < EXAMPLES_PER_ROW; x++ )
+        for(int column = 0; column < EXAMPLES_PER_ROW; column++)
         {
           const Example& example = ( *iter );
 
-          Actor tile = CreateTile( example.name, example.title, demoTileSize, true );
+          Actor tile = CreateTile( example.name, example.title, tileSize, true );
           FocusManager focusManager = FocusManager::Get();
           focusManager.SetFocusOrder( tile, ++exampleCount );
           focusManager.SetAccessibilityAttribute( tile, Dali::Toolkit::FocusManager::ACCESSIBILITY_LABEL,
@@ -485,7 +366,13 @@ void DaliTableView::Populate()
           focusManager.SetAccessibilityAttribute( tile, Dali::Toolkit::FocusManager::ACCESSIBILITY_HINT,
                                                   "You can run this example" );
 
-          tableView.AddChild( tile, TableView::CellPosition( y, x ) );
+          Vector3 position( margin * 0.5f + (tileSize.x + margin) * column - stageSize.width * mButtonsPageRelativeSize.x * 0.5f,
+                           margin * 0.5f + (tileSize.y + margin) * row - stageSize.height * mButtonsPageRelativeSize.y * 0.5f,
+                            0.0f);
+          tile.SetPosition( position + Vector3( tileSize.x, tileSize.y, 0.0f ) * 0.5f );
+          tile.SetSize( tileSize );
+          page.Add( tile );
+
           iter++;
 
           if( iter == mExampleList.end() )
@@ -493,31 +380,18 @@ void DaliTableView::Populate()
             break;
           }
         }
+
         if( iter == mExampleList.end() )
         {
           break;
         }
       }
 
-      // last row is thin.
-      tableView.SetFixedHeight( 3, BOTTOM_ROW_HEIGHT );
-
-      std::stringstream out;
-      out << ( t + 1 ) << " of " << mTotalPages;
-      Actor pageNumberText = CreateTile( "", out.str(), Size( 0.8f * stageSize.width, BOTTOM_ROW_HEIGHT ), false );
-
-      pageNumberText.ApplyConstraint( Constraint::New< Vector3 >( Actor::POSITION, Source( tableView, Actor::WORLD_POSITION),
-                                                                   TranslateLocalConstraint( Vector3( 0.0f, stageSize.y * 0.4f, 0.0f ) ) ) );
-      pageNumberText.ApplyConstraint( Constraint::New< Quaternion >( Actor::ROTATION, Source( tableView, Actor::WORLD_ROTATION ), EqualToConstraint() ) );
-      pageNumberText.ApplyConstraint( Constraint::New< Vector4 >( Actor::COLOR, Source( tableView, Actor::COLOR ), EqualToConstraint() ) );
-
-      //Stage::GetCurrent().Add( pageNumberText );
-
       // Set tableview position
-      Vector3 tableViewPos( stageSize.x * TABLE_RELATIVE_SIZE.x * t, 0.0f, 0.0f );
-      tableView.SetPosition( tableViewPos );
+      Vector3 pagePos( stageSize.x * mButtonsPageRelativeSize.x * t, 0.0f, 0.0f );
+      page.SetPosition( pagePos );
 
-      mTableViewList.push_back( tableView );
+      mPages.push_back( page );
 
       if( iter == mExampleList.end() )
       {
@@ -527,9 +401,9 @@ void DaliTableView::Populate()
   }
 
   // Update Ruler info.
-  mScrollRulerX = new FixedRuler( stageSize.width * TABLE_RELATIVE_SIZE.x );
+  mScrollRulerX = new FixedRuler( stageSize.width * mButtonsPageRelativeSize.x );
   mScrollRulerY = new DefaultRuler();
-  mScrollRulerX->SetDomain( RulerDomain( 0.0f, mTotalPages * stageSize.width * TABLE_RELATIVE_SIZE.x, true ) );
+  mScrollRulerX->SetDomain( RulerDomain( 0.0f, mTotalPages * stageSize.width * mButtonsPageRelativeSize.x, true ) );
   mScrollRulerY->Disable();
   mScrollView.SetRulerX( mScrollRulerX );
   mScrollView.SetRulerY( mScrollRulerY );
@@ -563,71 +437,58 @@ void DaliTableView::Rotate( unsigned int degrees )
   mRotateAnimation.Play();
 }
 
-Actor DaliTableView::CreateTile( const string& name, const string& title, const Size& parentSize, bool addBackground )
+Actor DaliTableView::CreateTile( const std::string& name, const std::string& title, const Size& parentSize, bool addBackground )
 {
   Actor tile = Actor::New();
   tile.SetName( name );
   tile.SetAnchorPoint( AnchorPoint::CENTER );
   tile.SetParentOrigin( ParentOrigin::CENTER );
 
-  // make the tile 100% of parent
-  tile.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
-
-  Actor content = Actor::New();
-  content.SetAnchorPoint( AnchorPoint::CENTER );
-  content.SetParentOrigin( ParentOrigin::CENTER );
-  content.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
-  tile.Add(content);
-
   // create background image
   if( addBackground )
   {
-    Image bg = Image::New( TILE_BACKGROUND );
+    Image bg = ResourceImage::New( TILE_BACKGROUND );
     ImageActor image = ImageActor::New( bg );
     image.SetAnchorPoint( AnchorPoint::CENTER );
     image.SetParentOrigin( ParentOrigin::CENTER );
     // make the image 100% of tile
-    image.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
+    image.SetSizeMode( SIZE_EQUAL_TO_PARENT );
     // move image back to get text appear in front
     image.SetZ( -1 );
     image.SetStyle( ImageActor::STYLE_NINE_PATCH );
     image.SetNinePatchBorder( Vector4( IMAGE_BORDER_LEFT, IMAGE_BORDER_TOP, IMAGE_BORDER_RIGHT, IMAGE_BORDER_BOTTOM ) );
-
-    content.Add( image );
+    tile.Add( image );
 
     // Add stencil
     ImageActor stencil = NewStencilImage();
-    stencil.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
+    stencil.SetSizeMode( SIZE_EQUAL_TO_PARENT );
     image.Add( stencil );
   }
 
-  TextView text = TextView::New( title );
-  text.SetAnchorPoint( AnchorPoint::CENTER );
-  text.SetParentOrigin( ParentOrigin::CENTER );
-  text.SetWidthExceedPolicy( Toolkit::TextView::ShrinkToFit );
-  text.SetMultilinePolicy( Toolkit::TextView::SplitByWord );
-  text.SetLineJustification( Toolkit::TextView::Center );
-  text.SetTextAlignment( Toolkit::Alignment::Type( Alignment::HorizontalCenter | Alignment::VerticalCenter ) );
-  text.SetColor( Color::WHITE );
-  text.SetZ( 1 );
-  // make the text 90% of tile
-  text.SetSize( 0.9f * parentSize.width, 0.9f * parentSize.height );
-  text.SetStyleToCurrentText( GetTableTextStyle() );
-  text.SetSnapshotModeEnabled( false );
-  content.Add( text );
+  TextLabel label = TextLabel::New();
+  label.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  label.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+  label.SetProperty( TextLabel::PROPERTY_MULTI_LINE, true );
+  label.SetProperty( TextLabel::PROPERTY_TEXT, title );
+  label.SetColor( Color::BLACK );
+  tile.Add( label );
+
+  // FIXME - This is a kludge because size negotiation is not finished
+  label.SetSize( parentSize );
 
   // Set the tile to be keyboard focusable
   tile.SetKeyboardFocusable(true);
 
   // connect to the touch events
   tile.TouchedSignal().Connect( this, &DaliTableView::OnTilePressed );
+  tile.HoveredSignal().Connect( this, &DaliTableView::OnTileHovered );
 
   return tile;
 }
 
 ImageActor DaliTableView::NewStencilImage()
 {
-  Image alpha = Image::New( TILE_BACKGROUND_ALPHA );
+  Image alpha = ResourceImage::New( TILE_BACKGROUND_ALPHA );
 
   ImageActor stencilActor = ImageActor::New( alpha );
   stencilActor.SetStyle( ImageActor::STYLE_NINE_PATCH );
@@ -677,7 +538,7 @@ bool DaliTableView::OnTilePressed( Actor actor, const TouchEvent& event )
     if( consumed )
     {
       mPressedAnimation = Animation::New( BUTTON_PRESS_ANIMATION_TIME );
-      mPressedAnimation.SetDestroyAction( Animation::Discard );
+      mPressedAnimation.SetEndAction( Animation::Discard );
 
       // scale the content actor within the Tile, as to not affect the placement within the Table.
       Actor content = actor.GetChildAt(0);
@@ -715,9 +576,7 @@ void DaliTableView::OnPressedAnimationFinished( Dali::Animation& source )
     else
     {
       const Example& example( iter->second );
-#ifdef USE_AUL
-      aul_open_app( example.name.c_str() );
-#else // USE_AUL
+
       std::stringstream stream;
       stream << DALI_EXAMPLE_BIN << example.name.c_str();
       pid_t pid = fork();
@@ -726,7 +585,6 @@ void DaliTableView::OnPressedAnimationFinished( Dali::Animation& source )
         execlp( stream.str().c_str(), example.name.c_str(), NULL );
         DALI_ASSERT_ALWAYS(false && "exec failed!");
       }
-#endif // USE_AUL
     }
     mPressedActor.Reset();
   }
@@ -745,8 +603,9 @@ void DaliTableView::OnScrollComplete( const Dali::Vector3& position )
 
   // move focus to 1st item of new page
   FocusManager focusManager = FocusManager::Get();
-  focusManager.SetCurrentFocusActor(mTableViewList[mScrollView.GetCurrentPage()].GetChildAt(TableView::CellPosition(1, 0)) );
+  focusManager.SetCurrentFocusActor(mPages[mScrollView.GetCurrentPage()].GetChildAt(0) );
 
+  ApplyCubeEffectToActors();
 }
 
 bool DaliTableView::OnScrollTouched( Actor actor, const TouchEvent& event )
@@ -777,38 +636,21 @@ void DaliTableView::ApplyScrollViewEffect()
 
 void DaliTableView::SetupInnerPageCubeEffect()
 {
-  ScrollViewCustomEffect customEffect;
-  mScrollViewEffect = customEffect = ScrollViewCustomEffect::New();
+  mScrollViewEffect = ScrollViewCubeEffect::New();
   mScrollView.SetScrollSnapDuration( EFFECT_SNAP_DURATION );
   mScrollView.SetScrollFlickDuration( EFFECT_FLICK_DURATION );
-  mScrollView.SetScrollSnapAlphaFunction( AlphaFunctions::EaseOutBack );
-  mScrollView.SetScrollFlickAlphaFunction( AlphaFunctions::EaseOutBack );
   mScrollView.RemoveConstraintsFromChildren();
-
-  customEffect.SetPageSpacing( Vector2( 30.0f, 30.0f ) );
-  customEffect.SetAngledOriginPageRotation( ANGLE_CUBE_PAGE_ROTATE );
-  customEffect.SetSwingAngle( ANGLE_CUBE_PAGE_ROTATE.x, Vector3( 0, -1, 0 ) );
-  customEffect.SetOpacityThreshold( 0.5f );   // Make fade out on edges
 }
 
-void DaliTableView::ApplyEffectToPage( Actor page, const Vector3& tableRelativeSize )
+void DaliTableView::ApplyCubeEffectToActor( Actor actor )
 {
-  page.RemoveConstraints();
+  actor.RemoveConstraints();
 
-  Constraint constraint = Constraint::New<Vector3>( Actor::SCALE,
-                                                    LocalSource( Actor::SIZE ),
-                                                    ParentSource( Actor::SIZE ),
-                                                    ScaleToFitConstraint() );
-  page.ApplyConstraint(constraint);
-
-  ApplyCustomEffectToPage( page );
-}
-
-void DaliTableView::ApplyCustomEffectToPage( Actor page )
-{
-  ScrollViewCustomEffect customEffect = ScrollViewCustomEffect::DownCast( mScrollViewEffect );
-  Vector2 vStageSize( Stage::GetCurrent().GetSize() );
-  customEffect.ApplyToPage( page, Vector3( vStageSize.x, vStageSize.y, 1.0f ) );
+  ScrollViewCubeEffect cubeEffect = ScrollViewCubeEffect::DownCast(mScrollViewEffect);
+  cubeEffect.ApplyToActor( actor,
+                           ScalePointSize( ( rand() & 1 ) ? ANCHOR_3DEFFECT_STYLE0 : ANCHOR_3DEFFECT_STYLE1 ),
+                           ANGLE_SWING_3DEFFECT,
+                           POSITION_SWING_3DEFFECT * Vector2(Stage::GetCurrent().GetSize()));
 }
 
 void DaliTableView::OnKeyEvent( const KeyEvent& event )
@@ -822,62 +664,25 @@ void DaliTableView::OnKeyEvent( const KeyEvent& event )
   }
 }
 
-Actor CreateBackgroundActor( const Vector2& size )
+void DaliTableView::SetupBackground( Actor bubbleContainer, Actor backgroundLayer, const Vector2& size )
 {
-  Actor layer = Actor::New();
-  layer.SetAnchorPoint( AnchorPoint::CENTER );
-  layer.SetParentOrigin( ParentOrigin::CENTER );
-  layer.SetSize( size );
-  return layer;
-}
-
-void DaliTableView::SetupBackground( Actor addToLayer, const Vector2& size )
-{
-  // Create distance field shape
+  // Create distance field shape.
   BitmapImage distanceField;
   Size imageSize( 512, 512 );
   CreateShapeImage( CIRCLE, imageSize, distanceField );
 
-  // Create layers
-  Actor backgroundAnimLayer0 = CreateBackgroundActor( size );
-  Actor backgroundAnimLayer1 = CreateBackgroundActor( size );
-  Actor backgroundAnimLayer2 = CreateBackgroundActor( size );
-
-  // Add constraints
-  Constraint animConstraint0 = Constraint::New < Vector3 > ( Actor::POSITION,
-      Source( mScrollView, mScrollView.GetPropertyIndex( ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
-      AnimScrollConstraint( backgroundAnimLayer0.GetCurrentPosition(), 0.75f ) );
-  backgroundAnimLayer0.ApplyConstraint( animConstraint0 );
-
-  Constraint animConstraint1 = Constraint::New < Vector3 > ( Actor::POSITION,
-      Source( mScrollView, mScrollView.GetPropertyIndex( ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
-      AnimScrollConstraint( backgroundAnimLayer1.GetCurrentPosition(), 0.5f ) );
-  backgroundAnimLayer1.ApplyConstraint( animConstraint1 );
-
-  Constraint animConstraint2 = Constraint::New < Vector3 > ( Actor::POSITION,
-      Source( mScrollView, mScrollView.GetPropertyIndex( ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
-      AnimScrollConstraint( backgroundAnimLayer2.GetCurrentPosition(), 0.25f ) );
-  backgroundAnimLayer2.ApplyConstraint( animConstraint2 );
+  // Create solid background colour.
+  ImageActor backgroundColourActor = Dali::Toolkit::CreateSolidColorActor( BACKGROUND_COLOR );
+  backgroundColourActor.SetAnchorPoint( AnchorPoint::CENTER );
+  backgroundColourActor.SetParentOrigin( ParentOrigin::CENTER );
+  backgroundColourActor.SetSize( size * BACKGROUND_SIZE_SCALE );
+  backgroundColourActor.SetZ( BACKGROUND_Z );
+  backgroundColourActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
+  backgroundLayer.Add( backgroundColourActor );
 
-  // Background
-  ImageActor layer = Dali::Toolkit::CreateSolidColorActor( BACKGROUND_COLOR );
-  layer.SetAnchorPoint( AnchorPoint::CENTER );
-  layer.SetParentOrigin( ParentOrigin::CENTER );
-  layer.SetSize( size * BACKGROUND_SIZE_SCALE );
-  layer.SetZ( BACKGROUND_Z );
-  layer.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
-
-  addToLayer.Add( layer );
-
-  // Parent the layers
-  addToLayer.Add( backgroundAnimLayer0 );
-  addToLayer.Add( backgroundAnimLayer1 );
-  addToLayer.Add( backgroundAnimLayer2 );
-
-  // Add all the children
-  AddBackgroundActors( backgroundAnimLayer0, NUM_BACKGROUND_IMAGES / 3, distanceField, size );
-  AddBackgroundActors( backgroundAnimLayer1, NUM_BACKGROUND_IMAGES / 3, distanceField, size );
-  AddBackgroundActors( backgroundAnimLayer2, NUM_BACKGROUND_IMAGES / 3, distanceField, size );
+  // Add bubbles to the bubbleContainer.
+  // Note: The bubbleContainer is parented externally to this function.
+  AddBackgroundActors( bubbleContainer, NUM_BACKGROUND_IMAGES, distanceField, size );
 }
 
 void DaliTableView::AddBackgroundActors( Actor layer, int count, BitmapImage distanceField, const Dali::Vector2& size )
@@ -904,15 +709,15 @@ void DaliTableView::AddBackgroundActors( Actor layer, int count, BitmapImage dis
     Vector3 actorPos(
         Random::Range( -size.x * 0.5f * BACKGROUND_SPREAD_SCALE, size.x * 0.5f * BACKGROUND_SPREAD_SCALE ),
         Random::Range( -size.y * 0.5f - randSize, size.y * 0.5f + randSize ),
-        Random::Range(-1.0f, 0.0f) );
+        Random::Range( BUBBLE_MIN_Z, BUBBLE_MAX_Z ) );
     dfActor.SetPosition( actorPos );
-    dfActor.SetSortModifier(size.x * 0.7f);
 
-    Constraint movementConstraint = Constraint::New < Vector3 > ( Actor::POSITION,
-        LocalSource( Actor::SIZE ),
-        ParentSource( Actor::SIZE ),
-        ShapeMovementConstraint );
-    dfActor.ApplyConstraint( movementConstraint );
+    // Define bubble horizontal parallax and vertical wrapping
+    Constraint animConstraint = Constraint::New < Vector3 > ( Actor::POSITION,
+      Source( mScrollView, mScrollView.GetPropertyIndex( ScrollView::SCROLL_POSITION_PROPERTY_NAME ) ),
+      Dali::ParentSource( Dali::Actor::SIZE ),
+      AnimateBubbleConstraint( actorPos, Random::Range( -0.85f, 0.25f ), randSize ) );
+    dfActor.ApplyConstraint( animConstraint );
 
     // Kickoff animation
     Animation animation = Animation::New( Random::Range( 40.0f, 200.0f ) );
@@ -949,8 +754,12 @@ void DaliTableView::CreateShapeImage( ShapeType shapeType, const Size& size, Bit
       break;
   }
 
-  GenerateDistanceFieldMap( &imageDataA8[ 0 ], size, distanceFieldOut.GetBuffer(), size, 8.0f, size );
-  distanceFieldOut.Update();
+  PixelBuffer* buffer = distanceFieldOut.GetBuffer();
+  if( buffer )
+  {
+    GenerateDistanceFieldMap( &imageDataA8[ 0 ], size, buffer, size, 8.0f, size );
+    distanceFieldOut.Update();
+  }
 }
 
 void DaliTableView::GenerateSquare( const Size& size, std::vector< unsigned char >& distanceFieldOut )
@@ -990,9 +799,7 @@ void DaliTableView::GenerateCircle( const Size& size, std::vector< unsigned char
 
 ImageActor DaliTableView::CreateLogo( std::string imagePath )
 {
-  Image image = Image::New( imagePath );
-  image.LoadingFinishedSignal().Connect( this, &DaliTableView::OnLogoLoaded );
-
+  Image image = ResourceImage::New( imagePath );
   ImageActor logo = ImageActor::New( image );
 
   logo.SetAnchorPoint( AnchorPoint::CENTER );
@@ -1001,11 +808,6 @@ ImageActor DaliTableView::CreateLogo( std::string imagePath )
   return logo;
 }
 
-void DaliTableView::OnLogoLoaded( Dali::Image image )
-{
-  mRootActor.SetFixedHeight( 1, image.GetHeight() + LOGO_BOTTOM_PADDING_HEIGHT );
-}
-
 bool DaliTableView::PauseBackgroundAnimation()
 {
   PauseAnimation();
@@ -1052,7 +854,7 @@ Dali::Actor DaliTableView::OnKeyboardPreFocusChange( Dali::Actor current, Dali::
   if ( !current && !proposed  )
   {
     // Set the initial focus to the first tile in the current page should be focused.
-    nextFocusActor = mTableViewList[mScrollView.GetCurrentPage()].GetChildAt(TableView::CellPosition(0, 0));
+    nextFocusActor = mPages[mScrollView.GetCurrentPage()].GetChildAt(0);
   }
   else if( !proposed || (proposed && proposed == mScrollViewLayer) )
   {
@@ -1092,12 +894,12 @@ Dali::Actor DaliTableView::OnKeyboardPreFocusChange( Dali::Actor current, Dali::
       int colPos = remainingExamples >= EXAMPLES_PER_PAGE ? EXAMPLES_PER_ROW - 1 : ( remainingExamples % EXAMPLES_PER_PAGE - rowPos * EXAMPLES_PER_ROW - 1 );
 
       // Move the focus to the last tile in the new page.
-      nextFocusActor = mTableViewList[newPage].GetChildAt(TableView::CellPosition(rowPos, colPos));
+      nextFocusActor = mPages[newPage].GetChildAt(colPos * EXAMPLES_PER_ROW + rowPos);
     }
     else
     {
       // Move the focus to the first tile in the new page.
-      nextFocusActor = mTableViewList[newPage].GetChildAt(TableView::CellPosition(0, 0));
+      nextFocusActor = mPages[newPage].GetChildAt(0);
     }
   }
 
@@ -1116,3 +918,11 @@ void DaliTableView::OnFocusedActorActivated( Dali::Actor activatedActor )
     OnTilePressed(mPressedActor, touchEventUp);
   }
 }
+
+bool DaliTableView::OnTileHovered( Actor actor, const HoverEvent& event )
+{
+  KeyboardFocusManager::Get().SetCurrentFocusActor( actor );
+  return true;
+}
+
+