diff --git a/devtools/create_engine/create_engine.cpp b/devtools/create_engine/create_engine.cpp index f31af277559..12aa7f1a77f 100644 --- a/devtools/create_engine/create_engine.cpp +++ b/devtools/create_engine/create_engine.cpp @@ -56,9 +56,10 @@ static const char *const FILENAMES_EVENTS[] = { "files_events/messages.cpp", "files_events/messages.h", "files/metaengine.cpp", "files/metaengine.h", "files_events/module.mk", "files_events/xyzzy.cpp", - "files_events/xyzzy.h", "files/POTFILES", - "files_events/views.h", "files_events/view1.cpp", - "files_events/view1.h", nullptr + "files_events/xyzzy.h", "files/POTFILES", "files_events/views.h", + "files_events/view.cpp", "files_events/view.h", + "files_events/view1.cpp", "files_events/view1.h", + nullptr }; const char *const ENGINES = "create_project ..\\.. --msvc\n"; diff --git a/devtools/create_engine/files_events/events.cpp b/devtools/create_engine/files_events/events.cpp index df7a10a2ba5..7d3b2335865 100644 --- a/devtools/create_engine/files_events/events.cpp +++ b/devtools/create_engine/files_events/events.cpp @@ -87,14 +87,17 @@ void Events::processEvent(Common::Event &ev) { break; case Common::EVENT_LBUTTONDOWN: case Common::EVENT_RBUTTONDOWN: - //case Common::EVENT_MBUTTONDOWN: + case Common::EVENT_MBUTTONDOWN: msgMouseDown(MouseDownMessage(ev.type, ev.mouse)); break; case Common::EVENT_LBUTTONUP: case Common::EVENT_RBUTTONUP: - //case Common::EVENT_MBUTTONUP: + case Common::EVENT_MBUTTONUP: msgMouseUp(MouseUpMessage(ev.type, ev.mouse)); break; + case Common::EVENT_MOUSEMOVE: + msgMouseMove(MouseMoveMessage(ev.type, ev.mouse)); + break; default: break; } diff --git a/devtools/create_engine/files_events/events.h b/devtools/create_engine/files_events/events.h index 1c94f247430..84fa8068223 100644 --- a/devtools/create_engine/files_events/events.h +++ b/devtools/create_engine/files_events/events.h @@ -207,6 +207,12 @@ public: /** * Handles events */ + // Mouse move only has a minimal implementation for performance reasons +protected: + virtual bool msgMouseMove(const MouseMoveMessage &msg) { return false; } +public: + bool send(const MouseMoveMessage &msg) { return msgMouseMove(msg); } + #define MESSAGE(NAME) \ protected: \ virtual bool msg##NAME(const NAME##Message &e) { \ @@ -223,7 +229,7 @@ public: return view->msg##NAME(msg); \ } \ bool send(const NAME##Message &msg) { \ - return send("Root", msg); \ + return msg##NAME(msg); \ } \ MESSAGE(Focus); @@ -272,6 +278,7 @@ protected: MESSAGE(Keypress); MESSAGE(MouseDown); MESSAGE(MouseUp); + MESSAGE(MouseMove); #undef MESSAGE public: Events(); diff --git a/devtools/create_engine/files_events/messages.h b/devtools/create_engine/files_events/messages.h index aaa6e3685a1..16b624c613f 100644 --- a/devtools/create_engine/files_events/messages.h +++ b/devtools/create_engine/files_events/messages.h @@ -71,6 +71,7 @@ struct MouseUpMessage : public MouseMessage { MouseUpMessage(Common::EventType type, const Common::Point &pos) : MouseMessage(type, pos) {} }; +typedef MouseMessage MouseMoveMessage; struct GameMessage : public Message { Common::String _name; diff --git a/devtools/create_engine/files_events/module.mk b/devtools/create_engine/files_events/module.mk index 9af3a1cb34a..bc94a085190 100644 --- a/devtools/create_engine/files_events/module.mk +++ b/devtools/create_engine/files_events/module.mk @@ -6,6 +6,7 @@ MODULE_OBJS = \ events.o \ messages.o \ metaengine.o \ + view.o \ view1.o # This module can be built as a plugin diff --git a/devtools/create_engine/files_events/view.cpp b/devtools/create_engine/files_events/view.cpp new file mode 100644 index 00000000000..db9423fa97b --- /dev/null +++ b/devtools/create_engine/files_events/view.cpp @@ -0,0 +1,81 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "xyzzy/view.h" + +namespace Xyzzy { + +void View::checkFocusedControl(const Common::Point &mousePos) { + if (_focusedElement) { + if (!_focusedElement->getBounds().contains(mousePos)) { + _focusedElement->send(UnfocusMessage()); + _focusedElement = nullptr; + } + + } else { + for (UIElement *child : _children) { + if (child->getBounds().contains(mousePos)) { + _focusedElement = child; + child->send(FocusMessage()); + break; + } + } + } +} + +UIElement *View::getElementAtPos(const Common::Point &pos) const { + for (UIElement *child : _children) { + if (child->getBounds().contains(pos)) + return child; + } + + return nullptr; +} + + +bool View::msgFocus(const FocusMessage &msg) { + _focusedElement = nullptr; + return UIElement::msgFocus(msg); +} + +bool View::msgUnfocus(const UnfocusMessage &msg) { + if (_focusedElement) + _focusedElement->send(UnfocusMessage()); + + return UIElement::msgUnfocus(msg); +} + +bool View::msgMouseMove(const MouseMoveMessage &msg) { + checkFocusedControl(msg._pos); + return true; +} + +bool View::msgMouseDown(const MouseDownMessage &msg) { + UIElement *child = getElementAtPos(msg._pos); + return child ? child->send(msg) : false; +} + +bool View::msgMouseUp(const MouseUpMessage &msg) { + UIElement *child = getElementAtPos(msg._pos); + return child ? child->send(msg) : false; +} + +} // namespace Xyzzy diff --git a/devtools/create_engine/files_events/view.h b/devtools/create_engine/files_events/view.h new file mode 100644 index 00000000000..f916883d400 --- /dev/null +++ b/devtools/create_engine/files_events/view.h @@ -0,0 +1,73 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef XYZZY_VIEW_H +#define XYZZY_VIEW_H + +#include "xyzzy/events.h" + +namespace Xyzzy { + +/** + * Base view class for screens and dialogs that appear on-screen. + * The View class takes care of two important things: + * 1) By default events get sent to all controls on a view until one + * handles it. For mouse events, we instead want only the control the + * mouse cursor is over to receive the events, saving the individual + * controls from having to check if the mouse is within their bounds. + * 2) Individual elements will get a Focus/Unfocus message as the + * mouse enters and leaves them. This allows, for example, buttons + * that have been pressed to de-select if the mouse leaves their bounds. + */ +class View : public UIElement { +private: + UIElement *_focusedElement = nullptr; + + /** + * Checks if a control is entered or left + */ + void checkFocusedControl(const Common::Point &mousePos); + + /** + * Check for an element at the given position + */ + UIElement *getElementAtPos(const Common::Point &pos) const; + +public: + View(const Common::String &name, UIElement *uiParent) : + UIElement(name, uiParent) { + } + View(const Common::String &name) : + UIElement(name) { + } + virtual ~View() { + } + + bool msgFocus(const FocusMessage &msg) override; + bool msgUnfocus(const UnfocusMessage &msg) override; + bool msgMouseMove(const MouseMoveMessage &msg) override; + bool msgMouseDown(const MouseDownMessage &msg) override; + bool msgMouseUp(const MouseUpMessage &msg) override; +}; + +} // namespace Xyzzy + +#endif diff --git a/devtools/create_engine/files_events/view1.h b/devtools/create_engine/files_events/view1.h index fcb6fbba6c5..62d0fc50bf9 100644 --- a/devtools/create_engine/files_events/view1.h +++ b/devtools/create_engine/files_events/view1.h @@ -22,17 +22,17 @@ #ifndef XYZZY_VIEW1_H #define XYZZY_VIEW1_H -#include "xyzzy/events.h" +#include "xyzzy/view.h" namespace Xyzzy { -class View1 : public UIElement { +class View1 : public View { private: byte _pal[256 * 3] = { 0 }; int _offset = 0; public: - View1() : UIElement("View1") {} + View1() : View("View1") {} virtual ~View1() {} bool msgFocus(const FocusMessage &msg) override;