Implement mouse event propagation

This commit is contained in:
Magnus Norddahl 2024-01-10 23:06:05 +01:00 committed by Christoph Oelckers
parent a0f52411d3
commit 8cc531e283
18 changed files with 135 additions and 60 deletions

View file

@ -72,6 +72,7 @@ public:
bool HasFocus();
bool IsEnabled();
bool IsVisible();
bool IsHidden();
void SetFocus();
void SetEnabled(bool value);
@ -113,11 +114,11 @@ public:
protected:
virtual void OnPaintFrame(Canvas* canvas) { }
virtual void OnPaint(Canvas* canvas) { }
virtual bool OnMouseDown(const Point& pos, int key) { return false; }
virtual bool OnMouseDoubleclick(const Point& pos, int key) { return false; }
virtual bool OnMouseUp(const Point& pos, int key) { return false; }
virtual bool OnMouseWheel(const Point& pos, EInputKey key) { return false; }
virtual void OnMouseMove(const Point& pos) { }
virtual void OnMouseDown(const Point& pos, int key) { }
virtual void OnMouseDoubleclick(const Point& pos, int key) { }
virtual void OnMouseUp(const Point& pos, int key) { }
virtual void OnMouseWheel(const Point& pos, EInputKey key) { }
virtual void OnMouseLeave() { }
virtual void OnRawMouseMove(int dx, int dy) { }
virtual void OnKeyChar(std::string chars) { }
@ -180,6 +181,7 @@ private:
Widget* FocusWidget = nullptr;
Widget* CaptureWidget = nullptr;
Widget* HoverWidget = nullptr;
bool HiddenFlag = false;
StandardCursor CurrentCursor = StandardCursor::arrow;

View file

@ -21,8 +21,8 @@ public:
protected:
void OnPaint(Canvas* canvas) override;
void OnMouseDown(const Point& pos, int key) override;
void OnMouseUp(const Point& pos, int key) override;
bool OnMouseDown(const Point& pos, int key) override;
bool OnMouseUp(const Point& pos, int key) override;
void OnMouseLeave() override;
void OnKeyUp(EInputKey key) override;

View file

@ -72,9 +72,9 @@ protected:
void OnPaintFrame(Canvas* canvas) override;
void OnPaint(Canvas* canvas) override;
void OnMouseMove(const Point& pos) override;
void OnMouseDown(const Point& pos, int key) override;
void OnMouseDoubleclick(const Point& pos, int key) override;
void OnMouseUp(const Point& pos, int key) override;
bool OnMouseDown(const Point& pos, int key) override;
bool OnMouseDoubleclick(const Point& pos, int key) override;
bool OnMouseUp(const Point& pos, int key) override;
void OnKeyChar(std::string chars) override;
void OnKeyDown(EInputKey key) override;
void OnKeyUp(EInputKey key) override;

View file

@ -25,9 +25,9 @@ public:
protected:
void OnPaint(Canvas* canvas) override;
void OnPaintFrame(Canvas* canvas) override;
void OnMouseDown(const Point& pos, int key) override;
void OnMouseDoubleclick(const Point& pos, int key) override;
void OnMouseWheel(const Point& pos, EInputKey key) override;
bool OnMouseDown(const Point& pos, int key) override;
bool OnMouseDoubleclick(const Point& pos, int key) override;
bool OnMouseWheel(const Point& pos, EInputKey key) override;
void OnKeyDown(EInputKey key) override;
void OnGeometryChanged() override;
void OnScrollbarScroll();

View file

@ -21,9 +21,9 @@ public:
protected:
void OnPaintFrame(Canvas* canvas) override;
void OnPaint(Canvas* canvas) override;
bool OnMouseDown(const Point& pos, int key) override;
bool OnMouseUp(const Point& pos, int key) override;
void OnMouseMove(const Point& pos) override;
void OnMouseDown(const Point& pos, int key) override;
void OnMouseUp(const Point& pos, int key) override;
void OnMouseLeave() override;
void OnKeyDown(EInputKey key) override;
void OnKeyUp(EInputKey key) override;

View file

@ -47,9 +47,9 @@ public:
std::function<void()> FuncScrollEnd;
protected:
bool OnMouseDown(const Point& pos, int key) override;
bool OnMouseUp(const Point& pos, int key) override;
void OnMouseMove(const Point& pos) override;
void OnMouseDown(const Point& pos, int key) override;
void OnMouseUp(const Point& pos, int key) override;
void OnMouseLeave() override;
void OnPaint(Canvas* canvas) override;
void OnEnableChanged() override;

