mediawiki-extensions-Visual.../modules/ve/ui/layouts/ve.ui.GridLayout.js
Timo Tijhof 4e64187beb Document and clean up events in all the things
* Document them consistently between secetions Inheritance and
  Static Properties under their own (new) section Events.
* Removed any quotes or brackets around the event name in existing
  @emit annotations
  Search: @emit.*['"{}(){}]
* For every call to this.emit() anywhere, added @emits.
* Fixed all warnings for references to undefined events
  (introduced as a result of the previous point).
  Event handler parameter documented based on the emit() call
  and actual handlers using the event. Usually the latter is
  more elaborate.
* Extend coverage of jQuery as needed
  (copied from mwcore/maintenance/jsduck/external.js
  written by me, hereby implicitly and explicitly released under MIT).

Specifics
* ve.ce.Surface#onContentChange: Fixed type of range from Object to ve.Range.
* ve.ce.SurfaceObserver#poll: Fix syntax for code from {} to `backticks`.
* ve.ui.Toolbar#onContextChange: Doesn't actually emit "clearState" event.
  Removed #onClearState in Tool, ButtonTool and DropdownTool.

Bug: 45872
Change-Id: Id879aa769b2c72d86a0322e75dddeb868211ce28
2013-03-20 09:58:27 -07:00

162 lines
3.3 KiB
JavaScript

/*!
* VisualEditor UserInterface GridLayout class.
*
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* Grid layout.
*
* @class
* @extends ve.ui.Layout
*
* @constructor
* @param {ve.ui.PanelLayout[]} panels Panels in the grid
* @param {Object} [config] Config options
* @cfg {number[]} [widths] Widths of columns as ratios
* @cfg {number[]} [heights] Heights of columns as ratios
*/
ve.ui.GridLayout = function VeUiGridLayout( panels, config ) {
var i, len, widths;
// Config initialization
config = config || {};
// Parent constructor
ve.ui.Layout.call( this, config );
// Properties
this.panels = [];
this.widths = [];
this.heights = [];
// Initialization
this.$.addClass( 've-ui-gridLayout' );
for ( i = 0, len = panels.length; i < len; i++ ) {
this.panels.push( panels[i] );
this.$.append( panels[i].$ );
}
if ( config.widths || config.heights ) {
this.layout( config.widths || [1], config.heights || [1] );
} else {
// Arrange in columns by default
widths = [];
for ( i = 0, len = this.panels.length; i < len; i++ ) {
widths[i] = 1;
}
this.layout( widths, [1] );
}
};
/* Inheritance */
ve.inheritClass( ve.ui.GridLayout, ve.ui.Layout );
/* Events */
/**
* @event layout
*/
/**
* @event update
*/
/* Static Properties */
ve.ui.GridLayout.static.tagName = 'div';
/* Methods */
/**
* Set grid dimensions.
*
* @method
* @param {number[]} widths Widths of columns as ratios
* @param {number[]} heights Heights of rows as ratios
* @throws {Error} If grid is not large enough to fit all panels
* @emits layout
*/
ve.ui.GridLayout.prototype.layout = function ( widths, heights ) {
var x, y,
xd = 0,
yd = 0,
cols = widths.length,
rows = heights.length;
// Verify grid is big enough to fit panels
if ( cols * rows < this.panels.length ) {
throw new Error( 'Grid is not large enough to fit ' + this.panels.length + 'panels' );
}
// Sum up denominators
for ( x = 0; x < cols; x++ ) {
xd += widths[x];
}
for ( y = 0; y < rows; y++ ) {
yd += heights[y];
}
// Store factors
this.widths = [];
this.heights = [];
for ( x = 0; x < cols; x++ ) {
this.widths[x] = widths[x] / xd;
}
for ( y = 0; y < rows; y++ ) {
this.heights[y] = heights[y] / yd;
}
// Synchronize view
this.update();
this.emit( 'layout' );
};
/**
* Update panel positions and sizes.
*
* @method
* @emits update
*/
ve.ui.GridLayout.prototype.update = function () {
var x, y, panel,
i = 0,
left = 0,
top = 0,
width = 0,
height = 0,
cols = this.widths.length,
rows = this.heights.length;
for ( y = 0; y < rows; y++ ) {
for ( x = 0; x < cols; x++ ) {
panel = this.panels[i];
width = this.widths[x];
height = this.heights[y];
panel.$.css( {
'width': Math.round( width * 100 ) + '%',
'height': Math.round( height * 100 ) + '%',
'left': Math.round( left * 100 ) + '%',
'top': Math.round( top * 100 ) + '%'
} );
i++;
left += width;
}
top += height;
left = 0;
}
this.emit( 'update' );
};
/**
* Get a panel at a given position.
*
* The x and y position is affected by the current grid layout.
*
* @method
* @param {number} x Horizontal position
* @param {number} y Vertical position
*/
ve.ui.GridLayout.prototype.getPanel = function ( x, y ) {
return this.panels[( x * this.widths.length ) + y];
};