diff options
Diffstat (limited to 'plugingui')
| -rw-r--r-- | plugingui/combobox.cc | 2 | ||||
| -rw-r--r-- | plugingui/eventhandler.cc | 318 | ||||
| -rw-r--r-- | plugingui/eventhandler.h | 37 | ||||
| -rw-r--r-- | plugingui/guievent.h | 132 | ||||
| -rw-r--r-- | plugingui/nativewindow.h | 61 | ||||
| -rw-r--r-- | plugingui/nativewindow_win32.cc | 32 | ||||
| -rw-r--r-- | plugingui/nativewindow_x11.cc | 6 | ||||
| -rw-r--r-- | plugingui/plugingui.cc | 9 | ||||
| -rw-r--r-- | plugingui/plugingui.h | 1 | 
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; | 
