Support splitting at the model layer

Splitting in the view will need to be removed and mapped to splits in
the model.
This commit is contained in:
Nathan Sobo
2014-01-08 14:55:22 -07:00
parent bb595ab08a
commit eb7f3ff5af
4 changed files with 126 additions and 3 deletions

View File

@@ -0,0 +1,79 @@
PaneModel = require '../src/pane-model'
PaneAxisModel = require '../src/pane-axis-model'
PaneContainerModel = require '../src/pane-container-model'
describe "PaneModel", ->
describe "split methods", ->
[pane1, container] = []
beforeEach ->
pane1 = new PaneModel(items: ["A"])
container = new PaneContainerModel(root: pane1)
describe "::splitLeft(params)", ->
describe "when the parent is the container root", ->
it "replaces itself with a row and inserts a new pane to the left of itself", ->
pane2 = pane1.splitLeft(items: ["B"])
pane3 = pane1.splitLeft(items: ["C"])
expect(container.root.orientation).toBe 'horizontal'
expect(container.root.children).toEqual [pane2, pane3, pane1]
describe "when the parent is a column", ->
it "replaces itself with a row and inserts a new pane to the left of itself", ->
pane1.splitDown()
pane2 = pane1.splitLeft(items: ["B"])
pane3 = pane1.splitLeft(items: ["C"])
row = container.root.children[0]
expect(row.orientation).toBe 'horizontal'
expect(row.children).toEqual [pane2, pane3, pane1]
describe "::splitRight(params)", ->
describe "when the parent is the container root", ->
it "replaces itself with a row and inserts a new pane to the right of itself", ->
pane2 = pane1.splitRight(items: ["B"])
pane3 = pane1.splitRight(items: ["C"])
expect(container.root.orientation).toBe 'horizontal'
expect(container.root.children).toEqual [pane1, pane3, pane2]
describe "when the parent is a column", ->
it "replaces itself with a row and inserts a new pane to the right of itself", ->
pane1.splitDown()
pane2 = pane1.splitRight(items: ["B"])
pane3 = pane1.splitRight(items: ["C"])
row = container.root.children[0]
expect(row.orientation).toBe 'horizontal'
expect(row.children).toEqual [pane1, pane3, pane2]
describe "::splitUp(params)", ->
describe "when the parent is the container root", ->
it "replaces itself with a column and inserts a new pane above itself", ->
pane2 = pane1.splitUp(items: ["B"])
pane3 = pane1.splitUp(items: ["C"])
expect(container.root.orientation).toBe 'vertical'
expect(container.root.children).toEqual [pane2, pane3, pane1]
describe "when the parent is a row", ->
it "replaces itself with a column and inserts a new pane above itself", ->
pane1.splitRight()
pane2 = pane1.splitUp(items: ["B"])
pane3 = pane1.splitUp(items: ["C"])
column = container.root.children[0]
expect(column.orientation).toBe 'vertical'
expect(column.children).toEqual [pane2, pane3, pane1]
describe "::splitDown(params)", ->
describe "when the parent is the container root", ->
it "replaces itself with a column and inserts a new pane below itself", ->
pane2 = pane1.splitDown(items: ["B"])
pane3 = pane1.splitDown(items: ["C"])
expect(container.root.orientation).toBe 'vertical'
expect(container.root.children).toEqual [pane1, pane3, pane2]
describe "when the parent is a row", ->
it "replaces itself with a column and inserts a new pane below itself", ->
pane1.splitRight()
pane2 = pane1.splitDown(items: ["B"])
pane3 = pane1.splitDown(items: ["C"])
column = container.root.children[0]
expect(column.orientation).toBe 'vertical'
expect(column.children).toEqual [pane1, pane3, pane2]

View File

@@ -2,15 +2,22 @@
module.exports =
class PaneAxisModel extends Model
constructor: (params) ->
@children = Sequence.fromArray(params?.children ? [])
constructor: ({@orientation, children}) ->
@children = Sequence.fromArray(children ? [])
@children.onEach (child) => child.parent = this
addChild: (child, index=@children.length) ->
@children.splice(index, 0, child)
removeChild: (child) ->
index = @children.indexOf(child)
@children.splice(index, 1) unless index is -1
throw new Error("Removing non-existent child") if index is -1
@children.splice(index, 1)
replaceChild: (oldChild, newChild) ->
index = @children.indexOf(oldChild)
throw new Error("Replacing non-existent child") if index is -1
@children.splice(index, 1, newChild)
insertChildBefore: (currentChild, newChild) ->
index = @children.indexOf(currentChild)

View File

@@ -0,0 +1,14 @@
{Model} = require 'theorist'
module.exports =
class PaneContainerModel extends Model
@properties
root: null
constructor: ->
super
@subscribe @$root, (root) => root?.parent = this
replaceChild: (oldChild, newChild) ->
throw new Error("Replacing non-existent child") if oldChild isnt @root
@root = newChild

View File

@@ -2,6 +2,7 @@
{dirname} = require 'path'
{Model} = require 'theorist'
Serializable = require 'serializable'
PaneAxisModel = require './pane-axis-model'
module.exports =
class PaneModel extends Model
@@ -189,3 +190,25 @@ class PaneModel extends Model
# Private:
copyActiveItem: ->
@activeItem.copy?() ? atom.deserializers.deserialize(@activeItem.serialize())
splitLeft: (params) ->
@split('horizontal', 'before', params)
splitRight: (params) ->
@split('horizontal', 'after', params)
splitUp: (params) ->
@split('vertical', 'before', params)
splitDown: (params) ->
@split('vertical', 'after', params)
split: (orientation, side, params) ->
if @parent.orientation isnt orientation
@parent.replaceChild(this, new PaneAxisModel({orientation, children: [this]}))
newPane = new @constructor(params)
switch side
when 'before' then @parent.insertChildBefore(this, newPane)
when 'after' then @parent.insertChildAfter(this, newPane)
newPane