Added scrollMode property to ScrollView to simplify Rulers 84/128384/5
authorDavid Steele <david.steele@samsung.com>
Tue, 9 May 2017 17:26:48 +0000 (18:26 +0100)
committerDavid Steele <david.steele@samsung.com>
Wed, 17 May 2017 16:29:24 +0000 (16:29 +0000)
The rulers are hard to use and understand, and require overriding
classes in the public API. This makes binding to C# require too much
effort, and pulls too many classes into C# that otherwise don't need to
be there.

Have instead added a devel property to enable the simplification of
setting up rulers - the new property map will be used internally to
create either DefaultRuler or FixedRuler, depending on the
settings. This makes it very easy to bind to C#.

Change-Id: I5932cd32487bae77b8c41ebd35e35f6bc879be33

12 files changed:
automated-tests/src/dali-toolkit/utc-Dali-ScrollView.cpp
build/tizen/dali-toolkit/Makefile.am
dali-toolkit/devel-api/controls/scrollable/scroll-view/scroll-mode.h [new file with mode: 0644]
dali-toolkit/devel-api/controls/scrollable/scroll-view/scroll-view-devel.h [new file with mode: 0644]
dali-toolkit/devel-api/file.list
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.h
plugins/dali-sharp/dali-bindings/dali_wrap.cpp
plugins/dali-sharp/examples/scroll-view.cs
plugins/dali-sharp/sharp/internal/DaliEnumConstants.cs
plugins/dali-sharp/sharp/internal/NDalicPINVOKE.cs
plugins/dali-sharp/sharp/internal/ScrollView.cs

index 1a88abb..55a9ff6 100644 (file)
@@ -22,6 +22,8 @@
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali/integration-api/events/touch-event-integ.h>
 #include <dali/integration-api/events/pan-gesture-event.h>
+#include <dali-toolkit/devel-api/controls/scrollable/scroll-view/scroll-view-devel.h>
+#include <dali-toolkit/devel-api/controls/scrollable/scroll-view/scroll-mode.h>
 
 using namespace Dali;
 using namespace Toolkit;
@@ -277,6 +279,37 @@ float TestAlphaFunction(float progress)
   return std::min( progress * 2.0f, 1.0f );
 }
 
+static Vector2 PerformGestureDiagonalSwipe(ToolkitTestApplication& application, Vector2 start, Vector2 direction, int frames, bool finish = true)
+{
+  gOnScrollStartCalled = false;
+  gOnScrollUpdateCalled = false;
+  gOnScrollCompleteCalled = false;
+  gOnSnapStartCalled = false;
+
+  // Now do a pan starting from (start) and heading (direction)
+  Vector2 pos(start);
+  SendPan(application, Gesture::Possible, pos);
+  SendPan(application, Gesture::Started, pos);
+  Wait(application);
+
+  for(int i = 0;i<frames;i++)
+  {
+    pos += direction; // Move in this direction
+    SendPan(application, Gesture::Continuing, pos);
+    Wait(application);
+  }
+
+  if(finish)
+  {
+    pos += direction; // Move in this direction.
+    SendPan(application, Gesture::Finished, pos);
+    Wait(application, RENDER_DELAY_SCROLL);
+  }
+
+  return pos;
+}
+
+
 } // unnamed namespace
 
 
@@ -591,6 +624,215 @@ int UtcDaliToolkitScrollViewScrollToPageP(void)
   END_TEST;
 }
 
+
+int UtcDaliToolkitScrollModeP1(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( " UtcDaliToolkitScrollView ScrollMode property" );
+
+  // Set up a scrollView.
+  ScrollView scrollView = ScrollView::New();
+
+  // Do not rely on stage size for UTC tests.
+  Vector2 pageSize( 720.0f, 1280.0f );
+  scrollView.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
+  scrollView.SetSize( pageSize );
+  scrollView.SetParentOrigin( ParentOrigin::CENTER );
+  scrollView.SetAnchorPoint( AnchorPoint::CENTER );
+  scrollView.SetPosition( 0.0f, 0.0f, 0.0f );
+
+  // Position rulers.
+  Property::Map rulerMap;
+  rulerMap.Add( ScrollMode::X_AXIS_SCROLL_ENABLED, true );
+  rulerMap.Add( ScrollMode::X_AXIS_SNAP_TO_INTERVAL, pageSize.width );
+  rulerMap.Add( ScrollMode::X_AXIS_SCROLL_BOUNDARY, pageSize.width*3 );
+  rulerMap.Add( ScrollMode::Y_AXIS_SCROLL_ENABLED, false );
+  scrollView.SetProperty( DevelScrollView::Property::SCROLL_MODE, rulerMap);
+
+  scrollView.SetWrapMode( false );
+  scrollView.SetScrollSensitive( true );
+
+  Stage::GetCurrent().Add( scrollView );
+
+  // Set up a gesture to perform.
+  Vector2 startPos( 50.0f, 0.0f );
+  Vector2 direction( -5.0f, 0.0f );
+  int frames = 200;
+
+  // Force starting position.
+  scrollView.ScrollTo( startPos, 0.0f );
+  Wait( application );
+
+  // Deliberately skip the "Finished" part of the gesture, so we can read the coordinates before the snap begins.
+  Vector2 currentPos( PerformGestureDiagonalSwipe( application, startPos, direction, frames - 1, false ) );
+
+  // Confirm the final X coord has not moved more than one page from the start X position.
+  DALI_TEST_GREATER( ( startPos.x + pageSize.width ), scrollView.GetCurrentScrollPosition().x, TEST_LOCATION );
+
+  // Finish the gesture and wait for the snap.
+  currentPos += direction;
+  SendPan( application, Gesture::Finished, currentPos );
+  // We add RENDER_FRAME_INTERVAL on to wait for an extra frame (for the last "finished" gesture to complete first.
+  Wait( application, RENDER_DELAY_SCROLL + RENDER_FRAME_INTERVAL );
+
+  // Confirm the final X coord has snapped to exactly one page ahead of the start page.
+  DALI_TEST_EQUALS( pageSize.width, scrollView.GetCurrentScrollPosition().x, Math::MACHINE_EPSILON_0, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliToolkitScrollModeP2(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( " UtcDaliToolkitScrollView ScrollMode property" );
+
+  // Set up a scrollView.
+  ScrollView scrollView = ScrollView::New();
+
+  // Do not rely on stage size for UTC tests.
+  Vector2 pageSize( 720.0f, 1280.0f );
+  scrollView.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
+  scrollView.SetSize( pageSize );
+  scrollView.SetParentOrigin( ParentOrigin::CENTER );
+  scrollView.SetAnchorPoint( AnchorPoint::CENTER );
+  scrollView.SetPosition( 0.0f, 0.0f, 0.0f );
+
+  // Position rulers.
+  Property::Map rulerMap;
+  rulerMap.Add( ScrollMode::X_AXIS_SCROLL_ENABLED, false );
+  rulerMap.Add( ScrollMode::Y_AXIS_SCROLL_ENABLED, true );
+  rulerMap.Add( ScrollMode::Y_AXIS_SNAP_TO_INTERVAL, pageSize.height );
+  rulerMap.Add( ScrollMode::Y_AXIS_SCROLL_BOUNDARY, pageSize.height*3 );
+  scrollView.SetProperty( DevelScrollView::Property::SCROLL_MODE, rulerMap);
+
+  scrollView.SetWrapMode( false );
+  scrollView.SetScrollSensitive( true );
+
+  Stage::GetCurrent().Add( scrollView );
+
+  // Set up a gesture to perform.
+  Vector2 startPos( 0.0f, 50.0f );
+  Vector2 direction( 0.0f, -6.0f );
+  int frames = 200;
+
+  // Force starting position.
+  scrollView.ScrollTo( startPos, 0.0f );
+  Wait( application );
+
+  // Deliberately skip the "Finished" part of the gesture, so we can read the coordinates before the snap begins.
+  Vector2 currentPos( PerformGestureDiagonalSwipe( application, startPos, direction, frames - 1, false ) );
+
+  // Confirm the final X coord has not moved more than one page from the start X position.
+  DALI_TEST_GREATER( ( startPos.y + pageSize.height ), scrollView.GetCurrentScrollPosition().y, TEST_LOCATION );
+
+  // Finish the gesture and wait for the snap.
+  currentPos += direction;
+  SendPan( application, Gesture::Finished, currentPos );
+  // We add RENDER_FRAME_INTERVAL on to wait for an extra frame (for the last "finished" gesture to complete first.
+  Wait( application, RENDER_DELAY_SCROLL + RENDER_FRAME_INTERVAL );
+
+  // Confirm the final Y coord has snapped to exactly one page ahead of the start page.
+  DALI_TEST_EQUALS( pageSize.height, scrollView.GetCurrentScrollPosition().y, Math::MACHINE_EPSILON_0, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliToolkitScrollModeP3(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( " UtcDaliToolkitScrollView ScrollMode property" );
+
+  // Set up a scrollView.
+  ScrollView scrollView = ScrollView::New();
+
+  // Do not rely on stage size for UTC tests.
+  Vector2 pageSize( 720.0f, 1280.0f );
+  scrollView.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
+  scrollView.SetSize( pageSize );
+  scrollView.SetParentOrigin( ParentOrigin::CENTER );
+  scrollView.SetAnchorPoint( AnchorPoint::CENTER );
+  scrollView.SetPosition( 0.0f, 0.0f, 0.0f );
+
+  // Position rulers.
+  Property::Map rulerMap;
+  rulerMap.Add( ScrollMode::X_AXIS_SCROLL_ENABLED, false );
+  rulerMap.Add( ScrollMode::Y_AXIS_SCROLL_ENABLED, true );
+  rulerMap.Add( ScrollMode::Y_AXIS_SNAP_TO_INTERVAL, pageSize.height );
+  rulerMap.Add( ScrollMode::Y_AXIS_SCROLL_BOUNDARY, pageSize.height*3 );
+  scrollView.SetProperty( DevelScrollView::Property::SCROLL_MODE, rulerMap);
+
+  scrollView.SetWrapMode( false );
+  scrollView.SetScrollSensitive( true );
+
+  Stage::GetCurrent().Add( scrollView );
+
+  // Set up a gesture to perform.
+  Vector2 startPos( 0.0f, 50.0f );
+  Vector2 direction( 0.0f, -6.0f );
+  int frames = 200;
+
+  // Force starting position.
+  scrollView.ScrollTo( startPos, 0.0f );
+  Wait( application );
+
+  // Deliberately skip the "Finished" part of the gesture, so we can read the coordinates before the snap begins.
+  Vector2 currentPos( PerformGestureDiagonalSwipe( application, startPos, direction, frames - 1, false ) );
+
+  // Confirm the final X coord has not moved more than one page from the start X position.
+  DALI_TEST_GREATER( ( startPos.y + pageSize.height ), scrollView.GetCurrentScrollPosition().y, TEST_LOCATION );
+
+  // Finish the gesture and wait for the snap.
+  currentPos += direction;
+  SendPan( application, Gesture::Finished, currentPos );
+  // We add RENDER_FRAME_INTERVAL on to wait for an extra frame (for the last "finished" gesture to complete first.
+  Wait( application, RENDER_DELAY_SCROLL + RENDER_FRAME_INTERVAL );
+
+  // Confirm the final Y coord has snapped to exactly one page ahead of the start page.
+  DALI_TEST_EQUALS( pageSize.height, scrollView.GetCurrentScrollPosition().y, Math::MACHINE_EPSILON_0, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliToolkitScrollModeP4(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( " UtcDaliToolkitScrollView ScrollMode property, DefaultRulers" );
+
+  // Set up a scrollView.
+  ScrollView scrollView = ScrollView::New();
+
+  // Do not rely on stage size for UTC tests.
+  Vector2 pageSize( 720.0f, 1280.0f );
+  scrollView.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
+  scrollView.SetSize( pageSize );
+  scrollView.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  scrollView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+  scrollView.SetPosition( 0.0f, 0.0f, 0.0f );
+
+  // Position rulers - expect Default rulers to be used which don't snap
+  Property::Map rulerMap;
+  rulerMap.Add( ScrollMode::X_AXIS_SCROLL_ENABLED, true );
+  rulerMap.Add( ScrollMode::Y_AXIS_SCROLL_ENABLED, true );
+  scrollView.SetProperty( DevelScrollView::Property::SCROLL_MODE, rulerMap);
+
+  scrollView.SetWrapMode( false );
+  scrollView.SetScrollSensitive( true );
+
+  Stage::GetCurrent().Add( scrollView );
+
+  Vector2 START_POSITION = Vector2(10.0f, 10.0f);
+
+  scrollView.ScrollTo(START_POSITION, 0.0f);
+  Wait(application);
+  // Try a vertical swipe.
+  PerformGestureDiagonalSwipe(application, START_POSITION, Vector2(0.0f, 1.0f), 60, true);
+  // Take into account resampling done when prediction is off.
+  DALI_TEST_EQUALS( scrollView.GetCurrentScrollPosition() - Vector2(0.0f, 0.5f), Vector2(10.0f, -50.0f), 0.25f, TEST_LOCATION );
+
+
+  END_TEST;
+}
+
 int UtcDaliToolkitScrollViewScrollToPageWithDirectionBiasP(void)
 {
   ToolkitTestApplication application;
@@ -949,36 +1191,6 @@ int UtcDaliToolkitScrollViewSignalsUpdate02(void)
   END_TEST;
 }
 
-static Vector2 PerformGestureDiagonalSwipe(ToolkitTestApplication& application, Vector2 start, Vector2 direction, int frames, bool finish = true)
-{
-  gOnScrollStartCalled = false;
-  gOnScrollUpdateCalled = false;
-  gOnScrollCompleteCalled = false;
-  gOnSnapStartCalled = false;
-
-  // Now do a pan starting from (start) and heading (direction)
-  Vector2 pos(start);
-  SendPan(application, Gesture::Possible, pos);
-  SendPan(application, Gesture::Started, pos);
-  Wait(application);
-
-  for(int i = 0;i<frames;i++)
-  {
-    pos += direction; // Move in this direction
-    SendPan(application, Gesture::Continuing, pos);
-    Wait(application);
-  }
-
-  if(finish)
-  {
-    pos += direction; // Move in this direction.
-    SendPan(application, Gesture::Finished, pos);
-    Wait(application, RENDER_DELAY_SCROLL);
-  }
-
-  return pos;
-}
-
 int UtcDaliToolkitScrollViewScrollSensitive(void)
 {
   ToolkitTestApplication application;
index 7127db2..a766f83 100644 (file)
@@ -106,6 +106,7 @@ develapieffectsviewdir =        $(develapicontrolsdir)/effects-view
 develapigaussianblurviewdir =   $(develapicontrolsdir)/gaussian-blur-view
 develapimagnifierdir =          $(develapicontrolsdir)/magnifier
 develapiitemviewdir =           $(develapicontrolsdir)/scrollable/item-view
+develapiscrollviewdir =         $(develapicontrolsdir)/scrollable/scroll-view
 develapiscrollbardir =          $(develapicontrolsdir)/scroll-bar
 develapinavigationviewdir =     $(develapicontrolsdir)/navigation-view
 develapipageturnviewdir =       $(develapicontrolsdir)/page-turn-view
@@ -136,6 +137,7 @@ develapifocusmanager_HEADERS =      $(devel_api_focus_manager_header_files)
 develapigaussianblurview_HEADERS =  $(devel_api_gaussian_blur_view_header_files)
 develapiimageloader_HEADERS =       $(devel_api_image_loader_header_files)
 develapiitemview_HEADERS =          $(devel_api_item_view_header_files)
+develapiscrollview_HEADERS =        $(devel_api_scroll_view_header_files)
 develapiscrollbar_HEADERS =         $(devel_api_scroll_bar_header_files)
 develapimagnifier_HEADERS =         $(devel_api_magnifier_header_files)
 develapinavigationview_HEADERS =    $(devel_api_navigation_view_header_files)
diff --git a/dali-toolkit/devel-api/controls/scrollable/scroll-view/scroll-mode.h b/dali-toolkit/devel-api/controls/scrollable/scroll-view/scroll-mode.h
new file mode 100644 (file)
index 0000000..1f55038
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef DALI_TOOLKIT_DEVEL_API_SCROLL_VIEW_SCROLL_MODE_H
+#define DALI_TOOLKIT_DEVEL_API_SCROLL_VIEW_SCROLL_MODE_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.
+ */
+namespace Dali
+{
+namespace Toolkit
+{
+namespace ScrollMode
+{
+
+enum Type
+{
+  /**
+   * @brief True if the content can be scrolled in X axis or false if
+   * not.
+   *
+   * @details Name "xAxisScrollEnabled", type Property::BOOLEAN
+   */
+  X_AXIS_SCROLL_ENABLED,
+
+  /**
+   * @brief When set, causes scroll view to snap to multiples of the
+   * value of the interval in the X axis while flicking.
+   *
+   * By default, there is no snapping.
+   * @details Name "xAxisSnapToInterval", type Property::FLOAT
+   */
+  X_AXIS_SNAP_TO_INTERVAL,
+
+  /**
+   * @brief When set, causes scroll view unable to scroll beyond the
+   * value of the boundary in the X axis.
+   *
+   * By default, there is no boundary.
+   * @details Name "xAxisScrollBoundary", type Property::FLOAT
+   */
+  X_AXIS_SCROLL_BOUNDARY,
+
+  /**
+   * @brief True if the content can be scrolled in Y axis or false if
+   * not.
+   *
+   * @details Name "yAxisScrollEnabled", type Property::BOOLEAN
+   */
+  Y_AXIS_SCROLL_ENABLED,
+
+  /**
+   * @brief When set, causes scroll view to snap to multiples of the
+   * value of the interval in the Y axis while flicking.
+   *
+   * By default, there is no snapping.
+   * @details Name "yAxisSnapToInterval", type Property::FLOAT
+   */
+  Y_AXIS_SNAP_TO_INTERVAL,
+
+  /**
+   * @brief When set, causes scroll view unable to scroll beyond the
+   * value of the boundary in the Y axis.
+   *
+   * By default, there is no boundary.
+   * @details Name "yAxisScrollBoundary", type Property::FLOAT
+   */
+  Y_AXIS_SCROLL_BOUNDARY
+};
+
+} // ScrollMode
+} // toolkit
+} // Dali
+
+#endif //DALI_TOOLKIT_DEVEL_API_SCROLL_VIEW_SCROLL_MODE_H
diff --git a/dali-toolkit/devel-api/controls/scrollable/scroll-view/scroll-view-devel.h b/dali-toolkit/devel-api/controls/scrollable/scroll-view/scroll-view-devel.h
new file mode 100644 (file)
index 0000000..ca5b34c
--- /dev/null
@@ -0,0 +1,72 @@
+#ifndef DALI_TOOLKIT_SCROLL_VIEW_DEVEL_H
+#define DALI_TOOLKIT_SCROLL_VIEW_DEVEL_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace DevelScrollView
+{
+
+namespace Property
+{
+
+enum
+{
+  // Event side properties
+
+  WRAP_ENABLED = Dali::Toolkit::ScrollView::Property::WRAP_ENABLED,
+  PANNING_ENABLED = Dali::Toolkit::ScrollView::Property::PANNING_ENABLED,
+  AXIS_AUTO_LOCK_ENABLED = Dali::Toolkit::ScrollView::Property::AXIS_AUTO_LOCK_ENABLED,
+  WHEEL_SCROLL_DISTANCE_STEP = Dali::Toolkit::ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP,
+
+  /**
+   * @brief The scroll mode
+   * @details Name "scrollMode", type Property::MAP
+   * The scroll mode map is a frontend for the Ruler helper class, containing the following keys:
+   *
+   * | %Property Name       | Type     | Required | Description                                                                                                                           |
+   * |----------------------|----------|----------|---------------------------------------------------------------------------------------------------------------------------------------|
+   * | xAxisScrollEnabled   | BOOLEAN  | No       | True if the content can be scrolled in X axis or false if not.                                                                        |
+   * | xAxisSnapToInterval  | FLOAT    | No       | When set, causes scroll view to snap to multiples of the value of the interval in the X axis while flicking. (by default no snapping) |
+   * | xAxisScrollBoundary  | FLOAT    | No       | When set, causes scroll view unable to scroll beyond the value of the boundary in the X axis (by default no boundary)                 |
+   * | yAxisScrollEnabled   | BOOLEAN  | No       | True if the content can be scrolled in Y axis or false if not.                                                                        |
+   * | yAxisSnapToInterval  | FLOAT    | No       | When set, causes scroll view to snap to multiples of the value of the interval in the Y axis while flicking. (by default no snapping) |
+   * | yAxisScrollBoundary  | FLOAT    | No       | When set, causes scroll view unable to scroll beyond the value of the boundary in the Y axis (by default no boundary)                 |
+   *
+   * Alternatively, one can use the keys defined in the Dali::Toolkit::ScrollMode::Type enumeration.
+   */
+  SCROLL_MODE = WHEEL_SCROLL_DISTANCE_STEP + 1,
+};
+
+} // namespace Property
+
+} // namespace DevelScrollView
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_SCROLL_VIEW_DEVEL_H
index fca2972..fa85816 100644 (file)
@@ -118,6 +118,10 @@ devel_api_scripting_header_files = \
   $(devel_api_src_dir)/scripting/script.h \
   $(devel_api_src_dir)/scripting/script-plugin.h
 
+devel_api_scroll_view_header_files = \
+  $(devel_api_src_dir)/controls/scrollable/scroll-view/scroll-mode.h \
+  $(devel_api_src_dir)/controls/scrollable/scroll-view/scroll-view-devel.h
+
 devel_api_shader_effects_header_files = \
   $(devel_api_src_dir)/shader-effects/alpha-discard-effect.h \
   $(devel_api_src_dir)/shader-effects/dissolve-effect.h \
index 9c05d79..9784415 100644 (file)
 #include <dali/public-api/object/type-registry-helper.h>
 #include <dali/public-api/object/property-map.h>
 #include <dali/devel-api/object/handle-devel.h>
+#include <dali/devel-api/object/property-helper-devel.h>
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/scroll-bar/scroll-bar.h>
 #include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h>
 #include <dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view-constraints.h>
+#include <dali-toolkit/devel-api/controls/scrollable/scroll-view/scroll-view-devel.h>
+#include <dali-toolkit/devel-api/controls/scrollable/scroll-view/scroll-mode.h>
 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.h>
 #include <dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-effect-impl.h>
 
@@ -250,6 +253,7 @@ DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "wrapEnabled",                B
 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "panningEnabled",             BOOLEAN,   PANNING_ENABLED             )
 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "axisAutoLockEnabled",        BOOLEAN,   AXIS_AUTO_LOCK_ENABLED      )
 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "wheelScrollDistanceStep",    VECTOR2,   WHEEL_SCROLL_DISTANCE_STEP  )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollMode", MAP, SCROLL_MODE )
 
 DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollPosition",  VECTOR2, SCROLL_POSITION)
 DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollPrePosition",   VECTOR2, SCROLL_PRE_POSITION)
@@ -2906,6 +2910,14 @@ void ScrollView::SetProperty( BaseObject* object, Property::Index index, const P
         scrollViewImpl.SetWheelScrollDistanceStep( value.Get<Vector2>() );
         break;
       }
+      case Toolkit::DevelScrollView::Property::SCROLL_MODE:
+      {
+        Property::Map* map = value.GetMap();
+        if( map )
+        {
+          scrollViewImpl.SetScrollMode( *map );
+        }
+      }
     }
   }
 }
@@ -2947,6 +2959,90 @@ Property::Value ScrollView::GetProperty( BaseObject* object, Property::Index ind
   return value;
 }
 
+void ScrollView::SetScrollMode( const Property::Map& scrollModeMap )
+{
+  Toolkit::RulerPtr rulerX, rulerY;
+
+  // Check the scroll mode in the X axis
+  bool xAxisScrollEnabled = true;
+  Property::Value* valuePtr = scrollModeMap.Find( Toolkit::ScrollMode::X_AXIS_SCROLL_ENABLED, "xAxisScrollEnabled" );
+  if( valuePtr && valuePtr->GetType() == Property::BOOLEAN )
+  {
+    valuePtr->Get( xAxisScrollEnabled );
+  }
+
+  if( !xAxisScrollEnabled )
+  {
+    // Default ruler and disabled
+    rulerX = new Toolkit::DefaultRuler();
+    rulerX->Disable();
+  }
+  else
+  {
+    valuePtr = scrollModeMap.Find( Toolkit::ScrollMode::X_AXIS_SNAP_TO_INTERVAL, "xAxisSnapToInterval" );
+    float xAxisSnapToInterval = 0.0f;
+    if( valuePtr && valuePtr->Get( xAxisSnapToInterval ) )
+    {
+      // Fixed ruler and enabled
+      rulerX = new Toolkit::FixedRuler( xAxisSnapToInterval );
+    }
+    else
+    {
+      // Default ruler and enabled
+      rulerX = new Toolkit::DefaultRuler();
+    }
+
+    valuePtr = scrollModeMap.Find( Toolkit::ScrollMode::X_AXIS_SCROLL_BOUNDARY, "xAxisScrollBoundary" );
+    float xAxisScrollBoundary = 0.0f;
+    if( valuePtr && valuePtr->Get( xAxisScrollBoundary ) )
+    {
+      // By default ruler domain is disabled unless set
+      rulerX->SetDomain( Toolkit::RulerDomain( 0, xAxisScrollBoundary, true ) );
+    }
+  }
+
+  // Check the scroll mode in the Y axis
+  bool yAxisScrollEnabled = true;
+  valuePtr = scrollModeMap.Find( Toolkit::ScrollMode::Y_AXIS_SCROLL_ENABLED, "yAxisScrollEnabled" );
+  if( valuePtr && valuePtr->GetType() == Property::BOOLEAN )
+  {
+    valuePtr->Get( yAxisScrollEnabled );
+  }
+
+  if( !yAxisScrollEnabled )
+  {
+    // Default ruler and disabled
+    rulerY = new Toolkit::DefaultRuler();
+    rulerY->Disable();
+  }
+  else
+  {
+    valuePtr = scrollModeMap.Find( Toolkit::ScrollMode::Y_AXIS_SNAP_TO_INTERVAL, "yAxisSnapToInterval" );
+    float yAxisSnapToInterval = 0.0f;
+    if( valuePtr && valuePtr->Get( yAxisSnapToInterval ) )
+    {
+      // Fixed ruler and enabled
+      rulerY = new Toolkit::FixedRuler(yAxisSnapToInterval);
+    }
+    else
+    {
+      // Default ruler and enabled
+      rulerY = new Toolkit::DefaultRuler();
+    }
+
+    valuePtr = scrollModeMap.Find( Toolkit::ScrollMode::Y_AXIS_SCROLL_BOUNDARY, "yAxisScrollBoundary" );
+    float yAxisScrollBoundary = 0.0f;
+    if( valuePtr && valuePtr->Get( yAxisScrollBoundary ) )
+    {
+      // By default ruler domain is disabled unless set
+      rulerY->SetDomain( Toolkit::RulerDomain( 0, yAxisScrollBoundary, true ) );
+    }
+  }
+
+  SetRulerX(rulerX);
+  SetRulerY(rulerY);
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 485d508..ab5f862 100644 (file)
@@ -859,6 +859,13 @@ private:
    */
   void OnScrollUpdateNotification(Dali::PropertyNotification& source);
 
+  /**
+   * Set up default rulers using a property map
+   * @param[in] scrollModeMap A map defining the characteristics of X and Y scrolling
+   * using either FixedRuler or DefaultRuler.
+   */
+  void SetScrollMode( const Property::Map& scrollModeMap );
+
 private:
 
   // Undefined
index 5ec44c6..cfe74dc 100644 (file)
@@ -453,6 +453,7 @@ SWIGINTERN void SWIG_CSharpException(int code, const char *msg) {
 #include <dali-toolkit/devel-api/controls/page-turn-view/page-turn-view.h>
 #include <dali-toolkit/devel-api/controls/page-turn-view/page-turn-landscape-view.h>
 #include <dali-toolkit/devel-api/controls/page-turn-view/page-turn-portrait-view.h>
+#include <dali-toolkit/devel-api/controls/scrollable/scroll-view/scroll-view-devel.h>
 #include <dali-toolkit/devel-api/controls/buttons/toggle-button.h>
 
 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
@@ -72853,6 +72854,15 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Dali_ScrollView_Property_WHEEL_SCROLL_DISTANCE
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_Dali_ScrollView_Property_SCROLL_MODE_get() {
+  int jresult ;
+  int result;
+
+  result = (int)Dali::Toolkit::DevelScrollView::Property::SCROLL_MODE;
+  jresult = (int)result;
+  return jresult;
+}
+
 SWIGEXPORT int SWIGSTDCALL CSharp_Dali_ScrollView_Property_SCROLL_POSITION_get() {
   int jresult ;
   int result;
index 3199857..af93924 100755 (executable)
@@ -95,12 +95,12 @@ namespace MyCSharpExample
 
             // Set scroll view to have 3 pages in X axis and allow page snapping,
             // and also disable scrolling in Y axis.
-            RulerPtr scrollRulerX = new RulerPtr(new FixedRuler(windowSize.Width));
-            RulerPtr scrollRulerY = new RulerPtr(new DefaultRuler());
-            scrollRulerX.SetDomain(new RulerDomain(0.0f, windowSize.Width * pageColumns, true));
-            scrollRulerY.Disable();
-            _scrollView.SetRulerX(scrollRulerX);
-            _scrollView.SetRulerY(scrollRulerY);
+            Property.Map rulerMap = new Property.Map();
+            rulerMap.Add((int)Dali.Constants.ScrollModeType.XAxisScrollEnabled, new Property.Value(true));
+            rulerMap.Add((int)Dali.Constants.ScrollModeType.XAxisSnapToInterval, new Property.Value(windowSize.Width));
+            rulerMap.Add((int)Dali.Constants.ScrollModeType.XAxisScrollBoundary, new Property.Value(windowSize.Width * pageColumns ) );
+            rulerMap.Add((int)Dali.Constants.ScrollModeType.YAxisScrollEnabled, new Property.Value( false ) );
+            _scrollView.ScrollMode = rulerMap;
 
             // Create a horizontal scroll bar in the bottom of scroll view (which is optional)
             _scrollBar = new ScrollBar();
index cf7958b..305e7bf 100755 (executable)
@@ -19,6 +19,16 @@ namespace Dali
 {
   namespace Constants
   {
+    public enum ScrollModeType
+    {
+      XAxisScrollEnabled,
+      XAxisSnapToInterval,
+      XAxisScrollBoundary,
+      YAxisScrollEnabled,
+      YAxisSnapToInterval,
+      YAxisScrollBoundary
+    }
+
     public enum TextureType
     {
       Texture2D     = Dali.TextureType.TEXTURE_2D,   ///< One 2D image                            @SINCE_1_1.43
index 0fd09c4..08a7dfd 100644 (file)
@@ -37,14 +37,14 @@ class NDalicPINVOKE {
     public static extern void SWIGRegisterExceptionCallbacks_NDalic(
                                 ExceptionDelegate applicationDelegate,
                                 ExceptionDelegate arithmeticDelegate,
-                                ExceptionDelegate divideByZeroDelegate, 
-                                ExceptionDelegate indexOutOfRangeDelegate, 
+                                ExceptionDelegate divideByZeroDelegate,
+                                ExceptionDelegate indexOutOfRangeDelegate,
                                 ExceptionDelegate invalidCastDelegate,
                                 ExceptionDelegate invalidOperationDelegate,
                                 ExceptionDelegate ioDelegate,
                                 ExceptionDelegate nullReferenceDelegate,
-                                ExceptionDelegate outOfMemoryDelegate, 
-                                ExceptionDelegate overflowDelegate, 
+                                ExceptionDelegate outOfMemoryDelegate,
+                                ExceptionDelegate overflowDelegate,
                                 ExceptionDelegate systemExceptionDelegate);
 
     [global::System.Runtime.InteropServices.DllImport("NDalic", EntryPoint="SWIGRegisterExceptionArgumentCallbacks_NDalic")]
@@ -136,7 +136,7 @@ class NDalicPINVOKE {
           if (pendingException != null)
             pending = true;
         return pending;
-      } 
+      }
     }
 
     public static void Set(global::System.Exception e) {
@@ -8318,6 +8318,9 @@ class NDalicPINVOKE {
   [global::System.Runtime.InteropServices.DllImport("NDalic", EntryPoint="CSharp_Dali_ScrollView_Property_WHEEL_SCROLL_DISTANCE_STEP_get")]
   public static extern int ScrollView_Property_WHEEL_SCROLL_DISTANCE_STEP_get();
 
+  [global::System.Runtime.InteropServices.DllImport("NDalic", EntryPoint="CSharp_Dali_ScrollView_Property_SCROLL_MODE_get")]
+  public static extern int ScrollView_Property_SCROLL_MODE_get();
+
   [global::System.Runtime.InteropServices.DllImport("NDalic", EntryPoint="CSharp_Dali_ScrollView_Property_SCROLL_POSITION_get")]
   public static extern int ScrollView_Property_SCROLL_POSITION_get();
 
index 3ccaaa2..b67bbb2 100644 (file)
@@ -153,20 +153,20 @@ public class SnapStartedEventArgs : EventArgs
   public class ClampEvent : global::System.IDisposable {
     private global::System.Runtime.InteropServices.HandleRef swigCPtr;
     protected bool swigCMemOwn;
-  
+
     internal ClampEvent(global::System.IntPtr cPtr, bool cMemoryOwn) {
       swigCMemOwn = cMemoryOwn;
       swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
     }
-  
+
     internal static global::System.Runtime.InteropServices.HandleRef getCPtr(ClampEvent obj) {
       return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
     }
-  
+
     ~ClampEvent() {
       Dispose();
     }
-  
+
     public virtual void Dispose() {
       lock(this) {
         if (swigCPtr.Handle != global::System.IntPtr.Zero) {
@@ -179,68 +179,68 @@ public class SnapStartedEventArgs : EventArgs
         global::System.GC.SuppressFinalize(this);
       }
     }
-  
+
     public ClampState2D scale {
       set {
         NDalicPINVOKE.ScrollView_ClampEvent_scale_set(swigCPtr, ClampState2D.getCPtr(value));
         if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-      } 
+      }
       get {
         global::System.IntPtr cPtr = NDalicPINVOKE.ScrollView_ClampEvent_scale_get(swigCPtr);
         ClampState2D ret = (cPtr == global::System.IntPtr.Zero) ? null : new ClampState2D(cPtr, false);
         if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         return ret;
-      } 
+      }
     }
-  
+
     public ClampState2D position {
       set {
         NDalicPINVOKE.ScrollView_ClampEvent_position_set(swigCPtr, ClampState2D.getCPtr(value));
         if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-      } 
+      }
       get {
         global::System.IntPtr cPtr = NDalicPINVOKE.ScrollView_ClampEvent_position_get(swigCPtr);
         ClampState2D ret = (cPtr == global::System.IntPtr.Zero) ? null : new ClampState2D(cPtr, false);
         if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         return ret;
-      } 
+      }
     }
-  
+
     public ClampState rotation {
       set {
         NDalicPINVOKE.ScrollView_ClampEvent_rotation_set(swigCPtr, (int)value);
         if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-      } 
+      }
       get {
         ClampState ret = (ClampState)NDalicPINVOKE.ScrollView_ClampEvent_rotation_get(swigCPtr);
         if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         return ret;
-      } 
+      }
     }
-  
+
     public ClampEvent() : this(NDalicPINVOKE.new_ScrollView_ClampEvent(), true) {
       if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
     }
-  
+
   }
 
   public class SnapEvent : global::System.IDisposable {
     private global::System.Runtime.InteropServices.HandleRef swigCPtr;
     protected bool swigCMemOwn;
-  
+
     internal SnapEvent(global::System.IntPtr cPtr, bool cMemoryOwn) {
       swigCMemOwn = cMemoryOwn;
       swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
     }
-  
+
     internal static global::System.Runtime.InteropServices.HandleRef getCPtr(SnapEvent obj) {
       return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
     }
-  
+
     ~SnapEvent() {
       Dispose();
     }
-  
+
     public virtual void Dispose() {
       lock(this) {
         if (swigCPtr.Handle != global::System.IntPtr.Zero) {
@@ -253,73 +253,73 @@ public class SnapStartedEventArgs : EventArgs
         global::System.GC.SuppressFinalize(this);
       }
     }
-  
+
    public static SnapEvent GetSnapEventFromPtr(global::System.IntPtr cPtr) {
       SnapEvent ret = new SnapEvent(cPtr, false);
        if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
       return ret;
     }
-  
+
     public SnapType type {
       set {
         NDalicPINVOKE.ScrollView_SnapEvent_type_set(swigCPtr, (int)value);
         if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-      } 
+      }
       get {
         SnapType ret = (SnapType)NDalicPINVOKE.ScrollView_SnapEvent_type_get(swigCPtr);
         if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         return ret;
-      } 
+      }
     }
-  
+
     public Vector2 position {
       set {
         NDalicPINVOKE.ScrollView_SnapEvent_position_set(swigCPtr, Vector2.getCPtr(value));
         if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-      } 
+      }
       get {
         global::System.IntPtr cPtr = NDalicPINVOKE.ScrollView_SnapEvent_position_get(swigCPtr);
         Vector2 ret = (cPtr == global::System.IntPtr.Zero) ? null : new Vector2(cPtr, false);
         if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         return ret;
-      } 
+      }
     }
-  
+
     public float duration {
       set {
         NDalicPINVOKE.ScrollView_SnapEvent_duration_set(swigCPtr, value);
         if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-      } 
+      }
       get {
         float ret = NDalicPINVOKE.ScrollView_SnapEvent_duration_get(swigCPtr);
         if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         return ret;
-      } 
+      }
     }
