I’m hitting a problem working on the ScrollView component over at react-juce:
Specifically, I’m trying to disable mouseDown/mouseUp handlers on all child components when we begin scrolling. As a quick test I’ve attempted the folllowing:
namespace detail
{
void recursiveClickIntercept(juce::Component *component, bool intercepts)
{
auto &children = component->getChildren();
for (auto *c : children)
recursiveClickIntercept(c, intercepts);
component->setInterceptsMouseClicks(intercepts, intercepts);
}
}
ScrollView::ScrollView()
{
// Use a default scrollEvent rate of 30Hz.
// This is prop configurable
startTimerHz(30);
viewport.onAreaChanged([this](const juce::Rectangle<int>& area)
{
if (isMouseButtonDown(true) && !isScrolling)
{
detail::recursiveClickIntercept(&viewport, false);
isScrolling = true;
}
lastScrollEvent.event = detail::makeScrollEventObject(area.getY(), area.getX());
lastScrollEvent.dirty = true;
});
addAndMakeVisible(viewport);
viewport.setScrollBarsShown(true, true);
exportNativeMethods();
}
However, I’m still seeing child elements of the Viewport getting their mouseUp calls fired:
Confused as to why I’m still getting mouseUp callbacks fired. Basically this results in our onClick callbacks in React components firing when we stop scrolling the list/viewport which is pretty nasty.
I perhaps need to debug further but am I missing something super obvious in the API here?
Since the hitTest that is actually affected by the setInterceptMouseClicks setting stops already the traversal into the children.
If you still get mouse events, I would look out for addMouseListener in the code. That will eventually duplicate events, that’s why I always advise against using it with a few exceptions.
I had a quick look and it seems like all View send their mouse events to the ReactApplicationRoot which feeds it to the EcmaScriptEngine, so it seems not to obey the JUCE flow of mouse events at all.
Yeah no for sure. I added some code a while back which triggers onClick callbacks in response to the dispatched “mouseUp” events in the react-juce event layer.
Basically I want to block dispatching the “mouseUp” event into React at all and this felt like the right route. Maybe it’s not though …
Could potentially handle this in Backend.ts in react-juce and avoid raising “onClick” callbacks based on parent scroll view state. In not convinced that’s the right call just yet!
The View event dispatching that runs from all Views up into ReactApplicationRoot is orthogonal to a juce::Component::mouseUp or other mouse events. That logic only exists to make sure that when a mouse event does occur on a View, we can dispatch the event into the javascript engine. But before that ever happens we have the business of juce::Component mouse event handling and setInterceptsMouseClicks.
@jucemarler what does the View heirarchy look like inside of the ScrollView? And do you know which View inside that heirarchy is responsible for firing the mouseUp in question?
Yeah indeed. I can even see I’m disabling mouse clicks on that View instance under the debugger when disabling mouse clicks on all children recursively.
The items in the ScrollView instance look a little like this:
The onClick prop is used for some selection state but right now it’s firing when I release mouse/finger to end a scroll.
In this case the mouseUp could vary based on cursor but most often it’ll be the ItemInfo component
EDIT: Might dig into mouse handle code a little further, I wonder if this is something to do with disabling mouse clicks after a mouseDown has already been received? Possible we’ve already set the peer in MouseInputSource and as a result we don’t call hitTest again before firing mouseUp, just a theory, Will test. .