Browse Source

Merge pull request #319 from rsredsq/RED-ATOMIC-INPUT

Improvements for multi touch. It should also fix #318
JoshEngebretson 10 years ago
parent
commit
9f117fbb59

+ 25 - 17
Source/Atomic/UI/UIInput.cpp

@@ -164,11 +164,6 @@ void UI::HandleTouchBegin(StringHash eventType, VariantMap& eventData)
         return;
 
     Input* input = GetSubsystem<Input>();
-    using namespace TouchBegin;
-    int x = eventData[P_X].GetInt();
-    int y = eventData[P_Y].GetInt();
-
-    IntVector2 pos = IntVector2(x, y);
     
     static double last_time = 0;
     static int counter = 1;
@@ -182,7 +177,15 @@ void UI::HandleTouchBegin(StringHash eventType, VariantMap& eventData)
         counter = 1;
 
     last_time = time;
-    rootWidget_->InvokePointerDown(pos.x_, pos.y_, counter, TB_MODIFIER_NONE, true);
+    unsigned numTouches = input->GetNumTouches();
+
+    for (unsigned i = 0; i < numTouches; i++)
+    {
+        TouchState* touch = input->GetTouch(i);
+        int px = touch->position_.x_;
+        int py = touch->position_.y_;
+        rootWidget_->InvokePointerDown(px, py, counter, TB_MODIFIER_NONE, true, touch->touchID_);
+    }
 }
 
 void UI::HandleTouchMove(StringHash eventType, VariantMap& eventData)
@@ -191,13 +194,16 @@ void UI::HandleTouchMove(StringHash eventType, VariantMap& eventData)
         return;
 
     Input* input = GetSubsystem<Input>();
-    using namespace TouchMove;
-    int x = eventData[P_X].GetInt();
-    int y = eventData[P_Y].GetInt();
 
-    IntVector2 pos = IntVector2(x, y);
+    unsigned numTouches = input->GetNumTouches();
 
-    rootWidget_->InvokePointerMove(pos.x_, pos.y_, TB_MODIFIER_NONE, true);
+    for (unsigned i = 0; i < numTouches; i++)
+    {
+        TouchState* touch = input->GetTouch(i);
+        int px = touch->position_.x_;
+        int py = touch->position_.y_;
+        rootWidget_->InvokePointerMove(px, py, TB_MODIFIER_NONE, true, touch->touchID_);
+    }
 }
 
 void UI::HandleTouchEnd(StringHash eventType, VariantMap& eventData)
@@ -206,13 +212,15 @@ void UI::HandleTouchEnd(StringHash eventType, VariantMap& eventData)
         return;
 
     Input* input = GetSubsystem<Input>();
-    using namespace TouchEnd;
-    int x = eventData[P_X].GetInt();
-    int y = eventData[P_Y].GetInt();
-
-    IntVector2 pos = IntVector2(x, y);
+    unsigned numTouches = input->GetNumTouches();
 
-    rootWidget_->InvokePointerUp(pos.x_, pos.y_, TB_MODIFIER_NONE, true);
+    for (unsigned i = 0; i < numTouches; i++)
+    {
+        TouchState* touch = input->GetTouch(i);
+        int px = touch->position_.x_;
+        int py = touch->position_.y_;
+        rootWidget_->InvokePointerUp(px, py, TB_MODIFIER_NONE, true, touch->touchID_);
+    }
 }
 
 static bool InvokeShortcut(int key, SPECIAL_KEY special_key, MODIFIER_KEYS modifierkeys, bool down)

+ 27 - 21
Source/ThirdParty/TurboBadger/tb_widgets.cpp

@@ -174,6 +174,18 @@ TBWidget *TBWidget::GetWidgetByIDInternal(const TBID &id, const TB_TYPE_ID type_
 	return nullptr;
 }
 
+TBWidget *TBWidget::GetWidgetByTouchId(unsigned touchId)
+{
+    if (IsCaptured() && touchId_ == touchId)
+        return this;
+    for (TBWidget *child = GetFirstChild(); child; child = child->GetNext())
+    {
+        if (TBWidget *sub_child = child->GetWidgetByTouchId(touchId))
+            return sub_child;
+    }
+    return nullptr;
+}
+
 TBStr TBWidget::GetTextByID(const TBID &id)
 {
 	if (TBWidget *widget = GetWidgetByID(id))
@@ -1274,10 +1286,10 @@ void TBWidget::StopLongClickTimer()
 	m_long_click_timer = nullptr;
 }
 
