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