mirror of
https://github.com/atom/atom.git
synced 2026-02-19 02:44:29 -05:00
30
src/panel-container-element.coffee
Normal file
30
src/panel-container-element.coffee
Normal file
@@ -0,0 +1,30 @@
|
||||
{CompositeDisposable} = require 'event-kit'
|
||||
|
||||
class PanelContainerElement extends HTMLElement
|
||||
createdCallback: ->
|
||||
@subscriptions = new CompositeDisposable
|
||||
|
||||
getModel: -> @model
|
||||
|
||||
setModel: (@model) ->
|
||||
@subscriptions.add @model.onDidAddPanel(@panelAdded.bind(this))
|
||||
@subscriptions.add @model.onDidRemovePanel(@panelRemoved.bind(this))
|
||||
@subscriptions.add @model.onDidDestroy(@destroyed.bind(this))
|
||||
|
||||
@setAttribute('location', @model.getLocation())
|
||||
|
||||
panelAdded: ({panel, index}) ->
|
||||
if index >= @childNodes.length
|
||||
@appendChild(panel.getView())
|
||||
else
|
||||
referenceItem = @childNodes[index + 1]
|
||||
@insertBefore(panel.getView(), referenceItem)
|
||||
|
||||
panelRemoved: ({panel, index}) ->
|
||||
@removeChild(@childNodes[index])
|
||||
|
||||
destroyed: ->
|
||||
@subscriptions.dispose()
|
||||
@parentNode?.removeChild(this)
|
||||
|
||||
module.exports = PanelContainerElement = document.registerElement 'atom-panel-container', prototype: PanelContainerElement.prototype
|
||||
66
src/panel-container.coffee
Normal file
66
src/panel-container.coffee
Normal file
@@ -0,0 +1,66 @@
|
||||
{Emitter, CompositeDisposable} = require 'event-kit'
|
||||
|
||||
module.exports =
|
||||
class PanelContainer
|
||||
constructor: ({@viewRegistry, @location}) ->
|
||||
@emitter = new Emitter
|
||||
@subscriptions = new CompositeDisposable
|
||||
@panels = []
|
||||
|
||||
destroy: ->
|
||||
pane.destroy() for pane in @getPanels()
|
||||
@subscriptions.dispose()
|
||||
@emitter.emit 'did-destroy', this
|
||||
@emitter.dispose()
|
||||
|
||||
###
|
||||
Section: Event Subscription
|
||||
###
|
||||
|
||||
onDidAddPanel: (callback) ->
|
||||
@emitter.on 'did-add-panel', callback
|
||||
|
||||
onDidRemovePanel: (callback) ->
|
||||
@emitter.on 'did-remove-panel', callback
|
||||
|
||||
onDidDestroy: (callback) ->
|
||||
@emitter.on 'did-destroy', callback
|
||||
|
||||
###
|
||||
Section: Panels
|
||||
###
|
||||
|
||||
getView: -> @viewRegistry.getView(this)
|
||||
|
||||
getLocation: -> @location
|
||||
|
||||
getPanels: -> @panels
|
||||
|
||||
addPanel: (panel) ->
|
||||
@subscriptions.add panel.onDidDestroy(@panelDestoryed.bind(this))
|
||||
|
||||
index = @getPanelIndex(panel)
|
||||
if index is @panels.length
|
||||
@panels.push(panel)
|
||||
else
|
||||
@panels.splice(index, 0, panel)
|
||||
|
||||
@emitter.emit 'did-add-panel', {panel, index}
|
||||
panel
|
||||
|
||||
panelDestoryed: (panel) ->
|
||||
index = @panels.indexOf(panel)
|
||||
if index > -1
|
||||
@panels.splice(index, 1)
|
||||
@emitter.emit 'did-remove-panel', {panel, index}
|
||||
|
||||
getPanelIndex: (panel) ->
|
||||
priority = panel.getPriority()
|
||||
if @location in ['bottom', 'right']
|
||||
for p, i in @panels by -1
|
||||
return i + 1 if priority < p.getPriority()
|
||||
0
|
||||
else
|
||||
for p, i in @panels
|
||||
return i if priority < p.getPriority()
|
||||
@panels.length
|
||||
31
src/panel-element.coffee
Normal file
31
src/panel-element.coffee
Normal file
@@ -0,0 +1,31 @@
|
||||
{CompositeDisposable} = require 'event-kit'
|
||||
{callAttachHooks} = require './space-pen-extensions'
|
||||
|
||||
class PanelElement extends HTMLElement
|
||||
createdCallback: ->
|
||||
@subscriptions = new CompositeDisposable
|
||||
|
||||
getModel: -> @model
|
||||
|
||||
setModel: (@model) ->
|
||||
view = @model.getItemView()
|
||||
@appendChild(view)
|
||||
callAttachHooks(view) # for backward compatibility with SpacePen views
|
||||
|
||||
@subscriptions.add @model.onDidChangeVisible(@visibleChanged.bind(this))
|
||||
@subscriptions.add @model.onDidDestroy(@destroyed.bind(this))
|
||||
|
||||
attachedCallback: ->
|
||||
@visibleChanged(@model.isVisible())
|
||||
|
||||
visibleChanged: (visible) ->
|
||||
if visible
|
||||
@style.display = null
|
||||
else
|
||||
@style.display = 'none'
|
||||
|
||||
destroyed: ->
|
||||
@subscriptions.dispose()
|
||||
@parentNode?.removeChild(this)
|
||||
|
||||
module.exports = PanelElement = document.registerElement 'atom-panel', prototype: PanelElement.prototype
|
||||
78
src/panel.coffee
Normal file
78
src/panel.coffee
Normal file
@@ -0,0 +1,78 @@
|
||||
{Emitter} = require 'event-kit'
|
||||
|
||||
# Extended: A container representing a panel on the edges of the editor window.
|
||||
# You should not create a `Panel` directly, instead use {Workspace::addTopPanel}
|
||||
# and friends to add panels.
|
||||
#
|
||||
# Examples: [tree-view](https://github.com/atom/tree-view),
|
||||
# [status-bar](https://github.com/atom/status-bar),
|
||||
# and [find-and-replace](https://github.com/atom/find-and-replace) all use
|
||||
# panels.
|
||||
module.exports =
|
||||
class Panel
|
||||
###
|
||||
Section: Construction and Destruction
|
||||
###
|
||||
|
||||
constructor: ({@viewRegistry, @item, @visible, @priority}) ->
|
||||
@emitter = new Emitter
|
||||
@visible ?= true
|
||||
@priority ?= 100
|
||||
|
||||
# Public: Destroy and remove this panel from the UI.
|
||||
destroy: ->
|
||||
@emitter.emit 'did-destroy', this
|
||||
|
||||
###
|
||||
Section: Event Subscription
|
||||
###
|
||||
|
||||
# Public: Invoke the given callback when the pane hidden or shown.
|
||||
#
|
||||
# * `callback` {Function} to be called when the pane is destroyed.
|
||||
# * `visible` {Boolean} true when the panel has been shown
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
|
||||
onDidChangeVisible: (callback) ->
|
||||
@emitter.on 'did-change-visible', callback
|
||||
|
||||
# Public: Invoke the given callback when the pane is destroyed.
|
||||
#
|
||||
# * `callback` {Function} to be called when the pane is destroyed.
|
||||
# * `panel` {Panel} this panel
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
|
||||
onDidDestroy: (callback) ->
|
||||
@emitter.on 'did-destroy', callback
|
||||
|
||||
###
|
||||
Section: Panel Details
|
||||
###
|
||||
|
||||
# Public: Gets this panel model's view DOM node.
|
||||
#
|
||||
# Returns an `<atom-panel>` {Element}
|
||||
getView: -> @viewRegistry.getView(this)
|
||||
|
||||
# Public: Gets your panel contents view.
|
||||
#
|
||||
# Returns an {Element} or jQuery element, depeneding on how you created the panel.
|
||||
getItemView: -> @viewRegistry.getView(@item)
|
||||
|
||||
# Public: Returns a {Number} indicating this panel's priority.
|
||||
getPriority: -> @priority
|
||||
|
||||
# Public: Returns a {Boolean} true when the panel is visible.
|
||||
isVisible: -> @visible
|
||||
|
||||
# Public: Hide this panel
|
||||
hide: ->
|
||||
wasVisible = @visible
|
||||
@visible = false
|
||||
@emitter.emit 'did-change-visible', @visible if wasVisible
|
||||
|
||||
# Public: Show this panel
|
||||
show: ->
|
||||
wasVisible = @visible
|
||||
@visible = true
|
||||
@emitter.emit 'did-change-visible', @visible unless wasVisible
|
||||
@@ -72,6 +72,18 @@ class WorkspaceElement extends HTMLElement
|
||||
window.addEventListener 'focus', handleWindowFocus
|
||||
@subscriptions.add(new Disposable -> window.removeEventListener 'focus', handleWindowFocus)
|
||||
|
||||
@panelContainers =
|
||||
top: @model.panelContainers.top.getView()
|
||||
left: @model.panelContainers.left.getView()
|
||||
right: @model.panelContainers.right.getView()
|
||||
bottom: @model.panelContainers.bottom.getView()
|
||||
|
||||
@horizontalAxis.insertBefore(@panelContainers.left, @verticalAxis)
|
||||
@horizontalAxis.appendChild(@panelContainers.right)
|
||||
|
||||
@verticalAxis.insertBefore(@panelContainers.top, @paneContainer)
|
||||
@verticalAxis.appendChild(@panelContainers.bottom)
|
||||
|
||||
@__spacePenView.setModel(@model)
|
||||
|
||||
setTextEditorFontSize: (fontSize) ->
|
||||
|
||||
@@ -141,59 +141,36 @@ class WorkspaceView extends View
|
||||
Section: Adding elements to the workspace
|
||||
###
|
||||
|
||||
# Essential: Prepend an element or view to the panels at the top of the
|
||||
# workspace.
|
||||
#
|
||||
# * `element` jQuery object or DOM element
|
||||
prependToTop: (element) ->
|
||||
deprecate 'Please use Workspace::addTopPanel() instead'
|
||||
@vertical.prepend(element)
|
||||
|
||||
# Essential: Append an element or view to the panels at the top of the workspace.
|
||||
#
|
||||
# * `element` jQuery object or DOM element
|
||||
appendToTop: (element) ->
|
||||
deprecate 'Please use Workspace::addTopPanel() instead'
|
||||
@panes.before(element)
|
||||
|
||||
# Essential: Prepend an element or view to the panels at the bottom of the
|
||||
# workspace.
|
||||
#
|
||||
# * `element` jQuery object or DOM element
|
||||
prependToBottom: (element) ->
|
||||
deprecate 'Please use Workspace::addBottomPanel() instead'
|
||||
@panes.after(element)
|
||||
|
||||
# Essential: Append an element or view to the panels at the bottom of the
|
||||
# workspace.
|
||||
#
|
||||
# * `element` jQuery object or DOM element
|
||||
appendToBottom: (element) ->
|
||||
deprecate 'Please use Workspace::addBottomPanel() instead'
|
||||
@vertical.append(element)
|
||||
|
||||
# Essential: Prepend an element or view to the panels at the left of the
|
||||
# workspace.
|
||||
#
|
||||
# * `element` jQuery object or DOM element
|
||||
prependToLeft: (element) ->
|
||||
deprecate 'Please use Workspace::addLeftPanel() instead'
|
||||
@horizontal.prepend(element)
|
||||
|
||||
# Essential: Append an element or view to the panels at the left of the
|
||||
# workspace.
|
||||
#
|
||||
# * `element` jQuery object or DOM element
|
||||
appendToLeft: (element) ->
|
||||
deprecate 'Please use Workspace::addLeftPanel() instead'
|
||||
@vertical.before(element)
|
||||
|
||||
# Essential: Prepend an element or view to the panels at the right of the
|
||||
# workspace.
|
||||
#
|
||||
# * `element` jQuery object or DOM element
|
||||
prependToRight: (element) ->
|
||||
deprecate 'Please use Workspace::addRightPanel() instead'
|
||||
@vertical.after(element)
|
||||
|
||||
# Essential: Append an element or view to the panels at the right of the
|
||||
# workspace.
|
||||
#
|
||||
# * `element` jQuery object or DOM element
|
||||
appendToRight: (element) ->
|
||||
deprecate 'Please use Workspace::addRightPanel() instead'
|
||||
@horizontal.append(element)
|
||||
|
||||
###
|
||||
|
||||
@@ -10,6 +10,10 @@ Grim = require 'grim'
|
||||
TextEditor = require './text-editor'
|
||||
PaneContainer = require './pane-container'
|
||||
Pane = require './pane'
|
||||
Panel = require './panel'
|
||||
PanelElement = require './panel-element'
|
||||
PanelContainer = require './panel-container'
|
||||
PanelContainerElement = require './panel-container-element'
|
||||
ViewRegistry = require './view-registry'
|
||||
WorkspaceElement = require './workspace-element'
|
||||
|
||||
@@ -45,6 +49,12 @@ class Workspace extends Model
|
||||
@paneContainer ?= new PaneContainer({@viewRegistry})
|
||||
@paneContainer.onDidDestroyPaneItem(@onPaneItemDestroyed)
|
||||
|
||||
@panelContainers =
|
||||
top: new PanelContainer({@viewRegistry, location: 'top'})
|
||||
left: new PanelContainer({@viewRegistry, location: 'left'})
|
||||
right: new PanelContainer({@viewRegistry, location: 'right'})
|
||||
bottom: new PanelContainer({@viewRegistry, location: 'bottom'})
|
||||
|
||||
@subscribeToActiveItem()
|
||||
|
||||
@addOpener (filePath) =>
|
||||
@@ -62,6 +72,14 @@ class Workspace extends Model
|
||||
modelConstructor: Workspace
|
||||
viewConstructor: WorkspaceElement
|
||||
|
||||
@addViewProvider
|
||||
modelConstructor: PanelContainer
|
||||
viewConstructor: PanelContainerElement
|
||||
|
||||
@addViewProvider
|
||||
modelConstructor: Panel
|
||||
viewConstructor: PanelElement
|
||||
|
||||
# Called by the Serializable mixin during deserialization
|
||||
deserializeParams: (params) ->
|
||||
for packageName in params.packagesWithActiveGrammars ? []
|
||||
@@ -578,6 +596,76 @@ class Workspace extends Model
|
||||
@paneContainer.destroy()
|
||||
@activeItemSubscriptions?.dispose()
|
||||
|
||||
|
||||
###
|
||||
Section: Panels
|
||||
###
|
||||
|
||||
# Essential: Adds a panel item to the bottom of the editor window.
|
||||
#
|
||||
# * `options` {Object}
|
||||
# * `item` Your panel content. It can be DOM element, a jQuery element, or
|
||||
# a model with a view registered via {::addViewProvider}. We recommend the
|
||||
# latter. See {::addViewProvider} for more information.
|
||||
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
|
||||
# (default: true)
|
||||
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
|
||||
# forced closer to the edges of the window. (default: 100)
|
||||
#
|
||||
# Returns a {Panel}
|
||||
addBottomPanel: (options) ->
|
||||
@addPanel('bottom', options)
|
||||
|
||||
# Essential: Adds a panel item to the left of the editor window.
|
||||
#
|
||||
# * `options` {Object}
|
||||
# * `item` Your panel content. It can be DOM element, a jQuery element, or
|
||||
# a model with a view registered via {::addViewProvider}. We recommend the
|
||||
# latter. See {::addViewProvider} for more information.
|
||||
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
|
||||
# (default: true)
|
||||
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
|
||||
# forced closer to the edges of the window. (default: 100)
|
||||
#
|
||||
# Returns a {Panel}
|
||||
addLeftPanel: (options) ->
|
||||
@addPanel('left', options)
|
||||
|
||||
# Essential: Adds a panel item to the right of the editor window.
|
||||
#
|
||||
# * `options` {Object}
|
||||
# * `item` Your panel content. It can be DOM element, a jQuery element, or
|
||||
# a model with a view registered via {::addViewProvider}. We recommend the
|
||||
# latter. See {::addViewProvider} for more information.
|
||||
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
|
||||
# (default: true)
|
||||
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
|
||||
# forced closer to the edges of the window. (default: 100)
|
||||
#
|
||||
# Returns a {Panel}
|
||||
addRightPanel: (options) ->
|
||||
@addPanel('right', options)
|
||||
|
||||
# Essential: Adds a panel item to the top of the editor window above the tabs.
|
||||
#
|
||||
# * `options` {Object}
|
||||
# * `item` Your panel content. It can be DOM element, a jQuery element, or
|
||||
# a model with a view registered via {::addViewProvider}. We recommend the
|
||||
# latter. See {::addViewProvider} for more information.
|
||||
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
|
||||
# (default: true)
|
||||
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
|
||||
# forced closer to the edges of the window. (default: 100)
|
||||
#
|
||||
# Returns a {Panel}
|
||||
addTopPanel: (options) ->
|
||||
@addPanel('top', options)
|
||||
|
||||
addPanel: (location, options) ->
|
||||
options ?= {}
|
||||
options.viewRegistry = @viewRegistry
|
||||
@panelContainers[location].addPanel(new Panel(options))
|
||||
|
||||
###
|
||||
Section: View Management
|
||||
###
|
||||
@@ -628,7 +716,7 @@ class Workspace extends Model
|
||||
# makes [HTML 5 custom elements](http://www.html5rocks.com/en/tutorials/webcomponents/customelements/)
|
||||
# an ideal tool for implementing views in Atom.
|
||||
#
|
||||
# ## Example
|
||||
# ## Examples
|
||||
#
|
||||
# Text editors are divided into a model and a view layer, so when you interact
|
||||
# with methods like `atom.workspace.getActiveTextEditor()` you're only going
|
||||
|
||||
Reference in New Issue
Block a user