|
|
@@ -73,6 +73,8 @@ TBWidget::TBWidget()
|
|
|
, m_long_click_timer(nullptr)
|
|
|
, m_delegate(nullptr)
|
|
|
, m_packed_init(0)
|
|
|
+ , needCapturing_(true)
|
|
|
+ , captured_(false)
|
|
|
{
|
|
|
#ifdef TB_RUNTIME_DEBUG_INFO
|
|
|
last_measure_time = 0;
|
|
|
@@ -209,7 +211,7 @@ void TBWidget::SetState(WIDGET_STATE state, bool on)
|
|
|
WIDGET_STATE TBWidget::GetAutoState() const
|
|
|
{
|
|
|
WIDGET_STATE state = m_state;
|
|
|
- bool add_pressed_state = !cancel_click && this == captured_widget && this == hovered_widget;
|
|
|
+ bool add_pressed_state = !cancel_click && (captured_ || this == captured_widget);
|
|
|
if (add_pressed_state)
|
|
|
state |= WIDGET_STATE_PRESSED;
|
|
|
if (this == hovered_widget && (!m_packed.no_automatic_hover_state || add_pressed_state))
|
|
|
@@ -1274,9 +1276,10 @@ void TBWidget::StopLongClickTimer()
|
|
|
|
|
|
void TBWidget::InvokePointerDown(int x, int y, int click_count, MODIFIER_KEYS modifierkeys, bool touch)
|
|
|
{
|
|
|
- if (!captured_widget)
|
|
|
+ TBWidget* down_widget = GetWidgetAt(x, y, true);
|
|
|
+ if (!captured_widget && down_widget->needCapturing_)
|
|
|
{
|
|
|
- SetCapturedWidget(GetWidgetAt(x, y, true));
|
|
|
+ SetCapturedWidget(down_widget);
|
|
|
SetHoveredWidget(captured_widget, touch);
|
|
|
//captured_button = button;
|
|
|
|
|
|
@@ -1320,27 +1323,34 @@ void TBWidget::InvokePointerDown(int x, int y, int click_count, MODIFIER_KEYS mo
|
|
|
focus_target = focus_target->m_parent;
|
|
|
}
|
|
|
}
|
|
|
- if (captured_widget)
|
|
|
+ if (down_widget)
|
|
|
{
|
|
|
- captured_widget->ConvertFromRoot(x, y);
|
|
|
+ down_widget->Invalidate();
|
|
|
+ down_widget->InvalidateSkinStates();
|
|
|
+ down_widget->OnCaptureChanged(true);
|
|
|
+ down_widget->ConvertFromRoot(x, y);
|
|
|
pointer_move_widget_x = pointer_down_widget_x = x;
|
|
|
pointer_move_widget_y = pointer_down_widget_y = y;
|
|
|
TBWidgetEvent ev(EVENT_TYPE_POINTER_DOWN, x, y, touch, modifierkeys);
|
|
|
ev.count = click_count;
|
|
|
- captured_widget->InvokeEvent(ev);
|
|
|
+ down_widget->InvokeEvent(ev);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void TBWidget::InvokePointerUp(int x, int y, MODIFIER_KEYS modifierkeys, bool touch)
|
|
|
{
|
|
|
- if (captured_widget)
|
|
|
+ TBWidget* down_widget = GetWidgetAt(x, y, true);
|
|
|
+ if (down_widget)
|
|
|
{
|
|
|
- captured_widget->ConvertFromRoot(x, y);
|
|
|
+ down_widget->Invalidate();
|
|
|
+ down_widget->InvalidateSkinStates();
|
|
|
+ down_widget->OnCaptureChanged(false);
|
|
|
+ down_widget->ConvertFromRoot(x, y);
|
|
|
TBWidgetEvent ev_up(EVENT_TYPE_POINTER_UP, x, y, touch, modifierkeys);
|
|
|
TBWidgetEvent ev_click(EVENT_TYPE_CLICK, x, y, touch, modifierkeys);
|
|
|
- captured_widget->InvokeEvent(ev_up);
|
|
|
- if (!cancel_click && captured_widget && captured_widget->GetHitStatus(x, y))
|
|
|
- captured_widget->InvokeEvent(ev_click);
|
|
|
+ down_widget->InvokeEvent(ev_up);
|
|
|
+ if (!cancel_click && down_widget->GetHitStatus(x, y))
|
|
|
+ down_widget->InvokeEvent(ev_click);
|
|
|
if (captured_widget) // && button == captured_button
|
|
|
captured_widget->ReleaseCapture();
|
|
|
}
|
|
|
@@ -1396,11 +1406,30 @@ void TBWidget::MaybeInvokeLongClickOrContextMenu(bool touch)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void TBWidget::ReleaseAllDownWidgets(TBWidget* widget, int x, int y, bool touch)
|
|
|
+{
|
|
|
+ for (TBWidget *child = widget->GetFirstChild(); child; child = child->GetNext())
|
|
|
+ {
|
|
|
+ if (child->IsCaptured() && !child->GetHitStatus(x, y))
|
|
|
+ {
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
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)
|
|
|
+ if (target)
|
|
|
{
|
|
|
target->ConvertFromRoot(x, y);
|
|
|
pointer_move_widget_x = x;
|
|
|
@@ -1412,7 +1441,8 @@ 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)
|