- Author:
- David Nickerson <david.nickerson@gmail.com>
- Date:
- 2021-09-17 15:50:49+12:00
- Desc:
- tweak html formatting
- Permanent Source URI:
- https://models.fieldml.org/workspace/a1/rawfile/1b3862589abf79ae9119ee0b5e99a8b785d762e1/dojo-presentation/js/dojo/dojox/grid/_ViewManager.js
dojo.provide("dojox.grid._ViewManager");
dojo.declare('dojox.grid._ViewManager', null, {
// summary:
// A collection of grid views. Owned by grid and used internally for managing grid views.
// description:
// Grid creates views automatically based on grid's layout structure.
// Users should typically not need to access individual views or the views collection directly.
constructor: function(inGrid){
this.grid = inGrid;
},
defaultWidth: 200,
views: [],
// operations
resize: function(){
this.onEach("resize");
},
render: function(){
this.onEach("render");
},
// views
addView: function(inView){
inView.idx = this.views.length;
this.views.push(inView);
},
destroyViews: function(){
for(var i=0, v; v=this.views[i]; i++){
v.destroy();
}
this.views = [];
},
getContentNodes: function(){
var nodes = [];
for(var i=0, v; v=this.views[i]; i++){
nodes.push(v.contentNode);
}
return nodes;
},
forEach: function(inCallback){
for(var i=0, v; v=this.views[i]; i++){
inCallback(v, i);
}
},
onEach: function(inMethod, inArgs){
inArgs = inArgs || [];
for(var i=0, v; v=this.views[i]; i++){
if(inMethod in v){
v[inMethod].apply(v, inArgs);
}
}
},
// layout
normalizeHeaderNodeHeight: function(){
var rowNodes = [];
for(var i=0, v; (v=this.views[i]); i++){
if(v.headerContentNode.firstChild){
rowNodes.push(v.headerContentNode);
}
}
this.normalizeRowNodeHeights(rowNodes);
},
normalizeRowNodeHeights: function(inRowNodes){
var h = 0;
for(var i=0, n, o; (n=inRowNodes[i]); i++){
h = Math.max(h, dojo.marginBox(n.firstChild).h);
}
h = (h >= 0 ? h : 0);
//
//
for(var i=0, n; (n=inRowNodes[i]); i++){
dojo.marginBox(n.firstChild, {h:h});
}
//
//console.log('normalizeRowNodeHeights ', h);
//
// querying the height here seems to help scroller measure the page on IE
if(inRowNodes&&inRowNodes[0]){
inRowNodes[0].parentNode.offsetHeight;
}
},
resetHeaderNodeHeight: function(){
for(var i=0, v, n; (v=this.views[i]); i++){
n = v.headerContentNode.firstChild;
if(n){
n.style.height = "";
}
}
},
renormalizeRow: function(inRowIndex){
var rowNodes = [];
for(var i=0, v, n; (v=this.views[i])&&(n=v.getRowNode(inRowIndex)); i++){
n.firstChild.style.height = '';
rowNodes.push(n);
}
this.normalizeRowNodeHeights(rowNodes);
},
getViewWidth: function(inIndex){
return this.views[inIndex].getWidth() || this.defaultWidth;
},
// must be called after view widths are properly set or height can be miscalculated
// if there are flex columns
measureHeader: function(){
// need to reset view header heights so they are properly measured.
this.resetHeaderNodeHeight();
this.forEach(function(inView){
inView.headerContentNode.style.height = '';
});
var h = 0;
// calculate maximum view header height
this.forEach(function(inView){
h = Math.max(inView.headerNode.offsetHeight, h);
});
return h;
},
measureContent: function(){
var h = 0;
this.forEach(function(inView){
h = Math.max(inView.domNode.offsetHeight, h);
});
return h;
},
findClient: function(inAutoWidth){
// try to use user defined client
var c = this.grid.elasticView || -1;
// attempt to find implicit client
if(c < 0){
for(var i=1, v; (v=this.views[i]); i++){
if(v.viewWidth){
for(i=1; (v=this.views[i]); i++){
if(!v.viewWidth){
c = i;
break;
}
}
break;
}
}
}
// client is in the middle by default
if(c < 0){
c = Math.floor(this.views.length / 2);
}
return c;
},
arrange: function(l, w){
var i, v, vw, len = this.views.length;
// find the client
var c = (w <= 0 ? len : this.findClient());
// layout views
var setPosition = function(v, l){
var ds = v.domNode.style;
var hs = v.headerNode.style;
if(!dojo._isBodyLtr()){
ds.right = l + 'px';
hs.right = l + 'px';
}else{
ds.left = l + 'px';
hs.left = l + 'px';
}
ds.top = 0 + 'px';
hs.top = 0;
}
// for views left of the client
//BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with
//leading and tailing concept.
for(i=0; (v=this.views[i])&&(i<c); i++){
// get width
vw = this.getViewWidth(i);
// process boxes
v.setSize(vw, 0);
setPosition(v, l);
if(v.headerContentNode && v.headerContentNode.firstChild){
vw = v.getColumnsWidth()+v.getScrollbarWidth();
}else{
vw = v.domNode.offsetWidth;
}
// update position
l += vw;
}
// next view (is the client, i++ == c)
i++;
// start from the right edge
var r = w;
// for views right of the client (iterated from the right)
for(var j=len-1; (v=this.views[j])&&(i<=j); j--){
// get width
vw = this.getViewWidth(j);
// set size
v.setSize(vw, 0);
// measure in pixels
vw = v.domNode.offsetWidth;
// update position
r -= vw;
// set position
setPosition(v, r);
}
if(c<len){
v = this.views[c];
// position the client box between left and right boxes
vw = Math.max(1, r-l);
// set size
v.setSize(vw + 'px', 0);
setPosition(v, l);
}
return l;
},
// rendering
renderRow: function(inRowIndex, inNodes){
var rowNodes = [];
for(var i=0, v, n, rowNode; (v=this.views[i])&&(n=inNodes[i]); i++){
rowNode = v.renderRow(inRowIndex);
n.appendChild(rowNode);
rowNodes.push(rowNode);
}
this.normalizeRowNodeHeights(rowNodes);
},
rowRemoved: function(inRowIndex){
this.onEach("rowRemoved", [ inRowIndex ]);
},
// updating
updateRow: function(inRowIndex, inHeight){
for(var i=0, v; v=this.views[i]; i++){
v.updateRow(inRowIndex, inHeight);
}
this.renormalizeRow(inRowIndex);
},
updateRowStyles: function(inRowIndex){
this.onEach("updateRowStyles", [ inRowIndex ]);
},
// scrolling
setScrollTop: function(inTop){
var top = inTop;
for(var i=0, v; v=this.views[i]; i++){
top = v.setScrollTop(inTop);
}
return top;
//this.onEach("setScrollTop", [ inTop ]);
},
getFirstScrollingView: function(){
// summary: Returns the first grid view with a scroll bar
for(var i=0, v; (v=this.views[i]); i++){
if(v.hasHScrollbar() || v.hasVScrollbar()){
return v;
}
}
}
});