Skip to content

Commit

Permalink
Implemented middle click to jump-to-location
Browse files Browse the repository at this point in the history
  • Loading branch information
ChaoticMind committed Apr 9, 2015
1 parent f3e3239 commit 175d058
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 7 deletions.
24 changes: 21 additions & 3 deletions lib/minimap-element.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -450,9 +450,14 @@ class MinimapElement extends HTMLElement
# {MinimapElement} canvas.
#
# event - The {Event} object.
mousePressedOverCanvas: ({which, pageY, target}) ->
return if which isnt 1

mousePressedOverCanvas: (e) ->
if e.which is 1
@leftMousePressedOverCanvas(e)
else if e.which is 2
@middleMousePressedOverCanvas(e)
else return

leftMousePressedOverCanvas: ({pageY, target}) ->
y = pageY - target.getBoundingClientRect().top
row = Math.floor(y / @minimap.getLineHeight()) + @minimap.getFirstVisibleScreenRow()

Expand All @@ -469,6 +474,16 @@ class MinimapElement extends HTMLElement
else
textEditor.setScrollTop(scrollTop)

middleMousePressedOverCanvas: ({pageY}) ->
{top: offsetTop} = @getBoundingClientRect()
y = pageY - offsetTop - @minimap.getTextEditorScaledHeight()/2

ratio = y /
(@minimap.getVisibleHeight() - @minimap.getTextEditorScaledHeight())

@minimap.textEditor.setScrollTop(
ratio * @minimap.getTextEditorMaxScrollTop())

# Internal: A method that relays the `mousewheel` events received by
# the {MinimapElement} to the {TextEditorElement}.
#
Expand All @@ -491,6 +506,9 @@ class MinimapElement extends HTMLElement
#
# event - The {Event} object.
startDrag: ({which, pageY}) ->
if which is 2
@mousePressedOverCanvas({which, pageY})

return if which isnt 1
{top} = @visibleArea.getBoundingClientRect()
{top: offsetTop} = @getBoundingClientRect()
Expand Down
8 changes: 4 additions & 4 deletions spec/helpers/events.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ mouseEvent = (type, properties) ->
shiftKey: false
metaKey: false
button: 0
relatedTarget: `undefined`
which: 1
relatedTarget: undefined
}

properties[k] = v for k,v of defaults when not properties[k]?
Expand All @@ -29,14 +28,15 @@ objectCenterCoordinates = (obj) ->
module.exports = {objectCenterCoordinates, mouseEvent}

['mousedown', 'mousemove', 'mouseup', 'click'].forEach (key) ->
module.exports[key] = (obj, {x, y, cx, cy, which}={}) ->
module.exports[key] = (obj, {x, y, cx, cy, btn} = {}) ->
{x,y} = objectCenterCoordinates(obj) unless x? and y?

unless cx? and cy?
cx = x
cy = y

obj.dispatchEvent(mouseEvent key, {pageX: x, pageY: y, clientX: cx, clientY: cy, which})
obj.dispatchEvent(mouseEvent key, {
pageX: x, pageY: y, clientX: cx, clientY: cy, button: btn})

module.exports.mousewheel = (obj, deltaX=0, deltaY=0) ->
obj.dispatchEvent(mouseEvent 'mousewheel', {deltaX, deltaY})
46 changes: 46 additions & 0 deletions spec/minimap-element-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,52 @@ describe 'MinimapElement', ->
it 'relays the events to the editor view', ->
expect(editorElement.component.presenter.setScrollTop).toHaveBeenCalled()

describe 'middle clicking the minimap', ->
[canvas, visibleArea, originalTop, originalLeft, maxScroll] = []

beforeEach ->
canvas = minimapElement.canvas
visibleArea = minimapElement.visibleArea
{top, left} = visibleArea.getBoundingClientRect()
[originalTop, originalLeft] = [top, left]
maxScroll = minimap.getTextEditorMaxScrollTop()

it 'scrolls to the top using the middle mouse button', ->
mousedown(canvas, x: originalLeft + 1, y: 0, btn: 1)
expect(editor.getScrollTop()).toEqual(0)

describe 'scrolling to the middle using the middle mouse button', ->
canvasMidY = undefined

beforeEach ->
editorMidY = editor.getHeight() / 2.0
{top, height} = canvas.getBoundingClientRect()
canvasMidY = top + (height / 2.0)
actualMidY = Math.min(canvasMidY, editorMidY)
mousedown(canvas, x: originalLeft + 1, y: actualMidY, btn: 1)

it 'scrolls the editor to the middle', ->
middleScrollTop = Math.round((maxScroll) / 2.0)
expect(editor.getScrollTop()).toEqual(middleScrollTop)

it 'updates the visible area to be centered', ->
nextAnimationFrame()
{top, height} = visibleArea.getBoundingClientRect()
visibleCenterY = top + (height / 2)
expect(visibleCenterY).toBeCloseTo(canvasMidY, 0)

it 'scrolls the editor to an arbitrary location', ->
scrollTo = 100 # pixels
scrollRatio = (scrollTo - minimap.getTextEditorScaledHeight()/2) /
(minimap.getVisibleHeight() - minimap.getTextEditorScaledHeight())
scrollRatio = Math.max(0, scrollRatio)
scrollRatio = Math.min(1, scrollRatio)

mousedown(canvas, x: originalLeft + 1, y: scrollTo, btn: 1)

expectedScroll = maxScroll * scrollRatio
expect(editor.getScrollTop()).toBeCloseTo(expectedScroll, 0)

describe 'pressing the mouse on the minimap canvas (without scroll animation)', ->
beforeEach ->
t = 0
Expand Down

0 comments on commit 175d058

Please sign in to comment.