Skip to content

Commit

Permalink
[SUTK] mouse event callbacks should be invoked only in the local coor…
Browse files Browse the repository at this point in the history
…dinates of a container
  • Loading branch information
ravi688 committed Aug 8, 2024
1 parent 5f4c6e9 commit f929808
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 13 deletions.
2 changes: 2 additions & 0 deletions sutk/include/sutk/Container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ namespace SUTK
Rect2Df getRect() const { return m_rect; }
Vec2Df getPosition() const noexcept { return m_rect.getPosition(); }
Vec2Df getSize() const noexcept { return m_rect.getSize(); }
bool contains(Vec2Df localCoords) const noexcept { return m_rect.contains(localCoords); }
bool containsGlobalCoords(Vec2Df globalCoords) const noexcept;
// rect setters
virtual void setRect(Rect2Df rect) { m_rect = rect; onResize(rect, true, true); }
void setPosition(Vec2Df pos) { m_rect.setPosition(pos); onResize(m_rect, true, false); }
Expand Down
48 changes: 42 additions & 6 deletions sutk/include/sutk/InputEventHandlerObject.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <sutk/defines.hpp> // for SUTK_API
#include <sutk/IInputDriver.hpp> // for SUTK::MouseButton and SUTK::KeyEvent
#include <sutk/Container.hpp> // for SUTK::Container

namespace SUTK
{
Expand Down Expand Up @@ -48,6 +49,27 @@ namespace SUTK
}
};

template<typename InputEventType>
class TInputEventHandlerContainerObject : public TInputEventHandlerObject<InputEventType>
{
private:
Container* m_container;

protected:
TInputEventHandlerContainerObject(InputEventType& event) noexcept : TInputEventHandlerObject<InputEventType>(event), m_container(NULL) { }
TInputEventHandlerContainerObject(InputEventType& event, Container* container) noexcept : TInputEventHandlerObject<InputEventType>(event), m_container(container) { }
bool isInside(Vec2Df point) const noexcept
{
return (m_container != NULL) ? m_container->containsGlobalCoords(point) : true;
}
Container* getContainer() noexcept { return m_container; }
};

// The onMouseEnter and onMouseExit are called only for the render window's entire rect
// Therefore, this class is not derived from TInputEventHandlerContainerObject
// If you want to get callbacks on mouse enter and exit across the boundaries of a specific Container
// then derive your class from MouseMoveHandlerObject and call at least once the enableMouseEnter and enableMouseExit with 'true' values
// to enable the callbacks.
class MouseEnterExitHandlerObject : public TInputEventHandlerObject<IInputDriver::OnMouseEnterExitEvent>
{
protected:
Expand All @@ -60,34 +82,48 @@ namespace SUTK
virtual ~MouseEnterExitHandlerObject() noexcept = default;
};

class MouseMoveHandlerObject : public TInputEventHandlerObject<IInputDriver::OnMouseMoveEvent>
#define MOUSE_INPUT_HANDLER_CTOR_DECLARE(className)\
className(UIDriver& driver) noexcept : className(driver, NULL) { }\
className(UIDriver& driver, Container* container) noexcept;\

class MouseMoveHandlerObject : public TInputEventHandlerContainerObject<IInputDriver::OnMouseMoveEvent>
{
private:
bool m_isMouseEnterEnabled;
bool m_isMouseExitEnabled;
bool m_isInside;
protected:
virtual void onMouseMove(Vec2Df position) = 0;

MouseMoveHandlerObject(UIDriver& driver) noexcept;
MOUSE_INPUT_HANDLER_CTOR_DECLARE(MouseMoveHandlerObject)

virtual void onMouseEnter() noexcept { }
virtual void onMouseExit() noexcept { }

void enableMouseEnter(bool isEnable) noexcept { m_isMouseEnterEnabled = isEnable; }
void enableMouseExit(bool isEnable) noexcept { m_isMouseExitEnabled = isEnable; }

public:
virtual ~MouseMoveHandlerObject() noexcept = default;
};

class MouseClickHandlerObject : public TInputEventHandlerObject<IInputDriver::OnMouseButtonEvent>
class MouseClickHandlerObject : public TInputEventHandlerContainerObject<IInputDriver::OnMouseButtonEvent>
{
protected:
virtual void onMouseClick(MouseButton button, KeyEvent action) = 0;

MouseClickHandlerObject(UIDriver& driver) noexcept;
MOUSE_INPUT_HANDLER_CTOR_DECLARE(MouseClickHandlerObject)

public:
virtual ~MouseClickHandlerObject() noexcept = default;
};

class MouseScrollHandlerObject : public TInputEventHandlerObject<IInputDriver::OnMouseScrollEvent>
class MouseScrollHandlerObject : public TInputEventHandlerContainerObject<IInputDriver::OnMouseScrollEvent>
{
protected:
virtual void onMouseScroll(Vec2Df scrollDelta) = 0;

MouseScrollHandlerObject(UIDriver& driver) noexcept;
MOUSE_INPUT_HANDLER_CTOR_DECLARE(MouseScrollHandlerObject)

public:
virtual ~MouseScrollHandlerObject() noexcept = default;
Expand Down
2 changes: 1 addition & 1 deletion sutk/include/sutk/defines.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ namespace SUTK
height += value;
}

bool contains(Vec2D<T> point) noexcept
bool contains(Vec2D<T> point) const noexcept
{
auto tl = getTopLeft();
auto br = getBottomRight();
Expand Down
5 changes: 5 additions & 0 deletions sutk/source/Container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ namespace SUTK
}
}

bool Container::containsGlobalCoords(Vec2Df globalCoords) const noexcept
{
return contains(getScreenCoordsToLocalCoords(globalCoords));
}

Vec2Df Container::getScreenCoordsToLocalCoords(Vec2Df screenCoords) const
{
return screenCoords - getLocalCoordsToScreenCoords({ 0u, 0u });
Expand Down
37 changes: 31 additions & 6 deletions sutk/source/InputEventHandlerObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,54 @@ namespace SUTK
setSubscriptionID(id);
}

MouseMoveHandlerObject::MouseMoveHandlerObject(UIDriver& driver) noexcept : TInputEventHandlerObject<IInputDriver::OnMouseMoveEvent>(driver.getInputDriver().getOnCursorMoveEvent())
MouseMoveHandlerObject::MouseMoveHandlerObject(UIDriver& driver, Container* container) noexcept : TInputEventHandlerContainerObject<IInputDriver::OnMouseMoveEvent>(driver.getInputDriver().getOnCursorMoveEvent(), container),
m_isMouseEnterEnabled(false),
m_isMouseExitEnabled(false),
m_isInside(false)
{
IInputDriver::OnMouseMoveEvent::SubscriptionID id = getEvent().subscribe([this](IInputDriver* inputDriver, SUTK::Vec2Df position)
{
onMouseMove(position);
if((!m_isInside) && isInside(position))
{
m_isInside = true;
if(m_isMouseEnterEnabled)
onMouseEnter();
}
else if(m_isInside && (!isInside(position)))
{
m_isInside = false;
if(m_isMouseExitEnabled)
onMouseExit();
}

if(m_isInside)
{
// convert global coordinates to the local coordinates of the container 'container'
Container* container = getContainer();
if(container != NULL)
position = container->getScreenCoordsToLocalCoords(position);
onMouseMove(position);
}
});
setSubscriptionID(id);
}

MouseClickHandlerObject::MouseClickHandlerObject(UIDriver& driver) noexcept : TInputEventHandlerObject<IInputDriver::OnMouseButtonEvent>(driver.getInputDriver().getOnMouseButtonEvent())
MouseClickHandlerObject::MouseClickHandlerObject(UIDriver& driver, Container* container) noexcept : TInputEventHandlerContainerObject<IInputDriver::OnMouseButtonEvent>(driver.getInputDriver().getOnMouseButtonEvent(), container)
{
IInputDriver::OnMouseButtonEvent::SubscriptionID id = getEvent().subscribe([this](IInputDriver* inputDriver, MouseButton button, KeyEvent event)
{
onMouseClick(button, event);
if(isInside(inputDriver->getMousePosition()))
onMouseClick(button, event);
});
setSubscriptionID(id);
}

MouseScrollHandlerObject::MouseScrollHandlerObject(UIDriver& driver) noexcept : TInputEventHandlerObject<IInputDriver::OnMouseScrollEvent>(driver.getInputDriver().getOnScrollEvent())
MouseScrollHandlerObject::MouseScrollHandlerObject(UIDriver& driver, Container* container) noexcept : TInputEventHandlerContainerObject<IInputDriver::OnMouseScrollEvent>(driver.getInputDriver().getOnScrollEvent(), container)
{
IInputDriver::OnMouseScrollEvent::SubscriptionID id = getEvent().subscribe([this](IInputDriver* inputDriver, Vec2Df scrollDelta)
{
onMouseScroll(scrollDelta);
if(isInside(inputDriver->getMousePosition()))
onMouseScroll(scrollDelta);
});
setSubscriptionID(id);
}
Expand Down

0 comments on commit f929808

Please sign in to comment.