View file

@ -85,9 +85,9 @@ public:
protected:
void OnPaintFrame(Canvas* canvas) override;
void OnGeometryChanged() override;
bool OnMouseDown(const Point& pos, int key) override;
bool OnMouseUp(const Point& pos, int key) override;
void OnMouseMove(const Point& pos) override;
void OnMouseDown(const Point& pos, int key) override;
void OnMouseUp(const Point& pos, int key) override;
void OnMouseLeave() override;
private:
@ -95,7 +95,6 @@ private:
ImageBox* Icon = nullptr;
TextLabel* Label = nullptr;
bool mouseDown = false;
bool hot = false;
};

View file

@ -56,9 +56,9 @@ protected:
void OnPaintFrame(Canvas* canvas) override;
void OnPaint(Canvas* canvas) override;
void OnMouseMove(const Point& pos) override;
void OnMouseDown(const Point& pos, int key) override;
void OnMouseDoubleclick(const Point& pos, int key) override;
void OnMouseUp(const Point& pos, int key) override;
bool OnMouseDown(const Point& pos, int key) override;
bool OnMouseDoubleclick(const Point& pos, int key) override;
bool OnMouseUp(const Point& pos, int key) override;
void OnKeyChar(std::string chars) override;
void OnKeyDown(EInputKey key) override;
void OnKeyUp(EInputKey key) override;

View file

@ -172,6 +172,11 @@ void Widget::Show()
{
DispWindow->Show();
}
else if (HiddenFlag)
{
HiddenFlag = false;
Update();
}
}
void Widget::ShowFullscreen()
@ -213,6 +218,11 @@ void Widget::Hide()
if (DispWindow)
DispWindow->Hide();
}
else if (!HiddenFlag)
{
HiddenFlag = true;
Update();
}
}
void Widget::ActivateWindow()
@ -299,7 +309,7 @@ void Widget::Paint(Canvas* canvas)
OnPaint(canvas);
for (Widget* w = FirstChild(); w != nullptr; w = w->NextSibling())
{
if (w->Type == WidgetType::Child)
if (w->Type == WidgetType::Child && !w->HiddenFlag)
w->Paint(canvas);
}
canvas->setOrigin(oldOrigin);
@ -323,9 +333,21 @@ bool Widget::IsEnabled()
return true;
}
bool Widget::IsHidden()
{
return !IsVisible();
}
bool Widget::IsVisible()
{
return true;
if (Type != WidgetType::Child)
{
return true; // DispWindow->IsVisible();
}
else
{
return !HiddenFlag;
}
}
void Widget::SetFocus()
@ -441,7 +463,7 @@ Widget* Widget::ChildAt(const Point& pos)
{
for (Widget* cur = LastChild(); cur != nullptr; cur = cur->PrevSibling())
{
if (cur->FrameGeometry.contains(pos))
if (!cur->HiddenFlag && cur->FrameGeometry.contains(pos))
{
Widget* cur2 = cur->ChildAt(pos - cur->ContentGeometry.topLeft());
return cur2 ? cur2 : cur;
@ -523,12 +545,26 @@ void Widget::OnWindowMouseMove(const Point& pos)
if (HoverWidget != widget)
{
if (HoverWidget)
HoverWidget->OnMouseLeave();
{
for (Widget* w = HoverWidget; w != widget && w != this; w = w->Parent())
{
Widget* p = w->Parent();
if (!w->FrameGeometry.contains(p->MapFrom(this, pos)))
{
w->OnMouseLeave();
}
}
}
HoverWidget = widget;
}
DispWindow->SetCursor(widget->CurrentCursor);
do
{
widget->OnMouseMove(widget->MapFrom(this, pos));
widget = widget->Parent();
} while (widget != this);
}
}
@ -543,7 +579,13 @@ void Widget::OnWindowMouseDown(const Point& pos, EInputKey key)
Widget* widget = ChildAt(pos);
if (!widget)
widget = this;
widget->OnMouseDown(widget->MapFrom(this, pos), key);
while (widget)
{
bool stopPropagation = widget->OnMouseDown(widget->MapFrom(this, pos), key);
if (stopPropagation || widget == this)
break;
widget = widget->Parent();
}
}
}
@ -558,7 +600,13 @@ void Widget::OnWindowMouseDoubleclick(const Point& pos, EInputKey key)
Widget* widget = ChildAt(pos);
if (!widget)
widget = this;
widget->OnMouseDoubleclick(widget->MapFrom(this, pos), key);
while (widget)
{
bool stopPropagation = widget->OnMouseDoubleclick(widget->MapFrom(this, pos), key);
if (stopPropagation || widget == this)
break;
widget = widget->Parent();
}
}
}
@ -573,7 +621,13 @@ void Widget::OnWindowMouseUp(const Point& pos, EInputKey key)
Widget* widget = ChildAt(pos);
if (!widget)
widget = this;
widget->OnMouseUp(widget->MapFrom(this, pos), key);
while (widget)
{
bool stopPropagation = widget->OnMouseUp(widget->MapFrom(this, pos), key);
if (stopPropagation || widget == this)
break;
widget = widget->Parent();
}
}
}
@ -588,7 +642,13 @@ void Widget::OnWindowMouseWheel(const Point& pos, EInputKey key)
Widget* widget = ChildAt(pos);
if (!widget)
widget = this;
widget->OnMouseWheel(widget->MapFrom(this, pos), key);
while (widget)
{
bool stopPropagation = widget->OnMouseWheel(widget->MapFrom(this, pos), key);
if (stopPropagation || widget == this)
break;
widget = widget->Parent();
}
}
}

