Merge branch 'devel/master' into tizen 12/113812/1
authorminho.sun <minho.sun@samsung.com>
Thu, 9 Feb 2017 02:23:04 +0000 (11:23 +0900)
committerminho.sun <minho.sun@samsung.com>
Thu, 9 Feb 2017 02:23:49 +0000 (11:23 +0900)
Change-Id: I6947f0c77b5e9925ad966bc8d7004d8a72ba61dd

com.samsung.dali-demo.xml
demo/dali-table-view.cpp
examples/animated-images/animated-images-example.cpp
examples/atlas/atlas-example.cpp [deleted file]
examples/clipping/clipping-example.cpp
examples/clipping/item-view-orientation-constraint.h [new file with mode: 0644]
examples/cube-transition-effect/cube-transition-effect-example.cpp
packaging/com.samsung.dali-demo.spec
shared/utility.h

index 4b3c4d0..056fa48 100644 (file)
        <ui-application appid="animated-shapes.example" exec="/usr/apps/com.samsung.dali-demo/bin/animated-shapes.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
                <label>Animated shapes</label>
        </ui-application>
-       <ui-application appid="atlas.example" exec="/usr/apps/com.samsung.dali-demo/bin/atlas.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
-               <label>Atlas</label>
-       </ui-application>
        <ui-application appid="size-negotiation.example" exec="/usr/apps/com.samsung.dali-demo/bin/size-negotiation.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
                <label>Size Negotiation</label>
        </ui-application>
index 799304e..67b9232 100644 (file)
@@ -460,10 +460,6 @@ void DaliTableView::Populate()
         }
       }
 
-      // Set tableview position
-      Vector3 pagePos( stageSize.width * TABLE_RELATIVE_SIZE.x * t, 0.0f, 0.0f );
-      page.SetPosition( pagePos );
-
       mPages.push_back( page );
 
       if( iter == mExampleList.end() )
index 5587ab9..547bdc2 100644 (file)
@@ -34,6 +34,9 @@ const char* const ANIMATE_GIF_DOG( DEMO_IMAGE_DIR "dog-anim.gif" );
 const char* const STATIC_GIF_LOGO( DEMO_IMAGE_DIR "dali-logo-static.gif" );
 const char* const ANIMATE_GIF_LOGO( DEMO_IMAGE_DIR "dali-logo-anim.gif" );
 
+const char* const ANIMATE_PIXEL_AREA( "Animate PixelArea" );
+const char* const ANIMATE_PIXEL_AREA_AND_SCALE( "Animate PixelArea & Scale" );
+
 const Vector4 DIM_COLOR( 0.85f, 0.85f, 0.85f, 0.85f );
 }
 
@@ -67,21 +70,24 @@ public:
     // Tie-in input event handlers:
     stage.KeyEventSignal().Connect( this, &AnimatedImageController::OnKeyEvent );
 
-    mActorDog = CreateGifViewWithOverlayButton( STATIC_GIF_DOG );
+    mActorDog = CreateGifViewWithOverlayPlayButton( STATIC_GIF_DOG );
     mActorDog.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
     mActorDog.SetY( -100.f );
     stage.Add( mActorDog );
 
-    mActorLogo = CreateGifViewWithOverlayButton( STATIC_GIF_LOGO );
+    mActorLogo = CreateGifViewWithOverlayPlayButton( STATIC_GIF_LOGO );
     mActorLogo.SetAnchorPoint( AnchorPoint::TOP_CENTER );
     mActorLogo.SetY( 100.f );
     stage.Add( mActorLogo );
+
+    mTapDetector = TapGestureDetector::New();
+    mTapDetector.DetectedSignal().Connect( this, &AnimatedImageController::OnTap );
   }
 
   /**
    * Create the gif image view with an overlay play button.
    */
-  Toolkit::ImageView CreateGifViewWithOverlayButton( const std::string& gifUrl  )
+  Toolkit::ImageView CreateGifViewWithOverlayPlayButton( const std::string& gifUrl  )
   {
     Toolkit::ImageView imageView = Toolkit::ImageView::New( gifUrl );
     imageView.SetParentOrigin( ParentOrigin::CENTER );
@@ -101,6 +107,32 @@ public:
     return imageView;
   }
 
