Skip to content

Commit

Permalink
Feature: Drag to select perf, CTRL to add to selection
Browse files Browse the repository at this point in the history
  • Loading branch information
mattlag committed Aug 9, 2024
1 parent 4edce83 commit 6c9dd87
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 37 deletions.
4 changes: 4 additions & 0 deletions src/edit_canvas/context_characters.js
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ export function isHotspotHere(cx, cy) {
* If a hotspot is at the clicked location, call the function
* @param {Number} cx - x value
* @param {Number} cy - y value
* @returns {Boolean} - returns true if a hotspot was clicked
*/
export function findAndCallHotspot(cx, cy) {
contextCharacters.canvasHotspots.forEach((spot) => {
Expand All @@ -584,8 +585,11 @@ export function findAndCallHotspot(cx, cy) {
cy >= spot.target.yMin
) {
spot.onclick();
return true;
}
});

return false;
}

/**
Expand Down
38 changes: 27 additions & 11 deletions src/edit_canvas/events_mouse.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getCurrentProject, getCurrentProjectEditor } from '../app/main.js';
import { getCurrentProjectEditor } from '../app/main.js';
import { closeAllNotations } from '../controls/dialogs/dialogs.js';
import { Maxes } from '../project_data/maxes.js';
import { Maxes, maxesOverlap } from '../project_data/maxes.js';
import { findAndUnderlineHotspot, isHotspotHere } from './context_characters.js';
import { setCursor } from './cursors.js';
import { canvasUIPointSize } from './draw_edit_affordances.js';
Expand Down Expand Up @@ -128,7 +128,6 @@ export function clickEmptySpace() {
editor.multiSelect.shapes.clear();
}


/**
* Selects items in a given area. This is used to support the
* drag to select in an area edit canvas interaction.
Expand All @@ -151,29 +150,46 @@ export function selectItemsInArea(x1, y1, x2, y2, type = 'pathPoints') {
const maxY = Math.max(y1, y2);
const area = new Maxes({ xMin: minX, xMax: maxX, yMin: minY, yMax: maxY });
const editor = getCurrentProjectEditor();
let shouldPublish = true;
const msPoints = editor.multiSelect.points;
const msShapes = editor.multiSelect.shapes;
const isCtrlDown = eventHandlerData.isCtrlDown;

if (type === 'pathPoints') {
editor.multiSelect.points.clear();
editor.multiSelect.shapes.clear();
msPoints.allowPublishing = false;
if(!isCtrlDown) msPoints.clear();
msShapes.allowPublishing = false;
if(!isCtrlDown) msShapes.clear();
editor.selectedItem.shapes.forEach((shape) => {
if (shape.pathPoints) {
if (maxesOverlap(shape.maxes, area) && shape.pathPoints) {
shape.pathPoints.forEach((point) => {
if (area.isPointInside(point.p.x, point.p.y)) {
editor.multiSelect.points.add(point);
editor.multiSelect.shapes.add(point.parent);
msPoints.add(point);
msShapes.add(point.parent);
shouldPublish = true;
}
});
}
});
} else if (type === 'shapes') {
editor.multiSelect.points.clear();
editor.multiSelect.shapes.clear();
msPoints.allowPublishing = false;
if(!isCtrlDown) msPoints.clear();
msShapes.allowPublishing = false;
if(!isCtrlDown) msShapes.clear();
editor.selectedItem.shapes.forEach((shape) => {
if (area.isMaxesInside(shape.maxes)) {
editor.multiSelect.shapes.add(shape);
msShapes.add(shape);
shouldPublish = true;
}
});
}

msPoints.allowPublishing = true;
msShapes.allowPublishing = true;
if (shouldPublish) {
msPoints.publishChanges();
msShapes.publishChanges();
}
}

/**
Expand Down
19 changes: 14 additions & 5 deletions src/edit_canvas/tools/path_edit.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getCurrentProjectEditor } from '../../app/main.js';
import { refreshPanel } from '../../panels/panels.js';
import { findAndCallHotspot } from '../context_characters.js';
import { setCursor } from '../cursors.js';
import { isOverControlPoint } from '../detect_edit_affordances.js';
Expand Down Expand Up @@ -100,9 +101,9 @@ export class Tool_PathEdit {
msShapes.select(clickedPath);
} else {
// log('detected NOTHING');
clickEmptySpace();
ehd.selecting = true;
findAndCallHotspot(ehd.mousePosition.x, ehd.mousePosition.y);
if (!ehd.isCtrlDown) clickEmptySpace();
const clickedHotspot = findAndCallHotspot(ehd.mousePosition.x, ehd.mousePosition.y);
if (!clickedHotspot) ehd.selecting = true;
}

// if (msShapes.members.length) editor.nav.panel = 'Attributes';
Expand Down Expand Up @@ -161,7 +162,13 @@ export class Tool_PathEdit {
ehd.undoQueueHasChanged = true;
editor.publish(`currentPathPoint`, this.controlPoint.parent);
} else if (ehd.selecting) {
selectItemsInArea(ehd.lastX, ehd.lastY, ehd.mousePosition.x, ehd.mousePosition.y, 'pathPoints');
selectItemsInArea(
ehd.lastX,
ehd.lastY,
ehd.mousePosition.x,
ehd.mousePosition.y,
'pathPoints'
);
editor.editCanvas.redraw();
}

Expand Down Expand Up @@ -207,7 +214,7 @@ export class Tool_PathEdit {
hcpIsSelected = hoverDetection && msPoints.isSelected(hoverDetection.pathPoint);
if (hoverDetection.controlPoint === 'p') {
// Hovered over a point
setCursor('penSquare');
setCursor('penSquare');
} else if (msPoints.singleton && hcpIsSelected) {
// Hovered over a handle
setCursor('penCircle');
Expand All @@ -225,6 +232,7 @@ export class Tool_PathEdit {
const ehd = eventHandlerData;
const editor = getCurrentProjectEditor();
const msPoints = editor.multiSelect.points;
const msShapes = editor.multiSelect.shapes;

if (this.monitorForDeselect) {
msPoints.remove(this.pathPoint);
Expand All @@ -237,6 +245,7 @@ export class Tool_PathEdit {

if (ehd.selecting) {
ehd.selecting = false;
refreshPanel();
editor.editCanvas.redraw();
}

Expand Down
19 changes: 15 additions & 4 deletions src/edit_canvas/tools/resize.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { getCurrentProjectEditor } from '../../app/main.js';
import { calculateAngle, clone } from '../../common/functions.js';
import { refreshPanel } from '../../panels/panels.js';
import { isMaxes } from '../../project_data/maxes.js';
import { findAndCallHotspot } from '../context_characters.js';
import { setCursor } from '../cursors.js';
import { cXsX, cYsY } from '../edit_canvas.js';
import { eventHandlerData } from '../events.js';
import { checkForMouseOverHotspot, clickEmptySpace, resizePath, selectItemsInArea } from '../events_mouse.js';
import {
checkForMouseOverHotspot,
clickEmptySpace,
resizePath,
selectItemsInArea,
} from '../events_mouse.js';
import { getShapeAtLocation } from './tools.js';

/**
Expand Down Expand Up @@ -88,9 +94,9 @@ export class Tool_Resize {
this.dragging = true;
} else {
// log('clicked on nothing');
clickEmptySpace();
ehd.selecting = true;
findAndCallHotspot(ehd.mousePosition.x, ehd.mousePosition.y);
if (!ehd.isCtrlDown) clickEmptySpace();
const clickedHotspot = findAndCallHotspot(ehd.mousePosition.x, ehd.mousePosition.y);
if (!clickedHotspot) ehd.selecting = true;
}
// log(`Tool_Resize.mousedown`, 'end');
}
Expand Down Expand Up @@ -212,6 +218,11 @@ export class Tool_Resize {
editor.multiSelect.shapes.remove(this.clickedPath);
}

if (ehd.selecting) {
ehd.selecting = false;
refreshPanel();
}

// Finish Up
this.clickedPath = false;
this.didStuff = false;
Expand Down
55 changes: 45 additions & 10 deletions src/panels/attributes_glyph_edit.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getCurrentProjectEditor } from '../app/main.js';
import { makeElement } from '../common/dom.js';
import { eventHandlerData } from '../edit_canvas/events.js';
import { showAddComponentDialog } from '../pages/components.js';
import { showAddLigatureDialog } from '../pages/ligatures.js';
import { makeCard_componentInstanceAttributes } from './card_component_instance.js';
Expand All @@ -21,37 +22,46 @@ import { refreshPanel } from './panels.js';

export function makePanel_GlyphAttributes() {
// log('makePanel_GlyphAttributes', 'start');

const editor = getCurrentProjectEditor();
let msShapes = editor.multiSelect.shapes;
let msPoints = editor.multiSelect.points;

// log(`msPoints.length: ${msPoints.length}`);
// if (eventHandlerData.selecting && (msShapes.length > 0 || msPoints.length > 0)) {
if (eventHandlerData.selecting) {
// log('makePanel_GlyphAttributes', 'end');
return [makeCard_dragToSelectSummary()];
}

let content = [];
// log(editor);

// Path Points
let selPoints = editor.multiSelect.points;
// log(selPoints);
if (selPoints.length === 1) {
// log(msPoints);
if (msPoints.length === 1) {
// log(`pushing point card`);
content.push(makeCard_pathPointAttributes(selPoints.singleton));
} else if (selPoints.length > 1) {
let virtualShape = selPoints.virtualShape;
content.push(makeCard_pathPointAttributes(msPoints.singleton));
} else if (msPoints.length > 1) {
let virtualShape = msPoints.virtualShape;
content.push(makeCard_multiSelectPathPointAttributes(virtualShape));
}

// Shapes
let msShapes = editor.multiSelect.shapes;
if (msShapes.length === 1) {
// One shape selected
// log('One shape selected');
// log(msShapes.singleton);
if (msShapes.singleton.objType === 'ComponentInstance') {
// component selected
// log("...Component selected");
// log('...Component selected');
content.push(makeCard_componentInstanceAttributes(msShapes.singleton));
} else {
// regular path selected
// log("...Regular path selected");
// log('...Regular path selected');
content.push(makeCard_pathAttributes(msShapes.singleton));
}
} else if (msShapes.length > 1 && selPoints.length === 0) {
} else if (msShapes.length > 1 && msPoints.length === 0) {
// Many shapes selected
// log('More than one shape selected');
content.push(makeCard_multiSelectPathAttributes(msShapes.virtualGlyph));
Expand Down Expand Up @@ -107,3 +117,28 @@ export function makePanel_GlyphAttributes() {
// log('makePanel_GlyphAttributes', 'end');
return content;
}

function makeCard_dragToSelectSummary() {
const editor = getCurrentProjectEditor();
let pointCount = editor.multiSelect.points.length;
let shapeCount = editor.multiSelect.shapes.length;
let text = '';

if (pointCount === 0) {
if (shapeCount === 0) text = 'Drag to select...';
if (shapeCount === 1) text = '1 selected shape';
if (shapeCount > 1) text = `${shapeCount} selected shapes`;
} else {
let pName = pointCount > 1 ? 'path points' : 'path point';
let sName = shapeCount > 1 ? 'shapes' : 'shape';
text = `${pointCount} selected ${pName} across ${shapeCount} ${sName}`;
}

let multiPathPointCard = makeElement({
tag: 'div',
className: 'panel__card',
innerHTML: `<h3>${text}</h3>`,
});

return multiPathPointCard;
}
2 changes: 1 addition & 1 deletion src/panels/card_path.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export function makeCard_multiSelectPathAttributes(virtualGlyph) {
let multiPathCard = makeElement({
tag: 'div',
className: 'panel__card',
innerHTML: `<h3>${virtualGlyph.shapes.length} selected paths</h3>`,
innerHTML: `<h3>${virtualGlyph.shapes.length} selected shapes</h3>`,
});

addAsChildren(multiPathCard, makeInputs_position(virtualGlyph));
Expand Down
7 changes: 5 additions & 2 deletions src/project_data/maxes.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,11 @@ export class Maxes extends GlyphElement {
* @returns {Boolean}
*/
isPointInside(x, y) {
let result = x <= this.xMax && x >= this.xMin && y <= this.yMax && y >= this.yMin;
return result;
if (x >= this.xMax) return false;
if (x <= this.xMin) return false;
if (y >= this.yMax) return false;
if (y <= this.yMin) return false;
return true;
}

/**
Expand Down
13 changes: 9 additions & 4 deletions src/project_editor/multiselect.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class MultiSelect {
constructor() {
this.members = [];
this.singleHandle = false;
this.allowPublishing = true;
}

isSelected(obj) {
Expand Down Expand Up @@ -193,8 +194,10 @@ export class MultiSelectPoints extends MultiSelect {

publishChanges(topic = 'whichPathPointIsSelected') {
// log(`MultiSelectPoints.publishChanges`, 'start');
const editor = getCurrentProjectEditor();
editor.publish(topic, this.members);
if(this.allowPublishing) {
const editor = getCurrentProjectEditor();
editor.publish(topic, this.members);
}
// log(`MultiSelectPoints.publishChanges`, 'end');
}

Expand Down Expand Up @@ -364,8 +367,10 @@ export class MultiSelectShapes extends MultiSelect {
}

publishChanges(topic = 'whichShapeIsSelected') {
const editor = getCurrentProjectEditor();
editor.publish(topic, this.members);
if(this.allowPublishing) {
const editor = getCurrentProjectEditor();
editor.publish(topic, this.members);
}
}

clear() {
Expand Down

0 comments on commit 6c9dd87

Please sign in to comment.