View file

@ -56,19 +56,21 @@ void CheckboxLabel::OnPaint(Canvas* canvas)
canvas->drawText(Point(14.0, GetHeight() - 5.0), Colorf::fromRgba8(255, 255, 255), text);
}
void CheckboxLabel::OnMouseDown(const Point& pos, int key)
bool CheckboxLabel::OnMouseDown(const Point& pos, int key)
{
mouseDownActive = true;
SetFocus();
return true;
}
void CheckboxLabel::OnMouseUp(const Point& pos, int key)
bool CheckboxLabel::OnMouseUp(const Point& pos, int key)
{
if (mouseDownActive)
{
Toggle();
}
mouseDownActive = false;
return true;
}
void CheckboxLabel::OnMouseLeave()

View file

@ -301,7 +301,7 @@ void LineEdit::OnMouseMove(const Point& pos)
}
}
void LineEdit::OnMouseDown(const Point& pos, int key)
bool LineEdit::OnMouseDown(const Point& pos, int key)
{
if (key == IK_LeftMouse)
{
@ -318,13 +318,15 @@ void LineEdit::OnMouseDown(const Point& pos, int key)
}
Update();
}
return true;
}
void LineEdit::OnMouseDoubleclick(const Point& pos, int key)
bool LineEdit::OnMouseDoubleclick(const Point& pos, int key)
{
return true;
}
void LineEdit::OnMouseUp(const Point& pos, int key)
bool LineEdit::OnMouseUp(const Point& pos, int key)
{
if (mouse_selecting && key == IK_LeftMouse)
{
@ -346,6 +348,7 @@ void LineEdit::OnMouseUp(const Point& pos, int key)
Update();
}
}
return true;
}
void LineEdit::OnKeyChar(std::string chars)

View file

@ -96,7 +96,7 @@ void ListView::OnPaintFrame(Canvas* canvas)
canvas->fillRect(Rect::xywh(w - 1.0, 0.0, 1.0, h - 0.0), bordercolor);
}
void ListView::OnMouseDown(const Point& pos, int key)
bool ListView::OnMouseDown(const Point& pos, int key)
{
SetFocus();
@ -109,17 +109,19 @@ void ListView::OnMouseDown(const Point& pos, int key)
ScrollToItem(selectedItem);
}
}
return true;
}
void ListView::OnMouseDoubleclick(const Point& pos, int key)
bool ListView::OnMouseDoubleclick(const Point& pos, int key)
{
if (key == IK_LeftMouse)
{
Activate();
}
return true;
}
void ListView::OnMouseWheel(const Point& pos, EInputKey key)
bool ListView::OnMouseWheel(const Point& pos, EInputKey key)
{
if (key == IK_MouseWheelUp)
{
@ -129,6 +131,7 @@ void ListView::OnMouseWheel(const Point& pos, EInputKey key)
{
scrollbar->SetPosition(std::min(scrollbar->GetPosition() + 20.0, scrollbar->GetMax()));
}
return true;
}
void ListView::OnKeyDown(EInputKey key)

View file

@ -57,14 +57,15 @@ void PushButton::OnMouseMove(const Point& pos)
}
}
void PushButton::OnMouseDown(const Point& pos, int key)
bool PushButton::OnMouseDown(const Point& pos, int key)
{
SetFocus();
buttonDown = true;
Update();
return true;
}
void PushButton::OnMouseUp(const Point& pos, int key)
bool PushButton::OnMouseUp(const Point& pos, int key)
{
if (buttonDown)
{
@ -73,6 +74,7 @@ void PushButton::OnMouseUp(const Point& pos, int key)
Repaint();
Click();
}
return true;
}
void PushButton::OnMouseLeave()

View file

@ -169,7 +169,7 @@ void Scrollbar::OnMouseMove(const Point& pos)
Update();
}
void Scrollbar::OnMouseDown(const Point& pos, int key)
bool Scrollbar::OnMouseDown(const Point& pos, int key)
{
mouse_drag_start_pos = pos;
@ -254,9 +254,10 @@ void Scrollbar::OnMouseDown(const Point& pos, int key)
Update();
CaptureMouse();
return true;
}
void Scrollbar::OnMouseUp(const Point& pos, int key)
bool Scrollbar::OnMouseUp(const Point& pos, int key)
{
if (mouse_down_mode == mouse_down_thumb_drag)
{
@ -269,6 +270,7 @@ void Scrollbar::OnMouseUp(const Point& pos, int key)
Update();
ReleaseMouseCapture();
return true;
}
void Scrollbar::OnMouseLeave()

View file

@ -104,6 +104,7 @@ int TabBar::AddTab(const std::shared_ptr<Image>& icon, const std::string& label)
TabBarTab* tab = new TabBarTab(this);
tab->SetIcon(icon);
tab->SetText(label);
tab->OnClick = [=]() { OnTabClicked(tab); };
int pageIndex = Tabs.size();
Tabs.push_back(tab);
if (CurrentIndex == -1)
@ -270,27 +271,21 @@ void TabBarTab::OnMouseMove(const Point& pos)
}
}
void TabBarTab::OnMouseDown(const Point& pos, int key)
bool TabBarTab::OnMouseDown(const Point& pos, int key)
{
mouseDown = true;
Update();
}
void TabBarTab::OnMouseUp(const Point& pos, int key)
{
if (mouseDown)
{
mouseDown = false;
Repaint();
if (OnClick)
OnClick();
return true;
}
bool TabBarTab::OnMouseUp(const Point& pos, int key)
{
return true;
}
void TabBarTab::OnMouseLeave()
{
hot = false;
mouseDown = false;
Update();
}
@ -309,7 +304,10 @@ void TabWidgetStack::SetCurrentWidget(Widget* widget)
CurrentWidget->SetVisible(false);
CurrentWidget = widget;
if (CurrentWidget)
{
CurrentWidget->SetVisible(true);
OnGeometryChanged();
}
}
}

View file

@ -286,7 +286,7 @@ void TextEdit::OnMouseMove(const Point& pos)
}
}
void TextEdit::OnMouseDown(const Point& pos, int key)
bool TextEdit::OnMouseDown(const Point& pos, int key)
{
if (key == IK_LeftMouse)
{
@ -298,13 +298,15 @@ void TextEdit::OnMouseDown(const Point& pos, int key)
Update();
}
return true;
}
void TextEdit::OnMouseDoubleclick(const Point& pos, int key)
bool TextEdit::OnMouseDoubleclick(const Point& pos, int key)
{
return true;
}
void TextEdit::OnMouseUp(const Point& pos, int key)
bool TextEdit::OnMouseUp(const Point& pos, int key)
{
if (mouse_selecting && key == IK_LeftMouse)
{
@ -326,6 +328,7 @@ void TextEdit::OnMouseUp(const Point& pos, int key)
Update();
}
}
return true;
}
void TextEdit::OnKeyChar(std::string chars)

View file

@ -212,7 +212,7 @@ void LogViewer::OnPaint(Canvas* canvas)
}
}
void LogViewer::OnMouseWheel(const Point& pos, EInputKey key)
bool LogViewer::OnMouseWheel(const Point& pos, EInputKey key)
{
if (key == IK_MouseWheelUp)
{
@ -222,6 +222,7 @@ void LogViewer::OnMouseWheel(const Point& pos, EInputKey key)
{
ScrollDown(4);
}
return true;
}
void LogViewer::OnKeyDown(EInputKey key)

View file

@ -43,7 +43,7 @@ public:
protected:
void OnPaintFrame(Canvas* canvas) override;
void OnPaint(Canvas* canvas) override;
void OnMouseWheel(const Point& pos, EInputKey key) override;
bool OnMouseWheel(const Point& pos, EInputKey key) override;
void OnKeyDown(EInputKey key) override;
void OnGeometryChanged() override;