+  Toolkit::ImageView CreateGifViewWithAnimatePixelAreaButton( const std::string& gifUrl, WrapMode::Type wrapModeU, WrapMode::Type wrapModeV, const std::string& buttonLabel )
+  {
+    Toolkit::ImageView imageView = Toolkit::ImageView::New();
+    imageView.SetProperty( Toolkit::ImageView::Property::IMAGE,
+                           Property::Map().Add( Toolkit::ImageVisual::Property::URL, gifUrl )
+                                          .Add( Toolkit::ImageVisual::Property::WRAP_MODE_U, wrapModeU )
+                                          .Add( Toolkit::ImageVisual::Property::WRAP_MODE_V, wrapModeV ));
+    imageView.SetParentOrigin( ParentOrigin::CENTER );
+
+    // Create a push button, and add it as child of the image view
+    Toolkit::PushButton animateButton = Toolkit::PushButton::New();
+    animateButton.SetProperty( Toolkit::Button::Property::LABEL, buttonLabel );
+    animateButton.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
+    animateButton.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+    animateButton.SetY( 20.f );
+
+    animateButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
+    animateButton.SetProperty( Actor::Property::INHERIT_SCALE, false );
+    imageView.Add( animateButton );
+
+    mTapDetector.Attach( animateButton );
+    mTapDetector.Attach( imageView );
+
+    return imageView;
+  }
+
   bool OnPlayButtonClicked( Toolkit::Button button )
   {
     Stage stage = Stage::GetCurrent();
@@ -111,8 +143,7 @@ public:
       // remove the static gif view, the play button is also removed as its child.
       stage.Remove( mActorDog );
 
-      mActorDog = Toolkit::ImageView::New( ANIMATE_GIF_DOG );
-      mActorDog.SetParentOrigin( ParentOrigin::CENTER );
+      mActorDog = CreateGifViewWithAnimatePixelAreaButton( ANIMATE_GIF_DOG, WrapMode::REPEAT, WrapMode::DEFAULT, ANIMATE_PIXEL_AREA_AND_SCALE );
       mActorDog.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
       mActorDog.SetY( -100.f );
       stage.Add( mActorDog );
@@ -122,8 +153,7 @@ public:
       // remove the static gif view, the play button is also removed as its child.
       stage.Remove( mActorLogo );
 
-      mActorLogo = Toolkit::ImageView::New( ANIMATE_GIF_LOGO );
-      mActorLogo.SetParentOrigin( ParentOrigin::CENTER );
+      mActorLogo = CreateGifViewWithAnimatePixelAreaButton( ANIMATE_GIF_LOGO, WrapMode::DEFAULT, WrapMode::MIRRORED_REPEAT, ANIMATE_PIXEL_AREA );
       mActorLogo.SetAnchorPoint( AnchorPoint::TOP_CENTER );
       mActorLogo.SetY( 100.f );
       stage.Add( mActorLogo );
@@ -131,6 +161,42 @@ public:
     return true;
   }
 
+  void OnTap(Dali::Actor actor, const Dali::TapGesture& tap)
+  {
+    if( actor.GetParent() ==  mActorDog ) // "Animate Pixel Area" button is clicked
+    {
+      Animation animation = Animation::New( 3.f );
+      animation.AnimateTo( Property( mActorDog, ImageView::Property::PIXEL_AREA ), Vector4( -1.0, 0.0, 3.f, 1.f ), AlphaFunction::SIN );
+      animation.AnimateTo( Property( mActorDog, Actor::Property::SCALE_X ), 3.f, AlphaFunction::SIN );
+      animation.Play();
+    }
+    else if( actor.GetParent() ==  mActorLogo ) // "Animate Pixel Area" button is clicked
+    {
+      Animation animation = Animation::New( 3.f );
+      animation.AnimateTo( Property( mActorLogo, ImageView::Property::PIXEL_AREA ), Vector4( 0.0, 1.0, 1.f, 1.f ), AlphaFunction::SIN );
+      animation.Play();
+    }
+    else if( actor == mActorDog ) // stop the animated gif, switch to static view
+    {
+      Stage stage = Stage::GetCurrent();
+      stage.Remove( mActorDog );
+
+      mActorDog = CreateGifViewWithOverlayPlayButton( STATIC_GIF_DOG );
+      mActorDog.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
+      mActorDog.SetY( -100.f );
+      stage.Add( mActorDog );
+    }
+    else if( actor == mActorLogo ) // stop the animated gif, switch to static view
+    {
+      Stage stage = Stage::GetCurrent();
+      stage.Remove( mActorLogo );
+
+      mActorLogo = CreateGifViewWithOverlayPlayButton( STATIC_GIF_LOGO );
+      mActorLogo.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+      mActorLogo.SetY( 100.f );
+      stage.Add( mActorLogo );
+    }
+  }
 
   void OnKeyEvent(const KeyEvent& event)
   {
@@ -147,6 +213,7 @@ private:
   Application&  mApplication;
   Toolkit::ImageView mActorDog;
   Toolkit::ImageView mActorLogo;
+  TapGestureDetector mTapDetector;
 };
 
 // Entry point for Linux & Tizen applications
diff --git a/examples/atlas/atlas-example.cpp b/examples/atlas/atlas-example.cpp
deleted file mode 100644 (file)
index 05483dc..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (c) 2017 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 <dali/dali.h>
-#include <dali/devel-api/images/atlas.h>
-#include <dali-toolkit/devel-api/controls/buttons/button-devel.h>
-
-#include "shared/view.h"
-#include <iostream>
-#include <cstdio>
-
-using namespace Dali;
-
-class AtlasController;
-
-namespace
-{
-const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-gradient.jpg" );
-const char * const TOOLBAR_IMAGE( DEMO_IMAGE_DIR "top-bar.png" );
-const char * const LOSE_CONTEXT_IMAGE( DEMO_IMAGE_DIR "icon-cluster-wobble.png" );
-const char * const LOSE_CONTEXT_IMAGE_SELECTED( DEMO_IMAGE_DIR "icon-cluster-wobble-selected.png" );
-
-Application gApplication;
-AtlasController* gAtlasController(NULL);
-}
-
-class AtlasController : public ConnectionTracker
-{
-public:
-
-  AtlasController( Application& application )
-  : mApplication( application )
-  {
-    // Connect to the Application's Init signal
-    mApplication.InitSignal().Connect( this, &AtlasController::Create );
-  }
-
-  ~AtlasController()
-  {
-    // Nothing to do here;
-  }
-
-  void Create( Application& application )
-  {
-    // Get a handle to the stage
-    Stage stage = Stage::GetCurrent();
-    stage.SetBackgroundColor(Color::YELLOW);
-
-    // Respond to a click anywhere on the stage
-    stage.KeyEventSignal().Connect(this, &AtlasController::OnKeyEvent);
-
-    mApplication.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
-
-    mContentLayer = DemoHelper::CreateView( mApplication,
-        mView,
-        mToolBar,
-        BACKGROUND_IMAGE,
-        TOOLBAR_IMAGE,
-        "Atlas" );
-
-    mLoseContextButton = Toolkit::PushButton::New();
-    mLoseContextButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, LOSE_CONTEXT_IMAGE );
-    mLoseContextButton.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, LOSE_CONTEXT_IMAGE_SELECTED );
-    mLoseContextButton.ClickedSignal().Connect( this, &AtlasController::OnLoseContextButtonClicked );
-    mToolBar.AddControl( mLoseContextButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
-
-    mAtlas = Atlas::New( 400,700, Pixel::RGBA8888);
-    mAtlas.Clear(Vector4(0.f,0.5f,0.5f,0.25f));
-    mAtlas.Upload( DEMO_IMAGE_DIR "icon-change.png", 50, 30 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "icon-cluster-carousel.png", 100, 30 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "icon-effects-on.png", 150, 30 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "icon-effect-cross.png", 100, 80 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "icon-effect-fold.png", 150, 80 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "icon-effect-wave.png", 200, 80 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "icon-item-view-layout-depth.png", 150, 130 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "icon-item-view-layout-grid.png", 200, 130 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "icon-item-view-layout-spiral.png", 250, 130 );
-
-    UploadBufferImages();
-    UploadPixelData();
-
-    mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-1.jpg", 4, 304 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-2.jpg", 136, 304 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-3.jpg", 268, 304 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-4.jpg", 4, 436 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-5.jpg", 136, 436 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-6.jpg", 268, 436 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-7.jpg", 4, 568 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-7.jpg", 136, 568 );
-    mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-7.jpg", 268, 568 );
-
-
-    Toolkit::ImageView imageView = Toolkit::ImageView::New( mAtlas );
-
-    imageView.SetParentOrigin(ParentOrigin::CENTER);
-    mContentLayer.Add( imageView );
-
-    mPanGestureDetector = PanGestureDetector::New();
-    mPanGestureDetector.DetectedSignal().Connect( this, &AtlasController::OnPanGesture );
-    mPanGestureDetector.Attach( imageView );
-
-    stage.ContextLostSignal().Connect( this, &AtlasController::OnContextLost );
-    stage.ContextRegainedSignal().Connect( this, &AtlasController::OnContextRegained );
-  }
-
-  void UploadBufferImages()
-  {
-    mAtlas.Upload( CreateBufferImage( Vector4(1.f, 1.f, 1.f, 0.5f  ), 80, 90 ), 0, 210 );
-    mAtlas.Upload( CreateBufferImage( Vector4(1.f, 1.f, 0.75f, 0.5f  ), 80, 80 ), 40, 210 );
-    mAtlas.Upload( CreateBufferImage( Vector4(1.f, 1.f, 0.5f, 0.5f  ), 80, 70 ), 80, 210 );
-    mAtlas.Upload( CreateBufferImage( Vector4(1.f, 1.f, 0.25f, 0.5f  ), 80, 60 ), 120, 210 );
-    mAtlas.Upload( CreateBufferImage( Vector4(1.f, 1.f, 0.f, 0.5f  ), 80, 50 ), 160, 210 );
-    mAtlas.Upload( CreateBufferImage( Vector4(0.75f, 0.75f, 0.f, 0.5f  ), 80, 40 ), 200, 210 );
-    mAtlas.Upload( CreateBufferImage( Vector4(0.5f, 0.5f, 0.f, 0.5f  ), 80, 30 ), 240, 210 );
-    mAtlas.Upload( CreateBufferImage( Vector4(0.25f, 0.25f, 0.f, 0.5f  ), 80, 20 ), 280, 210 );
-    mAtlas.Upload( CreateBufferImage( Vector4(0.1f, 0.1f, 0.f, 0.5f  ), 80, 10 ), 320, 210 );
-  }
-
-  void UploadPixelData()
-  {
-    mAtlas.Upload( CreatePixelData( Vector3(1.f, 1.f, 0.f ), 40, 40 ), 320, 30 );
-    mAtlas.Upload( CreatePixelData( Vector3(0.f, 1.f, 1.f ), 40, 40 ), 320, 80 );
-    mAtlas.Upload( CreatePixelData( Vector3(1.f, 0.f, 1.f ), 40, 40 ), 320, 130 );
-  }
-
-  static void NewWindow(void)
-  {
-    PositionSize posSize(0, 0, 720, 1280);
-    gApplication.ReplaceWindow(posSize, "NewWindow"); // Generates a new window
-  }
-
-  bool OnLoseContextButtonClicked( Toolkit::Button button )
-  {
-    // Add as an idle callback to avoid ProcessEvents being recursively called.
-    mApplication.AddIdle(MakeCallback( AtlasController::NewWindow ));
-    return true;
-  }
-
-  void OnKeyEvent( const KeyEvent& event )
-  {
-    if(event.state == KeyEvent::Down)
-    {
-      if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
-      {
-        mApplication.Quit();
-      }
-    }
-  }
-
-  void OnPanGesture( Actor actor, const PanGesture& gesture )
-  {
-    if( gesture.state == Gesture::Continuing )
-    {
-      actor.TranslateBy( Vector3( gesture.displacement ) );
-    }
-  }
-
-  void OnContextLost()
-  {
-    printf("Stage reporting context loss\n");
-  }
-
-  void OnContextRegained()
-  {
-    printf("Stage reporting context regain\n");
-    UploadBufferImages();
-    UploadPixelData();
-  }
-
-private:
-
-  BufferImage CreateBufferImage( const Vector4& color, const unsigned int width, const unsigned int height )
-  {
-    BufferImage imageData = BufferImage::New( width, height, Pixel::RGBA8888 );
-
-    // Create the image
-    PixelBuffer* pixbuf = imageData.GetBuffer();
-    const unsigned int bitmapSize = width * height;
-    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;
-    }
-
-    return imageData;
-  }
-
-  PixelData CreatePixelData( const Vector3& color, const unsigned int width, const unsigned int height )
-  {
-    unsigned int size = width*height;
-    unsigned int bufferSize = size * Pixel::GetBytesPerPixel(Pixel::RGB888);
-    unsigned char* pixels = new unsigned char [bufferSize];
-    for( unsigned int i = 0; i < size; i++ )
-    {
-      pixels[i*3u] = 0xFF * color.x;
-      pixels[i*3u+1u] = 0xFF * color.y;
-      pixels[i*3u+2u] = 0xFF * color.z;
-    }
-    return PixelData::New( pixels, bufferSize, width, height, Pixel::RGB888, PixelData::DELETE_ARRAY );
-  }
-
-
-private:
-  Application&  mApplication;
-  PanGestureDetector mPanGestureDetector;
-
-  Toolkit::Control           mView;                              ///< The View instance.
-  Toolkit::ToolBar           mToolBar;                           ///< The View's Toolbar.
-  Layer                      mContentLayer;                      ///< Content layer (scrolling cluster content)
-  Toolkit::PushButton        mLoseContextButton;
-  Atlas                      mAtlas;
-};
-
-void RunTest( Application& application )
-{
-  gAtlasController = new AtlasController(application);
-  application.MainLoop(Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS);
-}
-
-// Entry point for Linux & Tizen applications
-//
-int DALI_EXPORT_API main( int argc, char **argv )
-{
-  gApplication = Application::New( &argc, &argv, DEMO_THEME_PATH );
-
-  RunTest( gApplication );
-
-  return 0;
-}
index 4db5147..6598b68 100644 (file)
@@ -24,6 +24,7 @@
 
 // INTERNAL INCLUDES
 #include "clipping-item-factory.h"
