Skip to content

Commit

Permalink
Merge pull request #560 from Shallowmallow/HoveringInScrollViews
Browse files Browse the repository at this point in the history
Hovering in scroll views
  • Loading branch information
ianharrigan authored Jan 22, 2024
2 parents 24951e2 + 403b85b commit c559123
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
2 changes: 2 additions & 0 deletions haxe/ui/components/Scroll.hx
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ private class ScrollValueBehaviour extends DataBehaviour {
}

var changeEvent:UIEvent = new UIEvent(UIEvent.CHANGE);
changeEvent.previousValue = _previousValue;
changeEvent.value = pos;
scroll.dispatch(changeEvent);

var scrollEvent:ScrollEvent = new ScrollEvent(ScrollEvent.SCROLL);
Expand Down
57 changes: 57 additions & 0 deletions haxe/ui/containers/ScrollView.hx
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,17 @@ class ScrollViewEvents extends haxe.ui.events.Events {
private function onHScroll(event:UIEvent) {
_scrollview.invalidateComponent(InvalidationFlags.SCROLL);
_target.dispatch(new ScrollEvent(ScrollEvent.CHANGE));

if (!_scrollview.virtual) {
var scrollX:Float = event.value;
var oldScrollX:Float = event.previousValue;
var diffX = scrollX - oldScrollX;

var mouseX = haxe.ui.core.Screen.instance.currentMouseX;
var mouseY = haxe.ui.core.Screen.instance.currentMouseY;
// components have not yet moved so comparing actual and future position
simulateHoveringEvents(mouseX, mouseY, mouseX + diffX, mouseY);
}
}

private function onHScrollScroll(event:UIEvent) {
Expand All @@ -744,6 +755,52 @@ class ScrollViewEvents extends haxe.ui.events.Events {
private function onVScroll(event:UIEvent) {
_scrollview.invalidateComponent(InvalidationFlags.SCROLL);
_target.dispatch(new ScrollEvent(ScrollEvent.CHANGE));

if (!_scrollview.virtual) {
var scrollY:Float = event.value;
var oldScrollY:Float = event.previousValue;
var diffY = scrollY - oldScrollY;

var mouseX = haxe.ui.core.Screen.instance.currentMouseX;
var mouseY = haxe.ui.core.Screen.instance.currentMouseY;
// components have not yet moved so comparing actual and future position
simulateHoveringEvents(mouseX, mouseY, mouseX, mouseY + diffY);
}
}

private function simulateHoveringEvents(oldScreenX:Float, oldScreenY:Float, newScreenX:Float, newScreenY:Float) {

var oldComponents = _scrollview.findComponentsUnderPoint(oldScreenX, oldScreenY);
var newComponents = _scrollview.findComponentsUnderPoint(newScreenX, newScreenY, true);

var oldHoveredComponents = [];
var newHoveredComponents = [];

for ( c in oldComponents) {
@:privateAccess if (c.__events != null && (c.__events._map.exists(MouseEvent.MOUSE_OUT) ||
c.__events._map.exists(MouseEvent.MOUSE_OVER))) {
oldHoveredComponents.push(c);
}
}
for ( c in newComponents) {
@:privateAccess if (c.__events != null && (c.__events._map.exists(MouseEvent.MOUSE_OUT) ||
c.__events._map.exists(MouseEvent.MOUSE_OVER))) {
newHoveredComponents.push(c);
}
}

for ( c in oldHoveredComponents) {
if (newHoveredComponents.indexOf(c) ==-1) {
var mouseEvent = new MouseEvent(MouseEvent.MOUSE_OUT);
c.dispatch(mouseEvent);
}
}
for ( c in newHoveredComponents) {
if (oldHoveredComponents.indexOf(c) == -1) {
var mouseEvent = new MouseEvent(MouseEvent.MOUSE_OVER);
c.dispatch(mouseEvent);
}
}
}

private function onVScrollScroll(event:UIEvent) {
Expand Down
5 changes: 3 additions & 2 deletions haxe/ui/core/Component.hx
Original file line number Diff line number Diff line change
Expand Up @@ -895,11 +895,12 @@ class Component extends ComponentImpl
* @param screenX The global, on-screen `x` position of the point to check for components under
* @param screenY The global, on-screen `y` position of the point to check for components under
* @param type Used to filter all components that aren't of a specific type. `null` by default, which means no filter is applied.
* @param deepSearch Look into children even if parent is not under point
* @return An array of all components that overlap the "global" position `(x, y)`
*/
public function findComponentsUnderPoint<T:Component>(screenX:Float, screenY:Float, type:Class<T> = null):Array<Component> {
public function findComponentsUnderPoint<T:Component>(screenX:Float, screenY:Float, type:Class<T> = null, deepSearch:Bool = false):Array<Component> {
var c:Array<Component> = [];
if (hitTest(screenX, screenY, false)) {
if (deepSearch || hitTest(screenX, screenY, false)) {
for (child in childComponents) {
if (child.hitTest(screenX, screenY, false)) {
var match = true;
Expand Down

0 comments on commit c559123

Please sign in to comment.