project pane works. I call it Tree now though. Probably too generic, whatevs"

This commit is contained in:
Corey Johnson
2011-11-03 17:49:21 -07:00
parent 2a86e3bf61
commit a4ba4305dd
13 changed files with 130 additions and 221 deletions

View File

@@ -1 +0,0 @@
module.exports = Project = require 'project/project'

View File

@@ -1,45 +0,0 @@
_ = require 'underscore'
File = require 'fs'
Extension = require 'extension'
ProjectPane = require 'project/projectpane'
module.exports =
class Project extends Extension
keymap: ->
'Command-Ctrl-N': -> @pane.toggle()
storageNamespace: ->
@.constructor.name + @window.path
constructor: (args...) ->
super args...
@pane = new ProjectPane @window, @
@pane.toggle()
@window.on 'open', ({filename}) =>
if File.isDirectory filename
@pane.reload filename # I don't think this can ever happen.
else
openedPaths = @get 'openedPaths', []
if not _.include openedPaths, filename
openedPaths.push filename
@set 'openedPaths', openedPaths
@window.on 'close', ({filename}) =>
if File.isFile filename
openedPaths = @get 'openedPaths', []
openedPaths = _.without openedPaths, filename
@set 'openedPaths', openedPaths
load: ->
# Reopen files (remove ones that no longer exist)
openedPaths = @get 'openedPaths', []
for path in openedPaths
if File.isFile path
@window.open path
else if not File.exists path
openedPaths = _.without openedPaths, path
@set 'openedPaths', openedPaths

View File

@@ -1,71 +0,0 @@
$ = require 'jquery'
_ = require 'underscore'
File = require 'fs'
Pane = require 'pane'
module.exports =
class ProjectPane extends Pane
position: 'left'
project: null
html: $ require "project/project.html"
constructor: (@window, @project) ->
super @window
@reload()
$('#project li').live 'click', (event) =>
return true if event.__projectClicked__
$('#project .active').removeClass 'active'
el = $(event.currentTarget)
path = decodeURIComponent el.attr 'path'
if File.isDirectory path
openedPaths = @project.get 'openedPaths', []
if el.hasClass 'open'
openedPaths = _.without openedPaths, path
el.removeClass 'open'
el.children("ul").remove()
else
openedPaths.push path unless _.include openedPaths, path
el.addClass 'open'
list = @createList path
el.append list
@project.set 'openedPaths', openedPaths
else
el.addClass 'active'
@window.open path
# HACK I need the event to propogate beyond the project pane,
# but I need the project pane to ignore it. Need somehting
# cleaner here.
event.__projectClicked__ = true
true
reload: ->
@html.children('#project .cwd').text _.last @window.path.split '/'
fileList = @createList @window.path
fileList.addClass('files')
@html.children('#project .files').replaceWith(fileList)
createList: (root) ->
paths = File.list root
list = $('<ul>')
for path in paths
filename = path.replace(root, "").substring 1
type = if File.isDirectory path then 'dir' else 'file'
encodedPath = encodeURIComponent path
listItem = $("<li class='#{type}' path='#{encodedPath}'>#{filename}</li>")
openedPaths = @project.get 'openedPaths', []
if _.include(openedPaths, path) and type == 'dir'
listItem.append @createList path
listItem.addClass "open"
list.append listItem
list

View File

@@ -3,7 +3,7 @@ $ = require 'jquery'
Extension = require 'extension'
KeyBinder = require 'key-binder'
Event = require 'event'
TabsPane = require 'tabs/tabspane'
TabsPane = require 'tabs/tabs-pane'
fs = require 'fs'

View File

@@ -1,57 +0,0 @@
$ = require 'jquery'
_ = require 'underscore'
Pane = require 'pane'
module.exports =
class TabsPane extends Pane
position: 'top'
html: $ require 'tabs/tabs.html'
constructor: ->
# Style html
@html.parents('.pane').css height: 'inherit'
css = $('<style id="tabs-style"></style>').html require 'tabs/tabs.css'
$('head').append css
# click tab
tabPane = this
$('#tabs ul li').live 'mousedown', ->
tabPane.switchToTab this
false
nextTab: ->
@switchToTab $('#tabs ul .active').next()
prevTab: ->
@switchToTab $('#tabs ul .active').prev()
switchToTab: (tab) ->
tab = $("#tabs ul li").get(tab - 1) if _.isNumber tab
return if tab.length is 0
$("#tabs ul .active").removeClass("active")
$(tab).addClass 'active'
window.editor.focusBuffer $(tab).data 'path'
addTab: (path) ->
existing = $("#tabs [data-path='#{path}']")
if existing.length
return @switchToTab existing
name = if path then _.last path.split '/' else "untitled"
$("#tabs ul .active").removeClass()
$("#tabs ul").append """
<li data-path='#{path}'><a href='#'>#{name}</a></li>
"""
$("#tabs ul li:last").addClass 'active'
removeTab: (path) ->
tab = $("#tabs li[data-path='#{path}']")
if tab.hasClass("active")
nextTab = tab.next()
nextTab = tab.prev() if nextTab.length == 0
@switchToTab nextTab if nextTab.length != 0
tab.remove()

View File

Before

Width:  |  Height:  |  Size: 518 B

After

Width:  |  Height:  |  Size: 518 B

View File

@@ -0,0 +1 @@
module.exports = Tree = require 'tree/tree'

View File

@@ -0,0 +1,2 @@
tree:
'cmd-ctrl-n': (tree) -> tree.pane.toggle()

View File

