Browse Source

Plug-in all pugl/dpf events except SpecialEvent

Signed-off-by: falkTX <falktx@falktx.com>
pull/272/head
falkTX 4 years ago
parent
commit
feeb29de55
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
8 changed files with 344 additions and 194 deletions
  1. +15
    -0
      dgl/Base.hpp
  2. +6
    -3
      dgl/Events.hpp
  3. +75
    -3
      dgl/src/TopLevelWidgetPrivateData.cpp
  4. +6
    -1
      dgl/src/TopLevelWidgetPrivateData.hpp
  5. +116
    -4
      dgl/src/WidgetPrivateData.cpp
  6. +7
    -1
      dgl/src/WidgetPrivateData.hpp
  7. +114
    -2
      dgl/src/WindowPrivateData.cpp
  8. +5
    -180
      dgl/src/WindowPrivateData.hpp

+ 15
- 0
dgl/Base.hpp View File

@@ -130,6 +130,21 @@ enum CrossingMode {
kCrossingUngrab ///< Crossing due to a grab release
};

/**
Scroll direction.

Describes the direction of a scroll event along with whether the scroll is a "smooth" scroll.
The discrete directions are for devices like mouse wheels with constrained axes,
while a smooth scroll is for those with arbitrary scroll direction freedom, like some touchpads.
*/
enum ScrollDirection {
kScrollUp, ///< Scroll up
kScrollDown, ///< Scroll down
kScrollLeft, ///< Scroll left
kScrollRight, ///< Scroll right
kScrollSmooth ///< Smooth scroll in any direction
};

// --------------------------------------------------------------------------------------------------------------------
// Base DGL classes



+ 6
- 3
dgl/Events.hpp View File

@@ -170,19 +170,22 @@ namespace Events
Some systems and devices support finer resolution and/or higher values for fast scrolls,
so programs should handle any value gracefully.

@a pos The widget-relative coordinates of the pointer.
@a delta The scroll distance.
@a pos The widget-relative coordinates of the pointer.
@a delta The scroll distance.
@a direction The direction of the scroll or "smooth".
@see onScroll
*/
struct ScrollEvent : BaseEvent {
Point<double> pos;
Point<double> delta;
ScrollDirection direction;

/** Constuctor */
ScrollEvent() noexcept
: BaseEvent(),
pos(0.0, 0.0),
delta(0.0, 0.0) {}
delta(0.0, 0.0),
direction(kScrollSmooth) {}
};

