diff --git a/package.json b/package.json index 53078da1a..d6118f789 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "coffee-script": "1.7.0", "coffeestack": "0.7.0", "delegato": "^1", - "emissary": "^1.2.2", + "emissary": "^1.3.0", "event-kit": "0.0.0", "first-mate": "^2.0.5", "fs-plus": "^2.2.6", diff --git a/src/pane-axis-view.coffee b/src/pane-axis-view.coffee index 3039600c0..0018ee6b1 100644 --- a/src/pane-axis-view.coffee +++ b/src/pane-axis-view.coffee @@ -1,11 +1,17 @@ +{CompositeDisposable} = require 'event-kit' {View} = require './space-pen-extensions' PaneView = null module.exports = class PaneAxisView extends View initialize: (@model) -> - @onChildAdded(child) for child in @model.children - @subscribe @model.children, 'changed', @onChildrenChanged + @subscriptions = new CompositeDisposable + + @onChildAdded({child, index}) for child, index in @model.getChildren() + + @subscriptions.add @model.onDidAddChild(@onChildAdded) + @subscriptions.add @model.onDidRemoveChild(@onChildRemoved) + @subscriptions.add @model.onDidReplaceChild(@onChildReplaced) afterAttach: -> @container = @closest('.panes').view() @@ -14,19 +20,22 @@ class PaneAxisView extends View viewClass = model.getViewClass() model._view ?= new viewClass(model) - onChildrenChanged: ({index, removedValues, insertedValues}) => + onChildReplaced: ({index, oldChild, newChild}) => focusedElement = document.activeElement if @hasFocus() - @onChildRemoved(child, index) for child in removedValues - @onChildAdded(child, index + i) for child, i in insertedValues + @onChildRemoved({child: oldChild, index}) + @onChildAdded({child: newChild, index}) focusedElement?.focus() if document.activeElement is document.body - onChildAdded: (child, index) => + onChildAdded: ({child, index}) => view = @viewForModel(child) @insertAt(index, view) - onChildRemoved: (child) => + onChildRemoved: ({child}) => view = @viewForModel(child) view.detach() PaneView ?= require './pane-view' if view instanceof PaneView and view.model.isDestroyed() @container?.trigger 'pane:removed', [view] + + beforeRemove: -> + @subscriptions.dispose() diff --git a/src/pane-axis.coffee b/src/pane-axis.coffee index 12b335519..ffef40275 100644 --- a/src/pane-axis.coffee +++ b/src/pane-axis.coffee @@ -1,4 +1,5 @@ {Model} = require 'theorist' +{Emitter} = require 'event-kit' {flatten} = require 'underscore-plus' Serializable = require 'serializable' @@ -11,6 +12,7 @@ class PaneAxis extends Model Serializable.includeInto(this) constructor: ({@container, @orientation, children}) -> + @emitter = new Emitter @children = [] if children? @addChild(child) for child in children @@ -30,45 +32,53 @@ class PaneAxis extends Model else PaneRowView ?= require './pane-row-view' + getChildren: -> @children.slice() + getPanes: -> flatten(@children.map (child) -> child.getPanes()) - addChild: (child, index=@children.length) -> - @children.splice(index, 0, child) - @childAdded(child) + onDidAddChild: (fn) -> + @emitter.on 'did-add-child', fn - removeChild: (child) -> + onDidRemoveChild: (fn) -> + @emitter.on 'did-remove-child', fn + + onDidReplaceChild: (fn) -> + @emitter.on 'did-replace-child', fn + + addChild: (child, index=@children.length) -> + child.parent = this + child.container = @container + @subscribe child, 'destroyed', => @removeChild(child) + @children.splice(index, 0, child) + @emitter.emit 'did-add-child', {child, index} + + removeChild: (child, replacing=false) -> index = @children.indexOf(child) throw new Error("Removing non-existent child") if index is -1 + @unsubscribe child @children.splice(index, 1) - @childRemoved(child) - @reparentLastChild() if @children.length < 2 + @emitter.emit 'did-remove-child', {child, index} + @reparentLastChild() if not replacing and @children.length < 2 replaceChild: (oldChild, newChild) -> + @unsubscribe oldChild + newChild.parent = this + newChild.container = @container + @subscribe newChild, 'destroyed', => @removeChild(newChild) + index = @children.indexOf(oldChild) - throw new Error("Replacing non-existent child") if index is -1 @children.splice(index, 1, newChild) - @childRemoved(oldChild) - @childAdded(newChild) + @emitter.emit 'did-replace-child', {oldChild, newChild, index} insertChildBefore: (currentChild, newChild) -> index = @children.indexOf(currentChild) - @children.splice(index, 0, newChild) - @childAdded(newChild) + @addChild(newChild, index) insertChildAfter: (currentChild, newChild) -> index = @children.indexOf(currentChild) - @children.splice(index + 1, 0, newChild) - @childAdded(newChild) + @addChild(newChild, index + 1) reparentLastChild: -> @parent.replaceChild(this, @children[0]) @destroy() - - childAdded: (child) -> - child.parent = this - child.container = @container - @subscribe child, 'destroyed', => @removeChild(child) - - childRemoved: (child) -> - @unsubscribe child