All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dojo.dojox.grid._grid.scroller.js Maven / Gradle / Ivy

The newest version!
if(!dojo._hasResource['dojox.grid._grid.scroller']){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource['dojox.grid._grid.scroller'] = true;
dojo.provide('dojox.grid._grid.scroller');

dojo.declare('dojox.grid.scroller.base', null, {
	// summary:
	//	virtual scrollbox, abstract class
	//	Content must in /rows/
	//	Rows are managed in contiguous sets called /pages/
	//	There are a fixed # of rows per page
	//	The minimum rendered unit is a page
	constructor: function(){
		this.pageHeights = [];
		this.stack = [];
	},
	// specified
	rowCount: 0, // total number of rows to manage
	defaultRowHeight: 10, // default height of a row
	keepRows: 100, // maximum number of rows that should exist at one time
	contentNode: null, // node to contain pages
	scrollboxNode: null, // node that controls scrolling
	// calculated
	defaultPageHeight: 0, // default height of a page
	keepPages: 10, // maximum number of pages that should exists at one time
	pageCount: 0,
	windowHeight: 0,
	firstVisibleRow: 0,
	lastVisibleRow: 0,
	// private
	page: 0,
	pageTop: 0,
	// init
	init: function(inRowCount, inKeepRows, inRowsPerPage){
		switch(arguments.length){
			case 3: this.rowsPerPage = inRowsPerPage;
			case 2: this.keepRows = inKeepRows;
			case 1: this.rowCount = inRowCount;
		}
		this.defaultPageHeight = this.defaultRowHeight * this.rowsPerPage;
		//this.defaultPageHeight = this.defaultRowHeight * Math.min(this.rowsPerPage, this.rowCount);
		this.pageCount = Math.ceil(this.rowCount / this.rowsPerPage);
		this.keepPages = Math.max(Math.ceil(this.keepRows / this.rowsPerPage), 2);
		this.invalidate();
		if(this.scrollboxNode){
			this.scrollboxNode.scrollTop = 0;
			this.scroll(0);
			this.scrollboxNode.onscroll = dojo.hitch(this, 'onscroll');
		}
	},
	// updating
	invalidate: function(){
		this.invalidateNodes();
		this.pageHeights = [];
		this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0);
		this.resize();
	},
	updateRowCount: function(inRowCount){
		this.invalidateNodes();
		this.rowCount = inRowCount;
		// update page count, adjust document height
		oldPageCount = this.pageCount;
		this.pageCount = Math.ceil(this.rowCount / this.rowsPerPage);
		if(this.pageCount < oldPageCount){
			for(var i=oldPageCount-1; i>=this.pageCount; i--){
				this.height -= this.getPageHeight(i);
				delete this.pageHeights[i]
			}
		}else if(this.pageCount > oldPageCount){
			this.height += this.defaultPageHeight * (this.pageCount - oldPageCount - 1) + this.calcLastPageHeight();
		}
		this.resize();
	},
	// abstract interface
	pageExists: function(inPageIndex){
	},
	measurePage: function(inPageIndex){
	},
	positionPage: function(inPageIndex, inPos){
	},
	repositionPages: function(inPageIndex){
	},
	installPage: function(inPageIndex){
	},
	preparePage: function(inPageIndex, inPos, inReuseNode){
	},
	renderPage: function(inPageIndex){
	},
	removePage: function(inPageIndex){
	},
	pacify: function(inShouldPacify){
	},
	// pacification
	pacifying: false,
	pacifyTicks: 200,
	setPacifying: function(inPacifying){
		if(this.pacifying != inPacifying){
			this.pacifying = inPacifying;
			this.pacify(this.pacifying);
		}
	},
	startPacify: function(){
		this.startPacifyTicks = new Date().getTime();
	},
	doPacify: function(){
		var result = (new Date().getTime() - this.startPacifyTicks) > this.pacifyTicks;
		this.setPacifying(true);
		this.startPacify();
		return result;
	},
	endPacify: function(){
		this.setPacifying(false);
	},
	// default sizing implementation
	resize: function(){
		if(this.scrollboxNode){
			this.windowHeight = this.scrollboxNode.clientHeight;
		}
		dojox.grid.setStyleHeightPx(this.contentNode, this.height);
	},
	calcLastPageHeight: function(){
		if(!this.pageCount){
			return 0;
		}
		var lastPage = this.pageCount - 1;
		var lastPageHeight = ((this.rowCount % this.rowsPerPage)||(this.rowsPerPage)) * this.defaultRowHeight;
		this.pageHeights[lastPage] = lastPageHeight;
		return lastPageHeight;
	},
	updateContentHeight: function(inDh){
		this.height += inDh;
		this.resize();
	},
	updatePageHeight: function(inPageIndex){
		if(this.pageExists(inPageIndex)){
			var oh = this.getPageHeight(inPageIndex);
			var h = (this.measurePage(inPageIndex))||(oh);
			this.pageHeights[inPageIndex] = h;
			if((h)&&(oh != h)){
				this.updateContentHeight(h - oh)
				this.repositionPages(inPageIndex);
			}
		}
	},
	rowHeightChanged: function(inRowIndex){
		this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage));
	},
	// scroller core
	invalidateNodes: function(){
		while(this.stack.length){
			this.destroyPage(this.popPage());
		}
	},
	createPageNode: function(){
		var p = document.createElement('div');
		p.style.position = 'absolute';
		//p.style.width = '100%';
		p.style.left = '0';
		return p;
	},
	getPageHeight: function(inPageIndex){
		var ph = this.pageHeights[inPageIndex];
		return (ph !== undefined ? ph : this.defaultPageHeight);
	},
	// FIXME: this is not a stack, it's a FIFO list
	pushPage: function(inPageIndex){
		return this.stack.push(inPageIndex);
	},
	popPage: function(){
		return this.stack.shift();
	},
	findPage: function(inTop){
		var i = 0, h = 0;
		for(var ph = 0; i= inTop){
				break;
			}
		}
		this.page = i;
		this.pageTop = h;
	},
	buildPage: function(inPageIndex, inReuseNode, inPos){
		this.preparePage(inPageIndex, inReuseNode);
		this.positionPage(inPageIndex, inPos);
		// order of operations is key below
		this.installPage(inPageIndex);
		this.renderPage(inPageIndex);
		// order of operations is key above
		this.pushPage(inPageIndex);
	},
	needPage: function(inPageIndex, inPos){
		var h = this.getPageHeight(inPageIndex), oh = h;
		if(!this.pageExists(inPageIndex)){
			this.buildPage(inPageIndex, (this.keepPages)&&(this.stack.length >= this.keepPages), inPos);
			h = this.measurePage(inPageIndex) || h;
			this.pageHeights[inPageIndex] = h;
			if(h && (oh != h)){
				this.updateContentHeight(h - oh)
			}
		}else{
			this.positionPage(inPageIndex, inPos);
		}
		return h;
	},
	onscroll: function(){
		this.scroll(this.scrollboxNode.scrollTop);
	},
	scroll: function(inTop){
		this.startPacify();
		this.findPage(inTop);
		var h = this.height;
		var b = this.getScrollBottom(inTop);
		for(var p=this.page, y=this.pageTop; (p= 0 ? inTop + this.windowHeight : -1);
	},
	// events
	processNodeEvent: function(e, inNode){
		var t = e.target;
		while(t && (t != inNode) && t.parentNode && (t.parentNode.parentNode != inNode)){
			t = t.parentNode;
		}
		if(!t || !t.parentNode || (t.parentNode.parentNode != inNode)){
			return false;
		}
		var page = t.parentNode;
		e.topRowIndex = page.pageIndex * this.rowsPerPage;
		e.rowIndex = e.topRowIndex + dojox.grid.indexInParent(t);
		e.rowTarget = t;
		return true;
	},
	processEvent: function(e){
		return this.processNodeEvent(e, this.contentNode);
	},
	dummy: 0
});

