提交 22f93120 编写于 作者: J Jason Park 提交者: Jason

Add non-relative sections to workspace

上级 23e6b3ab
$line-height: 32px; $line-height: 32px;
$font-size-normal: 12px; $font-size-normal: 12px;
$font-size-large: 14px; $font-size-large: 14px;
\ No newline at end of file
:export {
lineHeight: $line-height;
fontSizeNormal: $font-size-normal;
fontSizeLarge: $font-size-large;
}
\ No newline at end of file
...@@ -94,13 +94,22 @@ class App extends React.Component { ...@@ -94,13 +94,22 @@ class App extends React.Component {
return categories && categoryKey && algorithmKey && ( return categories && categoryKey && algorithmKey && (
<div className={styles.app}> <div className={styles.app}>
<Workspace className={styles.workspace} wsProps={{ horizontal: false }}> <Workspace className={styles.workspace} wsProps={{ horizontal: false }}>
<Header wsProps={{ weight: .1, removable: false }} <Header wsProps={{
removable: false,
size: 32,
minSize: 32,
maxSize: 64,
}}
onClickTitleBar={() => this.navigatorReference.core.setVisible(!this.navigatorReference.core.visible)} onClickTitleBar={() => this.navigatorReference.core.setVisible(!this.navigatorReference.core.visible)}
navigatorOpened={navigatorOpened} /> navigatorOpened={navigatorOpened} />
<WSSectionContainer> <WSSectionContainer>
<Navigator wsProps={{ weight: .4, removable: false, reference: this.navigatorReference }} /> <Navigator wsProps={{
removable: false,
size: 240,
minSize: 120,
reference: this.navigatorReference
}} />
<WSSectionContainer wsProps={{ <WSSectionContainer wsProps={{
weight: 1,
removable: false, removable: false,
horizontal: false, horizontal: false,
reference: this.spawnReference, reference: this.spawnReference,
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
align-items: stretch; align-items: stretch;
padding: 16px; padding: 16px;
font-size: $font-size-large; font-size: $font-size-large;
overflow-y: scroll; overflow-y: auto;
li { li {
margin: 10px 0px; margin: 10px 0px;
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
.algorithm_list { .algorithm_list {
flex: 1; flex: 1;
overflow-y: scroll; overflow-y: auto;
} }
.footer { .footer {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
align-items: stretch; align-items: stretch;
padding: 16px; padding: 16px;
font-size: $font-size-large; font-size: $font-size-large;
overflow-y: scroll; overflow-y: auto;
a { a {
text-decoration: underline; text-decoration: underline;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
padding: 24px; padding: 24px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow-y: scroll; overflow-y: auto;
.message { .message {
margin: 2px 0; margin: 2px 0;
......
...@@ -17,8 +17,8 @@ class WSSectionContainer extends React.Component { ...@@ -17,8 +17,8 @@ class WSSectionContainer extends React.Component {
const { offsetLeft, offsetTop, offsetWidth, offsetHeight } = targetElement.parentElement; const { offsetLeft, offsetTop, offsetWidth, offsetHeight } = targetElement.parentElement;
const { horizontal } = this.core; const { horizontal } = this.core;
const position = horizontal ? clientX - offsetLeft : clientY - offsetTop; const position = horizontal ? clientX - offsetLeft : clientY - offsetTop;
const size = horizontal ? offsetWidth : offsetHeight; const containerSize = horizontal ? offsetWidth : offsetHeight;
this.core.resizeChild(index, position, size); this.core.resizeChild(index, position, containerSize);
} }
handleDropTabToContainer(tab, index) { handleDropTabToContainer(tab, index) {
...@@ -50,59 +50,60 @@ class WSSectionContainer extends React.Component { ...@@ -50,59 +50,60 @@ class WSSectionContainer extends React.Component {
const { children, horizontal } = this.core; const { children, horizontal } = this.core;
const visibleChildren = children.filter(child => child.visible); const visibleChildren = children.filter(child => child.visible);
const weights = visibleChildren.map(section => section.weight); const totalWeight = visibleChildren.reduce((sumWeight, child) => sumWeight + (child.relative ? child.weight : 0), 0);
const totalWeight = weights.reduce((sumWeight, weight) => sumWeight + weight, 0);
const elements = []; const elements = [];
children.forEach((child, i) => { visibleChildren.forEach((child, visibleIndex) => {
if (!child.visible) return; const index = children.indexOf(child);
const visibleIndex = visibleChildren.findIndex(visibleChild => visibleChild === child); elements.push(
const portion = child.weight / totalWeight; <Divider key={`divider-before-${child.key}`} horizontal={horizontal}
const style = { flex: portion }; onResize={visibleIndex > 0 && ((target, dx, dy) => this.handleResize(visibleIndex, target, dx, dy))}
if (elements.length) { 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(
<div key={child.key} className={classes(styles.wrapper)} style={style}>
{child.element}
</div>
);
} else {
elements.push( elements.push(
<Divider key={`divider-${i}`} horizontal={horizontal} <div key={child.key} className={classes(styles.wrapper, !horizontal && styles.horizontal)} style={style}>
onResize={(target, x, y) => this.handleResize(visibleIndex - 1, target, x, y)} <Divider horizontal={!horizontal}
onDropTab={tab => this.handleDropTabToContainer(tab, i)} onDropTab={tab => this.handleDropTabToSection(tab, index, true)}
onDropSection={section => this.handleDropSectionToContainer(section, i)} /> onDropSection={section => this.handleDropSectionToSection(section, index, true)} />
{child.element}
<Divider horizontal={!horizontal}
onDropTab={tab => this.handleDropTabToSection(tab, index)}
onDropSection={section => this.handleDropSectionToSection(section, index)} />
</div>
);
}
if (visibleIndex === visibleChildren.length - 1) {
elements.push(
<Divider key={`divider-after-${child.key}`} horizontal={horizontal}
onDropTab={tab => this.handleDropTabToContainer(tab, index + 1)}
onDropSection={section => this.handleDropSectionToContainer(section, index + 1)} />
); );
} }
elements.push(
<div key={child.key} className={classes(styles.wrapper, !horizontal && styles.horizontal)}
style={style}>
<Divider horizontal={!horizontal}
onDropTab={tab => this.handleDropTabToSection(tab, i, true)}
onDropSection={section => this.handleDropSectionToSection(section, i, true)} />
{child.element}
<Divider horizontal={!horizontal}
onDropTab={tab => this.handleDropTabToSection(tab, i)}
onDropSection={section => this.handleDropSectionToSection(section, i)} />
</div>
);
}); });
if (elements.length) {
const firstIndex = children.indexOf(visibleChildren[0]);
const lastIndex = children.indexOf(visibleChildren[visibleChildren.length - 1]);
elements.unshift(
<Divider key="divider-first" horizontal={horizontal}
onDropTab={tab => this.handleDropTabToContainer(tab, firstIndex)}
onDropSection={section => this.handleDropSectionToContainer(section, firstIndex)} />
);
elements.push(
<Divider key="divider-last" horizontal={horizontal}
onDropTab={tab => this.handleDropTabToContainer(tab, lastIndex + 1)}
onDropSection={section => this.handleDropSectionToContainer(section, lastIndex + 1)} />
);
} else {
elements.push(
<Droppable key="empty" className={styles.wrapper} droppingClassName={styles.dropping}
onDropTab={tab => this.handleDropTabToContainer(tab)}
onDropSection={section => this.handleDropSectionToContainer(section)} />
);
}
return ( return (
<div className={classes(styles.container, horizontal && styles.horizontal, className)}> <div className={classes(styles.container, horizontal && styles.horizontal, className)}>
{elements} {
elements.length ?
elements : (
<Droppable key="empty" className={styles.wrapper} droppingClassName={styles.dropping}
onDropTab={tab => this.handleDropTabToContainer(tab)}
onDropSection={section => this.handleDropSectionToContainer(section)} />
)
}
</div> </div>
); );
} }
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
display: flex; display: flex;
align-items: stretch; align-items: stretch;
height: $line-height; height: $line-height;
overflow-x: scroll; overflow-x: auto;
white-space: nowrap; white-space: nowrap;
flex-shrink: 0; flex-shrink: 0;
cursor: move; cursor: move;
......
...@@ -7,6 +7,7 @@ class Child { ...@@ -7,6 +7,7 @@ class Child {
return { return {
reference: Workspace.createReference(), reference: Workspace.createReference(),
removable: true, removable: true,
movable: true, // TODO:
}; };
} }
......
...@@ -4,11 +4,22 @@ class Section extends Child { ...@@ -4,11 +4,22 @@ class Section extends Child {
getDefaultProps() { getDefaultProps() {
return { return {
...super.getDefaultProps(), ...super.getDefaultProps(),
weight: 1,
visible: true, 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) { setVisible(visible) {
this.visible = visible; this.visible = visible;
this.parent.render(); this.parent.render();
......
...@@ -37,35 +37,54 @@ class SectionContainer extends parentMixin(Section) { ...@@ -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 visibleChildren = this.children.filter(child => child.visible);
const weights = visibleChildren.map(child => child.weight); let prevChild = visibleChildren.slice(0, index).reverse().find(child => child.resizable);
const totalWeight = weights.reduce((sumWeight, weight) => sumWeight + weight, 0); let nextChild = visibleChildren.slice(index).find(child => child.resizable);
if (prevChild && nextChild) {
const startWeight = weights.slice(0, index).reduce((sumWeight, weight) => sumWeight + weight, 0); let totalSize = 0;
const endWeight = position / size * totalWeight; let totalWeight = 0;
let subtotalSize = 0;
const oldWeight = weights[index]; let subtotalWeight = 0;
const newWeight = endWeight - startWeight; visibleChildren.forEach((child, i) => {
if (child.relative) {
const oldScale = totalWeight - startWeight - oldWeight; totalWeight += child.weight;
const newScale = totalWeight - startWeight - newWeight; if (i < index) subtotalWeight += child.weight;
const ratio = newScale / oldScale; } else {
totalSize += child.size;
weights[index] = newWeight; if (i < index) subtotalSize += child.size;
for (let i = index + 1; i < weights.length; i++) { }
weights[i] *= ratio; });
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();
} }
} }
......
...@@ -22,13 +22,15 @@ class TabContainer extends parentMixin(Section) { ...@@ -22,13 +22,15 @@ class TabContainer extends parentMixin(Section) {
} }
addChild(child, index = this.children.length) { addChild(child, index = this.children.length) {
super.addChild(child, index); super.addChild(child, index, () => {
this.setTabIndex(Math.min(index, this.children.length - 1)); this.setTabIndex(Math.min(index, this.children.length - 1));
});
} }
removeChild(index) { removeChild(index) {
super.removeChild(index); super.removeChild(index, () => {
this.setTabIndex(Math.min(this.tabIndex, this.children.length - 1)); this.setTabIndex(Math.min(this.tabIndex, this.children.length - 1));
});
} }
setTabIndex(tabIndex) { setTabIndex(tabIndex) {
......
...@@ -13,7 +13,7 @@ const parentMixin = (Base = Child) => class Parent extends Base { ...@@ -13,7 +13,7 @@ const parentMixin = (Base = Child) => class Parent extends Base {
return new Child(element); return new Child(element);
} }
addChild(child, index = this.children.length) { addChild(child, index = this.children.length, beforeRender) {
if (child.parent === this) { if (child.parent === this) {
const oldIndex = this.children.indexOf(child); const oldIndex = this.children.indexOf(child);
this.children[oldIndex] = null; this.children[oldIndex] = null;
...@@ -23,12 +23,14 @@ const parentMixin = (Base = Child) => class Parent extends Base { ...@@ -23,12 +23,14 @@ const parentMixin = (Base = Child) => class Parent extends Base {
this.children.splice(index, 0, child); this.children.splice(index, 0, child);
child.setParent(this); child.setParent(this);
} }
if(beforeRender) beforeRender();
this.render(); this.render();
} }
removeChild(index) { removeChild(index, beforeRender) {
this.children.splice(index, 1); this.children.splice(index, 1);
if (this.children.length === 0) this.remove(); if (this.children.length === 0) this.remove();
if(beforeRender) beforeRender();
this.render(); this.render();
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册