Skip to content

Commit

Permalink
fix(LayoutGrid): Use layout stacks to switch between views in a layout
Browse files Browse the repository at this point in the history
This is most useful in the 2D and Split view, where the slice view can
change orientations.
  • Loading branch information
floryst committed Mar 5, 2018
1 parent 8955c74 commit 007c6c4
Showing 1 changed file with 64 additions and 2 deletions.
66 changes: 64 additions & 2 deletions Sources/layouts/LayoutGrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ export default class LayoutGrid extends React.Component {
constructor(props) {
super(props);

// populate by the layout stack loop below
this.state = {};

// Save this, as the layout config should not change
this.config = props.initialConfig;

this.viewRefs = {};
this.layoutInitActiveView = {};
this.layoutStacks = {};

Object.keys(this.config.layouts).forEach((layoutName) => {
const layout = this.config.layouts[layoutName];
Expand All @@ -23,6 +27,33 @@ export default class LayoutGrid extends React.Component {
if (viewName) {
this.layoutInitActiveView[layoutName] = viewName;
}

// process stacks
const gridY = layout.grid[1];
const tmpStacks = {};
Object.keys(layout.views).forEach((name) => {
const view = layout.views[name];
const [x, y] = view.cell;
const stackId = x * gridY + y;
tmpStacks[stackId] = tmpStacks[stackId] || [];
tmpStacks[stackId].push(name);
});

this.layoutStacks[layoutName] = {};
Object.keys(tmpStacks).forEach((stackId) => {
const stack = tmpStacks[stackId];
if (stack.length > 1) {
const id = `StackActive_${layoutName}_${stackId}`;
stack.forEach((view) => {
// set stack id for this view in this layout
this.layoutStacks[layoutName][view] = id;
// set view as visible in stack if possible
if (layout.views[view].defaultVisible || !this.state[id]) {
this.state[id] = view;
}
});
}
});
});
}

Expand All @@ -34,11 +65,29 @@ export default class LayoutGrid extends React.Component {

// activate initial view, if specified
if (this.props.layout in this.layoutInitActiveView) {
const viewName = this.layoutInitActiveView[this.props.layout];
let viewName = this.layoutInitActiveView[this.props.layout];

// if initial view is shadowed by another view in same stack,
// then activate the other view.
const stackId = this.layoutStacks[this.props.layout][viewName];
if (stackId) {
// if active view in stack is current view, then this is a no-op.
viewName = this.state[stackId];
}

this.viewRefs[viewName].activateView();
}
}

setStackView(newView) {
const stackId = this.layoutStacks[this.props.layout][newView];
if (stackId in this.state) {
this.setState({ [stackId]: newView }, () => {
this.viewRefs[newView].activateView();
});
}
}

setViewRef(name, ref) {
this.viewRefs[name] = ref;
}
Expand All @@ -52,20 +101,33 @@ export default class LayoutGrid extends React.Component {
};

const views = Object.keys(this.config.views).map((viewName) => {
const visible = viewName in layout.views;
const viewSpec = this.config.views[viewName];
const props = Object.assign({}, viewSpec.props);
const cellStyle = {};

let visible = viewName in layout.views;
if (visible) {
const layoutSpec = layout.views[viewName];

if (viewName in this.layoutStacks[this.props.layout]) {
const stackId = this.layoutStacks[this.props.layout][viewName];
visible = this.state[stackId] === viewName;
}

const [xCell, yCell] = layoutSpec.cell;
Object.assign(cellStyle, {
gridArea: `${xCell} / ${yCell} / ${xCell + 1} / ${yCell + 1}`,
});

Object.assign(props, layoutSpec.propOverrides);

// set our custom stack changing function
if (viewSpec.stackChangeFunc && props[viewSpec.stackChangeFunc]) {
const func = props[viewSpec.stackChangeFunc];
props[viewSpec.stackChangeFunc] = (...args) => {
this.setStackView(func(...args));
};
}
}

return (
Expand Down

0 comments on commit 007c6c4

Please sign in to comment.