-  
+
     public SnapEvent() : this(NDalicPINVOKE.new_ScrollView_SnapEvent(), true) {
       if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
     }
-  
+
   }
 
   public class Property : global::System.IDisposable {
     private global::System.Runtime.InteropServices.HandleRef swigCPtr;
     protected bool swigCMemOwn;
-  
+
     internal Property(global::System.IntPtr cPtr, bool cMemoryOwn) {
       swigCMemOwn = cMemoryOwn;
       swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
     }
-  
+
     internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Property obj) {
       return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
     }
-  
+
     ~Property() {
       Dispose();
     }
-  
+
     public virtual void Dispose() {
       lock(this) {
         if (swigCPtr.Handle != global::System.IntPtr.Zero) {
@@ -332,15 +332,17 @@ public class SnapStartedEventArgs : EventArgs
         global::System.GC.SuppressFinalize(this);
       }
     }
-  
+
     public Property() : this(NDalicPINVOKE.new_ScrollView_Property(), true) {
       if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
     }
-  
+
     public static readonly int WRAP_ENABLED = NDalicPINVOKE.ScrollView_Property_WRAP_ENABLED_get();
     public static readonly int PANNING_ENABLED = NDalicPINVOKE.ScrollView_Property_PANNING_ENABLED_get();
     public static readonly int AXIS_AUTO_LOCK_ENABLED = NDalicPINVOKE.ScrollView_Property_AXIS_AUTO_LOCK_ENABLED_get();
     public static readonly int WHEEL_SCROLL_DISTANCE_STEP = NDalicPINVOKE.ScrollView_Property_WHEEL_SCROLL_DISTANCE_STEP_get();
+    public static readonly int SCROLL_MODE = NDalicPINVOKE.ScrollView_Property_SCROLL_MODE_get();
+
     public static readonly int SCROLL_POSITION = NDalicPINVOKE.ScrollView_Property_SCROLL_POSITION_get();
     public static readonly int SCROLL_PRE_POSITION = NDalicPINVOKE.ScrollView_Property_SCROLL_PRE_POSITION_get();
     public static readonly int SCROLL_PRE_POSITION_X = NDalicPINVOKE.ScrollView_Property_SCROLL_PRE_POSITION_X_get();
@@ -362,7 +364,7 @@ public class SnapStartedEventArgs : EventArgs
     public static readonly int SCROLL_DOMAIN_OFFSET = NDalicPINVOKE.ScrollView_Property_SCROLL_DOMAIN_OFFSET_get();
     public static readonly int SCROLL_POSITION_DELTA = NDalicPINVOKE.ScrollView_Property_SCROLL_POSITION_DELTA_get();
     public static readonly int START_PAGE_POSITION = NDalicPINVOKE.ScrollView_Property_START_PAGE_POSITION_get();
-  
+
   }
 
   public ScrollView () : this (NDalicPINVOKE.ScrollView_New(), true) {
@@ -921,6 +923,20 @@ public class SnapStartedEventArgs : EventArgs
     }
   }
 
+  public Dali.Property.Map ScrollMode
+  {
+    get
+    {
+      Dali.Property.Value value = GetProperty( ScrollView.Property.SCROLL_MODE );
+      Dali.Property.Map map = new Dali.Property.Map();
+      value.Get( map );
+      return map;
+    }
+    set
+    {
+      SetProperty( ScrollView.Property.SCROLL_MODE, new Dali.Property.Value( value ) );
+    }
+  }
 }
 
 }