Skip to content

Commit

Permalink
Merge pull request #1332 from quadratichq/move-cells
Browse files Browse the repository at this point in the history
Drag cells to move
  • Loading branch information
davidkircos committed May 13, 2024
2 parents 6f5438b + 7859a7f commit 957ce68
Show file tree
Hide file tree
Showing 30 changed files with 551 additions and 28 deletions.
2 changes: 2 additions & 0 deletions quadratic-client/src/app/events/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ interface EventTypes {
resizeHeadingColumn: (column: number) => void;

offlineTransactions: (transactions: number, operations: number) => void;

cellMoving: (move: boolean) => void;
}

export const events = new EventEmitter<EventTypes>();
17 changes: 15 additions & 2 deletions quadratic-client/src/app/gridGL/UI/Cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ export class Cursor extends Graphics {
startCell: CursorCell;
endCell: CursorCell;

// cursor rectangle for normal cells
cursorRectangle?: Rectangle;

constructor() {
super();
this.indicator = new Rectangle();
Expand Down Expand Up @@ -78,8 +81,14 @@ export class Cursor extends Graphics {
}

// hide cursor if code editor is open and CodeCursor is in the same cell
if (editorInteractionState.showCodeEditor && editor_selected_cell.x === cell.x && editor_selected_cell.y === cell.y)
if (
editorInteractionState.showCodeEditor &&
editor_selected_cell.x === cell.x &&
editor_selected_cell.y === cell.y
) {
this.cursorRectangle = undefined;
return;
}

// draw cursor
this.lineStyle({
Expand All @@ -102,6 +111,9 @@ export class Cursor extends Graphics {
alignment: 1,
});
this.drawRect(x, y, width, height);
this.cursorRectangle = undefined;
} else {
this.cursorRectangle = new Rectangle(x, y, width, height);
}
}

Expand All @@ -114,12 +126,13 @@ export class Cursor extends Graphics {
this.beginFill(colors.cursorCell, FILL_ALPHA);
this.startCell = sheet.getCellOffsets(cursor.originPosition.x, cursor.originPosition.y);
this.endCell = sheet.getCellOffsets(cursor.terminalPosition.x, cursor.terminalPosition.y);
this.drawRect(
this.cursorRectangle = new Rectangle(
this.startCell.x,
this.startCell.y,
this.endCell.x + this.endCell.width - this.startCell.x,
this.endCell.y + this.endCell.height - this.startCell.y
);
this.drawShape(this.cursorRectangle);
} else {
this.startCell = sheet.getCellOffsets(cursor.cursorPosition.x, cursor.cursorPosition.y);
this.endCell = sheet.getCellOffsets(cursor.cursorPosition.x, cursor.cursorPosition.y);
Expand Down
54 changes: 54 additions & 0 deletions quadratic-client/src/app/gridGL/UI/UICellMoving.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { sheets } from '@/app/grid/controller/Sheets';
import { pixiApp } from '@/app/gridGL/pixiApp/PixiApp';
import { colors } from '@/app/theme/colors';
import { BitmapText, Container, Graphics } from 'pixi.js';

const MOVING_THICKNESS = 3;

export class UICellMoving extends Container {
private graphics: Graphics;
private location: BitmapText;

dirty = false;

constructor() {
super();
this.graphics = this.addChild(new Graphics());
this.location = this.addChild(new BitmapText('', { fontName: 'OpenSans', fontSize: 12 }));
this.visible = false;
}

private drawMove() {
const moving = pixiApp.pointer.pointerCellMoving.moving;
if (!moving) {
throw new Error('Expected moving to be defined in drawMove');
}
this.visible = true;
this.graphics.clear();
this.graphics.lineStyle(1, colors.movingCells, MOVING_THICKNESS);
const offsets = sheets.sheet.offsets;
const start = offsets.getCellOffsets(moving.toColumn, moving.toRow);
const end = offsets.getCellOffsets(moving.toColumn + moving.width, moving.toRow + moving.height);
this.graphics.drawRect(start.x, start.y, end.x + end.w - start.x, end.y + end.h - start.y);
}

update() {
if (this.dirty) {
this.dirty = false;
switch (pixiApp.pointer.pointerCellMoving.state) {
case 'hover':
if (this.visible) {
this.visible = false;
}
break;
case 'move':
this.drawMove();
break;
default:
if (this.visible) {
this.visible = false;
}
}
}
}
}
25 changes: 20 additions & 5 deletions quadratic-client/src/app/gridGL/interaction/pointer/Pointer.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PointerCellMoving } from '@/app/gridGL/interaction/pointer/PointerCellMoving';
import { pixiAppSettings } from '@/app/gridGL/pixiApp/PixiAppSettings';
import { multiplayer } from '@/app/web-workers/multiplayerWebWorker/multiplayer';
import { Viewport } from 'pixi-viewport';
Expand All @@ -15,13 +16,15 @@ export class Pointer {
pointerHtmlCells: PointerHtmlCells;
pointerCursor: PointerCursor;
pointerDown: PointerDown;
pointerCellMoving: PointerCellMoving;

constructor(viewport: Viewport) {
this.pointerHeading = new PointerHeading();
this.pointerAutoComplete = new PointerAutoComplete();
this.pointerDown = new PointerDown();
this.pointerCursor = new PointerCursor();
this.pointerHtmlCells = new PointerHtmlCells();
this.pointerCellMoving = new PointerCellMoving();

viewport.on('pointerdown', this.handlePointerDown);
viewport.on('pointermove', this.pointerMove);
Expand Down Expand Up @@ -75,32 +78,43 @@ export class Pointer {
if (this.isMoreThanOneTouch(e)) return;
const world = pixiApp.viewport.toWorld(e.data.global);
const event = e.data.originalEvent as PointerEvent;
this.pointerHtmlCells.pointerDown(e) ||
this.pointerCellMoving.pointerDown(event) ||
this.pointerHtmlCells.pointerDown(e) ||
this.pointerHeading.pointerDown(world, event) ||
this.pointerAutoComplete.pointerDown(world) ||
this.pointerDown.pointerDown(world, event);

this.updateCursor();
};

private pointerMove = (e: InteractionEvent): void => {
if (this.isMoreThanOneTouch(e) || this.isOverCodeEditor(e)) return;
const world = pixiApp.viewport.toWorld(e.data.global);
this.pointerHtmlCells.pointerMove(e) ||
const event = e.data.originalEvent as PointerEvent;
this.pointerCellMoving.pointerMove(event, world) ||
this.pointerHtmlCells.pointerMove(e) ||
this.pointerHeading.pointerMove(world) ||
this.pointerAutoComplete.pointerMove(world) ||
this.pointerDown.pointerMove(world) ||
this.pointerCursor.pointerMove(world);

// change the cursor based on pointer priority
this.updateCursor();
};

// change the cursor based on pointer priority
private updateCursor() {
const cursor =
pixiApp.pointer.pointerCellMoving.cursor ??
pixiApp.pointer.pointerHtmlCells.cursor ??
pixiApp.pointer.pointerHeading.cursor ??
pixiApp.pointer.pointerAutoComplete.cursor;
pixiApp.canvas.style.cursor = cursor ?? 'unset';
};
}

private pointerUp = (e: InteractionEvent): void => {
if (this.isMoreThanOneTouch(e)) return;
this.pointerHtmlCells.pointerUp() ||
this.pointerCellMoving.pointerUp() ||
this.pointerHtmlCells.pointerUp() ||
this.pointerHeading.pointerUp() ||
this.pointerAutoComplete.pointerUp() ||
this.pointerDown.pointerUp();
Expand All @@ -116,6 +130,7 @@ export class Pointer {
return true;
}
return (
this.pointerCellMoving.handleEscape() ||
this.pointerHtmlCells.handleEscape() ||
this.pointerHeading.handleEscape() ||
this.pointerAutoComplete.handleEscape()
Expand Down

0 comments on commit 957ce68

Please sign in to comment.