Bug 466280: fix WidgetStack to support resizes, and use that support to enable panning the full range of content at smaller-than-default window sizes, r=vlad/stuart

This commit is contained in:
Gavin Sharp 2008-12-19 18:04:16 -05:00
Родитель 9ca5cffefe
Коммит 61422459a5
5 изменённых файлов: 100 добавлений и 57 удалений

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

@ -442,6 +442,10 @@ CanvasBrowser.prototype = {
clickOffsetY - cwin.scrollY];
},
get _effectiveContentAreaDimensions() {
return this._contentAreaDimensions.map(this._pageToScreen, this);
},
get _contentAreaDimensions() {
var cdoc = this._browser.contentDocument;

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

@ -61,6 +61,17 @@ function logbase() {
}
}
function dumpJSStack(stopAtNamedFunction) {
let caller = Components.stack.caller;
dump("\tStack: " + caller.name);
while ((caller = caller.caller)) {
dump(" <- " + caller.name);
if (stopAtNamedFunction && caller.name != "anonymous")
break;
}
dump("\n");
}
function log() {
return;
logbase.apply(window, arguments);
@ -371,11 +382,11 @@ WidgetStack.prototype = {
// panBy: pan the entire set of widgets by the given x and y amounts.
// This does the same thing as if the user dragged by the given amount.
// If this is called with an outstanding drag, weirdness might happen,
// but it also might work, so not isabling that.
// but it also might work, so not disabling that.
//
// if ignoreBarriers is true, then barriers are ignored for the pan.
panBy: function (dx, dy, ignoreBarriers) {
let needsDragWrap = !this._dragging();
panBy: function panBy(dx, dy, ignoreBarriers) {
let needsDragWrap = !this._dragging;
//log2("tlc rect.x start", this._widgetState['tab-list-container'].rect.x, needsDragWrap);
@ -475,7 +486,7 @@ WidgetStack.prototype = {
//
// setViewportBounds will move all the viewport-relative widgets into
// place based on the new viewport bounds.
setViewportBounds: function () {
setViewportBounds: function setViewportBounds() {
let oldBounds = this._viewportBounds.clone();
let oldInner = this._viewport.viewportInnerBounds.clone();
@ -561,18 +572,7 @@ WidgetStack.prototype = {
log2("viewingRect old", this._viewingRect.toString());
if (!this._pannableBounds.contains(this._viewingRect)) {
let dx = dright - dleft;
let dy = dbottom - dtop;
//console.log("panBy: ", -dx, -dy);
this._rectSanityCheck = false;
this.panBy(-dx, -dy, true);
this._rectSanityCheck = true;
}
this._adjustViewingRect();
log2("viewingRect new", this._viewingRect.toString());
log2("finished, inner bounds old:", oldInner, " new:", this._viewport.viewportInnerBounds);
@ -648,7 +648,7 @@ WidgetStack.prototype = {
dragStop: function () {
log("(dragStop)");
if (!this._dragging())
if (!this._dragging)
return;
if (this._viewportUpdateTimeout != -1)
@ -661,8 +661,8 @@ WidgetStack.prototype = {
},
// dragMove: process a mouse move to clientX,clientY for an ongoing drag
dragMove: function (clientX, clientY) {
if (!this._dragging())
dragMove: function dragStop(clientX, clientY) {
if (!this._dragging)
return;
log("(dragMove)", clientX, clientY);
@ -681,16 +681,13 @@ WidgetStack.prototype = {
// updateSize: tell the WidgetStack to update its size, because it
// was either resized or some other event took place.
updateSize: function() {
let rect = this._el.getBoundingClientRect();
let oldw = this._viewingRect.width;
let oldh = this._viewingRect.height;
let width = rect.right - rect.left;
let height = rect.bottom - rect.top;
updateSize: function updateSize() {
// XXX assumes we can only be resized from the bottom left/bottom right
this._viewingRect.width = width;
this._viewingRect.height = height;
let rect = this._el.getBoundingClientRect();
this._viewingRect.width = rect.width;
this._viewingRect.height = rect.height;
this._adjustViewingRect();
// If the viewport changed size (the only thing that's allowed to for now),
// update its internal sizes
@ -701,8 +698,8 @@ WidgetStack.prototype = {
let newViewportRect = this._viewport.widget.getBoundingClientRect();
let w = newViewportRect.right - newViewportRect.left;
let h = newViewportRect.bottom - newViewportRect.top;
let w = newViewportRect.width;
let h = newViewportRect.height;
if (this._viewport.widget.hasAttribute("widgetwidth") &&
this._viewport.widget.hasAttribute("widgetheight"))
@ -796,6 +793,39 @@ WidgetStack.prototype = {
// Internal code
//
_dumpRects: function () {
dump("WidgetStack:\n");
//dump("\tthis._viewportBounds: " + this._viewportBounds + "\n");
dump("\tthis._viewingRect: " + this._viewingRect + "\n");
dump("\tthis._viewport.viewportInnerBounds: " + this._viewport.viewportInnerBounds + "\n");
dump("\tthis._viewport.rect: " + this._viewport.rect + "\n");
//dump("\tthis._pannableBounds: " + this._pannableBounds + "\n");
},
// Ensures that _viewingRect is within _pannableBounds (call this when either
// one is resized)
_adjustViewingRect: function _adjustViewingRect() {
if (this._pannableBounds.contains(this._viewingRect))
return; // nothing to do here
this._rectSanityCheck = false;
let vr = this._viewingRect;
let pb = this._pannableBounds;
if (vr.right > pb.right)
this.panBy(pb.right - vr.right, 0, true);
else if (vr.left < pb.left)
this.panBy(pb.left - vr.left, 0, true);
if (vr.bottom > pb.bottom)
this.panBy(0, pb.bottom - vr.bottom, true);
else if(vr.top < pb.top)
this.panBy(0, pb.top - vr.top, true);
this._rectSanityCheck = true;
},
_getState: function (wid) {
if (!(wid in this._widgetState))
throw "Unknown widget id '" + wid + "'; widget not in stack";
@ -831,25 +861,25 @@ WidgetStack.prototype = {
},
_onMouseMove: function (ev) {
if (!this._dragging())
if (!this._dragging)
return;
this._dragCoordsFromClient(ev.screenX, ev.screenY);
if (!this._dragging() && this._dragState.outerDistSquared > 100)
if (!this._dragging && this._dragState.outerDistSquared > 100)
this._delayedDragStart();
this.dragMove(ev.screenX, ev.screenY);
},
_dragging: function () {
get _dragging() {
return this._dragState && this._dragState.dragging;
},
// dragStart: a drag was started, either by distance or by time.
_delayedDragStart: function () {
log("(dragStart)");
if (this._dragging())
if (this._dragging)
return;
if (this._dragState.dragStartTimeout != -1)
@ -888,7 +918,7 @@ WidgetStack.prototype = {
return [ioffsetx, ioffsety];
},
_viewportUpdate: function (force) {
_viewportUpdate: function _viewportUpdate(force) {
if (!this._viewport)
return;
@ -901,13 +931,12 @@ WidgetStack.prototype = {
// log2("viewportUpdate start", vws.rect.toString(), this._viewingRect.toString(), vws.originX, vws.originY);
let ioffsetx, ioffsety;
[ioffsetx, ioffsety] = this._panRegionOffsets();
let [ioffsetx, ioffsety] = this._panRegionOffsets();
// recover the amount the inner bounds moved by the amount the viewport widget moved.
// the rects are in screen space though, so we have to convert them to the virtual
// coordinate space.
if (this._dragging()) {
if (this._dragging) {
let idx = (vws.dragStartRect.x - vws.dragStartOffsets[0]) - (vws.rect.x - ioffsetx);
let idy = (vws.dragStartRect.y - vws.dragStartOffsets[1]) - (vws.rect.y - ioffsety);
@ -933,8 +962,8 @@ WidgetStack.prototype = {
}
// if we're dragging, update this so that we can call this function again
// durig the same drag and get the right values.
if (this._dragging()) {
// during the same drag and get the right values.
if (this._dragging) {
vws.dragStartOffsets = [ioffsetx, ioffsety];
vws.dragStartRect = vws.rect.clone();
}
@ -1106,7 +1135,7 @@ WidgetStack.prototype = {
return [dx, dy];
},
_panBy: function (dx, dy, ignoreBarriers) {
_panBy: function _panBy(dx, dy, ignoreBarriers) {
// initially we work in viewingRect coords, so the direction
// of the move is opposite from the direction of the pan
dx = -dx;

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

@ -79,7 +79,8 @@ var Browser = {
this._canvasBrowser = new CanvasBrowser(document.getElementById("browser-canvas"));
// initialize the WidgetStack
ws = new WidgetStack(document.getElementById("browser-container"));
let browserContainer = document.getElementById("browser-container");
ws = new WidgetStack(browserContainer);
ws.setViewportBounds({ top: 0, left: 0, right: 800, bottom: 480 });
// XXX this should live elsewhere
@ -98,11 +99,9 @@ var Browser = {
}
gSidebarVisible = visibleNow;
// deal with checkerboard
/*
// move checkerboard
let stack = document.getElementById("browser-container");
stack.style.backgroundPosition = -vr.left + "px " + -vr.top + "px";
*/
// this is really only necessary for maemo, where we don't
// always repaint fast enough
@ -111,10 +110,20 @@ var Browser = {
ws.setPanHandler(panHandler);
function resizeHandler() { ws.updateSize(); }
window.addEventListener("resize", resizeHandler, false);
function resizeHandler(e) {
if (e.target != window)
return;
setTimeout(resizeHandler, 0);
// resize our container...
let w = window.innerWidth;
let h = window.innerHeight;
let containerStyle = browserContainer.style;
containerStyle.width = containerStyle.maxWidth = w + "px";
containerStyle.height = containerStyle.maxHeight = h + "px";
ws.updateSize();
}
window.addEventListener("resize", resizeHandler, false);
function viewportHandler(b, ob) { self._canvasBrowser.viewportHandler(b, ob); }
ws.setViewportHandler(viewportHandler);
@ -231,12 +240,11 @@ var Browser = {
},
updateViewportSize: function() {
// XXX make sure this is right, and then add a better function for it.
var [w,h] = this._canvasBrowser._contentAreaDimensions;
w = Math.ceil(this._canvasBrowser._pageToScreen(w));
h = Math.ceil(this._canvasBrowser._pageToScreen(h));
var [w, h] = this._canvasBrowser._effectiveContentAreaDimensions.map(Math.ceil);
if (!this._currentViewportBounds || w != this._currentViewportBounds.width || h != this._currentViewportBounds.height) {
if (!this._currentViewportBounds ||
w != this._currentViewportBounds.width ||
h != this._currentViewportBounds.height) {
this._currentViewportBounds = {width: w, height: h};
let bounds = { top: 0, left: 0, right: Math.max(800, w), bottom: Math.max(480, h) }
//dump("setViewportBounds: " + bounds.toSource() + "\n");

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

@ -178,11 +178,11 @@
<!-- stupid stack needs to be in a box. not sure why -->
<box>
<stack id="browser-container" flex="1" style="width: 800px; height: 480px; max-width: 800px; max-height: 480px; background: lightgrey; /*background-image: url('chrome://browser/content/checkerboard.png')*/">
<stack id="browser-container" flex="1">
<!-- begin: Browser View -->
<hbox id="canvasbox"
style="-moz-stack-sizing: ignore; height: 1440px; width: 800px;"
style="-moz-stack-sizing: ignore;"
left="0" top="-480"
vptargetx="0"
vptargety="0"
@ -192,8 +192,6 @@
<html:canvas id="browser-canvas"
moz-opaque="true"
viewport="true"
style="height: 1440px; width: 800px;"
height="1440" width="800"
onnewtab="CommandUpdater.doCommand('cmd_newTab');"/>

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

@ -65,6 +65,10 @@ richlistitem {
font-size: 16.75pt !important;
}
#browser-container {
background-image: url('chrome://browser/content/checkerboard.png');
}
/* main toolbar (URL bar) -------------------------------------------------- */
#toolbar-main {
-moz-appearance: none;