Add support for new theme

This commit is contained in:
Paulo Gustavo Veiga 2023-02-28 21:54:30 -03:00
parent dc1e9c6549
commit e64c72d719
13 changed files with 123 additions and 137 deletions

View File

@ -25,7 +25,8 @@
"cypress": "^12.3.0",
"cypress-image-snapshot": "^4.0.1",
"jest-transform-stub": "^2.0.0",
"react": "^18.2.0"
"react": "^18.2.0",
"start-server-and-test": "^2.0.0"
},
"dependencies": {
"@wisemapping/mindplot": "^5.0.20",

View File

@ -224,7 +224,7 @@ class NodePropertyBuilder {
if (!this.topicShapeModel)
this.topicShapeModel = {
getValue: () => this.uniqueOrNull((node) => node.getShapeType()) as TopicShapeType,
setValue: (value: TopicShapeType) => this.designer.changeTopicShape(value),
setValue: (value: TopicShapeType) => this.designer.changeShapeType(value),
};
return this.topicShapeModel;
}

View File

@ -43,8 +43,8 @@ class CentralTopic extends Topic {
super.setCursor(type === 'move' ? 'default' : type);
}
updateTopicShape(): void {
// Overwite behaviour ...
updateTopicShape(): boolean {
return true;
}
updatePositionOnChangeSize(): void {

View File

@ -898,7 +898,7 @@ class Designer extends EventDispispatcher<DesignerEventType> {
}
}
changeTopicShape(shape: TopicShapeType): void {
changeShapeType(shape: TopicShapeType): void {
const validateFunc = (topic: Topic) =>
!(topic.getType() === 'CentralTopic' && (shape === 'line' || shape === 'none'));

View File

@ -41,6 +41,7 @@ class DesignerActionRunner {
$assert(command, 'command can not be null');
command.execute(this._context);
this._undoManager.enqueue(command);
this.fireChangeEvent();
LayoutEventBus.fireEvent('forceLayout');
}

View File

@ -65,10 +65,6 @@ class MainTopic extends Topic {
return group;
}
updateTopicShape() {
this.redrawShapeType();
}
disconnect(canvas: Canvas) {
super.disconnect(canvas);

View File

@ -199,12 +199,10 @@ class StandaloneActionDispatcher extends ActionDispatcher {
}
changeShapeTypeToTopic(topicsIds: number[], shapeType: TopicShapeType) {
$assert(topicsIds, 'topicsIds can not be null');
$assert(shapeType, 'shapeType can not be null');
const commandFunc = (topic: Topic, commandShapeType: TopicShapeType) => {
const result = topic.getShapeType();
topic.setShapeType(commandShapeType);
return result;
};

View File

@ -117,34 +117,38 @@ abstract class Topic extends NodeGraph {
return this._parent;
}
protected redrawShapeType() {
this.removeInnerShape();
updateTopicShape(): boolean {
const result = this.getInnerShape().getShapeType() !== this.getShapeType();
if (result) {
this.removeInnerShape();
// Create a new one ...
const innerShape = this.getInnerShape();
// Create a new one ...
const innerShape = this.getInnerShape();
// Update figure size ...
const size = this.getSize();
this.setSize(size, true);
// Update figure size ...
const size = this.getSize();
this.setSize(size, true);
const group = this.get2DElement();
innerShape.appendTo(group);
const group = this.get2DElement();
innerShape.appendTo(group);
// Move text to the front ...
const text = this.getOrBuildTextShape();
text.moveToFront();
// Move text to the front ...
const text = this.getOrBuildTextShape();
text.moveToFront();
// Move iconGroup to front ...
const iconGroup = this.getIconGroup();
if (iconGroup) {
iconGroup.moveToFront();
}
// Move connector to front
const connector = this.getShrinkConnector();
if (connector) {
connector.moveToFront();
// Move iconGroup to front ...
const iconGroup = this.getIconGroup();
if (iconGroup) {
iconGroup.moveToFront();
}
// Move connector to front
const connector = this.getShrinkConnector();
if (connector) {
connector.moveToFront();
}
}
return result;
}
getShapeType(): TopicShapeType {
@ -709,7 +713,7 @@ abstract class Topic extends NodeGraph {
this.get2DElement().setPosition(cx, cy);
// Update connection lines ...
this._updateConnectionLines();
this.updateConnection();
// Check object state.
this.invariant();
@ -735,21 +739,6 @@ abstract class Topic extends NodeGraph {
return result;
}
private _updateConnectionLines(): void {
// Update this to parent line ...
const outgoingLine = this.getOutgoingLine();
if (outgoingLine) {
outgoingLine.redraw();
}
// Update all the incoming lines ...
const incomingLines = this.getIncomingLines();
incomingLines.forEach((line) => line.redraw());
// Update relationship lines
this._relationships.forEach((r) => r.redraw());
}
setBranchVisibility(value: boolean): void {
let current: Topic = this;
let parent: Topic | null = this;
@ -948,7 +937,6 @@ abstract class Topic extends NodeGraph {
const model = this.getModel();
model.setOrder(value);
// In case of drag a node, color change based on the order ...
this.redraw();
}
@ -964,14 +952,10 @@ abstract class Topic extends NodeGraph {
// Create a connection line ...
const outgoingLine = this.createConnectionLine(targetTopic);
// outgoingLine.setVisibility(false);
this._outgoingLine = outgoingLine;
canvas.append(outgoingLine);
// Update figure is necessary.
this.updateTopicShape(targetTopic);
// Display connection node...
const connector = targetTopic.getShrinkConnector();
if (connector) {
@ -984,6 +968,10 @@ abstract class Topic extends NodeGraph {
parentNode: targetTopic.getModel(),
childNode: this.getModel(),
});
// Hack for the case of first node created, it needs to review the positioning problem.
LayoutEventBus.fireEvent('forceLayout');
this.redraw();
}
}
@ -992,8 +980,6 @@ abstract class Topic extends NodeGraph {
return new ConnectionLine(this, targetTopic, type);
}
abstract updateTopicShape(targetTopic: Topic): void;
append(child: Topic): void {
const children = this.getChildren();
children.push(child);
@ -1060,17 +1046,15 @@ abstract class Topic extends NodeGraph {
return result;
}
private redrawConnection(): boolean {
private updateConnection(): boolean {
let result = false;
if (this._isInWorkspace) {
// Adjust connection line if there is a change in the parent...
if (this._outgoingLine) {
// Has the style change ?
const connStyleChanged =
this._outgoingLine.getLineType() !== this.getParent()!.getConnectionStyle();
if (connStyleChanged) {
// Todo: Review static reference ...
const workspace = designer.getWorkSpace();
this._outgoingLine.removeFromWorkspace(workspace);
@ -1079,11 +1063,18 @@ abstract class Topic extends NodeGraph {
this._outgoingLine.setVisibility(this.isVisible());
workspace.append(this._outgoingLine);
const incomingLines = this.getIncomingLines();
incomingLines.forEach((line) => line.redraw());
result = true;
}
// Force the repaint in case that the main topic color has changed.
const borderColor = this.getBorderColor();
this._connector!.setColor(borderColor);
this._outgoingLine.redraw();
result = true;
}
}
return result;
@ -1094,11 +1085,8 @@ abstract class Topic extends NodeGraph {
const theme = ThemeFactory.create(this.getModel());
const textShape = this.getOrBuildTextShape();
// Needs to update inner shape ...
const shapeType = this.getShapeType();
if (shapeType !== this._innerShape?.getShapeType()) {
this.redrawShapeType();
}
// Update shape ...
const shapeChanged = this.updateTopicShape();
// Update font ...
const fontColor = this.getFontColor();
@ -1145,32 +1133,27 @@ abstract class Topic extends NodeGraph {
const topicWith = iconGroupWith + 2 * textIconSpacing + textWidth + padding * 2;
// Update connections ...
const changed = this.redrawConnection();
this.setSize({ width: topicWith, height: topicHeight }, changed);
const connectionChanged = this.updateConnection();
this.setSize({ width: topicWith, height: topicHeight }, connectionChanged);
// Adjust all topic elements positions ...
const yPosition = (topicHeight - textHeight) / 2;
iconGroup.setPosition(padding, yPosition - yPosition / 4);
textShape.setPosition(padding + iconGroupWith + textIconSpacing, yPosition);
// Update relationship lines
this._relationships.forEach((r) => r.redraw());
// Update topic color ...
const innerShape = this.getInnerShape();
const borderColor = this.getBorderColor();
this.getInnerShape().setStroke(null, 'solid', borderColor);
innerShape.setStroke(null, 'solid', borderColor);
const bgColor = this.getBackgroundColor();
this.getInnerShape().setFill(bgColor);
innerShape.setFill(bgColor);
// Force the repaint in case that the main topic color has changed.
if (this.getParent()) {
this._connector!.setColor(borderColor);
if (this.getParent()?.isCentralTopic()) {
this._outgoingLine?.redraw();
}
}
if (redrawChildren) {
this.getChildren().forEach((t) => t.redraw(redrawChildren));
if (redrawChildren || shapeChanged || connectionChanged) {
this.getChildren().forEach((t) => t.redraw(true));
}
}
}

View File

@ -199,7 +199,6 @@ class LayoutManager extends EventDispispatcher<LayoutEventType> {
node.resetPositionState();
node.resetOrderState();
node.resetFreeState();
this._events.push(event);
}
this._collectChanges(this._treeSet.getChildren(node));

View File

@ -55,43 +55,30 @@ class Node {
return this._id;
}
/** */
setFree(value) {
this._setProperty('free', value);
}
/** */
isFree() {
return this._getProperty('free');
}
/** */
hasFreeChanged() {
return this._isPropertyChanged('free');
}
/** */
hasFreeDisplacementChanged() {
return this._isPropertyChanged('freeDisplacement');
return this.isPropertyChanged('freeDisplacement');
}
/** */
setShrunken(value: boolean) {
this._setProperty('shrink', value);
this.setProperty('shrink', value);
}
/** */
areChildrenShrunken() {
return this._getProperty('shrink');
return this.getProperty('shrink');
}
/** */
setOrder(order: number) {
$assert(
typeof order === 'number' && Number.isFinite(order),
`Order can not be null. Value:${order}`,
);
this._setProperty('order', order);
if (this.getOrder() !== order) {
this.setProperty('order', order);
}
}
/** */
@ -118,68 +105,75 @@ class Node {
}
}
/** */
getOrder() {
return this._getProperty('order');
getOrder(): number {
return this.getProperty('order') as number;
}
/** */
hasOrderChanged() {
return this._isPropertyChanged('order');
return this.isPropertyChanged('order');
}
/** */
hasPositionChanged() {
return this._isPropertyChanged('position');
return this.isPropertyChanged('position');
}
/** */
hasSizeChanged(): boolean {
return this._isPropertyChanged('size');
return this.isPropertyChanged('size');
}
/** */
getPosition(): PositionType {
return this._getProperty('position');
return this.getProperty('position') as PositionType;
}
/** */
setSize(size: SizeType) {
this._setProperty('size', { ...size });
setSize(size: SizeType): void {
const currentSize = this.getSize();
if (
!currentSize ||
(currentSize &&
(Math.abs(currentSize.height - size.height) > 0.5 ||
Math.abs(currentSize.width - size.width) > 0.5))
) {
this.setProperty('size', { ...size });
}
}
/** */
getSize(): SizeType {
return this._getProperty('size');
return this.getProperty('size') as SizeType;
}
setFreeDisplacement(displacement: PositionType) {
setFreeDisplacement(displacement: PositionType): void {
const oldDisplacement = this.getFreeDisplacement();
const newDisplacement = {
x: oldDisplacement.x + displacement.x,
y: oldDisplacement.y + displacement.y,
};
this._setProperty('freeDisplacement', { ...newDisplacement });
this.setProperty('freeDisplacement', { ...newDisplacement });
}
/** */
resetFreeDisplacement() {
this._setProperty('freeDisplacement', { x: 0, y: 0 });
}
/** */
getFreeDisplacement() {
const freeDisplacement = this._getProperty('freeDisplacement');
getFreeDisplacement(): PositionType {
const freeDisplacement = this.getProperty('freeDisplacement') as PositionType;
return freeDisplacement || { x: 0, y: 0 };
}
setPosition(position: PositionType) {
setPosition(position: PositionType): void {
// This is a performance improvement to avoid movements that really could be avoided.
this._setProperty('position', position);
const currentPos = this.getPosition();
if (
!currentPos ||
(currentPos &&
(Math.abs(currentPos.x - position.x) > 0.5 || Math.abs(currentPos.y - position.y) > 0.5))
) {
this.setProperty('position', { ...position });
}
}
_setProperty(key: string, value) {
setProperty(key: string, value) {
let prop = this._properties[key];
if (!prop) {
prop = {
@ -198,12 +192,12 @@ class Node {
this._properties[key] = prop;
}
_getProperty(key: string) {
private getProperty(key: string): null | number | PositionType | SizeType {
const prop = this._properties[key];
return $defined(prop) ? prop.value : null;
}
_isPropertyChanged(key) {
isPropertyChanged(key: string) {
const prop = this._properties[key];
return prop ? prop.hasChanged : false;
}

View File

@ -60,10 +60,6 @@ class OriginalLayout {
throw new Error('Node already disconnected');
}
// Make it fixed
node.setFree(false);
node.resetFreeDisplacement();
// Remove from children list.
const sorter = parent.getSorter();
sorter.detach(this._treeSet, node);
@ -174,9 +170,6 @@ class OriginalLayout {
private fixOverlapping(node: Node, heightById: Map<number, number>): void {
const children = this._treeSet.getChildren(node);
if (node.isFree()) {
this._shiftBranches(node, heightById);
}
children.forEach((child) => {
this.fixOverlapping(child, heightById);
});
@ -196,7 +189,7 @@ class OriginalLayout {
OriginalLayout._branchesOverlap(shiftedBranch, sibling, heightById),
);
/* eslint-enable */
if (!sibling.isFree() || overlappingOccurs) {
if (overlappingOccurs) {
const sAmount = node.getFreeDisplacement().y;
this._treeSet.shiftBranchPosition(sibling, 0, sAmount);
shiftedBranches.push(sibling);

View File

@ -288,7 +288,7 @@ class RootedTreeSet {
if (this._rootNodes.includes(node)) {
fillColor = '#000';
} else {
fillColor = node.isFree() ? '#abc' : '#c00';
fillColor = '#c00';
}
rect.attr('fill', fillColor);

View File

@ -6421,6 +6421,7 @@ __metadata:
react: ^18.2.0
react-color: ^2.19.3
react-loader-spinner: ^5.3.4
start-server-and-test: ^2.0.0
peerDependencies:
"@emotion/react": ^11.10.5
"@emotion/styled": ^11.10.5
@ -20604,6 +20605,26 @@ __metadata:
languageName: node
linkType: hard
"start-server-and-test@npm:^2.0.0":
version: 2.0.0
resolution: "start-server-and-test@npm:2.0.0"
dependencies:
arg: ^5.0.2
bluebird: 3.7.2
check-more-types: 2.24.0
debug: 4.3.4
execa: 5.1.1
lazy-ass: 1.6.0
ps-tree: 1.2.0
wait-on: 7.0.1
bin:
server-test: src/bin/start.js
start-server-and-test: src/bin/start.js
start-test: src/bin/start.js
checksum: 8788e59ad78275332c78325a804504ac558f06a112d47cb5bc3d012d2bda46add72c863cae2357836fe245ee4e22e2fec0b6d47dbdf5e0f0f5cfd1a57544d100
languageName: node
linkType: hard
"state-toggle@npm:^1.0.0":
version: 1.0.3
resolution: "state-toggle@npm:1.0.3"