~xigoi/vier

66407f69dfa2d9654de9e23f71381eeb9291461a — Adam Blažek 8 months ago 59b85b9
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]