Correctly handle mousemove events when switching between canvases or leaving the document.

Closes #250.
This commit is contained in:
Jürg Lehni 2013-12-08 23:57:46 +01:00
parent 17e4078e3b
commit 663836ae41
2 changed files with 43 additions and 20 deletions

View file

@ -42,6 +42,10 @@ var DomEvent = {
return event.target || event.srcElement; return event.target || event.srcElement;
}, },
getRelatedTarget: function(event) {
return event.relatedTarget || event.toElement;
},
getOffset: function(event, target) { getOffset: function(event, target) {
// Remove target offsets from page coordinates // Remove target offsets from page coordinates
return DomEvent.getPoint(event).subtract(DomElement.getOffset( return DomEvent.getPoint(event).subtract(DomElement.getOffset(

View file

@ -114,7 +114,7 @@ var View = Base.extend(Callback, /** @lends View# */{
if (!this._project) if (!this._project)
return false; return false;
// Clear focus if removed view had it // Clear focus if removed view had it
if (View._focused == this) if (View._focused === this)
View._focused = null; View._focused = null;
// Remove view from internal structures // Remove view from internal structures
View._views.splice(View._views.indexOf(this), 1); View._views.splice(View._views.indexOf(this), 1);
@ -671,38 +671,56 @@ var View = Base.extend(Callback, /** @lends View# */{
view.update(); view.update();
} }
function handleMouseMove(view, point, event) {
view._handleEvent('mousemove', point, event);
var tool = view._scope._tool;
if (tool) {
// If there's no onMouseDrag, fire onMouseMove while dragging.
tool._handleEvent(dragging && tool.responds('mousedrag')
? 'mousedrag' : 'mousemove', point, event);
}
view.update();
return tool;
}
function mousemove(event) { function mousemove(event) {
var view; var view = View._focused;
if (!dragging) { if (!dragging) {
// See if we can get the view from the current event target, and // See if we can get the view from the current event target, and
// handle the mouse move over it. // handle the mouse move over it.
view = getView(event); var target = getView(event);
if (view) { if (target) {
// Temporarily focus this view without making it sticky, so // Temporarily focus this view without making it sticky, so
// Key events are handled too during the mouse over // Key events are handled too during the mouse over
prevFocus = View._focused; // If we switch view, fire one last mousemove in the old view,
View._focused = tempFocus = view; // to give items the change to receive a mouseleave, etc.
} else if (tempFocus && tempFocus == View._focused) { if (view !== target)
handleMouseMove(view, viewToProject(view, event), event);
prevFocus = view;
view = View._focused = tempFocus = target;
} else if (tempFocus && tempFocus === view) {
// Clear temporary focus again and update it. // Clear temporary focus again and update it.
View._focused = prevFocus; view = View._focused = prevFocus;
updateFocus(); updateFocus();
} }
} }
if (!(view = view || View._focused)) if (view) {
return; var point = viewToProject(view, event);
var point = event && viewToProject(view, event); if (dragging || new Rectangle(new Point(),
if (dragging || new Rectangle(new Point(), view.getViewSize()).contains(point))
view.getViewSize()).contains(point)) { tool = handleMouseMove(view, point, event);
view._handleEvent('mousemove', point, event);
if (tool = view._scope._tool) {
// If there's no onMouseDrag, fire onMouseMove while dragging.
tool._handleEvent(dragging && tool.responds('mousedrag')
? 'mousedrag' : 'mousemove', point, event);
}
view.update();
} }
} }
function mouseout(event) {
// When the moues leaves the document, fire one last mousemove event,
// to give items the change to receive a mouseleave, etc.
var view = View._focused,
target = DomEvent.getRelatedTarget(event);
if (view && (!target || target.nodeName === 'HTML'))
handleMouseMove(view, viewToProject(view, event), event);
}
function mouseup(event) { function mouseup(event) {
var view = View._focused; var view = View._focused;
if (!view || !dragging) if (!view || !dragging)
@ -730,6 +748,7 @@ var View = Base.extend(Callback, /** @lends View# */{
DomEvent.add(document, { DomEvent.add(document, {
mousemove: mousemove, mousemove: mousemove,
mouseout: mouseout,
mouseup: mouseup, mouseup: mouseup,
touchmove: mousemove, touchmove: mousemove,
touchend: mouseup, touchend: mouseup,