+#include "item-view-orientation-constraint.h"
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -32,8 +33,13 @@ namespace
 {
 const char * const APPLICATION_TITLE( "Clipping Controls" );
 const Vector3 APPLICATION_TITLE_PARENT_ORIGIN( 0.5f, 0.03f, 0.5f ); // Set the parent origin to a small percentage below the top (so the demo will scale for different resolutions).
+
 const Vector3 ITEM_VIEW_LAYOUT_SIZE_SCALE( 0.75f, 0.5f, 0.75f );
 const float ITEM_VIEW_BORDER_SIZE = 2.0f;
+const float ITEM_VIEW_MAXIMUM_ROTATION_IN_DEGREES = 20.0f;
+const float ITEM_VIEW_LAYOUT_POSITION_CHANGE_MULTIPLIER = 3.0f;
+const float ITEM_VIEW_ROTATION_ANIMATION_TIME = 0.2f;
+
 const char * const BUTTON_LABEL( "Toggle Clipping Mode" );
 } // unnamed namespace
 
@@ -44,6 +50,8 @@ const char * const BUTTON_LABEL( "Toggle Clipping Mode" );
  * need to clip to. UI Controls automate the creation of the renderers/visuals when they are set to clip their children.
  *
  * This example displays an item-view whose clipping mode is toggled without the need for adding any renderers to it.
