more fixes for updates/resizing
parent
5bddf62d54
commit
1092244bbf
|
@ -14,12 +14,14 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const allowWhitespace = true;
|
import FixedDistributor from "./fixed";
|
||||||
|
|
||||||
|
// const allowWhitespace = true;
|
||||||
const blendOverflow = false;
|
const blendOverflow = false;
|
||||||
const handleHeight = 1;
|
const handleHeight = 1;
|
||||||
|
|
||||||
function log(...params) {
|
function log(...params) {
|
||||||
// console.log.apply(console, params);
|
console.log.apply(console, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clamp(height, min, max) {
|
function clamp(height, min, max) {
|
||||||
|
@ -53,31 +55,46 @@ export class Layout {
|
||||||
this._applyNewSize();
|
this._applyNewSize();
|
||||||
}
|
}
|
||||||
// [{id, count}]
|
// [{id, count}]
|
||||||
setSections(sections) {
|
update(sections, availableHeight) {
|
||||||
|
if (Number.isFinite(availableHeight)) {
|
||||||
|
this._availableHeight = availableHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._sections.forEach((section, i) => {
|
||||||
|
this._sectionHeights[section.id] = this._originalHeights[i];
|
||||||
|
});
|
||||||
|
|
||||||
this._sections = sections;
|
this._sections = sections;
|
||||||
this._applyNewSize();
|
this._applyNewSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
openHandle(id) {
|
openHandle(id) {
|
||||||
return new Handle(this, this._getSectionIndex(id));
|
const index = this._getSectionIndex(id);
|
||||||
|
//log(`openHandle resolved ${id} to ${index}`);
|
||||||
|
return new Handle(this, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getAvailableHeight() {
|
_getAvailableHeight() {
|
||||||
const nonCollapsedSectionCount = this._sections.reduce((count, section) => {
|
const nonCollapsedSectionCount = this._sections.reduce((count, section) => {
|
||||||
const collapsed = this._collapsedState[section.id];
|
const collapsed = this._collapsedState[section.id];
|
||||||
return count + (collapsed ? 0 : 1);
|
return count + (collapsed ? 0 : 1);
|
||||||
});
|
}, 0);
|
||||||
return this._availableHeight - ((nonCollapsedSectionCount - 1) * handleHeight);
|
return this._availableHeight - ((nonCollapsedSectionCount - 1) * handleHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
_applyNewSize() {
|
_applyNewSize() {
|
||||||
const height = this._getAvailableHeight();
|
const height = this._getAvailableHeight();
|
||||||
const sectionHeights = this._sections.map((section) => {
|
const sectionHeights = this._sections.map((section) => {
|
||||||
return this._sectionHeight[section.id] || (height / this._sections.length);
|
return this._sectionHeights[section.id] || (height / this._sections.length);
|
||||||
});
|
});
|
||||||
const totalRequestedHeight = sectionHeights.reduce((sum, h) => h + sum, 0);
|
const totalRequestedHeight = sectionHeights.reduce((sum, h) => h + sum, 0);
|
||||||
const ratios = sectionHeights.map((h) => h / totalRequestedHeight);
|
const ratios = sectionHeights.map((h) => h / totalRequestedHeight);
|
||||||
this._originalHeights = ratios.map((r) => r * height);
|
this._originalHeights = ratios.map((r) => r * height);
|
||||||
|
// re-assign adjusted heights
|
||||||
|
this._sections.forEach((section, i) => {
|
||||||
|
this._sectionHeights[section.id] = this._originalHeights[i];
|
||||||
|
});
|
||||||
|
log("_applyNewSize", height, this._sections, sectionHeights, ratios, this._originalHeights);
|
||||||
this._heights = this._originalHeights.slice(0);
|
this._heights = this._originalHeights.slice(0);
|
||||||
this._relayout();
|
this._relayout();
|
||||||
}
|
}
|
||||||
|
@ -87,6 +104,8 @@ export class Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
_getMaxHeight(i) {
|
_getMaxHeight(i) {
|
||||||
|
return 100000;
|
||||||
|
/*
|
||||||
const section = this._sections[i];
|
const section = this._sections[i];
|
||||||
const collapsed = this._collapsedState[section.id];
|
const collapsed = this._collapsedState[section.id];
|
||||||
|
|
||||||
|
@ -95,6 +114,7 @@ export class Layout {
|
||||||
} else {
|
} else {
|
||||||
return this._sectionHeight(section.count);
|
return this._sectionHeight(section.count);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
_sectionHeight(count) {
|
_sectionHeight(count) {
|
||||||
|
@ -103,6 +123,7 @@ export class Layout {
|
||||||
|
|
||||||
_getMinHeight(i) {
|
_getMinHeight(i) {
|
||||||
const section = this._sections[i];
|
const section = this._sections[i];
|
||||||
|
log("_getMinHeight", i, section);
|
||||||
return this._sectionHeight(Math.min(section.count, 1));
|
return this._sectionHeight(Math.min(section.count, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,11 +133,11 @@ export class Layout {
|
||||||
// calls itself recursively until it has distributed all the overflow
|
// calls itself recursively until it has distributed all the overflow
|
||||||
// or run out of unclamped sections.
|
// or run out of unclamped sections.
|
||||||
|
|
||||||
let unclampedSections = [];
|
const unclampedSections = [];
|
||||||
|
|
||||||
let overflowPerSection = blendOverflow ? (overflow / sections.length) : overflow;
|
// let overflowPerSection = blendOverflow ? (overflow / sections.length) : overflow;
|
||||||
for (const i of sections) {
|
for (const i of sections) {
|
||||||
newHeight = clamp(this._heights[i] - overflow, this._getMinHeight(i), this._getMaxHeight(i));
|
const newHeight = clamp(this._heights[i] - overflow, this._getMinHeight(i), this._getMaxHeight(i));
|
||||||
if (newHeight == this._heights[i] - overflow) {
|
if (newHeight == this._heights[i] - overflow) {
|
||||||
unclampedSections.push(i);
|
unclampedSections.push(i);
|
||||||
}
|
}
|
||||||
|
@ -129,7 +150,7 @@ export class Layout {
|
||||||
//log(`for section ${i} overflow is ${overflow}`);
|
//log(`for section ${i} overflow is ${overflow}`);
|
||||||
|
|
||||||
if (!blendOverflow) {
|
if (!blendOverflow) {
|
||||||
overflowPerSection = overflow;
|
// overflowPerSection = overflow;
|
||||||
if (Math.abs(overflow) < 1.0) break;
|
if (Math.abs(overflow) < 1.0) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,11 +164,11 @@ export class Layout {
|
||||||
return overflow;
|
return overflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
_rebalanceAbove(overflowAbove) {
|
_rebalanceAbove(anchor, overflowAbove) {
|
||||||
if (Math.abs(overflowAbove) > 1.0) {
|
if (Math.abs(overflowAbove) > 1.0) {
|
||||||
log(`trying to rebalance upstream with ${overflowAbove}`);
|
// log(`trying to rebalance upstream with ${overflowAbove}`);
|
||||||
let sections = [];
|
const sections = [];
|
||||||
for (let i = anchor - 1; i >= 1; i--) {
|
for (let i = anchor - 1; i >= 0; i--) {
|
||||||
sections.push(i);
|
sections.push(i);
|
||||||
}
|
}
|
||||||
overflowAbove = this._applyOverflow(overflowAbove, sections);
|
overflowAbove = this._applyOverflow(overflowAbove, sections);
|
||||||
|
@ -155,11 +176,11 @@ export class Layout {
|
||||||
return overflowAbove;
|
return overflowAbove;
|
||||||
}
|
}
|
||||||
|
|
||||||
_rebalanceBelow(overflowBelow) {
|
_rebalanceBelow(anchor, overflowBelow) {
|
||||||
if (Math.abs(overflowBelow) > 1.0) {
|
if (Math.abs(overflowBelow) > 1.0) {
|
||||||
log(`trying to rebalance downstream with ${overflowBelow}`);
|
// log(`trying to rebalance downstream with ${overflowBelow}`);
|
||||||
let sections = [];
|
const sections = [];
|
||||||
for (let i = anchor + 1; i <= this._sections.length; i++) {
|
for (let i = anchor + 1; i < this._sections.length; i++) {
|
||||||
sections.push(i);
|
sections.push(i);
|
||||||
}
|
}
|
||||||
overflowBelow = this._applyOverflow(overflowBelow, sections);
|
overflowBelow = this._applyOverflow(overflowBelow, sections);
|
||||||
|
@ -183,32 +204,29 @@ export class Layout {
|
||||||
// overflowAbove = minus how much are we above max height?
|
// overflowAbove = minus how much are we above max height?
|
||||||
overflowAbove = (maxHeight - this._heights[anchor]) - offset;
|
overflowAbove = (maxHeight - this._heights[anchor]) - offset;
|
||||||
overflowBelow = offset;
|
overflowBelow = offset;
|
||||||
log(`pulling downwards clamped at max: ${overflowAbove} ${overflowBelow}`);
|
// log(`pulling downwards clamped at max: ${overflowAbove} ${overflowBelow}`);
|
||||||
}
|
} else if (this._heights[anchor] + offset < minHeight) { // new height < min?
|
||||||
// new height < min?
|
|
||||||
else if (this._heights[anchor] + offset < minHeight) {
|
|
||||||
// we're pulling upwards and clamped
|
// we're pulling upwards and clamped
|
||||||
// overflowAbove = ??? (offset is negative here, so - offset will add)
|
// overflowAbove = ??? (offset is negative here, so - offset will add)
|
||||||
overflowAbove = (minHeight - this._heights[anchor]) - offset;
|
overflowAbove = (minHeight - this._heights[anchor]) - offset;
|
||||||
overflowBelow = offset;
|
overflowBelow = offset;
|
||||||
log(`pulling upwards clamped at min: ${overflowAbove} ${overflowBelow}`);
|
// log(`pulling upwards clamped at min: ${overflowAbove} ${overflowBelow}`);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
overflowAbove = 0;
|
overflowAbove = 0;
|
||||||
overflowBelow = offset;
|
overflowBelow = offset;
|
||||||
log(`resizing the anchor: ${overflowAbove} ${overflowBelow}`);
|
// log(`resizing the anchor: ${overflowAbove} ${overflowBelow}`);
|
||||||
}
|
}
|
||||||
this._heights[anchor] = clamp(this._heights[anchor] + offset, minHeight, maxHeight);
|
this._heights[anchor] = clamp(this._heights[anchor] + offset, minHeight, maxHeight);
|
||||||
|
|
||||||
// these are reassigned the amount of overflow that could not be rebalanced
|
// these are reassigned the amount of overflow that could not be rebalanced
|
||||||
// meaning we dragged the handle too far and it can't follow the cursor anymore
|
// meaning we dragged the handle too far and it can't follow the cursor anymore
|
||||||
overflowAbove = this._rebalanceAbove(overflowAbove);
|
overflowAbove = this._rebalanceAbove(anchor, overflowAbove);
|
||||||
overflowBelow = this._rebalanceBelow(overflowBelow);
|
overflowBelow = this._rebalanceBelow(anchor, overflowBelow);
|
||||||
|
|
||||||
if (!clamped) { // to avoid risk of infinite recursion
|
if (!clamped) { // to avoid risk of infinite recursion
|
||||||
// clamp to avoid overflowing or underflowing the page
|
// clamp to avoid overflowing or underflowing the page
|
||||||
if (Math.abs(overflowAbove) > 1.0) {
|
if (Math.abs(overflowAbove) > 1.0) {
|
||||||
log(`clamping with overflowAbove ${overflowAbove}`);
|
// log(`clamping with overflowAbove ${overflowAbove}`);
|
||||||
// here we do the layout again with offset - the amount of space we took too much
|
// here we do the layout again with offset - the amount of space we took too much
|
||||||
this._relayout(anchor, offset + overflowAbove, true);
|
this._relayout(anchor, offset + overflowAbove, true);
|
||||||
return offset + overflowAbove;
|
return offset + overflowAbove;
|
||||||
|
@ -216,25 +234,26 @@ export class Layout {
|
||||||
|
|
||||||
if (Math.abs(overflowBelow) > 1.0) {
|
if (Math.abs(overflowBelow) > 1.0) {
|
||||||
// here we do the layout again with offset - the amount of space we took too much
|
// here we do the layout again with offset - the amount of space we took too much
|
||||||
log(`clamping with overflowBelow ${overflowBelow}`);
|
// log(`clamping with overflowBelow ${overflowBelow}`);
|
||||||
this._relayout(anchor, offset - overflowBelow, true);
|
this._relayout(anchor, offset - overflowBelow, true);
|
||||||
return offset - overflowBelow;
|
return offset - overflowBelow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log("updating layout, heights are now", this._heights);
|
||||||
// apply the heights
|
// apply the heights
|
||||||
for (let i = 0; i < this._sections.length; i++) {
|
for (let i = 0; i < this._sections.length; i++) {
|
||||||
const section = this._sections[i];
|
const section = this._sections[i];
|
||||||
this._applyHeight(section.id, this._heights[i]);
|
this._applyHeight(section.id, this._heights[i]);
|
||||||
// const roomSubList = document.getElementById(`roomSubList${i}`);
|
|
||||||
// roomSubList.style.height = `${heights[i]}px`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
_commitHeights() {
|
_commitHeights() {
|
||||||
this._originalHeights = this._heights;
|
const heights = this._heights.slice(0);
|
||||||
|
log("committing heights:", heights);
|
||||||
|
this._originalHeights = heights;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,28 +272,18 @@ class Handle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Distributor {
|
export class Distributor extends FixedDistributor {
|
||||||
constructor(item, cfg) {
|
constructor(item, cfg) {
|
||||||
this._item = item;
|
super(item);
|
||||||
this._layout = cfg.layout;
|
const layout = cfg.layout;
|
||||||
this._initialTop;
|
this._handle = layout.openHandle(item.id);
|
||||||
}
|
|
||||||
|
|
||||||
start() {
|
|
||||||
this._handle = this._layout.openHandle(this._item.id);
|
|
||||||
this._initialTop = this._item.getOffset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
finish() {
|
finish() {
|
||||||
this._handle.finish();
|
this._handle.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
resize() {
|
resize(offset) {
|
||||||
// not supported
|
|
||||||
}
|
|
||||||
|
|
||||||
resizeFromContainerOffset(containerOffset) {
|
|
||||||
const offset = containerOffset - this._initialTop;
|
|
||||||
this._handle.setOffset(offset);
|
this._handle.setOffset(offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue