Make mouse behavior better

This commit is contained in:
dylan 2023-05-08 23:14:01 -07:00
parent 7f9e873323
commit b248a016a9
2 changed files with 72 additions and 6 deletions

View File

@ -177,6 +177,7 @@ const transformForPaste = (text: string) => {
}
const state = {
doubleClickTimer: 0,
history: [] as Array<{code: string, anchor: number, focus: number}>,
historyDebounce: 0,
historyIndex: 0,
@ -222,6 +223,7 @@ const state = {
}
this.historyDebounce = historyDebounceFrames;
},
wordMode: false,
scrollX: 0,
scrollY: 0,
anchor: 0,
@ -240,6 +242,34 @@ const state = {
clampInRange(n: number) {
return Math.max(0, Math.min(n, this.code.length))
},
findNearestWordBoundaryLeft(index: number) {
if (index === this.code.length-1) {
return index;
}
const words1 = this.code.slice(0, index+1).split(/\b/g);
if (words1[words1.length-1].length === 1) {
return index;
}
const words = this.code.slice(0, index).split(/\b/g);
if (!words.length) {
return 0;
}
return index-words[words.length-1].length;
},
findNearestWordBoundaryRight(index: number) {
if (index === 0) {
return index;
}
const words1 = this.code.slice(index-1).split(/\b/g);
if (words1[0].length === 1) {
return index;
}
const words = this.code.slice(index).split(/\b/g);
if (!words.length) {
return this.code.length;
}
return index+words[0].length;
},
setSelection(anchor: number | {x: number, y: number}, focus?: number | {x: number, y: number}) {
if (typeof anchor !== "number") {
anchor = gridToIndex(this.code, anchor.x, anchor.y);
@ -248,14 +278,36 @@ const state = {
if (typeof focus !== "number") {
focus = gridToIndex(this.code, focus.x, focus.y);
}
this.anchor = this.clampInRange(anchor),
this.anchor = this.clampInRange(anchor);
this.focus = this.clampInRange(focus);
if (this.wordMode) {
console.log('word mode', this.anchor, this.focus, this.findNearestWordBoundaryLeft(this.anchor), this.findNearestWordBoundaryRight(this.focus));
if (this.anchor <= this.focus) {
this.anchor = this.findNearestWordBoundaryLeft(this.anchor);
this.focus = this.findNearestWordBoundaryRight(this.focus);
} else {
this.anchor = this.findNearestWordBoundaryRight(this.anchor);
this.focus = this.findNearestWordBoundaryLeft(this.focus);
}
}
this.anchor = this.clampInRange(this.anchor);
this.focus = this.clampInRange(this.focus);
},
setFocus(focus: number | {x: number, y: number}) {
if (typeof focus !== "number") {
focus = gridToIndex(this.code, focus.x, focus.y);
}
this.focus = this.clampInRange(focus);
if (this.wordMode) {
if (this.anchor <= this.focus) {
this.anchor = this.findNearestWordBoundaryLeft(this.anchor);
this.focus = this.findNearestWordBoundaryRight(this.focus);
} else {
this.anchor = this.findNearestWordBoundaryRight(this.anchor);
this.focus = this.findNearestWordBoundaryLeft(this.focus);
}
}
this.focus = this.clampInRange(this.focus);
},
insertText(text: string) {
const {code, anchor, focus} = this;
@ -453,13 +505,23 @@ const update = async () => {
state.snapshot();
}
}
if (state.doubleClickTimer > 0) {
state.doubleClickTimer -= 1;
}
if (mouseDown()) {
if (mouseDown() && !shiftKeyDown()) {
if (state.doubleClickTimer > 0) {
state.wordMode = true;
} else {
state.doubleClickTimer = 10;
}
const {x, y} = mousePos();
state.setSelection(pixelToIndex(state.code, x, y-8));
} else if (mouseHeld()) {
const {x, y} = mousePos();
state.setFocus(pixelToIndex(state.code, x, y-8));
} else {
state.wordMode = false;
}
const keyboardString = getKeyboardString();

View File

@ -14,7 +14,7 @@ const mouseButtonsDown = {
[M.MIDDLE]: false,
};
const mouseEvents: Array<{
type: "click" | "down" | "up" | "move",
type: "click" | "down" | "up" | "move" | "dblclick",
button: typeof M[keyof typeof M],
x: number,
y: number,
@ -35,9 +35,9 @@ const eventPixelCoords = (evt: WindowMouseEvent) => {
}
}
// addEventListener("dblclick", (evt) => {
// console.log("dblclick", evt.button, evt.clientX, evt.clientY);
// });
addEventListener("dblclick", (evt) => {
mouseEvents.push({type: "dblclick", button: evt.button, ...eventPixelCoords(evt)});
});
addEventListener("click", (evt) => {
mouseEvents.push({type: "click", button: evt.button, ...eventPixelCoords(evt)});
@ -87,6 +87,10 @@ export const mouseClick = (button: number = M.LEFT) => {
return mouseEvents.some(ev => ev.button === button && ev.type === "click");
}
export const mouseDoubleClick = (button: number = M.LEFT) => {
return mouseEvents.some(ev => ev.button === button && ev.type === "dblclick");
}
export const mouseHeld = (button: number = M.LEFT) => {
return mouseButtonsDown[button];
}