-void TBWidget::InvokePointerDown(int x, int y, int click_count, MODIFIER_KEYS modifierkeys, bool touch)
+void TBWidget::InvokePointerDown(int x, int y, int click_count, MODIFIER_KEYS modifierkeys, bool touch, int touchId)
 {
     TBWidget* down_widget = GetWidgetAt(x, y, true);
-	if (!captured_widget && down_widget->needCapturing_)
+	if (!captured_widget && down_widget && down_widget->needCapturing_)
 	{
 		SetCapturedWidget(down_widget);
 		SetHoveredWidget(captured_widget, touch);
@@ -1328,6 +1340,7 @@ void TBWidget::InvokePointerDown(int x, int y, int click_count, MODIFIER_KEYS mo
         down_widget->Invalidate();
         down_widget->InvalidateSkinStates();
         down_widget->OnCaptureChanged(true);
+        down_widget->SetTouchId(touchId);
 		down_widget->ConvertFromRoot(x, y);
 		pointer_move_widget_x = pointer_down_widget_x = x;
 		pointer_move_widget_y = pointer_down_widget_y = y;
@@ -1337,10 +1350,10 @@ void TBWidget::InvokePointerDown(int x, int y, int click_count, MODIFIER_KEYS mo
 	}
 }
 
-void TBWidget::InvokePointerUp(int x, int y, MODIFIER_KEYS modifierkeys, bool touch)
+void TBWidget::InvokePointerUp(int x, int y, MODIFIER_KEYS modifierkeys, bool touch, int touchId)
 {
     TBWidget* down_widget = GetWidgetAt(x, y, true);
-	if (down_widget)
+	if (down_widget && down_widget->touchId_ == touchId)
 	{
         down_widget->Invalidate();
         down_widget->InvalidateSkinStates();
@@ -1406,27 +1419,21 @@ void TBWidget::MaybeInvokeLongClickOrContextMenu(bool touch)
 	}
 }
 
-void TBWidget::ReleaseAllDownWidgets(TBWidget* widget, int x, int y, bool touch)
+void TBWidget::InvokePointerMove(int x, int y, MODIFIER_KEYS modifierkeys, bool touch, int touchId)
 {
-    for (TBWidget *child = widget->GetFirstChild(); child; child = child->GetNext())
+    TBWidget* move = GetWidgetByTouchId(touchId);
+    if (move && move->IsCaptured())
     {
-        if (child->IsCaptured() && !child->GetHitStatus(x, y))
+        move->ConvertFromRoot(x, y);
+        if (move->GetHitStatus(x, y)<=0)
         {
-            child->Invalidate();
-            child->InvalidateSkinStates();
-            child->OnCaptureChanged(false);
-            TBWidgetEvent ev_up(EVENT_TYPE_POINTER_UP, x, y, false, TB_MODIFIER_NONE);
-            child->InvokeEvent(ev_up);
-        }
-        if (child->GetFirstChild())
-        {
-            ReleaseAllDownWidgets(child, x, y, touch);
+            move->Invalidate();
+            move->InvalidateSkinStates();
+            move->OnCaptureChanged(false);
+            TBWidgetEvent ev_up(EVENT_TYPE_POINTER_UP, x, y, true, TB_MODIFIER_NONE);
+            move->InvokeEvent(ev_up);
         }
     }
-}
-
-void TBWidget::InvokePointerMove(int x, int y, MODIFIER_KEYS modifierkeys, bool touch)
-{
 	SetHoveredWidget(GetWidgetAt(x, y, true), touch);
 	TBWidget *target = captured_widget ? captured_widget : hovered_widget;
     if (target)
@@ -1442,7 +1449,6 @@ void TBWidget::InvokePointerMove(int x, int y, MODIFIER_KEYS modifierkeys, bool
 		// The move event was not handled, so handle panning of scrollable widgets.
 		HandlePanningOnMove(x, y);
     }
-    ReleaseAllDownWidgets(this, x, y, touch);
 }
 
 void TBWidget::HandlePanningOnMove(int x, int y)

+ 9 - 4
Source/ThirdParty/TurboBadger/tb_widgets.h

@@ -937,9 +937,9 @@ public:
 		this call and are not sure what the event will cause, use TBWidgetSafePointer to detect self deletion. */
 	bool InvokeEvent(TBWidgetEvent &ev);
 
-	void InvokePointerDown(int x, int y, int click_count, MODIFIER_KEYS modifierkeys, bool touch);
-	void InvokePointerUp(int x, int y, MODIFIER_KEYS modifierkeys, bool touch);
-	void InvokePointerMove(int x, int y, MODIFIER_KEYS modifierkeys, bool touch);
+	void InvokePointerDown(int x, int y, int click_count, MODIFIER_KEYS modifierkeys, bool touch, int touchId = 0);
+	void InvokePointerUp(int x, int y, MODIFIER_KEYS modifierkeys, bool touch, int touchId = 0);
+	void InvokePointerMove(int x, int y, MODIFIER_KEYS modifierkeys, bool touch, int touchId = 0);
 	void InvokeWheel(int x, int y, int delta_x, int delta_y, MODIFIER_KEYS modifierkeys);
 
         void InvokeRightPointerDown(int x, int y, int click_count, MODIFIER_KEYS modifierkeys);
@@ -993,7 +993,11 @@ public:
 
     bool IsCaptured() { return captured_; }
 
-    void ReleaseAllDownWidgets(TBWidget* widget, int x, int y, bool touch);
+    void SetTouchId(unsigned touchId) { touchId_ = touchId; }
+
+    unsigned GetTouchId() { return touchId_; }
+
+    TBWidget *GetWidgetByTouchId(unsigned touchId);
 
 private:
 	friend class TBWidgetListener;	///< It does iteration of m_listeners for us.
@@ -1019,6 +1023,7 @@ private:
     TBWidgetDelegate* m_delegate;
     bool needCapturing_; //if ours widget need capturing
     bool captured_; //if ours widget is currently captured
+    unsigned touchId_;
 	union {
 		struct {
 			uint16 is_group_root : 1;