/**


+ 75
- 3
dgl/src/TopLevelWidgetPrivateData.cpp View File

@@ -37,7 +37,37 @@ TopLevelWidget::PrivateData::~PrivateData()
window.pData->topLevelWidget = nullptr;
}

void TopLevelWidget::PrivateData::mouseEvent(const Events::MouseEvent& ev)
bool TopLevelWidget::PrivateData::keyboardEvent(const Events::KeyboardEvent& ev)
{
// give top-level widget chance to catch this event first
if (self->onKeyboard(ev))
return true;

// propagate event to all subwidgets recursively
return selfw->pData->giveKeyboardEventForSubWidgets(ev);
}

bool TopLevelWidget::PrivateData::specialEvent(const Events::SpecialEvent& ev)
{
// give top-level widget chance to catch this event first
if (self->onSpecial(ev))
return true;

// propagate event to all subwidgets recursively
return selfw->pData->giveSpecialEventForSubWidgets(ev);
}

bool TopLevelWidget::PrivateData::characterInputEvent(const Events::CharacterInputEvent& ev)
{
// give top-level widget chance to catch this event first
if (self->onCharacterInput(ev))
return true;

// propagate event to all subwidgets recursively
return selfw->pData->giveCharacterInputEventForSubWidgets(ev);
}

bool TopLevelWidget::PrivateData::mouseEvent(const Events::MouseEvent& ev)
{
Events::MouseEvent rev = ev;

@@ -51,10 +81,52 @@ void TopLevelWidget::PrivateData::mouseEvent(const Events::MouseEvent& ev)

// give top-level widget chance to catch this event first
if (self->onMouse(ev))
return;
return true;

// propagate event to all subwidgets recursively
return selfw->pData->giveMouseEventForSubWidgets(rev);
}

bool TopLevelWidget::PrivateData::motionEvent(const Events::MotionEvent& ev)
{
Events::MotionEvent rev = ev;

if (window.pData->autoScaling)
{
const double autoScaleFactor = window.pData->autoScaleFactor;

rev.pos.setX(ev.pos.getX() / autoScaleFactor);
rev.pos.setY(ev.pos.getY() / autoScaleFactor);
}

// give top-level widget chance to catch this event first
if (self->onMotion(ev))
return true;

// propagate event to all subwidgets recursively
return selfw->pData->giveMotionEventForSubWidgets(rev);
}

bool TopLevelWidget::PrivateData::scrollEvent(const Events::ScrollEvent& ev)
{
Events::ScrollEvent rev = ev;

if (window.pData->autoScaling)
{
const double autoScaleFactor = window.pData->autoScaleFactor;

rev.pos.setX(ev.pos.getX() / autoScaleFactor);
rev.pos.setY(ev.pos.getY() / autoScaleFactor);
rev.delta.setX(ev.delta.getX() / autoScaleFactor);
rev.delta.setY(ev.delta.getY() / autoScaleFactor);
}

// give top-level widget chance to catch this event first
if (self->onScroll(ev))
return true;

// propagate event to all subwidgets recursively
selfw->pData->giveMouseEventForSubWidgets(rev);
return selfw->pData->giveScrollEventForSubWidgets(rev);
}

void TopLevelWidget::PrivateData::fallbackOnResize()


+ 6
- 1
dgl/src/TopLevelWidgetPrivateData.hpp View File

@@ -33,7 +33,12 @@ struct TopLevelWidget::PrivateData {
explicit PrivateData(TopLevelWidget* const s, Window& w);
~PrivateData();
void display();
void mouseEvent(const Events::MouseEvent& ev);
bool keyboardEvent(const Events::KeyboardEvent& ev);
bool specialEvent(const Events::SpecialEvent& ev);
bool characterInputEvent(const Events::CharacterInputEvent& ev);
bool mouseEvent(const Events::MouseEvent& ev);
bool motionEvent(const Events::MotionEvent& ev);
bool scrollEvent(const Events::ScrollEvent& ev);
void fallbackOnResize();

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)


+ 116
- 4
dgl/src/WidgetPrivateData.cpp View File

@@ -67,12 +67,68 @@ void Widget::PrivateData::displaySubWidgets(const uint width, const uint height,
}
}

void Widget::PrivateData::giveMouseEventForSubWidgets(Events::MouseEvent& ev)
// -----------------------------------------------------------------------

bool Widget::PrivateData::giveKeyboardEventForSubWidgets(const Events::KeyboardEvent& ev)
{
if (! visible)
return;
return false;
if (subWidgets.size() == 0)
return;
return false;

FOR_EACH_SUBWIDGET_INV(rit)
{
SubWidget* const widget(*rit);

if (widget->isVisible() && widget->onKeyboard(ev))
return true;
}

return false;
}

bool Widget::PrivateData::giveSpecialEventForSubWidgets(const Events::SpecialEvent& ev)
{
if (! visible)
return false;
if (subWidgets.size() == 0)
return false;

FOR_EACH_SUBWIDGET_INV(rit)
{
SubWidget* const widget(*rit);

if (widget->isVisible() && widget->onSpecial(ev))
return true;
}

return false;
}

bool Widget::PrivateData::giveCharacterInputEventForSubWidgets(const Events::CharacterInputEvent& ev)
{
if (! visible)
return false;
if (subWidgets.size() == 0)
return false;

FOR_EACH_SUBWIDGET_INV(rit)
{
SubWidget* const widget(*rit);

if (widget->isVisible() && widget->onCharacterInput(ev))
return true;
}

return false;
}

bool Widget::PrivateData::giveMouseEventForSubWidgets(Events::MouseEvent& ev)
{
if (! visible)
return false;
if (subWidgets.size() == 0)
return false;

const double x = ev.pos.getX();
const double y = ev.pos.getY();
@@ -88,8 +144,64 @@ void Widget::PrivateData::giveMouseEventForSubWidgets(Events::MouseEvent& ev)
y - widget->getAbsoluteY());

if (widget->onMouse(ev))
return;
return true;
}

return false;
}

bool Widget::PrivateData::giveMotionEventForSubWidgets(Events::MotionEvent& ev)
{
if (! visible)
return false;
if (subWidgets.size() == 0)
return false;

const double x = ev.pos.getX();
const double y = ev.pos.getY();

FOR_EACH_SUBWIDGET_INV(rit)
{
SubWidget* const widget(*rit);

if (! widget->isVisible())
continue;

ev.pos = Point<double>(x - widget->getAbsoluteX(),
y - widget->getAbsoluteY());

if (widget->onMotion(ev))
return true;
}

return false;
}

bool Widget::PrivateData::giveScrollEventForSubWidgets(Events::ScrollEvent& ev)
{
if (! visible)
return false;
if (subWidgets.size() == 0)
return false;

const double x = ev.pos.getX();
const double y = ev.pos.getY();

FOR_EACH_SUBWIDGET_INV(rit)
{
SubWidget* const widget(*rit);

if (! widget->isVisible())
continue;

ev.pos = Point<double>(x - widget->getAbsoluteX(),
y - widget->getAbsoluteY());

if (widget->onScroll(ev))
return true;
}

return false;
}

// -----------------------------------------------------------------------


+ 7
- 1
dgl/src/WidgetPrivateData.hpp View File

@@ -42,7 +42,13 @@ struct Widget::PrivateData {
~PrivateData();

void displaySubWidgets(uint width, uint height, double autoScaleFactor);
void giveMouseEventForSubWidgets(Events::MouseEvent& ev);

bool giveKeyboardEventForSubWidgets(const Events::KeyboardEvent& ev);
bool giveSpecialEventForSubWidgets(const Events::SpecialEvent& ev);
bool giveCharacterInputEventForSubWidgets(const Events::CharacterInputEvent& ev);
bool giveMouseEventForSubWidgets(Events::MouseEvent& ev);
bool giveMotionEventForSubWidgets(Events::MotionEvent& ev);
bool giveScrollEventForSubWidgets(Events::ScrollEvent& ev);

static TopLevelWidget* findTopLevelWidget(Widget* const w);



+ 114
- 2
dgl/src/WindowPrivateData.cpp View File

@@ -384,9 +384,48 @@ void Window::PrivateData::onPuglClose()
close();
}

void Window::PrivateData::onPuglKey(const Events::KeyboardEvent& ev)
{
DGL_DBGp("onPuglKey : %i %u %u\n", ev.press, ev.key, ev.keycode);

// if (fModal.childFocus != nullptr)
// return fModal.childFocus->focus();

#ifndef DPF_TEST_WINDOW_CPP
if (topLevelWidget != nullptr)
topLevelWidget->pData->keyboardEvent(ev);
#endif
}

void Window::PrivateData::onPuglSpecial(const Events::SpecialEvent& ev)
{
DGL_DBGp("onPuglSpecial : %i %u\n", ev.press, ev.key);

// if (fModal.childFocus != nullptr)
// return fModal.childFocus->focus();

#ifndef DPF_TEST_WINDOW_CPP
if (topLevelWidget != nullptr)
topLevelWidget->pData->specialEvent(ev);
#endif
}

void Window::PrivateData::onPuglText(const Events::CharacterInputEvent& ev)
{
DGL_DBGp("onPuglText : %u %u %s\n", ev.keycode, ev.character, ev.string);

// if (fModal.childFocus != nullptr)
// return fModal.childFocus->focus();

#ifndef DPF_TEST_WINDOW_CPP
if (topLevelWidget != nullptr)
topLevelWidget->pData->characterInputEvent(ev);
#endif
}

void Window::PrivateData::onPuglMouse(const Events::MouseEvent& ev)
{
DGL_DBGp("PUGL: onMouse : %i %i %f %f\n", ev.button, ev.press, ev.pos.getX(), ev.pos.getY());
DGL_DBGp("onPuglMouse : %i %i %f %f\n", ev.button, ev.press, ev.pos.getX(), ev.pos.getY());

// if (fModal.childFocus != nullptr)
// return fModal.childFocus->focus();
@@ -397,6 +436,32 @@ void Window::PrivateData::onPuglMouse(const Events::MouseEvent& ev)
#endif
}

void Window::PrivateData::onPuglMotion(const Events::MotionEvent& ev)
{
DGL_DBGp("onPuglMotion : %f %f\n", ev.button, ev.pos.getX(), ev.pos.getY());

// if (fModal.childFocus != nullptr)
// return fModal.childFocus->focus();

#ifndef DPF_TEST_WINDOW_CPP
if (topLevelWidget != nullptr)
topLevelWidget->pData->motionEvent(ev);
#endif
}

void Window::PrivateData::onPuglScroll(const Events::ScrollEvent& ev)
{
DGL_DBGp("onPuglScroll : %f %f %f %f\n", ev.pos.getX(), ev.pos.getY(), ev.delta.getX(), ev.delta.getY());

// if (fModal.childFocus != nullptr)
// return fModal.childFocus->focus();

#ifndef DPF_TEST_WINDOW_CPP
if (topLevelWidget != nullptr)
topLevelWidget->pData->scrollEvent(ev);
#endif
}

static int printEvent(const PuglEvent* event, const char* prefix, const bool verbose);

PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event)
@@ -424,6 +489,7 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu

///< View moved/resized, a #PuglEventConfigure
case PUGL_CONFIGURE:
// unused x, y (double)
pData->onPuglConfigure(event->configure.width, event->configure.height);
break;

@@ -441,6 +507,7 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu

///< View must be drawn, a #PuglEventExpose
case PUGL_EXPOSE:
// unused x, y, width, height (double)
pData->onPuglExpose();
break;

@@ -459,14 +526,38 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu

///< Key pressed, a #PuglEventKey
case PUGL_KEY_PRESS:
break;
///< Key released, a #PuglEventKey
case PUGL_KEY_RELEASE:
{
// unused x, y, xRoot, yRoot (double)
// TODO special keys?
Events::KeyboardEvent ev;
ev.mod = event->key.state;
ev.flags = event->key.flags;
ev.time = static_cast<uint>(event->key.time * 1000.0 + 0.5);
ev.press = event->type == PUGL_KEY_PRESS;
ev.key = event->key.key;
ev.keycode = event->key.keycode;
if ((ev.mod & kModifierShift) != 0 && ev.key >= 'a' && ev.key <= 'z')
ev.key -= 'a' - 'A'; // a-z -> A-Z
pData->onPuglKey(ev);
break;
}

///< Character entered, a #PuglEventText
case PUGL_TEXT:
{
// unused x, y, xRoot, yRoot (double)
Events::CharacterInputEvent ev;
ev.mod = event->text.state;
ev.flags = event->text.flags;
ev.time = static_cast<uint>(event->text.time * 1000.0 + 0.5);
ev.keycode = event->text.keycode;
ev.character = event->text.character;
std::strncpy(ev.string, event->text.string, sizeof(ev.string));
pData->onPuglText(ev);
break;
}

///< Pointer entered view, a #PuglEventCrossing
case PUGL_POINTER_IN:
@@ -493,11 +584,29 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu

///< Pointer moved, a #PuglEventMotion
case PUGL_MOTION:
{
Events::MotionEvent ev;
ev.mod = event->motion.state;
ev.flags = event->motion.flags;
ev.time = static_cast<uint>(event->motion.time * 1000.0 + 0.5);
ev.pos = Point<double>(event->motion.x, event->motion.y);
pData->onPuglMotion(ev);
break;
}

///< Scrolled, a #PuglEventScroll
case PUGL_SCROLL:
{
Events::ScrollEvent ev;
ev.mod = event->scroll.state;
ev.flags = event->scroll.flags;
ev.time = static_cast<uint>(event->scroll.time * 1000.0 + 0.5);
ev.pos = Point<double>(event->scroll.x, event->scroll.y);
ev.delta = Point<double>(event->scroll.dx, event->scroll.dy);
ev.direction = static_cast<ScrollDirection>(event->scroll.direction);
pData->onPuglScroll(ev);
break;
}

///< Custom client message, a #PuglEventClient
case PUGL_CLIENT:
@@ -646,6 +755,9 @@ static int printEvent(const PuglEvent* event, const char* prefix, const bool ver
return 0;
}

#undef DGL_DBG
#undef DGL_DBGF

// -----------------------------------------------------------------------

END_NAMESPACE_DGL

+ 5
- 180
dgl/src/WindowPrivateData.hpp View File

@@ -109,20 +109,16 @@ struct Window::PrivateData : IdleCallback {
void onPuglConfigure(int width, int height);
void onPuglExpose();
void onPuglClose();
void onPuglKey(const Events::KeyboardEvent& ev);
void onPuglSpecial(const Events::SpecialEvent& ev);
void onPuglText(const Events::CharacterInputEvent& ev);
void onPuglMouse(const Events::MouseEvent& ev);
void onPuglMotion(const Events::MotionEvent& ev);
void onPuglScroll(const Events::ScrollEvent& ev);

// Pugl event handling entry point
static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event);

#if 0
// Fallback build-specific Window functions
struct Fallback {
static void onDisplayBefore(const GraphicsContext& context);
static void onDisplayAfter(const GraphicsContext& context);
static void onReshape(const GraphicsContext& context, uint width, uint height);
};
#endif

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData)
};

@@ -185,33 +181,6 @@ END_NAMESPACE_DGL
#endif
#endif

#if 0 // ndef DPF_TEST_WINDOW_CPP
// -------------------------------------------------------------------
// stuff that uses pugl internals or build-specific things

void init(const bool resizable = false);
void setVisible(const bool visible);
void windowSpecificIdle();

// -------------------------------------------------------------------

// -------------------------------------------------------------------

void addWidget(Widget* const widget);
void removeWidget(Widget* const widget);

// -------------------------------------------------------------------

void onPuglClose();
void onPuglMouse(const Widget::MouseEvent& ev);

// -------------------------------------------------------------------
#endif

// #ifdef DISTRHO_DEFINES_H_INCLUDED
// friend class DISTRHO_NAMESPACE::UI;
// #endif

#if 0
// -----------------------------------------------------------------------
// Window Private
@@ -287,147 +256,6 @@ struct Window::PrivateData {

// -------------------------------------------------------------------

// -------------------------------------------------------------------

int onPuglKeyboard(const bool press, const uint key)
{
DBGp("PUGL: onKeyboard : %i %i\n", press, key);

if (fModal.childFocus != nullptr)
{
fModal.childFocus->focus();
return 0;
}

Widget::KeyboardEvent ev;
ev.press = press;
ev.key = key;
ev.mod = static_cast<Modifier>(puglGetModifiers(fView));
ev.time = puglGetEventTimestamp(fView);

FOR_EACH_WIDGET_INV(rit)
{
Widget* const widget(*rit);

if (widget->isVisible() && widget->onKeyboard(ev))
return 0;
}

return 1;
}

int onPuglSpecial(const bool press, const Key key)
{
DBGp("PUGL: onSpecial : %i %i\n", press, key);

if (fModal.childFocus != nullptr)
{
fModal.childFocus->focus();
return 0;
}

Widget::SpecialEvent ev;
ev.press = press;
ev.key = key;
ev.mod = static_cast<Modifier>(puglGetModifiers(fView));
ev.time = puglGetEventTimestamp(fView);

FOR_EACH_WIDGET_INV(rit)
{
Widget* const widget(*rit);

if (widget->isVisible() && widget->onSpecial(ev))
return 0;
}

return 1;
}

void onPuglMotion(int x, int y)
{
// DBGp("PUGL: onMotion : %i %i\n", x, y);

if (fModal.childFocus != nullptr)
return;

x /= fAutoScaling;
y /= fAutoScaling;

Widget::MotionEvent ev;
ev.mod = static_cast<Modifier>(puglGetModifiers(fView));
ev.time = puglGetEventTimestamp(fView);

FOR_EACH_WIDGET_INV(rit)
{
Widget* const widget(*rit);

ev.pos = Point<int>(x-widget->getAbsoluteX(), y-widget->getAbsoluteY());

if (widget->isVisible() && widget->onMotion(ev))
break;
}
}

void onPuglScroll(int x, int y, float dx, float dy)
{
DBGp("PUGL: onScroll : %i %i %f %f\n", x, y, dx, dy);

if (fModal.childFocus != nullptr)
return;

x /= fAutoScaling;
y /= fAutoScaling;
dx /= fAutoScaling;
dy /= fAutoScaling;

Widget::ScrollEvent ev;
ev.delta = Point<float>(dx, dy);
ev.mod = static_cast<Modifier>(puglGetModifiers(fView));
ev.time = puglGetEventTimestamp(fView);

FOR_EACH_WIDGET_INV(rit)
{
Widget* const widget(*rit);

ev.pos = Point<int>(x-widget->getAbsoluteX(), y-widget->getAbsoluteY());

if (widget->isVisible() && widget->onScroll(ev))
break;
}
}

// -------------------------------------------------------------------

bool handlePluginKeyboard(const bool press, const uint key)
{
DBGp("PUGL: handlePluginKeyboard : %i %i\n", press, key);

if (fModal.childFocus != nullptr)
{
fModal.childFocus->focus();
return true;
}

Widget::KeyboardEvent ev;
ev.press = press;
ev.key = key;
ev.mod = static_cast<Modifier>(fView->mods);
ev.time = 0;

if ((ev.mod & kModifierShift) != 0 && ev.key >= 'a' && ev.key <= 'z')
ev.key -= 'a' - 'A'; // a-z -> A-Z

FOR_EACH_WIDGET_INV(rit)
{
Widget* const widget(*rit);

if (widget->isVisible() && widget->onKeyboard(ev))
return true;
}

return false;
}

bool handlePluginSpecial(const bool press, const Key key)
{
DBGp("PUGL: handlePluginSpecial : %i %i\n", press, key);
@@ -519,7 +347,4 @@ struct Window::PrivateData {
};
#endif

// #undef DGL_DBG
// #undef DGL_DBGF

#endif // DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED

Loading…
Cancel
Save