diff --git a/src/frontend/common/stylesheet/dimensions.scss b/src/frontend/common/stylesheet/dimensions.scss index 2c4d99c6c88e22634778d23a3104161a48a7de5c..d1bea7a2bd4883aae558d63861ec448e950ab2c1 100644 --- a/src/frontend/common/stylesheet/dimensions.scss +++ b/src/frontend/common/stylesheet/dimensions.scss @@ -1,3 +1,9 @@ $line-height: 32px; $font-size-normal: 12px; -$font-size-large: 14px; \ No newline at end of file +$font-size-large: 14px; + +:export { + lineHeight: $line-height; + fontSizeNormal: $font-size-normal; + fontSizeLarge: $font-size-large; +} \ No newline at end of file diff --git a/src/frontend/components/App/index.jsx b/src/frontend/components/App/index.jsx index 601197b9d172ba480ac09776cd1487f104d57920..23d43b04834f323f3de79f046195de89f79748ce 100644 --- a/src/frontend/components/App/index.jsx +++ b/src/frontend/components/App/index.jsx @@ -94,13 +94,22 @@ class App extends React.Component { return categories && categoryKey && algorithmKey && (
-
this.navigatorReference.core.setVisible(!this.navigatorReference.core.visible)} navigatorOpened={navigatorOpened} /> - + child.visible); - const weights = visibleChildren.map(section => section.weight); - const totalWeight = weights.reduce((sumWeight, weight) => sumWeight + weight, 0); + const totalWeight = visibleChildren.reduce((sumWeight, child) => sumWeight + (child.relative ? child.weight : 0), 0); const elements = []; - children.forEach((child, i) => { - if (!child.visible) return; - const visibleIndex = visibleChildren.findIndex(visibleChild => visibleChild === child); - const portion = child.weight / totalWeight; - const style = { flex: portion }; - if (elements.length) { + visibleChildren.forEach((child, visibleIndex) => { + const index = children.indexOf(child); + elements.push( + 0 && ((target, dx, dy) => this.handleResize(visibleIndex, target, dx, dy))} + onDropTab={tab => this.handleDropTabToContainer(tab, index)} + onDropSection={section => this.handleDropSectionToContainer(section, index)} /> + ); + const style = child.relative ? { + flexGrow: child.weight / totalWeight, + } : { + flexGrow: 0, + flexBasis: child.size, + }; + if (children.length === 1) { + elements.push( +
+ {child.element} +
+ ); + } else { elements.push( - this.handleResize(visibleIndex - 1, target, x, y)} - onDropTab={tab => this.handleDropTabToContainer(tab, i)} - onDropSection={section => this.handleDropSectionToContainer(section, i)} /> +
+ this.handleDropTabToSection(tab, index, true)} + onDropSection={section => this.handleDropSectionToSection(section, index, true)} /> + {child.element} + this.handleDropTabToSection(tab, index)} + onDropSection={section => this.handleDropSectionToSection(section, index)} /> +
+ ); + } + if (visibleIndex === visibleChildren.length - 1) { + elements.push( + this.handleDropTabToContainer(tab, index + 1)} + onDropSection={section => this.handleDropSectionToContainer(section, index + 1)} /> ); } - elements.push( -
- this.handleDropTabToSection(tab, i, true)} - onDropSection={section => this.handleDropSectionToSection(section, i, true)} /> - {child.element} - this.handleDropTabToSection(tab, i)} - onDropSection={section => this.handleDropSectionToSection(section, i)} /> -
- ); }); - if (elements.length) { - const firstIndex = children.indexOf(visibleChildren[0]); - const lastIndex = children.indexOf(visibleChildren[visibleChildren.length - 1]); - elements.unshift( - this.handleDropTabToContainer(tab, firstIndex)} - onDropSection={section => this.handleDropSectionToContainer(section, firstIndex)} /> - ); - elements.push( - this.handleDropTabToContainer(tab, lastIndex + 1)} - onDropSection={section => this.handleDropSectionToContainer(section, lastIndex + 1)} /> - ); - } else { - elements.push( - this.handleDropTabToContainer(tab)} - onDropSection={section => this.handleDropSectionToContainer(section)} /> - ); - } return (
- {elements} + { + elements.length ? + elements : ( + this.handleDropTabToContainer(tab)} + onDropSection={section => this.handleDropSectionToContainer(section)} /> + ) + }
); } diff --git a/src/frontend/workspace/components/WSTabContainer/stylesheet.scss b/src/frontend/workspace/components/WSTabContainer/stylesheet.scss index 4a1148162938d19b5d2354171bda57a77aa14df8..0012fdbcae886b917afdb1626103cf7b7dab62f5 100644 --- a/src/frontend/workspace/components/WSTabContainer/stylesheet.scss +++ b/src/frontend/workspace/components/WSTabContainer/stylesheet.scss @@ -25,7 +25,7 @@ display: flex; align-items: stretch; height: $line-height; - overflow-x: scroll; + overflow-x: auto; white-space: nowrap; flex-shrink: 0; cursor: move; diff --git a/src/frontend/workspace/core/Child.js b/src/frontend/workspace/core/Child.js index 7fe6138a871bff65b47233bd84cbbc8973acf830..661417470e9ec38bd07f03676adf4c84067d204a 100644 --- a/src/frontend/workspace/core/Child.js +++ b/src/frontend/workspace/core/Child.js @@ -7,6 +7,7 @@ class Child { return { reference: Workspace.createReference(), removable: true, + movable: true, // TODO: }; } diff --git a/src/frontend/workspace/core/Section.js b/src/frontend/workspace/core/Section.js index a686af550d452eb1fb7264e20bc6b028dee6bdc4..207c08a5d1f1aaa19c7f3c6c4c1c833cc750255d 100644 --- a/src/frontend/workspace/core/Section.js +++ b/src/frontend/workspace/core/Section.js @@ -4,11 +4,22 @@ class Section extends Child { getDefaultProps() { return { ...super.getDefaultProps(), - weight: 1, visible: true, + resizable: true, + weight: 1, + minWeight: 0, + maxWeight: Number.MAX_VALUE, + size: -1, + minSize: 0, + maxSize: Number.MAX_VALUE, }; } + constructor(element) { + super(element); + this.relative = this.size === -1; + } + setVisible(visible) { this.visible = visible; this.parent.render(); diff --git a/src/frontend/workspace/core/SectionContainer.js b/src/frontend/workspace/core/SectionContainer.js index a79b77245b1bac8baa883cd7888cea4c603e5b65..3ecf541be81cb33e71e573f848e31a97207ede0f 100644 --- a/src/frontend/workspace/core/SectionContainer.js +++ b/src/frontend/workspace/core/SectionContainer.js @@ -37,35 +37,54 @@ class SectionContainer extends parentMixin(Section) { } } - resizeChild(index, position, size) { + resizeChild(index, position, containerSize) { const visibleChildren = this.children.filter(child => child.visible); - const weights = visibleChildren.map(child => child.weight); - const totalWeight = weights.reduce((sumWeight, weight) => sumWeight + weight, 0); - - const startWeight = weights.slice(0, index).reduce((sumWeight, weight) => sumWeight + weight, 0); - const endWeight = position / size * totalWeight; - - const oldWeight = weights[index]; - const newWeight = endWeight - startWeight; - - const oldScale = totalWeight - startWeight - oldWeight; - const newScale = totalWeight - startWeight - newWeight; - const ratio = newScale / oldScale; - - weights[index] = newWeight; - for (let i = index + 1; i < weights.length; i++) { - weights[i] *= ratio; + let prevChild = visibleChildren.slice(0, index).reverse().find(child => child.resizable); + let nextChild = visibleChildren.slice(index).find(child => child.resizable); + if (prevChild && nextChild) { + let totalSize = 0; + let totalWeight = 0; + let subtotalSize = 0; + let subtotalWeight = 0; + visibleChildren.forEach((child, i) => { + if (child.relative) { + totalWeight += child.weight; + if (i < index) subtotalWeight += child.weight; + } else { + totalSize += child.size; + if (i < index) subtotalSize += child.size; + } + }); + const factor = (containerSize - totalSize) / totalWeight; + const oldPosition = subtotalSize + subtotalWeight * factor; + let deltaSize = position - oldPosition; + if (prevChild.relative) { + deltaSize = Math.max((prevChild.minWeight - prevChild.weight) * factor, deltaSize); + deltaSize = Math.min((prevChild.maxWeight - prevChild.weight) * factor, deltaSize); + } else { + deltaSize = Math.max(prevChild.minSize - prevChild.size, deltaSize); + deltaSize = Math.min(prevChild.maxSize - prevChild.size, deltaSize); + } + if (nextChild.relative) { + deltaSize = Math.min((nextChild.weight - nextChild.minWeight) * factor, deltaSize); + deltaSize = Math.max((nextChild.weight - nextChild.maxWeight) * factor, deltaSize); + } else { + deltaSize = Math.min(nextChild.size - nextChild.minSize, deltaSize); + deltaSize = Math.max(nextChild.size - nextChild.maxSize, deltaSize); + } + const deltaWeight = deltaSize / factor; + if (prevChild.relative) { + prevChild.weight += deltaWeight; + } else { + prevChild.size += deltaSize; + } + if (nextChild.relative) { + nextChild.weight -= deltaWeight; + } else { + nextChild.size -= deltaSize; + } + this.render(); } - - for (let i = index; i < weights.length; i++) { - if (weights[i] / totalWeight * size < 20) return; - } - - for (let i = index; i < weights.length; i++) { - visibleChildren[i].weight = weights[i]; - } - - this.render(); } } diff --git a/src/frontend/workspace/core/TabContainer.js b/src/frontend/workspace/core/TabContainer.js index 5dbc2d1ca6742ade8201834e277d46b2159f45b4..6f78c1516870181de2e53738250afc9e0c138492 100644 --- a/src/frontend/workspace/core/TabContainer.js +++ b/src/frontend/workspace/core/TabContainer.js @@ -22,13 +22,15 @@ class TabContainer extends parentMixin(Section) { } addChild(child, index = this.children.length) { - super.addChild(child, index); - this.setTabIndex(Math.min(index, this.children.length - 1)); + super.addChild(child, index, () => { + this.setTabIndex(Math.min(index, this.children.length - 1)); + }); } removeChild(index) { - super.removeChild(index); - this.setTabIndex(Math.min(this.tabIndex, this.children.length - 1)); + super.removeChild(index, () => { + this.setTabIndex(Math.min(this.tabIndex, this.children.length - 1)); + }); } setTabIndex(tabIndex) { diff --git a/src/frontend/workspace/core/mixins/parentMixin.js b/src/frontend/workspace/core/mixins/parentMixin.js index 643c576035817b352a2fe956b936a5ea5116a881..abc55d93808877663b57f0ff48c473f8a07dd67d 100644 --- a/src/frontend/workspace/core/mixins/parentMixin.js +++ b/src/frontend/workspace/core/mixins/parentMixin.js @@ -13,7 +13,7 @@ const parentMixin = (Base = Child) => class Parent extends Base { return new Child(element); } - addChild(child, index = this.children.length) { + addChild(child, index = this.children.length, beforeRender) { if (child.parent === this) { const oldIndex = this.children.indexOf(child); this.children[oldIndex] = null; @@ -23,12 +23,14 @@ const parentMixin = (Base = Child) => class Parent extends Base { this.children.splice(index, 0, child); child.setParent(this); } + if(beforeRender) beforeRender(); this.render(); } - removeChild(index) { + removeChild(index, beforeRender) { this.children.splice(index, 1); if (this.children.length === 0) this.remove(); + if(beforeRender) beforeRender(); this.render(); }