Fix touch re-ordering in the presets and bank management dialogs.

This commit is contained in:
Robin E. R. Davies
2025-06-22 23:44:46 -04:00
parent f95ecebb6b
commit 130cda3773
8 changed files with 68 additions and 41 deletions
+1
View File
@@ -3,6 +3,7 @@ channel bindings help dialog. <ChannelBindingHelpDialog
Tooltips on touch ui?
draggable UI: scrolloffset!?
- pipewire aux in?
+4
View File
@@ -19,6 +19,10 @@ div {
min-width: 0;
}
.draggable-button-base {
touch-action: none;
}
@media not all /* seems to be ok in current chrome (prefers-color-scheme: light) */{
input[type="number"].scrollMod::-webkit-outer-spin-button,
input[type="number"].scrollMod::-webkit-inner-spin-button {
+5
View File
@@ -783,6 +783,11 @@ export
onContextMenu={(e) => {
if (!this.model_.debug) {
e.preventDefault(); e.stopPropagation();
} else {
if ((e.target as any).tagName === "IMG") {
e.preventDefault();
e.stopPropagation();
}
}
}}
>
+1 -1
View File
@@ -456,7 +456,7 @@ const BankDialog = withStyles(
{(this.state.banks.getEntry(this.state.selectedItem) != null)
&& (
<div style={{ flex: "0 0 auto" }}>
<div style={{ flex: "0 0 auto", display: "flex", flexFlow: "row nowrap", alignItems: "center" }}>
<Button color="inherit" onClick={(e) => this.handleCopy()}>
Copy
</Button>
+28 -13
View File
@@ -48,18 +48,12 @@ function isValidPointer(e: React.PointerEvent): boolean {
return false;
}
function screenToClient(element: HTMLElement, point: Point): Point {
const dpr = (window.devicePixelRatio || 1) as number;;
function screenToClient(e: React.PointerEvent): Point {
let element = e.currentTarget;
let rect = element.getBoundingClientRect();
const cssScreenX = point.x / dpr;
const cssScreenY = point.y / dpr;
const cssWindowX = window.screenX / dpr;
const cssWindowY = window.screenY / dpr;
const clientX = cssScreenX - cssWindowX - rect.left;
const clientY = cssScreenY - cssWindowY - rect.top;
return { x: clientX, y: clientY };
const x = e.clientX + rect.left;
const y = e.clientY + rect.right;
return { x: x, y: y };
}
export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
@@ -118,6 +112,12 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
return (
<ButtonBase
{...rest}
className="draggable-button-base"
onContextMenu={(e) => {
e.preventDefault();
e.stopPropagation();
return false;
}}
onPointerDown={(e) => {
if (!isValidPointer(e)) {
return;
@@ -127,7 +127,7 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
}
e.currentTarget.setPointerCapture(e.pointerId);
setPointerId(e.pointerId);
setPointerDownPoint(screenToClient(e.currentTarget,{ x: e.screenX, y: e.screenY }));
setPointerDownPoint(screenToClient(e));
let currentTarget = e.currentTarget as HTMLButtonElement;
if (longPressDelay === undefined || longPressDelay >= 0)
@@ -144,6 +144,9 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
setSuppressClick(true);
}, longPressDelay??1250));
}
e.preventDefault();
e.stopPropagation();
return false;
}}
onPointerMove={(e) => {
if (e.pointerId === pointerId) {
@@ -152,7 +155,7 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
props.onLongPressMove(e);
}
} else {
let clientPoint = screenToClient(e.currentTarget as HTMLElement, {x: e.screenX, y: e.screenY} );
let clientPoint = screenToClient(e);
let dx = pointerDownPoint.x- clientPoint.x;
let dy = pointerDownPoint.y - clientPoint.y;
@@ -161,6 +164,9 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
}
}
}
e.preventDefault();
e.stopPropagation();
return false;
}}
onPointerUp={(e) => {
if (e.pointerId === pointerId) {
@@ -176,8 +182,17 @@ export default function DraggableButtonBase(props: DraggableButtonBaseProps) {
setSuppressClick(true); // only way to cancel the click
return;
}
e.preventDefault();
e.stopPropagation();
}
}}
// onTouchStart={(e)=> {
// //e.preventDefault();
// }}
// onTouchMove={(e)=> {
// //e.preventDefault();
// }}
onClick={(e) => {
if (clickSuppressed) {
e.stopPropagation();
+9 -7
View File
@@ -305,8 +305,6 @@ const DraggableGrid =
handlePointerDownCapture(e: any) {
// a new pointer down of any type cancels capture
this.cancelDrag();
e.preventDefault();
e.stopPropagation();
}
@@ -500,6 +498,7 @@ const DraggableGrid =
element.style.zIndex = this.savedIndex;
element.style.background = this.savedBackground;
element.style.opacity = "1";
element.style.touchAction = "";
}
@@ -575,8 +574,8 @@ const DraggableGrid =
let originalBounds = this.animationData[this.startIndex].originalPosition;
let newLocation = new DOMRect(
originalBounds.x + clientX - this.startX,
originalBounds.y + clientY - this.startY,
originalBounds.x + clientX - this.startX+3,
originalBounds.y + clientY - this.startY+3,
originalBounds.width,
originalBounds.height);
@@ -704,6 +703,7 @@ const DraggableGrid =
this.savedIndex = gridElement.style.zIndex;
gridElement.style.zIndex = "3";
gridElement.style.touchAction = "none";
this.savedBackground = gridElement.style.background;
gridElement.style.background = isDarkMode()? "333": "#EEE";
gridElement.style.opacity = "0.8";
@@ -719,8 +719,8 @@ const DraggableGrid =
let grid = this.refGrid.current!;
this.gridBounds = grid.getBoundingClientRect();
window.addEventListener("touchmove",this.handleTouchMove, {passive: false});
window.addEventListener("touchend",this.handleTouchEnd, {passive: false});
window.addEventListener("touchmove",this.handleTouchMove, {capture: true, passive: false});
window.addEventListener("touchend",this.handleTouchEnd, {capture: true, passive: false});
this.prepareChildren();
@@ -754,7 +754,7 @@ const DraggableGrid =
}
}
handlePointerMove(e: PointerEvent<HTMLDivElement>): void {
handlePointerMove(e: PointerEvent<HTMLDivElement>): boolean {
if (this.isCapturedPointer(e)) {
if (!this.dragStarted && this.dragThresholdExceeded(e)) {
this.startDrag();
@@ -779,8 +779,10 @@ const DraggableGrid =
}
this.checkForAutoScroll(e.currentTarget);
return false;
}
}
return true;
}
autoScrollTimer?: number;
+17 -19
View File
@@ -93,20 +93,11 @@ const audioFileExtensions: { [name: string]: boolean } = {
".ra": true
};
function screenToClient(element: HTMLDivElement, point: Point): Point {
const dpr = (window.devicePixelRatio || 1) as number;;
let rect = element.getBoundingClientRect();
const cssScreenX = point.x / dpr;
const cssScreenY = point.y / dpr;
const cssWindowX = window.screenX / dpr;
const cssWindowY = window.screenY / dpr;
const clientX = cssScreenX - cssWindowX - rect.left;
const clientY = cssScreenY - cssWindowY - rect.top;
return { x: clientX, y: clientY };
function screenToClient(currentTarget: HTMLElement, e: React.PointerEvent): Point {
let rect = currentTarget.getBoundingClientRect();
const x = e.clientX + rect.left;
const y = e.clientY + rect.right;
return { x: x, y: y };
}
function isAudioFile(filename: string) {
let npos = filename.lastIndexOf('.');
@@ -265,6 +256,11 @@ export default withStyles(
private mounted: boolean = false;
private model: PiPedalModel;
transformDragPoint(element: HTMLElement, point: Point): Point {
// STUB: will have to deal with scroll offset at some point.
return point;
}
private requestFiles(navPath: string) {
if (!this.props.open) {
return;
@@ -355,8 +351,8 @@ export default withStyles(
element.style.top = "5px";
element.style.left = "5px";
element.style.background = isDarkMode() ? "#555" : "#EEF" // xxx: dark mode.
if (this.lastDivRef) {
this.longPressStartPoint = screenToClient(this.lastDivRef, { x: e.screenX, y: e.screenY });
if (this.listContainerElementRef) {
this.longPressStartPoint = screenToClient(currentTarget,e);
}
return true;
} else if (!this.state.multiSelect) {
@@ -379,9 +375,9 @@ export default withStyles(
if (!this.isTracksDirectory()) {
return;
}
if (this.lastDivRef) {
if (this.listContainerElementRef) {
let element = e.target as HTMLButtonElement;
let point = screenToClient(this.lastDivRef, { x: e.screenX, y: e.screenY });
let point = screenToClient(e.currentTarget,e);
if (this.longPressStartPoint) {
let dy = point.y - this.longPressStartPoint.y;
element.style.left = (5) + "px";
@@ -929,6 +925,8 @@ export default withStyles(
return (<InsertDriveFileIcon style={style} />);
}
listContainerElementRef: HTMLDivElement | null = null;
render() {
const isTracksDirectory = this.isTracksDirectory();
@@ -1167,7 +1165,7 @@ export default withStyles(
</div>
<div
ref={(element) => this.onMeasureRef(element)}
ref={(element) => { this.listContainerElementRef = element; this.onMeasureRef(element); }}
style={{
flex: "1 1 100%", display: "flex", flexFlow: "row wrap",
position: "relative", justifyContent: "flex-start", alignContent: "flex-start", paddingLeft: 16, paddingBottom: 16
+3 -1
View File
@@ -385,7 +385,9 @@ const PresetDialog = withStyles(
{(this.state.presets.getItem(this.state.selectedItem) != null)
&& (
<div style={{ flex: "0 0 auto" }}>
<div style={{ flex: "0 0 auto", display: "flex", flexFlow: "row nowrap", alignItems: "center"
}}>
<Button color="inherit" onClick={(e) => this.handleCopy()}>
Copy
</Button>