#include "Widget.h" #include "Event.h" #include "EventLoop.h" #include "WindowManager.h" #include "Window.h" #include Widget::Widget(Widget* parent) : Object(parent) { m_backgroundColor = Color::White; m_foregroundColor = Color::Black; } Widget::~Widget() { } void Widget::setWindowRelativeRect(const Rect& rect) { // FIXME: Make some kind of event loop driven ResizeEvent? m_relativeRect = rect; update(); } void Widget::repaint(const Rect& rect) { event(*make(rect)); } void Widget::event(Event& event) { switch (event.type()) { case Event::Paint: if (auto* win = window()) { if (win->isBeingDragged()) return; } m_hasPendingPaintEvent = false; return onPaint(static_cast(event)); case Event::Show: return onShow(static_cast(event)); case Event::Hide: return onHide(static_cast(event)); case Event::KeyDown: return onKeyDown(static_cast(event)); case Event::KeyUp: return onKeyUp(static_cast(event)); case Event::MouseMove: return onMouseMove(static_cast(event)); case Event::MouseDown: if (auto* win = window()) { // FIXME: if (acceptsFocus()) win->setFocusedWidget(this); } return onMouseDown(static_cast(event)); case Event::MouseUp: return onMouseUp(static_cast(event)); default: return Object::event(event); } } void Widget::onPaint(PaintEvent& event) { //printf("Widget::onPaint :)\n"); for (auto* ch : children()) { auto* child = (Widget*)ch; child->onPaint(event); } } void Widget::onShow(ShowEvent&) { } void Widget::onHide(HideEvent&) { } void Widget::onKeyDown(KeyEvent&) { } void Widget::onKeyUp(KeyEvent&) { } void Widget::onMouseDown(MouseEvent&) { } void Widget::onMouseUp(MouseEvent&) { } void Widget::onMouseMove(MouseEvent&) { } void Widget::update() { if (m_hasPendingPaintEvent) return; m_hasPendingPaintEvent = true; EventLoop::main().postEvent(this, make(rect())); } Widget::HitTestResult Widget::hitTest(int x, int y) { // FIXME: Care about z-order. for (auto* ch : children()) { auto* child = (Widget*)ch; if (child->relativeRect().contains(x, y)) { return child->hitTest(x - child->relativeRect().x(), y - child->relativeRect().y()); } } return { this, x, y }; } void Widget::setWindow(Window* window) { if (m_window == window) return; m_window = window; } bool Widget::isFocused() const { if (auto* win = window()) return win->isActive() && win->focusedWidget() == this; return false; } void Widget::setFocus(bool focus) { if (focus == isFocused()) return; if (auto* win = window()) win->setFocusedWidget(this); }