837 lines
33 KiB
JavaScript
837 lines
33 KiB
JavaScript
"use strict";
|
|
(function gridLayout_js() {
|
|
var moduleName = "views/gridLayout";
|
|
|
|
var defineArray = [];
|
|
defineArray.push("views/view");
|
|
defineArray.push("views/layout");
|
|
|
|
define(moduleName, defineArray, function gridLayout_module() {
|
|
var View = require("views/view");
|
|
var Layout = require("views/layout");
|
|
|
|
var GridLayout = Layout.inherit({
|
|
"className": "GridLayout",
|
|
"constructor": function(controller, options) {
|
|
var base = {
|
|
|
|
};
|
|
W.extend(base, options);
|
|
Layout.fn.constructor.call(this, controller, base);
|
|
|
|
this._rh = [];
|
|
this._rH = [];
|
|
this._rw = [];
|
|
this._rW = [];
|
|
this._lay = [[[]]];
|
|
this._cols = [{}];
|
|
this._rows = [{}];
|
|
this._sde = []; //size dependent elements
|
|
},
|
|
"append": function(child, row, col, rowSpan, colSpan, aligment) {
|
|
aligment = aligment || 5;
|
|
this._addChild(child, aligment);
|
|
child.on("sizeDependencyChange", this._onChildSizeDependencyChange.bind(this, child));
|
|
|
|
rowSpan = rowSpan || 1;
|
|
colSpan = colSpan || 1;
|
|
|
|
var tRow = row + rowSpan;
|
|
var tCol = col + colSpan;
|
|
|
|
while (this._lay.length < tRow) {
|
|
this._lay.push([]);
|
|
|
|
}
|
|
for (var i = 0; i < this._lay.length; ++i) {
|
|
while (this._lay[i].length < tCol) {
|
|
this._lay[i].push([]);
|
|
}
|
|
}
|
|
var obj = {
|
|
child: child,
|
|
col: col,
|
|
row: row,
|
|
colspan: colSpan,
|
|
rowspan: rowSpan,
|
|
a: aligment
|
|
}
|
|
var item = this._c[this._c.length - 1];
|
|
item.col = col;
|
|
item.row = row;
|
|
item.colspan = colSpan;
|
|
item.rowspan = rowSpan;
|
|
|
|
for (i = row; i < tRow; ++i) {
|
|
for (var j = col; j < tCol; ++j) {
|
|
this._lay[i][j].push(obj);
|
|
}
|
|
}
|
|
|
|
if (child._o.sizeDependency !== Layout.SizeDependency.straight.independent) {
|
|
this._sde.push(obj);
|
|
if (this._o.sizeDependency === Layout.SizeDependency.straight.independent) {
|
|
this.setSizeDependency(child._o.sizeDependency)
|
|
} else {
|
|
if (this._o.sizeDependency !== child._o.sizeDependency) {
|
|
this.setSizeDependency(Layout.SizeDependency.straight.undefined)
|
|
}
|
|
}
|
|
}
|
|
|
|
this._recountLimits();
|
|
if (this._w !== undefined && this._h !== undefined) {
|
|
this.refreshLay();
|
|
}
|
|
},
|
|
"_cleanupLay": function() {
|
|
var i;
|
|
var rowsC = false;
|
|
var colsC = false;
|
|
while (!rowsC) {
|
|
for (i = 0; i < this._lay[this._lay.length - 1].length; ++i) {
|
|
if (this._lay[this._lay.length - 1][i].length) {
|
|
rowsC = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!rowsC) {
|
|
this._lay.pop()
|
|
rowsC = !this._lay.length;
|
|
colsC = !this._lay.length;
|
|
}
|
|
}
|
|
while (!colsC) {
|
|
for (i = 0; i < this._lay.length; ++i) {
|
|
if (this._lay[i][this._lay[i].length - 1].length) {
|
|
colsC = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!colsC) {
|
|
for (i = 0; i < this._lay.length; ++i) {
|
|
this._lay[i].pop();
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"clear": function() {
|
|
Layout.fn.clear.call(this);
|
|
|
|
this._rh = [];
|
|
this._rH = [];
|
|
this._rw = [];
|
|
this._rW = [];
|
|
this._lay = [[[]]];
|
|
this._cols = [{}];
|
|
this._rows = [{}];
|
|
this._sde = [];
|
|
},
|
|
"_onChildChangeLimits": function() {
|
|
var notification = this._recountLimits();
|
|
if (!notification) {
|
|
this.refreshLay();
|
|
}
|
|
},
|
|
"_positionElements": function() {
|
|
var shiftW = 0;
|
|
var shiftH = 0;
|
|
|
|
var positioned = [];
|
|
|
|
for (var i = 0; i < this._lay.length; ++i) {
|
|
shiftW = 0;
|
|
for (var j = 0; j < this._lay[i].length; ++j) {
|
|
for (var k = 0; k < this._lay[i][j].length; ++k) {
|
|
var e = this._lay[i][j][k];
|
|
var child = e.child;
|
|
if (positioned.indexOf(child) === -1) {
|
|
var tWidth = 0;
|
|
var tHeight = 0;
|
|
var s;
|
|
for (s = 0; s < e.colspan; ++s) {
|
|
tWidth += this._cols[j + s].cur;
|
|
}
|
|
for (s = 0; s < e.rowspan; ++s) {
|
|
tHeight += this._rows[i + s].cur;
|
|
}
|
|
child.setSize(tWidth, tHeight);
|
|
|
|
switch (e.a) {
|
|
case Layout.Aligment.LeftTop:
|
|
child.setTop(shiftH);
|
|
child.setLeft(shiftW);
|
|
break;
|
|
case Layout.Aligment.LeftCenter:
|
|
child.setTop(shiftH + (tHeight - child._h) / 2);
|
|
child.setLeft(shiftW);
|
|
break;
|
|
case Layout.Aligment.LeftBottom:
|
|
child.setTop(shiftH + (tHeight - child._h));
|
|
child.setLeft(shiftW);
|
|
break;
|
|
case Layout.Aligment.CenterTop:
|
|
child.setTop(shiftH);
|
|
child.setLeft(shiftW + (tWidth - child._w) / 2);
|
|
break;
|
|
case Layout.Aligment.CenterCenter:
|
|
child.setTop(shiftH + (tHeight - child._h) / 2);
|
|
child.setLeft(shiftW + (tWidth - child._w) / 2);
|
|
break;
|
|
case Layout.Aligment.CenterBottom:
|
|
child.setTop(shiftH + (tHeight - child._h));
|
|
child.setLeft((tWidth - child._w) / 2);
|
|
break;
|
|
case Layout.Aligment.RightTop:
|
|
child.setTop(shiftH);
|
|
child.setLeft(shiftW + (tWidth - child._h));
|
|
break;
|
|
case Layout.Aligment.RightCenter:
|
|
child.setTop((tHeight - child._h) / 2);
|
|
child.setLeft(shiftW + (tWidth - child._h));
|
|
break;
|
|
case Layout.Aligment.RightBottom:
|
|
child.setTop(shiftH + (tHeight - child._h));
|
|
child.setLeft(shiftW + (tWidth - child._h));
|
|
break;
|
|
|
|
}
|
|
positioned.push(child);
|
|
}
|
|
}
|
|
shiftW += this._cols[j].cur;
|
|
}
|
|
shiftH += this._rows[i].cur;
|
|
}
|
|
},
|
|
"_recountLimits": function() {
|
|
this._rh = [];
|
|
this._rH = [];
|
|
this._rw = [];
|
|
this._rW = [];
|
|
this._cols = [];
|
|
this._rows = [];
|
|
var i, j;
|
|
var multiCols = [];
|
|
var multiRows = [];
|
|
var proccessed = Object.create(null);
|
|
|
|
for (i = 0; i < this._lay.length; ++i) {
|
|
while (!this._rows[i]) {
|
|
this._rows.push({
|
|
count: 0,
|
|
min: 0,
|
|
max: Infinity
|
|
});
|
|
}
|
|
for (j = 0; j < this._lay[i].length; ++j) {
|
|
while (!this._cols[j]) {
|
|
this._cols.push({
|
|
count: 0,
|
|
min: 0,
|
|
max: Infinity
|
|
});
|
|
}
|
|
for (var k = 0; k < this._lay[i][j].length; ++k) {
|
|
var e = this._lay[i][j][k];
|
|
++this._cols[j].count;
|
|
++this._rows[i].count;
|
|
|
|
if (proccessed[e.child._id]) {
|
|
continue;
|
|
}
|
|
|
|
var colMinW = this._cols[j].min;
|
|
var rowMinH = this._rows[i].min;
|
|
var colMaxW = this._cols[j].max;
|
|
var rowMaxH = this._rows[i].max;
|
|
|
|
if (e.colspan === 1) {
|
|
this._cols[j].min = Math.max(colMinW, e.child._o.minWidth);
|
|
this._cols[j].max = Math.min(colMaxW, e.child._o.maxWidth);
|
|
} else {
|
|
multiCols.push({
|
|
p: j,
|
|
e: e
|
|
});
|
|
}
|
|
if (e.rowspan === 1) {
|
|
this._rows[i].min = Math.max(rowMinH, e.child._o.minHeight);
|
|
this._rows[i].max = Math.min(rowMaxH, e.child._o.maxHeight);
|
|
} else {
|
|
multiRows.push({
|
|
p: i,
|
|
e: e
|
|
});
|
|
}
|
|
|
|
proccessed[e.child._id] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
multiLimits(this._cols, multiCols, true, this._rw, this._rW);
|
|
multiLimits(this._rows, multiRows, false, this._rh, this._rH);
|
|
|
|
for (i = 0; i < this._sde.length; ++i) {
|
|
var dep = this._sde[i];
|
|
var cols = [];
|
|
var rows = [];
|
|
var tdwMax = 0;
|
|
var tdwMin = 0;
|
|
var tdhMax = 0;
|
|
var tdhMin = 0;
|
|
for (var c = 0; c < dep.colspan; ++c) {
|
|
var col = this._cols[dep.col + c];
|
|
tdwMax += col.max;
|
|
tdwMin += col.min;
|
|
if (col.min < col.max) {
|
|
cols.push(col);
|
|
}
|
|
}
|
|
for (var r = 0; r < dep.rowspan; ++r) {
|
|
var row = this._rows[dep.row + r];
|
|
tdhMax += row.max;
|
|
tdhMin += row.min;
|
|
if (row.min < row.max) {
|
|
rows.push(row);
|
|
}
|
|
}
|
|
var cMaxWidth, cMinWidth, cMaxHeight, cMinHeight;
|
|
var opts = dep.child._o;
|
|
var cmw = true;
|
|
var cMw = true;
|
|
var cmh = true;
|
|
var cMh = true;
|
|
while (cols.length || rows.length) {
|
|
switch (opts.sizeDependency) {
|
|
case Layout.SizeDependency.straight.straight:
|
|
if (cMh) {
|
|
cMaxWidth = dep.child.getMaxWidthForHeight(tdhMax);
|
|
cMh = false;
|
|
}
|
|
if (cmh) {
|
|
cMinWidth = dep.child.getMinWidthForHeight(tdhMin);
|
|
cmh = false;
|
|
}
|
|
if (cMw) {
|
|
cMaxHeight = dep.child.getMaxHeightForWidth(tdwMax);
|
|
cMw = false;
|
|
}
|
|
if (cmw) {
|
|
cMinHeight = dep.child.getMinHeightForWidth(tdwMin);
|
|
cmw = false;
|
|
}
|
|
break;
|
|
case Layout.SizeDependency.straight.reversed:
|
|
if (cMh) {
|
|
cMinWidth = dep.child.getMinWidthForHeight(tdhMax);
|
|
cMh = false;
|
|
}
|
|
if (cmh) {
|
|
cMaxWidth = dep.child.getMaxWidthForHeight(tdhMin);
|
|
cmh = false;
|
|
}
|
|
if (cMw) {
|
|
cMinHeight = dep.child.getMinHeightForWidth(tdwMax);
|
|
cMw = false;
|
|
}
|
|
if (cmw) {
|
|
cMaxHeight = dep.child.getMaxHeightForWidth(tdwMin);
|
|
cmw = false;
|
|
}
|
|
break;
|
|
}
|
|
var changed = false;
|
|
|
|
if (!changed && cMinWidth > tdwMin) {
|
|
var wDiff = cMinWidth - tdwMin;
|
|
var change = wDiff - adjust(wDiff, cols, true);
|
|
if (change > 0) {
|
|
changed = true;
|
|
cmw = true;
|
|
tdwMin += change;
|
|
}
|
|
}
|
|
if (!changed && cMinHeight > tdhMin) {
|
|
var hDiff = cMaxHeight - tdhMin;
|
|
var change = hDiff - adjust(hDiff, rows, true);
|
|
if (change > 0) {
|
|
changed = true;
|
|
cmh = true;
|
|
tdhMin += change;
|
|
}
|
|
}
|
|
if (!changed && cMaxWidth < tdwMax) {
|
|
var wDiff = tdwMax - cMaxWidth;
|
|
if (wDiff < Infinity) {
|
|
var change = wDiff - adjust(wDiff, cols, false);
|
|
if (change > 0) {
|
|
changed = true;
|
|
cMw = true;
|
|
tdwMax -= change;
|
|
}
|
|
} else {
|
|
constrain(cMaxWidth, cols, false);
|
|
changed = true;
|
|
cMw = true;
|
|
tdwMax = cMaxWidth;
|
|
}
|
|
}
|
|
if (!changed && cMaxHeight < tdhMax) {
|
|
var hDiff = tdhMax - cMaxHeight;
|
|
if (hDiff < Infinity) {
|
|
var change = hDiff - adjust(hDiff, rows, false);
|
|
if (change > 0) {
|
|
changed = true;
|
|
cMh = true;
|
|
tdhMax -= change;
|
|
}
|
|
} else {
|
|
constrain(cMaxHeight, rows, false);
|
|
changed = true;
|
|
cMh = true;
|
|
tdhMax = cMaxHeight;
|
|
}
|
|
}
|
|
if (!changed) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
var tw = total(this._cols, this._rw, this._rW);
|
|
var th = total(this._rows, this._rh, this._rH);
|
|
|
|
this._storedCols = [];
|
|
this._storedRows = [];
|
|
if (this._o.sizeDependency !== Layout.SizeDependency.straight.independent) {
|
|
W.extend(true, this._storedCols, this._cols);
|
|
W.extend(true, this._storedRows, this._rows);
|
|
}
|
|
|
|
return this._setLimits(tw.min, th.min, tw.max, th.max);
|
|
},
|
|
"refreshLay": function() {
|
|
if (this._o.sizeDependency !== Layout.SizeDependency.straight.independent) {
|
|
this._cols = [];
|
|
this._rows = [];
|
|
W.extend(true, this._cols, this._storedCols);
|
|
W.extend(true, this._rows, this._storedRows);
|
|
}
|
|
|
|
var totalMaxW = 0;
|
|
var totalMaxH = 0;
|
|
var totalMinW = 0;
|
|
var totalMinH = 0;
|
|
var i;
|
|
|
|
for (i = 0; i < this._cols.length; ++i) {
|
|
totalMaxW += this._cols[i].max;
|
|
totalMinW += this._cols[i].min
|
|
}
|
|
|
|
if (this._w <= totalMinW || this._w >= totalMaxW) {
|
|
var kW;
|
|
var keyW;
|
|
if (this._w <= totalMinW) {
|
|
kW = this._w / totalMinW;
|
|
keyW = "min";
|
|
} else {
|
|
kW = this._w / totalMaxW;
|
|
keyW = "max";
|
|
}
|
|
|
|
for (i = 0; i < this._cols.length; ++i) {
|
|
this._cols[i].cur = this._cols[i][keyW] * kW;
|
|
}
|
|
} else {
|
|
distribute(this._w, this._cols, this._rw, this._rW);
|
|
}
|
|
|
|
for (i = 0; i < this._sde.length; ++i) {
|
|
var dep = this._sde[i];
|
|
var rows = [];
|
|
var tdw = 0;
|
|
var tdhMax = 0;
|
|
var tdhMin = 0;
|
|
for (var c = 0; c < dep.colspan; ++c) {
|
|
tdw += this._cols[dep.col + c].cur;
|
|
}
|
|
for (var r = 0; r < dep.rowspan; ++r) {
|
|
var row = this._rows[dep.row + r];
|
|
tdhMax += row.max;
|
|
tdhMin += row.min;
|
|
if (row.min < row.max) {
|
|
rows.push(row);
|
|
}
|
|
}
|
|
|
|
if (rows.length > 0) {
|
|
var cMaxHeight = dep.child.getMaxHeightForWidth(tdw);
|
|
var cMinHeight = dep.child.getMinHeightForWidth(tdw);
|
|
if (cMaxHeight < tdhMax) {
|
|
adjust(tdhMax - cMaxHeight, rows, false);
|
|
}
|
|
if (cMinHeight > tdhMin) {
|
|
adjust(cMinHeight - cMinHeight, rows, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < this._rows.length; ++i) {
|
|
totalMaxH += this._rows[i].max;
|
|
totalMinH += this._rows[i].min;
|
|
}
|
|
|
|
if (this._h <= totalMinH || this._h >= totalMaxH) {
|
|
var kH;
|
|
var keyH;
|
|
if (this._h <= totalMinH) {
|
|
kH = this._h / totalMinH;
|
|
keyH = "min";
|
|
} else {
|
|
kH = this._h / totalMaxH;
|
|
keyH = "max";
|
|
}
|
|
|
|
for (i = 0; i < this._rows.length; ++i) {
|
|
this._rows[i].cur = this._rows[i][keyH] * kH;
|
|
}
|
|
} else {
|
|
distribute(this._h, this._rows, this._rh, this._rH);
|
|
}
|
|
this._positionElements();
|
|
},
|
|
"removeChild": function(child) {
|
|
var obj = Layout.fn.removeChild.call(this, child);
|
|
var found = obj !== undefined;
|
|
var layObject;
|
|
|
|
if (found) {
|
|
child.off("sizeDependencyChange") //assuming a child is supposed to have only one parent that should be okay
|
|
var cs = obj.colspan;
|
|
var rs = obj.rowspan;
|
|
var row = obj.row;
|
|
var col = obj.col;
|
|
for (var i = 0; i < rs; ++ i) {
|
|
for (var j = 0; j < cs; ++j) {
|
|
var cell = this._lay[row + i][col + j];
|
|
for (var k = 0; k < cell.length; ++k) {
|
|
if (cell[k].child === child) {
|
|
layObject = cell[k];
|
|
cell.splice(k, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var di = this._sde.indexOf(layObject);
|
|
if (di !== -1) {
|
|
this._sde.splice(di, 1);
|
|
this._recalculateSizeDependency(); //TODO need to recalculate the grid, but not sure about the order of triggers.
|
|
}
|
|
|
|
this._cleanupLay();
|
|
this._recountLimits();
|
|
this.refreshLay();
|
|
}
|
|
},
|
|
"setSize": function(w, h) {
|
|
View.fn.setSize.call(this, w, h);
|
|
|
|
if (this._c.length) {
|
|
this.refreshLay();
|
|
}
|
|
},
|
|
"_recalculateSizeDependency": function() {
|
|
if (this._sde.length === 0) {
|
|
this.setSizeDependency(Layout.SizeDependency.straight.independent);
|
|
} else {
|
|
var sd = this._sde[0]._o.sizeDependency;
|
|
for (var d = 0; d < this._sde.length; ++d) {
|
|
var csd = this._sde[d]._o.sizeDependency
|
|
if (sd !== csd) {
|
|
sd = Layout.SizeDependency.straight.undefined;
|
|
}
|
|
if (sd === Layout.SizeDependency.straight.undefined) {
|
|
break;
|
|
}
|
|
}
|
|
if (sd !== this._o.sizeDependency) {
|
|
this.setSizeDependency(sd);
|
|
}
|
|
}
|
|
},
|
|
"_onChildSizeDependencyChange": function(child, d) {
|
|
if (d === Layout.SizeDependency.straight.independent) {
|
|
var index = this._getChildObjectIndex(child);
|
|
var obj = this._c[index]; //I assume it presents among children
|
|
|
|
var di = this._sde.indexOf(obj);
|
|
this._sde.splice(di, 1);
|
|
}
|
|
this._recalculateSizeDependency(); //TODO need to recalculate the grid, but not sure about the order of triggers.
|
|
}
|
|
});
|
|
|
|
function distribute (size, array, rm, rM) {
|
|
var i;
|
|
var cMax = [];
|
|
for (i = 0; i < array.length; ++i) {
|
|
array[i].cur = array[i].min;
|
|
size -= array[i].min;
|
|
|
|
if (array[i].cur < array[i].max) {
|
|
cMax.push(array[i]);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < rm.length && size > 1; ++i) {
|
|
var rule = rm[i];
|
|
var trm = 0;
|
|
var mems = [];
|
|
for (var j = 0; j < rule.el.length; ++j) {
|
|
var mem = array[rule.el[j]];
|
|
trm += mem.cur;
|
|
mems.push(mem);
|
|
}
|
|
var c = rule.val - trm;
|
|
if (c > 1) {
|
|
size -= c;
|
|
mems.sort(GridLayout._candidatesSortMax);
|
|
c -= deliver(mems, c);
|
|
if (c > 1) {
|
|
var p = c / rule.el.length;
|
|
for (j = 0; j < rule.el.length; ++j) {
|
|
array[rule.el[j]].cur += p;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
cMax.sort(GridLayout._candidatesSortMax);
|
|
size -= deliver(cMax, size);
|
|
|
|
for (i = 0; i < rM.length; ++i) {
|
|
var rule = rm[i];
|
|
var trm = 0;
|
|
var mems = [];
|
|
for (var j = 0; j < rule.el.length; ++j) {
|
|
var mem = array[rule.el[j]];
|
|
trm += mem.cur;
|
|
mems.push(mem);
|
|
}
|
|
var c = trm - rule.val;
|
|
if (c > 1) {
|
|
size += c;
|
|
var p = c / mems.length;
|
|
for (j = 0; j < mems.length; ++j) {
|
|
mems.cur -= p;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (size) {
|
|
var portion = size / array.length;
|
|
for (i = 0; i < array.length; ++i) {
|
|
array.cur += portion;
|
|
}
|
|
}
|
|
}
|
|
|
|
function deliver(cMax, size) {
|
|
var oSize = size;
|
|
while (cMax.length && size) {
|
|
var portion = size / cMax.length;
|
|
var last = cMax[cMax.length -1];
|
|
|
|
var avail = last.max - last.cur;
|
|
if (portion >= avail) {
|
|
size -= avail;
|
|
last.cur = last.max;
|
|
cMax.pop();
|
|
} else {
|
|
for (var i = 0; i < cMax.length; ++i) {
|
|
cMax[i].cur += portion;
|
|
}
|
|
size = 0;
|
|
}
|
|
}
|
|
|
|
return oSize - size;
|
|
}
|
|
|
|
function multiLimits(arr, elements, w, rm, rM) {
|
|
var mind = "minWidth";
|
|
var maxd = "maxWidth";
|
|
var spand = "colspan";
|
|
if (!w) {
|
|
mind = "minHeight";
|
|
maxd = "maxHeight";
|
|
spand = "rowspan";
|
|
}
|
|
for (var i = 0; i < elements.length; ++i) {
|
|
var e = elements[i].e;
|
|
var pos = elements[i].p;
|
|
var span = e[spand];
|
|
var target = pos + span;
|
|
var minSize = 0;
|
|
var maxSize = 0;
|
|
var flexible = [];
|
|
var el = [];
|
|
for (var j = pos; j < target; ++j) {
|
|
minSize += arr[j].min;
|
|
maxSize += arr[j].max;
|
|
el.push(j);
|
|
if (arr[j].min < arr[j].max) {
|
|
flexible.push(arr[j]);
|
|
}
|
|
}
|
|
|
|
var leftMin = e.child._o[mind] - minSize;
|
|
var leftMax = maxSize - e.child._o[maxd];
|
|
var naMin = adjust(leftMin, flexible, true);
|
|
var naMax = adjust(leftMax, flexible, false);
|
|
if (naMin > 0) {
|
|
rm.push({
|
|
el: el,
|
|
val: e.child._o[mind]
|
|
});
|
|
}
|
|
if (naMax > 0) {
|
|
rM.push({
|
|
el: el,
|
|
val: e.child._o[maxd]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
function adjust(space, arr, isMin) {
|
|
while (space > 0 && arr.length > 0) {
|
|
var portion = space / arr.length;
|
|
|
|
for (var j = 0; j < arr.length; ++j) {
|
|
var mem = arr[j];
|
|
var lPortion = Math.min(mem.max - mem.min, portion);
|
|
if (isMin === true) {
|
|
mem.min += lPortion;
|
|
} else {
|
|
mem.max -= lPortion;
|
|
}
|
|
space -= lPortion;
|
|
if (mem.min === mem.max) {
|
|
arr.splice(j, 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (space < 1) {
|
|
space = 0;
|
|
}
|
|
}
|
|
if (space < 0) {
|
|
space = 0;
|
|
}
|
|
return space;
|
|
}
|
|
|
|
function constrain(space, arr, isMin) {
|
|
while (space > 0 && arr.length > 0) {
|
|
var portion = space / arr.length;
|
|
|
|
for (var j = 0; j < arr.length; ++j) {
|
|
var mem = arr[j];
|
|
var lPortion
|
|
if (isMin === true) {
|
|
lPortion = Math.min(mem.max, portion);
|
|
mem.min = lPortion;
|
|
} else {
|
|
lPortion = Math.max(mem.min, portion);
|
|
mem.max = lPortion;
|
|
}
|
|
space -= lPortion;
|
|
if (mem.min === mem.max) {
|
|
arr.splice(j, 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (space < 1) {
|
|
space = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
function total(arr, rm, rM) {
|
|
var min = 0;
|
|
var max = 0;
|
|
var am = [];
|
|
for (var i = 0; i < arr.length; ++i) {
|
|
var el = arr[i];
|
|
if (el.count === 0) {
|
|
el.min = 0;
|
|
el.max = 0;
|
|
} else {
|
|
min += el.min;
|
|
el.max = Math.max(el.max, el.min);
|
|
max += el.max;
|
|
}
|
|
am.push({
|
|
min: el.min,
|
|
max: el.max
|
|
});
|
|
}
|
|
|
|
min += shove(rm, am, true);
|
|
max -= shove(rM, am, false);
|
|
|
|
return {
|
|
min: min,
|
|
max: Math.max(max, min)
|
|
}
|
|
}
|
|
|
|
function shove(rules, arr, isMin) {
|
|
var dim = "max";
|
|
if (isMin === true) {
|
|
dim = "min";
|
|
}
|
|
var change = 0;
|
|
for (var i = 0; i < rules.length; ++i) {
|
|
var rule = rules[i];
|
|
var val = rule.val;
|
|
var tr = 0;
|
|
for (var j = 0; j < rule.el.length; ++j) {
|
|
tr += arr[rule.el[j]][dim];
|
|
}
|
|
var c;
|
|
if (isMin) {
|
|
c = val - tr;
|
|
} else {
|
|
c = tr - val;
|
|
}
|
|
if (c > 0) {
|
|
var p = c / rule.el.length;
|
|
for (j = 0; j < rule.el.length; ++j) {
|
|
if (isMin) {
|
|
arr[rule.el[j]][dim] += p;
|
|
} else {
|
|
arr[rule.el[j]][dim] -= p; //TODO a possibility of going under zero
|
|
}
|
|
}
|
|
change += c;
|
|
}
|
|
}
|
|
return change;
|
|
}
|
|
|
|
GridLayout._candidatesSortMax = function(a, b) {
|
|
return b.max - a.max;
|
|
}
|
|
|
|
return GridLayout;
|
|
});
|
|
})();
|