- Yes, that’s the right thing to do. The Distances sample demonstrates an override of the Tool.standardMouseSelect method. For your enlightenment, here’s its definition:
public standardMouseSelect(): void {
const diagram = this.diagram;
if (!diagram.allowSelect) return;
const e = diagram.lastInput;
const curobj = diagram.findPartAt(e.documentPoint, false); // to select containing Group if Part.canSelect() is false
if (curobj !== null) {
if (e.meta || e.control) { // toggle the part's selection
diagram.raiseDiagramEvent('ChangingSelection', diagram.selection);
let part = curobj;
while (part !== null && !part.canSelect()) part = part.containingGroup;
if (part !== null) part.isSelected = !part.isSelected;
diagram.raiseDiagramEvent('ChangedSelection', diagram.selection);
} else if (e.shift) { // add the part to the selection
if (!curobj.isSelected) {
diagram.raiseDiagramEvent('ChangingSelection', diagram.selection);
let part = curobj;
while (part !== null && !part.canSelect()) part = part.containingGroup;
if (part !== null) part.isSelected = true;
diagram.raiseDiagramEvent('ChangedSelection', diagram.selection);
}
} else {
if (!curobj.isSelected) {
let part = curobj;
while (part !== null && !part.canSelect()) part = part.containingGroup;
if (part !== null) diagram.select(part); // also raises ChangingSelection/Finished
}
}
} else if (e.left && !(e.meta || e.control) && !e.shift) {
// left click on background with no modifier: clear selection
diagram.clearSelection(); // also raises ChangingSelection/Finished
}
}
Diagram.raiseDiagramEvent isn’t officially documented, but it’s in go.d.ts
and you can depend on it.
- The DragSelectingTool.selectInRect method does not raise any DiagramEvents. Here is its definition:
public selectInRect(r: Rect): void {
const diagram = this.diagram;
const e = diagram.lastInput;
const parts = diagram.findPartsIn(r, this.isPartialInclusion);
if (e.meta || e.control) { // toggle or deselect
if (e.shift) { // deselect only
const it = parts.iterator;
while (it.next()) {
const p = it.value;
if (p.isSelected) p.isSelected = false;
}
} else { // toggle selectedness of parts
const it = parts.iterator;
while (it.next()) {
const tp = it.value;
tp.isSelected = !tp.isSelected;
}
}
} else if (e.shift) { // extend selection only
const it = parts.iterator;
while (it.next()) {
const ep = it.value;
if (!ep.isSelected) ep.isSelected = true;
}
} else { // select parts, and unselect all other previously selected parts
// this tries to avoid deselecting and then reselecting any Part
const tounselect = new List<Part>();
const sit = diagram.selection.iterator;
while (sit.next()) {
const sp = sit.value;
if (!parts.contains(sp)) tounselect.add(sp);
}
const uit = tounselect.iterator;
while (uit.next()) {
const up = uit.value;
up.isSelected = false;
}
const it = parts.iterator;
while (it.next()) {
const ps = it.value;
if (!ps.isSelected) ps.isSelected = true;
}
}
}
Also you might find instructive the RealtimeDragSelectingTool implementation, Realtime Drag Selecting Tool , which you can find either as JavaScript in extensions/ or as TypeScript in extensionsJSM/. Here is its override:
public selectInRect(r: go.Rect): void {
const diagram = this.diagram;
const orig = this._originalSelection;
const temp = this._temporarySelection;
const e = diagram.lastInput;
const found = diagram.findPartsIn(r, this.isPartialInclusion);
if (e.control || e.meta) { // toggle or deselect
if (e.shift) { // deselect only
temp.each(function(p: go.Part) { if (!found.contains(p)) p.isSelected = orig.contains(p); });
found.each(function(p: go.Part) { p.isSelected = false; temp.add(p); });
} else { // toggle selectedness of parts based on _originalSelection
temp.each(function(p: go.Part) { if (!found.contains(p)) p.isSelected = orig.contains(p); });
found.each(function(p: go.Part) { p.isSelected = !orig.contains(p); temp.add(p); });
}
} else if (e.shift) { // extend selection only
temp.each(function(p: go.Part) { if (!found.contains(p)) p.isSelected = orig.contains(p); });
found.each(function(p: go.Part) { p.isSelected = true; temp.add(p); });
} else { // select found parts, and unselect all other previously selected parts
temp.each(function(p: go.Part) { if (!found.contains(p)) p.isSelected = false; });
orig.each(function(p: go.Part) { if (!found.contains(p)) p.isSelected = false; });
found.each(function(p: go.Part) { p.isSelected = true; temp.add(p); });
}
}