@@ -0,0 +1,73 @@
$ = require 'jquery'
_ = require 'underscore'
fs = require 'fs'
Pane = require 'pane'
module.exports =
class TreePane extends Pane
position: 'left'
tree: null
html: $ require "tree/tree.html"
constructor: (@tree) ->
@reload()
$('#tree li').live 'click', (event) =>
return true if event.__treeClicked__
$('#tree .active').removeClass 'active'
el = $(event.currentTarget)
path = decodeURIComponent el.data 'path'
if fs.isDirectory path
window.x = @tree
openedDirs = @tree.getOpenedDirs()
if el.hasClass 'open'
openedDirs = _.without openedDirs, path
el.removeClass 'open'
el.children("ul").remove()
else
openedDirs.push path unless path in openedDirs
el.addClass 'open'
list = @createList path
el.append list
@tree.setOpenedDirs openedDirs
else
el.addClass 'active'
window.open path
# HACK I need the event to propogate beyond the tree pane,
# but I need the tree pane to ignore it. Need somehting
# cleaner here.
event.__treeClicked__ = true
true
reload: ->
@html.children('#tree .cwd').text _.last atomController.path.split '/'
fileList = @createList atomController.path
fileList.addClass 'files'
@html.children('#tree .files').replaceWith fileList
createList: (root) ->
paths = fs.list root
list = $('<ul>')
for path in paths
filename = path.replace(root, "").substring 1
type = if fs.isDirectory path then 'dir' else 'file'
encodedPath = encodeURIComponent path
listItem = $("<li class='#{type}' data-path='#{encodedPath}'>#{filename}</li>")
openedDirs = @tree.getOpenedDirs()
if path in openedDirs and fs.isDirectory path
listItem.append @createList path
listItem.addClass "open"
list.append listItem
list

View File

@@ -0,0 +1,35 @@
_ = require 'underscore'
Event = require 'event'
Extension = require 'extension'
KeyBinder = require 'key-binder'
Storage = require 'storage'
TreePane = require 'tree/tree-pane'
fs = require 'fs'
module.exports =
class Tree extends Extension
constructor: ->
KeyBinder.register "tree", @
KeyBinder.load require.resolve "tree/key-bindings.coffee"
# Remove dirs that no longer exist
openedPaths = @getOpenedDirs()
for dir in openedPaths when not fs.exists dir
openedDirs = _.without openedDirs, path
@setOpenedDirs openedDirs
@pane = new TreePane @
storageNamespace: ->
@.constructor.name + ":" + atomController.path
getOpenedDirs: ->
Storage.get @storageNamespace() + ':openedDirs', []
setOpenedDirs: (value) ->
Storage.set @storageNamespace() + ':openedDirs', value
startup: ->
@pane.show()

View File

@@ -1,5 +1,5 @@
<style>
#project {
#tree {
min-width: 200px;
height: 100%;
background-color: #DDE3EA;
@@ -10,7 +10,7 @@
overflow: auto;
}
#project .cwd {
#tree .cwd {
padding-top: 5px;
padding-left: 5px;
font-weight: bold;
@@ -19,48 +19,48 @@
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
}
#project ul {
#tree ul {
margin: 0;
padding-top: 2px;
list-style-type: none;
}
#project li {
#tree li {
padding: 0;
padding-left: 20px;
line-height: 20px;
}
#project li ul li {
#tree li ul li {
padding-left: 110px;
margin-left: -100px;
}
#project li.file {
#tree li.file {
font-weight: normal;
}
#project li.dir {
#tree li.dir {
font-weight: bold;
}
#project li.dir {
background: url('extensions/project/images/dir-toggle.png') 9px 6px no-repeat;
#tree li.dir {
background: url('extensions/tree/images/dir-toggle.png') 9px 6px no-repeat;
}
#project li.dir.open {
#tree li.dir.open {
background-position: 9px -16px;
}
#project li ul li.dir {
#tree li ul li.dir {
background-position: 100px 6px;
}
#project li ul li.dir.open {
#tree li ul li.dir.open {
background-position: 100px -16px;
}
#project li.active {
#tree li.active {
background-image: -webkit-gradient(linear,0% 0,0% 100%,from(#BCCBEB),to(#8094BB));
border-top: 1px solid #A0AFCD;
color: #fff;
@@ -68,7 +68,7 @@
}
</style>
<div id='project'>
<div id='tree'>
<div class='cwd'></div>
<ul class='files'></ul>
</div>

View File

@@ -3,6 +3,8 @@ fs = require 'fs'
module.exports =
class Extension
pane: null
constructor: ->
console.log "#{@constructor.name}: Loaded"
@@ -11,33 +13,3 @@ class Extension
startup: ->
shutdown: ->
pane: ->
# This should be stored keyed on the window path I think? But what if the path
# changes?
get: (key, defaultValue) ->
try
object = JSON.parse(localStorage[@storageNamespace()] ? "{}")
catch error
error.message += "\nGetting #{key}"
console.error(error)
object[key] ? defaultValue
set: (key, value) ->
try
object = JSON.parse(localStorage[@storageNamespace()] ? "{}")
catch error
error.message += "\nSetting #{key}: #{value}"
console.error(error)
if value == undefined
delete object[key]
else
object[key] = value
localStorage[@storageNamespace()] = JSON.stringify(object)

View File

@@ -2,12 +2,12 @@ module.exports =
class Storage
@get: (key, defaultValue) ->
try
object = JSON.parse(localStorage[key] ? "{}")
value = JSON.parse(localStorage[key] ? null) ? defaultValue
catch error
error.message += "\nGetting #{key}"
console.error(error)
object ? defaultValue
value
@set: (key, value) ->
if value == undefined