diff --git a/src/resizer/distributors/roomsublist.js b/src/resizer/distributors/roomsublist.js deleted file mode 100644 index cc7875bfb0..0000000000 --- a/src/resizer/distributors/roomsublist.js +++ /dev/null @@ -1,132 +0,0 @@ -/* -Copyright 2019 New Vector Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import Sizer from "../sizer"; -import ResizeItem from "../item"; - -class RoomSizer extends Sizer { - setItemSize(item, size) { - item.style.maxHeight = `${Math.round(size)}px`; - item.classList.add("resized-sized"); - } - - clearItemSize(item) { - item.style.maxHeight = null; - item.classList.remove("resized-sized"); - } -} - -class RoomSubListItem extends ResizeItem { - isCollapsed() { - return this.domNode.classList.contains("mx_RoomSubList_hidden"); - } - - maxSize() { - const header = this.domNode.querySelector(".mx_RoomSubList_labelContainer"); - const scrollItem = this.domNode.querySelector(".mx_RoomSubList_scroll"); - const headerHeight = this.sizer.getItemSize(header); - return headerHeight + (scrollItem ? scrollItem.scrollHeight : 0); - } - - minSize() { - const isNotEmpty = this.domNode.classList.contains("mx_RoomSubList_nonEmpty"); - return isNotEmpty ? 74 : 31; //size of header + 1? room tile (see room sub list css) - } - - isSized() { - return this.domNode.classList.contains("resized-sized"); - } -} - -export default class RoomSubListDistributor { - static createItem(resizeHandle, resizer, sizer) { - return new RoomSubListItem(resizeHandle, resizer, sizer); - } - - static createSizer(containerElement, vertical, reverse) { - return new RoomSizer(containerElement, vertical, reverse); - } - - constructor(item) { - this.item = item; - } - - _handleSize() { - return 1; - } - - resize(size) { - //console.log("*** starting resize session with size", size); - let item = this.item; - while (item) { - const minSize = item.minSize(); - if (item.isCollapsed()) { - item = item.previous(); - } else if (size <= minSize) { - //console.log(" - resizing", item.id, "to min size", minSize); - item.setSize(minSize); - const remainder = minSize - size; - item = item.previous(); - if (item) { - size = item.size() - remainder - this._handleSize(); - } - } else { - const maxSize = item.maxSize(); - if (size > maxSize) { - // console.log(" - resizing", item.id, "to maxSize", maxSize); - item.setSize(maxSize); - const remainder = size - maxSize; - item = item.previous(); - if (item) { - size = item.size() + remainder; // todo: handle size here? - } - } else { - //console.log(" - resizing", item.id, "to size", size); - item.setSize(size); - item = null; - size = 0; - } - } - } - //console.log("*** ending resize session"); - } - - resizeFromContainerOffset(containerOffset) { - this.resize(containerOffset - this.item.offset()); - } - - start() { - // set all max-height props to the actual height. - let item = this.item.first(); - const sizes = []; - while (item) { - if (!item.isCollapsed()) { - sizes.push(item.size()); - } else { - sizes.push(100); - } - item = item.next(); - } - item = this.item.first(); - sizes.forEach((size) => { - item.setSize(size); - item = item.next(); - }); - } - - finish() { - } -} diff --git a/src/resizer/distributors/roomsublist2.js b/src/resizer/distributors/roomsublist2.js deleted file mode 100644 index a715087630..0000000000 --- a/src/resizer/distributors/roomsublist2.js +++ /dev/null @@ -1,332 +0,0 @@ -/* -Copyright 2019 New Vector Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import FixedDistributor from "./fixed"; - -function clamp(height, min, max) { - if (height > max) return max; - if (height < min) return min; - return height; -} - -export class Layout { - constructor(applyHeight, initialSizes, collapsedState, options) { - // callback to set height of section - this._applyHeight = applyHeight; - // list of {id, count} objects, - // determines sections and order of them - this._sections = []; - // stores collapsed by id - this._collapsedState = Object.assign({}, collapsedState); - // total available height to the layout - // (including resize handles, ...) - this._availableHeight = 0; - // heights stored by section section id - this._sectionHeights = Object.assign({}, initialSizes); - // in-progress heights, while dragging. Committed on mouse-up. - this._heights = []; - // use while manually resizing to cancel - // the resize for a given mouse position - // when the previous resize made the layout - // constrained - this._clampedOffset = 0; - // used while manually resizing, to clear - // _clampedOffset when the direction of resizing changes - this._lastOffset = 0; - - this._allowWhitespace = options && options.allowWhitespace; - this._handleHeight = (options && options.handleHeight) || 0; - } - - setAvailableHeight(newSize) { - this._availableHeight = newSize; - // needs more work - this._applyNewSize(); - } - - expandSection(id, height) { - this._collapsedState[id] = false; - this._applyNewSize(); - this.openHandle(id).setHeight(height).finish(); - } - - collapseSection(id) { - this._collapsedState[id] = true; - this._applyNewSize(); - } - - update(sections, availableHeight, force = false) { - let heightChanged = false; - - if (Number.isFinite(availableHeight) && availableHeight !== this._availableHeight) { - heightChanged = true; - this._availableHeight = availableHeight; - } - - const sectionsChanged = - sections.length !== this._sections.length || - sections.some((a, i) => { - const b = this._sections[i]; - return a.id !== b.id || a.count !== b.count; - }); - - if (!heightChanged && !sectionsChanged && !force) { - return; - } - - this._sections = sections; - const totalHeight = this._getAvailableHeight(); - const defaultHeight = Math.floor(totalHeight / this._sections.length); - this._sections.forEach((section, i) => { - if (!this._sectionHeights[section.id]) { - this._sectionHeights[section.id] = clamp( - defaultHeight, - this._getMinHeight(i), - this._getMaxHeight(i), - ); - } - }); - this._applyNewSize(); - } - - openHandle(id) { - const index = this._getSectionIndex(id); - return new Handle(this, index, this._sectionHeights[id]); - } - - _getAvailableHeight() { - const nonCollapsedSectionCount = this._sections.reduce((count, section) => { - const collapsed = this._collapsedState[section.id]; - return count + (collapsed ? 0 : 1); - }, 0); - return this._availableHeight - ((nonCollapsedSectionCount - 1) * this._handleHeight); - } - - _applyNewSize() { - const newHeight = this._getAvailableHeight(); - const currHeight = this._sections.reduce((sum, section) => { - return sum + this._sectionHeights[section.id]; - }, 0); - const offset = newHeight - currHeight; - this._heights = this._sections.map((section) => this._sectionHeights[section.id]); - const sections = this._sections.map((_, i) => i); - this._applyOverflow(-offset, sections, true); - this._applyHeights(); - this._commitHeights(); - } - - _getSectionIndex(id) { - return this._sections.findIndex((s) => s.id === id); - } - - _getMaxHeight(i) { - const section = this._sections[i]; - const collapsed = this._collapsedState[section.id]; - - if (collapsed) { - return this._sectionHeight(0); - } else if (!this._allowWhitespace) { - return this._sectionHeight(section.count); - } else { - return 100000; - } - } - - _sectionHeight(count) { - return 36 + (count === 0 ? 0 : 4 + (count * 34)); - } - - _getMinHeight(i) { - const section = this._sections[i]; - const collapsed = this._collapsedState[section.id]; - const maxItems = collapsed ? 0 : 1; - return this._sectionHeight(Math.min(section.count, maxItems)); - } - - _applyOverflow(overflow, sections, blend) { - // take the given overflow amount, and applies it to the given sections. - // calls itself recursively until it has distributed all the overflow - // or run out of unclamped sections. - - const unclampedSections = []; - - let overflowPerSection = blend ? (overflow / sections.length) : overflow; - for (const i of sections) { - const newHeight = clamp( - this._heights[i] - overflowPerSection, - this._getMinHeight(i), - this._getMaxHeight(i), - ); - if (newHeight == this._heights[i] - overflowPerSection) { - unclampedSections.push(i); - } - // when section is growing, overflow increases? - // 100 -= 200 - 300 - // 100 -= -100 - // 200 - overflow -= this._heights[i] - newHeight; - this._heights[i] = newHeight; - if (!blend) { - overflowPerSection = overflow; - if (Math.abs(overflow) < 1.0) break; - } - } - - if (Math.abs(overflow) > 1.0 && unclampedSections.length > 0) { - // we weren't able to distribute all the overflow so recurse and try again - overflow = this._applyOverflow(overflow, unclampedSections, blend); - } - - return overflow; - } - - _rebalanceAbove(sectionIndex, overflowAbove) { - if (Math.abs(overflowAbove) > 1.0) { - const sections = []; - for (let i = sectionIndex - 1; i >= 0; i--) { - sections.push(i); - } - overflowAbove = this._applyOverflow(overflowAbove, sections); - } - return overflowAbove; - } - - _rebalanceBelow(sectionIndex, overflowBelow) { - if (Math.abs(overflowBelow) > 1.0) { - const sections = []; - for (let i = sectionIndex + 1; i < this._sections.length; i++) { - sections.push(i); - } - overflowBelow = this._applyOverflow(overflowBelow, sections); - } - return overflowBelow; - } - - // @param offset the amount the sectionIndex is moved from what is stored in _sectionHeights, positive if downwards - // if we're constrained, return the offset we should be constrained at. - _relayout(sectionIndex = 0, offset = 0, constrained = false) { - this._heights = this._sections.map((section) => this._sectionHeights[section.id]); - // are these the amounts the items above/below shrank/grew and need to be relayouted? - let overflowAbove; - let overflowBelow; - const maxHeight = this._getMaxHeight(sectionIndex); - const minHeight = this._getMinHeight(sectionIndex); - // new height > max ? - if (this._heights[sectionIndex] + offset > maxHeight) { - // we're pulling downwards and constrained - // overflowAbove = minus how much are we above max height - overflowAbove = (maxHeight - this._heights[sectionIndex]) - offset; - overflowBelow = offset; - } else if (this._heights[sectionIndex] + offset < minHeight) { // new height < min? - // we're pulling upwards and constrained - overflowAbove = (minHeight - this._heights[sectionIndex]) - offset; - overflowBelow = offset; - } else { - overflowAbove = 0; - overflowBelow = offset; - } - this._heights[sectionIndex] = clamp(this._heights[sectionIndex] + offset, minHeight, maxHeight); - - // 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 - overflowAbove = this._rebalanceAbove(sectionIndex, overflowAbove); - overflowBelow = this._rebalanceBelow(sectionIndex, overflowBelow); - - if (!constrained) { // to avoid risk of infinite recursion - // clamp to avoid overflowing or underflowing the page - if (Math.abs(overflowAbove) > 1.0) { - // here we do the layout again with offset - the amount of space we took too much - this._relayout(sectionIndex, offset + overflowAbove, true); - return offset + overflowAbove; - } - - if (Math.abs(overflowBelow) > 1.0) { - // here we do the layout again with offset - the amount of space we took too much - this._relayout(sectionIndex, offset - overflowBelow, true); - return offset - overflowBelow; - } - } - - this._applyHeights(); - return undefined; - } - - _applyHeights() { - // apply the heights - for (let i = 0; i < this._sections.length; i++) { - const section = this._sections[i]; - this._applyHeight(section.id, this._heights[i]); - } - } - - _commitHeights() { - this._sections.forEach((section, i) => { - this._sectionHeights[section.id] = this._heights[i]; - }); - } - - _setUncommittedSectionHeight(sectionIndex, offset) { - if (Math.sign(offset) != Math.sign(this._lastOffset)) { - this._clampedOffset = undefined; - } - if (this._clampedOffset !== undefined) { - if (offset < 0 && offset < this._clampedOffset) { - return; - } - if (offset > 0 && offset > this._clampedOffset) { - return; - } - } - this._clampedOffset = this._relayout(sectionIndex, offset); - this._lastOffset = offset; - } -} - -class Handle { - constructor(layout, sectionIndex, height) { - this._layout = layout; - this._sectionIndex = sectionIndex; - this._initialHeight = height; - } - - setHeight(height) { - this._layout._setUncommittedSectionHeight( - this._sectionIndex, - height - this._initialHeight, - ); - return this; - } - - finish() { - this._layout._commitHeights(); - return this; - } -} - -export class Distributor extends FixedDistributor { - constructor(item, cfg) { - super(item); - this._handle = cfg.getLayout().openHandle(item.id); - } - - finish() { - this._handle.finish(); - } - - resize(height) { - this._handle.setHeight(height); - } -} diff --git a/src/resizer/index.js b/src/resizer/index.js index 7c4b2bd493..1fd8f4da46 100644 --- a/src/resizer/index.js +++ b/src/resizer/index.js @@ -17,5 +17,4 @@ limitations under the License. export FixedDistributor from "./distributors/fixed"; export CollapseDistributor from "./distributors/collapse"; -export RoomSubListDistributor from "./distributors/roomsublist"; export Resizer from "./resizer";