Start adding event subscription methods to pane

This branch uses EventKit, an ultra-simple library for implementing
events. The object implementing the methods maintains its own emitter
object rather than doing a mixin like Emissary encourages. This will
make it easier for us to deprecate ::on on the object itself. Unlike
emissary, the EventKit Emitter implements a super minimalistic API that
only allows one value to be emitted and always returns a Disposable
from subscriptions.
This commit is contained in:
Nathan Sobo
2014-08-26 20:54:19 -06:00
parent ebb02bcd37
commit b8fcbe9451
3 changed files with 43 additions and 14 deletions

View File

@@ -27,6 +27,7 @@
"coffeestack": "0.7.0",
"delegato": "^1",
"emissary": "^1.2.2",
"event-kit": "0.0.0",
"first-mate": "^2.0.5",
"fs-plus": "^2.2.6",
"fstream": "0.1.24",
@@ -109,7 +110,6 @@
"welcome": "0.18.0",
"whitespace": "0.25.0",
"wrap-guide": "0.21.0",
"language-c": "0.28.0",
"language-coffee-script": "0.30.0",
"language-css": "0.17.0",

View File

@@ -36,7 +36,7 @@ describe "Pane", ->
pane.addItem(item3, 1)
expect(pane.getItems()).toEqual [item1, item3, item2]
it "adds the item after the active item ", ->
it "adds the item after the active item if no index is provided", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
[item1, item2, item3] = pane.getItems()
pane.activateItem(item2)
@@ -47,13 +47,17 @@ describe "Pane", ->
it "sets the active item after adding the first item", ->
pane = new Pane
item = new Item("A")
events = []
pane.on 'item-added', -> events.push('item-added')
pane.$activeItem.changes.onValue -> events.push('active-item-changed')
pane.addItem(item)
expect(pane.getActiveItem()).toBe item
expect(events).toEqual ['item-added', 'active-item-changed']
it "invokes ::onDidAddItem() observers", ->
pane = new Pane(items: [new Item("A"), new Item("B")])
events = []
pane.onDidAddItem (event) -> events.push(event)
item = new Item("C")
pane.addItem(item, 1)
expect(events).toEqual [{item, index: 1}]
describe "::activateItem(item)", ->
pane = null
@@ -72,6 +76,12 @@ describe "Pane", ->
expect(item in pane.getItems()).toBe true
expect(pane.getActiveItem()).toBe item
it "invokes ::onDidChangeActiveItem() observers", ->
observed = []
pane.onDidChangeActiveItem (item) -> observed.push(item)
pane.activateItem(pane.itemAtIndex(1))
expect(observed).toEqual [pane.itemAtIndex(1)]
describe "::activateNextItem() and ::activatePreviousItem()", ->
it "sets the active item to the next/previous item, looping around at either end", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
@@ -135,10 +145,11 @@ describe "Pane", ->
pane.destroyItem(item2)
expect(pane.getActiveItem()).toBe item1
it "emits 'item-removed' with the item, its index, and true indicating the item is being destroyed", ->
pane.on 'item-removed', itemRemovedHandler = jasmine.createSpy("itemRemovedHandler")
it "invokes ::onDidRemoveItem() observers", ->
events = []
pane.onDidRemoveItem (event) -> events.push(event)
pane.destroyItem(item2)
expect(itemRemovedHandler).toHaveBeenCalledWith(item2, 1, true)
expect(events).toEqual [{item: item2, index: 1, destroyed: true}]
describe "if the item is modified", ->
itemUri = null

View File

@@ -1,5 +1,6 @@
{find, compact, extend, last} = require 'underscore-plus'
{Model, Sequence} = require 'theorist'
{Emitter} = require 'event-kit'
Serializable = require 'serializable'
PaneAxis = require './pane-axis'
Editor = require './editor'
@@ -64,6 +65,8 @@ class Pane extends Model
constructor: (params) ->
super
@emitter = new Emitter
@items = Sequence.fromArray(compact(params?.items ? []))
@activeItem ?= @items[0]
@@ -91,6 +94,15 @@ class Pane extends Model
# Called by the view layer to construct a view for this model.
getViewClass: -> PaneView ?= require './pane-view'
onDidAddItem: (fn) ->
@emitter.on 'did-add-item', fn
onDidRemoveItem: (fn) ->
@emitter.on 'did-remove-item', fn
onDidChangeActiveItem: (fn) ->
@emitter.on 'did-change-active-item', fn
isActive: -> @active
# Called by the view layer to indicate that the pane has gained focus.
@@ -123,6 +135,10 @@ class Pane extends Model
getActiveItem: ->
@activeItem
setActiveItem: (@activeItem) ->
@emitter.emit 'did-change-active-item', @activeItem
@activeItem
# Public: Returns an {Editor} if the pane item is an {Editor}, or null
# otherwise.
getActiveEditor: ->
@@ -160,7 +176,7 @@ class Pane extends Model
activateItem: (item) ->
if item?
@addItem(item)
@activeItem = item
@setActiveItem(item)
# Public: Adds the item to the pane.
#
@@ -174,6 +190,7 @@ class Pane extends Model
@items.splice(index, 0, item)
@emit 'item-added', item, index
@emitter.emit 'did-add-item', {item, index}
@activeItem ?= item
item
@@ -191,7 +208,7 @@ class Pane extends Model
@addItem(item, index + i) for item, i in items
items
removeItem: (item, destroying) ->
removeItem: (item, destroyed) ->
index = @items.indexOf(item)
return if index is -1
if item is @activeItem
@@ -202,8 +219,9 @@ class Pane extends Model
else
@activatePreviousItem()
@items.splice(index, 1)
@emit 'item-removed', item, index, destroying
@container?.itemDestroyed(item) if destroying
@emit 'item-removed', item, index, destroyed
@emitter.emit 'did-remove-item', {item, index, destroyed}
@container?.itemDestroyed(item) if destroyed
@destroy() if @items.length is 0 and atom.config.get('core.destroyEmptyPanes')
# Public: Moves the given item to the specified index.