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::  | 
