@@ -19,9 +19,9 @@ struct Window; | |||
struct PatchManager; | |||
namespace event { | |||
struct State; | |||
} // namespace event | |||
namespace widget { | |||
struct EventState; | |||
} // namespace widget | |||
namespace app { | |||
@@ -31,7 +31,7 @@ struct Scene; | |||
/** Contains the application state */ | |||
struct Context { | |||
event::State* event = NULL; | |||
widget::EventState* event = NULL; | |||
app::Scene* scene = NULL; | |||
engine::Engine* engine = NULL; | |||
Window* window = NULL; | |||
@@ -1,449 +0,0 @@ | |||
#pragma once | |||
#include <vector> | |||
#include <set> | |||
#include <common.hpp> | |||
#include <math.hpp> | |||
/** Remaps Ctrl to Cmd on Mac | |||
Use this instead of GLFW_MOD_CONTROL, since Cmd should be used on Mac in place of Ctrl on Linux/Windows. | |||
*/ | |||
#if defined ARCH_MAC | |||
#define RACK_MOD_CTRL GLFW_MOD_SUPER | |||
#define RACK_MOD_CTRL_NAME "⌘" | |||
#else | |||
#define RACK_MOD_CTRL GLFW_MOD_CONTROL | |||
#define RACK_MOD_CTRL_NAME "Ctrl" | |||
#endif | |||
#define RACK_MOD_SHIFT_NAME "Shift" | |||
#define RACK_MOD_ALT_NAME "Alt" | |||
/** Filters actual mod keys from the mod flags. | |||
Use this if you don't care about GLFW_MOD_CAPS_LOCK and GLFW_MOD_NUM_LOCK. | |||
Example usage: | |||
if ((e.mod & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) ... | |||
*/ | |||
#define RACK_MOD_MASK (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SUPER) | |||
namespace rack { | |||
namespace widget { | |||
struct Widget; | |||
} | |||
/** Handles user interaction with Widget. | |||
*/ | |||
namespace event { | |||
/** A per-event state shared and writable by all widgets that recursively handle an event. */ | |||
struct Context { | |||
/** Whether the event should continue recursing to children Widgets. */ | |||
bool propagating = true; | |||
/** Whether the event has been consumed by an event handler and no more handlers should consume the event. */ | |||
bool consumed = false; | |||
/** The widget that responded to the event. */ | |||
widget::Widget* target = NULL; | |||
}; | |||
/** Base class for all events. */ | |||
struct Base { | |||
Context* context = NULL; | |||
/** Prevents the event from being handled by more Widgets. | |||
*/ | |||
void stopPropagating() const { | |||
if (!context) | |||
return; | |||
context->propagating = false; | |||
} | |||
bool isPropagating() const { | |||
if (!context) | |||
return true; | |||
return context->propagating; | |||
} | |||
/** Tells the event handler that a particular Widget consumed the event. | |||
You usually want to stop propagation as well, so call consume() instead. | |||
*/ | |||
void setTarget(widget::Widget* w) const { | |||
if (!context) | |||
return; | |||
context->target = w; | |||
} | |||
widget::Widget* getTarget() const { | |||
if (!context) | |||
return NULL; | |||
return context->target; | |||
} | |||
/** Sets the target Widget and stops propagating. | |||
A NULL Widget may be passed to consume but not set a target. | |||
*/ | |||
void consume(widget::Widget* w) const { | |||
if (!context) | |||
return; | |||
context->propagating = false; | |||
context->consumed = true; | |||
context->target = w; | |||
} | |||
void unconsume() const { | |||
if (!context) | |||
return; | |||
context->consumed = false; | |||
} | |||
bool isConsumed() const { | |||
if (!context) | |||
return false; | |||
return context->consumed; | |||
} | |||
}; | |||
/** An event prototype with a vector position. */ | |||
struct PositionBase { | |||
/** The pixel coordinate where the event occurred, relative to the Widget it is called on. */ | |||
math::Vec pos; | |||
}; | |||
#define RACK_HELD 3 | |||
/** An event prototype with a GLFW key. */ | |||
struct KeyBase { | |||
/** The key corresponding to what it would be called in its position on a QWERTY US keyboard. | |||
For example, the WASD directional keys used for first-person shooters will always be reported as "WASD", regardless if they say "ZQSD" on an AZERTY keyboard. | |||
You should usually not use these for printable characters such as "Ctrl+V" key commands. Instead, use `keyName`. | |||
You *should* use these for non-printable keys, such as Escape, arrow keys, Home, F1-12, etc. | |||
You should also use this for Enter, Tab, and Space. Although they are printable keys, they do not appear in `keyName`. | |||
See GLFW_KEY_* for the list of possible values. | |||
*/ | |||
int key; | |||
/** Platform-dependent "software" key code. | |||
This variable is only included for completion. There should be no reason for you to use this. | |||
You should instead use `key` (for non-printable characters) or `keyName` (for printable characters). | |||
Values are platform independent and can change between different keyboards or keyboard layouts on the same OS. | |||
*/ | |||
int scancode; | |||
/** String containing the lowercase key name, if it produces a printable character. | |||
This is the only variable that correctly represents the label printed on any keyboard layout, whether it's QWERTY, AZERTY, QWERTZ, Dvorak, etc. | |||
For example, if the user presses the key labeled "q" regardless of the key position, `keyName` will be "q". | |||
For non-printable characters this is an empty string. | |||
Enter, Tab, and Space do not give a `keyName`. Use `key` instead. | |||
Shift has no effect on the key name. Shift+1 results in "1", Shift+q results in "q", etc. | |||
*/ | |||
std::string keyName; | |||
/** The type of event occurring with the key. | |||
Possible values are GLFW_RELEASE, GLFW_PRESS, GLFW_REPEAT, or RACK_HELD. | |||
RACK_HELD is sent every frame while the key is held. | |||
*/ | |||
int action; | |||
/** Bitwise OR of key modifiers, such as Ctrl or Shift. | |||
Use (mods & RACK_MOD_MASK) == RACK_MOD_CTRL to check for Ctrl on Linux and Windows but Cmd on Mac. | |||
See GLFW_MOD_* for the list of possible values. | |||
*/ | |||
int mods; | |||
}; | |||
/** An event prototype with a Unicode character. */ | |||
struct TextBase { | |||
/** Unicode code point of the character */ | |||
int codepoint; | |||
}; | |||
/** Occurs every frame when the mouse is hovering over a Widget. | |||
Recurses. | |||
Consume this event to allow Enter and Leave to occur. | |||
*/ | |||
struct Hover : Base, PositionBase { | |||
/** Change in mouse position since the last frame. Can be zero. */ | |||
math::Vec mouseDelta; | |||
}; | |||
/** Occurs each mouse button press or release. | |||
Recurses. | |||
Consume this event to allow DoubleClick, Select, Deselect, SelectKey, SelectText, DragStart, DragEnd, DragMove, and DragDrop to occur. | |||
*/ | |||
struct Button : Base, PositionBase { | |||
/** GLFW_MOUSE_BUTTON_LEFT, GLFW_MOUSE_BUTTON_RIGHT, GLFW_MOUSE_BUTTON_MIDDLE, etc. */ | |||
int button; | |||
/** GLFW_PRESS or GLFW_RELEASE */ | |||
int action; | |||
/** GLFW_MOD_* */ | |||
int mods; | |||
}; | |||
/** Occurs when the left mouse button is pressed a second time on the same Widget within a time duration. | |||
Must consume the Button event (on left button press) to receive this event. | |||
*/ | |||
struct DoubleClick : Base { | |||
}; | |||
/** Occurs when a key is pressed, released, or repeated while the mouse is hovering a Widget. | |||
Recurses. | |||
*/ | |||
struct HoverKey : Base, PositionBase, KeyBase { | |||
}; | |||
/** Occurs when a character is typed while the mouse is hovering a Widget. | |||
Recurses. | |||
*/ | |||
struct HoverText : Base, PositionBase, TextBase { | |||
}; | |||
/** Occurs when the mouse scroll wheel is moved while the mouse is hovering a Widget. | |||
Recurses. | |||
*/ | |||
struct HoverScroll : Base, PositionBase { | |||
/** Change of scroll wheel position. */ | |||
math::Vec scrollDelta; | |||
}; | |||
/** Occurs when a Widget begins consuming the Hover event. | |||
Must consume the Hover event to receive this event. | |||
The target sets `hoveredWidget`, which allows Leave to occur. | |||
*/ | |||
struct Enter : Base { | |||
}; | |||
/** Occurs when a different Widget is entered. | |||
Must consume the Hover event (when a Widget is entered) to receive this event. | |||
*/ | |||
struct Leave : Base { | |||
}; | |||
/** Occurs when a Widget begins consuming the Button press event for the left mouse button. | |||
Must consume the Button event (on left button press) to receive this event. | |||
The target sets `selectedWidget`, which allows SelectText and SelectKey to occur. | |||
*/ | |||
struct Select : Base { | |||
}; | |||
/** Occurs when a different Widget is selected. | |||
Must consume the Button event (on left button press, when the Widget is selected) to receive this event. | |||
*/ | |||
struct Deselect : Base { | |||
}; | |||
/** Occurs when a key is pressed, released, or repeated while a Widget is selected. | |||
Must consume to prevent HoverKey from being triggered. | |||
*/ | |||
struct SelectKey : Base, KeyBase { | |||
}; | |||
/** Occurs when text is typed while a Widget is selected. | |||
Must consume to prevent HoverKey from being triggered. | |||
*/ | |||
struct SelectText : Base, TextBase { | |||
}; | |||
struct DragBase : Base { | |||
/** The mouse button held while dragging. */ | |||
int button; | |||
}; | |||
/** Occurs when a Widget begins being dragged. | |||
Must consume the Button event (on press) to receive this event. | |||
The target sets `draggedWidget`, which allows DragEnd, DragMove, DragHover, DragEnter, and DragDrop to occur. | |||
*/ | |||
struct DragStart : DragBase { | |||
}; | |||
/** Occurs when a Widget stops being dragged by releasing the mouse button. | |||
Must consume the Button event (on press, when the Widget drag begins) to receive this event. | |||
*/ | |||
struct DragEnd : DragBase { | |||
}; | |||
/** Occurs every frame on the dragged Widget. | |||
Must consume the Button event (on press, when the Widget drag begins) to receive this event. | |||
*/ | |||
struct DragMove : DragBase { | |||
/** Change in mouse position since the last frame. Can be zero. */ | |||
math::Vec mouseDelta; | |||
}; | |||
/** Occurs every frame when the mouse is hovering over a Widget while another Widget (possibly the same one) is being dragged. | |||
Recurses. | |||
Consume this event to allow DragEnter and DragLeave to occur. | |||
*/ | |||
struct DragHover : DragBase, PositionBase { | |||
/** The dragged widget */ | |||
widget::Widget* origin = NULL; | |||
/** Change in mouse position since the last frame. Can be zero. */ | |||
math::Vec mouseDelta; | |||
}; | |||
/** Occurs when the mouse enters a Widget while dragging. | |||
Must consume the DragHover event to receive this event. | |||
The target sets `draggedWidget`, which allows DragLeave to occur. | |||
*/ | |||
struct DragEnter : DragBase { | |||
/** The dragged widget */ | |||
widget::Widget* origin = NULL; | |||
}; | |||
/** Occurs when the mouse leaves a Widget while dragging. | |||
Must consume the DragHover event (when the Widget is entered) to receive this event. | |||
*/ | |||
struct DragLeave : DragBase { | |||
/** The dragged widget */ | |||
widget::Widget* origin = NULL; | |||
}; | |||
/** Occurs when the mouse button is released over a Widget while dragging. | |||
Must consume the Button event (on release) to receive this event. | |||
*/ | |||
struct DragDrop : DragBase { | |||
/** The dragged widget */ | |||
widget::Widget* origin = NULL; | |||
}; | |||
/** Occurs when a selection of files from the operating system is dropped onto a Widget. | |||
Recurses. | |||
*/ | |||
struct PathDrop : Base, PositionBase { | |||
PathDrop(const std::vector<std::string>& paths) : paths(paths) {} | |||
/** List of file paths in the dropped selection */ | |||
const std::vector<std::string>& paths; | |||
}; | |||
/** Occurs after a certain action is triggered on a Widget. | |||
The concept of an "action" is defined by the type of Widget. | |||
*/ | |||
struct Action : Base { | |||
}; | |||
/** Occurs after the value of a Widget changes. | |||
The concept of a "value" is defined by the type of Widget. | |||
*/ | |||
struct Change : Base { | |||
}; | |||
/** Occurs when the pixel buffer of this module must be refreshed. | |||
Recurses. | |||
*/ | |||
struct Dirty : Base { | |||
}; | |||
/** Occurs after a Widget's position is set by Widget::setPosition(). | |||
*/ | |||
struct Reposition : Base { | |||
}; | |||
/** Occurs after a Widget's size is set by Widget::setSize(). | |||
*/ | |||
struct Resize : Base { | |||
}; | |||
/** Occurs after a Widget is added to a parent. | |||
*/ | |||
struct Add : Base { | |||
}; | |||
/** Occurs before a Widget is removed from its parent. | |||
*/ | |||
struct Remove : Base { | |||
}; | |||
/** Occurs after a Widget is shown with Widget::show(). | |||
Recurses. | |||
*/ | |||
struct Show : Base { | |||
}; | |||
/** Occurs after a Widget is hidden with Widget::hide(). | |||
Recurses. | |||
*/ | |||
struct Hide : Base { | |||
}; | |||
struct State { | |||
widget::Widget* rootWidget = NULL; | |||
/** State widgets | |||
Don't set these directly unless you know what you're doing. Use the set*() methods instead. | |||
*/ | |||
widget::Widget* hoveredWidget = NULL; | |||
widget::Widget* draggedWidget = NULL; | |||
int dragButton = 0; | |||
widget::Widget* dragHoveredWidget = NULL; | |||
widget::Widget* selectedWidget = NULL; | |||
/** For double-clicking */ | |||
double lastClickTime = -INFINITY; | |||
widget::Widget* lastClickedWidget = NULL; | |||
std::set<int> heldKeys; | |||
widget::Widget* getRootWidget() { | |||
return rootWidget; | |||
} | |||
widget::Widget* getHoveredWidget() { | |||
return hoveredWidget; | |||
} | |||
widget::Widget* getDraggedWidget() { | |||
return draggedWidget; | |||
} | |||
widget::Widget* getDragHoveredWidget() { | |||
return dragHoveredWidget; | |||
} | |||
widget::Widget* getSelectedWidget() { | |||
return selectedWidget; | |||
} | |||
void setHovered(widget::Widget* w); | |||
void setDragged(widget::Widget* w, int button); | |||
void setDragHovered(widget::Widget* w); | |||
void setSelected(widget::Widget* w); | |||
/** Prepares a widget for deletion */ | |||
void finalizeWidget(widget::Widget* w); | |||
bool handleButton(math::Vec pos, int button, int action, int mods); | |||
bool handleHover(math::Vec pos, math::Vec mouseDelta); | |||
bool handleLeave(); | |||
bool handleScroll(math::Vec pos, math::Vec scrollDelta); | |||
bool handleText(math::Vec pos, int codepoint); | |||
bool handleKey(math::Vec pos, int key, int scancode, int action, int mods); | |||
bool handleDrop(math::Vec pos, const std::vector<std::string>& paths); | |||
bool handleDirty(); | |||
}; | |||
} // namespace event | |||
} // namespace rack |
@@ -16,6 +16,7 @@ | |||
#include <helpers.hpp> | |||
#include <componentlibrary.hpp> | |||
#include <widget/event.hpp> | |||
#include <widget/Widget.hpp> | |||
#include <widget/TransparentWidget.hpp> | |||
#include <widget/OpaqueWidget.hpp> | |||
@@ -3,7 +3,6 @@ | |||
#include <widget/OpaqueWidget.hpp> | |||
#include <Quantity.hpp> | |||
#include <context.hpp> | |||
#include <event.hpp> | |||
namespace rack { | |||
@@ -5,7 +5,7 @@ | |||
#include <math.hpp> | |||
#include <window.hpp> | |||
#include <color.hpp> | |||
#include <event.hpp> | |||
#include <widget/event.hpp> | |||
#include <weakptr.hpp> | |||
@@ -168,60 +168,333 @@ struct Widget : WeakBase { | |||
} | |||
} | |||
/** Override these event callbacks to respond to events. | |||
See event.hpp for a description of each event. | |||
using BaseEvent = widget::BaseEvent; | |||
/** An event prototype with a vector position. */ | |||
struct PositionBaseEvent { | |||
/** The pixel coordinate where the event occurred, relative to the Widget it is called on. */ | |||
math::Vec pos; | |||
}; | |||
/** Occurs every frame when the mouse is hovering over a Widget. | |||
Recurses. | |||
Consume this event to allow Enter and Leave to occur. | |||
*/ | |||
virtual void onHover(const event::Hover& e) { | |||
struct HoverEvent : BaseEvent, PositionBaseEvent { | |||
/** Change in mouse position since the last frame. Can be zero. */ | |||
math::Vec mouseDelta; | |||
}; | |||
virtual void onHover(const HoverEvent& e) { | |||
recursePositionEvent(&Widget::onHover, e); | |||
} | |||
virtual void onButton(const event::Button& e) { | |||
/** Occurs each mouse button press or release. | |||
Recurses. | |||
Consume this event to allow DoubleClick, Select, Deselect, SelectKey, SelectText, DragStart, DragEnd, DragMove, and DragDrop to occur. | |||
*/ | |||
struct ButtonEvent : BaseEvent, PositionBaseEvent { | |||
/** GLFW_MOUSE_BUTTON_LEFT, GLFW_MOUSE_BUTTON_RIGHT, GLFW_MOUSE_BUTTON_MIDDLE, etc. */ | |||
int button; | |||
/** GLFW_PRESS or GLFW_RELEASE */ | |||
int action; | |||
/** GLFW_MOD_* */ | |||
int mods; | |||
}; | |||
virtual void onButton(const ButtonEvent& e) { | |||
recursePositionEvent(&Widget::onButton, e); | |||
} | |||
virtual void onDoubleClick(const event::DoubleClick& e) {} | |||
virtual void onHoverKey(const event::HoverKey& e) { | |||
/** Occurs when the left mouse button is pressed a second time on the same Widget within a time duration. | |||
Must consume the Button event (on left button press) to receive this event. | |||
*/ | |||
struct DoubleClickEvent : BaseEvent {}; | |||
virtual void onDoubleClick(const DoubleClickEvent& e) {} | |||
/** An event prototype with a GLFW key. */ | |||
struct KeyBaseEvent { | |||
/** The key corresponding to what it would be called in its position on a QWERTY US keyboard. | |||
For example, the WASD directional keys used for first-person shooters will always be reported as "WASD", regardless if they say "ZQSD" on an AZERTY keyboard. | |||
You should usually not use these for printable characters such as "Ctrl+V" key commands. Instead, use `keyName`. | |||
You *should* use these for non-printable keys, such as Escape, arrow keys, Home, F1-12, etc. | |||
You should also use this for Enter, Tab, and Space. Although they are printable keys, they do not appear in `keyName`. | |||
See GLFW_KEY_* for the list of possible values. | |||
*/ | |||
int key; | |||
/** Platform-dependent "software" key code. | |||
This variable is only included for completion. There should be no reason for you to use this. | |||
You should instead use `key` (for non-printable characters) or `keyName` (for printable characters). | |||
Values are platform independent and can change between different keyboards or keyboard layouts on the same OS. | |||
*/ | |||
int scancode; | |||
/** String containing the lowercase key name, if it produces a printable character. | |||
This is the only variable that correctly represents the label printed on any keyboard layout, whether it's QWERTY, AZERTY, QWERTZ, Dvorak, etc. | |||
For example, if the user presses the key labeled "q" regardless of the key position, `keyName` will be "q". | |||
For non-printable characters this is an empty string. | |||
Enter, Tab, and Space do not give a `keyName`. Use `key` instead. | |||
Shift has no effect on the key name. Shift+1 results in "1", Shift+q results in "q", etc. | |||
*/ | |||
std::string keyName; | |||
/** The type of event occurring with the key. | |||
Possible values are GLFW_RELEASE, GLFW_PRESS, GLFW_REPEAT, or RACK_HELD. | |||
RACK_HELD is sent every frame while the key is held. | |||
*/ | |||
int action; | |||
/** Bitwise OR of key modifiers, such as Ctrl or Shift. | |||
Use (mods & RACK_MOD_MASK) == RACK_MOD_CTRL to check for Ctrl on Linux and Windows but Cmd on Mac. | |||
See GLFW_MOD_* for the list of possible values. | |||
*/ | |||
int mods; | |||
}; | |||
/** Occurs when a key is pressed, released, or repeated while the mouse is hovering a Widget. | |||
Recurses. | |||
*/ | |||
struct HoverKeyEvent : BaseEvent, PositionBaseEvent, KeyBaseEvent {}; | |||
virtual void onHoverKey(const HoverKeyEvent& e) { | |||
recursePositionEvent(&Widget::onHoverKey, e); | |||
} | |||
virtual void onHoverText(const event::HoverText& e) { | |||
/** An event prototype with a Unicode character. */ | |||
struct TextBaseEvent { | |||
/** Unicode code point of the character */ | |||
int codepoint; | |||
}; | |||
/** Occurs when a character is typed while the mouse is hovering a Widget. | |||
Recurses. | |||
*/ | |||
struct HoverTextEvent : BaseEvent, PositionBaseEvent, TextBaseEvent {}; | |||
virtual void onHoverText(const HoverTextEvent& e) { | |||
recursePositionEvent(&Widget::onHoverText, e); | |||
} | |||
virtual void onHoverScroll(const event::HoverScroll& e) { | |||
/** Occurs when the mouse scroll wheel is moved while the mouse is hovering a Widget. | |||
Recurses. | |||
*/ | |||
struct HoverScrollEvent : BaseEvent, PositionBaseEvent { | |||
/** Change of scroll wheel position. */ | |||
math::Vec scrollDelta; | |||
}; | |||
virtual void onHoverScroll(const HoverScrollEvent& e) { | |||
recursePositionEvent(&Widget::onHoverScroll, e); | |||
} | |||
virtual void onEnter(const event::Enter& e) {} | |||
virtual void onLeave(const event::Leave& e) {} | |||
virtual void onSelect(const event::Select& e) {} | |||
virtual void onDeselect(const event::Deselect& e) {} | |||
virtual void onSelectKey(const event::SelectKey& e) {} | |||
virtual void onSelectText(const event::SelectText& e) {} | |||
virtual void onDragStart(const event::DragStart& e) {} | |||
virtual void onDragEnd(const event::DragEnd& e) {} | |||
virtual void onDragMove(const event::DragMove& e) {} | |||
virtual void onDragHover(const event::DragHover& e) { | |||
/** Occurs when a Widget begins consuming the Hover event. | |||
Must consume the Hover event to receive this event. | |||
The target sets `hoveredWidget`, which allows Leave to occur. | |||
*/ | |||
struct EnterEvent : BaseEvent {}; | |||
virtual void onEnter(const EnterEvent& e) {} | |||
/** Occurs when a different Widget is entered. | |||
Must consume the Hover event (when a Widget is entered) to receive this event. | |||
*/ | |||
struct LeaveEvent : BaseEvent {}; | |||
virtual void onLeave(const LeaveEvent& e) {} | |||
/** Occurs when a Widget begins consuming the Button press event for the left mouse button. | |||
Must consume the Button event (on left button press) to receive this event. | |||
The target sets `selectedWidget`, which allows SelectText and SelectKey to occur. | |||
*/ | |||
struct SelectEvent : BaseEvent {}; | |||
virtual void onSelect(const SelectEvent& e) {} | |||
/** Occurs when a different Widget is selected. | |||
Must consume the Button event (on left button press, when the Widget is selected) to receive this event. | |||
*/ | |||
struct DeselectEvent : BaseEvent {}; | |||
virtual void onDeselect(const DeselectEvent& e) {} | |||
/** Occurs when a key is pressed, released, or repeated while a Widget is selected. | |||
Must consume to prevent HoverKey from being triggered. | |||
*/ | |||
struct SelectKeyEvent : BaseEvent, KeyBaseEvent {}; | |||
virtual void onSelectKey(const SelectKeyEvent& e) {} | |||
/** Occurs when text is typed while a Widget is selected. | |||
Must consume to prevent HoverKey from being triggered. | |||
*/ | |||
struct SelectTextEvent : BaseEvent, TextBaseEvent {}; | |||
virtual void onSelectText(const SelectTextEvent& e) {} | |||
struct DragBaseEvent : BaseEvent { | |||
/** The mouse button held while dragging. */ | |||
int button; | |||
}; | |||
/** Occurs when a Widget begins being dragged. | |||
Must consume the Button event (on press) to receive this event. | |||
The target sets `draggedWidget`, which allows DragEnd, DragMove, DragHover, DragEnter, and DragDrop to occur. | |||
*/ | |||
struct DragStartEvent : DragBaseEvent {}; | |||
virtual void onDragStart(const DragStartEvent& e) {} | |||
/** Occurs when a Widget stops being dragged by releasing the mouse button. | |||
Must consume the Button event (on press, when the Widget drag begins) to receive this event. | |||
*/ | |||
struct DragEndEvent : DragBaseEvent {}; | |||
virtual void onDragEnd(const DragEndEvent& e) {} | |||
/** Occurs every frame on the dragged Widget. | |||
Must consume the Button event (on press, when the Widget drag begins) to receive this event. | |||
*/ | |||
struct DragMoveEvent : DragBaseEvent { | |||
/** Change in mouse position since the last frame. Can be zero. */ | |||
math::Vec mouseDelta; | |||
}; | |||
virtual void onDragMove(const DragMoveEvent& e) {} | |||
/** Occurs every frame when the mouse is hovering over a Widget while another Widget (possibly the same one) is being dragged. | |||
Recurses. | |||
Consume this event to allow DragEnter and DragLeave to occur. | |||
*/ | |||
struct DragHoverEvent : DragBaseEvent, PositionBaseEvent { | |||
/** The dragged widget */ | |||
Widget* origin = NULL; | |||
/** Change in mouse position since the last frame. Can be zero. */ | |||
math::Vec mouseDelta; | |||
}; | |||
virtual void onDragHover(const DragHoverEvent& e) { | |||
recursePositionEvent(&Widget::onDragHover, e); | |||
} | |||
virtual void onDragEnter(const event::DragEnter& e) {} | |||
virtual void onDragLeave(const event::DragLeave& e) {} | |||
virtual void onDragDrop(const event::DragDrop& e) {} | |||
virtual void onPathDrop(const event::PathDrop& e) { | |||
/** Occurs when the mouse enters a Widget while dragging. | |||
Must consume the DragHover event to receive this event. | |||
The target sets `draggedWidget`, which allows DragLeave to occur. | |||
*/ | |||
struct DragEnterEvent : DragBaseEvent { | |||
/** The dragged widget */ | |||
Widget* origin = NULL; | |||
}; | |||
virtual void onDragEnter(const DragEnterEvent& e) {} | |||
/** Occurs when the mouse leaves a Widget while dragging. | |||
Must consume the DragHover event (when the Widget is entered) to receive this event. | |||
*/ | |||
struct DragLeaveEvent : DragBaseEvent { | |||
/** The dragged widget */ | |||
Widget* origin = NULL; | |||
}; | |||
virtual void onDragLeave(const DragLeaveEvent& e) {} | |||
/** Occurs when the mouse button is released over a Widget while dragging. | |||
Must consume the Button event (on release) to receive this event. | |||
*/ | |||
struct DragDropEvent : DragBaseEvent { | |||
/** The dragged widget */ | |||
Widget* origin = NULL; | |||
}; | |||
virtual void onDragDrop(const DragDropEvent& e) {} | |||
/** Occurs when a selection of files from the operating system is dropped onto a Widget. | |||
Recurses. | |||
*/ | |||
struct PathDropEvent : BaseEvent, PositionBaseEvent { | |||
PathDropEvent(const std::vector<std::string>& paths) : paths(paths) {} | |||
/** List of file paths in the dropped selection */ | |||
const std::vector<std::string>& paths; | |||
}; | |||
virtual void onPathDrop(const PathDropEvent& e) { | |||
recursePositionEvent(&Widget::onPathDrop, e); | |||
} | |||
virtual void onAction(const event::Action& e) {} | |||
virtual void onChange(const event::Change& e) {} | |||
virtual void onDirty(const event::Dirty& e) { | |||
/** Occurs after a certain action is triggered on a Widget. | |||
The concept of an "action" is defined by the type of Widget. | |||
*/ | |||
struct ActionEvent : BaseEvent {}; | |||
virtual void onAction(const ActionEvent& e) {} | |||
/** Occurs after the value of a Widget changes. | |||
The concept of a "value" is defined by the type of Widget. | |||
*/ | |||
struct ChangeEvent : BaseEvent {}; | |||
virtual void onChange(const ChangeEvent& e) {} | |||
/** Occurs when the pixel buffer of this module must be refreshed. | |||
Recurses. | |||
*/ | |||
struct DirtyEvent : BaseEvent {}; | |||
virtual void onDirty(const DirtyEvent& e) { | |||
recurseEvent(&Widget::onDirty, e); | |||
} | |||
virtual void onReposition(const event::Reposition& e) {} | |||
virtual void onResize(const event::Resize& e) {} | |||
virtual void onAdd(const event::Add& e) {} | |||
virtual void onRemove(const event::Remove& e) {} | |||
virtual void onShow(const event::Show& e) { | |||
/** Occurs after a Widget's position is set by Widget::setPosition(). | |||
*/ | |||
struct RepositionEvent : BaseEvent {}; | |||
virtual void onReposition(const RepositionEvent& e) {} | |||
/** Occurs after a Widget's size is set by Widget::setSize(). | |||
*/ | |||
struct ResizeEvent : BaseEvent {}; | |||
virtual void onResize(const ResizeEvent& e) {} | |||
/** Occurs after a Widget is added to a parent. | |||
*/ | |||
struct AddEvent : BaseEvent {}; | |||
virtual void onAdd(const AddEvent& e) {} | |||
/** Occurs before a Widget is removed from its parent. | |||
*/ | |||
struct RemoveEvent : BaseEvent {}; | |||
virtual void onRemove(const RemoveEvent& e) {} | |||
/** Occurs after a Widget is shown with Widget::show(). | |||
Recurses. | |||
*/ | |||
struct ShowEvent : BaseEvent {}; | |||
virtual void onShow(const ShowEvent& e) { | |||
recurseEvent(&Widget::onShow, e); | |||
} | |||
virtual void onHide(const event::Hide& e) { | |||
/** Occurs after a Widget is hidden with Widget::hide(). | |||
Recurses. | |||
*/ | |||
struct HideEvent : BaseEvent {}; | |||
virtual void onHide(const HideEvent& e) { | |||
recurseEvent(&Widget::onHide, e); | |||
} | |||
}; | |||
} // namespace widget | |||
/** Deprecated Rack v1 event namespace. | |||
Use `ExampleWidget` instead of `event::Example` in new code. | |||
*/ | |||
namespace event { | |||
using Base = widget::BaseEvent; | |||
using PositionBase = widget::Widget::PositionBaseEvent; | |||
using KeyBase = widget::Widget::KeyBaseEvent; | |||
using TextBase = widget::Widget::TextBaseEvent; | |||
using Hover = widget::Widget::HoverEvent; | |||
using Button = widget::Widget::ButtonEvent; | |||
using DoubleClick = widget::Widget::DoubleClickEvent; | |||
using HoverKey = widget::Widget::HoverKeyEvent; | |||
using HoverText = widget::Widget::HoverTextEvent; | |||
using HoverScroll = widget::Widget::HoverScrollEvent; | |||
using Enter = widget::Widget::EnterEvent; | |||
using Leave = widget::Widget::LeaveEvent; | |||
using Select = widget::Widget::SelectEvent; | |||
using Deselect = widget::Widget::DeselectEvent; | |||
using SelectKey = widget::Widget::SelectKeyEvent; | |||
using SelectText = widget::Widget::SelectTextEvent; | |||
using DragBase = widget::Widget::DragBaseEvent; | |||
using DragStart = widget::Widget::DragStartEvent; | |||
using DragEnd = widget::Widget::DragEndEvent; | |||
using DragMove = widget::Widget::DragMoveEvent; | |||
using DragHover = widget::Widget::DragHoverEvent; | |||
using DragEnter = widget::Widget::DragEnterEvent; | |||
using DragLeave = widget::Widget::DragLeaveEvent; | |||
using DragDrop = widget::Widget::DragDropEvent; | |||
using PathDrop = widget::Widget::PathDropEvent; | |||
using Action = widget::Widget::ActionEvent; | |||
using Change = widget::Widget::ChangeEvent; | |||
using Dirty = widget::Widget::DirtyEvent; | |||
using Reposition = widget::Widget::RepositionEvent; | |||
using Resize = widget::Widget::ResizeEvent; | |||
using Add = widget::Widget::AddEvent; | |||
using Remove = widget::Widget::RemoveEvent; | |||
using Show = widget::Widget::ShowEvent; | |||
using Hide = widget::Widget::HideEvent; | |||
} | |||
} // namespace rack |
@@ -0,0 +1,155 @@ | |||
#pragma once | |||
#include <vector> | |||
#include <set> | |||
#include <common.hpp> | |||
#include <math.hpp> | |||
/** Remaps Ctrl to Cmd on Mac | |||
Use this instead of GLFW_MOD_CONTROL, since Cmd should be used on Mac in place of Ctrl on Linux/Windows. | |||
*/ | |||
#if defined ARCH_MAC | |||
#define RACK_MOD_CTRL GLFW_MOD_SUPER | |||
#define RACK_MOD_CTRL_NAME "⌘" | |||
#else | |||
#define RACK_MOD_CTRL GLFW_MOD_CONTROL | |||
#define RACK_MOD_CTRL_NAME "Ctrl" | |||
#endif | |||
#define RACK_MOD_SHIFT_NAME "Shift" | |||
#define RACK_MOD_ALT_NAME "Alt" | |||
/** Filters actual mod keys from the mod flags. | |||
Use this if you don't care about GLFW_MOD_CAPS_LOCK and GLFW_MOD_NUM_LOCK. | |||
Example usage: | |||
if ((e.mod & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) ... | |||
*/ | |||
#define RACK_MOD_MASK (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SUPER) | |||
/** A key action state representing the the key is (still) being held. | |||
*/ | |||
#define RACK_HELD 3 | |||
namespace rack { | |||
namespace widget { | |||
struct Widget; | |||
/** A per-event state shared and writable by all widgets that recursively handle an event. */ | |||
struct EventContext { | |||
/** Whether the event should continue recursing to children Widgets. */ | |||
bool propagating = true; | |||
/** Whether the event has been consumed by an event handler and no more handlers should consume the event. */ | |||
bool consumed = false; | |||
/** The widget that responded to the event. */ | |||
Widget* target = NULL; | |||
}; | |||
/** Base class for all events. */ | |||
struct BaseEvent { | |||
EventContext* context = NULL; | |||
/** Prevents the event from being handled by more Widgets. | |||
*/ | |||
void stopPropagating() const { | |||
if (!context) | |||
return; | |||
context->propagating = false; | |||
} | |||
bool isPropagating() const { | |||
if (!context) | |||
return true; | |||
return context->propagating; | |||
} | |||
/** Tells the event handler that a particular Widget consumed the event. | |||
You usually want to stop propagation as well, so call consume() instead. | |||
*/ | |||
void setTarget(Widget* w) const { | |||
if (!context) | |||
return; | |||
context->target = w; | |||
} | |||
Widget* getTarget() const { | |||
if (!context) | |||
return NULL; | |||
return context->target; | |||
} | |||
/** Sets the target Widget and stops propagating. | |||
A NULL Widget may be passed to consume but not set a target. | |||
*/ | |||
void consume(Widget* w) const { | |||
if (!context) | |||
return; | |||
context->propagating = false; | |||
context->consumed = true; | |||
context->target = w; | |||
} | |||
void unconsume() const { | |||
if (!context) | |||
return; | |||
context->consumed = false; | |||
} | |||
bool isConsumed() const { | |||
if (!context) | |||
return false; | |||
return context->consumed; | |||
} | |||
}; | |||
struct EventState { | |||
Widget* rootWidget = NULL; | |||
/** State widgets | |||
Don't set these directly unless you know what you're doing. Use the set*() methods instead. | |||
*/ | |||
Widget* hoveredWidget = NULL; | |||
Widget* draggedWidget = NULL; | |||
int dragButton = 0; | |||
Widget* dragHoveredWidget = NULL; | |||
Widget* selectedWidget = NULL; | |||
/** For double-clicking */ | |||
double lastClickTime = -INFINITY; | |||
Widget* lastClickedWidget = NULL; | |||
std::set<int> heldKeys; | |||
Widget* getRootWidget() { | |||
return rootWidget; | |||
} | |||
Widget* getHoveredWidget() { | |||
return hoveredWidget; | |||
} | |||
Widget* getDraggedWidget() { | |||
return draggedWidget; | |||
} | |||
Widget* getDragHoveredWidget() { | |||
return dragHoveredWidget; | |||
} | |||
Widget* getSelectedWidget() { | |||
return selectedWidget; | |||
} | |||
void setHovered(Widget* w); | |||
void setDragged(Widget* w, int button); | |||
void setDragHovered(Widget* w); | |||
void setSelected(Widget* w); | |||
/** Prepares a widget for deletion */ | |||
void finalizeWidget(Widget* w); | |||
bool handleButton(math::Vec pos, int button, int action, int mods); | |||
bool handleHover(math::Vec pos, math::Vec mouseDelta); | |||
bool handleLeave(); | |||
bool handleScroll(math::Vec pos, math::Vec scrollDelta); | |||
bool handleText(math::Vec pos, int codepoint); | |||
bool handleKey(math::Vec pos, int key, int scancode, int action, int mods); | |||
bool handleDrop(math::Vec pos, const std::vector<std::string>& paths); | |||
bool handleDirty(); | |||
}; | |||
} // namespace widget | |||
} // namespace rack |
@@ -5,7 +5,6 @@ | |||
#include <context.hpp> | |||
#include <patch.hpp> | |||
#include <settings.hpp> | |||
#include <event.hpp> | |||
#include <engine/Engine.hpp> | |||
#include <engine/Port.hpp> | |||
@@ -1,6 +1,5 @@ | |||
#include <ui/Button.hpp> | |||
#include <context.hpp> | |||
#include <event.hpp> | |||
namespace rack { | |||
@@ -1,6 +1,5 @@ | |||
#include <ui/ChoiceButton.hpp> | |||
#include <context.hpp> | |||
#include <event.hpp> | |||
namespace rack { | |||
@@ -70,7 +70,7 @@ void MenuItem::doAction() { | |||
if (disabled) | |||
return; | |||
event::Context cAction; | |||
widget::EventContext cAction; | |||
event::Action eAction; | |||
eAction.context = &cAction; | |||
// Consume event by default, but allow action to un-consume it to prevent the menu from being removed. | |||
@@ -33,7 +33,7 @@ void ZoomWidget::setZoom(float zoom) { | |||
this->zoom = zoom; | |||
// Trigger Dirty event | |||
event::Context cDirty; | |||
widget::EventContext cDirty; | |||
event::Dirty eDirty; | |||
eDirty.context = &cDirty; | |||
Widget::onDirty(eDirty); | |||
@@ -1,42 +1,42 @@ | |||
#include <event.hpp> | |||
#include <widget/event.hpp> | |||
#include <widget/Widget.hpp> | |||
#include <context.hpp> | |||
#include <window.hpp> | |||
namespace rack { | |||
namespace event { | |||
namespace widget { | |||
void State::setHovered(widget::Widget* w) { | |||
void EventState::setHovered(widget::Widget* w) { | |||
if (w == hoveredWidget) | |||
return; | |||
if (hoveredWidget) { | |||
// Trigger Leave event | |||
Leave eLeave; | |||
// Trigger LeaveEvent | |||
Widget::LeaveEvent eLeave; | |||
hoveredWidget->onLeave(eLeave); | |||
hoveredWidget = NULL; | |||
} | |||
if (w) { | |||
// Trigger Enter event | |||
Context cEnter; | |||
// Trigger EnterEvent | |||
EventContext cEnter; | |||
cEnter.target = w; | |||
Enter eEnter; | |||
Widget::EnterEvent eEnter; | |||
eEnter.context = &cEnter; | |||
w->onEnter(eEnter); | |||
hoveredWidget = cEnter.target; | |||
} | |||
} | |||
void State::setDragged(widget::Widget* w, int button) { | |||
void EventState::setDragged(widget::Widget* w, int button) { | |||
if (w == draggedWidget) | |||
return; | |||
if (draggedWidget) { | |||
// Trigger DragEnd event | |||
DragEnd eDragEnd; | |||
// Trigger DragEndEvent | |||
Widget::DragEndEvent eDragEnd; | |||
eDragEnd.button = dragButton; | |||
draggedWidget->onDragEnd(eDragEnd); | |||
draggedWidget = NULL; | |||
@@ -45,10 +45,10 @@ void State::setDragged(widget::Widget* w, int button) { | |||
dragButton = button; | |||
if (w) { | |||
// Trigger DragStart event | |||
Context cDragStart; | |||
// Trigger DragStartEvent | |||
EventContext cDragStart; | |||
cDragStart.target = w; | |||
DragStart eDragStart; | |||
Widget::DragStartEvent eDragStart; | |||
eDragStart.context = &cDragStart; | |||
eDragStart.button = dragButton; | |||
w->onDragStart(eDragStart); | |||
@@ -56,13 +56,13 @@ void State::setDragged(widget::Widget* w, int button) { | |||
} | |||
} | |||
void State::setDragHovered(widget::Widget* w) { | |||
void EventState::setDragHovered(widget::Widget* w) { | |||
if (w == dragHoveredWidget) | |||
return; | |||
if (dragHoveredWidget) { | |||
// Trigger DragLeave event | |||
DragLeave eDragLeave; | |||
// Trigger DragLeaveEvent | |||
Widget::DragLeaveEvent eDragLeave; | |||
eDragLeave.button = dragButton; | |||
eDragLeave.origin = draggedWidget; | |||
dragHoveredWidget->onDragLeave(eDragLeave); | |||
@@ -70,10 +70,10 @@ void State::setDragHovered(widget::Widget* w) { | |||
} | |||
if (w) { | |||
// Trigger DragEnter event | |||
Context cDragEnter; | |||
// Trigger DragEnterEvent | |||
EventContext cDragEnter; | |||
cDragEnter.target = w; | |||
DragEnter eDragEnter; | |||
Widget::DragEnterEvent eDragEnter; | |||
eDragEnter.context = &cDragEnter; | |||
eDragEnter.button = dragButton; | |||
eDragEnter.origin = draggedWidget; | |||
@@ -82,29 +82,29 @@ void State::setDragHovered(widget::Widget* w) { | |||
} | |||
} | |||
void State::setSelected(widget::Widget* w) { | |||
void EventState::setSelected(widget::Widget* w) { | |||
if (w == selectedWidget) | |||
return; | |||
if (selectedWidget) { | |||
// Trigger Deselect event | |||
Deselect eDeselect; | |||
// Trigger DeselectEvent | |||
Widget::DeselectEvent eDeselect; | |||
selectedWidget->onDeselect(eDeselect); | |||
selectedWidget = NULL; | |||
} | |||
if (w) { | |||
// Trigger Select event | |||
Context cSelect; | |||
// Trigger SelectEvent | |||
EventContext cSelect; | |||
cSelect.target = w; | |||
Select eSelect; | |||
Widget::SelectEvent eSelect; | |||
eSelect.context = &cSelect; | |||
w->onSelect(eSelect); | |||
selectedWidget = cSelect.target; | |||
} | |||
} | |||
void State::finalizeWidget(widget::Widget* w) { | |||
void EventState::finalizeWidget(widget::Widget* w) { | |||
if (hoveredWidget == w) | |||
setHovered(NULL); | |||
if (draggedWidget == w) | |||
@@ -117,14 +117,14 @@ void State::finalizeWidget(widget::Widget* w) { | |||
lastClickedWidget = NULL; | |||
} | |||
bool State::handleButton(math::Vec pos, int button, int action, int mods) { | |||
bool EventState::handleButton(math::Vec pos, int button, int action, int mods) { | |||
bool cursorLocked = APP->window->isCursorLocked(); | |||
widget::Widget* clickedWidget = NULL; | |||
if (!cursorLocked) { | |||
// Trigger Button event | |||
Context cButton; | |||
Button eButton; | |||
// Trigger ButtonEvent | |||
EventContext cButton; | |||
Widget::ButtonEvent eButton; | |||
eButton.context = &cButton; | |||
eButton.pos = pos; | |||
eButton.button = button; | |||
@@ -142,8 +142,8 @@ bool State::handleButton(math::Vec pos, int button, int action, int mods) { | |||
setDragHovered(NULL); | |||
if (clickedWidget && draggedWidget) { | |||
// Trigger DragDrop event | |||
DragDrop eDragDrop; | |||
// Trigger DragDropEvent | |||
Widget::DragDropEvent eDragDrop; | |||
eDragDrop.button = dragButton; | |||
eDragDrop.origin = draggedWidget; | |||
clickedWidget->onDragDrop(eDragDrop); | |||
@@ -163,8 +163,8 @@ bool State::handleButton(math::Vec pos, int button, int action, int mods) { | |||
if (clickedWidget | |||
&& clickTime - lastClickTime <= doubleClickDuration | |||
&& lastClickedWidget == clickedWidget) { | |||
// Trigger DoubleClick event | |||
DoubleClick eDoubleClick; | |||
// Trigger DoubleClickEvent | |||
Widget::DoubleClickEvent eDoubleClick; | |||
clickedWidget->onDoubleClick(eDoubleClick); | |||
// Reset double click | |||
lastClickTime = -INFINITY; | |||
@@ -180,7 +180,7 @@ bool State::handleButton(math::Vec pos, int button, int action, int mods) { | |||
return !!clickedWidget; | |||
} | |||
bool State::handleHover(math::Vec pos, math::Vec mouseDelta) { | |||
bool EventState::handleHover(math::Vec pos, math::Vec mouseDelta) { | |||
bool cursorLocked = APP->window->isCursorLocked(); | |||
// Fake a key RACK_HELD event for each held key | |||
@@ -195,9 +195,9 @@ bool State::handleHover(math::Vec pos, math::Vec mouseDelta) { | |||
if (draggedWidget) { | |||
bool dragHovered = false; | |||
if (!cursorLocked) { | |||
// Trigger DragHover event | |||
Context cDragHover; | |||
DragHover eDragHover; | |||
// Trigger DragHoverEvent | |||
EventContext cDragHover; | |||
Widget::DragHoverEvent eDragHover; | |||
eDragHover.context = &cDragHover; | |||
eDragHover.button = dragButton; | |||
eDragHover.pos = pos; | |||
@@ -206,13 +206,13 @@ bool State::handleHover(math::Vec pos, math::Vec mouseDelta) { | |||
rootWidget->onDragHover(eDragHover); | |||
setDragHovered(cDragHover.target); | |||
// If consumed, don't continue after DragMove so Hover is not triggered. | |||
// If consumed, don't continue after DragMoveEvent so HoverEvent is not triggered. | |||
if (cDragHover.target) | |||
dragHovered = true; | |||
} | |||
// Trigger DragMove event | |||
DragMove eDragMove; | |||
// Trigger DragMoveEvent | |||
Widget::DragMoveEvent eDragMove; | |||
eDragMove.button = dragButton; | |||
eDragMove.mouseDelta = mouseDelta; | |||
draggedWidget->onDragMove(eDragMove); | |||
@@ -221,9 +221,9 @@ bool State::handleHover(math::Vec pos, math::Vec mouseDelta) { | |||
} | |||
if (!cursorLocked) { | |||
// Trigger Hover event | |||
Context cHover; | |||
Hover eHover; | |||
// Trigger HoverEvent | |||
EventContext cHover; | |||
Widget::HoverEvent eHover; | |||
eHover.context = &cHover; | |||
eHover.pos = pos; | |||
eHover.mouseDelta = mouseDelta; | |||
@@ -236,7 +236,7 @@ bool State::handleHover(math::Vec pos, math::Vec mouseDelta) { | |||
return false; | |||
} | |||
bool State::handleLeave() { | |||
bool EventState::handleLeave() { | |||
heldKeys.clear(); | |||
// When leaving the window, don't un-hover widgets because the mouse might be dragging. | |||
// setDragHovered(NULL); | |||
@@ -244,10 +244,10 @@ bool State::handleLeave() { | |||
return true; | |||
} | |||
bool State::handleScroll(math::Vec pos, math::Vec scrollDelta) { | |||
// Trigger HoverScroll event | |||
Context cHoverScroll; | |||
HoverScroll eHoverScroll; | |||
bool EventState::handleScroll(math::Vec pos, math::Vec scrollDelta) { | |||
// Trigger HoverScrollEvent | |||
EventContext cHoverScroll; | |||
Widget::HoverScrollEvent eHoverScroll; | |||
eHoverScroll.context = &cHoverScroll; | |||
eHoverScroll.pos = pos; | |||
eHoverScroll.scrollDelta = scrollDelta; | |||
@@ -256,10 +256,10 @@ bool State::handleScroll(math::Vec pos, math::Vec scrollDelta) { | |||
return !!cHoverScroll.target; | |||
} | |||
bool State::handleDrop(math::Vec pos, const std::vector<std::string>& paths) { | |||
// Trigger PathDrop event | |||
Context cPathDrop; | |||
PathDrop ePathDrop(paths); | |||
bool EventState::handleDrop(math::Vec pos, const std::vector<std::string>& paths) { | |||
// Trigger PathDropEvent | |||
EventContext cPathDrop; | |||
Widget::PathDropEvent ePathDrop(paths); | |||
ePathDrop.context = &cPathDrop; | |||
ePathDrop.pos = pos; | |||
rootWidget->onPathDrop(ePathDrop); | |||
@@ -267,11 +267,11 @@ bool State::handleDrop(math::Vec pos, const std::vector<std::string>& paths) { | |||
return !!cPathDrop.target; | |||
} | |||
bool State::handleText(math::Vec pos, int codepoint) { | |||
bool EventState::handleText(math::Vec pos, int codepoint) { | |||
if (selectedWidget) { | |||
// Trigger SelectText event | |||
Context cSelectText; | |||
SelectText eSelectText; | |||
// Trigger SelectTextEvent | |||
EventContext cSelectText; | |||
Widget::SelectTextEvent eSelectText; | |||
eSelectText.context = &cSelectText; | |||
eSelectText.codepoint = codepoint; | |||
selectedWidget->onSelectText(eSelectText); | |||
@@ -279,9 +279,9 @@ bool State::handleText(math::Vec pos, int codepoint) { | |||
return true; | |||
} | |||
// Trigger HoverText event | |||
Context cHoverText; | |||
HoverText eHoverText; | |||
// Trigger HoverText | |||
EventContext cHoverText; | |||
Widget::HoverTextEvent eHoverText; | |||
eHoverText.context = &cHoverText; | |||
eHoverText.pos = pos; | |||
eHoverText.codepoint = codepoint; | |||
@@ -290,7 +290,7 @@ bool State::handleText(math::Vec pos, int codepoint) { | |||
return !!cHoverText.target; | |||
} | |||
bool State::handleKey(math::Vec pos, int key, int scancode, int action, int mods) { | |||
bool EventState::handleKey(math::Vec pos, int key, int scancode, int action, int mods) { | |||
// Update heldKey state | |||
if (action == GLFW_PRESS) { | |||
heldKeys.insert(key); | |||
@@ -302,9 +302,9 @@ bool State::handleKey(math::Vec pos, int key, int scancode, int action, int mods | |||
} | |||
if (selectedWidget) { | |||
// Trigger SelectKey event | |||
Context cSelectKey; | |||
SelectKey eSelectKey; | |||
// Trigger SelectKeyEvent | |||
EventContext cSelectKey; | |||
Widget::SelectKeyEvent eSelectKey; | |||
eSelectKey.context = &cSelectKey; | |||
eSelectKey.key = key; | |||
eSelectKey.scancode = scancode; | |||
@@ -318,9 +318,9 @@ bool State::handleKey(math::Vec pos, int key, int scancode, int action, int mods | |||
return true; | |||
} | |||
// Trigger HoverKey event | |||
Context cHoverKey; | |||
HoverKey eHoverKey; | |||
// Trigger HoverKeyEvent | |||
EventContext cHoverKey; | |||
Widget::HoverKeyEvent eHoverKey; | |||
eHoverKey.context = &cHoverKey; | |||
eHoverKey.pos = pos; | |||
eHoverKey.key = key; | |||
@@ -334,15 +334,15 @@ bool State::handleKey(math::Vec pos, int key, int scancode, int action, int mods | |||
return !!cHoverKey.target; | |||
} | |||
bool State::handleDirty() { | |||
// Trigger Dirty event | |||
Context cDirty; | |||
Dirty eDirty; | |||
bool EventState::handleDirty() { | |||
// Trigger DirtyEvent | |||
EventContext cDirty; | |||
Widget::DirtyEvent eDirty; | |||
eDirty.context = &cDirty; | |||
rootWidget->onDirty(eDirty); | |||
return true; | |||
} | |||
} // namespace event | |||
} // namespace widget | |||
} // namespace rack |
@@ -12,10 +12,10 @@ | |||
#include <window.hpp> | |||
#include <asset.hpp> | |||
#include <widget/Widget.hpp> | |||
#include <app/Scene.hpp> | |||
#include <keyboard.hpp> | |||
#include <gamepad.hpp> | |||
#include <event.hpp> | |||
#include <context.hpp> | |||
#include <patch.hpp> | |||
#include <settings.hpp> | |||
@@ -183,7 +183,7 @@ int main(int argc, char* argv[]) { | |||
contextSet(new Context); | |||
APP->engine = new engine::Engine; | |||
if (!settings::headless) { | |||
APP->event = new event::State; | |||
APP->event = new widget::EventState; | |||
APP->history = new history::State; | |||
APP->window = new Window; | |||
APP->scene = new app::Scene; | |||