Monday, July 5, 2010

View Tab : The Implementation - Part 2

This post is the continuation of View Tab : The Implementation - Part 1

The next line of code in viewTab.js ensures that the preview thumbnail (PT) is created only if aTab is not the active tab (only if VIEWTAB_NOPREV_SELECTED is set to true).
if(aTab!=gBrowser.selectedTab && VIEWTAB_NOPREV_SELECTED){

Next, we get the extract the browser window for which the PT is to be created.

//Get the browser's content window
var prevWin=aTab.linkedBrowser.contentWindow;
var prevWinWidth=prevWin.innerWidth;
var prevWinHeight=prevWin.innerHeight;

The linkedBrowser property of a tab, aTab in this case, returns the browser associated with the tab, and the contentWindow property of a browser returns the window element in the browser. Thus, prevWin is now set to the window for which the PT is to be created, and prevWinWidth and prevWinHeight to its width and height respectively.

The PT, however does not show the entire window, instead it only shows a portion of the window, whose dimensions are determined as follows,

//Define the region to snip
var snipHeight=Math.round
(prevWinHeight*VIEWTAB_SNIP_RATIO);
var snipWidth=Math.round
(snipHeight*VIEWTAB_ASPECT_RATIO);

The height of the portion to be shown, the snip, is VIEWTAB_SNIP_RATIO times the actual height of the window, and the width is calculated so as to maintain the aspect ratio. I chose to set the height first and not width because many widths go well with the same height (especially considering the fact that may different screen ratios: 4:3, 5:4, 16:9 etc. are currently in use, and that sometimes users choose to split their screens width-wise to display two windows side by side while maintaining their original heights). All in all, experimenting with this revealed that setting the height first leads to better results, and so it's been done this way.

The next block of code is where the actual business begins, in setting up an HTML canvas to display prevWindow (a portion of it, actually) in the PT.

//Define and prepare the canvas for Drawing
var prevCanvas = document.createElementNS
("http://www.w3.org/1999/xhtml","canvas");
var canHeight = Math.ceil
(screen.availHeight*VIEWTAB_SIZE_RATIO);
var canWidth = Math.ceil
(canHeight*VIEWTAB_ASPECT_RATIO);
prevCanvas.id="viewTabCanvas";
prevCanvas.width=canWidth;
prevCanvas.height=canHeight;

prevCanvas is set to a new empty HTML canvas. A canvas can be used to draw and animate objects, including windows, which is what is being done here. A tutorial on the usage of the canvas element can be found here. I found some code that was useful for View Tab here. This is really the best thing about Mozilla, everything is so well documented. Its not just the reference, there are so many tutorials, examples and code snippets, that make it really easy to follow along and get a hang of things.

Moving on, prevCanvas is given the id "viewTabCanvas", its height is set to VIEWTAB_SIZE_RATIO times the screen height, and width, of course, is set to VIEWTAB_ASPECT_RATIO times the height.

Next, the drawing context of prevCanvas is extracted, and the canvas is cleared for drawing.

//Get the drawing context
var ctx=prevCanvas.getContext("2d");
ctx.clearRect(0,0,canWidth,canHeight);
ctx.save();

The drawing context is used to actually draw on the canvas. More on the drawing context here. The clearRect method clears the canvas, and the save method saves the current state of ctx.

//Decide whether preview window should
//scroll to the current position or not
var initX=0;
var initY=0;

if(VIEWTAB_SCROLL_PREV){
initX=prevWin.scrollX;
initY=prevWin.scrollY;
}

Then, depending on the value of VIEWTAB_SCROLL_PREV, the coordinates on the window from where we are to begin drawing, are decided. If VIEWTAB_SCROLL_PREV is set to true, then the preview in the thumbnail is scrolled by the same amount to which the actual window is scrolled, otherwise, the top-left portion of the page is drawn, even if it is scrolled to a different position.

The next block of code actually draws the window.
//Draw The window in the canvas
ctx.scale(canWidth/snipWidth,canHeight/snipHeight);
ctx.drawWindow(prevWin,initX,initY,
snipWidth,snipHeight,"rgb(255,255,255)");
ctx.restore();
ctx.scale scales whatever is drawn next by the given ratios along the x and y directions. This line of code is responsible for shrinking the preview so it fits in the PT. Next, ctx.drawWindow draws a portion of prevWindow, whose starting coordinates, followed by its width and height, are passed as parameters to the function. The last parameter "rgb(255,255,255)", which corresponds to the color white, sets the background. ctx.restore() restores the previously saved state of ctx.

With this, we are done with creating a preview canvas, and all that's left to do is make sure it shows up at the right place. More in the next post.

No comments:

Post a Comment