+ *
+ * Additionally, a constraint is used to modify the item-view's orientation.
  */
 class ClippingExample : public ConnectionTracker
 {
@@ -100,6 +108,14 @@ private:
     const Vector3 itemViewLayoutSize( ITEM_VIEW_LAYOUT_SIZE_SCALE.x * stageSize.x, ITEM_VIEW_LAYOUT_SIZE_SCALE.y * stageSize.y, ITEM_VIEW_LAYOUT_SIZE_SCALE.z * stageSize.x );
     mItemView.ActivateLayout( 0, itemViewLayoutSize, 0.0f );
 
+    // Connect to the scroll started and completed signals to apply orientation constraints & animations.
+    mItemView.ScrollStartedSignal().Connect( this, &ClippingExample::ScrollStarted );
+    mItemView.ScrollCompletedSignal().Connect( this, &ClippingExample::ScrollCompleted );
+
+    // Create a constraint for the item-view which we apply when we start scrolling and remove when we stop.
+    mItemViewOrientationConstraint = Constraint::New< Quaternion >( mItemView, Actor::Property::ORIENTATION, ItemViewOrientationConstraint( ITEM_VIEW_MAXIMUM_ROTATION_IN_DEGREES, ITEM_VIEW_LAYOUT_POSITION_CHANGE_MULTIPLIER ) );
+    mItemViewOrientationConstraint.AddSource( LocalSource( ItemView::Property::LAYOUT_POSITION ) );
+
     // Create a border around item-view (as item-view is clipping its children, we should NOT add this as a child of item-view).
     Control border = Control::New();
     border.SetParentOrigin( ParentOrigin::CENTER );
@@ -107,10 +123,16 @@ private:
     border.SetProperty( Control::Property::BACKGROUND,
                         Property::Map().Add( Visual::Property::TYPE, Visual::BORDER )
                                        .Add( BorderVisual::Property::COLOR, Color::WHITE )
-                                       .Add( BorderVisual::Property::SIZE, 2.0f ) );
+                                       .Add( BorderVisual::Property::SIZE, 2.0f )
+                                       .Add( BorderVisual::Property::ANTI_ALIASING, true ) );
     border.SetSize( Vector3( itemViewLayoutSize.x + ITEM_VIEW_BORDER_SIZE * 2.0f, itemViewLayoutSize.y + ITEM_VIEW_BORDER_SIZE * 2.0f, itemViewLayoutSize.z + ITEM_VIEW_BORDER_SIZE * 2.0f ) );
     stage.Add( border );
 
+    // Constrain the border's orientation to the orientation of item-view.
+    Constraint constraint = Constraint::New< Quaternion >( border, Actor::Property::ORIENTATION, EqualToConstraint() );
+    constraint.AddSource( Source( mItemView, Actor::Property::ORIENTATION ) );
+    constraint.Apply();
+
     // Create a button to toggle the clipping mode
     PushButton button = Toolkit::PushButton::New();
     button.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
@@ -118,14 +140,36 @@ private:
     button.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
     button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
     button.SetProperty( Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D );
-    button.SetProperty( Button::Property::LABEL,
-                        Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT )
-                                       .Add( Toolkit::TextVisual::Property::TEXT, BUTTON_LABEL ) );
+    button.SetProperty( Button::Property::LABEL, BUTTON_LABEL );
     button.ClickedSignal().Connect( this, &ClippingExample::OnButtonClicked );
     stage.Add( button );
   }
 
   /**
+   * @brief Called when the item-view starts to scroll.
+   *
+   * Here we want to apply the item-view constraint.
+   */
+  void ScrollStarted( const Vector2& /* currentScrollPosition */ )
+  {
+    mItemViewOrientationConstraint.Apply();
+  }
+
+  /**
+   * @brief Called when the item-view scrolling completes.
+   *
+   * Here we remove the item-view orientation constraint and perform an animation to return the item-view back to base-rotation.
+   */
+  void ScrollCompleted( const Vector2& /* currentScrollPosition */ )
+  {
+    Animation animation = Animation::New( ITEM_VIEW_ROTATION_ANIMATION_TIME );
+    animation.AnimateTo( Property( mItemView, Actor::Property::ORIENTATION ), Quaternion( Degree( 0.0f ), Vector3::XAXIS ), AlphaFunction::EASE_IN_SINE );
+    animation.Play();
+
+    mItemViewOrientationConstraint.Remove();
+  }
+
+  /**
    * @brief Called when any key event is received
    *
    * Will use this to quit the application if Back or the Escape key is received
@@ -163,6 +207,7 @@ private:
   Application& mApplication; ///< Reference to the application class.
   ItemView mItemView; ///< The item view which whose children we would like to clip.
   ClippingItemFactory mClippingItemFactory; ///< The ItemFactory used to create our items.
+  Constraint mItemViewOrientationConstraint; ///< The constraint used to control the orientation of item-view.
 };
 
 int DALI_EXPORT_API main( int argc, char **argv )
diff --git a/examples/clipping/item-view-orientation-constraint.h b/examples/clipping/item-view-orientation-constraint.h
new file mode 100644 (file)
index 0000000..0ff4bf9
--- /dev/null
@@ -0,0 +1,102 @@
+#ifndef ITEM_VIEW_ORIENTATION_CONSTRAINT_H
+#define ITEM_VIEW_ORIENTATION_CONSTRAINT_H
+
+/*
+ * Copyright (c) 2017 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/constraint.h>
+#include <dali/public-api/math/degree.h>
+#include <dali/public-api/math/math-utils.h>
+#include <dali/public-api/math/quaternion.h>
+#include <dali/public-api/math/radian.h>
+#include <dali/public-api/math/vector3.h>
+
+/**
+ * @brief Constraint used to constrain the orientation of the item-view depending on the position within the layout.
+ */
+class ItemViewOrientationConstraint
+{
+public:
+
+  /**
+   * @brief Constructor.
+   * @param[in] maximumRotationInDegrees       The maximum rotation (in degrees) that we should rotate the item-view by.
+   * @param[in] layoutPositionChangeMultiplier This value is used to multiply the change in layout position
+   *                                           (in order to exaggerate the amount moved so it's more visible).
+   */
+  ItemViewOrientationConstraint( float maximumRotationInDegrees, float layoutPositionChangeMultiplier )
+  : mMaximumRotationInDegrees( maximumRotationInDegrees ),
+    mLayoutPositionChangeMultiplier( layoutPositionChangeMultiplier ),
+    mStartingLayoutPosition( 0.0f ),
+    mStartingAngle( 0.0f ),
+    mFirstCall( true )
+  {
+  }
+
+  /**
+   * @brief Will be called by the Constraint.
+   *
+   * The first time this operator is called, it uses the values as it's base reference.
+   * Thereafter, the position in the layout is used to determine the rotation around the X-Axis.
+   *
+   * @param[in] rotation The rotation of the item-view.
+   * @param[in] inputs   The constraint inputs:
+   *                     [0] ItemView::Property::LAYOUT_POSITION, float
+   */
+  void operator()( Dali::Quaternion& rotation, const Dali::PropertyInputContainer& inputs )
+  {
+    const float& layoutPosition = inputs[ 0 ]->GetFloat();
+
+    // Store values for base reference when called the first call.
+    if( mFirstCall )
+    {
+      mStartingLayoutPosition = layoutPosition;
+
+      Dali::Vector3 axis;
+      Dali::Radian angleInRadians;
+      rotation.ToAxisAngle( axis, angleInRadians );
+      Dali::Degree angleInDegrees( angleInRadians ); // Convert to Degrees
+
+      mStartingAngle = angleInDegrees.degree;
+      if( axis.x < 0.0f ) // We only rotate round the X-Axis. So if the X-Axis is negative, then the angle is also a negative angle.
+      {
+        mStartingAngle = -mStartingAngle;
+      }
+
+      mFirstCall = false;
+    }
+    else
+    {
+      // All subsequent calls should tilt the orientation of the item-view around the X-Axis depending on how much our position has changed in the layout.
+
+      Dali::Degree angle( mStartingAngle + mLayoutPositionChangeMultiplier * ( mStartingLayoutPosition - layoutPosition ) );
+      Dali::ClampInPlace( angle.degree, -mMaximumRotationInDegrees, mMaximumRotationInDegrees ); // Ensure the angle does not exceed maximum specified (in both directions).
+      rotation = Dali::Quaternion( angle, Dali::Vector3::XAXIS );
+    }
+  }
+
+private:
+
+  const float mMaximumRotationInDegrees; ///< The maximum allowable rotation of the item-view.
+  const float mLayoutPositionChangeMultiplier; ///< This value is used to multiply the change in layout position.
+  float mStartingLayoutPosition; ///< The starting layout position.
+  float mStartingAngle; ///< The starting angle (in degrees) of the item-view.
+  bool mFirstCall; ///< A boolean to state whether this is the first time the operator() is called. Allows us to set the starting values.
+};
+
+#endif // ITEM_VIEW_ORIENTATION_CONSTRAINT_H
index 9cc96a2..5f338e4 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali/dali.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali-toolkit/devel-api/controls/buttons/button-devel.h>
+#include <dali-toolkit/devel-api/controls/buttons/toggle-button.h>
 #include <dali-toolkit/devel-api/transition-effects/cube-transition-effect.h>
 #include <dali-toolkit/devel-api/transition-effects/cube-transition-cross-effect.h>
 #include <dali-toolkit/devel-api/transition-effects/cube-transition-fold-effect.h>
