From 734a79b7ec9f449669e1871871fd0289397f9b60 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 14 Oct 2014 17:45:13 -0700 Subject: [PATCH] Add initial panel API. It can only add things to the left right now. --- spec/workspace-spec.coffee | 12 +++++++++++ spec/workspace-view-spec.coffee | 37 +++++++++++++++++++++++++++++++++ src/panel-element.coffee | 17 +++++++++++++++ src/panel.coffee | 26 +++++++++++++++++++++++ src/workspace-element.coffee | 9 ++++++++ src/workspace.coffee | 18 ++++++++++++++++ 6 files changed, 119 insertions(+) create mode 100644 src/panel-element.coffee create mode 100644 src/panel.coffee diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 5230fe966..b3a8bac1a 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -456,3 +456,15 @@ describe "Workspace", -> expect(item2.isModified()).toBe false expect(atom.setDocumentEdited).toHaveBeenCalledWith(false) + + describe "adding panels", -> + class TestPanel + constructior: -> + + describe '::addLeftPanel(model)', -> + it 'emits an onDidAddPanel event and returns a panel', -> + atom.workspace.onDidAddPanel addPanelSpy = jasmine.createSpy() + panel = atom.workspace.addLeftPanel(item: new TestPanel()) + + expect(panel).toBeDefined() + expect(addPanelSpy).toHaveBeenCalledWith(panel) diff --git a/spec/workspace-view-spec.coffee b/spec/workspace-view-spec.coffee index fd8750910..8b648d3b4 100644 --- a/spec/workspace-view-spec.coffee +++ b/spec/workspace-view-spec.coffee @@ -270,3 +270,40 @@ describe "WorkspaceView", -> atom.config.set('editor.lineHeight', '30px') expect(getComputedStyle(editorNode).lineHeight).toBe atom.config.get('editor.lineHeight') expect(editor.getLineHeightInPixels()).not.toBe initialLineHeight + + describe 'adding panels', -> + workspaceElement = null + class TestPanel + constructior: -> + + class TestPanelElement extends HTMLElement + createdCallback: -> + @classList.add('test-root') + setModel: (@model) -> + TestPanelElement = document.registerElement 'atom-test-element', prototype: TestPanelElement.prototype + + beforeEach -> + workspaceElement = atom.workspace.getView(atom.workspace) + atom.workspace.addViewProvider + modelConstructor: TestPanel + viewConstructor: TestPanelElement + + describe 'Workspace::addLeftPanel(panel)', -> + it 'adds an atom-panel and removes it when Panel::destroy() is called', -> + panelNode = workspaceElement.querySelector('atom-panel') + expect(panelNode).toBe null + + panel = atom.workspace.addLeftPanel(item: new TestPanel()) + + panelNode = workspaceElement.querySelector('atom-panel') + expect(panelNode instanceof HTMLElement).toBe true + expect(panelNode.childNodes[0]).toHaveClass 'test-root' + + panel.destroy() + panelNode = workspaceElement.querySelector('atom-panel') + expect(panelNode).toBe null + + it 'adds the panel before the vertical axis', -> + panel = atom.workspace.addLeftPanel(item: new TestPanel()) + panelNode = workspaceElement.querySelector('atom-panel') + expect(panelNode.nextSibling).toBe workspaceElement.verticalAxis diff --git a/src/panel-element.coffee b/src/panel-element.coffee new file mode 100644 index 000000000..bf5f086ea --- /dev/null +++ b/src/panel-element.coffee @@ -0,0 +1,17 @@ +{CompositeDisposable} = require 'event-kit' + +class PanelElement extends HTMLElement + createdCallback: -> + @subscriptions = new CompositeDisposable + + getModel: -> @model + + setModel: (@model) -> + @appendChild(@model.getView()) + @subscriptions.add @model.onDidDestroy(@destroyed.bind(this)) + + destroyed: -> + @subscriptions.dispose() + @parentNode?.removeChild(this) + +module.exports = PanelElement = document.registerElement 'atom-panel', prototype: PanelElement.prototype diff --git a/src/panel.coffee b/src/panel.coffee new file mode 100644 index 000000000..01fb16b6b --- /dev/null +++ b/src/panel.coffee @@ -0,0 +1,26 @@ +{Emitter} = require 'event-kit' + +# Public: +module.exports = +class Panel + constructor: ({@viewRegistry, @item, @orientation}) -> + @emitter = new Emitter + + destroy: -> + @emitter.emit 'did-destroy', this + + getView: -> @viewRegistry.getView(@item) + + getOrientation: -> @orientation + + ### + Section: Event Subscription + ### + + # Public: Invoke the given callback when the pane is destroyed. + # + # * `callback` {Function} to be called when the pane is destroyed. + # + # Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. + onDidDestroy: (callback) -> + @emitter.on 'did-destroy', callback diff --git a/src/workspace-element.coffee b/src/workspace-element.coffee index 686674cde..d9219b664 100644 --- a/src/workspace-element.coffee +++ b/src/workspace-element.coffee @@ -65,6 +65,8 @@ class WorkspaceElement extends HTMLElement window.addEventListener 'focus', handleWindowFocus @subscriptions.add(new Disposable -> window.removeEventListener 'focus', handleWindowFocus) + @subscriptions.add @model.onDidAddPanel(@panelAdded.bind(this)) + @__spacePenView.setModel(@model) setTextEditorFontSize: (fontSize) -> @@ -90,6 +92,13 @@ class WorkspaceElement extends HTMLElement focusPaneViewOnRight: -> @paneContainer.focusPaneViewOnRight() + panelAdded: (panel) -> + panelView = @model.getView(panel) + + switch panel.getOrientation() + when 'left' + @horizontalAxis.insertBefore(panelView, @verticalAxis) + atom.commands.add 'atom-workspace', 'window:increase-font-size': -> @getModel().increaseFontSize() 'window:decrease-font-size': -> @getModel().decreaseFontSize() diff --git a/src/workspace.coffee b/src/workspace.coffee index 7c072ff77..73d07868f 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -10,6 +10,8 @@ Grim = require 'grim' TextEditor = require './text-editor' PaneContainer = require './pane-container' Pane = require './pane' +Panel = require './panel' +PanelElement = require './panel-element' ViewRegistry = require './view-registry' WorkspaceElement = require './workspace-element' @@ -62,6 +64,10 @@ class Workspace extends Model modelConstructor: Workspace viewConstructor: WorkspaceElement + @addViewProvider + modelConstructor: Panel + viewConstructor: PanelElement + # Called by the Serializable mixin during deserialization deserializeParams: (params) -> for packageName in params.packagesWithActiveGrammars ? [] @@ -277,6 +283,9 @@ class Workspace extends Model @onDidAddPaneItem ({item, pane, index}) -> callback({textEditor: item, pane, index}) if item instanceof TextEditor + onDidAddPanel: (callback) -> + @emitter.on 'did-add-panel', callback + eachEditor: (callback) -> deprecate("Use Workspace::observeTextEditors instead") @@ -659,3 +668,12 @@ class Workspace extends Model # added provider. addViewProvider: (providerSpec) -> @viewRegistry.addViewProvider(providerSpec) + + ### + Section: Panels + ### + + addLeftPanel: (options) -> + panel = new Panel(_.extend(options, {@viewRegistry, orientation: 'left'})) + @emitter.emit('did-add-panel', panel) + panel