VulpesOS/gaia/shared/elements/gaia_grid/js/grid_layout.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

193 lines
4.6 KiB
JavaScript
Executable file

'use strict';
/* global devicePixelRatio */
/* global verticalPreferences */
(function(exports) {
const maxIconsPerRow = 4;
// 320 / 5 = 64px | 480 / 5 = 96px | 540 / 5 = 108px | ...
const iconScaleFactorMaxIconsPerRow = 5;
const minIconsPerRow = 3;
// 320 / 3.8 = 84px | 480 / 3.8 = 126px | 540 / 3.8 = 142px | ...
const iconScaleFactorMinIconsPerRow = 3.8;
const distanceBetweenIconsWithMinIconsPerRow = 36;
const distanceBetweenIconsWithMaxIconsPerRow = 38;
const eachTextRowHeight = 20;
var constraintSize;
function GridLayout(gridView) {
this.gridView = gridView;
if (window.verticalPreferences) {
verticalPreferences.get('grid.cols').then(value => {
this.cols = value;
this.onReady();
}, this.onReady);
verticalPreferences.addEventListener('updated', this);
} else {
this.onReady();
}
}
GridLayout.prototype = {
minIconsPerRow: minIconsPerRow,
maxIconsPerRow: maxIconsPerRow,
_cols: minIconsPerRow,
_offsetY: 0,
_percent: 1,
/**
* The visible height of each divider.
* Calculated by the divider class and cached here.
*/
_dividerLineHeight: 0,
get percent() {
return this._percent;
},
get cols() {
return this._cols;
},
set cols(value) {
if (!value || value === this._cols) {
return;
}
if (window.verticalPreferences) {
verticalPreferences.put('grid.cols', value);
}
// Reset the y-offset because we will re-render everything anyway.
this._offsetY = 0;
this._percent = value == minIconsPerRow ? 1 :
minIconsPerRow / maxIconsPerRow;
this._cols = value;
},
/**
* The width of the grid.
*/
get constraintSize() {
if (!constraintSize) {
this.calculateSize();
}
return constraintSize;
},
/**
* The height of each grid item.
*/
get gridItemHeight() {
var height = this.gridIconSize +
(this._cols === minIconsPerRow ?
distanceBetweenIconsWithMinIconsPerRow :
distanceBetweenIconsWithMaxIconsPerRow);
// Increase height for additional rows of text.
var defaultTextRows = 2;
var definedRows = parseInt(
this.gridView.element.getAttribute('text-rows'), 10);
if (definedRows > defaultTextRows) {
height += (definedRows - defaultTextRows) * eachTextRowHeight;
}
return height;
},
/**
* The width of each grid item.
* This number changes based on current zoom level.
*/
get gridItemWidth() {
return this.constraintSize / this._cols;
},
/**
* Returns the maximum size in pixels for an icon image. It is the size when
* the grid is displayed with the minimum number of columns per row.
*/
get gridMaxIconSize() {
var baseSize = (this.constraintSize / iconScaleFactorMinIconsPerRow);
return baseSize * devicePixelRatio;
},
/**
* Returns the icon image size depending on grid configuration and screen
* characteristics.
*/
get gridIconSize() {
var numCols = this._cols;
var size = this.constraintSize / numCols;
if (numCols === minIconsPerRow) {
size = this.constraintSize / iconScaleFactorMinIconsPerRow;
} else if (numCols === maxIconsPerRow) {
size = this.constraintSize / iconScaleFactorMaxIconsPerRow;
}
return Math.floor(size);
},
/**
* Gets the current offset of the Y-axis for the current zoom level.
* This value is updated by calling zoom.stepYAxis. For example, each
* group of three icons, or a divider, should increment this value.
* The value is reset and recalculated when the zoom level changes.
*/
get offsetY() {
return this._offsetY;
},
set offsetY(value) {
this._offsetY = value;
},
/**
* After we render a row we need to store the current position of the y-axis
*/
stepYAxis: function(value) {
this._offsetY += value;
},
/**
* General event handler.
*/
handleEvent: function(e) {
switch(e.type) {
case 'updated':
var prop = e.target;
if (prop.name === 'grid.cols') {
this.cols = parseInt(prop.value, 10);
this.gridView.render();
}
break;
}
},
calculateSize: function() {
constraintSize = Math.min(window.screen.width, window.screen.height);
},
onReady: function() {
window.dispatchEvent(new CustomEvent('gaiagrid-layout-ready'));
}
};
exports.GridLayout = GridLayout;
}(window));