/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
Down,
+
+ /// <summary>
+ /// Left bound.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ Left,
+
+ /// <summary>
+ /// Right bound.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ Right,
}
/// <summary>
private float logValueOfDeceleration = 0.0f;
private float decelerationRate = 0.0f;
- private View verticalTopShadowView;
- private View verticalBottomShadowView;
- private const int verticalShadowScaleHeightLimit = 64 * 3;
- private const int verticalShadowAnimationDuration = 300;
- private Animation verticalShadowAnimation;
- private bool isVerticalShadowShown = false;
+ private View topOverShootingShadowView;
+ private View bottomOverShootingShadowView;
+ private View leftOverShootingShadowView;
+ private View rightOverShootingShadowView;
+ private const int overShootingShadowScaleHeightLimit = 64 * 3;
+ private const int overShootingShadowAnimationDuration = 300;
+ private Animation overShootingShadowAnimation;
+ private bool isOverShootingShadowShown = false;
private float startShowShadowDisplacement;
/// <summary>
Scrollbar = new Scrollbar();
//Show vertical shadow on the top (or bottom) of the scrollable when panning down (or up).
- verticalTopShadowView = new View
+ topOverShootingShadowView = new View
{
- BackgroundImage = Tizen.NUI.FrameworkInformation.ResourcePath + "nui_component_default_scroll_over_shooting_top.png",
+ BackgroundImage = FrameworkInformation.ResourcePath + "nui_component_default_scroll_over_shooting_top.png",
Opacity = 1.0f,
SizeHeight = 0.0f,
PositionUsesPivotPoint = true,
ParentOrigin = NUI.ParentOrigin.TopCenter,
PivotPoint = NUI.PivotPoint.TopCenter,
};
- verticalBottomShadowView = new View
+ bottomOverShootingShadowView = new View
{
- BackgroundImage = Tizen.NUI.FrameworkInformation.ResourcePath + "nui_component_default_scroll_over_shooting_bottom.png",
+ BackgroundImage = FrameworkInformation.ResourcePath + "nui_component_default_scroll_over_shooting_bottom.png",
Opacity = 1.0f,
SizeHeight = 0.0f,
PositionUsesPivotPoint = true,
ParentOrigin = NUI.ParentOrigin.BottomCenter,
PivotPoint = NUI.PivotPoint.BottomCenter,
};
+ //Show horizontal shadow on the left (or right) of the scrollable when panning down (or up).
+ leftOverShootingShadowView = new View
+ {
+ BackgroundImage = FrameworkInformation.ResourcePath + "nui_component_default_scroll_over_shooting_left.png",
+ Opacity = 1.0f,
+ SizeWidth = 0.0f,
+ PositionUsesPivotPoint = true,
+ ParentOrigin = NUI.ParentOrigin.CenterLeft,
+ PivotPoint = NUI.PivotPoint.CenterLeft,
+ };
+ rightOverShootingShadowView = new View
+ {
+ BackgroundImage = FrameworkInformation.ResourcePath + "nui_component_default_scroll_over_shooting_right.png",
+ Opacity = 1.0f,
+ SizeWidth = 0.0f,
+ PositionUsesPivotPoint = true,
+ ParentOrigin = NUI.ParentOrigin.CenterRight,
+ PivotPoint = NUI.PivotPoint.CenterRight,
+ };
AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Trait, "ScrollableBase");
}
if (type == DisposeTypes.Explicit)
{
- StopVerticalShadowAnimation();
+ StopOverShootingShadowAnimation();
StopScroll();
if (mPanGestureDetector != null)
[EditorBrowsable(EditorBrowsableState.Never)]
public bool EnableOverShootingEffect { get; set; } = false;
- private void AttachShadowView()
+ private void AttachOverShootingShadowView()
{
if (!EnableOverShootingEffect)
return;
- if (ScrollingDirection != Direction.Vertical)
- return;
-
// stop animation if necessary.
- StopVerticalShadowAnimation();
+ StopOverShootingShadowAnimation();
+
+ if (ScrollingDirection == Direction.Horizontal)
+ {
+ base.Add(leftOverShootingShadowView);
+ base.Add(rightOverShootingShadowView);
- base.Add(verticalTopShadowView);
- base.Add(verticalBottomShadowView);
+ leftOverShootingShadowView.Size = new Size(0.0f, SizeHeight);
+ leftOverShootingShadowView.Opacity = 1.0f;
+ leftOverShootingShadowView.RaiseToTop();
+
+ rightOverShootingShadowView.Size = new Size(0.0f, SizeHeight);
+ rightOverShootingShadowView.Opacity = 1.0f;
+ rightOverShootingShadowView.RaiseToTop();
+ }
+ else
+ {
+ base.Add(topOverShootingShadowView);
+ base.Add(bottomOverShootingShadowView);
- verticalTopShadowView.Size = new Size(SizeWidth, 0.0f);
- verticalTopShadowView.Opacity = 1.0f;
- verticalTopShadowView.RaiseToTop();
+ topOverShootingShadowView.Size = new Size(SizeWidth, 0.0f);
+ topOverShootingShadowView.Opacity = 1.0f;
+ topOverShootingShadowView.RaiseToTop();
- verticalBottomShadowView.Size = new Size(SizeWidth, 0.0f);
- verticalBottomShadowView.Opacity = 1.0f;
- verticalBottomShadowView.RaiseToTop();
+ bottomOverShootingShadowView.Size = new Size(SizeWidth, 0.0f);
+ bottomOverShootingShadowView.Opacity = 1.0f;
+ bottomOverShootingShadowView.RaiseToTop();
+ }
- // at the beginning, height of vertical shadow is 0, so it is invisible.
- isVerticalShadowShown = false;
+ // at the beginning, height or width of overshooting shadow is 0, so it is invisible.
+ isOverShootingShadowShown = false;
}
- private void DragVerticalShadow(float totalPanDisplacement, float panDisplacement)
+ private void DragOverShootingShadow(float totalPanDisplacement, float panDisplacement)
{
if (!EnableOverShootingEffect)
return;
- if (ScrollingDirection != Direction.Vertical)
- return;
-
if (totalPanDisplacement > 0) // downwards
{
- // check if reaching at the top.
+ // check if reaching at the top / left.
if ((int)finalTargetPosition != 0)
{
- isVerticalShadowShown = false;
+ isOverShootingShadowShown = false;
return;
}
// save start displacement, and re-calculate displacement.
- if (!isVerticalShadowShown)
+ if (!isOverShootingShadowShown)
{
startShowShadowDisplacement = totalPanDisplacement;
}
- isVerticalShadowShown = true;
-
- // trigger event
- ScrollOutOfBoundEventArgs.Direction direction = panDisplacement > 0 ?
- ScrollOutOfBoundEventArgs.Direction.Down : ScrollOutOfBoundEventArgs.Direction.Up;
- OnScrollOutOfBound(direction, totalPanDisplacement);
+ isOverShootingShadowShown = true;
float newDisplacement = (int)totalPanDisplacement < (int)startShowShadowDisplacement ? 0 : totalPanDisplacement - startShowShadowDisplacement;
- // scale limit of width is 60%.
- float widthScale = newDisplacement / verticalShadowScaleHeightLimit;
- verticalTopShadowView.SizeWidth = widthScale > 0.6f ? SizeWidth * 0.4f : SizeWidth * (1.0f - widthScale);
+ if (ScrollingDirection == Direction.Horizontal)
+ {
+ // scale limit of height is 60%.
+ float heightScale = newDisplacement / overShootingShadowScaleHeightLimit;
+ leftOverShootingShadowView.SizeHeight = heightScale > 0.6f ? SizeHeight * 0.4f : SizeHeight * (1.0f - heightScale);
+
+ // scale limit of width is 300%.
+ leftOverShootingShadowView.SizeWidth = newDisplacement > overShootingShadowScaleHeightLimit ? overShootingShadowScaleHeightLimit : newDisplacement;
+
+ // trigger event
+ ScrollOutOfBoundEventArgs.Direction scrollDirection = panDisplacement > 0 ?
+ ScrollOutOfBoundEventArgs.Direction.Right : ScrollOutOfBoundEventArgs.Direction.Left;
+ OnScrollOutOfBound(scrollDirection, totalPanDisplacement);
+ }
+ else
+ {
+ // scale limit of width is 60%.
+ float widthScale = newDisplacement / overShootingShadowScaleHeightLimit;
+ topOverShootingShadowView.SizeWidth = widthScale > 0.6f ? SizeWidth * 0.4f : SizeWidth * (1.0f - widthScale);
- // scale limit of height is 300%.
- verticalTopShadowView.SizeHeight = newDisplacement > verticalShadowScaleHeightLimit ? verticalShadowScaleHeightLimit : newDisplacement;
+ // scale limit of height is 300%.
+ topOverShootingShadowView.SizeHeight = newDisplacement > overShootingShadowScaleHeightLimit ? overShootingShadowScaleHeightLimit : newDisplacement;
+
+ // trigger event
+ ScrollOutOfBoundEventArgs.Direction scrollDirection = panDisplacement > 0 ?
+ ScrollOutOfBoundEventArgs.Direction.Down : ScrollOutOfBoundEventArgs.Direction.Up;
+ OnScrollOutOfBound(scrollDirection, totalPanDisplacement);
+ }
}
else if (totalPanDisplacement < 0) // upwards
{
// check if reaching at the bottom.
if (-(int)finalTargetPosition != (int)maxScrollDistance)
{
- isVerticalShadowShown = false;
+ isOverShootingShadowShown = false;
return;
}
// save start displacement, and re-calculate displacement.
- if (!isVerticalShadowShown)
+ if (!isOverShootingShadowShown)
{
startShowShadowDisplacement = totalPanDisplacement;
}
- isVerticalShadowShown = true;
-
- // trigger event
- ScrollOutOfBoundEventArgs.Direction direction = panDisplacement > 0 ?
- ScrollOutOfBoundEventArgs.Direction.Down : ScrollOutOfBoundEventArgs.Direction.Up;
- OnScrollOutOfBound(direction, totalPanDisplacement);
+ isOverShootingShadowShown = true;
float newDisplacement = (int)startShowShadowDisplacement < (int)totalPanDisplacement ? 0 : startShowShadowDisplacement - totalPanDisplacement;
- // scale limit of width is 60%.
- float widthScale = newDisplacement / verticalShadowScaleHeightLimit;
- verticalBottomShadowView.SizeWidth = widthScale > 0.6f ? SizeWidth * 0.4f : SizeWidth * (1.0f - widthScale);
+ if (ScrollingDirection == Direction.Horizontal)
+ {
+ // scale limit of height is 60%.
+ float heightScale = newDisplacement / overShootingShadowScaleHeightLimit;
+ rightOverShootingShadowView.SizeHeight = heightScale > 0.6f ? SizeHeight * 0.4f : SizeHeight * (1.0f - heightScale);
+
+ // scale limit of width is 300%.
+ rightOverShootingShadowView.SizeWidth = newDisplacement > overShootingShadowScaleHeightLimit ? overShootingShadowScaleHeightLimit : newDisplacement;
- // scale limit of height is 300%.
- verticalBottomShadowView.SizeHeight = newDisplacement > verticalShadowScaleHeightLimit ? verticalShadowScaleHeightLimit : newDisplacement;
+ // trigger event
+ ScrollOutOfBoundEventArgs.Direction scrollDirection = panDisplacement > 0 ?
+ ScrollOutOfBoundEventArgs.Direction.Right : ScrollOutOfBoundEventArgs.Direction.Left;
+ OnScrollOutOfBound(scrollDirection, totalPanDisplacement);
+ }
+ else
+ {
+ // scale limit of width is 60%.
+ float widthScale = newDisplacement / overShootingShadowScaleHeightLimit;
+ bottomOverShootingShadowView.SizeWidth = widthScale > 0.6f ? SizeWidth * 0.4f : SizeWidth * (1.0f - widthScale);
+
+ // scale limit of height is 300%.
+ bottomOverShootingShadowView.SizeHeight = newDisplacement > overShootingShadowScaleHeightLimit ? overShootingShadowScaleHeightLimit : newDisplacement;
+
+ // trigger event
+ ScrollOutOfBoundEventArgs.Direction scrollDirection = panDisplacement > 0 ?
+ ScrollOutOfBoundEventArgs.Direction.Down : ScrollOutOfBoundEventArgs.Direction.Up;
+ OnScrollOutOfBound(scrollDirection, totalPanDisplacement);
+ }
}
else
{
// if total displacement is 0, shadow would become invisible.
- isVerticalShadowShown = false;
+ isOverShootingShadowShown = false;
}
}
- private void PlayVerticalShadowAnimation()
+ private void PlayOverShootingShadowAnimation()
{
if (!EnableOverShootingEffect)
return;
- if (ScrollingDirection != Direction.Vertical)
- return;
-
// stop animation if necessary.
- StopVerticalShadowAnimation();
+ StopOverShootingShadowAnimation();
- if (verticalShadowAnimation == null)
+ if (overShootingShadowAnimation == null)
{
- verticalShadowAnimation = new Animation(verticalShadowAnimationDuration);
- verticalShadowAnimation.Finished += OnVerticalShadowAnimationFinished;
+ overShootingShadowAnimation = new Animation(overShootingShadowAnimationDuration);
+ overShootingShadowAnimation.Finished += OnOverShootingShadowAnimationFinished;
}
- View targetView = totalDisplacementForPan < 0 ? verticalBottomShadowView : verticalTopShadowView;
- verticalShadowAnimation.AnimateTo(targetView, "SizeWidth", SizeWidth);
- verticalShadowAnimation.AnimateTo(targetView, "SizeHeight", 0.0f);
- verticalShadowAnimation.AnimateTo(targetView, "Opacity", 0.0f);
- verticalShadowAnimation.Play();
+ if (ScrollingDirection == Direction.Horizontal)
+ {
+ View targetView = totalDisplacementForPan < 0 ? rightOverShootingShadowView : leftOverShootingShadowView;
+ overShootingShadowAnimation.AnimateTo(targetView, "SizeHeight", SizeHeight);
+ overShootingShadowAnimation.AnimateTo(targetView, "SizeWidth", 0.0f);
+ overShootingShadowAnimation.AnimateTo(targetView, "Opacity", 0.0f);
+ }
+ else
+ {
+ View targetView = totalDisplacementForPan < 0 ? bottomOverShootingShadowView : topOverShootingShadowView;
+ overShootingShadowAnimation.AnimateTo(targetView, "SizeWidth", SizeWidth);
+ overShootingShadowAnimation.AnimateTo(targetView, "SizeHeight", 0.0f);
+ overShootingShadowAnimation.AnimateTo(targetView, "Opacity", 0.0f);
+ }
+ overShootingShadowAnimation.Play();
}
- private void StopVerticalShadowAnimation()
+ private void StopOverShootingShadowAnimation()
{
- if (verticalShadowAnimation == null || verticalShadowAnimation.State != Animation.States.Playing)
+ if (overShootingShadowAnimation == null || overShootingShadowAnimation.State != Animation.States.Playing)
return;
- verticalShadowAnimation.Stop(Animation.EndActions.Cancel);
- OnVerticalShadowAnimationFinished(null, null);
- verticalShadowAnimation.Clear();
+ overShootingShadowAnimation.Stop(Animation.EndActions.Cancel);
+ OnOverShootingShadowAnimationFinished(null, null);
+ overShootingShadowAnimation.Clear();
}
- private void OnVerticalShadowAnimationFinished(object sender, EventArgs e)
+ private void OnOverShootingShadowAnimationFinished(object sender, EventArgs e)
{
- base.Remove(verticalTopShadowView);
- base.Remove(verticalBottomShadowView);
+ if (ScrollingDirection == Direction.Horizontal)
+ {
+ base.Remove(leftOverShootingShadowView);
+ base.Remove(rightOverShootingShadowView);
- verticalTopShadowView.Size = new Size(SizeWidth, 0.0f);
- verticalBottomShadowView.Size = new Size(SizeWidth, 0.0f);
+ leftOverShootingShadowView.Size = new Size(0.0f, SizeHeight);
+ rightOverShootingShadowView.Size = new Size(0.0f, SizeHeight);
+ }
+ else
+ {
+ base.Remove(topOverShootingShadowView);
+ base.Remove(bottomOverShootingShadowView);
+
+ topOverShootingShadowView.Size = new Size(SizeWidth, 0.0f);
+ bottomOverShootingShadowView.Size = new Size(SizeWidth, 0.0f);
+ }
- // after animation finished, height & opacity of vertical shadow both are 0, so it is invisible.
- isVerticalShadowShown = false;
+ // after animation finished, height/width & opacity of vertical shadow both are 0, so it is invisible.
+ isOverShootingShadowShown = false;
}
private void OnScrollOutOfBound(ScrollOutOfBoundEventArgs.Direction direction, float displacement)
{
readyToNotice = false;
base.Add(mInterruptTouchingChild);
- AttachShadowView();
+ AttachOverShootingShadowView();
Debug.WriteLineIf(LayoutDebugScrollableBase, "Gesture Start");
if (scrolling && !SnapToPage)
{
{
if (ScrollingDirection == Direction.Horizontal)
{
- ScrollBy(panGesture.Displacement.X, false);
+ // if vertical shadow is shown, does not scroll.
+ if (!isOverShootingShadowShown)
+ {
+ ScrollBy(panGesture.Displacement.X, false);
+ }
totalDisplacementForPan += panGesture.Displacement.X;
+ DragOverShootingShadow(totalDisplacementForPan, panGesture.Displacement.X);
}
else
{
// if vertical shadow is shown, does not scroll.
- if (!isVerticalShadowShown)
+ if (!isOverShootingShadowShown)
{
ScrollBy(panGesture.Displacement.Y, false);
}
totalDisplacementForPan += panGesture.Displacement.Y;
- DragVerticalShadow(totalDisplacementForPan, panGesture.Displacement.Y);
+ DragOverShootingShadow(totalDisplacementForPan, panGesture.Displacement.Y);
}
Debug.WriteLineIf(LayoutDebugScrollableBase, "OnPanGestureDetected Continue totalDisplacementForPan:" + totalDisplacementForPan);
}
else if (panGesture.State == Gesture.StateType.Finished || panGesture.State == Gesture.StateType.Cancelled)
{
- PlayVerticalShadowAnimation();
+ PlayOverShootingShadowAnimation();
OnScrollDragEnded();
StopScroll(); // Will replace previous animation so will stop existing one.
-using System;
-using System.Collections.Generic;
-using System.Text;
+
using Tizen.NUI.BaseComponents;
namespace Tizen.NUI.Samples
public class ScrollableBaseOutOfBoundSample : IExample
{
private View root;
- private Components.ScrollableBase mScrollableBase = null;
- private TextLabel[] items;
+ private Components.ScrollableBase horizontalScrollableBase = null;
+ private TextLabel[] horizontalItems;
+
+ private Components.ScrollableBase verticalScrollableBase = null;
+ private TextLabel[] verticalItems;
public void Activate()
{
};
root.Layout = new LinearLayout()
{
- LinearOrientation = LinearLayout.Orientation.Vertical
+ LinearOrientation = LinearLayout.Orientation.Vertical,
};
window.Add(root);
- CreateScrollableBase();
+ CreateHorizontalScrollableBase();
+
+ CreateVerticalScrollableBase();
+ }
+
+ private void CreateHorizontalScrollableBase()
+ {
+ horizontalScrollableBase = new Components.ScrollableBase()
+ {
+ Size = new Size(400, 300),
+ ScrollingDirection = Components.ScrollableBase.Direction.Horizontal,
+ };
+ horizontalScrollableBase.ScrollOutOfBound += OnHorizontalScrollOutOfBound;
+
+ horizontalItems = new TextLabel[5];
+ for (int i = 0; i < 5; i++)
+ {
+ horizontalItems[i] = new TextLabel
+ {
+ Position = new Position(i * 200, 0),
+ Size = new Size(200, 300),
+ PointSize = 12.0f,
+ TextColor = Color.Black,
+ };
+ if (i % 2 == 0)
+ {
+ horizontalItems[i].BackgroundColor = Color.White;
+ }
+ else
+ {
+ horizontalItems[i].BackgroundColor = Color.Cyan;
+ }
+ horizontalScrollableBase.Add(horizontalItems[i]);
+ }
+ root.Add(horizontalScrollableBase);
+ }
+
+ private void OnHorizontalScrollOutOfBound(object sender, Components.ScrollOutOfBoundEventArgs e)
+ {
+ if (e.ScrollableBound == Components.ScrollOutOfBoundEventArgs.Bound.Left)
+ {
+ horizontalItems[0].Text = "Reached at the left.";
+ }
+ else if (e.ScrollableBound == Components.ScrollOutOfBoundEventArgs.Bound.Right)
+ {
+ horizontalItems[4].Text = "Reached at the right.";
+ }
}
- private void CreateScrollableBase()
+ private void CreateVerticalScrollableBase()
{
- mScrollableBase = new Components.ScrollableBase()
+ verticalScrollableBase = new Components.ScrollableBase()
{
- Position = new Position(300, 100),
Size = new Size(400, 300),
ScrollingDirection = Components.ScrollableBase.Direction.Vertical,
EnableOverShootingEffect = true,
};
- mScrollableBase.ScrollOutOfBound += OnScrollOutOfBound;
+ verticalScrollableBase.ScrollOutOfBound += OnVerticalScrollOutOfBound;
- items = new TextLabel[5];
+ verticalItems = new TextLabel[5];
for (int i = 0; i < 5; i++)
{
- items[i] = new TextLabel
+ verticalItems[i] = new TextLabel
{
Position = new Position(0, i * 100),
- Size = new Size(800, 100),
+ Size = new Size(400, 100),
PointSize = 12.0f,
TextColor = Color.Black,
};
if (i % 2 == 0)
{
- items[i].BackgroundColor = Color.White;
+ verticalItems[i].BackgroundColor = Color.White;
}
else
{
- items[i].BackgroundColor = Color.Cyan;
+ verticalItems[i].BackgroundColor = Color.Cyan;
}
- mScrollableBase.Add(items[i]);
+ verticalScrollableBase.Add(verticalItems[i]);
}
- root.Add(mScrollableBase);
+ root.Add(verticalScrollableBase);
}
- private void OnScrollOutOfBound(object sender, Components.ScrollOutOfBoundEventArgs e)
+ private void OnVerticalScrollOutOfBound(object sender, Components.ScrollOutOfBoundEventArgs e)
{
if (e.Displacement > 100)
{
{
for (int i = 0; i < 5; i++)
{
- if (items[i] != null)
+ if (verticalItems[i] != null)
+ {
+ verticalScrollableBase.Remove(verticalItems[i]);
+ verticalItems[i].Dispose();
+ }
+ }
+ if (verticalScrollableBase != null)
+ {
+ root.Remove(verticalScrollableBase);
+ verticalScrollableBase.Dispose();
+ }
+ for (int i = 0; i < 5; i++)
+ {
+ if (horizontalItems[i] != null)
{
- mScrollableBase.Remove(items[i]);
- items[i].Dispose();
+ horizontalScrollableBase.Remove(horizontalItems[i]);
+ horizontalItems[i].Dispose();
}
}
- if (mScrollableBase != null)
+ if (horizontalScrollableBase != null)
{
- root.Remove(mScrollableBase);
- mScrollableBase.Dispose();
+ root.Remove(horizontalScrollableBase);
+ horizontalScrollableBase.Dispose();
}
root.Dispose();
}