pulsar/src/pane-container-view.coffee

149 lines
4.2 KiB
CoffeeScript
Raw Normal View History

Delegator = require 'delegato'
2013-10-16 04:52:20 +04:00
{$, View} = require './space-pen-extensions'
2014-01-14 00:29:00 +04:00
PaneView = require './pane-view'
PaneContainer = require './pane-container'
2014-02-06 22:02:53 +04:00
# Manages the list of panes within a {WorkspaceView}
module.exports =
class PaneContainerView extends View
Delegator.includeInto(this)
@delegatesMethod 'saveAll', toProperty: 'model'
@content: ->
@div class: 'panes'
initialize: (params) ->
if params instanceof PaneContainer
@model = params
else
@model = new PaneContainer({root: params?.root?.model})
@subscribe @model.$root, @onRootChanged
@subscribe @model.$activePaneItem.changes, @onActivePaneItemChanged
viewForModel: (model) ->
if model?
viewClass = model.getViewClass()
model._view ?= new viewClass(model)
getRoot: ->
@children().first().view()
onRootChanged: (root) =>
focusedElement = document.activeElement if @hasFocus()
oldRoot = @getRoot()
2014-01-14 00:29:00 +04:00
if oldRoot instanceof PaneView and oldRoot.model.isDestroyed()
@trigger 'pane:removed', [oldRoot]
oldRoot?.detach()
if root?
view = @viewForModel(root)
@append(view)
focusedElement?.focus()
else
atom.workspaceView?.focus() if focusedElement?
onActivePaneItemChanged: (activeItem) =>
@trigger 'pane-container:active-pane-item-changed', [activeItem]
removeChild: (child) ->
throw new Error("Removing non-existant child") unless @getRoot() is child
@setRoot(null)
2014-01-14 00:29:00 +04:00
@trigger 'pane:removed', [child] if child instanceof PaneView
confirmClose: ->
saved = true
for pane in @getPaneViews()
2013-10-30 02:55:01 +04:00
for item in pane.getItems()
if not pane.promptToSaveItem(item)
saved = false
break
saved
getPaneViews: ->
@find('.pane').views()
indexOfPane: (pane) ->
@getPaneViews().indexOf(pane.view())
paneAtIndex: (index) ->
@getPaneViews()[index]
eachPaneView: (callback) ->
callback(pane) for pane in @getPaneViews()
paneAttached = (e) -> callback($(e.target).view())
@on 'pane:attached', paneAttached
off: => @off 'pane:attached', paneAttached
getFocusedPane: ->
@find('.pane:has(:focus)').view()
getActivePane: ->
@viewForModel(@model.activePane)
getActivePaneItem: ->
@model.activePaneItem
getActiveView: ->
@getActivePane()?.activeView
2013-10-30 05:39:44 +04:00
paneForUri: (uri) ->
2014-01-14 02:47:31 +04:00
@viewForModel(@model.paneForUri(uri))
2013-10-30 05:39:44 +04:00
focusNextPaneView: ->
@model.activateNextPane()
focusPreviousPaneView: ->
@model.activatePreviousPane()
focusPaneViewAbove: ->
2014-01-30 00:08:34 +04:00
@nearestPaneInDirection('above')?.focus()
focusPaneViewBelow: ->
2014-01-30 00:08:34 +04:00
@nearestPaneInDirection('below')?.focus()
focusPaneViewOnLeft: ->
2014-01-30 00:08:34 +04:00
@nearestPaneInDirection('left')?.focus()
focusPaneViewOnRight: ->
2014-01-30 00:08:34 +04:00
@nearestPaneInDirection('right')?.focus()
nearestPaneInDirection: (direction) ->
distance = (pointA, pointB) ->
2014-01-30 00:10:15 +04:00
x = pointB.x - pointA.x
y = pointB.y - pointA.y
2014-01-30 00:14:30 +04:00
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))
2014-01-30 00:10:15 +04:00
2014-01-30 00:08:34 +04:00
pane = @getActivePane()
box = @boundingBoxForPane(pane)
panes = @getPaneViews()
2014-01-30 00:08:34 +04:00
.filter (otherPane) =>
otherBox = @boundingBoxForPane(otherPane)
switch direction
when 'left' then otherBox.right.x <= box.left.x
when 'right' then otherBox.left.x >= box.right.x
when 'above' then otherBox.bottom.y <= box.top.y
when 'below' then otherBox.top.y >= box.bottom.y
.sort (paneA, paneB) =>
boxA = @boundingBoxForPane(paneA)
boxB = @boundingBoxForPane(paneB)
switch direction
2014-01-30 01:10:07 +04:00
when 'left' then distance(box.left, boxA.right) - distance(box.left, boxB.right)
when 'right' then distance(box.right, boxA.left) - distance(box.right, boxB.left)
when 'above' then distance(box.top, boxA.bottom) - distance(box.top, boxB.bottom)
when 'below' then distance(box.bottom, boxA.top) - distance(box.bottom, boxB.top)
2014-01-30 00:08:34 +04:00
panes[0]
boundingBoxForPane: (pane) ->
boundingBox = pane[0].getBoundingClientRect()
left: {x: boundingBox.left, y: boundingBox.top}
right: {x: boundingBox.right, y: boundingBox.top}
top: {x: boundingBox.left, y: boundingBox.top}
bottom: {x: boundingBox.left, y: boundingBox.bottom}
getPanes: ->
@getPaneViews()