Browse Source

Child elements of a scroll view can now be auto disabled when touch scrolling to prevent triggering of child element events.

hdunderscore 11 years ago
parent
commit
17e48a27f5

+ 4 - 0
Source/Engine/LuaScript/pkgs/UI/ScrollView.pkg

@@ -14,6 +14,8 @@ class ScrollView : public UIElement
     void SetPageStep(float step);
     void SetScrollDeceleration(float deceleration);
     void SetScrollSnapEpsilon(float snap);
+    void SetAutoDisableChildren(bool disable);
+    void SetAutoDisableThreshold(float amount);
 
     const IntVector2& GetViewPosition() const;
     UIElement* GetContentElement() const;
@@ -25,6 +27,8 @@ class ScrollView : public UIElement
     float GetPageStep() const;
     float GetScrollDeceleration() const;
     float GetScrollSnapEpsilon() const;
+    bool GetAutoDisableChildren() const;
+    float GetAutoDisableThreshold() const;
 
     tolua_property__get_set IntVector2& viewPosition;
     tolua_property__get_set UIElement* contentElement;

+ 4 - 0
Source/Engine/Script/UIAPI.cpp

@@ -244,6 +244,10 @@ static void RegisterScrollView(asIScriptEngine* engine)
     engine->RegisterObjectMethod("ScrollView", "float get_scrollDeceleration() const", asMETHOD(ScrollView, GetScrollDeceleration), asCALL_THISCALL);
     engine->RegisterObjectMethod("ScrollView", "void set_scrollSnapEpsilon(float)", asMETHOD(ScrollView, SetScrollSnapEpsilon), asCALL_THISCALL);
     engine->RegisterObjectMethod("ScrollView", "float get_scrollSnapEpsilon() const", asMETHOD(ScrollView, GetScrollSnapEpsilon), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ScrollView", "void set_autoDisableChildren(bool)", asMETHOD(ScrollView, SetAutoDisableChildren), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ScrollView", "bool get_autoDisableChildren() const", asMETHOD(ScrollView, GetAutoDisableChildren), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ScrollView", "void set_autoDisableThreshold(float)", asMETHOD(ScrollView, SetAutoDisableThreshold), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ScrollView", "float get_autoDisableThreshold() const", asMETHOD(ScrollView, GetAutoDisableThreshold), asCALL_THISCALL);
 }
 
 void ListViewSetSelections(CScriptArray* selections, ListView* ptr)

+ 25 - 1
Source/Engine/UI/ScrollView.cpp

@@ -53,7 +53,11 @@ ScrollView::ScrollView(Context* context) :
     scrollDeceleration_(30.0f),
     scrollSnapEpsilon_(M_EPSILON),
     scrollTouchDown_(false),
