+ font size for tab names now scales properly

+ tabs now return to their proper size when you pull them out of a group
+ you can now nest groups inside of other groups (though all of the funky repercussions haven't been sorted out yet)
This commit is contained in:
Ian Gilman 2010-03-31 17:24:16 -07:00
parent 34935fdee3
commit 033ae50793
8 changed files with 162 additions and 123 deletions

View File

@ -33,6 +33,7 @@ window.Group = function(listOfEls, options) {
this._children = []; // an array of Items
this._container = null;
this._padding = 30;
this.defaultSize = new Point(TabItems.tabWidth * 1.5, TabItems.tabHeight * 1.5);
var self = this;
@ -48,7 +49,6 @@ window.Group = function(listOfEls, options) {
zIndex: -100,
opacity: 0,
})
.data("group", this)
.data('item', this)
.appendTo("body")
.animate({opacity:1.0}).dequeue();
@ -112,7 +112,7 @@ window.Group = function(listOfEls, options) {
};
// ----------
window.Group.prototype = $.extend(new Item(), {
window.Group.prototype = $.extend(new Item(), new Subscribable(), {
// ----------
_getBoundingBox: function(els) {
var el;
@ -160,7 +160,14 @@ window.Group.prototype = $.extend(new Item(), {
// ----------
setBounds: function(rect, immediately) {
this.setPosition(rect.left, rect.top, immediately);
this.setSize(rect.width, rect.height, immediately);
this.setSize(rect.width, rect.height, immediately, {dontArrange: true});
var $titlebar = $('.titlebar', this._container);
var titleHeight = $titlebar.height();
var box = new Rect(rect);
box.top += titleHeight;
box.height -= titleHeight;
this.arrange({animate: !immediately, bounds: box});
},
// ----------
@ -178,11 +185,14 @@ window.Group.prototype = $.extend(new Item(), {
if(immediately)
$(this._container).css(options);
else
$(this._container).animate(options);
$(this._container).animate(options).dequeue();
},
// ----------
setSize: function(width, height, immediately) {
setSize: function(width, height, immediately, options) {
if(typeof(options) == 'undefined')
options = {};
var $titlebar = $('.titlebar', this._container);
var titleHeight = $titlebar.height();
@ -192,11 +202,18 @@ window.Group.prototype = $.extend(new Item(), {
$(this._container).css(containerOptions);
$titlebar.css(titleOptions);
} else {
$(this._container).animate(containerOptions);
$titlebar.animate(titleOptions);
$(this._container).animate(containerOptions).dequeue();
$titlebar.animate(titleOptions).dequeue();
}
if(!options.dontArrange) {
//TODO sort out the bounds and titlebar stuff for real
var box = this.getBounds();
box.width = width;
box.top += titleHeight;
box.height = height - titleHeight;
this.arrange({animate: !immediately, bounds: box});
}
this.arrange({animate: !immediately});
},
// ----------
@ -205,16 +222,8 @@ window.Group.prototype = $.extend(new Item(), {
$.each(toClose, function(index, child) {
child.close();
});
},
// ----------
addOnClose: function(referenceObject, callback) {
Utils.error('Group.addOnClose not implemented');
},
// ----------
removeOnClose: function(referenceObject) {
Utils.error('Group.removeOnClose not implemented');
this._sendOnClose();
},
// ----------
@ -301,7 +310,7 @@ window.Group.prototype = $.extend(new Item(), {
this._children.splice(index, 1);
$el.data("group", null);
scaleTab( $el, 160/$el.width());
item.setSize(item.defaultSize.x, item.defaultSize.y);
$el.droppable("enable");
item.removeOnClose(this);
@ -325,13 +334,16 @@ window.Group.prototype = $.extend(new Item(), {
},
// ----------
arrange: function(options){
if( options && options.animate == false ) animate = false;
else animate = true;
arrange: function(options) {
if( options && options.animate == false )
animate = false;
else
animate = true;
if(typeof(options) == 'undefined')
options = {};
//Utils.log(speed);
/*if( this._children.length < 2 ) return;*/
var bb = this._getContainerBox();
var bb = (options.bounds ? options.bounds : this._getContainerBox());
var count = this._children.length;
var bbAspect = bb.width/bb.height;
@ -369,14 +381,12 @@ window.Group.prototype = $.extend(new Item(), {
var x = pad; var y=pad; var numInCol = 0;
for each(var item in this._children){
var sizeOptions = {width:tabW, height:tabH, top:y+bb.top, left:x+bb.left};
if( animate ) $(item.getContainer()).animate(sizeOptions).dequeue();
else $(item.getContainer()).css(sizeOptions).dequeue();
item.setBounds(new Rect(x + bb.left, y + bb.top, tabW, tabH), !animate);
x += tabW + pad;
numInCol += 1;
if( numInCol >= best.numCols ) [x, numInCol, y] = [pad, 0, y+tabH+pad];
if( numInCol >= best.numCols )
[x, numInCol, y] = [pad, 0, y+tabH+pad];
}
},
@ -386,6 +396,7 @@ window.Group.prototype = $.extend(new Item(), {
$(container).draggable({
start: function(){
$dragged = $(this);
$(container).data("origPosition", $(container).position());
$.each(self._children, function(index, child) {
child.dragData = {startBounds: child.getBounds()};
@ -400,10 +411,17 @@ window.Group.prototype = $.extend(new Item(), {
child.dragData.startBounds.top + dY,
true);
});
/* $(this).css({zIndex: zIndex}); */
/* zIndex += 1; */
},
stop: function() {
self.pushAway();
}
if(!$dragged.hasClass('willGroup') && !$dragged.data('group'))
Items.item(this).pushAway();
$dragged = null;
},
/* zIndex: 999 */
});
$(container).droppable({
@ -420,7 +438,7 @@ window.Group.prototype = $.extend(new Item(), {
$dragged.removeClass("willGroup");
self.add( $dragged, {left:event.pageX, top:event.pageY} )
},
accept: ".tab",
accept: ".tab, .group",
});
$(container).resizable({
@ -563,20 +581,8 @@ window.Groups = {
};
// ##########
function scaleTab( el, factor ){
var $el = $(el);
$el.animate({
width: $el.width()*factor,
height: $el.height()*factor,
fontSize: parseInt($el.css("fontSize"))*factor,
},250).dequeue();
}
$(".tab").data('isDragging', false)
.draggable(window.Groups.dragOptions)
.droppable(window.Groups.dropOptions);
})();

View File

@ -9,7 +9,10 @@
// addOnClose: function(referenceObject, callback)
// removeOnClose: function(referenceObject)
//
// In addition, it must have a property, isAnItem, set to true.
// In addition, it must have these properties:
// isAnItem, set to true (set by Item)
// defaultSize, a Point
//
// Its container must also have a jQuery data named 'item' that points to the item.
window.Item = function() {
@ -94,14 +97,10 @@ window.Items = {
getTopLevelItems: function() {
var items = [];
$('.tab').each(function() {
$('.tab, .group').each(function() {
$this = $(this);
if(!$this.data('group'))
items.push($this.data('tabItem'));
});
$('.group').each(function() {
items.push($(this).data('group'));
items.push($this.data('item'));
});
return items;

View File

@ -3,6 +3,8 @@ window.TabItem = function(container, tab) {
this.container = container;
this.tab = tab;
this.defaultSize = new Point(TabItems.tabWidth, TabItems.tabHeight);
$(this.container).data('item', this);
};
@ -19,32 +21,22 @@ window.TabItem.prototype = $.extend(new Item(), {
// ----------
setBounds: function(rect, immediately) {
this.setPosition(rect.left, rect.top, immediately);
this.setSize(rect.width, rect.height, immediately);
var css = $.extend(this._getSizeCSS(rect.width, rect.height), {
left: rect.left,
top: rect.top,
});
this._change(css, immediately);
},
// ----------
setPosition: function(left, top, immediately) {
if(immediately)
$(this.container).css({left: left, top: top});
else {
TabMirror.pausePainting();
$(this.container).animate({left: left, top: top}, {complete: function() {
TabMirror.resumePainting();
}});
}
this._change({left: left, top: top}, immediately);
},
// ----------
setSize: function(width, height, immediately) {
if(immediately)
$(this.container).css({width: width, height: height});
else {
TabMirror.pausePainting();
$(this.container).animate({width: width, height: height}, {complete: function() {
TabMirror.resumePainting();
}});
}
this._change(this._getSizeCSS(width, height), immediately);
},
// ----------
@ -60,17 +52,45 @@ window.TabItem.prototype = $.extend(new Item(), {
// ----------
removeOnClose: function(referenceObject) {
this.tab.mirror.removeOnClose(referenceObject);
},
// ----------
_getSizeCSS: function(width, height) {
var scale = width / TabItems.tabWidth;
return {
width: width,
height: height,
fontSize: TabItems.fontSize * scale
};
},
// ----------
_change: function(css, immediately) {
if(immediately)
$(this.container).css(css);
else {
TabMirror.pausePainting();
$(this.container).animate(css, {complete: function() {
TabMirror.resumePainting();
}}).dequeue();
}
}
});
// ##########
window.TabItems = {
tabWidth: 160,
tabHeight: 137,
fontSize: 9,
init: function() {
var self = this;
function mod($div){
Utils.log('mod');
if(window.Groups) {
$div.data('isDragging', false);
$div.draggable(window.Groups.dragOptions);
$div.droppable(window.Groups.dropOptions);
}

View File

@ -21,10 +21,8 @@ var Tabbar = {
// ##########
window.Page = {
startX: 30,
startY: 70,
tabWidth: 160,
tabHeight: 137,
startY: 70,
init: function() {
Utils.homeTab.raw.maxWidth = 60;
Utils.homeTab.raw.minWidth = 60;
@ -181,7 +179,7 @@ var grid = new ArrangeClass("Grid", function(value) {
if(typeof(value) == 'boolean')
immediately = value;
var box = new Rect(Page.startX, Page.startY, Page.tabWidth, Page.tabHeight);
var box = new Rect(Page.startX, Page.startY, TabItems.tabWidth, TabItems.tabHeight);
$(".tab:visible").each(function(i){
var item = Items.item(this);
item.setBounds(box, immediately);

View File

@ -104,7 +104,7 @@ TabCanvas.prototype = {
}
}
// ----------
// ##########
function Mirror(tab, manager) {
this.tab = tab;
this.manager = manager;
@ -124,7 +124,6 @@ function Mirror(tab, manager) {
this.favEl = $('.fav', div).get(0);
this.nameEl = $('.name', div).get(0);
this.canvasEl = $('.thumb', div).get(0);
this.onCloseSubscribers = [];
var doc = this.tab.contentDocument;
if( !_isIframe(doc) ) {
@ -134,52 +133,29 @@ function Mirror(tab, manager) {
}
}
Mirror.prototype.triggerPaint = function() {
var date = new Date();
this.needsPaint = date.getTime();
};
Mirror.prototype.forceCanvasSize = function(w, h) {
this.canvasSizeForced = true;
var $canvas = $(this.canvasEl);
$canvas.attr('width', w);
$canvas.attr('height', h);
this.tabCanvas.paint();
};
Mirror.prototype.unforceCanvasSize = function() {
this.canvasSizeForced = false;
};
Mirror.prototype.addOnClose = function(referenceElement, callback) {
var existing = jQuery.grep(this.onCloseSubscribers, function(element) {
return element.referenceElement == referenceElement;
});
Mirror.prototype = $.extend(new Subscribable(), {
// ----------
triggerPaint: function() {
var date = new Date();
this.needsPaint = date.getTime();
},
if(existing.size) {
Utils.assert('should only ever be one', existing.size == 1);
existing[0].callback = callback;
} else {
this.onCloseSubscribers.push({
referenceElement: referenceElement,
callback: callback
});
// ----------
forceCanvasSize: function(w, h) {
this.canvasSizeForced = true;
var $canvas = $(this.canvasEl);
$canvas.attr('width', w);
$canvas.attr('height', h);
this.tabCanvas.paint();
},
// ----------
unforceCanvasSize: function() {
this.canvasSizeForced = false;
}
};
});
Mirror.prototype.removeOnClose = function(referenceElement) {
this.onCloseSubscribers = jQuery.grep(this.onCloseSubscribers, function(element) {
return element.referenceElement == referenceElement;
}, true);
};
Mirror.prototype._sendOnClose = function() {
jQuery.each(this.onCloseSubscribers, function(index, object) {
object.callback(this);
});
};
// ----------
// ##########
var TabMirror = function( ){ this.init() }
TabMirror.prototype = {
init: function(){

View File

@ -106,6 +106,45 @@ window.Rect.prototype = {
}
};
// ##########
// TODO generalize for any number of events
window.Subscribable = function() {
this.onCloseSubscribers = [];
};
window.Subscribable.prototype = {
// ----------
addOnClose: function(referenceElement, callback) {
var existing = jQuery.grep(this.onCloseSubscribers, function(element) {
return element.referenceElement == referenceElement;
});
if(existing.size) {
Utils.assert('should only ever be one', existing.size == 1);
existing[0].callback = callback;
} else {
this.onCloseSubscribers.push({
referenceElement: referenceElement,
callback: callback
});
}
},
// ----------
removeOnClose: function(referenceElement) {
this.onCloseSubscribers = jQuery.grep(this.onCloseSubscribers, function(element) {
return element.referenceElement == referenceElement;
}, true);
},
// ----------
_sendOnClose: function() {
jQuery.each(this.onCloseSubscribers, function(index, object) {
object.callback(this);
});
}
};
// ##########
var Utils = {
// ___ Windows and Tabs

View File

@ -3,6 +3,7 @@
}
.willGroup{
border: 1px inset rgba(255,0,0,1);
-moz-box-shadow: 0px 0px 10px rgba(255,0,0,1);
}
@ -30,7 +31,7 @@ input.name{
/* Resizable
----------------------------------*/
.resizer{
background-image: url(chrome://tabcandy/content/img/shared/resizer.png);
background-image: url(../img/resizer.png);
}
.ui-resizable { position: relative;}

View File

@ -15,6 +15,7 @@
}
.tab{
font-size: 9px;
position: absolute;
display: block;
float:left;
@ -49,7 +50,6 @@
}
.name{
font-size: 9px;
display:block;
width:160px;
white-space: nowrap;