From b615d676336d919ad55cf6c8d2ad5d5d1458481b Mon Sep 17 00:00:00 2001 From: bryzZz Date: Wed, 4 Oct 2023 14:36:11 +0800 Subject: [PATCH] bug fixes --- src/renderer/src/lib/data/EditorManager.ts | 13 ++++---- src/renderer/src/lib/data/StateMachine.ts | 34 ++++++++++++-------- src/renderer/src/lib/data/UndoRedo.ts | 36 ++++++++++++++-------- src/renderer/src/lib/drawable/Draggable.ts | 8 ++--- src/renderer/src/types/StateMachine.ts | 6 +++- 5 files changed, 61 insertions(+), 36 deletions(-) diff --git a/src/renderer/src/lib/data/EditorManager.ts b/src/renderer/src/lib/data/EditorManager.ts index e00b7423c..568b14286 100644 --- a/src/renderer/src/lib/data/EditorManager.ts +++ b/src/renderer/src/lib/data/EditorManager.ts @@ -428,11 +428,6 @@ export class EditorManager { const state = this.data.elements.states[id]; if (!state) return false; - // Если удаляемое состояние было начальным, стираем текущее значение - if (this.data.elements.initialState === id) { - this.data.elements.initialState = ''; - } - delete this.data.elements.states[id]; return true; @@ -447,11 +442,15 @@ export class EditorManager { return true; } - createEvent(stateId: string, eventData: EventData) { + createEvent(stateId: string, eventData: EventData, eventIdx?: number) { const state = this.data.elements.states[stateId]; if (!state) return false; - state.events.push(eventData); + if (eventIdx !== undefined) { + state.events.splice(eventIdx, 0, eventData); + } else { + state.events.push(eventData); + } return true; } diff --git a/src/renderer/src/lib/data/StateMachine.ts b/src/renderer/src/lib/data/StateMachine.ts index 97a49952b..3f4d98e3f 100644 --- a/src/renderer/src/lib/data/StateMachine.ts +++ b/src/renderer/src/lib/data/StateMachine.ts @@ -207,7 +207,7 @@ export class StateMachine extends EventEmitter { if (canUndo) { this.undoRedo.do({ type: 'changeStateName', - args: { id, name, state }, + args: { id, name, prevName: state.data.name }, }); } @@ -312,20 +312,22 @@ export class StateMachine extends EventEmitter { const state = this.states.get(id); if (!state || !state.parent) return; - this.container.app.manager.unlinkState(id); - // Вычисляем новую координату, потому что после отсоединения родителя не сможем. const newBounds = { ...state.bounds, ...state.compoundPosition }; - this.container.app.manager.changeStateBounds(id, newBounds); + this.changeStatePosition(id, state.bounds, newBounds); + // this.container.app.manager.changeStateBounds(id, newBounds); if (canUndo) { this.undoRedo.do({ type: 'unlinkState', args: { parentId: state.parent.id, childId: id }, + numberOfConnectedActions: 1, // Изменение позиции }); - state.removeOnceOff('dragend'); + state.addOnceOff('dragend'); } + this.container.app.manager.unlinkState(id); + state.parent.children.delete(id); state.parent = undefined; @@ -365,10 +367,16 @@ export class StateMachine extends EventEmitter { numberOfConnectedActions += 1; } + // Если удаляемое состояние было начальным, стираем текущее значение + if (this.container.app.manager.data.elements.initialState === id) { + this.changeInitialState('', canUndo); + numberOfConnectedActions += 1; + } + if (canUndo) { this.undoRedo.do({ type: 'deleteState', - args: { id, state }, + args: { id, stateData: structuredClone(state.data) }, numberOfConnectedActions, }); } @@ -402,16 +410,18 @@ export class StateMachine extends EventEmitter { if (!soruceState || !targetState) return; + const position = params.position ?? { + x: (soruceState.bounds.x + targetState.bounds.x) / 2, + y: (soruceState.bounds.y + targetState.bounds.y) / 2, + }; + // Создание данных const id = this.container.app.manager.createTransition({ id: prevId, source, target, color, - position: { - x: (soruceState.bounds.x + targetState.bounds.x) / 2, - y: (soruceState.bounds.y + targetState.bounds.y) / 2, - }, + position, component, method, doAction, @@ -571,11 +581,11 @@ export class StateMachine extends EventEmitter { this.container.isDirty = true; } - createEvent(stateId: string, eventData: EventData) { + createEvent(stateId: string, eventData: EventData, eventIdx?: number) { const state = this.states.get(stateId); if (!state) return; - this.container.app.manager.createEvent(stateId, eventData); + this.container.app.manager.createEvent(stateId, eventData, eventIdx); state.eventBox.recalculate(); diff --git a/src/renderer/src/lib/data/UndoRedo.ts b/src/renderer/src/lib/data/UndoRedo.ts index f0ba92616..521a9c8a3 100644 --- a/src/renderer/src/lib/data/UndoRedo.ts +++ b/src/renderer/src/lib/data/UndoRedo.ts @@ -4,6 +4,7 @@ import { Component, Transition as TransitionData, EventData, + State as StateData, } from '@renderer/types/diagram'; import { AddComponentParams, @@ -21,13 +22,12 @@ import { import { StateMachine } from './StateMachine'; import { EventSelection } from '../drawable/Events'; -import { State } from '../drawable/State'; import { Transition } from '../drawable/Transition'; type PossibleActions = { stateCreate: CreateStateParameters & { newStateId: string }; - deleteState: { id: string; state: State }; - changeStateName: { id: string; name: string; state: State }; + deleteState: { id: string; stateData: StateData }; + changeStateName: { id: string; name: string; prevName: string }; changeStateEvents: { args: ChangeStateEventsParams; prevActions: EventAction[] }; linkState: { parentId: string; childId: string }; unlinkState: { parentId: string; childId: string }; @@ -73,26 +73,26 @@ export const actionFunctions: ActionFunctions = { redo: sM.createState.bind(sM, { ...args, id: args.newStateId }, false), undo: sM.deleteState.bind(sM, args.newStateId, false), }), - deleteState: (sM, { id, state }) => ({ + deleteState: (sM, { id, stateData }) => ({ redo: sM.deleteState.bind(sM, id, false), undo: sM.createState.bind( sM, { - name: state.data.name, + name: stateData.name, id, position: { - x: state.data.bounds.x + state.data.bounds.width / 2, - y: state.data.bounds.y + state.data.bounds.height / 2, + x: stateData.bounds.x + stateData.bounds.width / 2, + y: stateData.bounds.y + stateData.bounds.height / 2, }, - parentId: state.data.parent, - events: structuredClone(state.data.events), + parentId: stateData.parent, + events: stateData.events, }, false ), }), - changeStateName: (sM, { id, name, state }) => ({ + changeStateName: (sM, { id, name, prevName }) => ({ redo: sM.changeStateName.bind(sM, id, name, false), - undo: sM.changeStateName.bind(sM, id, state.data.name, false), + undo: sM.changeStateName.bind(sM, id, prevName, false), }), changeStateEvents: (sM, { args, prevActions }) => ({ redo: sM.changeStateEvents.bind(sM, args, false), @@ -169,7 +169,7 @@ export const actionFunctions: ActionFunctions = { }), deleteEvent: (sM, { stateId, eventIdx, prevValue }) => ({ redo: sM.deleteEvent.bind(sM, stateId, { eventIdx, actionIdx: null }, false), - undo: sM.createEvent.bind(sM, stateId, prevValue), + undo: sM.createEvent.bind(sM, stateId, prevValue, eventIdx), }), deleteEventAction: (sM, { stateId, event, prevValue }) => ({ redo: sM.deleteEvent.bind(sM, stateId, event, false), @@ -208,6 +208,10 @@ export class UndoRedo { do(action: Action) { this.redoStack.length = 0; this.undoStack.push(action); + + console.log('do', action); + console.log('undoStack', this.undoStack); + console.log('redoStack', this.redoStack); } undo = () => { @@ -225,6 +229,10 @@ export class UndoRedo { // Если соединённые действия то первое должно попасть в конец redo стека this.redoStack.push(action); + + console.log('undo'); + console.log('undoStack', this.undoStack); + console.log('redoStack', this.redoStack); }; redo = () => { @@ -247,6 +255,10 @@ export class UndoRedo { if (this.undoStack.length > STACK_SIZE_LIMIT) { this.undoStack.shift(); } + + console.log('redo'); + console.log('undoStack', this.undoStack); + console.log('redoStack', this.redoStack); }; isUndoStackEmpty() { diff --git a/src/renderer/src/lib/drawable/Draggable.ts b/src/renderer/src/lib/drawable/Draggable.ts index 692731d44..0de7bcc83 100644 --- a/src/renderer/src/lib/drawable/Draggable.ts +++ b/src/renderer/src/lib/drawable/Draggable.ts @@ -258,6 +258,10 @@ export abstract class Draggable extends EventEmitter { this.globalMouseUp(); + if (prevDragging) { + this.dragEnd(); + } + const isUnderMouse = this.isUnderMouse(e); if (!isUnderMouse) return; @@ -267,10 +271,6 @@ export abstract class Draggable extends EventEmitter { this.emit('mouseup', { event: e, target: this }); - if (prevDragging) { - this.dragEnd(); - } - if (this.isMouseDown) { this.isMouseDown = false; this.emit('click', { event: e, target: this }); diff --git a/src/renderer/src/types/StateMachine.ts b/src/renderer/src/types/StateMachine.ts index 75f746e29..adb10efbc 100644 --- a/src/renderer/src/types/StateMachine.ts +++ b/src/renderer/src/types/StateMachine.ts @@ -1,7 +1,11 @@ import { CreateTransitionParameters as MCreateTransitionParameters } from '@renderer/types/EditorManager'; + import { Component } from './diagram'; +import { Point } from './graphics'; -export type CreateTransitionParameters = Omit; +export type CreateTransitionParameters = Omit & { + position?: Point; +}; export interface EditComponentParams { name: string;