update wiki
53
Box-Selection.md
Normal file
53
Box-Selection.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# Plan: Box Selection
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Add drag-to-select functionality for selecting multiple shapes within a rectangle.
|
||||||
|
|
||||||
|
## Current State
|
||||||
|
- Click selects single shape (in Controller.mousePressed)
|
||||||
|
- Shift+click adds to selection
|
||||||
|
- Selection uses SelectionAttributes
|
||||||
|
|
||||||
|
## Implementation Plan
|
||||||
|
|
||||||
|
### 1. Controller changes
|
||||||
|
- Add state: `boxSelectOrigin` (Point), `boxSelectActive` (boolean)
|
||||||
|
- Add `boxSelectionRectangle` (Rectangle) for current drag area
|
||||||
|
|
||||||
|
### 2. Mouse handling
|
||||||
|
- `mousePressed`:
|
||||||
|
- If click on empty area (no shape), start box selection
|
||||||
|
- Store origin point
|
||||||
|
- Clear current selection unless Shift is held
|
||||||
|
- `mouseDragged`:
|
||||||
|
- If boxSelectActive, update rectangle from origin to current point
|
||||||
|
- Repaint to show selection box
|
||||||
|
- `mouseReleased`:
|
||||||
|
- Calculate final box rectangle
|
||||||
|
- Find all shapes whose bounds intersect with box
|
||||||
|
- Add to selection (or replace if no Shift)
|
||||||
|
- Clear box selection state, repaint
|
||||||
|
|
||||||
|
### 3. Visual feedback
|
||||||
|
- Draw semi-transparent rectangle during drag in ShapesView
|
||||||
|
- Use XOR mode or overlay for drawing
|
||||||
|
- Box outline: dashed line, gray color
|
||||||
|
|
||||||
|
### 4. Selection behavior
|
||||||
|
- Default: box replaces current selection
|
||||||
|
- Shift+drag: box adds to current selection
|
||||||
|
- Box entirely within shape = shape selected
|
||||||
|
- Partial overlap: select shape (standard behavior)
|
||||||
|
|
||||||
|
### 5. Intersection check
|
||||||
|
- Use `shape.getBounds().intersects(boxRect)`
|
||||||
|
- Handle composite shapes (SCollection) - check children
|
||||||
|
|
||||||
|
## Files to modify
|
||||||
|
- `ui/Controller.java` - mouse handling
|
||||||
|
- `ui/ShapesView.java` - draw box overlay in paintComponent
|
||||||
|
|
||||||
|
## Edge cases
|
||||||
|
- Drag on existing selection: allow move instead of box select
|
||||||
|
- Very small drag (< 5px): treat as click, select shape under point
|
||||||
|
- Empty box: clear selection
|
||||||
9
Home.md
9
Home.md
@@ -1 +1,8 @@
|
|||||||
Bienvenue sur le Wiki.
|
# Home
|
||||||
|
|
||||||
|
## Project Plans
|
||||||
|
|
||||||
|
1. [Resize Shapes](Resize-Shapes.md) - Add ability to resize shapes by dragging corner handles
|
||||||
|
2. [Text Shapes](Text-Shapes.md) - Add support for creating text shapes
|
||||||
|
3. [Undo/Redo Stack](Undo-Redo-Stack.md) - Implement undo/redo functionality
|
||||||
|
4. [Box Selection](Box-Selection.md) - Add drag-to-select for multiple shapes
|
||||||
|
|||||||
45
Resize-Shapes.md
Normal file
45
Resize-Shapes.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# Plan: Resize Shapes
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Add the ability to resize shapes by dragging corner handles on selected shapes.
|
||||||
|
|
||||||
|
## Current State
|
||||||
|
- Selection already draws red corner handles via `ShapeDraftman.drawHandlerIfSelected()`
|
||||||
|
- `Controller` handles mouse events for selection and moving
|
||||||
|
- Selection uses `SelectionAttributes` on shapes
|
||||||
|
|
||||||
|
## Implementation Plan
|
||||||
|
|
||||||
|
### 1. ResizeHandle enum
|
||||||
|
- Create `ResizeHandle` enum in `shapes/` package with positions: NW, N, NE, E, SE, S, SW, W
|
||||||
|
- Each handle knows its cursor type
|
||||||
|
|
||||||
|
### 2. Controller changes
|
||||||
|
- Add mouse state: `resizing` (boolean), `activeHandle` (ResizeHandle), `resizeOrigin` (Point)
|
||||||
|
- Add `getHandleAt(Point)` method to find which handle is clicked
|
||||||
|
- Modify mouse handlers:
|
||||||
|
- `mousePressed`: If click is on a handle, enter resize mode
|
||||||
|
- `mouseDragged`: If resizing, calculate delta and call shape's resize method
|
||||||
|
- `mouseReleased`: Exit resize mode
|
||||||
|
- Add cursor changes based on handle position
|
||||||
|
|
||||||
|
### 3. Shape interface changes
|
||||||
|
- Add `resize(ResizeHandle handle, int dx, int dy)` method to `Shape` interface
|
||||||
|
- Implement in `AbstractShape` or each concrete shape
|
||||||
|
- For basic shapes (rectangle, circle, triangle):
|
||||||
|
- Rectangle: adjust width/height based on handle
|
||||||
|
- Circle: adjust radius (maintain aspect ratio or allow ellipse)
|
||||||
|
- Triangle: adjust vertices
|
||||||
|
|
||||||
|
### 4. Visual feedback
|
||||||
|
- Update `ShapeDraftman` to use different handle positions (not just corners)
|
||||||
|
- Consider showing resize preview during drag
|
||||||
|
|
||||||
|
## Files to modify
|
||||||
|
- `shapes/Shape.java` - add resize method
|
||||||
|
- `ui/Controller.java` - mouse handling for resize
|
||||||
|
- `shapes/SRectangle.java`, `SCircle.java`, `STriangle.java` - implement resize logic
|
||||||
|
|
||||||
|
## Alternative consideration
|
||||||
|
- Could use a separate `Resizer` class to keep Controller clean
|
||||||
|
- Could implement resize in `AbstractShape` for common logic
|
||||||
62
Text-Shapes.md
Normal file
62
Text-Shapes.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# Plan: Text Shapes
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Add support for creating text shapes in the canvas.
|
||||||
|
|
||||||
|
## Current State
|
||||||
|
- Available shapes: SRectangle, SCircle, STriangle
|
||||||
|
- Uses visitor pattern for rendering
|
||||||
|
- Menu system in App.java for adding shapes
|
||||||
|
|
||||||
|
## Implementation Plan
|
||||||
|
|
||||||
|
### 1. Create SText class
|
||||||
|
- New class `shapes/SText` extending `AbstractShape`
|
||||||
|
- Fields: `text` (String), `fontSize` (int, default 16), `fontName` (String, default "SansSerif"), `fontStyle` (int, default Font.PLAIN)
|
||||||
|
- Empty or cancelled input falls back to placeholder `"Text"`
|
||||||
|
- Override `resize(ResizeHandle, int, int)` as no-op (text not resizable)
|
||||||
|
- Implement `accept(ShapeVisitor)` calling `visitor.visitText(this)`
|
||||||
|
- Bounds are stored as a Rectangle at construction time (position only, zero size); updated and cached by ShapeDraftman on each paint via FontMetrics for accurate hit-test and selection
|
||||||
|
|
||||||
|
### 2. ShapeVisitor interface change
|
||||||
|
- Add `visitText(SText text)` to the `ShapeVisitor` interface
|
||||||
|
- All implementations must implement this method
|
||||||
|
|
||||||
|
### 3. ShapeDraftman changes
|
||||||
|
- Implement `visitText(SText)`: render with `Graphics2D.drawString()`
|
||||||
|
- After drawing, measure text via `g2d.getFontMetrics()` and update the cached bounds on the SText object
|
||||||
|
- Selection visuals reuse existing `drawHandlerIfSelected()` with measured bounds
|
||||||
|
|
||||||
|
### 4. SVGDraftman / HTMLDraftman changes
|
||||||
|
- Implement `visitText(SText)` in both visitors
|
||||||
|
- Escape special characters in text content for safe export (& < > " ')
|
||||||
|
|
||||||
|
### 5. Controller changes
|
||||||
|
- Add lightweight text-placement mode (boolean `addingText`)
|
||||||
|
- When active, next canvas click prompts via `JOptionPane.showInputDialog()`
|
||||||
|
- If input is null (cancelled): do not create shape, exit text-placement mode
|
||||||
|
- If input is empty: use placeholder `"Text"`
|
||||||
|
- Create `SText` at click position, add to model, exit text-placement mode
|
||||||
|
|
||||||
|
### 6. App.java changes
|
||||||
|
- Add "Add Text" menu item that calls `controller.enterTextMode()`
|
||||||
|
- Single-line, no wrapping; bounds expand horizontally with text length
|
||||||
|
|
||||||
|
## Files to create/modify
|
||||||
|
- Create: `shapes/SText.java`
|
||||||
|
- Modify: `ShapeVisitor.java` — add `visitText(SText)`
|
||||||
|
- Modify: `ui/ShapeDraftman.java` — implement visitText, update bounds via FontMetrics
|
||||||
|
- Modify: `ui/visitors/SVGDraftman.java` — implement visitText
|
||||||
|
- Modify: `ui/visitors/HTMLDraftman.java` — implement visitText
|
||||||
|
- Modify: `ui/Controller.java` — add text-placement mode
|
||||||
|
- Modify: `App.java` — add "Add Text" menu item
|
||||||
|
|
||||||
|
## Defaults
|
||||||
|
- Font: SansSerif, plain, size 16
|
||||||
|
- Placeholder: "Text"
|
||||||
|
- Text is single-line, no wrapping
|
||||||
|
|
||||||
|
## Out of scope (first version)
|
||||||
|
- Double-click to edit existing text
|
||||||
|
- Font size/style configuration via UI
|
||||||
|
- Text resize (no-op for now)
|
||||||
51
Undo-Redo-Stack.md
Normal file
51
Undo-Redo-Stack.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# Plan: Undo/Redo Stack
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Implement undo/redo functionality with a command history stack.
|
||||||
|
|
||||||
|
## Current State
|
||||||
|
- Controller handles shape operations (add, delete, move, color change)
|
||||||
|
- No command history exists
|
||||||
|
- Selection system tracks selected shapes
|
||||||
|
|
||||||
|
## Implementation Plan
|
||||||
|
|
||||||
|
### 1. Command pattern
|
||||||
|
- Create `Command` interface with `execute()` and `undo()` methods
|
||||||
|
- Create concrete commands:
|
||||||
|
- `AddShapeCommand` - stores shape reference, removes on undo
|
||||||
|
- `DeleteShapesCommand` - stores shapes list, re-adds on undo
|
||||||
|
- `MoveShapeCommand` - stores shape, original pos, new pos
|
||||||
|
- `ChangeColorCommand` - stores shape, old/new colors
|
||||||
|
- `ResizeCommand` - stores shape, old/new bounds
|
||||||
|
- `GroupCommand` - composite for batch operations
|
||||||
|
|
||||||
|
### 2. CommandManager class
|
||||||
|
- Maintains two stacks: `undoStack`, `redoStack`
|
||||||
|
- `execute(Command)`: push to undoStack, clear redoStack
|
||||||
|
- `undo()`: pop from undoStack, call undo(), push to redoStack
|
||||||
|
- `redo()`: pop from redoStack, call execute(), push to undoStack
|
||||||
|
- Limit stack size (e.g., 50 commands)
|
||||||
|
|
||||||
|
### 3. Controller integration
|
||||||
|
- Replace direct shape operations with commands
|
||||||
|
- Example: instead of `collection.add(shape)`, do `commandManager.execute(new AddShapeCommand(shape, collection))`
|
||||||
|
|
||||||
|
### 4. Keyboard shortcuts
|
||||||
|
- Ctrl+Z: undo
|
||||||
|
- Ctrl+Y: redo (or Ctrl+Shift+Z)
|
||||||
|
- Update menu with these shortcuts
|
||||||
|
|
||||||
|
### 5. Menu additions
|
||||||
|
- Add Edit menu items: Undo, Redo
|
||||||
|
- Enable/disable based on stack state
|
||||||
|
|
||||||
|
## Files to create/modify
|
||||||
|
- Create: `commands/Command.java`, `commands/CommandManager.java`
|
||||||
|
- Create: `commands/AddShapeCommand.java`, `commands/DeleteShapesCommand.java`, `commands/MoveShapeCommand.java`, etc.
|
||||||
|
- Modify: `ui/Controller.java`, `App.java` (menu)
|
||||||
|
|
||||||
|
## Edge cases
|
||||||
|
- Copy/paste after undo: clear redo stack
|
||||||
|
- Multi-select delete: single compound command
|
||||||
|
- Application close: no persistence needed (in-memory only)
|
||||||
Reference in New Issue
Block a user