Fixed button hover being stuck
This commit is contained in:
parent
b5101261a4
commit
19469c5946
1
TODO.md
1
TODO.md
|
@ -82,7 +82,6 @@ Common UI
|
|||
---------
|
||||
|
||||
* Add caret/focus to text input
|
||||
* Fix hover being stuck when the cursor exits the window, or the item moves or is hidden
|
||||
* Add a standard confirm dialog
|
||||
* Mobile: think UI layout so that fingers do not block the view (right and left handed)
|
||||
* Mobile: display tooltips larger and on the side of screen where the finger is not
|
||||
|
|
|
@ -16,7 +16,8 @@ module TS.SpaceTac.UI.Specs {
|
|||
});
|
||||
|
||||
it("handles hover and click on desktops and mobile targets", function (done) {
|
||||
let newButton: () => [Phaser.Button, any] = () => {
|
||||
let pointer = new Phaser.Pointer(testgame.ui, 0);
|
||||
function newButton(): [Phaser.Button, any] {
|
||||
var button = new Phaser.Button(testgame.ui);
|
||||
var funcs = {
|
||||
enter: () => null,
|
||||
|
@ -27,52 +28,81 @@ module TS.SpaceTac.UI.Specs {
|
|||
spyOn(funcs, "leave");
|
||||
spyOn(funcs, "click");
|
||||
UITools.setHoverClick(button, funcs.enter, funcs.leave, funcs.click, 50, 100);
|
||||
UITools.hovered = null;
|
||||
return [button, funcs];
|
||||
}
|
||||
let enter = (button: Phaser.Button) => (<any>button.input)._pointerOverHandler(pointer);
|
||||
let leave = (button: Phaser.Button) => (<any>button.input)._pointerOutHandler(pointer);
|
||||
let press = (button: Phaser.Button) => button.onInputDown.dispatch(button, pointer);
|
||||
let release = (button: Phaser.Button) => button.onInputUp.dispatch(button, pointer);
|
||||
let destroy = (button: Phaser.Button) => button.events.onDestroy.dispatch();
|
||||
|
||||
// Simple click on desktop
|
||||
let [button, funcs] = newButton();
|
||||
button.onInputOver.dispatch();
|
||||
button.onInputDown.dispatch();
|
||||
button.onInputUp.dispatch();
|
||||
enter(button);
|
||||
press(button);
|
||||
release(button);
|
||||
expect(funcs.enter).toHaveBeenCalledTimes(0);
|
||||
expect(funcs.leave).toHaveBeenCalledTimes(0);
|
||||
expect(funcs.click).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Simple click on mobile
|
||||
[button, funcs] = newButton();
|
||||
button.onInputDown.dispatch();
|
||||
button.onInputUp.dispatch();
|
||||
press(button);
|
||||
release(button);
|
||||
expect(funcs.enter).toHaveBeenCalledTimes(1);
|
||||
expect(funcs.leave).toHaveBeenCalledTimes(1);
|
||||
expect(funcs.click).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Leaves on destroy
|
||||
[button, funcs] = newButton();
|
||||
button.onInputDown.dispatch();
|
||||
press(button);
|
||||
jasmine.clock().tick(150);
|
||||
expect(funcs.enter).toHaveBeenCalledTimes(1);
|
||||
expect(funcs.leave).toHaveBeenCalledTimes(0);
|
||||
expect(funcs.click).toHaveBeenCalledTimes(0);
|
||||
button.events.onDestroy.dispatch();
|
||||
destroy(button);
|
||||
expect(funcs.enter).toHaveBeenCalledTimes(1);
|
||||
expect(funcs.leave).toHaveBeenCalledTimes(1);
|
||||
expect(funcs.click).toHaveBeenCalledTimes(0);
|
||||
button.onInputDown.dispatch();
|
||||
button.onInputUp.dispatch();
|
||||
press(button);
|
||||
release(button);
|
||||
expect(funcs.enter).toHaveBeenCalledTimes(1);
|
||||
expect(funcs.leave).toHaveBeenCalledTimes(1);
|
||||
expect(funcs.click).toHaveBeenCalledTimes(0);
|
||||
|
||||
// Force-leave when hovering another button without clean leaving a first one
|
||||
let [button1, funcs1] = newButton();
|
||||
let [button2, funcs2] = newButton();
|
||||
enter(button1);
|
||||
jasmine.clock().tick(150);
|
||||
expect(funcs1.enter).toHaveBeenCalledTimes(1);
|
||||
expect(funcs1.leave).toHaveBeenCalledTimes(0);
|
||||
expect(funcs1.click).toHaveBeenCalledTimes(0);
|
||||
enter(button2);
|
||||
expect(funcs1.enter).toHaveBeenCalledTimes(1);
|
||||
expect(funcs1.leave).toHaveBeenCalledTimes(1);
|
||||
expect(funcs1.click).toHaveBeenCalledTimes(0);
|
||||
expect(funcs2.enter).toHaveBeenCalledTimes(0);
|
||||
expect(funcs2.leave).toHaveBeenCalledTimes(0);
|
||||
expect(funcs2.click).toHaveBeenCalledTimes(0);
|
||||
jasmine.clock().tick(150);
|
||||
expect(funcs1.enter).toHaveBeenCalledTimes(1);
|
||||
expect(funcs1.leave).toHaveBeenCalledTimes(1);
|
||||
expect(funcs1.click).toHaveBeenCalledTimes(0);
|
||||
expect(funcs2.enter).toHaveBeenCalledTimes(1);
|
||||
expect(funcs2.leave).toHaveBeenCalledTimes(0);
|
||||
expect(funcs2.click).toHaveBeenCalledTimes(0);
|
||||
|
||||
// Hold to hover on mobile
|
||||
jasmine.clock().uninstall();
|
||||
[button, funcs] = newButton();
|
||||
button.onInputDown.dispatch();
|
||||
button.onInputDown.dispatch(button, pointer);
|
||||
Timer.global.schedule(150, () => {
|
||||
expect(funcs.enter).toHaveBeenCalledTimes(1);
|
||||
expect(funcs.leave).toHaveBeenCalledTimes(0);
|
||||
expect(funcs.click).toHaveBeenCalledTimes(0);
|
||||
button.onInputUp.dispatch();
|
||||
button.onInputUp.dispatch(button, pointer);
|
||||
expect(funcs.enter).toHaveBeenCalledTimes(1);
|
||||
expect(funcs.leave).toHaveBeenCalledTimes(1);
|
||||
expect(funcs.click).toHaveBeenCalledTimes(0);
|
||||
|
|
|
@ -8,6 +8,8 @@ module TS.SpaceTac.UI {
|
|||
|
||||
// Common UI tools functions
|
||||
export class UITools {
|
||||
static hovered: Phaser.Button | null = null;
|
||||
|
||||
/**
|
||||
* Get the position of an object, adjusted to remain inside a container
|
||||
*/
|
||||
|
@ -90,9 +92,19 @@ module TS.SpaceTac.UI {
|
|||
});
|
||||
}
|
||||
|
||||
obj.onInputOver.add(() => {
|
||||
obj.onInputOver.add((_: any, pointer: Phaser.Pointer) => {
|
||||
if (destroyed) return;
|
||||
|
||||
if (UITools.hovered) {
|
||||
if (UITools.hovered === obj) {
|
||||
return;
|
||||
} else {
|
||||
// Dirty fix - Force a "pointer out" on previously hovered, if it did not go out cleanly
|
||||
(<any>UITools.hovered.input)._pointerOutHandler(pointer);
|
||||
}
|
||||
}
|
||||
UITools.hovered = obj;
|
||||
|
||||
if (obj.visible && obj.alpha) {
|
||||
cursorinside = true;
|
||||
enternext = Timer.global.schedule(hovertime, effectiveenter);
|
||||
|
@ -102,6 +114,10 @@ module TS.SpaceTac.UI {
|
|||
obj.onInputOut.add(() => {
|
||||
if (destroyed) return;
|
||||
|
||||
if (UITools.hovered === obj) {
|
||||
UITools.hovered = null;
|
||||
}
|
||||
|
||||
cursorinside = false;
|
||||
effectiveleave();
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue