Skip to content

Commit

Permalink
Diagram layout not always saved #549
Browse files Browse the repository at this point in the history
  • Loading branch information
bindeali committed Sep 18, 2024
1 parent 9ad1735 commit ee050c4
Show file tree
Hide file tree
Showing 13 changed files with 135 additions and 53 deletions.
29 changes: 19 additions & 10 deletions src/function/FunctionDiagram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export function changeDiagrams(diagram?: string) {
export function centerDiagram(
p: joint.dia.Paper = paper,
g: joint.dia.Graph = graph
) {
): boolean {
p.translate(0, 0);
let x = 0;
let y = 0;
Expand All @@ -88,7 +88,8 @@ export function centerDiagram(
-((x / g.getElements().length) * scale) + computedSize.width / 2,
-((y / g.getElements().length) * scale) + computedSize.height / 2
);
if (g === graph) updateDiagramPosition(AppSettings.selectedDiagram);
if (g === graph) return setDiagramPosition(AppSettings.selectedDiagram);
else return false;
}

export function zoomDiagram(
Expand All @@ -97,7 +98,7 @@ export function zoomDiagram(
delta: number,
p: joint.dia.Paper = paper,
updatePosition: boolean = true
) {
): boolean {
const oldTranslate = p.translate();
const oldScale = p.scale().sx;
const nextScale = delta === 0 ? 1 : _.round(delta * 0.1 + oldScale, 1);
Expand All @@ -107,20 +108,28 @@ export function zoomDiagram(
oldTranslate.ty + y * (oldScale - nextScale)
);
p.scale(nextScale, nextScale);
if (updatePosition) updateDiagramPosition(AppSettings.selectedDiagram);
if (updatePosition) return setDiagramPosition(AppSettings.selectedDiagram);
}
return false;
}

/**
* Saves the diagram position and scale information.
* @param diagram The diagram to be updated
* @returns if the information has been updated or not.
*/
export function updateDiagramPosition(diagram: string) {
Diagrams[diagram].origin = {
x: paper.translate().tx,
y: paper.translate().ty,
};
Diagrams[diagram].scale = paper.scale().sx;
export function setDiagramPosition(diagram: string): boolean {
if (Diagrams[diagram].origin.x !== paper.translate().tx && Diagrams[diagram].origin.y !== paper.translate().ty) {
Diagrams[diagram].origin = {
x: paper.translate().tx,
y: paper.translate().ty,
};
// When zooming, the position is calculated again as well (see zoomDiagram function)
if (Diagrams[diagram].scale !== paper.scale().sx) {
Diagrams[diagram].scale = paper.scale().sx;
}
return true;
} else return false;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/function/FunctionGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
} from "../queries/update/UpdateLinkQueries";
import { insertNewCacheTerms, insertNewRestrictions } from "./FunctionCache";
import { addLink } from "./FunctionCreateVars";
import { clearSelection, updateDiagramPosition } from "./FunctionDiagram";
import { clearSelection, setDiagramPosition } from "./FunctionDiagram";
import { drawGraphElement, getDisplayLabel } from "./FunctionDraw";
import {
initElements,
Expand Down Expand Up @@ -99,7 +99,7 @@ export function centerElementInView(id: string) {
paper.getComputedSize().height / 2 -
elem.getBBox().height
);
updateDiagramPosition(AppSettings.selectedDiagram);
setDiagramPosition(AppSettings.selectedDiagram);
}
}

Expand Down
11 changes: 7 additions & 4 deletions src/function/FunctionTouch.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { updateDiagramPosition, zoomDiagram } from "./FunctionDiagram";
import { setDiagramPosition, zoomDiagram } from "./FunctionDiagram";
import { AppSettings } from "../config/Variables";
import { paper } from "../main/DiagramCanvas";

let drag: { x: any; y: any } | undefined = undefined;
let pinchZoom: number = 1;

export function initTouchEvents(manager: HammerManager) {
export function initTouchEvents(manager: HammerManager, update: (diagram: string) => void) {
manager.add(new Hammer.Pinch({ enable: true, threshold: 0 }));
manager.add(
new Hammer.Pan({
enable: (recognizer, event) => event && event.pointerType === "touch",
enable: (_, event) => event && event.pointerType === "touch",
threshold: 10,
})
);
Expand All @@ -31,7 +31,8 @@ export function initTouchEvents(manager: HammerManager) {
});

manager.on("panend", () => {
updateDiagramPosition(AppSettings.selectedDiagram);
if (setDiagramPosition(AppSettings.selectedDiagram))
update(AppSettings.selectedDiagram);
drag = undefined;
});

Expand All @@ -49,4 +50,6 @@ export function initTouchEvents(manager: HammerManager) {
pinchZoom -= 0.1;
}
});