dojo.declare('dojox.grid.scroller', dojox.grid.scroller.base, {
	// summary:
	//	virtual scroller class, makes no assumption about shape of items being scrolled
	constructor: function(){
		this.pageNodes = [];
	},
	// virtual rendering interface
	renderRow: function(inRowIndex, inPageNode){
	},
	removeRow: function(inRowIndex){
	},
	// page node operations
	getDefaultNodes: function(){
		return this.pageNodes;
	},
	getDefaultPageNode: function(inPageIndex){
		return this.getDefaultNodes()[inPageIndex];
	},
	positionPageNode: function(inNode, inPos){
		inNode.style.top = inPos + 'px';
	},
	getPageNodePosition: function(inNode){
		return inNode.offsetTop;
	},
	repositionPageNodes: function(inPageIndex, inNodes){
		var last = 0;
		for(var i=0; i=0 && inBottom>inScrollBottom; i--, row--){
			inBottom -= rows[i].offsetHeight;
		}
		return row + 1;
	},
	getLastVisibleRow: function(inPage, inBottom, inScrollBottom){
		if(!this.pageExists(inPage)){
			return 0;
		}
		return this.getLastVisibleRowNodes(inPage, inBottom, inScrollBottom, this.getDefaultNodes());
	},
	findTopRowForNodes: function(inScrollTop, inNodes){
		var rows = dojox.grid.divkids(inNodes[this.page]);
		for(var i=0,l=rows.length,t=this.pageTop,h; i= inScrollTop){
				this.offset = h - (t - inScrollTop);
				return i + this.page * this.rowsPerPage;
			}
		}
		return -1;
	},
	findScrollTopForNodes: function(inRow, inNodes){
		var rowPage = Math.floor(inRow / this.rowsPerPage);
		var t = 0;
		for(var i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy