summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugingui/eventhandler.cc60
-rw-r--r--plugingui/eventhandler.h6
-rw-r--r--plugingui/nativewindow.h4
-rw-r--r--plugingui/nativewindow_pugl.cc10
-rw-r--r--plugingui/nativewindow_pugl.h1
-rw-r--r--plugingui/nativewindow_win32.cc19
-rw-r--r--plugingui/nativewindow_win32.h1
-rw-r--r--plugingui/nativewindow_x11.cc60
-rw-r--r--plugingui/nativewindow_x11.h2
9 files changed, 120 insertions, 43 deletions
diff --git a/plugingui/eventhandler.cc b/plugingui/eventhandler.cc
index 98e4cef..68f7f46 100644
--- a/plugingui/eventhandler.cc
+++ b/plugingui/eventhandler.cc
@@ -48,6 +48,11 @@ Event *EventHandler::getNextEvent()
return nativeWindow.getNextEvent();
}
+Event *EventHandler::peekNextEvent()
+{
+ return nativeWindow.peekNextEvent();
+}
+
void EventHandler::processEvents()
{
while(hasEvent())
@@ -68,6 +73,22 @@ void EventHandler::processEvents()
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()))
@@ -79,6 +100,22 @@ void EventHandler::processEvents()
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);
@@ -173,7 +210,27 @@ void EventHandler::processEvents()
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)
@@ -188,6 +245,9 @@ void EventHandler::processEvents()
case EventType::key:
{
+
+ // TODO: Filter out multiple arrow events.
+
auto keyEvent = static_cast<KeyEvent*>(event);
if(window.keyboardFocus())
{
diff --git a/plugingui/eventhandler.h b/plugingui/eventhandler.h
index 8fa42e4..b011f87 100644
--- a/plugingui/eventhandler.h
+++ b/plugingui/eventhandler.h
@@ -38,7 +38,7 @@ class EventHandler {
public:
EventHandler(NativeWindow& nativeWindow, Window& window);
- //! \brief Process all evebts currently in the event queue.
+ //! \brief Process all events currently in the event queue.
void processEvents();
//! \brief Query if any events are currently in the event queue.
@@ -48,6 +48,10 @@ public:
//! \return A pointer to the event or nullptr if there are none.
Event *getNextEvent();
+ //! \brief Get a single event from the event queue without popping it.
+ //! \return A pointer to the event or nullptr if there are none.
+ Event *peekNextEvent();
+
Notifier<> closeNotifier;
private:
diff --git a/plugingui/nativewindow.h b/plugingui/nativewindow.h
index 46891f2..a44693c 100644
--- a/plugingui/nativewindow.h
+++ b/plugingui/nativewindow.h
@@ -75,6 +75,10 @@ public:
//! \brief Read a single event from the event queue.
//! \return A pointer to the event or nullptr is none exists.
virtual Event *getNextEvent() = 0;
+
+ //! \brief Read next event without popping it from the event queue.
+ //! \return A pointer to the event or nullptr is none exists.
+ virtual Event* peekNextEvent() = 0;
};
} // GUI::
diff --git a/plugingui/nativewindow_pugl.cc b/plugingui/nativewindow_pugl.cc
index 0864c2b..b9dcd54 100644
--- a/plugingui/nativewindow_pugl.cc
+++ b/plugingui/nativewindow_pugl.cc
@@ -243,4 +243,14 @@ Event *NativeWindowPugl::getNextEvent()
return event;
}
+Event *NativeWindowPugl::peekNextEvent()
+{
+ Event *event = nullptr;
+
+ if(!eventq.empty()) {
+ event = eventq.front();
+ }
+ return event;
+}
+
} // GUI::
diff --git a/plugingui/nativewindow_pugl.h b/plugingui/nativewindow_pugl.h
index f5d89ab..335e7e4 100644
--- a/plugingui/nativewindow_pugl.h
+++ b/plugingui/nativewindow_pugl.h
@@ -54,6 +54,7 @@ public:
bool hasEvent();
Event *getNextEvent();
+ Event *peekNextEvent();
private:
Window* window{nullptr};
diff --git a/plugingui/nativewindow_win32.cc b/plugingui/nativewindow_win32.cc
index 9f8936f..72e0598 100644
--- a/plugingui/nativewindow_win32.cc
+++ b/plugingui/nativewindow_win32.cc
@@ -411,7 +411,7 @@ void NativeWindowWin32::grabMouse(bool grab)
bool NativeWindowWin32::hasEvent()
{
MSG msg;
- return PeekMessage(&msg, nullptr, 0, 0, 0) != 0;
+ return PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE) != 0;
}
Event* NativeWindowWin32::getNextEvent()
@@ -431,4 +431,21 @@ Event* NativeWindowWin32::getNextEvent()
return event;
}
+Event* NativeWindowWin32::peekNextEvent()
+{
+ Event* event = nullptr;
+
+ MSG msg;
+ if(PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ event = this->event;
+ this->event = nullptr;
+
+ return event;
+}
+
} // GUI::
diff --git a/plugingui/nativewindow_win32.h b/plugingui/nativewindow_win32.h
index 57172f4..fa4b6bc 100644
--- a/plugingui/nativewindow_win32.h
+++ b/plugingui/nativewindow_win32.h
@@ -54,6 +54,7 @@ public:
bool hasEvent() override;
Event* getNextEvent() override;
+ Event* peekNextEvent() override;
private:
static LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
diff --git a/plugingui/nativewindow_x11.cc b/plugingui/nativewindow_x11.cc
index d47c67f..02ee653 100644
--- a/plugingui/nativewindow_x11.cc
+++ b/plugingui/nativewindow_x11.cc
@@ -353,30 +353,29 @@ Event* NativeWindowX11::getNextEvent()
return nullptr;
}
- Event* event = nullptr;
-
- XEvent xevent;
- XNextEvent(display, &xevent);
+ XEvent xEvent;
+ XNextEvent(display, &xEvent);
+ return translateXMessage(xEvent);
+}
- if(xevent.type == MotionNotify)
+Event* NativeWindowX11::peekNextEvent()
+{
+ if(display == nullptr)
{
- while(true) // Hack to make sure only the last event is played.
- {
- if(!hasEvent())
- {
- break;
- }
+ return nullptr;
+ }
- XEvent peekXEvent;
- XPeekEvent(display, &peekXEvent);
- if(peekXEvent.type != MotionNotify)
- {
- break;
- }
+ XEvent peekXEvent;
+ XPeekEvent(display, &peekXEvent);
+ return translateXMessage(peekXEvent);
+}
- XNextEvent(display, &xevent);
- }
+Event* NativeWindowX11::translateXMessage(XEvent& xevent)
+{
+ Event* event = nullptr;
+ if(xevent.type == MotionNotify)
+ {
auto mouseMoveEvent = new MouseMoveEvent();
mouseMoveEvent->window_id = xevent.xmotion.window;
mouseMoveEvent->x = xevent.xmotion.x;
@@ -411,26 +410,6 @@ Event* NativeWindowX11::getNextEvent()
if((xevent.xbutton.button == 4) || (xevent.xbutton.button == 5))
{
int scroll = 1;
- while(true) // Hack to make sure only the last event is played.
- {
- if(!hasEvent())
- {
- break;
- }
-
- XEvent peekXEvent;
- XPeekEvent(display, &peekXEvent);
-
- if((peekXEvent.type != ButtonPress) &&
- (peekXEvent.type != ButtonRelease))
- {
- break;
- }
-
- scroll += 1;
- XNextEvent(display, &xevent);
- }
-
auto scrollEvent = new ScrollEvent();
scrollEvent->window_id = xevent.xbutton.window;
scrollEvent->x = xevent.xbutton.x;
@@ -455,7 +434,7 @@ Event* NativeWindowX11::getNextEvent()
buttonEvent->button = MouseButton::right;
break;
default:
- WARN(X11, "Unknown button %d, setting to Left\n",
+ WARN(X11, "Unknown button %d, setting to MouseButton::left\n",
xevent.xbutton.button);
buttonEvent->button = MouseButton::left;
break;
@@ -479,7 +458,6 @@ Event* NativeWindowX11::getNextEvent()
if(xevent.type == KeyPress || xevent.type == KeyRelease)
{
- //printf("key: %d\n", xevent.xkey.keycode);
auto keyEvent = new KeyEvent();
keyEvent->window_id = xevent.xkey.window;
diff --git a/plugingui/nativewindow_x11.h b/plugingui/nativewindow_x11.h
index fb43457..2529631 100644
--- a/plugingui/nativewindow_x11.h
+++ b/plugingui/nativewindow_x11.h
@@ -50,8 +50,10 @@ public:
void grabMouse(bool grab) override;
bool hasEvent() override;
Event* getNextEvent() override;
+ Event* peekNextEvent() override;
private:
+ Event* translateXMessage(XEvent& xevent);
XImage* createImageFromBuffer(unsigned char* buf, int width, int height);
::Window xwindow;