Added radial menu demo 87/22187/2
authorDavid Steele <david.steele@partner.samsung.com>
Thu, 29 May 2014 17:12:38 +0000 (18:12 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Thu, 29 May 2014 17:40:07 +0000 (18:40 +0100)
(Shows off stencil mode and animated meshes)

Change-Id: I0ed8f6de271ca914edd570434b27ff37edb1ab6f
Signed-off-by: David Steele <david.steele@partner.samsung.com>
12 files changed:
build/tizen/examples/Makefile.am
com.samsung.dali-demo.xml
demo/dali-demo.cpp
demo/images/layer1.png [new file with mode: 0644]
demo/images/layer2.png [new file with mode: 0644]
demo/images/layer3.png [new file with mode: 0644]
demo/images/layer4.png [new file with mode: 0644]
examples/radial-menu/radial-menu-example.cpp [new file with mode: 0644]
examples/radial-menu/radial-sweep-view-impl.cpp [new file with mode: 0644]
examples/radial-menu/radial-sweep-view-impl.h [new file with mode: 0644]
examples/radial-menu/radial-sweep-view.cpp [new file with mode: 0644]
examples/radial-menu/radial-sweep-view.h [new file with mode: 0644]

index 8e48fd3d23b1a36debc5c9286801ff48591461ea..51c5a79100ae1406a8307e08531ef8bfd951ddc6 100644 (file)
@@ -28,6 +28,7 @@ bin_PROGRAMS = \
                motion-blur.example \
                motion-stretch.example \
                page-turn-view.example \
+               radial-menu.example \
                scroll-view.example \
                shadow-bone-lighting.example
 
@@ -51,7 +52,7 @@ EXAMPLE_CXXFLAGS      = $(DALI_CFLAGS) \
 
 EXAMPLE_DEPS =
 
-EXAMPLE_LDADD = $(DALI_LIBS) $(DALI_TOOLKIT_LIBS) $(ECORE_X_LIBS) $(CAPI_MEDIA_PLAYER_LIBS) $(CAPI_APPFW_APPLICATION_LIBS) -lrt
+EXAMPLE_LDADD = $(DALI_LIBS) $(DALI_TOOLKIT_LIBS) $(ECORE_X_LIBS) $(CAPI_MEDIA_PLAYER_LIBS) $(CAPI_APPFW_APPLICATION_LIBS) -lrt -lEGL
 
 
 blocks_example_SOURCES = $(examples_src_dir)/blocks/blocks-example.cpp
@@ -109,6 +110,13 @@ page_turn_view_example_CXXFLAGS = $(EXAMPLE_CXXFLAGS)
 page_turn_view_example_DEPENDENCIES = $(EXAMPLE_DEPS)
 page_turn_view_example_LDADD = $(EXAMPLE_LDADD)
 
+radial_menu_example_SOURCES = $(examples_src_dir)/radial-menu/radial-menu-example.cpp \
+                              $(examples_src_dir)/radial-menu/radial-sweep-view.cpp \
+                              $(examples_src_dir)/radial-menu/radial-sweep-view-impl.cpp
+radial_menu_example_CXXFLAGS = $(EXAMPLE_CXXFLAGS)
+radial_menu_example_DEPENDENCIES = $(EXAMPLE_DEPS)
+radial_menu_example_LDADD = $(EXAMPLE_LDADD)
+
 scroll_view_example_SOURCES = $(examples_src_dir)/scroll-view/scroll-view-example.cpp
 scroll_view_example_CXXFLAGS = $(EXAMPLE_CXXFLAGS)
 scroll_view_example_DEPENDENCIES = $(EXAMPLE_DEPS)
index c53e728c83ad5153a61906f5bff67ffd223950bf..3ebe285cbb609b3699d2059aa12517ab82c6d9be 100644 (file)
@@ -43,6 +43,9 @@
        <ui-application appid="motion-stretch.example" exec="/opt/apps/com.samsung.dali-demo/bin/motion-stretch.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
                <label>Motion Stretch</label>
        </ui-application>
+       <ui-application appid="radial-menu.example" exec="/opt/apps/com.samsung.dali-demo/bin/radial-menu.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
+               <label>Radial Menu</label>
+       </ui-application>
        <ui-application appid="scroll-view.example" exec="/opt/apps/com.samsung.dali-demo/bin/scroll-view.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
                <label>Scroll View</label>
        </ui-application>
index 9194f65a395323b402338f66b1fc309fe6be9ca9..2bd7d2491bed7c99d158ef5824b038c58b322089 100644 (file)
@@ -34,6 +34,7 @@ int main(int argc, char **argv)
   demo.AddExample(Example("motion-blur.example", "Motion Blur"));
   demo.AddExample(Example("motion-stretch.example", "Motion Stretch"));
   demo.AddExample(Example("page-turn-view.example", "Page Turn View"));
+  demo.AddExample(Example("radial-menu.example", "Radial Menu"));
   demo.AddExample(Example("scroll-view.example", "Scroll View"));
   demo.AddExample(Example("shadow-bone-lighting.example", "Lights and shadows"));
   app.MainLoop();
diff --git a/demo/images/layer1.png b/demo/images/layer1.png
new file mode 100644 (file)
index 0000000..7a2d7b0
Binary files /dev/null and b/demo/images/layer1.png differ
diff --git a/demo/images/layer2.png b/demo/images/layer2.png
new file mode 100644 (file)
index 0000000..01a8942
Binary files /dev/null and b/demo/images/layer2.png differ
diff --git a/demo/images/layer3.png b/demo/images/layer3.png
new file mode 100644 (file)
index 0000000..dd9f44b
Binary files /dev/null and b/demo/images/layer3.png differ
diff --git a/demo/images/layer4.png b/demo/images/layer4.png
new file mode 100644 (file)
index 0000000..75464c8
Binary files /dev/null and b/demo/images/layer4.png differ
diff --git a/examples/radial-menu/radial-menu-example.cpp b/examples/radial-menu/radial-menu-example.cpp
new file mode 100644 (file)
index 0000000..0525096
--- /dev/null
@@ -0,0 +1,282 @@
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.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://floralicense.org/license/
+//
+// 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-toolkit/dali-toolkit.h>
+#include "../shared/view.h"
+#include "radial-sweep-view.h"
+#include "radial-sweep-view-impl.h"
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+namespace
+{
+const char* TEST_OUTER_RING_FILENAME = DALI_IMAGE_DIR "layer2.png"; // Image to be masked
+const char* TEST_INNER_RING_FILENAME = DALI_IMAGE_DIR "layer1.png"; // Image to be masked
+const char* TEST_MENU_FILENAME = DALI_IMAGE_DIR "layer3.png"; // Image to be masked
+const char* TEST_DIAL_FILENAME = DALI_IMAGE_DIR "layer4.png"; // Image to be masked
+const char* BACKGROUND_IMAGE( DALI_IMAGE_DIR "desktop_background.png" ); // Background for view
+const char* TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" ); // Background for toolbar
+const char* APPLICATION_TITLE( "Radial Menu" );
+const char * const PLAY_ICON( DALI_IMAGE_DIR "icon-play.png" );
+const char * const STOP_ICON( DALI_IMAGE_DIR "icon-stop.png" );
+}
+
+
+/********************************************************************************
+ * Application controller class
+ */
+
+// This example shows how to create a mesh actor for use as a stencil buffer
+class RadialMenuExample : public ConnectionTracker
+{
+public:
+  /**
+   * Constructor
+   * @param[in] app The application handle
+   */
+  RadialMenuExample(Application app);
+
+  /**
+   * Destructor
+   */
+  ~RadialMenuExample();
+
+private:
+
+  /**
+   * Initialization signal handler - all actor initialization should happen here
+   * @param[in] app The application handle
+   */
+  void OnInit(Application& app);
+
+  /**
+   * Create a sweep view with the given image and parameters
+   */
+  RadialSweepView CreateSweepView( std::string imageName, Degree initial, Degree final );
+
+  void StartAnimation();
+
+  bool OnButtonClicked( Toolkit::Button button );
+
+  void OnAnimationFinished( Animation& source );
+
+  /**
+   * Main key event handler
+   *
+   * @param[in] event The key event to respond to
+   */
+  void OnKeyEvent(const KeyEvent& event);
+
+private: // Member variables
+  enum AnimState
+  {
+    STOPPED,
+    PAUSED,
+    PLAYING
+  };
+
+  Application     mApplication; ///< The application handle
+  Toolkit::View   mView;        ///< The toolbar view
+  Layer           mContents;    ///< The toolbar contents pane
+  ImageActor      mImageActor;  ///< Image actor shown by stencil mask
+  Animation       mAnimation;
+  AnimState       mAnimationState;
+
+  Image               mIconPlay;
+  Image               mIconStop;
+  Toolkit::PushButton mPlayStopButton;
+  ImageActor      mDialActor;
+  RadialSweepView mRadialSweepView1;
+  RadialSweepView mRadialSweepView2;
+  RadialSweepView mRadialSweepView3;
+};
+
+RadialMenuExample::RadialMenuExample(Application app)
+: mApplication( app ),
+  mAnimationState(STOPPED)
+{
+  // Connect to the Application's Init signal
+  app.InitSignal().Connect(this, &RadialMenuExample::OnInit);
+}
+
+RadialMenuExample::~RadialMenuExample()
+{
+  // Nothing to do here; actor handles will clean up themselves.
+}
+
+void RadialMenuExample::OnInit(Application& app)
+{
+  // The Init signal is received once (only) during the Application lifetime
+  Stage::GetCurrent().KeyEventSignal().Connect(this, &RadialMenuExample::OnKeyEvent);
+
+  // Create toolbar & view
+  Toolkit::ToolBar toolBar;
+  mContents = DemoHelper::CreateView( mApplication,
+                                      mView,
+                                      toolBar,
+                                      BACKGROUND_IMAGE,
+                                      TOOLBAR_IMAGE,
+                                      APPLICATION_TITLE );
+
+  mIconPlay = Image::New( PLAY_ICON );
+  mIconStop = Image::New( STOP_ICON );
+  mPlayStopButton = Toolkit::PushButton::New();
+  mPlayStopButton.SetBackgroundImage( mIconStop );
+
+  mPlayStopButton.ClickedSignal().Connect( this, &RadialMenuExample::OnButtonClicked );
+
+  toolBar.AddControl( mPlayStopButton,
+                      DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage,
+                      Toolkit::Alignment::HorizontalRight,
+                      DemoHelper::DEFAULT_PLAY_PADDING );
+
+  Vector2 imgSize = Image::GetImageSize(TEST_OUTER_RING_FILENAME);
+  float scale = Stage::GetCurrent().GetSize().width / imgSize.width;
+
+  mRadialSweepView1 = CreateSweepView( TEST_OUTER_RING_FILENAME, Degree(-90.0f), Degree(-90.0f));
+  mRadialSweepView2 = CreateSweepView( TEST_INNER_RING_FILENAME, Degree(90.0f),  Degree(0.0f));
+  mRadialSweepView3 = CreateSweepView( TEST_MENU_FILENAME, Degree(100.0f), Degree(0.0f));
+  mRadialSweepView3.SetInitialActorAngle(Degree(-110));
+  mRadialSweepView3.SetFinalActorAngle(Degree(0));
+
+  Image dial = Image::New( TEST_DIAL_FILENAME );
+  mDialActor = ImageActor::New( dial );
+  mDialActor.SetPositionInheritanceMode(USE_PARENT_POSITION);
+  mDialActor.SetScale(scale);
+  Layer dialLayer = Layer::New();
+
+  dialLayer.Add(mDialActor);
+  dialLayer.SetPositionInheritanceMode(USE_PARENT_POSITION);
+  dialLayer.SetSize(Stage::GetCurrent().GetSize());
+  mContents.Add(dialLayer);
+
+  mRadialSweepView1.SetScale(scale);
+  mRadialSweepView2.SetScale(scale);
+  mRadialSweepView3.SetScale(scale);
+
+  StartAnimation();
+}
+
+void RadialMenuExample::StartAnimation()
+{
+  mDialActor.SetOpacity(0.0f);
+  mRadialSweepView1.SetOpacity(0.0f);
+  mAnimation = Animation::New(6.0f);
+  mRadialSweepView1.Activate(mAnimation, 0.0f, 3.0f);
+  mRadialSweepView2.Activate(mAnimation, 1.5f, 3.0f);
+  mRadialSweepView3.Activate(mAnimation, 3.0f, 3.0f);
+  mAnimation.OpacityTo(mDialActor, 1.0f, AlphaFunctions::EaseIn, 0.0f, 0.8f);
+  mAnimation.OpacityTo(mRadialSweepView1, 1.0f, AlphaFunctions::EaseIn, 0.0f, 0.5f);
+  mAnimation.FinishedSignal().Connect( this, &RadialMenuExample::OnAnimationFinished );
+
+  mAnimationState = PLAYING;
+  mAnimation.Play();
+}
+
+bool RadialMenuExample::OnButtonClicked( Toolkit::Button button )
+{
+  switch( mAnimationState )
+  {
+    case PLAYING:
+    {
+      mAnimation.Pause();
+      mPlayStopButton.SetBackgroundImage( mIconPlay );
+    }
+    break;
+
+    case PAUSED:
+    {
+      mAnimation.Play();
+      mPlayStopButton.SetBackgroundImage( mIconStop );
+    }
+    break;
+
+    case STOPPED:
+    {
+      mPlayStopButton.SetBackgroundImage( mIconStop );
+      mRadialSweepView1.Deactivate();
+      mRadialSweepView2.Deactivate();
+      mRadialSweepView3.Deactivate();
+      StartAnimation();
+    }
+  }
+  return false;
+}
+
+void RadialMenuExample::OnAnimationFinished( Animation& source )
+{
+  mAnimationState = STOPPED;
+  mPlayStopButton.SetBackgroundImage( mIconPlay );
+}
+
+RadialSweepView RadialMenuExample::CreateSweepView( std::string imageName,
+                                                    Degree initialAngle,
+                                                    Degree finalAngle)
+{
+  // Create the image
+  Image image = Image::New(imageName);
+  mImageActor = ImageActor::New(image);
+  mImageActor.SetParentOrigin(ParentOrigin::CENTER);
+  mImageActor.SetAnchorPoint(AnchorPoint::CENTER);
+
+  // Create the stencil
+  float diameter = std::max(image.GetWidth(), image.GetHeight());
+  RadialSweepView radialSweepView = RadialSweepView::New();
+  radialSweepView.SetDiameter( diameter );
+  radialSweepView.SetInitialAngle( initialAngle );
+  radialSweepView.SetFinalAngle( finalAngle );
+  radialSweepView.SetInitialSector( Degree(0.0f) );
+  radialSweepView.SetFinalSector( Degree(359.999f) );
+  radialSweepView.SetSize( Stage::GetCurrent().GetSize());
+  radialSweepView.SetEasingFunction( Dali::AlphaFunctions::EaseInOut );
+  radialSweepView.SetPositionInheritanceMode(USE_PARENT_POSITION);
+  mContents.Add(radialSweepView);
+  radialSweepView.Add( mImageActor );
+  mImageActor.SetPositionInheritanceMode(USE_PARENT_POSITION);
+
+  return radialSweepView;
+}
+
+
+void RadialMenuExample::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 RunTest(Application app)
+{
+  RadialMenuExample test(app);
+
+  app.MainLoop();
+}
+
+// Entry point for Linux & Tizen applications
+int main(int argc, char **argv)
+{
+  Application app = Application::New(&argc, &argv);
+
+  RunTest(app);
+
+  return 0;
+}
diff --git a/examples/radial-menu/radial-sweep-view-impl.cpp b/examples/radial-menu/radial-sweep-view-impl.cpp
new file mode 100644 (file)
index 0000000..81457e6
--- /dev/null
@@ -0,0 +1,378 @@
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.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://floralicense.org/license/
+//
+// 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 "radial-sweep-view-impl.h"
+
+using namespace Dali;
+
+namespace
+{
+
+/**
+ * Method to project a point on a circle of radius halfSide at given
+ * angle onto a square of side 2 * halfSide
+ */
+Vector3 CircleSquareProjection( Degree angle, float halfSide )
+{
+  Vector3 position(0.0f, 0.0f, 0.0f);
+  Radian angleInRadians(angle);
+
+  //  135  90   45
+  //     +--+--+
+  //     | \|/ |
+  // 180 +--+--+ 0
+  //     | /|\ |
+  //     +--+--+
+  //  225  270  315
+  if( angle >= 45.0f && angle < 135.0f )
+  {
+    position.x = halfSide * cosf(angleInRadians) / sinf(angleInRadians);
+    position.y = -halfSide;
+  }
+  else if( angle >= 135.0f && angle < 225.0f )
+  {
+    position.x = -halfSide;
+    position.y = halfSide * sinf(angleInRadians) / cosf(angleInRadians);
+  }
+  else if( angle >= 225.0f && angle < 315.0f )
+  {
+    position.x = -halfSide * cosf(angleInRadians) / sinf(angleInRadians);
+    position.y =  halfSide;
+  }
+  else
+  {
+    position.x = halfSide;
+    position.y = -halfSide * sinf(angleInRadians) / cosf(angleInRadians);
+  }
+  return position;
+}
+
+float HoldZeroFastEaseInOutHoldOne(float progress)
+{
+  if( progress < 0.2f)
+  {
+    return 0.0f;
+  }
+  else if(progress < 0.5f)
+  {
+    return AlphaFunctions::EaseIn((progress-0.2) / 0.3f) * 0.5f;
+  }
+  else if(progress < 0.8f)
+  {
+    return AlphaFunctions::EaseOut((progress - 0.5f) / 0.3f) * 0.5f + 0.5f;
+  }
+  else
+  {
+    return 1.0f;
+  }
+}
+
+struct SquareFanConstraint
+{
+  SquareFanConstraint(int sideIndex)
+  : mSideIndex(sideIndex)
+  {
+  }
+
+  Vector3 operator()( const Vector3& current, const PropertyInput& start, const PropertyInput& rotation )
+  {
+    float degree = fmodf((start.GetFloat() + rotation.GetFloat()), 360.0f);
+    if(degree < 0.0f)
+    {
+      degree += 360.0f;
+    }
+
+    float startAngle = (90.0f*mSideIndex)-45.0f;
+    float endAngle = (90.0f*mSideIndex)+45.0f;
+    if(degree < startAngle)
+    {
+      return Vector3::ZERO;
+    }
+    else if( degree >= endAngle )
+    {
+      degree = endAngle;
+    }
+    Vector3 pos = CircleSquareProjection(Degree(degree), 0.5f);
+    pos.x = -pos.x; // Inverting X makes the animation go anti clockwise from left center
+    return pos;
+  }
+
+  int mSideIndex;
+};
+
+} // anonymous namespace
+
+
+RadialSweepView RadialSweepViewImpl::New( )
+{
+  return New( 2.0f, 100.0f, Degree(0.0f), Degree(0.0f), Degree(0.0f), Degree(359.999f) );
+}
+
+
+RadialSweepView RadialSweepViewImpl::New( float duration, float diameter, Degree initialAngle, Degree finalAngle, Degree initialSector, Degree finalSector )
+{
+  RadialSweepViewImpl* impl= new RadialSweepViewImpl(duration, diameter, initialAngle, finalAngle, initialSector, finalSector);
+  RadialSweepView handle = RadialSweepView(*impl);
+  return handle;
+}
+
+RadialSweepViewImpl::RadialSweepViewImpl( float duration, float diameter, Degree initialAngle, Degree finalAngle, Degree initialSector, Degree finalSector )
+: Control( false ),
+  mDuration(duration),
+  mDiameter(diameter),
+  mInitialAngle(initialAngle),
+  mFinalAngle(finalAngle),
+  mInitialSector(initialSector),
+  mFinalSector(finalSector),
+  mInitialActorAngle(0),
+  mFinalActorAngle(0),
+  mEasingFunction(HoldZeroFastEaseInOutHoldOne),
+  mRotateActorsWithStencil(false),
+  mRotateActors(false)
+{
+}
+
+void RadialSweepViewImpl::SetDuration(float duration)
+{
+  mDuration = duration;
+}
+
+void RadialSweepViewImpl::SetEasingFunction( Dali::AlphaFunction easingFunction )
+{
+  mEasingFunction = easingFunction;
+}
+
+void RadialSweepViewImpl::SetDiameter(float diameter)
+{
+  mDiameter = diameter;
+}
+
+void RadialSweepViewImpl::SetInitialAngle( Dali::Degree initialAngle)
+{
+  mInitialAngle = initialAngle;
+}
+
+void RadialSweepViewImpl::SetFinalAngle( Dali::Degree finalAngle)
+{
+  mFinalAngle = finalAngle;
+}
+
+void RadialSweepViewImpl::SetInitialSector( Dali::Degree initialSector)
+{
+  mInitialSector = initialSector;
+}
+
+void RadialSweepViewImpl::SetFinalSector( Dali::Degree finalSector)
+{
+  mFinalSector = finalSector;
+}
+
+void RadialSweepViewImpl::SetInitialActorAngle( Dali::Degree initialAngle )
+{
+  mInitialActorAngle = initialAngle;
+  mRotateActors = true;
+}
+
+void RadialSweepViewImpl::SetFinalActorAngle( Dali::Degree finalAngle )
+{
+  mFinalActorAngle = finalAngle;
+  mRotateActors = true;
+}
+
+float RadialSweepViewImpl::GetDuration( )
+{
+  return mDuration;
+}
+
+float RadialSweepViewImpl::GetDiameter( )
+{
+  return mDiameter;
+}
+
+Dali::Degree RadialSweepViewImpl::GetInitialAngle( )
+{
+  return mInitialAngle;
+}
+
+Dali::Degree RadialSweepViewImpl::GetFinalAngle( )
+{
+  return mFinalAngle;
+}
+
+Dali::Degree RadialSweepViewImpl::GetInitialSector( )
+{
+  return mInitialSector;
+}
+
+Dali::Degree RadialSweepViewImpl::GetFinalSector( )
+{
+  return mFinalSector;
+}
+
+Dali::Degree RadialSweepViewImpl::GetInitialActorAngle( )
+{
+  return mInitialActorAngle;
+}
+
+Dali::Degree RadialSweepViewImpl::GetFinalActorAngle(  )
+{
+  return mFinalActorAngle;
+}
+
+void RadialSweepViewImpl::RotateActorsWithStencil(bool rotate)
+{
+  mRotateActorsWithStencil = rotate;
+}
+
+void RadialSweepViewImpl::Add(Actor actor)
+{
+  if( ! mLayer )
+  {
+    mLayer = Layer::New();
+    Self().Add(mLayer);
+    mLayer.SetSize( Stage::GetCurrent().GetSize() );
+    mLayer.SetPositionInheritanceMode(USE_PARENT_POSITION);
+  }
+
+  mLayer.Add(actor);
+}
+
+void RadialSweepViewImpl::Activate( Animation anim, float offsetTime, float duration )
+{
+  bool startAnimation=false;
+  if( ! anim )
+  {
+    mAnim = Animation::New( mDuration );
+    anim = mAnim;
+    startAnimation = true;
+  }
+
+  if( ! mStencilActor )
+  {
+    CreateStencil( mInitialSector );
+    mLayer.Add( mStencilActor );
+    mStencilActor.SetSize(mDiameter, mDiameter);
+  }
+
+  mStencilActor.SetRotation( Degree(mInitialAngle), Vector3::ZAXIS );
+  mStencilActor.SetProperty( mRotationAngleIndex, static_cast<float>(mInitialSector) );
+
+  if( mRotateActors )
+  {
+    for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
+    {
+      Actor actor = mLayer.GetChildAt(i);
+      if( actor != mStencilActor )
+      {
+        anim.RotateTo( actor, mInitialActorAngle, Vector3::ZAXIS );
+      }
+    }
+  }
+
+  anim.AnimateTo( Property( mStencilActor, mRotationAngleIndex ), static_cast<float>(mFinalSector), mEasingFunction, TimePeriod( offsetTime, duration) );
+  anim.RotateTo( mStencilActor, mFinalAngle, Vector3::ZAXIS, mEasingFunction, offsetTime, duration );
+
+  if( mRotateActorsWithStencil )
+  {
+    for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
+    {
+      Actor actor = mLayer.GetChildAt(i);
+      if( actor != mStencilActor )
+      {
+        anim.RotateTo( actor, Degree(mFinalAngle - mInitialAngle), Vector3::ZAXIS, mEasingFunction, offsetTime, duration );
+      }
+    }
+  }
+  else if( mRotateActors )
+  {
+    for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
+    {
+      Actor actor = mLayer.GetChildAt(i);
+      if( actor != mStencilActor )
+      {
+        anim.RotateTo( actor, mFinalActorAngle, Vector3::ZAXIS, mEasingFunction, offsetTime, duration );
+      }
+    }
+  }
+
+
+  if( startAnimation )
+  {
+    anim.SetLooping(true);
+    anim.Play();
+  }
+}
+
+
+void RadialSweepViewImpl::Deactivate()
+{
+  if( mAnim )
+  {
+    mAnim.Stop();
+  }
+  // mLayer.Remove( mStencilActor );
+  // mStencilActor.Reset();
+  // mMesh.Reset();
+  // mMaterial.Reset();
+}
+
+void RadialSweepViewImpl::CreateStencil( Degree initialSector )
+{
+  mMaterial = Material::New("Material");
+  mMaterial.SetDiffuseColor(Color::WHITE);
+  mMaterial.SetAmbientColor(Vector4(0.0, 0.1, 0.1, 1.0));
+
+  // Generate a square mesh with a point at the center:
+
+  AnimatableMesh::Faces faces;
+  // Create triangles joining up the verts
+  faces.push_back(0); faces.push_back(1); faces.push_back(2);
+  faces.push_back(0); faces.push_back(2); faces.push_back(3);
+  faces.push_back(0); faces.push_back(3); faces.push_back(4);
+  faces.push_back(0); faces.push_back(4); faces.push_back(5);
+  faces.push_back(0); faces.push_back(5); faces.push_back(6);
+
+  mMesh = AnimatableMesh::New(7, faces, mMaterial);
+  mMesh[0].SetPosition( Vector3(  0.0f,  0.0f, 0.0f ) ); // Center pt
+
+  mStencilActor = MeshActor::New(mMesh);
+  mStencilActor.SetAffectedByLighting(false);
+  mStencilActor.SetCullFace(CullNone); // Allow clockwise & anticlockwise faces
+
+  mStartAngleIndex = mStencilActor.RegisterProperty("start-angle", Property::Value(0.0f));
+  mRotationAngleIndex = mStencilActor.RegisterProperty("rotation-angle", Property::Value(initialSector));
+
+  Source srcStart( mStencilActor, mStartAngleIndex );
+  Source srcRot( mStencilActor, mRotationAngleIndex );
+
+  // Constrain the vertices of the square mesh to sweep out a sector as the
+  // rotation angle is animated.
+  mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(1, AnimatableVertex::POSITION),
+                                                  srcStart, srcStart, SquareFanConstraint(0)));
+  mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(2, AnimatableVertex::POSITION),
+                                                  srcStart, srcRot, SquareFanConstraint(0)));
+  mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(3, AnimatableVertex::POSITION),
+                                                  srcStart, srcRot, SquareFanConstraint(1)));
+  mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(4, AnimatableVertex::POSITION),
+                                                  srcStart, srcRot, SquareFanConstraint(2)));
+  mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(5, AnimatableVertex::POSITION),
+                                                  srcStart, srcRot, SquareFanConstraint(3)));
+  mMesh.ApplyConstraint(Constraint::New<Vector3>( mMesh.GetPropertyIndex(6, AnimatableVertex::POSITION),
+                                                  srcStart, srcRot, SquareFanConstraint(4)));
+
+  mStencilActor.SetDrawMode( DrawMode::STENCIL );
+  mStencilActor.SetPositionInheritanceMode(USE_PARENT_POSITION);
+}
diff --git a/examples/radial-menu/radial-sweep-view-impl.h b/examples/radial-menu/radial-sweep-view-impl.h
new file mode 100644 (file)
index 0000000..6ed3432
--- /dev/null
@@ -0,0 +1,119 @@
+#ifndef DALI_DEMO_RADIAL_SWEEP_VIEW_IMPL_H
+#define DALI_DEMO_RADIAL_SWEEP_VIEW_IMPL_H
+
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.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://floralicense.org/license/
+//
+// 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-toolkit/dali-toolkit.h>
+#include "radial-sweep-view.h"
+
+
+/********************************************************************************
+ * Class to implement a layer with a radial sweep stencil mask and an actor tree
+ */
+class RadialSweepViewImpl : public Dali::Toolkit::Internal::Control
+{
+public:
+  static RadialSweepView New();
+
+  static RadialSweepView New( float duration,
+                              float diameter,
+                              Dali::Degree initialAngle,
+                              Dali::Degree finalAngle,
+                              Dali::Degree initialSector,
+                              Dali::Degree finalSector );
+
+  RadialSweepViewImpl( float duration,
+                       float diameter,
+                       Dali::Degree initialAngle,
+                       Dali::Degree finalAngle,
+                       Dali::Degree initialSector,
+                       Dali::Degree finalSector );
+
+  void SetDuration(float duration);
+  void SetEasingFunction( Dali::AlphaFunction easingFunction );
+
+  void SetDiameter(float diameter);
+  void SetInitialAngle( Dali::Degree initialAngle);
+  void SetFinalAngle( Dali::Degree finalAngle);
+  void SetInitialSector( Dali::Degree initialSector);
+  void SetFinalSector( Dali::Degree finalSector);
+  void SetInitialActorAngle( Dali::Degree initialAngle );
+  void SetFinalActorAngle( Dali::Degree finalAngle );
+
+  float GetDuration( );
+  float GetDiameter( );
+  Dali::Degree GetInitialAngle( );
+  Dali::Degree GetFinalAngle( );
+  Dali::Degree GetInitialSector( );
+  Dali::Degree GetFinalSector( );
+  Dali::Degree GetInitialActorAngle( );
+  Dali::Degree GetFinalActorAngle( );
+
+  void RotateActorsWithStencil(bool rotate);
+
+  void Add( Dali::Actor actor );
+
+  void Activate( Dali::Animation anim = Dali::Animation(), float offsetTime=0, float duration=2.0f );
+
+  void Deactivate();
+
+private:
+
+  /**
+   * Create the stencil mask
+   */
+  void CreateStencil(Dali::Degree initialSector );
+
+private:
+  Dali::Layer           mLayer;
+  Dali::Animation       mAnim;
+  float                 mDuration;
+  float                 mDiameter;
+  Dali::Degree          mInitialAngle;
+  Dali::Degree          mFinalAngle;
+  Dali::Degree          mInitialSector;
+  Dali::Degree          mFinalSector;
+  Dali::Degree          mInitialActorAngle;
+  Dali::Degree          mFinalActorAngle;
+  Dali::AlphaFunction   mEasingFunction;
+  Dali::MeshActor       mStencilActor;       ///< Stencil actor which generates mask
+  Dali::Material        mMaterial;           ///< Material for drawing mesh actor
+  Dali::AnimatableMesh  mMesh;               ///< Animatable mesh
+  Dali::Property::Index mStartAngleIndex;    ///< Index of start-angle property
+  Dali::Property::Index mRotationAngleIndex; ///< Index of rotation-angle property
+  bool                  mRotateActorsWithStencil:1;
+  bool                  mRotateActors;
+};
+
+
+inline RadialSweepViewImpl& GetImpl( RadialSweepView& obj )
+{
+  DALI_ASSERT_ALWAYS(obj);
+  Dali::RefObject& handle = obj.GetImplementation();
+  return static_cast<RadialSweepViewImpl&>(handle);
+}
+
+inline const RadialSweepViewImpl& GetImpl( const RadialSweepView& obj )
+{
+  DALI_ASSERT_ALWAYS(obj);
+  const Dali::RefObject& handle = obj.GetImplementation();
+  return static_cast<const RadialSweepViewImpl&>(handle);
+}
+
+
+
+#endif // DALI_DEMO_RADIAL_SWEEP_VIEW_IMPL_H
diff --git a/examples/radial-menu/radial-sweep-view.cpp b/examples/radial-menu/radial-sweep-view.cpp
new file mode 100644 (file)
index 0000000..de7dc92
--- /dev/null
@@ -0,0 +1,183 @@
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.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://floralicense.org/license/
+//
+// 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 "radial-sweep-view.h"
+#include "radial-sweep-view-impl.h"
+
+using namespace Dali;
+
+RadialSweepView::RadialSweepView()
+{
+}
+
+RadialSweepView::RadialSweepView(const RadialSweepView& handle)
+: Control(handle)
+{
+}
+
+RadialSweepView& RadialSweepView::operator=(const RadialSweepView& rhs)
+{
+  if( &rhs != this )
+  {
+    Control::operator=(rhs);
+  }
+  return *this;
+}
+
+RadialSweepView::~RadialSweepView()
+{
+}
+
+RadialSweepView RadialSweepView::DownCast( BaseHandle handle )
+{
+  return Control::DownCast<RadialSweepView, RadialSweepViewImpl>(handle);
+}
+
+RadialSweepView RadialSweepView::New( )
+{
+  return RadialSweepViewImpl::New();
+}
+
+RadialSweepView RadialSweepView::New( float duration,
+                                      float diameter,
+                                      Degree initialAngle,
+                                      Degree finalAngle,
+                                      Degree initialSector,
+                                      Degree finalSector )
+{
+  return RadialSweepViewImpl::New(duration, diameter, initialAngle, finalAngle, initialSector, finalSector );
+}
+
+RadialSweepView::RadialSweepView( RadialSweepViewImpl& impl )
+: Control( impl )
+{
+}
+
+RadialSweepView::RadialSweepView( Dali::Internal::CustomActor* impl )
+: Control( impl )
+{
+  VerifyCustomActorPointer<RadialSweepViewImpl>(impl);
+}
+
+void RadialSweepView::SetDuration(float duration)
+{
+  GetImpl(*this).SetDuration(duration);
+}
+
+void RadialSweepView::SetEasingFunction( Dali::AlphaFunction easingFunction )
+{
+  GetImpl(*this).SetEasingFunction( easingFunction );
+}
+
+void RadialSweepView::SetDiameter(float diameter)
+{
+  GetImpl(*this).SetDiameter(diameter);
+}
+
+void RadialSweepView::SetInitialAngle( Dali::Degree initialAngle)
+{
+  GetImpl(*this).SetInitialAngle(initialAngle);
+}
+
+void RadialSweepView::SetFinalAngle( Dali::Degree finalAngle)
+{
+  GetImpl(*this).SetFinalAngle(finalAngle);
+}
+
+void RadialSweepView::SetInitialSector( Dali::Degree initialSector)
+{
+  GetImpl(*this).SetInitialSector(initialSector);
+}
+
+void RadialSweepView::SetFinalSector( Dali::Degree finalSector)
+{
+  GetImpl(*this).SetFinalSector(finalSector);
+}
+
+void RadialSweepView::SetInitialActorAngle( Dali::Degree initialAngle )
+{
+  GetImpl(*this).SetInitialActorAngle(initialAngle);
+}
+
+void RadialSweepView::SetFinalActorAngle( Dali::Degree finalAngle )
+{
+  GetImpl(*this).SetFinalActorAngle(finalAngle);
+}
+
+float RadialSweepView::GetDuration( )
+{
+  return GetImpl(*this).GetDuration();
+}
+
+float RadialSweepView::GetDiameter( )
+{
+  return GetImpl(*this).GetDiameter();
+}
+
+Dali::Degree RadialSweepView::GetInitialAngle( )
+{
+  return GetImpl(*this).GetInitialAngle();
+}
+
+Dali::Degree RadialSweepView::GetFinalAngle( )
+{
+  return GetImpl(*this).GetFinalAngle();
+}
+
+Dali::Degree RadialSweepView::GetInitialSector( )
+{
+  return GetImpl(*this).GetInitialSector();
+}
+
+Dali::Degree RadialSweepView::GetFinalSector( )
+{
+  return GetImpl(*this).GetFinalSector();
+}
+
+Dali::Degree RadialSweepView::GetInitialActorAngle( )
+{
+  return GetImpl(*this).GetInitialActorAngle();
+}
+
+Dali::Degree RadialSweepView::GetFinalActorAngle( )
+{
+  return GetImpl(*this).GetFinalActorAngle();
+}
+
+void RadialSweepView::RotateActorsWithStencil(bool rotate)
+{
+  GetImpl(*this).RotateActorsWithStencil(rotate);
+}
+
+void RadialSweepView::Add(Actor actor)
+{
+  GetImpl(*this).Add(actor);
+}
+
+void RadialSweepView::Activate()
+{
+  GetImpl(*this).Activate();
+}
+
+void RadialSweepView::Activate( Dali::Animation anim, float offsetTime, float duration )
+{
+  GetImpl(*this).Activate(anim, offsetTime, duration);
+}
+
+void RadialSweepView::Deactivate()
+{
+  GetImpl(*this).Deactivate();
+}
diff --git a/examples/radial-menu/radial-sweep-view.h b/examples/radial-menu/radial-sweep-view.h
new file mode 100644 (file)
index 0000000..f5a36e4
--- /dev/null
@@ -0,0 +1,149 @@
+#ifndef DALI_DEMO_RADIAL_SWEEP_VIEW_H
+#define DALI_DEMO_RADIAL_SWEEP_VIEW_H
+
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.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://floralicense.org/license/
+//
+// 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-toolkit/dali-toolkit.h>
+
+class RadialSweepViewImpl;
+
+
+/********************************************************************************
+ * Handle to RadialSweepView implementation
+ */
+class RadialSweepView : public Dali::Toolkit::Control
+{
+public:
+  /**
+   * Create a new RadialSweepView with default parameters (2 second animation,
+   * no rotation, sweeping out a full cicle).
+   */
+  static RadialSweepView New( );
+
+  /**
+   * Create a new RadialSweepView.
+   * @param[in] duration The duration of the sweep animation
+   * @param[in] diameter The diameter of the stencil mask
+   * @param[in] initialAngle The initial angle of the anticlockwise line of the sweep sector
+   * @param[in] finalAngle The final angle of the anticlockwise line of the sweep sector
+   * @param[in] initialSector The angle of the starting sector
+   * @param[in] finalSector The angle of the sector at the end of the animation.
+   * Note, to cover the entire circle, use a value of 359.9999f, not zero or 360.
+   *
+   *            initial sector
+   *             \   |  .
+   *              \  |    .
+   * initialAngle  \ |     .   final sector
+   *                \|      _|
+   *                 .________
+   */
+  static RadialSweepView New( float duration,
+                              float diameter,
+                              Dali::Degree initialAngle,
+                              Dali::Degree finalAngle,
+                              Dali::Degree initialSector,
+                              Dali::Degree finalSector );
+
+  void SetDuration(float duration);
+
+  void SetEasingFunction( Dali::AlphaFunction easingFunction );
+
+  void SetDiameter(float diameter);
+
+  void SetInitialAngle( Dali::Degree initialAngle);
+
+  void SetFinalAngle( Dali::Degree finalAngle);
+
+  void SetInitialSector( Dali::Degree initialSector);
+
+  void SetFinalSector( Dali::Degree finalSector);
+
+  void SetInitialActorAngle( Dali::Degree initialAngle );
+
+  void SetFinalActorAngle( Dali::Degree finalAngle );
+
+  float GetDuration( );
+
+  float GetDiameter( );
+
+  Dali::Degree GetInitialAngle( );
+
+  Dali::Degree GetFinalAngle( );
+
+  Dali::Degree GetInitialSector( );
+
+  Dali::Degree GetFinalSector( );
+
+  Dali::Degree GetInitialActorAngle( );
+
+  Dali::Degree GetFinalActorAngle( );
+
+  /**
+   * @param[in] rotate True if the actors should rotate with the stencil
+   */
+  void RotateActorsWithStencil(bool rotate);
+
+  /**
+   * Add actors to the view
+   */
+  void Add(Actor actor);
+
+  /**
+   * Activate the sweep animation
+   */
+  void Activate( );
+
+  void Activate( Dali::Animation anim, float offsetTime, float duration );
+
+  /**
+   * Deactivate the sweep animation
+   */
+  void Deactivate();
+
+  /**
+   * Default constructor. Create an uninitialized handle.
+   */
+  RadialSweepView();
+
+  /**
+   * Copy constructor
+   */
+  RadialSweepView(const RadialSweepView& handle);
+
+  /**
+   * Assignment operator
+   */
+  RadialSweepView& operator=(const RadialSweepView& rhs);
+
+  /**
+   * Destructor
+   */
+  virtual ~RadialSweepView();
+
+  /**
+   * Downcast method
+   */
+  static RadialSweepView DownCast( BaseHandle handle );
+
+public: // Not for use by application developers
+
+  RadialSweepView( RadialSweepViewImpl& impl );
+
+  RadialSweepView( Dali::Internal::CustomActor* impl );
+};
+
+#endif