Skip to content
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

feat: support both mouse selection with the left mouse button and panning with the middle mouse button in the graph #3965

Merged
Merged
4 changes: 4 additions & 0 deletions examples/x6-example-features/src/pages/selection/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export default class Example extends React.Component {
width: 800,
height: 600,
grid: true,
panning: {
enabled: true,
eventTypes: ['mouseWheelDown'],
},
})

const keyboard = new Keyboard()
Expand Down
38 changes: 36 additions & 2 deletions packages/x6-plugin-selection/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ export class Selection
Selection.defaultOptions,
options,
)

if (!Array.isArray(this.options.eventTypes)) {
// a new option, compatible with the behavior of older versions
this.options.eventTypes = ['leftMouseDown', 'mouseWheelDown']
aMoonkin marked this conversation as resolved.
Show resolved Hide resolved
}
aMoonkin marked this conversation as resolved.
Show resolved Hide resolved

CssLoader.ensure(this.name, content)
}

Expand Down Expand Up @@ -304,21 +310,47 @@ export class Selection
}

protected startListening() {
this.graph.on('blank:mousedown', this.onBlankMouseDown, this)
if (this.options.eventTypes?.includes('leftMouseDown')) {
aMoonkin marked this conversation as resolved.
Show resolved Hide resolved
this.graph.on('blank:mousedown', this.onBlankLeftMouseDown, this)
}
if (this.options.eventTypes?.includes('mouseWheelDown')) {
this.graph.on('blank:mousedown', this.onBlankMouseWheelDown, this)
}
this.graph.on('blank:click', this.onBlankClick, this)
this.graph.on('cell:mousemove', this.onCellMouseMove, this)
this.graph.on('cell:mouseup', this.onCellMouseUp, this)
this.selectionImpl.on('box:mousedown', this.onBoxMouseDown, this)
}

protected stopListening() {
this.graph.off('blank:mousedown', this.onBlankMouseDown, this)
if (this.options.eventTypes?.includes('leftMouseDown')) {
this.graph.off('blank:mousedown', this.onBlankLeftMouseDown, this)
}
if (this.options.eventTypes?.includes('mouseWheelDown')) {
this.graph.off('blank:mousedown', this.onBlankMouseWheelDown, this)
}
this.graph.off('blank:click', this.onBlankClick, this)
this.graph.off('cell:mousemove', this.onCellMouseMove, this)
this.graph.off('cell:mouseup', this.onCellMouseUp, this)
this.selectionImpl.off('box:mousedown', this.onBoxMouseDown, this)
}

protected onBlankLeftMouseDown(mouseDownEvent: EventArgs['blank:mousedown']) {
if (mouseDownEvent.e.button !== 0) {
aMoonkin marked this conversation as resolved.
Show resolved Hide resolved
return
}
this.onBlankMouseDown(mouseDownEvent)
}

protected onBlankMouseWheelDown(
mouseDownEvent: EventArgs['blank:mousedown'],
) {
if (mouseDownEvent.e.button !== 1) {
return
}
this.onBlankMouseDown(mouseDownEvent)
}

protected onBlankMouseDown({ e }: EventArgs['blank:mousedown']) {
const allowGraphPanning = this.graph.panning.allowPanning(e, true)
const scroller = this.graph.getPlugin<any>('scroller')
Expand Down Expand Up @@ -449,9 +481,11 @@ export class Selection
}

export namespace Selection {
type SelectionEventType = 'leftMouseDown' | 'mouseWheelDown'
export interface EventArgs extends SelectionImpl.EventArgs {}
export interface Options extends SelectionImpl.CommonOptions {
enabled?: boolean
eventTypes?: SelectionEventType[]
aMoonkin marked this conversation as resolved.
Show resolved Hide resolved
}

export type Filter = SelectionImpl.Filter
Expand Down
21 changes: 20 additions & 1 deletion packages/x6/src/graph/panning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ export class PanningManager extends Base {
this.onRightMouseDown = this.onRightMouseDown.bind(this)
Dom.Event.on(this.graph.container, 'mousedown', this.onRightMouseDown)
}

if (eventTypes.includes('mouseWheelDown')) {
aMoonkin marked this conversation as resolved.
Show resolved Hide resolved
this.onMouseWheelDown = this.onMouseWheelDown.bind(this)
Dom.Event.on(this.graph.container, 'mousedown', this.onMouseWheelDown)
}

if (eventTypes.includes('mouseWheel')) {
this.mousewheelHandle = new Dom.MouseWheelHandle(
this.graph.container,
Expand All @@ -57,6 +63,9 @@ export class PanningManager extends Base {
if (eventTypes.includes('rightMouseDown')) {
Dom.Event.off(this.graph.container, 'mousedown', this.onRightMouseDown)
}
if (eventTypes.includes('mouseWheelDown')) {
Dom.Event.off(this.graph.container, 'mousedown', this.onMouseWheelDown)
}
if (eventTypes.includes('mouseWheel')) {
if (this.mousewheelHandle) {
this.mousewheelHandle.disable()
Expand Down Expand Up @@ -137,6 +146,12 @@ export class PanningManager extends Base {
}
}

protected onMouseWheelDown(e: Dom.MouseDownEvent) {
if (e.button === 1 && this.allowPanning(e, true)) {
this.startPanning(e)
}
}

protected allowMouseWheel(e: WheelEvent) {
return this.pannable && !e.ctrlKey
}
Expand Down Expand Up @@ -195,7 +210,11 @@ export class PanningManager extends Base {
}

export namespace PanningManager {
type EventType = 'leftMouseDown' | 'rightMouseDown' | 'mouseWheel'
type EventType =
| 'leftMouseDown'
aMoonkin marked this conversation as resolved.
Show resolved Hide resolved
| 'rightMouseDown'
| 'mouseWheel'
| 'mouseWheelDown'
export interface Options {
enabled?: boolean
modifiers?: string | ModifierKey[] | null
Expand Down
Loading