Skip to content

Commit

Permalink
7 support multiselect (#18)
Browse files Browse the repository at this point in the history
* Add multiselect using shift click and batch shift/change fill effect

* Add key deselection and finer grain movement/resizing

* Move right click menu to left hand side when there is not enough space
  • Loading branch information
DjCrqss authored Jan 29, 2024
1 parent 641fc6e commit 147c3c0
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 35 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Pressure-sensitive display for the analogue values of your Wooting keyboard! Vis

### Customisation and Presets
Woot-verlay is made to be extremely customisable. Right-click on keys to rename, change the fill direction or delete them.
Drag the keys to shift them around. Grab the green or orange dotted edges of a key to resize.
Drag the keys to shift them around. Grab the green or orange dotted edges of a key to resize. Shift click to multi select.
<br>

Presets are available to save and import. They can be found [here in the project wiki!](https://github.com/DjCrqss/Woot-verlay/wiki/Presets)
Expand Down
2 changes: 1 addition & 1 deletion js/keyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function buildKey(curKey) {
curLabel.textContent = curKey.label;

// make key draggable and listen to other mouse events
dragElement(curDiv);
keyInteract(curDiv);

buildOptions();
}
Expand Down
153 changes: 120 additions & 33 deletions js/keymenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@

const menuDialog = document.getElementById("keyOptionDialog");
const renameInput = document.getElementById("keyLabel");
var activeKey;

var activeKey; // current key being interacted with for single select and for right click menu positioning
var selectedKeys = new Set(); // list of keys selected with shift or box select

// show menu
function showOptions() {
menuDialog.style.display = "flex";
menuDialog.style.top = parseInt(activeKey.style.top) + 8 + "px";
menuDialog.style.left = parseInt(activeKey.style.left) + activeKey.clientWidth + 20 + "px";
menuDialog.style.top = parseInt(activeKey.style.top) + 8 - window.scrollY + "px";

// if key is too close to the right side of the screen, show menu on the left
if (parseInt(activeKey.style.left) + activeKey.clientWidth + menuDialog.offsetWidth > window.innerWidth) {
menuDialog.style.left = parseInt(activeKey.style.left) - menuDialog.clientWidth - window.scrollX + "px";
} else {
menuDialog.style.left = parseInt(activeKey.style.left) + activeKey.clientWidth + 20 - window.scrollX + "px";
}

if(activeKey != null) {
renameInput.value = activeKey.getElementsByClassName('label')[0].innerHTML;
}
Expand All @@ -16,9 +26,10 @@ function showOptions() {
// update direction of key object
function updateKeySettings(direction) {
if (activeKey != null) {
var progress = activeKey.getElementsByClassName('progress')[0];
progress.className = "progress";
progress.classList.add(direction);
selectedKeys.forEach(key => {
key.element.getElementsByClassName('progress')[0].className = "progress";
key.element.getElementsByClassName('progress')[0].classList.add(direction);
});
}
saveState();
}
Expand All @@ -34,42 +45,88 @@ function updateKeyLabel(event){

// hide menu
document.addEventListener("click", function (event) {
if (activeKey != null && !menuDialog.contains(event.target)) {
if (activeKey != null && !menuDialog.contains(event.target) && !activeKey.contains(event.target)
&& ![...selectedKeys].some(x => x.element.contains(event.target)) && !event.shiftKey){
activeKey.style.backgroundColor = "";
activeKey = null;
hideDialog();
deselect();
}
});

// add listener for CTRL + A
// document.addEventListener("keydown", function (event) {
// if (event.ctrlKey && event.key === 'a') {
// event.preventDefault();
// // select all keys
// keyboard.childNodes.forEach(key => {
// select(key);
// });
// }
// });


function hideDialog() {
menuDialog.style.display = "none";
}

async function removeKey() {
if (activeKey != null) {
activeKey.style.opacity = 0;
activeKey.style.backgroundColor = "#925555";
hideDialog();
selectedKeys.forEach(key => {
key.element.style.opacity = 0;
key.element.style.backgroundColor = "#925555";
});

await new Promise(resolve => setTimeout(resolve, 500));
try { keyboard.removeChild(activeKey); } catch (exception) { }
try {
selectedKeys.forEach(key => {
keyboard.removeChild(key.element);
});
} catch (exception) { }
activeKey = null;
deselect();
saveState();
}
}

async function select(elmnt){
// if not already in selected keys, add to list
if(![...selectedKeys].some(x => x.element == elmnt)){
selectedKeys.add({
element: elmnt,
x: parseInt(elmnt.style.left),
y: parseInt(elmnt.style.top),
oldPosX: 0,
oldPosY: 0,
width: elmnt.clientWidth,
height: elmnt.clientHeight
});
}

activeKey = elmnt;
elmnt.style.backgroundColor = "var(--wooting-yellow)";
}
async function deselect(){
selectedKeys.forEach(key => {
key.element.style.backgroundColor = "";
});
selectedKeys.clear();
hideDialog();
}

// all functions related to dragging and resizing a key
function dragElement(elmnt) {
function keyInteract(elmnt) {
// current position
var x = parseInt(elmnt.style.left);
var y = parseInt(elmnt.style.top);
var x = 0;
var y = 0;
// curent size
var width = elmnt.clientWidth;
var height = elmnt.clientHeight;
var width = 0;
var height = 0;
// previous mouse position
var oldPosX = 0;
var oldPosY = 0;

elmnt.onmousedown = dragMouseDown;
elmnt.onmousedown = mouseDown;
elmnt.onmousemove = showResize;

async function showResize(e){
Expand All @@ -84,32 +141,48 @@ function dragElement(elmnt) {
}
}

async function dragMouseDown(e) {
async function mouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup
// update initial values
x = parseInt(elmnt.style.left);
y = parseInt(elmnt.style.top);
oldPosX = e.clientX;
oldPosY = e.clientY;
document.onmouseup = closeDragElement;
width = elmnt.clientWidth;
height = elmnt.clientHeight;

// call a function whenever the cursor moves
if (e.button === 2) { // show options on left click
if(activeKey != null) {
activeKey.style.backgroundColor = "";
document.onmouseup = mouseUp;


if (e.shiftKey && e.button === 0) {
// add to selection on shift click
if(![...selectedKeys].some(x => x.element == elmnt)){
select(elmnt);
} else {
// remove from selection on shift click
selectedKeys.delete([...selectedKeys].find(x => x.element == elmnt));
elmnt.style.backgroundColor = "";
}
activeKey = elmnt;
activeKey.style.backgroundColor = "var(--wooting-yellow)";
}
// deselect if not shift click
else if(activeKey != null && ![...selectedKeys].some(x => x.element == elmnt)) {
deselect();
}

if (e.button === 2) { // show options on left click
select(elmnt);
showOptions();
} else if(e.clientX > parseInt(elmnt.style.left) + elmnt.offsetWidth - 5 && e.clientY > parseInt(elmnt.style.top) + elmnt.offsetHeight - 5){ // resize both when dragging bottom right corner
document.onmousemove = elementResizeBoth;
}else if ((e.clientX > parseInt(elmnt.style.left) + elmnt.offsetWidth - 5)) { // resize width when dragging right side
} else if ((e.clientX > parseInt(elmnt.style.left) + elmnt.offsetWidth - 5)) { // resize width when dragging right side
document.onmousemove = elementResizeWidth;
} else if (e.clientY > parseInt(elmnt.style.top) + elmnt.offsetHeight - 5) { // resize height when dragging bottom
document.onmousemove = elementResizeHeight;
} else { // move on drag
document.onmousemove = elementDrag;
}


}

Expand Down Expand Up @@ -164,18 +237,32 @@ function dragElement(elmnt) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
x += (e.clientX - oldPosX);
y += (e.clientY - oldPosY);
// set the element's new position:

xDiff = e.clientX - oldPosX;
yDiff = e.clientY - oldPosY;

x += xDiff;
y += yDiff;
elmnt.style.top = snapGrid(y) + "px";
elmnt.style.left = snapGrid(x) + "px";

selectedKeys.forEach(key => {
// if(key.element == elmnt) return;
key.x += xDiff;
key.y += yDiff;
key.element.style.top = snapGrid(key.y) + "px";
key.element.style.left = snapGrid(key.x) + "px";
key.oldPosX = e.clientX;
key.oldPosY = e.clientY;
});

// set old values
oldPosX = e.clientX;
oldPosY = e.clientY;

}

function closeDragElement() {
function mouseUp() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
Expand All @@ -185,7 +272,7 @@ function dragElement(elmnt) {
}

function snapGrid(num) {
return Math.ceil(num / 6) * 6;
return Math.ceil(num / 4) * 4;
}


0 comments on commit 147c3c0

Please sign in to comment.