manager.on("pinchend", () => update(AppSettings.selectedDiagram))
}
18 changes: 17 additions & 1 deletion src/main/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ import ValidationPanel from "../panels/ValidationPanel";
import VocabularyPanel from "../panels/VocabularyPanel";
import { qb } from "../queries/QueryBuilder";
import { updateVocabularyAnnotations } from "../queries/update/UpdateChangeQueries";
import { updateDiagramMetadata } from "../queries/update/UpdateDiagramQueries";
import {
updateDiagramMetadata,
updateDiagramPosition,
} from "../queries/update/UpdateDiagramQueries";
import { MainView } from "./MainView";
import { ToastService } from "./ToastService";

Expand Down Expand Up @@ -88,6 +91,8 @@ export default class App extends React.Component<
private readonly validationPanel: React.RefObject<ValidationPanel>;
private readonly diagramPanel: React.RefObject<DiagramPanel>;

private posScaleTimeout: number = 0;

constructor(props: DiagramAppProps) {
super(props);

Expand Down Expand Up @@ -133,6 +138,7 @@ export default class App extends React.Component<
this.handleChangeInterfaceLanguage.bind(this);
this.handleStatus = this.handleStatus.bind(this);
this.performTransaction = this.performTransaction.bind(this);
this.setPositionOrScaleTimeout = this.setPositionOrScaleTimeout.bind(this);

StoreAlerts.subscribe(
(s) => s.showCriticalAlert,
Expand Down Expand Up @@ -187,6 +193,14 @@ export default class App extends React.Component<
return true;
}

setPositionOrScaleTimeout(diagram: string): void {
window.clearTimeout(this.posScaleTimeout);
this.posScaleTimeout = window.setTimeout(
() => this.performTransaction(updateDiagramPosition(diagram)),
1000
);
}

handleChangeInterfaceLanguage(languageCode: string) {
AppSettings.interfaceLanguage = languageCode;
this.forceUpdate();
Expand Down Expand Up @@ -324,6 +338,7 @@ export default class App extends React.Component<
handleStatus={this.handleStatus}
performTransaction={this.performTransaction}
tooltip={this.state.tooltip}
setPositionOrScaleTimeout={this.setPositionOrScaleTimeout}
/>
<VocabularyPanel
ref={this.itemPanel}
Expand Down Expand Up @@ -388,6 +403,7 @@ export default class App extends React.Component<
this.detailPanel.current?.forceUpdate();
this.diagramPanel.current?.forceUpdate();
}}
setPositionOrScaleTimeout={this.setPositionOrScaleTimeout}
/>
<CreationModals
elemConfiguration={this.state.newElemConfiguration}
Expand Down
11 changes: 7 additions & 4 deletions src/main/DiagramCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { CellColors } from "../config/visual/CellColors";
import {
centerDiagram,
resetDiagramSelection,
updateDiagramPosition,
setDiagramPosition,
zoomDiagram,
} from "../function/FunctionDiagram";
import {
Expand Down Expand Up @@ -57,6 +57,7 @@ interface Props {
configuration: LinkCreationConfiguration | ElemCreationConfiguration
) => void;
handleStatus: Function;
setPositionOrScaleTimeout: (diagram: string) => void;
}

