Color picking and pixel deletion
3 files changed, 61 insertions(+), 18 deletions(-) M src/vier.nim M website/index.html M website/index.xd
M src/vier.nim => src/vier.nim +47 -12
@@ 157,6 157,12 @@ proc widgetSize(picture: Picture, isPalette = false): Vec = else: picture.canvasSize + (0'i32, margin + textSize) proc `[]`(picture: Picture, pos: Vec): Color = picture.image.getImageColor(pos.x, pos.y) proc colorAtCursor(picture: Picture): Color = picture[picture.cursor] proc moveCursor(picture: Picture, movement: Vec) = ## Moves the cursor by the given amount, ensuring that it stays in bounds. @@ picture.cursor.x = clamp(picture.cursor.x + movement.x, 0'i32..<picture.image.width) 255,10 261,10 @@ proc select(picture: Picture, target: Vec, tool: Tool) = let pos = stack.pop if pos in toSelect: continue let currentColor = picture.image.getImageColor(pos.x, pos.y) let currentColor = picture[pos] toSelect.incl(pos) template check(x, y: int) = if distance(picture.image.getImageColor(x, y), currentColor) <= tool.tolerance: if distance(picture[(x, y)], currentColor) <= tool.tolerance: stack.add((x, y)) @@ if pos.x > 0: 287,11 293,7 @@ proc injectColor(picture: Picture, color: Color) = pixelChanges: collect( for pixel in picture.selection: PixelChange( pos: pixel, originalColor: picture.image.getImageColor(pixel.x, pixel.y), newColor: color, ) PixelChange(pos: pixel, originalColor: picture[pixel], newColor: color) ) ) @@ picture.add(change) 305,7 307,7 @@ proc addColor(picture: Picture, color: Color) = pixelChanges: collect( for pixel in picture.selection: let originalColor = picture.image.getImageColor(pixel.x, pixel.y) let originalColor = picture[pixel] PixelChange( pos: pixel, @@ originalColor: originalColor, 499,7 501,7 @@ proc selectedPalette(app: App): Picture = proc updateColor(app: App) = ## Sets the primary color to the color currently selected in the palette. let palette = app.selectedPalette app.color = palette.image.getImageColor(palette.cursor.x, palette.cursor.y) app.color = palette.colorAtCursor proc swapColors(app: App) = @@ swap(app.color, app.secondaryColor) 598,6 600,22 @@ proc processKeyboard(app: App) = app.tool = Tool(kind: tBrush) if isKeyPressed(C): app.mode = mColor if isKeyPressed(D): let picture = app.selectedPicture let change = ImageChange( pixelChanges: @[ PixelChange( pos: picture.cursor, originalColor: picture.colorAtCursor, newColor: Blank, ) ] ) picture.add(change) picture.apply(change) if isKeyPressed(F): app.tool = Tool(kind: tFlood) @@ if isKeyPressed(I): 626,10 644,13 @@ proc processKeyboard(app: App) = app.selectedPicture.write() if isKeyPressed(X): app.swapColors() if isKeyPressed(Y): app.color = app.selectedPicture.colorAtCursor if isKeyPressed(Semicolon): app.mode = mCommand app.command = "" discard getCharPressed() while (var ch = getCharPressed(); ch != 0): discard if isKeyPressed(Equal): if shift: @@ app.pictures.apply(zoomIn) 660,11 681,25 @@ proc processKeyboard(app: App) = app.selectedPicture.moveCursor(movement) if isKeyDown(Space) and not isKeyPressed(Space): app.selectedPicture.dragPixel( app.selectedPicture.cursor, app.mode, app.tool, app.color app.selectedPicture.cursor, app.mode, app.tool, if shift: app.secondaryColor else: app.color , ) if isKeyPressed(Space): app.selectedPicture.clickPixel( app.selectedPicture.cursor, app.mode, app.tool, app.color app.selectedPicture.cursor, app.mode, app.tool, if shift: app.secondaryColor else: app.color , ) of mColor: if movement != square(0):
M website/index.html => website/index.html +7 -3
@@ 30,16 30,19 @@ nimble <span class="token function">install</span> <dl><dt><img src="assets/icons/tools/brush.png" alt="Brush icon" /> Brush</dt><dd>The brush tool selects pixels that it moves over.</dd><dt><img src="assets/icons/tools/segment.png" alt="Segment icon" /> Segment</dt><dd>The segment tool selects a line segment.</dd><dt><img src="assets/icons/tools/rectangle.png" alt="Rectangle icon" /> Rectangle</dt><dd>The rectangle tool selects an axis-aligned rectangle.</dd><dt><img src="assets/icons/tools/flood.png" alt="Flood icon" /> Flood</dt><dd>The flood tool selects a contiguous area of pixels with the same color.</dd></dl></section> <section><h2 class="xd-section-heading">Keyboard mappings</h2><p>The key mappings are inspired by Vim. They are currently not customizable.</p> <table><tr><th>Key</th><th>Alone</th><th>Shift</th><th>Control</th></tr> <tr><td><kbd>⎵</kbd></td><td>hold to draw</td></tr> <tr><td><kbd>A</kbd></td><td>Mode ← Add</td></tr> <tr><td><kbd>⎵</kbd></td><td>hold to draw</td><td>hold to draw with secondary color</td></tr> <tr><td><kbd>A</kbd></td><td>Mode ← Add / add to selection</td></tr> <tr><td><kbd>B</kbd></td><td>Tool ← Brush</td></tr> <tr><td><kbd>C</kbd></td><td>Mode ← Color</td></tr> <tr><td><kbd>D</kbd></td><td>delete pixel / delete selection</td></tr> <tr><td><kbd>F</kbd></td><td>Tool ← Flood</td></tr> <tr><td><kbd>H</kbd></td><td>move left</td><td></td><td>previous picture/palette</td></tr> <tr><td><kbd>I</kbd></td><td>Mode ← Inject</td></tr> <tr><td><kbd>I</kbd></td><td>Mode ← Inject / fill selection</td></tr> <tr><td><kbd>J</kbd></td><td>move down</td><td></td></tr> <tr><td><kbd>K</kbd></td><td>move up</td><td></td></tr> <tr><td><kbd>L</kbd></td><td>move right</td><td></td><td>next picture/palette</td></tr> <tr><td><kbd>M</kbd></td><td>Tool ← Mirror / cut selection</td></tr> <tr><td><kbd>P</kbd></td><td>paste</td></tr> <tr><td><kbd>Q</kbd></td><td>quit</td><td>force quit</td></tr> <tr><td><kbd>R</kbd></td><td>Tool ← Rectangle</td><td></td><td>redo</td></tr> @@ <tr><td><kbd>S</kbd></td><td>Tool ← Segment</td></tr> 47,6 50,7 @@ nimble <span class="token function">install</span> <tr><td><kbd>V</kbd></td><td>Mode ← Select</td></tr> <tr><td><kbd>W</kbd></td><td>write picture</td><td>write all pictures</td></tr> <tr><td><kbd>X</kbd></td><td>swap colors</td></tr> <tr><td><kbd>Y</kbd></td><td>pick color / copy selection</td><td>pick secondary color</td></tr> <tr><td><kbd>-</kbd></td><td>zoom out</td><td>zoom out all pictures</td></tr> <tr><td><kbd>=</kbd></td><td>zoom in</td><td>zoom in all pictures</td></tr> <tr><td><kbd>;</kbd></td><td>Mode ← Command</td></tr></table>
M website/index.xd => website/index.xd +7 -3
@@ 59,17 59,20 @@ [p The key mappings are inspired by Vim. They are currently not customizable.] [table [header-row Key; Alone; Shift; Control] [row [<kbd> ⎵]; hold to draw] [row [<kbd> A]; Mode ← Add] [row [<kbd> ⎵]; hold to draw; hold to draw with secondary color] [row [<kbd> A]; Mode ← Add / add to selection] [row [<kbd> B]; Tool ← Brush] [row [<kbd> C]; Mode ← Color] [row [<kbd> D]; delete pixel / delete selection] [# row [<kbd> E]; Tool ← Ellipse] [row [<kbd> F]; Tool ← Flood] [row [<kbd> H]; move left; [# move to left edge]; previous picture/palette] [row [<kbd> I]; Mode ← Inject] [row [<kbd> I]; Mode ← Inject / fill selection] [row [<kbd> J]; move down; [# move to bottom edge]] [row [<kbd> K]; move up; [# move to top edge]] [row [<kbd> L]; move right; [# move to right edge]; next picture/palette] [row [<kbd> M]; Tool ← Mirror / cut selection] [row [<kbd> P]; paste] [row [<kbd> Q]; quit; force quit] [row [<kbd> R]; Tool ← Rectangle; ; redo] @@ [row [<kbd> S]; Tool ← Segment] 77,6 80,7 @@ [row [<kbd> V]; Mode ← Select] [row [<kbd> W]; write picture; write all pictures] [row [<kbd> X]; swap colors] [row [<kbd> Y]; pick color / copy selection; pick secondary color] [row [<kbd> -]; zoom out; zoom out all pictures] [row [<kbd> =]; zoom in; zoom in all pictures] [row [<kbd> [;]]; Mode ← Command]