Change focusing behavior: Try getting the view from the current event target in mousemove event, and temporarily focus views so keyboard events are handled too.

This commit is contained in:
Jürg Lehni 2011-06-22 08:29:53 +01:00
parent 07cfaf8662
commit a1196c9f74
2 changed files with 40 additions and 24 deletions

View file

@ -69,7 +69,7 @@ var Key = this.Key = new function() {
var character = String.fromCharCode(charCode), var character = String.fromCharCode(charCode),
key = keys[keyCode] || character.toLowerCase(), key = keys[keyCode] || character.toLowerCase(),
handler = down ? 'onKeyDown' : 'onKeyUp', handler = down ? 'onKeyDown' : 'onKeyUp',
view = View.focused, view = View._focused,
scope = view && view.isVisible() && view._scope, scope = view && view.isVisible() && view._scope,
tool = scope && scope.tool; tool = scope && scope.tool;
keyMap[key] = down; keyMap[key] = down;

View file

@ -101,8 +101,8 @@ var View = this.View = Base.extend({
this._events = this._createEvents(); this._events = this._createEvents();
DomEvent.add(this._canvas, this._events); DomEvent.add(this._canvas, this._events);
// Make sure the first view is focused for keyboard input straight away // Make sure the first view is focused for keyboard input straight away
if (!View.focused) if (!View._focused)
View.focused = this; View._focused = this;
// As soon as a new view is added we need to mark the redraw as not // As soon as a new view is added we need to mark the redraw as not
// motified, so the next call loops through all the views again. // motified, so the next call loops through all the views again.
this._scope._redrawNotified = false; this._scope._redrawNotified = false;
@ -243,8 +243,9 @@ var View = this.View = Base.extend({
remove: function() { remove: function() {
if (this._index == null) if (this._index == null)
return false; return false;
if (View.focused == this) // Clear focus if removed view had it
View.focused = null; if (View._focused == this)
View._focused = null;
delete View._views[this._id]; delete View._views[this._id];
Base.splice(this._scope.views, null, this._index, 1); Base.splice(this._scope.views, null, this._index, 1);
// Uninstall event handlers again for this view. // Uninstall event handlers again for this view.
@ -370,15 +371,45 @@ var View = this.View = Base.extend({
var tool, var tool,
timer, timer,
curPoint, curPoint,
tempFocus,
dragging = false; dragging = false;
function viewToArtwork(view, event) { function viewToArtwork(view, event) {
return view.viewToArtwork(DomEvent.getOffset(event, view._canvas)); return view.viewToArtwork(DomEvent.getOffset(event, view._canvas));
} }
function updateFocus() {
if (!View._focused || !View._focused.isVisible()) {
// Find the first visible view in all scopes
PaperScope.each(function(scope) {
for (var i = 0, l = scope.views.length; i < l; i++) {
var view = scope.views[i];
if (view.isVisible()) {
View._focused = tempFocus = view;
throw Base.stop;
}
}
});
}
}
function mousemove(event) { function mousemove(event) {
var view = View.focused; var view;
if (!view || !(tool = view._scope.tool)) if (!dragging) {
// See if we can get the view from the current event target, and
// handle the mouse move over it.
view = View._views[DomEvent.getTarget(event).getAttribute('id')];
if (view) {
// Temporarily focus this view without making it sticky, so
// Key events are handled too during the mouse over
View._focused = tempFocus = view;
} else if (tempFocus && tempFocus == View._focused) {
// Clear temporary focus again and update it.
View._focused = null;
updateFocus();
}
}
if (!(view = view || View._focused) || !(tool = view._scope.tool))
return; return;
var point = event && viewToArtwork(view, event); var point = event && viewToArtwork(view, event);
var onlyMove = !!(!tool.onMouseDrag && tool.onMouseMove); var onlyMove = !!(!tool.onMouseDrag && tool.onMouseMove);
@ -398,7 +429,7 @@ var View = this.View = Base.extend({
} }
function mouseup(event) { function mouseup(event) {
var view = View.focused; var view = View._focused;
if (!view || !dragging) if (!view || !dragging)
return; return;
dragging = false; dragging = false;
@ -420,21 +451,6 @@ var View = this.View = Base.extend({
DomEvent.stop(event); DomEvent.stop(event);
} }
function updateFocus() {
if (!View.focused || View.focused.isInvisible()) {
// Find the first visible view in all scopes
PaperScope.each(function(scope) {
for (var i = 0, l = scope.views.length; i < l; i++) {
var view = scope.views[i];
if (view.isVisible()) {
View.focused = view;
throw Base.stop;
}
}
});
}
}
// mousemove and mouseup events need to be installed on document, not the // mousemove and mouseup events need to be installed on document, not the
// view canvas, since we want to catch the end of drag events even outside // view canvas, since we want to catch the end of drag events even outside
// our view. Only the mousedown events are installed on the view, as handled // our view. Only the mousedown events are installed on the view, as handled
@ -459,7 +475,7 @@ var View = this.View = Base.extend({
function mousedown(event) { function mousedown(event) {
// Tell the Key class which view should receive keyboard input. // Tell the Key class which view should receive keyboard input.
View.focused = view; View._focused = view;
if (!(tool = view._scope.tool)) if (!(tool = view._scope.tool))
return; return;
curPoint = viewToArtwork(view, event); curPoint = viewToArtwork(view, event);