tigma 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,12 +2,14 @@
2
2
 
3
3
  A terminal-based design tool for creating ASCII diagrams and designs.
4
4
 
5
- ## Installation
5
+ ## Running
6
6
 
7
7
  ```bash
8
- bun install
8
+ bunx tigma
9
9
  ```
10
10
 
11
+ Currently this requires [bun](http://bun.sh).
12
+
11
13
  ## Usage
12
14
 
13
15
  ```bash
@@ -47,6 +49,7 @@ Switch between tools using keyboard shortcuts:
47
49
  - **Shift+Click** to add/remove objects from selection (multi-select)
48
50
  - **Click+Drag** to move selected objects
49
51
  - **Click on empty space** to deselect all
52
+ - **Click+Drag on empty space** to box-select multiple items (hold Shift to add)
50
53
 
51
54
  #### Rectangle Resizing
52
55
 
@@ -125,7 +128,7 @@ Designs are saved as `.tigma` files in JSON format. The file stores:
125
128
  ## Features
126
129
 
127
130
  - **Layered rendering**: Objects stack based on z-index; newer objects appear on top by default
128
- - **Multi-selection**: Select multiple objects with Shift+Click
131
+ - **Multi-selection**: Select multiple objects with Shift+Click or box-select
129
132
  - **Undo/Redo**: Up to 100 history snapshots
130
133
  - **Terminal responsive**: Adapts to terminal resize events
131
134
  - **Mouse support**: Full mouse interaction including hover highlighting
package/dist/index.js CHANGED
@@ -14876,6 +14876,8 @@ class CanvasApp {
14876
14876
  currentFilePath = null;
14877
14877
  saveStatusMessage = null;
14878
14878
  saveStatusTimeout = 0;
14879
+ isSelecting = false;
14880
+ isSelectionPending = false;
14879
14881
  showSavePrompt = false;
14880
14882
  savePromptInput = "";
14881
14883
  gridWidth = 0;
@@ -15351,6 +15353,11 @@ class CanvasApp {
15351
15353
  if (event.x !== this.mouseDownX || event.y !== this.mouseDownY) {
15352
15354
  this.hasDragged = true;
15353
15355
  }
15356
+ if (this.isSelectionPending && this.hasDragged && this.currentTool === "move") {
15357
+ this.isSelectionPending = false;
15358
+ this.isSelecting = true;
15359
+ this.isDraggingMouse = true;
15360
+ }
15354
15361
  if (this.isDraggingSelection) {
15355
15362
  const dx = event.x - this.dragStartX;
15356
15363
  const dy = event.y - this.dragStartY;
@@ -15362,7 +15369,7 @@ class CanvasApp {
15362
15369
  if (rectId !== undefined) {
15363
15370
  this.resizeRect(rectId, event.x, event.y);
15364
15371
  }
15365
- } else if (this.isDrawingRect || this.isDrawingLine) {
15372
+ } else if (this.isDrawingRect || this.isDrawingLine || this.isSelecting) {
15366
15373
  this.drawCursorX = Math.max(0, Math.min(this.gridWidth - 1, event.x));
15367
15374
  this.drawCursorY = Math.max(0, Math.min(this.gridHeight - 1, event.y));
15368
15375
  this.renderer.requestRender();
@@ -15380,6 +15387,11 @@ class CanvasApp {
15380
15387
  this.drawCursorY = Math.max(0, Math.min(this.gridHeight - 1, event.y));
15381
15388
  this.commitLine();
15382
15389
  }
15390
+ if (this.isSelecting) {
15391
+ this.drawCursorX = Math.max(0, Math.min(this.gridWidth - 1, event.x));
15392
+ this.drawCursorY = Math.max(0, Math.min(this.gridHeight - 1, event.y));
15393
+ this.commitSelection();
15394
+ }
15383
15395
  if (this.clickedOnSelectedTextBox && !this.hasDragged && this.selectedTextBoxIds.size === 1) {
15384
15396
  const textBoxId = this.selectedTextBoxIds.values().next().value;
15385
15397
  const textBox = this.textBoxes.find((b) => b.id === textBoxId);
@@ -15398,6 +15410,8 @@ class CanvasApp {
15398
15410
  this.isDraggingMouse = false;
15399
15411
  this.clickedOnSelectedTextBox = false;
15400
15412
  this.hasDragged = false;
15413
+ this.isSelecting = false;
15414
+ this.isSelectionPending = false;
15401
15415
  return;
15402
15416
  }
15403
15417
  if (event.type === "down") {
@@ -15502,6 +15516,11 @@ class CanvasApp {
15502
15516
  if (!shiftHeld) {
15503
15517
  this.clearSelection();
15504
15518
  }
15519
+ this.isSelectionPending = true;
15520
+ this.drawStartX = event.x;
15521
+ this.drawStartY = event.y;
15522
+ this.drawCursorX = event.x;
15523
+ this.drawCursorY = event.y;
15505
15524
  this.renderer.requestRender();
15506
15525
  return;
15507
15526
  }
@@ -15877,6 +15896,40 @@ class CanvasApp {
15877
15896
  this.isDrawingLine = false;
15878
15897
  this.setTool("move");
15879
15898
  }
15899
+ commitSelection() {
15900
+ if (!this.isSelecting)
15901
+ return;
15902
+ const selX1 = Math.min(this.drawStartX, this.drawCursorX);
15903
+ const selX2 = Math.max(this.drawStartX, this.drawCursorX);
15904
+ const selY1 = Math.min(this.drawStartY, this.drawCursorY);
15905
+ const selY2 = Math.max(this.drawStartY, this.drawCursorY);
15906
+ const isIntersecting = (x1, y1, x2, y2) => {
15907
+ return !(x2 < selX1 || x1 > selX2 || y2 < selY1 || y1 > selY2);
15908
+ };
15909
+ for (const box of this.textBoxes) {
15910
+ const width = Math.max(1, this.getTextLength(box));
15911
+ const bx1 = box.x;
15912
+ const bx2 = box.x + width - 1;
15913
+ const by1 = box.y;
15914
+ const by2 = box.y;
15915
+ if (isIntersecting(bx1, by1, bx2, by2)) {
15916
+ this.selectTextBox(box.id, true);
15917
+ }
15918
+ }
15919
+ for (const rect of this.rectangles) {
15920
+ const { x1, y1, x2, y2 } = this.normalizeRect(rect);
15921
+ if (isIntersecting(x1, y1, x2, y2)) {
15922
+ this.selectRect(rect.id, true);
15923
+ }
15924
+ }
15925
+ for (const line of this.lines) {
15926
+ const { x1, y1, x2, y2 } = this.normalizeLine(line);
15927
+ if (isIntersecting(x1, y1, x2, y2)) {
15928
+ this.selectLine(line.id, true);
15929
+ }
15930
+ }
15931
+ this.isSelecting = false;
15932
+ }
15880
15933
  deleteLine(id) {
15881
15934
  this.saveSnapshot();
15882
15935
  this.lines = this.lines.filter((l) => l.id !== id);
@@ -16012,6 +16065,8 @@ class CanvasApp {
16012
16065
  }
16013
16066
  this.isDrawingRect = false;
16014
16067
  this.isDrawingLine = false;
16068
+ this.isSelecting = false;
16069
+ this.isSelectionPending = false;
16015
16070
  this.isDraggingMouse = false;
16016
16071
  this.currentTool = tool;
16017
16072
  if (tool !== "move") {
@@ -16057,6 +16112,9 @@ class CanvasApp {
16057
16112
  if (this.isDrawingLine) {
16058
16113
  this.renderLinePreview(buffer);
16059
16114
  }
16115
+ if (this.isSelecting) {
16116
+ this.renderSelectionBoxPreview(buffer);
16117
+ }
16060
16118
  if (this.activeTextBoxId !== null) {
16061
16119
  const activeBox = this.textBoxes.find((b) => b.id === this.activeTextBoxId);
16062
16120
  if (activeBox) {
@@ -16339,6 +16397,36 @@ class CanvasApp {
16339
16397
  buffer.setCell(x, y, char, fg2, bg2, attrs);
16340
16398
  }
16341
16399
  }
16400
+ renderSelectionBoxPreview(buffer) {
16401
+ const x1 = Math.min(this.drawStartX, this.drawCursorX);
16402
+ const x2 = Math.max(this.drawStartX, this.drawCursorX);
16403
+ const y1 = Math.min(this.drawStartY, this.drawCursorY);
16404
+ const y2 = Math.max(this.drawStartY, this.drawCursorY);
16405
+ const fg2 = this.toolbarActiveColor;
16406
+ for (let y = y1;y <= y2; y++) {
16407
+ for (let x = x1;x <= x2; x++) {
16408
+ if (x < 0 || x >= this.gridWidth || y < 0 || y >= this.gridHeight)
16409
+ continue;
16410
+ let char = "";
16411
+ if (y === y1 && x === x1)
16412
+ char = "+";
16413
+ else if (y === y1 && x === x2)
16414
+ char = "+";
16415
+ else if (y === y2 && x === x1)
16416
+ char = "+";
16417
+ else if (y === y2 && x === x2)
16418
+ char = "+";
16419
+ else if (y === y1 || y === y2)
16420
+ char = "-";
16421
+ else if (x === x1 || x === x2)
16422
+ char = "\u2502";
16423
+ if (char) {
16424
+ const currentBg = this.readBufferBg(buffer, x, y);
16425
+ buffer.setCell(x, y, char, fg2, currentBg, 0);
16426
+ }
16427
+ }
16428
+ }
16429
+ }
16342
16430
  getLineChar(x1, y1, x2, y2, index, total) {
16343
16431
  const dx = x2 - x1;
16344
16432
  const dy = y2 - y1;
@@ -16600,7 +16688,7 @@ class CanvasApp {
16600
16688
  if (this.activeTextBoxId !== null) {
16601
16689
  modeText = "| Editing (Esc to finish)";
16602
16690
  } else if (this.currentTool === "move") {
16603
- modeText = "| Click to select, drag to move";
16691
+ modeText = "| Click to select, drag to move, drag empty space to box-select";
16604
16692
  } else if (this.currentTool === "text") {
16605
16693
  modeText = "| Click to add/edit text";
16606
16694
  } else if (this.isDrawingRect || this.isDrawingLine) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tigma",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "A terminal-based design tool",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",