@@ -192,8 +193,6 @@ private:
 
   Vector2                         mPanPosition;
   Vector2                         mPanDisplacement;
-
-  Toolkit::PushButton             mEffectChangeButton;
 };
 
 CubeTransitionApp::CubeTransitionApp( Application& application )
@@ -218,12 +217,18 @@ void CubeTransitionApp::OnInit( Application& application )
   mContent = DemoHelper::CreateView( application, mView, mToolBar, "", TOOLBAR_IMAGE, "" );
   mContent.SetBehavior( Layer::LAYER_3D );
 
-  // Add an effect-changing button on the right of the tool bar.
-  mEffectChangeButton = Toolkit::PushButton::New();
-  mEffectChangeButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, EFFECT_WAVE_IMAGE );
-  mEffectChangeButton.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, EFFECT_WAVE_IMAGE_SELECTED );
-  mEffectChangeButton.ClickedSignal().Connect( this, &CubeTransitionApp::OnEffectButtonClicked );
-  mToolBar.AddControl( mEffectChangeButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
+
+  // Add an effect changing toggle button
+  Toolkit::ToggleButton effectChangeToggleButton = Toolkit::ToggleButton::ToggleButton::New();
+
+  effectChangeToggleButton.SetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS,
+                                        Property::Array().Add( EFFECT_WAVE_IMAGE )
+                                                         .Add( EFFECT_CROSS_IMAGE)
+                                                         .Add( EFFECT_FOLD_IMAGE )
+                                      );
+
+  effectChangeToggleButton.ClickedSignal().Connect( this, &CubeTransitionApp::OnEffectButtonClicked );
+  mToolBar.AddControl( effectChangeToggleButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
 
   // Add title to the tool bar.
   mTitle = DemoHelper::CreateToolBarLabel( APPLICATION_TITLE_WAVE );
@@ -325,23 +330,16 @@ bool CubeTransitionApp::OnEffectButtonClicked( Toolkit::Button button )
   {
     mCurrentEffect = mCubeCrossEffect;
     mTitle.SetProperty( TextLabel::Property::TEXT, std::string(APPLICATION_TITLE_CROSS) );
-    mEffectChangeButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, EFFECT_CROSS_IMAGE );
-    mEffectChangeButton.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, EFFECT_CROSS_IMAGE_SELECTED );
-
   }
   else if(mCurrentEffect == mCubeCrossEffect)
   {
     mCurrentEffect = mCubeFoldEffect;
     mTitle.SetProperty( TextLabel::Property::TEXT, std::string(APPLICATION_TITLE_FOLD) );
-    mEffectChangeButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, EFFECT_FOLD_IMAGE );
-    mEffectChangeButton.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, EFFECT_FOLD_IMAGE_SELECTED );
   }
   else
   {
     mCurrentEffect = mCubeWaveEffect;
     mTitle.SetProperty( TextLabel::Property::TEXT, std::string(APPLICATION_TITLE_WAVE) );
-    mEffectChangeButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, EFFECT_WAVE_IMAGE );
-    mEffectChangeButton.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, EFFECT_WAVE_IMAGE_SELECTED );
   }
   mContent.Add( mCurrentEffect );
 
index 5d81885..737fa81 100755 (executable)
@@ -2,7 +2,7 @@
 
 Name:       com.samsung.dali-demo
 Summary:    The OpenGLES Canvas Core Demo
-Version:    1.2.22
+Version:    1.2.25
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0
index ece3327..283ae33 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 #include <dali/dali.h>
-#include <dali/devel-api/images/atlas.h>
 #include <dali/devel-api/adaptor-framework/bitmap-loader.h>
 #include <dali/public-api/rendering/geometry.h>
 #include <dali/public-api/rendering/texture.h>