2014-01-14 21:53:16 +04:00
|
|
|
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'
|
2014-01-14 00:56:31 +04:00
|
|
|
PaneContainer = require './pane-container'
|
2013-02-21 09:28:43 +04:00
|
|
|
|
2014-02-06 22:02:53 +04:00
|
|
|
# Manages the list of panes within a {WorkspaceView}
|
2013-02-21 09:28:43 +04:00
|
|
|
module.exports =
|
2014-01-14 00:39:02 +04:00
|
|
|
class PaneContainerView extends View
|
2014-01-14 21:53:16 +04:00
|
|
|
Delegator.includeInto(this)
|
2014-01-09 05:49:50 +04:00
|
|
|
|
2014-01-14 22:12:08 +04:00
|
|
|
@delegatesMethod 'saveAll', toProperty: 'model'
|
|
|
|
|
2013-02-21 09:28:43 +04:00
|
|
|
@content: ->
|
2013-12-02 20:41:34 +04:00
|
|
|
@div class: 'panes'
|
2013-02-21 09:28:43 +04:00
|
|
|
|
2014-01-09 05:49:50 +04:00
|
|
|
initialize: (params) ->
|
2014-01-14 00:56:31 +04:00
|
|
|
if params instanceof PaneContainer
|
2014-01-09 05:49:50 +04:00
|
|
|
@model = params
|
|
|
|
else
|
2014-01-14 00:56:31 +04:00
|
|
|
@model = new PaneContainer({root: params?.root?.model})
|
2014-01-09 05:49:50 +04:00
|
|
|
|
2014-01-11 22:22:31 +04:00
|
|
|
@subscribe @model.$root, @onRootChanged
|
|
|
|
@subscribe @model.$activePaneItem.changes, @onActivePaneItemChanged
|
2013-06-21 02:57:34 +04:00
|
|
|
|
2014-01-09 05:49:50 +04:00
|
|
|
viewForModel: (model) ->
|
2014-01-11 00:44:02 +04:00
|
|
|
if model?
|
|
|
|
viewClass = model.getViewClass()
|
|
|
|
model._view ?= new viewClass(model)
|
2014-01-09 05:49:50 +04:00
|
|
|
|
2013-02-21 09:28:43 +04:00
|
|
|
getRoot: ->
|
|
|
|
@children().first().view()
|
|
|
|
|
2014-01-09 05:49:50 +04:00
|
|
|
onRootChanged: (root) =>
|
2014-01-11 04:25:30 +04:00
|
|
|
focusedElement = document.activeElement if @hasFocus()
|
|
|
|
|
2014-01-10 22:45:08 +04:00
|
|
|
oldRoot = @getRoot()
|
2014-01-14 00:29:00 +04:00
|
|
|
if oldRoot instanceof PaneView and oldRoot.model.isDestroyed()
|
2014-01-11 02:04:51 +04:00
|
|
|
@trigger 'pane:removed', [oldRoot]
|
2014-01-10 22:45:08 +04:00
|
|
|
oldRoot?.detach()
|
2013-08-27 00:35:39 +04:00
|
|
|
if root?
|
2014-01-09 05:49:50 +04:00
|
|
|
view = @viewForModel(root)
|
|
|
|
@append(view)
|
2014-01-11 04:25:30 +04:00
|
|
|
focusedElement?.focus()
|
2014-01-12 07:48:01 +04:00
|
|
|
else
|
|
|
|
atom.workspaceView?.focus() if focusedElement?
|
2013-06-21 02:57:34 +04:00
|
|
|
|
2014-01-10 05:58:01 +04:00
|
|
|
onActivePaneItemChanged: (activeItem) =>
|
|
|
|
@trigger 'pane-container:active-pane-item-changed', [activeItem]
|
|
|
|
|
2013-06-21 02:57:34 +04:00
|
|
|
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
|
2013-06-21 02:57:34 +04:00
|
|
|
|
2013-03-13 02:43:37 +04:00
|
|
|
confirmClose: ->
|
2013-06-27 12:21:14 +04:00
|
|
|
saved = true
|
2014-02-19 03:13:27 +04:00
|
|
|
for pane in @getPaneViews()
|
2013-10-30 02:55:01 +04:00
|
|
|
for item in pane.getItems()
|
2013-10-30 21:46:48 +04:00
|
|
|
if not pane.promptToSaveItem(item)
|
2013-06-27 14:39:29 +04:00
|
|
|
saved = false
|
|
|
|
break
|
2013-06-27 12:21:14 +04:00
|
|
|
saved
|
2013-03-13 02:43:37 +04:00
|
|
|
|
2014-02-19 03:13:27 +04:00
|
|
|
getPaneViews: ->
|
2013-02-26 22:41:41 +04:00
|
|
|
@find('.pane').views()
|
|
|
|
|
|
|
|
indexOfPane: (pane) ->
|
2014-02-19 03:13:27 +04:00
|
|
|
@getPaneViews().indexOf(pane.view())
|
2013-02-26 22:41:41 +04:00
|
|
|
|
|
|
|
paneAtIndex: (index) ->
|
2014-02-19 03:13:27 +04:00
|
|
|
@getPaneViews()[index]
|
2013-02-21 09:28:43 +04:00
|
|
|
|
2014-02-19 03:05:29 +04:00
|
|
|
eachPaneView: (callback) ->
|
2014-02-19 03:13:27 +04:00
|
|
|
callback(pane) for pane in @getPaneViews()
|
2013-02-26 02:27:09 +04:00
|
|
|
paneAttached = (e) -> callback($(e.target).view())
|
|
|
|
@on 'pane:attached', paneAttached
|
2013-11-21 07:07:56 +04:00
|
|
|
off: => @off 'pane:attached', paneAttached
|
2013-02-26 02:27:09 +04:00
|
|
|
|
2013-02-21 09:28:43 +04:00
|
|
|
getFocusedPane: ->
|
|
|
|
@find('.pane:has(:focus)').view()
|
|
|
|
|
2013-02-21 22:56:47 +04:00
|
|
|
getActivePane: ->
|
2014-01-11 00:44:02 +04:00
|
|
|
@viewForModel(@model.activePane)
|
2013-02-21 22:56:47 +04:00
|
|
|
|
2013-02-22 03:25:51 +04:00
|
|
|
getActivePaneItem: ->
|
2014-01-10 22:34:26 +04:00
|
|
|
@model.activePaneItem
|
2013-02-22 03:25:51 +04:00
|
|
|
|
|
|
|
getActiveView: ->
|
2013-02-28 01:15:38 +04:00
|
|
|
@getActivePane()?.activeView
|
2013-02-21 22:56:47 +04:00
|
|
|
|
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
|
|
|
|
2014-02-19 03:31:19 +04:00
|
|
|
focusNextPaneView: ->
|
2014-01-14 22:15:14 +04:00
|
|
|
@model.activateNextPane()
|
2014-01-11 04:25:30 +04:00
|
|
|
|
2014-02-19 03:31:19 +04:00
|
|
|
focusPreviousPaneView: ->
|
2014-01-14 22:15:14 +04:00
|
|
|
@model.activatePreviousPane()
|
2014-01-27 02:25:59 +04:00
|
|
|
|
2014-02-19 03:31:19 +04:00
|
|
|
focusPaneViewAbove: ->
|
2014-01-30 00:08:34 +04:00
|
|
|
@nearestPaneInDirection('above')?.focus()
|
2014-01-27 02:25:59 +04:00
|
|
|
|
2014-02-19 03:31:19 +04:00
|
|
|
focusPaneViewBelow: ->
|
2014-01-30 00:08:34 +04:00
|
|
|
@nearestPaneInDirection('below')?.focus()
|
2014-01-27 02:25:59 +04:00
|
|
|
|
2014-02-19 03:31:19 +04:00
|
|
|
focusPaneViewOnLeft: ->
|
2014-01-30 00:08:34 +04:00
|
|
|
@nearestPaneInDirection('left')?.focus()
|
2014-01-27 02:25:59 +04:00
|
|
|
|
2014-02-19 03:31:19 +04:00
|
|
|
focusPaneViewOnRight: ->
|
2014-01-30 00:08:34 +04:00
|
|
|
@nearestPaneInDirection('right')?.focus()
|
|
|
|
|
|
|
|
nearestPaneInDirection: (direction) ->
|
2014-01-30 01:20:54 +04:00
|
|
|
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)
|
2014-02-19 03:13:27 +04:00
|
|
|
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}
|
2014-02-19 03:13:27 +04:00
|
|
|
|
|
|
|
getPanes: ->
|
|
|
|
@getPaneViews()
|