Skip to content

Commit

Permalink
Implement multiple Overs for Interactives (#537)
Browse files Browse the repository at this point in the history
  • Loading branch information
Yanrishatum authored and ncannasse committed Mar 9, 2019
1 parent da0ae22 commit 1be675f
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 47 deletions.
11 changes: 3 additions & 8 deletions h2d/Interactive.hx
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,8 @@ class Interactive extends Drawable implements hxd.SceneEvents.Interactive {
mouseDownButton = -1;
case EOver:
onOver(e);
if( !e.cancel && cursor != null )
hxd.System.setCursor(cursor);
case EOut:
mouseDownButton = -1;
onOut(e);
if( !e.cancel )
hxd.System.setCursor(Default);
case EWheel:
onWheel(e);
case EFocusLost:
Expand All @@ -206,8 +201,8 @@ class Interactive extends Drawable implements hxd.SceneEvents.Interactive {

function set_cursor(c) {
this.cursor = c;
if( isOver() && cursor != null )
hxd.System.setCursor(cursor);
if ( scene != null && scene.events != null )
scene.events.updateCursor(this);
return c;
}

Expand Down Expand Up @@ -247,7 +242,7 @@ class Interactive extends Drawable implements hxd.SceneEvents.Interactive {
}

public function isOver() {
return scene != null && scene.events != null && @:privateAccess scene.events.currentOver == this;
return scene != null && scene.events != null && @:privateAccess scene.events.overList.indexOf(this) != -1;
}

public function hasFocus() {
Expand Down
11 changes: 3 additions & 8 deletions h3d/scene/Interactive.hx
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,8 @@ class Interactive extends Object implements hxd.SceneEvents.Interactive {
mouseDownButton = -1;
case EOver:
onOver(e);
if( !e.cancel && cursor != null )
hxd.System.setCursor(cursor);
case EOut:
mouseDownButton = -1;
onOut(e);
if( !e.cancel )
hxd.System.setCursor(Default);
case EWheel:
onWheel(e);
case EFocusLost:
Expand All @@ -120,8 +115,8 @@ class Interactive extends Object implements hxd.SceneEvents.Interactive {

function set_cursor(c) {
this.cursor = c;
if( isOver() && cursor != null )
hxd.System.setCursor(cursor);
if ( scene != null && scene.events != null )
scene.events.updateCursor(this);
return c;
}

Expand All @@ -136,7 +131,7 @@ class Interactive extends Object implements hxd.SceneEvents.Interactive {
}

public function isOver() {
return scene != null && scene.events != null && @:privateAccess scene.events.currentOver == this;
return scene != null && scene.events != null && @:privateAccess scene.events.overList.indexOf(this) != -1;
}

public function hasFocus() {
Expand Down
111 changes: 80 additions & 31 deletions hxd/SceneEvents.hx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ interface InteractiveScene {
}

interface Interactive {
public var propagateEvents : Bool;
public var cursor(default, set) : hxd.Cursor;
public function handleEvent( e : Event ) : Void;
public function getInteractiveScene() : InteractiveScene;
}
Expand All @@ -18,7 +20,7 @@ class SceneEvents {
var window : hxd.Window;
var scenes : Array<InteractiveScene>;

var currentOver : Interactive;
var overList : Array<Interactive>;
var currentFocus : Interactive;

var pendingEvents : Array<hxd.Event>;
Expand Down Expand Up @@ -47,6 +49,7 @@ class SceneEvents {
scenes = [];
pendingEvents = [];
pushList = [];
overList = [];
if( window == null ) window = hxd.Window.getInstance();
this.window = window;
window.addEventTarget(onEvent);
Expand All @@ -60,10 +63,8 @@ class SceneEvents {
function onRemove(i) {
if( i == currentFocus )
currentFocus = null;
if( i == currentOver ) {
currentOver = null;
hxd.System.setCursor(Default);
}
if ( overList.remove(i) )
selectCursor();
pushList.remove(i);
}

Expand Down Expand Up @@ -120,9 +121,12 @@ class SceneEvents {
function emitEvent( event : hxd.Event ) {
var oldX = event.relX, oldY = event.relY;
var handled = false;
var checkOver = false, checkPush = false, cancelFocus = false;
var checkOver = false, fillOver = false, checkPush = false, cancelFocus = false, updateCursor = false;
var overIndex : Int = 0;
switch( event.kind ) {
case EMove, ECheck: checkOver = true;
case EMove, ECheck:
checkOver = true;
fillOver = true;
case EPush: cancelFocus = true; checkPush = true;
case ERelease: checkPush = true;
case EKeyUp, EKeyDown, ETextInput, EWheel:
Expand All @@ -149,28 +153,44 @@ class SceneEvents {
}

if( checkOver ) {
if( currentOver != i ) {
onOut.cancel = false;
if( currentOver != null )
currentOver.handleEvent(onOut);
if( !onOut.cancel ) {
var old = event.propagate;
if ( fillOver ) {
var idx = overList.indexOf(i);
if ( idx == -1 ) {
var oldPropagate = event.propagate;
var oldKind = event.kind;
event.kind = EOver;
event.cancel = false;
i.handleEvent(event);
if( event.cancel )
currentOver = null;
else {
currentOver = i;
checkOver = false;
if ( !event.cancel ) {
overList.insert(overIndex, i);
overIndex++;
fillOver = event.propagate;
updateCursor = true;
}
event.kind = oldKind;
event.propagate = oldPropagate;
event.cancel = false;
event.propagate = old;
} else {
var o = overList[idx];
if ( idx < overIndex ) {
do {
overList[idx] = overList[idx + 1];
idx++;
} while ( idx < overIndex );
overList[overIndex] = o;
updateCursor = true;
} else if ( idx > overIndex ) {
do {
overList[idx] = overList[idx - 1];
idx--;
} while ( idx > overIndex );
overList[overIndex] = o;
updateCursor = true;
}
fillOver = i.propagateEvents;
overIndex++;
}
} else
checkOver = false;
}
} else {
if( checkPush ) {
if( event.kind == EPush )
Expand Down Expand Up @@ -200,12 +220,20 @@ class SceneEvents {
if( cancelFocus && currentFocus != null )
blur();

if( checkOver && currentOver != null ) {
onOut.cancel = false;
currentOver.handleEvent(onOut);
if( !onOut.cancel )
currentOver = null;
if( checkOver && overIndex < overList.length ) {
var idx = overList.length - 1;
do {
onOut.cancel = false;
overList[idx].handleEvent(onOut);
if ( !onOut.cancel ) {
overList.remove(overList[idx]);
continue;
}
} while ( --idx >= overIndex );
updateCursor = true;
}
if ( updateCursor )
selectCursor();

if( !handled && event != checkPos ) {
if( event.kind == EPush )
Expand Down Expand Up @@ -264,15 +292,21 @@ class SceneEvents {
}
case EOver:
isOut = false;
selectCursor();
continue;
case EOut:
// leave window
isOut = true;
if( currentOver != null ) {
onOut.cancel = false;
currentOver.handleEvent(onOut);
if( !onOut.cancel )
currentOver = null;
if ( overList.length > 0 ) {
var i = overList.length - 1;
while ( i >= 0 ) {
onOut.cancel = false;
overList[i].handleEvent(onOut);
if ( !onOut.cancel )
overList.remove(overList[i]);
i--;
}
selectCursor();
}
continue;
default:
Expand Down Expand Up @@ -324,6 +358,21 @@ class SceneEvents {
return currentFocus;
}

public function updateCursor( i : Interactive ) {
if ( overList.indexOf(i) != -1 ) selectCursor();
}

function selectCursor() {
var cur : hxd.Cursor = Default;
for ( o in overList ) {
if ( o.cursor != null ) {
cur = o.cursor;
break;
}
}
hxd.System.setCursor(cur);
}

function onEvent( e : hxd.Event ) {
if( !enablePhysicalMouse && e.kind == EMove ) return;
pendingEvents.push(e);
Expand Down

0 comments on commit 1be675f

Please sign in to comment.