-
-
Notifications
You must be signed in to change notification settings - Fork 934
Enable Multi-MouseButton Support for dragPan #5354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5354 +/- ##
==========================================
- Coverage 91.84% 91.83% -0.02%
==========================================
Files 282 282
Lines 38908 38930 +22
Branches 6827 6831 +4
==========================================
+ Hits 35735 35750 +15
- Misses 3046 3052 +6
- Partials 127 128 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
How will this behave when rotating with right click (default behavior) and setting drag pan to right click? |
|
|
||
| isValidStartEvent(e: MouseEvent) { | ||
| return this._correctEvent(e); | ||
| return this._correctEvent(e, this._buttons); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of passing buttons it might be better to pass a predicate to override the default one - what happens if someone wants to have right click with control button for panning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to point that out! I've tried setting the right click for panning and it looks like if dragRotate is enabled it will not pan the map. So it is safe for now?.
I would gladly accept any help with a better approach since I'm not good with typescript and have not much experience in large projects in general.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_correctEvent is basically what you want to override.
I would try and find a way to pass it down instead if adding a buttons parameter and pass that down...
|
Any updates on the feedback and questions I asked? |
|
Hi @HarelM, I also need this functionality and am most of the way to an implementation that addresses your comments here. Should I just open a new PR? |
|
My main concern about this feature is button collision when you override one gesture and "cancel" other gesture. |
|
Yes, I can see how you could run into problems if the predicate you use conflicts with another handler. Is it rotate, pitch, and roll you are concerned about? I was thinking it would be simple enough to allow specifying a |
|
There's a few more handlers: zoom, context menu, scroll, two finger gesture/block. |
|
I'm wondering if we're making this all more complicated than it needs to be. I really only need dragPan on middle mouse (in addition to the existing buttons), and I suspect that is all the original issue author wanted as well. What would you think about dropping the idea of button configuration and just make dragPan handled on middle-mouse by default? |
|
I think that you can hack the following in theory (I haven't fully tested it): |
Ah yes, interesting. I would be pretty hesitant to reach into the internals like that without a proper API.
This is the minimal change I am proposing. Are there reasons not to want to support drag pan with middle mouse by default? diff --git a/src/ui/handler/drag_move_state_manager.ts b/src/ui/handler/drag_move_state_manager.ts
index 5ef48fb72..a8b5b0097 100644
--- a/src/ui/handler/drag_move_state_manager.ts
+++ b/src/ui/handler/drag_move_state_manager.ts
@@ -1,12 +1,14 @@
import {DOM} from '../../util/dom';
const LEFT_BUTTON = 0;
+const MIDDLE_BUTTON = 1;
const RIGHT_BUTTON = 2;
// the values for each button in MouseEvent.buttons
const BUTTONS_FLAGS = {
[LEFT_BUTTON]: 1,
- [RIGHT_BUTTON]: 2
+ [RIGHT_BUTTON]: 2,
+ [MIDDLE_BUTTON]: 4,
};
function buttonNoLongerPressed(e: MouseEvent, button: number) {
diff --git a/src/ui/handler/mouse.ts b/src/ui/handler/mouse.ts
index 30dd66471..1e712a6cd 100644
--- a/src/ui/handler/mouse.ts
+++ b/src/ui/handler/mouse.ts
@@ -23,6 +23,7 @@ export interface MousePitchHandler extends DragMoveHandler<DragPitchResult, Mous
export interface MouseRollHandler extends DragMoveHandler<DragRollResult, MouseEvent> {}
const LEFT_BUTTON = 0;
+const MIDDLE_BUTTON = 1;
const RIGHT_BUTTON = 2;
const assignEvents = (handler: DragHandler<DragPanResult, MouseEvent>) => {
@@ -39,7 +40,9 @@ export function generateMousePanHandler({enable, clickTolerance}: {
enable?: boolean;
}): MousePanHandler {
const mouseMoveStateManager = new MouseMoveStateManager({
- checkCorrectEvent: (e: MouseEvent) => DOM.mouseButton(e) === LEFT_BUTTON && !e.ctrlKey,
+ checkCorrectEvent: (e: MouseEvent) =>
+ (DOM.mouseButton(e) === LEFT_BUTTON && !e.ctrlKey) ||
+ (DOM.mouseButton(e) === MIDDLE_BUTTON),
});
return new DragHandler<DragPanResult, MouseEvent>({
clickTolerance, |
|
I don't think this is the same as the original issue, I'm also not sure why you'd need to support both left click and middle click to drag... |
|
Yes, you are correct. And as I've been exploring this more for our own use I've run into the issue you were worried about with conflicting handlers. For now I'm using your suggestion to do this (map.dragPan._mousePan as any)._moveStateManager._correctEvent =...It doesn't quite work on it's own if you want middle mouse support because middle mouse is not considered valid by export const LEFT_BUTTON = 0
export const MIDDLE_BUTTON = 1
export const RIGHT_BUTTON = 2
export const BUTTONS_FLAGS = {
[LEFT_BUTTON]: 1,
[MIDDLE_BUTTON]: 4,
[RIGHT_BUTTON]: 2,
}
const manager = (map.dragPan as any)._mousePan._moveStateManager
manager.isValidMoveEvent = function (e: MouseEvent): boolean {
if (this._eventButton === undefined) return false
const flag = BUTTONS_FLAGS[this._eventButton]
if (flag === undefined) return false
return valid = e.buttons !== undefined && (e.buttons & flag) === flag
}I'll see if a reasonable pattern emerges for setting groups of handlers in a coherent way as I'm implementing it for our use case. |
This PR enhances the functionality of dragPan in MapLibre GL JS, addressing feature request #5341.
It introduces the ability to configure one or multiple mouse buttons for the dragPan interaction using the MouseEvent.button property.
Previously, dragPan was limited to left mouse button, restricting user interaction and personalization. This improvement provides greater flexibility for users who want to customize the drag behavior of the map.
Examples
1. Configuring on Map Initialization:
2. Updating on DragPan Enable:
Launch Checklist
CHANGELOG.mdunder the## mainsection.