-    barScrolling_(false)
+    barScrolling_(false),
+    scrollChildrenDisable_(false),
+    autoDisableChildren_(false),
+    autoDisableThreshold_(25.0f),
+    touchDistanceSum_(0.0f)
 {
     clipChildren_ = true;
     SetEnabled(true);
@@ -100,6 +104,8 @@ void ScrollView::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(ScrollView, VAR_BOOL, "Auto Show/Hide Scrollbars", GetScrollBarsAutoVisible, SetScrollBarsAutoVisible, bool, true, AM_FILE);
     ACCESSOR_ATTRIBUTE(ScrollView, VAR_FLOAT, "Scroll Deceleration", GetScrollDeceleration, SetScrollDeceleration, float, 30.0f, AM_FILE);
     ACCESSOR_ATTRIBUTE(ScrollView, VAR_FLOAT, "Scroll Snap Epsilon", GetScrollSnapEpsilon, SetScrollSnapEpsilon, float, 1.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE(ScrollView, VAR_BOOL, "Auto Disable Children", GetAutoDisableChildren, SetAutoDisableChildren, bool, false, AM_FILE);
+    ACCESSOR_ATTRIBUTE(ScrollView, VAR_FLOAT, "Auto Disable Threshold", GetAutoDisableThreshold, SetAutoDisableThreshold, float, 25.0f, AM_FILE);
 }
 
 void ScrollView::Update(float timeStep)
@@ -518,11 +524,21 @@ void ScrollView::HandleTouchMove(StringHash eventType, VariantMap& eventData)
         // Take new scrolling speed if it's faster than the current accumulated value
         float dX = (float)-eventData[P_DX].GetInt();
         float dY = (float)-eventData[P_DY].GetInt();
+
         if (Abs(dX) > Abs(touchScrollSpeed_.x_))
             touchScrollSpeed_.x_ = dX;
         if (Abs(dY) > Abs(touchScrollSpeed_.y_))
             touchScrollSpeed_.y_ = dY;
 
+        // Auto disable children
+        touchDistanceSum_ += dX * dX + dY * dY;
+        if (touchDistanceSum_ >= autoDisableThreshold_)
+            if (visible_ && autoDisableChildren_ && !scrollChildrenDisable_)
+            {
+                scrollChildrenDisable_ = true;
+                scrollPanel_->SetDeepEnabled(false);
+            }
+            
         touchScrollSpeedMax_.x_ = dX;
         touchScrollSpeedMax_.y_ = dY;
     }
@@ -546,6 +562,14 @@ void ScrollView::HandleTouchMove(StringHash eventType, VariantMap& eventData)
     else if (eventType == E_TOUCHEND)
     {
         // 'Flick' action
+        // Release any auto disabled children
+        if (scrollChildrenDisable_)
+        {
+            touchDistanceSum_ = 0.0f;
+            scrollChildrenDisable_ = false;
+            scrollPanel_->ResetDeepEnabled();
+        }
+
         barScrolling_ = false;
         scrollTouchDown_ = false;
         if (Abs(touchScrollSpeedMax_.x_) > scrollSnapEpsilon_ )

+ 16 - 0
Source/Engine/UI/ScrollView.h

@@ -72,6 +72,10 @@ public:
     void SetScrollDeceleration(float deceleration) { scrollDeceleration_ = deceleration; }
     /// Set scroll snap epsilon
     void SetScrollSnapEpsilon(float snap) { scrollSnapEpsilon_ = snap; }
+    /// Set whether child elements should be disabled while touch scrolling.
+    void SetAutoDisableChildren(bool disable) { autoDisableChildren_ = disable; };
+    /// Set how much touch movement is needed to trigger child element disabling.
+    void SetAutoDisableThreshold(float amount) { autoDisableThreshold_ = amount; };
 
     /// Return view offset from the top-left corner.
     const IntVector2& GetViewPosition() const { return viewPosition_; }
@@ -93,6 +97,10 @@ public:
     float GetScrollDeceleration() const { return scrollDeceleration_; }
     /// Return scroll snap epsilon
     float GetScrollSnapEpsilon() const { return scrollSnapEpsilon_; }
+    /// Return whether child element will be disabled while touch scrolling.
+    bool GetAutoDisableChildren() const { return autoDisableChildren_; }
+    /// Return how much touch movement is needed to trigger child element disabling.
+    float GetAutoDisableThreshold() const { return autoDisableThreshold_; }
 
     /// Set view position attribute.
     void SetViewPositionAttr(const IntVector2& value);
@@ -145,6 +153,14 @@ protected:
     bool scrollTouchDown_;
     /// Used to prevent touch scroll - scroll bar conflict
     bool barScrolling_;
+    /// Used to determine if child elements should be disabled while touch scrolling, to prevent their trigger.
+    bool autoDisableChildren_;
+    /// Used to determine if children have been disabled.
+    bool scrollChildrenDisable_;
+    /// Distance moved with touch scrolling
+    float touchDistanceSum_;
+    /// Threshold to trigger auto disable children
+    float autoDisableThreshold_;
 
 private:
     /// Handle scrollbar value changed.