Skip to content

Commit

Permalink
Add support for modifying multi-select keys
Browse files Browse the repository at this point in the history
Signed-off-by: Hollow Man <[email protected]>
  • Loading branch information
HollowMan6 committed Jun 29, 2024
1 parent 83275d3 commit a26aa24
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 10 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ options = {
disabledIcon: 'https://github.com/mit-cml/workspace-multiselect/raw/main/test/media/unselect.svg',
},

// Keys for multi-selection mode switch. Any key value is possible (see MDN docs).
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
// The best support (default) is given for Shift. Provide an empty array []
// will revert to the default key.
multiSelectKeys: ['Shift', 'Control'],

multiselectCopyPaste: {
// Enable the copy/paste accross tabs feature (true by default).
crossTab: true,
Expand Down
12 changes: 9 additions & 3 deletions src/multiselect.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export class Multiselect {
this.useCopyPasteCrossTab_ = true;
this.useCopyPasteMenu_ = true;
this.multiFieldUpdate_ = true;
this.multiSelectKeys_ = ['shift'];
}

/**
Expand All @@ -44,6 +45,11 @@ export class Multiselect {
* to set.
*/
init(options) {
if (options.multiSelectKeys && options.multiSelectKeys.length > 0) {
this.multiSelectKeys_ = options.multiSelectKeys.map((key) => {
return key.toLocaleLowerCase();
});
}
const injectionDiv = this.workspace_.getInjectionDiv();
this.onKeyDownWrapper_ = Blockly.browserEvents.conditionalBind(
injectionDiv, 'keydown', this, this.onKeyDown_);
Expand Down Expand Up @@ -87,7 +93,7 @@ export class Multiselect {
}

this.controls_ = new MultiselectControls(
this.workspace_, options.multiselectIcon, this);
this.workspace_, options.multiselectIcon, this.multiSelectKeys_);
multiselectControlsList.add(this.controls_);
if (!options.multiselectIcon || !options.multiselectIcon.hideIcon) {
const svgControls = this.controls_.createDom();
Expand Down Expand Up @@ -329,7 +335,7 @@ export class Multiselect {
* @private
*/
onKeyDown_(e) {
if (e.keyCode === Blockly.utils.KeyCodes.SHIFT &&
if (this.multiSelectKeys_.indexOf(e.key.toLocaleLowerCase()) > -1 &&
!inMultipleSelectionModeWeakMap.get(this.workspace_)) {
this.controls_.enableMultiselect();
}
Expand All @@ -341,7 +347,7 @@ export class Multiselect {
* @private
*/
onKeyUp_(e) {
if (e.keyCode === Blockly.utils.KeyCodes.SHIFT) {
if (this.multiSelectKeys_.indexOf(e.key.toLocaleLowerCase()) > -1) {
this.controls_.disableMultiselect();
}
}
Expand Down
20 changes: 13 additions & 7 deletions src/multiselect_controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@ export class MultiselectControls {
/**
* @param {!Blockly.WorkspaceSvg} workspace The workspace to sit in.
* @param {Object} options The icons configuration.
* @param {!Array<string>} multiSelectKeys The key codes for
* switching between multi select mode.
*/
constructor(workspace, options) {
constructor(workspace, options, multiSelectKeys) {
/**
* Icon path of the multi select controls when enabled.
* @type {string}
Expand Down Expand Up @@ -86,6 +88,13 @@ export class MultiselectControls {
*/
this.id = 'multiselectControls';

/**
* The key codes for switching between multi select.
* @type {!Array<string>}
* @private
*/
this.multiSelectKeys_ = multiSelectKeys;

/**
* A handle to use to unbind the mouse down event handler for multi select
* button. Opaque data returned from browserEvents.conditionalBind.
Expand Down Expand Up @@ -371,6 +380,7 @@ export class MultiselectControls {
multiselectMode: true,
draggability: false,
usePointerEvents: true,
multiSelectKeys: this.multiSelectKeys_,
});
// Filter out the parent block when selecting child blocks
// to mitigate the invisible rectangles issue.
Expand Down Expand Up @@ -423,9 +433,7 @@ export class MultiselectControls {
});
if (byIcon) {
document.dispatchEvent(
new KeyboardEvent('keydown', {'key': 'shift'}));
this.workspace_.getInjectionDiv().dispatchEvent(
new KeyboardEvent('keydown', {'key': 'meta'}));
new KeyboardEvent('keydown', {'key': this.multiSelectKeys_[0]}));
}
this.updateMultiselectIcon(true);
inMultipleSelectionModeWeakMap.set(this.workspace_, true);
Expand All @@ -439,10 +447,8 @@ export class MultiselectControls {
inMultipleSelectionModeWeakMap.set(this.workspace_, false);
if (this.dragSelect_) {
if (byIcon) {
this.workspace_.getInjectionDiv().dispatchEvent(
new KeyboardEvent('keyup', {'key': 'meta'}));
document.dispatchEvent(
new KeyboardEvent('keyup', {'key': 'shift'}));
new KeyboardEvent('keyup', {'key': this.multiSelectKeys_[0]}));
}
this.dragSelect_.stop();
this.dragSelect_ = null;
Expand Down
1 change: 1 addition & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ document.addEventListener('DOMContentLoaded', function() {
enabledIcon: 'media/select.svg',
disabledIcon: 'media/unselect.svg',
},
multiSelectKeys: ['Shift', 'Control'],
multiselectCopyPaste: {
crossTab: true,
menu: true,
Expand Down

0 comments on commit a26aa24

Please sign in to comment.