Bug 715970 - Highlighted node should center in the visualization (Tilt); r=rcampbell

This commit is contained in:
Victor Porof 2012-02-02 19:14:40 +02:00
Родитель 644bf8031c
Коммит fa8bfa3fd1
6 изменённых файлов: 117 добавлений и 5 удалений

Просмотреть файл

@ -246,7 +246,7 @@ Tilt.prototype = {
*/
update: function T_update(aNode) {
if (this.currentInstance) {
this.currentInstance.presenter.highlightNode(aNode);
this.currentInstance.presenter.highlightNode(aNode, "moveIntoView");
}
},

Просмотреть файл

@ -60,6 +60,7 @@ const WIREFRAME_COLOR = [0, 0, 0, 0.25];
const INTRO_TRANSITION_DURATION = 50;
const OUTRO_TRANSITION_DURATION = 40;
const INITIAL_Z_TRANSLATION = 400;
const MOVE_INTO_VIEW_ACCURACY = 50;
const MOUSE_CLICK_THRESHOLD = 10;
const MOUSE_INTRO_DELAY = 10;
@ -641,10 +642,12 @@ TiltVisualizer.Presenter.prototype = {
*
* @param {Element} aNode
* the html node to be highlighted
* @param {String} aFlags
* flags specifying highlighting options
*/
highlightNode: function TVP_highlightNode(aNode)
highlightNode: function TVP_highlightNode(aNode, aFlags)
{
this.highlightNodeFor(this.traverseData.nodes.indexOf(aNode));
this.highlightNodeFor(this.traverseData.nodes.indexOf(aNode), aFlags);
},
/**
@ -703,8 +706,10 @@ TiltVisualizer.Presenter.prototype = {
*
* @param {Number} aNodeIndex
* the index of the node in the this.traverseData array
* @param {String} aFlags
* flags specifying highlighting options
*/
highlightNodeFor: function TVP_highlightNodeFor(aNodeIndex)
highlightNodeFor: function TVP_highlightNodeFor(aNodeIndex, aFlags)
{
this.redraw = true;
@ -749,6 +754,17 @@ TiltVisualizer.Presenter.prototype = {
this.contentWindow.innerHeight < y ||
this.contentWindow.pageYOffset > 0);
// if something is highlighted, make sure it's inside the current viewport;
// the point which should be moved into view is considered the center [x, y]
// position along the top edge of the currently selected node
if (aFlags && aFlags.indexOf("moveIntoView") !== -1)
{
this.controller.arcball.moveIntoView(vec3.lerp(
vec3.scale(this.highlight.v0, this.transforms.zoom, []),
vec3.scale(this.highlight.v1, this.transforms.zoom, []), 0.5));
}
Services.obs.notifyObservers(null, this.NOTIFICATIONS.HIGHLIGHTING, null);
},
@ -1002,6 +1018,7 @@ TiltVisualizer.Controller = function TV_Controller(aCanvas, aPresenter)
* Save a reference to the presenter to modify its model-view transforms.
*/
this.presenter = aPresenter;
this.presenter.controller = this;
/**
* The initial controller dimensions and offset, in pixels.
@ -1733,6 +1750,25 @@ TiltVisualizer.Arcball.prototype = {
this._mouseButton = -1;
},
/**
* Moves a target point into view only if it's outside the currently visible
* area bounds (in which case it also resets any additional transforms).
*
* @param {Arary} aPoint
* the [x, y] point which should be brought into view
*/
moveIntoView: function TVA_moveIntoView(aPoint) {
let visiblePointX = -(this._currentTrans[0] + this._additionalTrans[0]);
let visiblePointY = -(this._currentTrans[1] + this._additionalTrans[1]);
if (aPoint[1] - visiblePointY - MOVE_INTO_VIEW_ACCURACY > this.height ||
aPoint[1] - visiblePointY + MOVE_INTO_VIEW_ACCURACY < 0 ||
aPoint[0] - visiblePointX > this.width ||
aPoint[0] - visiblePointX < 0) {
this.reset([0, -aPoint[1]]);
}
},
/**
* Resize this implementation to use different bounds.
* This function is automatically called when the arcball is created.

Просмотреть файл

@ -76,6 +76,7 @@ _BROWSER_TEST_FILES = \
browser_tilt_math07.js \
browser_tilt_picking.js \
browser_tilt_picking_delete.js \
browser_tilt_picking_highlight01-offs.js \
browser_tilt_picking_highlight01.js \
browser_tilt_picking_highlight02.js \
browser_tilt_picking_highlight03.js \

Просмотреть файл

@ -0,0 +1,70 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
let presenter;
function test() {
if (!isTiltEnabled()) {
info("Skipping highlight test because Tilt isn't enabled.");
return;
}
if (!isWebGLSupported()) {
info("Skipping highlight test because WebGL isn't supported.");
return;
}
requestLongerTimeout(10);
waitForExplicitFinish();
createTab(function() {
createTilt({
onTiltOpen: function(instance)
{
presenter = instance.presenter;
Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false);
presenter.onInitializationFinished = function() {
let contentDocument = presenter.contentWindow.document;
let div = contentDocument.getElementById("far-far-away");
presenter.highlightNode(div, "moveIntoView");
};
}
});
});
}
function whenHighlighting() {
ok(presenter._currentSelection > 0,
"Highlighting a node didn't work properly.");
ok(!presenter.highlight.disabled,
"After highlighting a node, it should be highlighted. D'oh.");
ok(presenter.controller.arcball._resetInterval,
"Highlighting a node that's not already visible should trigger a reset!");
executeSoon(function() {
Services.obs.addObserver(whenUnhighlighting, UNHIGHLIGHTING, false);
presenter.highlightNode(null);
});
}
function whenUnhighlighting() {
ok(presenter._currentSelection < 0,
"Unhighlighting a should remove the current selection.");
ok(presenter.highlight.disabled,
"After unhighlighting a node, it shouldn't be highlighted anymore. D'oh.");
executeSoon(function() {
Services.obs.addObserver(cleanup, DESTROYED, false);
InspectorUI.closeInspectorUI();
});
}
function cleanup() {
Services.obs.removeObserver(whenHighlighting, HIGHLIGHTING);
Services.obs.removeObserver(whenUnhighlighting, UNHIGHLIGHTING);
Services.obs.removeObserver(cleanup, DESTROYED);
gBrowser.removeCurrentTab();
finish();
}

Просмотреть файл

@ -27,7 +27,7 @@ function test() {
let contentDocument = presenter.contentWindow.document;
let div = contentDocument.getElementById("first-law");
presenter.highlightNode(div);
presenter.highlightNode(div, "moveIntoView");
};
}
});
@ -39,6 +39,8 @@ function whenHighlighting() {
"Highlighting a node didn't work properly.");
ok(!presenter.highlight.disabled,
"After highlighting a node, it should be highlighted. D'oh.");
ok(!presenter.controller.arcball._resetInterval,
"Highlighting a node that's already visible shouldn't trigger a reset.");
executeSoon(function() {
Services.obs.addObserver(whenUnhighlighting, UNHIGHLIGHTING, false);

Просмотреть файл

@ -37,6 +37,9 @@ const DEFAULT_HTML = "data:text/html," +
"A robot must protect its own existence as long as such protection " +
"does not conflict with the First or Second Laws." +
"</div>" +
"<div id='far-far-away' style='position: absolute; top: 250%;'>" +
"I like bacon." +
"</div>" +
"<body>" +
"</html>";