-
Notifications
You must be signed in to change notification settings - Fork 3
Add text edit #185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add text edit #185
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -172,6 +172,12 @@ export class InputManager { | |
| this.inputPoint = new Point(); | ||
|
|
||
| this.snapping = new Snapping(); | ||
|
|
||
| // Text editing state | ||
| this.textEditing = false; | ||
| this.editingTextItem = undefined; | ||
| this.editingTextIndex = undefined; | ||
| this.originalTextString = ''; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -184,6 +190,11 @@ export class InputManager { | |
| // this.promptOption.reject('reject'); | ||
| this.promptOption = undefined; | ||
| DesignCore.Scene.reset(); | ||
|
|
||
| // Exit text editing mode if active | ||
| if (this.textEditing) { | ||
| this.exitTextEdit(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -222,6 +233,14 @@ export class InputManager { | |
| * @param {any} input | ||
| */ | ||
| onCommand(input) { | ||
| // Handle text editing mode first | ||
| if (this.textEditing) { | ||
| // For text editing, when onCommand is called, it means Enter was pressed | ||
| // So we should confirm the edit | ||
| this.confirmTextEdit(); | ||
| return; | ||
| } | ||
|
|
||
| if (this.activeCommand !== undefined) { | ||
| this.promptOption.respond(input); | ||
| } else if (DesignCore.CommandManager.isCommandOrShortcut(input)) { | ||
|
|
@@ -234,6 +253,12 @@ export class InputManager { | |
| * Handle enter / return presses | ||
| */ | ||
| onEnterPressed() { | ||
| // Handle text editing mode first | ||
| if (this.textEditing) { | ||
| this.confirmTextEdit(); | ||
| return; | ||
| } | ||
|
|
||
| if (this.activeCommand !== undefined) { | ||
| if (this.promptOption.types.includes(Input.Type.SELECTIONSET) && DesignCore.Scene.selectionManager.selectionSet.accepted !== true) { | ||
| DesignCore.Scene.selectionManager.selectionSet.accepted = true; | ||
|
|
@@ -255,6 +280,12 @@ export class InputManager { | |
| * Handle escape presses to reset | ||
| */ | ||
| onEscapePressed() { | ||
| // Handle text editing mode first | ||
| if (this.textEditing) { | ||
| this.cancelTextEdit(); | ||
| return; | ||
| } | ||
|
|
||
| this.reset(); | ||
| } | ||
|
|
||
|
|
@@ -316,7 +347,8 @@ export class InputManager { | |
| } | ||
|
|
||
| // Determine if the mouse is over a scene item only if no snap point is available | ||
| if (snapped === undefined) { | ||
| // Skip selection/hover logic when in text editing mode | ||
| if (snapped === undefined && !this.textEditing) { | ||
| if (this.activeCommand === undefined || this.activeCommand !== undefined && (this.promptOption.types.includes(Input.Type.SINGLESELECTION) || this.promptOption.types.includes(Input.Type.SELECTIONSET))) { | ||
| const index = DesignCore.Scene.selectionManager.findClosestItem(DesignCore.Mouse.pointOnScene()); | ||
| if (index !== undefined) { | ||
|
|
@@ -461,4 +493,111 @@ export class InputManager { | |
| return DesignCore.Scene.addItem(item.type, item, index); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Start text editing mode | ||
| * @param {Object} textItem - the text item to edit | ||
| * @param {number} textIndex - index of the text item in scene.items | ||
| */ | ||
| startTextEdit(textItem, textIndex) { | ||
| this.textEditing = true; | ||
| this.editingTextItem = textItem; | ||
| this.editingTextIndex = textIndex; | ||
| this.originalTextString = textItem.string; | ||
|
|
||
| // Set the command line content directly | ||
| DesignCore.CommandLine.command = textItem.string; | ||
| DesignCore.CommandLine.prompt = 'Edit text:'; | ||
| DesignCore.CommandLine.update(); | ||
|
|
||
| // Clear any existing selection and temp items | ||
| DesignCore.Scene.selectionManager.reset(); | ||
| DesignCore.Scene.tempItems = []; | ||
|
|
||
| // Mark scene as requiring save since we're editing | ||
| DesignCore.Scene.saveRequired(); | ||
|
|
||
| // Request a repaint to show editing state | ||
| DesignCore.Canvas.requestPaint(); | ||
| } | ||
|
|
||
| /** | ||
| * Exit text editing mode | ||
| */ | ||
| exitTextEdit() { | ||
| this.textEditing = false; | ||
| this.editingTextItem = undefined; | ||
| this.editingTextIndex = undefined; | ||
| this.originalTextString = ''; | ||
|
|
||
| // Reset command line | ||
| DesignCore.CommandLine.resetPrompt(); | ||
| } | ||
|
|
||
| /** | ||
| * Handle text editing input | ||
| * @param {string} input - the input text | ||
| */ | ||
| handleTextEditInput(input) { | ||
| if (!this.textEditing || !this.editingTextItem || this.editingTextIndex === undefined) { | ||
|
||
| return; | ||
| } | ||
|
|
||
| // Get the current command line content | ||
| const currentText = DesignCore.CommandLine.command; | ||
|
|
||
| // Update the scene item | ||
| const textItem = DesignCore.Scene.items[this.editingTextIndex]; | ||
| textItem.string = currentText; | ||
|
|
||
| // Also update the editing item reference to keep them in sync | ||
| this.editingTextItem.string = currentText; | ||
|
|
||
| // Update the command line display to ensure it's in sync | ||
| DesignCore.CommandLine.cmdLine = DesignCore.CommandLine.prompt + currentText; | ||
| if (DesignCore.CommandLine.updateCallbackFunction) { | ||
| DesignCore.CommandLine.updateCallbackFunction(DesignCore.CommandLine.cmdLine); | ||
| } | ||
|
|
||
| // Force a repaint | ||
| DesignCore.Canvas.requestPaint(); | ||
| } | ||
|
|
||
| /** | ||
| * Confirm text editing changes | ||
| */ | ||
| confirmTextEdit() { | ||
| if (!this.textEditing || !this.editingTextItem || this.editingTextIndex === undefined) { | ||
| return; | ||
| } | ||
|
|
||
| // The scene item is already updated during typing, so we just need to exit editing mode | ||
| // Mark scene as requiring save | ||
| DesignCore.Scene.saveRequired(); | ||
|
|
||
| // Exit text editing mode | ||
| this.exitTextEdit(); | ||
|
|
||
| // Request a repaint | ||
| DesignCore.Canvas.requestPaint(); | ||
| } | ||
|
|
||
| /** | ||
| * Cancel text editing and restore original text | ||
| */ | ||
| cancelTextEdit() { | ||
| if (!this.textEditing || !this.editingTextItem || this.editingTextIndex === undefined) { | ||
| return; | ||
| } | ||
|
|
||
| // Restore original text | ||
| this.editingTextItem.string = this.originalTextString; | ||
| DesignCore.Scene.items[this.editingTextIndex].string = this.originalTextString; | ||
|
|
||
| // Exit text editing mode | ||
| this.exitTextEdit(); | ||
|
|
||
| // Request a repaint | ||
| DesignCore.Canvas.requestPaint(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| import {Point} from '../../core/entities/point'; | ||
| import {Text} from '../../core/entities/text'; | ||
| import {DesignCore} from '../../core/designCore.js'; | ||
|
|
||
| import {File} from '../test-helpers/test-helpers.js'; | ||
|
|
||
|
|
@@ -193,3 +194,41 @@ AcDbText | |
| newText.dxf(file); | ||
| expect(file.contents).toEqual(dxfString); | ||
| }); | ||
|
|
||
| test('Test Text.isBeingEdited', () => { | ||
| const text = new Text({points: [new Point(100, 100)], string: 'Test Text'}); | ||
|
|
||
| // Mock DesignCore.Scene.inputManager | ||
| const mockInputManager = { | ||
| textEditing: false, | ||
| editingTextItem: null, | ||
| }; | ||
|
|
||
| // Mock DesignCore.Scene | ||
| const mockScene = { | ||
| inputManager: mockInputManager, | ||
| }; | ||
|
|
||
| // Mock DesignCore with proper structure including Core | ||
| const originalCore = DesignCore._core; | ||
| DesignCore._core = { | ||
| scene: mockScene, | ||
| }; | ||
|
Comment on lines
+213
to
+216
|
||
|
|
||
| try { | ||
| // Test when not being edited | ||
| expect(text.isBeingEdited()).toBe(false); | ||
|
|
||
| // Test when text editing is active but different item | ||
| mockInputManager.textEditing = true; | ||
| mockInputManager.editingTextItem = new Text({points: [new Point(200, 200)]}); | ||
| expect(text.isBeingEdited()).toBe(false); | ||
|
|
||
| // Test when this text is being edited | ||
| mockInputManager.editingTextItem = text; | ||
| expect(text.isBeingEdited()).toBe(true); | ||
| } finally { | ||
| // Restore original DesignCore | ||
| DesignCore._core = originalCore; | ||
| } | ||
| }); | ||
Uh oh!
There was an error while loading. Please reload this page.