summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugingui/combobox.cc2
-rw-r--r--plugingui/eventhandler.cc318
-rw-r--r--plugingui/eventhandler.h37
-rw-r--r--plugingui/guievent.h132
-rw-r--r--plugingui/nativewindow.h61
-rw-r--r--plugingui/nativewindow_win32.cc32
-rw-r--r--plugingui/nativewindow_x11.cc6
-rw-r--r--plugingui/plugingui.cc9
-rw-r--r--plugingui/plugingui.h1
9 files changed, 324 insertions, 274 deletions
diff --git a/plugingui/combobox.cc b/plugingui/combobox.cc
index 4d2637a..c627b05 100644
--- a/plugingui/combobox.cc
+++ b/plugingui/combobox.cc
@@ -38,7 +38,7 @@ namespace GUI {
void ComboBox::listboxSelectHandler()
{
ButtonEvent e;
- e.direction = 1;
+ e.direction = ButtonEvent::Down;
buttonEvent(&e);
}
diff --git a/plugingui/eventhandler.cc b/plugingui/eventhandler.cc
index cec5fab..e47cbf5 100644
--- a/plugingui/eventhandler.cc
+++ b/plugingui/eventhandler.cc
@@ -29,166 +29,180 @@
#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)
+void EventHandler::processEvents()
{
- this->closeHandler = handler;
- this->closeHandlerPtr = ptr;
+ while(hasEvent())
+ {
+ Painter p(window); // Make sure we only redraw buffer one time.
+
+ auto event = getNextEvent();
+
+ if(event == nullptr)
+ {
+ continue;
+ }
+
+ switch(event->type()) {
+ case Event::Repaint:
+ window->redraw();
+ break;
+
+ case Event::Resize:
+ {
+ auto resizeEvent = static_cast<ResizeEvent*>(event);
+ if((resizeEvent->width != window->width()) ||
+ (resizeEvent->height != window->height()))
+ {
+ window->resized(resizeEvent->width, resizeEvent->height);
+ }
+ }
+ break;
+
+ case Event::MouseMove:
+ {
+ 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 Event::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 == ButtonEvent::Up)
+ {
+ auto widget = window->buttonDownFocus();
+ buttonEvent->x -= widget->windowX();
+ buttonEvent->y -= widget->windowY();
+
+ widget->buttonEvent(buttonEvent);
+ break;
+ }
+ else // Event::Button::Down
+ {
+ window->setButtonDownFocus(nullptr);
+ }
+ }
+
+ if(widget)
+ {
+ buttonEvent->x -= widget->windowX();
+ buttonEvent->y -= widget->windowY();
+
+ widget->buttonEvent(buttonEvent);
+
+ if((buttonEvent->direction == ButtonEvent::Down) &&
+ widget->catchMouse())
+ {
+ window->setButtonDownFocus(widget);
+ }
+
+ if(widget->isFocusable())
+ {
+ window->setKeyboardFocus(widget);
+ }
+ }
+ }
+ break;
+
+ case Event::Scroll:
+ {
+ auto scrollEvent = static_cast<ScrollEvent*>(event);
+
+ auto widget = window->find(scrollEvent->x, scrollEvent->y);
+ if(widget)
+ {
+ scrollEvent->x -= widget->windowX();
+ scrollEvent->y -= widget->windowY();
+
+ widget->scrollEvent(scrollEvent);
+ }
+ }
+ break;
+
+ case Event::Key:
+ {
+ auto keyEvent = static_cast<KeyEvent*>(event);
+ if(window->keyboardFocus())
+ {
+ window->keyboardFocus()->keyEvent(keyEvent);
+ }
+ }
+ break;
+
+ case Event::Close:
+ closeNotifier();
+ break;
+ }
+
+ delete event;
+ }
}
-void GUI::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;
- }
-}
+} // GUI::
diff --git a/plugingui/eventhandler.h b/plugingui/eventhandler.h
index 028418d..b865cbb 100644
--- a/plugingui/eventhandler.h
+++ b/plugingui/eventhandler.h
@@ -24,39 +24,38 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#ifndef __DRUMGIZMO_EVENTHANDLER_H__
-#define __DRUMGIZMO_EVENTHANDLER_H__
+#pragma once
#include "guievent.h"
#include "nativewindow.h"
-//#include "window.h"
+#include "notifier.h"
namespace GUI {
+
class Window;
class EventHandler {
public:
- EventHandler(NativeWindow *native, Window *window);
-
- void processEvents();
+ EventHandler(NativeWindow *nativeWindow, Window *window);
- bool hasEvent();
- Event *getNextEvent();
+ //! \brief Process all evebts currently in the event queue.
+ void processEvents();
- void registerCloseHandler(void (*handler)(void *), void *ptr);
+ //! \brief Query if any events are currently in the event queue.
+ bool hasEvent();
-private:
- Window *window;
- int last_click;
- void (*closeHandler)(void *);
- void *closeHandlerPtr;
+ //! \brief Get a single event from the event queue.
+ //! \return A pointer to the event or nullptr if there are none.
+ Event *getNextEvent();
- // Used to ignore mouse button release after a double click.
- bool last_was_dbl_click;
+ Notifier<> closeNotifier;
- NativeWindow *native;
-};
+private:
+ Window *window;
+ NativeWindow *nativeWindow;
+ // Used to ignore mouse button release after a double click.
+ bool lastWasDoubleClick;
};
-#endif/*__DRUMGIZMO_EVENTHANDLER_H__*/
+} // GUI::
diff --git a/plugingui/guievent.h b/plugingui/guievent.h
index 4732101..221e056 100644
--- a/plugingui/guievent.h
+++ b/plugingui/guievent.h
@@ -24,8 +24,7 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#ifndef __DRUMGIZMO_GUI_EVENT_H__
-#define __DRUMGIZMO_GUI_EVENT_H__
+#pragma once
#include <unistd.h>
@@ -40,102 +39,113 @@ namespace GUI {
class Event {
public:
- typedef enum {
- MouseMove,
- Repaint,
- Button,
- Scroll,
- Key,
- Close,
- Resize
- } Type;
- virtual ~Event() {}
-
- virtual Type type() = 0;
+ typedef enum {
+ MouseMove,
+ Repaint,
+ Button,
+ Scroll,
+ Key,
+ Close,
+ Resize
+ } Type;
+ virtual ~Event() {}
+
+ virtual Type type() = 0;
#ifdef X11
- ::Window window_id;
+ ::Window window_id;
#endif/*X11*/
};
class MouseMoveEvent : public Event {
public:
- Type type() { return MouseMove; }
+ Type type() { return MouseMove; }
- int x;
- int y;
+ int x;
+ int y;
};
class ButtonEvent : public Event {
public:
- Type type() { return Button; }
+ Type type() { return Button; }
- int x;
- int y;
+ int x;
+ int y;
- int direction;
- int button;
- int doubleclick;
+ enum {
+ Up,
+ Down,
+ } direction;
+
+ enum {
+ Right,
+ Middle,
+ Left,
+ } button;
+
+ bool doubleclick;
};
class ScrollEvent : public Event {
public:
- Type type() { return Scroll; }
+ Type type() { return Scroll; }
- int x;
- int y;
+ int x;
+ int y;
- int delta;
+ int delta;
};
class RepaintEvent : public Event {
public:
- Type type() { return Repaint; }
+ Type type() { return Repaint; }
- int x;
- int y;
- size_t width;
- size_t height;
+ int x;
+ int y;
+ size_t width;
+ size_t height;
};
class KeyEvent : public Event {
public:
- Type type() { return Key; }
-
- int direction;
- int keycode;
- std::string text;
-
- enum {
- KEY_UNKNOWN =-1,
- KEY_LEFT = 1,
- KEY_RIGHT = 2,
- KEY_UP = 3,
- KEY_DOWN = 4,
- KEY_DELETE = 5,
- KEY_BACKSPACE = 6,
- KEY_HOME = 7,
- KEY_END = 8,
- KEY_PGDOWN = 9,
- KEY_PGUP = 10,
- KEY_ENTER = 11,
- KEY_CHARACTER = 0xffff // character data is stored in 'text'
- };
+ Type type() { return Key; }
+
+ enum {
+ Up,
+ Down,
+ } direction;
+
+ int keycode;
+ std::string text;
+
+ enum {
+ KEY_UNKNOWN =-1,
+ KEY_LEFT = 1,
+ KEY_RIGHT = 2,
+ KEY_UP = 3,
+ KEY_DOWN = 4,
+ KEY_DELETE = 5,
+ KEY_BACKSPACE = 6,
+ KEY_HOME = 7,
+ KEY_END = 8,
+ KEY_PGDOWN = 9,
+ KEY_PGUP = 10,
+ KEY_ENTER = 11,
+ KEY_CHARACTER = 0xffff // character data is stored in 'text'
+ };
};
class CloseEvent : public Event {
public:
- Type type() { return Close; }
+ Type type() { return Close; }
};
class ResizeEvent : public Event {
public:
- Type type() { return Resize; }
-
- size_t width;
- size_t height;
-};
+ Type type() { return Resize; }
+ size_t width;
+ size_t height;
};
-#endif/*__DRUMGIZMO_GUI_EVENT_H__*/
+} // GUI::
diff --git a/plugingui/nativewindow.h b/plugingui/nativewindow.h
index d68909d..46891f2 100644
--- a/plugingui/nativewindow.h
+++ b/plugingui/nativewindow.h
@@ -24,8 +24,7 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#ifndef __DRUMGIZMO_NATIVEWINDOW_H__
-#define __DRUMGIZMO_NATIVEWINDOW_H__
+#pragma once
#include <string>
@@ -33,25 +32,49 @@
namespace GUI {
+//! \brief Interface class for native window implementations.
class NativeWindow {
public:
- NativeWindow() {}
- virtual ~NativeWindow() {}
-
- virtual void setFixedSize(int width, int height) = 0;
- virtual void resize(int width, int height) = 0;
- virtual void move(int x, int y) = 0;
- virtual void show() = 0;
- virtual void setCaption(const std::string &caption) = 0;
- virtual void hide() = 0;
- virtual void handleBuffer() = 0;
- virtual void redraw() = 0;
- virtual void grabMouse(bool grab) = 0;
-
- virtual bool hasEvent() = 0;
- virtual Event *getNextEvent() = 0;
-};
+ NativeWindow() {}
+ virtual ~NativeWindow() {}
+
+ //! \brief Set a fixed size to the window.
+ //! It resizes the window and disallows user resizing.
+ virtual void setFixedSize(int width, int height) = 0;
+
+ // TODO: setScalable(bool) ??
+
+ //! \brief Set a new size of the window.
+ virtual void resize(int width, int height) = 0;
+
+ //! \brief Move the window to a new position.
+ virtual void move(int x, int y) = 0;
+
+ //! \brief Show the window if it is hidden.
+ virtual void show() = 0;
+
+ //! \brief Hides the window.
+ virtual void hide() = 0;
+
+ //! \brief Sets the window caption in the title bar (if it has one).
+ virtual void setCaption(const std::string &caption) = 0;
+
+ //! \brief Recreate a window render buffer based on the internal buffer.
+ //! This need to be called whenever the internal buffer size has changed.
+ virtual void handleBuffer() = 0;
+
+ //! \brief Draw the internal rendering buffer to the window buffer.
+ virtual void redraw() = 0;
+
+ //! \brief Toggle capture mouse mode.
+ virtual void grabMouse(bool grab) = 0;
+
+ //! \brief Query if the event queue contains any events.
+ virtual bool hasEvent() = 0;
+ //! \brief Read a single event from the event queue.
+ //! \return A pointer to the event or nullptr is none exists.
+ virtual Event *getNextEvent() = 0;
};
-#endif/*__DRUMGIZMO_NATIVEWINDOW_H__*/
+} // GUI::
diff --git a/plugingui/nativewindow_win32.cc b/plugingui/nativewindow_win32.cc
index 871bafe..fcee1a6 100644
--- a/plugingui/nativewindow_win32.cc
+++ b/plugingui/nativewindow_win32.cc
@@ -125,24 +125,28 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
if(msg == WM_LBUTTONUP ||
msg == WM_LBUTTONDBLCLK ||
- msg == WM_LBUTTONDOWN) e->button = 0;
-
- if(msg == WM_RBUTTONUP ||
+ msg == WM_LBUTTONDOWN) e->button = ButtonEvent::Left;
+ else if(msg == WM_RBUTTONUP ||
msg == WM_RBUTTONDBLCLK ||
- msg == WM_RBUTTONDOWN) e->button = 1;
-
- if(msg == WM_MBUTTONUP ||
+ msg == WM_RBUTTONDOWN) e->button = ButtonEvent::Middle;
+ else if(msg == WM_MBUTTONUP ||
msg == WM_MBUTTONDBLCLK ||
- msg == WM_MBUTTONDOWN) e->button = 2;
+ msg == WM_MBUTTONDOWN) e->button = ButtonEvent::Right;
+ else {
+ delete e;
+ break; // unknown button
+ }
- e->direction = 0;
if(msg == WM_LBUTTONUP ||
msg == WM_RBUTTONUP ||
- msg == WM_MBUTTONUP) e->direction = -1;
-
- if(msg == WM_LBUTTONDOWN ||
+ msg == WM_MBUTTONUP) e->direction = ButtonEvent::Up;
+ else if(msg == WM_LBUTTONDOWN ||
msg == WM_RBUTTONDOWN ||
- msg == WM_MBUTTONDOWN) e->direction = 1;
+ msg == WM_MBUTTONDOWN) e->direction = ButtonEvent::Down;
+ else {
+ delete e;
+ break; // unknown direction
+ }
e->doubleclick = (msg == WM_LBUTTONDBLCLK ||
msg == WM_RBUTTONDBLCLK ||
@@ -171,7 +175,7 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
default: e->keycode = GUI::KeyEvent::KEY_UNKNOWN; break;
}
e->text = "";
- e->direction = -1;
+ e->direction = KeyEvent::Up;
native->event = e;
}
break;
@@ -183,7 +187,7 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
GUI::KeyEvent *e = new GUI::KeyEvent();
e->keycode = GUI::KeyEvent::KEY_CHARACTER;
e->text += (char)wp;
- e->direction = -1;
+ e->direction = KeyEvent::Up;
native->event = e;
}
}
diff --git a/plugingui/nativewindow_x11.cc b/plugingui/nativewindow_x11.cc
index cb6cf73..4d91b32 100644
--- a/plugingui/nativewindow_x11.cc
+++ b/plugingui/nativewindow_x11.cc
@@ -334,8 +334,8 @@ GUI::Event *GUI::NativeWindowX11::getNextEvent()
e->window_id = xe.xbutton.window;
e->x = xe.xbutton.x;
e->y = xe.xbutton.y;
- e->button = 0;
- e->direction = xe.type == ButtonPress?1:-1;
+ e->button = ButtonEvent::Left;
+ e->direction = (xe.type == ButtonPress) ? ButtonEvent::Down : ButtonEvent::Up;
e->doubleclick =
xe.type == ButtonPress && (xe.xbutton.time - last_click) < 200;
@@ -371,7 +371,7 @@ GUI::Event *GUI::NativeWindowX11::getNextEvent()
}
e->text.append(buf, sz);
- e->direction = xe.type == KeyPress?1:-1;
+ e->direction = (xe.type == KeyPress) ? KeyEvent::Down : KeyEvent::Up;
event = e;
}
diff --git a/plugingui/plugingui.cc b/plugingui/plugingui.cc
index 0a68d72..9bb451d 100644
--- a/plugingui/plugingui.cc
+++ b/plugingui/plugingui.cc
@@ -224,10 +224,9 @@ void PluginGUI::deinit()
if(window) delete window;
}
-void closeEventHandler(void *ptr)
+void PluginGUI::closeEventHandler()
{
- volatile bool *closing = (volatile bool*)ptr;
- *closing = true;
+ closing = true;
}
void PluginGUI::init()
@@ -238,8 +237,8 @@ void PluginGUI::init()
config->load();
window = new Window();
- window->eventHandler()->registerCloseHandler(closeEventHandler,
- (void*)&closing);
+ auto eventHandler = window->eventHandler();
+ CONNECT(eventHandler, closeNotifier, this, &PluginGUI::closeEventHandler);
window->setFixedSize(370, 330);
window->setCaption("DrumGizmo v" VERSION);
diff --git a/plugingui/plugingui.h b/plugingui/plugingui.h
index b5fd5d0..52cd8d2 100644
--- a/plugingui/plugingui.h
+++ b/plugingui/plugingui.h
@@ -92,6 +92,7 @@ private:
void velocityCheckClick(bool checked);
void kitBrowseClick();
void midimapBrowseClick();
+ void closeEventHandler();
// Humanized velocity controls:
CheckBox *velocityCheck;