Skip to content

Commit

Permalink
Merge pull request projectstorm#41 from projectstorm/improvements/res…
Browse files Browse the repository at this point in the history
…izing

Added r_overConstrained
  • Loading branch information
dylanvorster committed May 9, 2023
2 parents e22c46c + 515640e commit 93a94a7
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 16 deletions.
6 changes: 6 additions & 0 deletions .changeset/mean-fans-provide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@projectstorm/react-workspaces-behavior-divider-dropzone': minor
'@projectstorm/react-workspaces-core': minor
---

added r_overConstrained and fixed spelling mistake for internal r_dimensions field
11 changes: 11 additions & 0 deletions demo/stories/helpers/complexModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ import { WorkspaceEngine } from '@projectstorm/react-workspaces-core';

export const createComplexModel = (engine: WorkspaceEngine) => {
let model = new RootWorkspaceModel(engine);
model.registerListener({
overConstrainedChanged: () => {
console.log(`overconstrained: ${model.r_overConstrained ? 'true' : 'false'}`);

// when we overconstrained, we can use the directive below to cause the children layouts on the root model
// to be recomputed (this method exists on all ExpandNodeModels )
if (model.r_overConstrained) {
model.recomputeInitialSizes();
}
}
});
model.setHorizontal(true);

const trayFactory = engine.getFactory<WorkspaceTrayFactory>(WorkspaceTrayModel.NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const DropzoneDividersLayerWidget: React.FC<DropzoneDividersLayerWidgetPr
.flatten()
.filter((p) => p instanceof WorkspaceNodeModel)
.flatMap((m: WorkspaceNodeModel) => {
return m.r_divisons.map((division, index) => {
return m.r_divisions.map((division, index) => {
return (
<DropzoneDividerWidget
theme={props.theme?.()}
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/core/WorkspaceEngine.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import * as _ from 'lodash';
import { WorkspaceModelFactory } from './WorkspaceModelFactory';
import { WorkspaceModel } from '../core-models/WorkspaceModel';
import { WorkspaceEngineInterface } from './WorkspaceEngineInterface';
Expand Down Expand Up @@ -61,7 +62,7 @@ export class WorkspaceEngine extends BaseObserver<WorkspaceEngineListener> imple
this.invalidateLayout();
},
dimensionsInvalidated: () => {
this.invalidateDimensions();
this.invalidateDimensionsDebounced();
}
});
this.rootModel = model;
Expand All @@ -77,6 +78,10 @@ export class WorkspaceEngine extends BaseObserver<WorkspaceEngineListener> imple
this.iterateListeners((cb) => cb.layoutInvalidated?.());
}

invalidateDimensionsDebounced = _.debounce(() => {
this.invalidateDimensions();
}, 200);

invalidateDimensions() {
this.rootModel
.flatten()
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/core/dimensions/DimensionContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ export class DimensionContainer extends BaseObserver<DimensionContainerListener>
});
}

protected fireUpdated = _.debounce(() => {
protected fireUpdated = () => {
this.iterateListeners((cb) => cb.updated?.());
}, 0);
};

get dimensions(): IDimension {
return {
Expand Down
12 changes: 10 additions & 2 deletions packages/core/src/core/dimensions/Size.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BaseListener, BaseObserver } from '../BaseObserver';

export interface SizeListener extends BaseListener {
updated: () => any;
updated: (event: { prev: ISize }) => any;
}

export interface ISize {
Expand Down Expand Up @@ -53,6 +53,10 @@ export class Size extends BaseObserver<SizeListener> implements ISize {

update(size: Partial<ISize>) {
let updated = false;
let old: ISize = {
width: this._width,
height: this._height
};
if (size.width != null && size.width !== this.width) {
this._width = size.width;
updated = true;
Expand All @@ -62,7 +66,11 @@ export class Size extends BaseObserver<SizeListener> implements ISize {
updated = true;
}
if (updated) {
this.iterateListeners((cb) => cb.updated?.());
this.iterateListeners((cb) =>
cb.updated?.({
prev: old
})
);
}
}
}
8 changes: 6 additions & 2 deletions packages/core/src/entities/node/ExpandNodeModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export interface ExpandNodeModelSerialized extends WorkspaceNodeModelSerialized
/**
* This is a smarter version of the standard Node model which can work with
* panels that expand, and treats them like standard panels, allowing them to resize
*
* The magic happens in the getPanelDirective() method, which tells child to behave slightly differently.
* This means for example, we can cause the last panel in a set to expand, even if none of the children actually
* want to expand (expandHorizontal/Vertical == false)
*/
export class ExpandNodeModel<
S extends ExpandNodeModelSerialized = ExpandNodeModelSerialized
Expand Down Expand Up @@ -104,11 +108,11 @@ export class ExpandNodeModel<

getResizeDivisions(): ResizeDivision[] {
let divs: ResizeDivision[] = [];
for (let i = 1; i < this.r_divisons.length - 1; i++) {
for (let i = 1; i < this.r_divisions.length - 1; i++) {
divs.push({
before: this.children[i - 1],
after: this.children[i],
dimensions: this.r_divisons[i],
dimensions: this.r_divisions[i],
vertical: !this.vertical
});
}
Expand Down
25 changes: 19 additions & 6 deletions packages/core/src/entities/node/WorkspaceNodeModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface ResizeDivision {

export interface WorkspaceNodeModelListener extends WorkspaceCollectionModelListener {
divisionsRecomputed: () => any;
overConstrainedChanged: () => any;
}

export interface WorkspaceNodeModelSerialized extends SerializedCollectionModel {
Expand All @@ -31,12 +32,24 @@ export class WorkspaceNodeModel<
static NAME = 'srw-node';

vertical: boolean;
r_divisons: DimensionContainer[];
r_divisions: DimensionContainer[];
r_overConstrained: boolean;

constructor(type: string = WorkspaceNodeModel.NAME) {
super(type);
this.vertical = true;
this.r_divisons = [];
this.r_divisions = [];
this.r_overConstrained = false;
}

// !----------- additional renders ---------

setOverConstrained(overConstrainedChanged: boolean) {
if (this.r_overConstrained === overConstrainedChanged) {
return;
}
this.r_overConstrained = overConstrainedChanged;
this.iterateListeners((cb) => cb.overConstrainedChanged?.());
}

// !----------- serialize ---------
Expand All @@ -57,7 +70,7 @@ export class WorkspaceNodeModel<

getResizeDivisions(): ResizeDivision[] {
let divs: ResizeDivision[] = [];
for (let i = 1; i < this.r_divisons.length - 1; i++) {
for (let i = 1; i < this.r_divisions.length - 1; i++) {
if (this.vertical) {
if (this.children[i - 1].expandVertical && this.children[i].expandVertical) {
continue;
Expand All @@ -71,7 +84,7 @@ export class WorkspaceNodeModel<
divs.push({
before: this.children[i - 1],
after: this.children[i],
dimensions: this.r_divisons[i],
dimensions: this.r_divisions[i],
vertical: !this.vertical
});
}
Expand All @@ -86,11 +99,11 @@ export class WorkspaceNodeModel<
}

getAllRenderDimensions(): DimensionContainer[] {
return super.getAllRenderDimensions().concat(Array.from(this.r_divisons.values()));
return super.getAllRenderDimensions().concat(Array.from(this.r_divisions.values()));
}

recomputeDivisions() {
this.r_divisons = this.children
this.r_divisions = this.children
.map((c) => {
return new DimensionContainer();
})
Expand Down
14 changes: 13 additions & 1 deletion packages/core/src/entities/node/WorkspaceNodeWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { WorkspaceModel } from '../../core-models/WorkspaceModel';
import { useModelElement } from '../../widgets/hooks/useModelElement';
import { DirectionalLayoutWidget } from '../../widgets/layouts/DirectionalLayoutWidget';
import { DimensionContainer } from '../../core/dimensions/DimensionContainer';
import { useEffect } from 'react';

export interface WorkspaceNodeWidgetProps {
engine: WorkspaceEngine;
Expand All @@ -22,11 +23,22 @@ export const WorkspaceNodeWidget: React.FC<WorkspaceNodeWidgetProps> = (props) =
engine: props.engine,
model: props.model
});
useEffect(() => {
return props.model.r_dimensions.registerListener({
updated: () => {
if (props.model.vertical) {
props.model.setOverConstrained(ref.current.scrollHeight > props.model.r_dimensions.size.height);
} else {
props.model.setOverConstrained(ref.current.scrollWidth > props.model.r_dimensions.size.width);
}
}
});
}, []);
return (
<S.DirectionalLayout
forwardRef={ref}
dimensionContainerForDivider={(index: number) => {
return props.model.r_divisons[index];
return props.model.r_divisions[index];
}}
getChildSizeDirective={(model) => {
return props.model.getPanelDirective(model);
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/widgets/layers/debug/DebugLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export const DebugLayerWidget: React.FC<DebugLayerWidgetProps> = (props) => {
? props.model
.flatten()
.filter((p) => p instanceof WorkspaceNodeModel)
.flatMap((m: WorkspaceNodeModel) => m.r_divisons)
.flatMap((m: WorkspaceNodeModel) => m.r_divisions)
.map((m) => {
return <S.Outline dimension={m} key={m.id} />;
})
Expand Down

0 comments on commit 93a94a7

Please sign in to comment.