|
@@ -32,6 +32,27 @@ bool TBWidget::update_widget_states = true;
|
|
|
bool TBWidget::update_skin_states = true;
|
|
bool TBWidget::update_skin_states = true;
|
|
|
bool TBWidget::show_focus_state = false;
|
|
bool TBWidget::show_focus_state = false;
|
|
|
|
|
|
|
|
|
|
+static TBHashTableAutoDeleteOf<TBWidget::TOUCH_INFO> s_touch_info;
|
|
|
|
|
+
|
|
|
|
|
+TBWidget::TOUCH_INFO *TBWidget::GetTouchInfo(uint32 id)
|
|
|
|
|
+{
|
|
|
|
|
+ return s_touch_info.Get(id);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static TBWidget::TOUCH_INFO *NewTouchInfo(uint32 id)
|
|
|
|
|
+{
|
|
|
|
|
+ assert(!s_touch_info.Get(id));
|
|
|
|
|
+ TBWidget::TOUCH_INFO *ti = new TBWidget::TOUCH_INFO;
|
|
|
|
|
+ memset(ti, 0, sizeof(TBWidget::TOUCH_INFO));
|
|
|
|
|
+ s_touch_info.Add(id, ti);
|
|
|
|
|
+ return ti;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void DeleteTouchInfo(uint32 id)
|
|
|
|
|
+{
|
|
|
|
|
+ s_touch_info.Delete(id);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// == TBLongClickTimer ==================================================================
|
|
// == TBLongClickTimer ==================================================================
|
|
|
|
|
|
|
|
/** One shot timer for long click event */
|
|
/** One shot timer for long click event */
|
|
@@ -89,6 +110,7 @@ TBWidget::~TBWidget()
|
|
|
assert(!m_parent); ///< A widget must be removed from parent before deleted
|
|
assert(!m_parent); ///< A widget must be removed from parent before deleted
|
|
|
m_packed.is_dying = true;
|
|
m_packed.is_dying = true;
|
|
|
|
|
|
|
|
|
|
+ // Unreference from pointer capture
|
|
|
if (this == hovered_widget)
|
|
if (this == hovered_widget)
|
|
|
hovered_widget = nullptr;
|
|
hovered_widget = nullptr;
|
|
|
if (this == captured_widget)
|
|
if (this == captured_widget)
|
|
@@ -96,6 +118,16 @@ TBWidget::~TBWidget()
|
|
|
if (this == focused_widget)
|
|
if (this == focused_widget)
|
|
|
focused_widget = nullptr;
|
|
focused_widget = nullptr;
|
|
|
|
|
|
|
|
|
|
+ // Unreference from touch info
|
|
|
|
|
+ TBHashTableIteratorOf<TOUCH_INFO> it(&s_touch_info);
|
|
|
|
|
+ while (TOUCH_INFO *ti = it.GetNextContent())
|
|
|
|
|
+ {
|
|
|
|
|
+ if (this == ti->hovered_widget)
|
|
|
|
|
+ ti->hovered_widget = nullptr;
|
|
|
|
|
+ if (this == ti->captured_widget)
|
|
|
|
|
+ ti->captured_widget = nullptr;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (m_delegate)
|
|
if (m_delegate)
|
|
|
m_delegate->OnDelete();
|
|
m_delegate->OnDelete();
|
|
|
|
|
|
|
@@ -1083,7 +1115,7 @@ PreferredSize TBWidget::GetPreferredSize(const SizeConstraints &in_constraints)
|
|
|
// Override the calculated ps with any specified layout parameter.
|
|
// Override the calculated ps with any specified layout parameter.
|
|
|
if (m_layout_params)
|
|
if (m_layout_params)
|
|
|
{
|
|
{
|
|
|
-#define LP_OVERRIDE(param) if (m_layout_params->param != LayoutParams::UNSPECIFIED) \
|
|
|
|
|
|
|
+#define LP_OVERRIDE(param) if (m_layout_params->param != LayoutParams::UNSPECIFIED) \
|
|
|
m_cached_ps.param = m_layout_params->param;
|
|
m_cached_ps.param = m_layout_params->param;
|
|
|
LP_OVERRIDE(min_w);
|
|
LP_OVERRIDE(min_w);
|
|
|
LP_OVERRIDE(min_h);
|
|
LP_OVERRIDE(min_h);
|
|
@@ -1316,7 +1348,7 @@ void TBWidget::StopLongClickTimer()
|
|
|
m_long_click_timer = nullptr;
|
|
m_long_click_timer = nullptr;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void TBWidget::InvokePointerDown(int x, int y, int click_count, MODIFIER_KEYS modifierkeys, bool touch, int touchId)
|
|
|
|
|
|
|
+bool TBWidget::InvokePointerDown(int x, int y, int click_count, MODIFIER_KEYS modifierkeys, bool touch, int touchId)
|
|
|
{
|
|
{
|
|
|
TBWidget* down_widget = GetWidgetAt(x, y, true);
|
|
TBWidget* down_widget = GetWidgetAt(x, y, true);
|
|
|
if (!captured_widget && down_widget && down_widget->needCapturing_)
|
|
if (!captured_widget && down_widget && down_widget->needCapturing_)
|
|
@@ -1397,10 +1429,15 @@ void TBWidget::InvokePointerDown(int x, int y, int click_count, MODIFIER_KEYS mo
|
|
|
TBWidgetEvent ev(EVENT_TYPE_POINTER_DOWN, x, y, touch, modifierkeys);
|
|
TBWidgetEvent ev(EVENT_TYPE_POINTER_DOWN, x, y, touch, modifierkeys);
|
|
|
ev.count = click_count;
|
|
ev.count = click_count;
|
|
|
down_widget->InvokeEvent(ev);
|
|
down_widget->InvokeEvent(ev);
|
|
|
|
|
+
|
|
|
|
|
+ // Return true when captured instead of InvokeEvent result. If a widget is
|
|
|
|
|
+ // hit is more interesting for callers than if the event was handled or not.
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void TBWidget::InvokePointerUp(int x, int y, MODIFIER_KEYS modifierkeys, bool touch, int touchId)
|
|
|
|
|
|
|
+bool TBWidget::InvokePointerUp(int x, int y, MODIFIER_KEYS modifierkeys, bool touch, int touchId)
|
|
|
{
|
|
{
|
|
|
//get down_widget before making handling captured_widget event to make sure that down_widget won't be changed
|
|
//get down_widget before making handling captured_widget event to make sure that down_widget won't be changed
|
|
|
TBWidget* down_widget = GetWidgetAt(x, y, true);
|
|
TBWidget* down_widget = GetWidgetAt(x, y, true);
|
|
@@ -1452,7 +1489,12 @@ void TBWidget::InvokePointerUp(int x, int y, MODIFIER_KEYS modifierkeys, bool to
|
|
|
//ReleaseCapture
|
|
//ReleaseCapture
|
|
|
down_widget->Invalidate();
|
|
down_widget->Invalidate();
|
|
|
down_widget->InvalidateSkinStates();
|
|
down_widget->InvalidateSkinStates();
|
|
|
|
|
+
|
|
|
|
|
+ // Return true when captured instead of InvokeEvent result. If a widget is
|
|
|
|
|
+ // hit is more interesting for callers than if the event was handled or not.
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void TBWidget::InvokeRightPointerDown(int x, int y, int click_count, MODIFIER_KEYS modifierkeys)
|
|
void TBWidget::InvokeRightPointerDown(int x, int y, int click_count, MODIFIER_KEYS modifierkeys)
|
|
@@ -1593,6 +1635,98 @@ void TBWidget::HandlePanningOnMove(int x, int y)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void TBWidget::InvokePointerCancel()
|
|
|
|
|
+{
|
|
|
|
|
+ if (captured_widget)
|
|
|
|
|
+ captured_widget->ReleaseCapture();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+bool TBWidget::InvokeTouchDown(int x, int y, uint32 id, int click_count, MODIFIER_KEYS modifierkeys)
|
|
|
|
|
+{
|
|
|
|
|
+ if (id == 0)
|
|
|
|
|
+ return InvokePointerDown(x, y, click_count, modifierkeys, true);
|
|
|
|
|
+
|
|
|
|
|
+ TOUCH_INFO *ti = NewTouchInfo(id);
|
|
|
|
|
+ if (!ti)
|
|
|
|
|
+ return false;
|
|
|
|
|
+
|
|
|
|
|
+ if (!ti->captured_widget)
|
|
|
|
|
+ ti->captured_widget = GetWidgetAt(x, y, true);
|
|
|
|
|
+ if (ti->captured_widget && !ti->captured_widget->GetState(WIDGET_STATE_DISABLED))
|
|
|
|
|
+ ti->hovered_widget = ti->captured_widget;
|
|
|
|
|
+
|
|
|
|
|
+ if (ti->captured_widget)
|
|
|
|
|
+ {
|
|
|
|
|
+ ti->captured_widget->ConvertFromRoot(x, y);
|
|
|
|
|
+ ti->move_widget_x = ti->down_widget_x = x;
|
|
|
|
|
+ ti->move_widget_y = ti->down_widget_y = y;
|
|
|
|
|
+ TBWidgetEvent ev(EVENT_TYPE_TOUCH_DOWN, x, y, true, modifierkeys);
|
|
|
|
|
+ ev.count = click_count;
|
|
|
|
|
+ ev.ref_id = id;
|
|
|
|
|
+ ti->captured_widget->InvokeEvent(ev);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+bool TBWidget::InvokeTouchUp(int x, int y, uint32 id, MODIFIER_KEYS modifierkeys)
|
|
|
|
|
+{
|
|
|
|
|
+ if (id == 0)
|
|
|
|
|
+ return InvokePointerUp(x, y, modifierkeys, true);
|
|
|
|
|
+ TOUCH_INFO *ti = GetTouchInfo(id);
|
|
|
|
|
+ if (ti && ti->captured_widget)
|
|
|
|
|
+ {
|
|
|
|
|
+ ti->captured_widget->ConvertFromRoot(x, y);
|
|
|
|
|
+ TBWidgetEvent ev(EVENT_TYPE_TOUCH_UP, x, y, true, modifierkeys);
|
|
|
|
|
+ ev.ref_id = id;
|
|
|
|
|
+ ti->captured_widget->InvokeEvent(ev);
|
|
|
|
|
+ DeleteTouchInfo(id);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void TBWidget::InvokeTouchMove(int x, int y, uint32 id, MODIFIER_KEYS modifierkeys)
|
|
|
|
|
+{
|
|
|
|
|
+ if (id == 0)
|
|
|
|
|
+ return InvokePointerMove(x, y, modifierkeys, true);
|
|
|
|
|
+
|
|
|
|
|
+ TOUCH_INFO *ti = GetTouchInfo(id);
|
|
|
|
|
+ if (!ti)
|
|
|
|
|
+ return;
|
|
|
|
|
+
|
|
|
|
|
+ ti->hovered_widget = GetWidgetAt(x, y, true);
|
|
|
|
|
+ if (ti->captured_widget)
|
|
|
|
|
+ {
|
|
|
|
|
+ ti->captured_widget->ConvertFromRoot(x, y);
|
|
|
|
|
+ ti->move_widget_x = x;
|
|
|
|
|
+ ti->move_widget_y = y;
|
|
|
|
|
+ TBWidgetEvent ev(EVENT_TYPE_TOUCH_MOVE, x, y, true, modifierkeys);
|
|
|
|
|
+ ev.ref_id = id;
|
|
|
|
|
+ if (ti->captured_widget->InvokeEvent(ev))
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void TBWidget::InvokeTouchCancel(uint32 id)
|
|
|
|
|
+{
|
|
|
|
|
+ if (id == 0)
|
|
|
|
|
+ return InvokePointerCancel();
|
|
|
|
|
+
|
|
|
|
|
+ TOUCH_INFO *ti = GetTouchInfo(id);
|
|
|
|
|
+ if (ti)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (ti->captured_widget)
|
|
|
|
|
+ {
|
|
|
|
|
+ TBWidgetEvent ev(EVENT_TYPE_TOUCH_CANCEL, 0, 0, true);
|
|
|
|
|
+ ev.ref_id = id;
|
|
|
|
|
+ ti->captured_widget->InvokeEvent(ev);
|
|
|
|
|
+ }
|
|
|
|
|
+ DeleteTouchInfo(id);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
void TBWidget::InvokeWheel(int x, int y, int delta_x, int delta_y, MODIFIER_KEYS modifierkeys)
|
|
void TBWidget::InvokeWheel(int x, int y, int delta_x, int delta_y, MODIFIER_KEYS modifierkeys)
|
|
|
{
|
|
{
|
|
|
SetHoveredWidget(GetWidgetAt(x, y, true), true);
|
|
SetHoveredWidget(GetWidgetAt(x, y, true), true);
|