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

Add non-relative sections to workspace

上级 23e6b3ab
$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
......@@ -94,13 +94,22 @@ class App extends React.Component {
return categories && categoryKey && algorithmKey && (
<div className={styles.app}>
<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)}
navigatorOpened={navigatorOpened} />
<WSSectionContainer>
<Navigator wsProps={{ weight: .4, removable: false, reference: this.navigatorReference }} />
<Navigator wsProps={{
removable: false,
size: 240,
minSize: 120,
reference: this.navigatorReference
}} />
<WSSectionContainer wsProps={{
weight: 1,
removable: false,
horizontal: false,
reference: this.spawnReference,
......
......@@ -6,7 +6,7 @@
align-items: stretch;
padding: 16px;
font-size: $font-size-large;
overflow-y: scroll;
overflow-y: auto;
li {
margin: 10px 0px;
......
......@@ -33,7 +33,7 @@
.algorithm_list {
flex: 1;
overflow-y: scroll;
overflow-y: auto;
}
.footer {
......
......@@ -6,7 +6,7 @@
align-items: stretch;
padding: 16px;
font-size: $font-size-large;
overflow-y: scroll;
overflow-y: auto;
a {
text-decoration: underline;
......
......@@ -6,7 +6,7 @@
padding: 24px;
display: flex;
flex-direction: column;
overflow-y: scroll;
overflow-y: auto;
.message {
margin: 2px 0;
......
......@@ -17,8 +17,8 @@ class WSSectionContainer extends React.Component {
const { offsetLeft, offsetTop, offsetWidth, offsetHeight } = targetElement.parentElement;
const { horizontal } = this.core;
const position = horizontal ? clientX - offsetLeft : clientY - offsetTop;
const size = horizontal ? offsetWidth : offsetHeight;
this.core.resizeChild(index, position, size);
const containerSize = horizontal ? offsetWidth : offsetHeight;
this.core.resizeChild(index, position, containerSize);
}
handleDropTabToContainer(tab, index) {
......@@ -50,59 +50,60 @@ class WSSectionContainer extends React.Component {
const { children, horizontal } = this.core;
const visibleChildren = children.filter(child => 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(
<Divider key={`divider-before-${child.key}`} horizontal={horizontal}
onResize={visibleIndex > 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(
<div key={child.key} className={classes(styles.wrapper)} style={style}>
{child.element}
</div>
);
} else {
elements.push(
<Divider key={`divider-${i}`} horizontal={horizontal}
onResize={(target, x, y) => this.handleResize(visibleIndex - 1, target, x, y)}
onDropTab={tab => this.handleDropTabToContainer(tab, i)}
onDropSection={section => this.handleDropSectionToContainer(section, i)} />
<div key={child.key} className={classes(styles.wrapper, !horizontal && styles.horizontal)} style={style}>
<Divider horizontal={!horizontal}
onDropTab={tab => this.handleDropTabToSection(tab, index, true)}
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 (
<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>
);
}
......
......@@ -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;
......
......@@ -7,6 +7,7 @@ class Child {
return {
reference: Workspace.createReference(),
removable: true,
movable: true, // TODO:
};
}
......
......@@ -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();
......
......@@ -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();
}
}
......
......@@ -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) {
......
......@@ -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();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册