diff options
Diffstat (limited to 'plugingui/eventhandler.cc')
-rw-r--r-- | plugingui/eventhandler.cc | 371 |
1 files changed, 221 insertions, 150 deletions
diff --git a/plugingui/eventhandler.cc b/plugingui/eventhandler.cc index cec5fab..9a6fa8d 100644 --- a/plugingui/eventhandler.cc +++ b/plugingui/eventhandler.cc @@ -29,166 +29,237 @@ #include "window.h" #include "painter.h" -GUI::EventHandler::EventHandler(GUI::NativeWindow *n, GUI::Window *w) -{ - native = n; - window = w; +namespace GUI { - last_click = 0; - last_was_dbl_click = false; -} +EventHandler::EventHandler(NativeWindow& nativeWindow, Window& window) + : window(window) + , nativeWindow(nativeWindow) +// , last_click(0) + , lastWasDoubleClick(false) +{} -bool GUI::EventHandler::hasEvent() +bool EventHandler::hasEvent() { - return native->hasEvent(); + return nativeWindow.hasEvent(); } -GUI::Event *GUI::EventHandler::getNextEvent() +Event *EventHandler::getNextEvent() { - return native->getNextEvent(); + return nativeWindow.getNextEvent(); } -void GUI::EventHandler::registerCloseHandler(void (*handler)(void *), void *ptr) +Event *EventHandler::peekNextEvent() { - this->closeHandler = handler; - this->closeHandlerPtr = ptr; + return nativeWindow.peekNextEvent(); } -void GUI::EventHandler::processEvents() +void EventHandler::processEvents() { - while(hasEvent()) { - Painter p(window); // Make sure we only redraw buffer one time. - - Event *event = getNextEvent(); - - if(event == NULL) continue; - - // Widget *widget = gctx->widgets[event->window_id]; - switch(event->type()) { - case Event::Repaint: - // window->repaint((RepaintEvent*)event); - window->redraw(); - break; - case Event::Resize: - { - // window->repaint((RepaintEvent*)event) - ResizeEvent *re = (ResizeEvent*)event; - if(re->width != window->width() || re->height != window->height()) { - window->resized(re->width, re->height); - //window->repaint_r(NULL); - } - } - break; - case Event::MouseMove: - { - MouseMoveEvent *me = (MouseMoveEvent*)event; - - Widget *w = window->find(me->x, me->y); - Widget *oldw = window->mouseFocus(); - if(w != oldw) { - // Send focus leave to oldw - if(oldw) oldw->mouseLeaveEvent(); - // Send focus enter to w - if(w) w->mouseEnterEvent(); - - window->setMouseFocus(w); - } - - if(window->buttonDownFocus()) { - Widget *w = window->buttonDownFocus(); - /* - if(me->x < w->x()) me->x = w->x(); - if(me->x > w->x() + w->width()) me->x = w->x() + w->width(); - if(me->y < w->y()) me->y = w->y(); - if(me->y > w->y() + w->height()) me->y = w->y() + w->height(); - */ - me->x -= w->windowX(); - me->y -= w->windowY(); - - window->buttonDownFocus()->mouseMoveEvent(me); - break; - } - - if(w) { - me->x -= w->windowX(); - me->y -= w->windowY(); - w->mouseMoveEvent(me); - } - } - break; - case Event::Button: - { - if(last_was_dbl_click) { - last_was_dbl_click = false; - continue; - } - ButtonEvent *be = (ButtonEvent *)event; - - last_was_dbl_click = be->doubleclick; - - Widget *w = window->find(be->x, be->y); - - if(window->buttonDownFocus()) { - if(be->direction == -1) { - Widget *w = window->buttonDownFocus(); - /* - if(be->x < w->x()) be->x = w->x(); - if(be->x > w->x() + w->width()) be->x = w->x() + w->width(); - if(be->y < w->y()) be->y = w->y(); - if(be->y > w->y() + w->height()) be->y = w->y() + w->height(); - */ - be->x -= w->windowX(); - be->y -= w->windowY(); - - w->buttonEvent(be); - break; - } else { - window->setButtonDownFocus(NULL); - } - } - - if(w) { - be->x -= w->windowX(); - be->y -= w->windowY(); - - w->buttonEvent(be); - - if(be->direction == 1) { - if(w->catchMouse()) window->setButtonDownFocus(w); - } - - if(w->isFocusable()) window->setKeyboardFocus(w); - } - } - break; - case Event::Scroll: - { - ScrollEvent *se = (ScrollEvent *)event; - - Widget *w = window->find(se->x, se->y); - - //printf("scroller (%d,%d) %p\n", se->x, se->y, w); - - if(w) { - se->x -= w->windowX(); - se->y -= w->windowY(); - - w->scrollEvent(se); - } - } - break; - case Event::Key: - // window->key((KeyEvent*)event); - // lineedit->keyEvent((KeyEvent*)event); - if(window->keyboardFocus()) - window->keyboardFocus()->keyEvent((KeyEvent*)event); - break; - case Event::Close: - if(closeHandler) closeHandler(closeHandlerPtr); - //delete window; - //window = NULL; - break; - } - delete event; - } + while(hasEvent()) + { + Painter p(window); // Make sure we only redraw buffer one time. + + auto event = getNextEvent(); + + if(event == nullptr) + { + continue; + } + + switch(event->type()) { + case EventType::repaint: + window.redraw(); + break; + + case EventType::resize: + { + while(true) + { + if(!hasEvent()) + { + break; + } + + auto peekEvent = peekNextEvent(); + if(!peekEvent || (peekEvent->type() != EventType::resize)) + { + break; + } + + event = getNextEvent(); + } + + auto resizeEvent = static_cast<ResizeEvent*>(event); + if((resizeEvent->width != window.width()) || + (resizeEvent->height != window.height())) + { + window.resized(resizeEvent->width, resizeEvent->height); + } + } + break; + + case EventType::mouseMove: + { + while(true) + { + if(!hasEvent()) + { + break; + } + + auto peekEvent = peekNextEvent(); + if(!peekEvent || (peekEvent->type() != EventType::mouseMove)) + { + break; + } + + event = getNextEvent(); + } + + auto moveEvent = static_cast<MouseMoveEvent*>(event); + + auto widget = window.find(moveEvent->x, moveEvent->y); + auto oldwidget = window.mouseFocus(); + if(widget != oldwidget) + { + // Send focus leave to oldwidget + if(oldwidget) + { + oldwidget->mouseLeaveEvent(); + } + + // Send focus enter to widget + if(widget) + { + widget->mouseEnterEvent(); + } + + window.setMouseFocus(widget); + } + + if(window.buttonDownFocus()) + { + auto widget = window.buttonDownFocus(); + moveEvent->x -= widget->windowX(); + moveEvent->y -= widget->windowY(); + + window.buttonDownFocus()->mouseMoveEvent(moveEvent); + break; + } + + if(widget) + { + moveEvent->x -= widget->windowX(); + moveEvent->y -= widget->windowY(); + widget->mouseMoveEvent(moveEvent); + } + } + break; + + case EventType::button: + { + if(lastWasDoubleClick) + { + lastWasDoubleClick = false; + continue; + } + + auto buttonEvent = static_cast<ButtonEvent*>(event); + + lastWasDoubleClick = buttonEvent->doubleClick; + + auto widget = window.find(buttonEvent->x, buttonEvent->y); + + if(window.buttonDownFocus()) + { + if(buttonEvent->direction == Direction::up) + { + auto widget = window.buttonDownFocus(); + buttonEvent->x -= widget->windowX(); + buttonEvent->y -= widget->windowY(); + + widget->buttonEvent(buttonEvent); + window.setButtonDownFocus(nullptr); + break; + } + } + + if(widget) + { + buttonEvent->x -= widget->windowX(); + buttonEvent->y -= widget->windowY(); + + widget->buttonEvent(buttonEvent); + + if((buttonEvent->direction == Direction::down) && + widget->catchMouse()) + { + window.setButtonDownFocus(widget); + } + + if(widget->isFocusable()) + { + window.setKeyboardFocus(widget); + } + } + } + break; + + case EventType::scroll: + { + int delta = 0; + while(true) + { + if(!hasEvent()) + { + break; + } + + auto peekEvent = peekNextEvent(); + if(!peekEvent || (peekEvent->type() != EventType::scroll)) + { + break; + } + + auto scrollEvent = static_cast<ScrollEvent*>(event); + delta += scrollEvent->delta; + event = getNextEvent(); + } + + auto scrollEvent = static_cast<ScrollEvent*>(event); + scrollEvent->delta += delta; + + auto widget = window.find(scrollEvent->x, scrollEvent->y); + if(widget) + { + scrollEvent->x -= widget->windowX(); + scrollEvent->y -= widget->windowY(); + + widget->scrollEvent(scrollEvent); + } + } + break; + + case EventType::key: + { + + // TODO: Filter out multiple arrow events. + + auto keyEvent = static_cast<KeyEvent*>(event); + if(window.keyboardFocus()) + { + window.keyboardFocus()->keyEvent(keyEvent); + } + } + break; + + case EventType::close: + closeNotifier(); + break; + } + + delete event; + } } + +} // GUI:: |