# DragToEdit

Command-drag a shape in the window, and the numbers in this file change. ⌘] and ⌘[ move the shape's line past its neighbor's line

Run it with `swift run --package-path Examples Example-Live-DragToEdit`.

```swift
import Ollin

// DragToEdit: move, resize, and turn a shape with the pointer, and watch the
// file change.
//
// Run it under the live host, from the repo root:
//
//   swift run OllinLive Examples/Live/DragToEdit/Sketch.swift
//
// Hold Command over the canvas. The shape under the pointer is outlined, with
// the line that drew it named above the outline. Then:
//
//   drag the shape          the two numbers that place it become where you left it
//   drag a corner           the numbers that size it grow or shrink
//   drag the knob above it  the shape turns, if the line says which way it faces
//   press ⌘] or ⌘[         the shape's line moves past its neighbor's, so it
//                           draws in front or behind; Shift takes it all the way
//
// Let go and the file is written. The watcher sees the save, the sketch
// recompiles, and the shape is where you left it. The file is the only thing
// that changed, so it is your editor's undo that takes it back.
//
// Most shapes below are placed by plain numbers, which is what makes them
// draggable. Two are not, deliberately: the green dot is placed by a
// calculation, so a drag says what stands where a number would have to be, and
// the yellow one is placed by a parameter's name, so a drag sets that parameter instead
// of writing the file. That is the whole rule. A number can be dragged, a parameter
// can be set, a calculation can be neither.

@main
final class DragToEdit: Sketch {
    override var canvasSize: CanvasSize { .square(720) }

    @Param(60 ... 660) var sunX = 120.0

    override func draw() {
        background(Color(hex: 0xF4F1EA))
        noStroke()

        // A face, laid out by hand. Drag any of it, or a corner of it. With
        // the face outlined, ⌘] brings it forward over the eyes, its fill
        // going along and the eyes' fill put back after it; ⌘[ undoes that.
        fill(Color(hex: 0xE4572E))
        drawCircle(360, 300, 150)

        fill(Color(hex: 0xF4F1EA))
        drawCircle(310, 265, 26)
        drawCircle(415, 265, 26)

        fill(Color(hex: 0x1B1B1B))
        drawCircle(315, 270, 11)
        drawCircle(420, 270, 11)

        // A mouth, and a bar under the whole thing. Both are placed by their
        // top-left corner, so that corner stays put while the others resize.
        drawRect(315, 350, 90, 14, cornerRadius: 7)
        drawRect(210, 540, 300, 10, cornerRadius: 5)

        // A triangle and a line, to show that the other shapes drag too. The
        // line has no size on its call, so it offers the turn knob and no
        // corners: it swings about its own middle.
        fill(Color(hex: 0x2E86AB))
        drawTriangle(560, 470, 44)

        stroke(Color(hex: 0x1B1B1B))
        strokeWeight(3)
        drawLine(150, 190, 230, 130)

        // An arc carries its own two angles, so the knob above it turns those.
        noFill()
        strokeWeight(6)
        drawArc(360, 300, 190, 190, start: 0.6, stop: 2.5)

        // This one is placed by a calculation, so it cannot be dragged. Try it:
        // the host says what stands where the number would be.
        noStroke()
        fill(Color(hex: 0x9BBF3B))
        drawCircle(width - 120, 620, 34)

        // And this one is placed by a parameter. Dragging it sets the parameter, which
        // needs no recompile, and leaves the line as it is written.
        fill(Color(hex: 0xF2C14E))
        drawCircle(sunX, 120, 40)
    }
}
```