export var paper: joint.dia.Paper;
Expand Down Expand Up @@ -109,7 +110,7 @@ export default class DiagramCanvas extends React.Component<Props> {
const node = this.canvasRef.current! as HTMLElement;
const hammer = require("hammerjs");
const hammerManager = new hammer.Manager(node, { domEvents: true });
initTouchEvents(hammerManager);
initTouchEvents(hammerManager, this.props.setPositionOrScaleTimeout);

paper = new joint.dia.Paper({
el: node,
Expand Down Expand Up @@ -315,7 +316,8 @@ export default class DiagramCanvas extends React.Component<Props> {
*/
"blank:mousewheel": (evt, x, y, delta) => {
evt.preventDefault();
zoomDiagram(x, y, delta);
if (zoomDiagram(x, y, delta))
this.props.setPositionOrScaleTimeout(AppSettings.selectedDiagram);
},
/**
* Pointer move on canvas:
Expand Down Expand Up @@ -420,7 +422,8 @@ export default class DiagramCanvas extends React.Component<Props> {
* Perform selection based on the selection box
*/
"blank:pointerup": (evt) => {
updateDiagramPosition(AppSettings.selectedDiagram);
if (setDiagramPosition(AppSettings.selectedDiagram))
this.props.setPositionOrScaleTimeout(AppSettings.selectedDiagram);
this.drag = undefined;
if (evt.button === 0 || evt.type === "touchend") {
this.props.updateDetailPanel(DetailPanelMode.HIDDEN);
Expand Down
2 changes: 2 additions & 0 deletions src/main/MainView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type Props = {
) => void;
projectLanguage: string;
update: () => void;
setPositionOrScaleTimeout: (diagram: string) => void;
};

export const MainView: React.FC<Props> = (props: Props) => {
Expand All @@ -50,6 +51,7 @@ export const MainView: React.FC<Props> = (props: Props) => {
<div className={"mainView"} id={"mainView"} style={getStyle()}>
{mode === MainViewMode.CANVAS && (
<DiagramCanvas
setPositionOrScaleTimeout={props.setPositionOrScaleTimeout}
projectLanguage={props.projectLanguage}
updateElementPanel={props.updateElementPanel}
updateDetailPanel={props.updateDetailPanel}
Expand Down
7 changes: 4 additions & 3 deletions src/panels/MenuPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface MenuPanelProps {
performTransaction: (...queries: string[]) => void;
retry: boolean;
tooltip: boolean;
setPositionOrScaleTimeout: (diagram: string) => void;
}

interface MenuPanelState {
Expand Down Expand Up @@ -113,9 +114,9 @@ export default class MenuPanel extends React.Component<
<MenuPanelValidate validate={() => this.props.validate()} />
)}
<MenuPanelExport />
<ZoomWidget />
<ViewWidget />
<FitContentWidget />
<ZoomWidget update={this.props.setPositionOrScaleTimeout} />
<ViewWidget update={this.props.setPositionOrScaleTimeout} />
<FitContentWidget update={this.props.setPositionOrScaleTimeout} />
<div
className={
"right" + (this.props.freeze ? " nointeract" : " interact")
Expand Down
4 changes: 4 additions & 0 deletions src/panels/diagram/DiagramTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Locale } from "../../config/Locale";
import { StoreSettings } from "../../config/Store";
import { AppSettings, Diagrams } from "../../config/Variables";
import { changeDiagrams } from "../../function/FunctionDiagram";
import { updateDiagramPosition } from "../../queries/update/UpdateDiagramQueries";

interface Props {
diagram: string;
Expand All @@ -26,6 +27,9 @@ export const DiagramTab: React.FC<Props> = (props: Props) => {
StoreSettings.update((s) => {
s.mainViewMode = MainViewMode.CANVAS;
});
props.performTransaction(
updateDiagramPosition(AppSettings.selectedDiagram)
);
changeDiagrams(props.diagram);
props.update();
AppSettings.selectedLinks = [];
Expand Down
19 changes: 10 additions & 9 deletions src/panels/menu/widget/FitContentWidget.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import classNames from "classnames";
import React from "react";
import { OverlayTrigger, Tooltip } from "react-bootstrap";
import { Locale } from "../../../config/Locale";
import { AppSettings, Diagrams } from "../../../config/Variables";
import { ReactComponent as FitContentSVG } from "../../../svg/fitContent.svg";
import { AppSettings } from "../../../config/Variables";
import { setDiagramPosition } from "../../../function/FunctionDiagram";
import { paper } from "../../../main/DiagramCanvas";
import classNames from "classnames";
import { ReactComponent as FitContentSVG } from "../../../svg/fitContent.svg";

export default class FitContentWidget extends React.Component {
interface Props {
update: (diagram: string) => void;
}
export default class FitContentWidget extends React.Component<Props> {
render() {
return (
<span
Expand Down Expand Up @@ -43,11 +47,8 @@ export default class FitContentWidget extends React.Component {
maxScale: 2,
minScale: 0.1,
});
Diagrams[AppSettings.selectedDiagram].origin = {
x: paper.translate().tx,
y: paper.translate().ty,
};
Diagrams[AppSettings.selectedDiagram].scale = paper.scale().sx;
if (setDiagramPosition(AppSettings.selectedDiagram))
this.props.update(AppSettings.selectedDiagram);
}}
>
<FitContentSVG />
Expand Down
24 changes: 15 additions & 9 deletions src/panels/menu/widget/ViewWidget.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import classNames from "classnames";
import React from "react";
import { OverlayTrigger, Tooltip } from "react-bootstrap";
import { Locale } from "../../../config/Locale";
import { AppSettings, Diagrams } from "../../../config/Variables";
import { centerDiagram, zoomDiagram } from "../../../function/FunctionDiagram";
import { ReactComponent as CenterSVG } from "../../../svg/centerView.svg";
import { ReactComponent as RestoreZoomSVG } from "../../../svg/restoreZoom.svg";
import classNames from "classnames";

export default class ViewWidget extends React.Component {
interface Props {
update: (diagram: string) => void;
}
export default class ViewWidget extends React.Component<Props> {
render() {
return (
<span
Expand All @@ -25,7 +27,8 @@ export default class ViewWidget extends React.Component {
>
<button
onClick={() => {
centerDiagram();
if (centerDiagram())
this.props.update(AppSettings.selectedDiagram);
}}
>
<CenterSVG />
Expand All @@ -41,11 +44,14 @@ export default class ViewWidget extends React.Component {
>
<button
onClick={() => {
zoomDiagram(
Diagrams[AppSettings.selectedDiagram].origin.x,
Diagrams[AppSettings.selectedDiagram].origin.y,
0
);
if (
zoomDiagram(
Diagrams[AppSettings.selectedDiagram].origin.x,
Diagrams[AppSettings.selectedDiagram].origin.y,
0
)
)
this.props.update(AppSettings.selectedDiagram);
}}
>
<RestoreZoomSVG />
Expand Down
Loading

0 comments on commit ee050c4

Please sign in to comment.