-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsplitter.coffee
114 lines (111 loc) · 5.04 KB
/
splitter.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# github.com/twolfson/computedStyle
window.computedStyle = (e, p, g) ->
g = window.getComputedStyle
(if g then g(e) else e.currentStyle)[p.replace(/-(\w)/gi, (w, l) -> l.toUpperCase())]
app = angular.module('splitter', [])
app.directive 'splitter', ->
{ restrict: 'A',
link: (scope, element, attrs) ->
panes = element.children()
length = panes.length
if length<2 then return
domElement = element[0]
element.css('position', 'absolute')
$ = angular.element
vertical = attrs.vertical
if vertical
widthProp = 'height'; heightProp = 'width'; minWidthProp = 'min-height'; maxWidthProp = 'max-height'
leftProp = 'top'; topProp = 'left'; clientXProp = 'clientY'
verticalClass = 'vertical'
else
widthProp = 'width'; heightProp = 'height'; minWidthProp = 'min-width'; maxWidthProp = 'max-width'
leftProp = 'left'; topProp = 'top'; clientXProp = 'clientX'
verticalClass = 'horizontal'
elementHeight = computedStyle(domElement, heightProp)
elementTop = computedStyle(domElement, topProp)
elementLeft = parseInt(computedStyle(domElement, leftProp))
elementWidth = parseInt(computedStyle(domElement, widthProp))
elementRight = elementLeft+elementWidth
drag = draggingHandler = null
jqPanes = for i in [0...length] then $(panes[i])
handlers = []
pane = panes[length-1]
jqPane = jqPanes[length-1]
jqPane.css('position', 'absolute')
pane.minWidth = parseInt(computedStyle(pane, minWidthProp) or '0')
pane.width = parseInt(computedStyle(pane, widthProp) or jqPane.css(widthProp, '100px') and '100')
for i in [0...length-1]
pane = panes[i]
jqPane = jqPanes[i]
jqPane.css('position', 'absolute')
pane.minWidth = parseInt(computedStyle(pane, minWidthProp) or '0')
pane.width = parseInt(computedStyle(pane, widthProp) or jqPane.css(widthProp, '100px') and '100')
handler = angular.element('<div class="'+verticalClass+ ' split-handler" style="position:absolute;"></div>')
left = left+jqPane.width
handler.index = i
handler.css(leftProp, computedStyle(panes[i+1], leftProp))
handler.css(heightProp, elementHeight)
handler.css(topProp, elementTop)
jqPane.after handler
handlers.push handler
do (handler=handler, pane=pane, i=i) ->
handler.bind 'mousedown', (ev) ->
ev.preventDefault(); drag = true; draggingHandler = handler
handler.bind 'click', (ev) ->
ev.preventDefault()
if handler.clicked
handler.clicked = false
if i<length-2
if parseInt(handlers[i+1].css(leftProp))<parseInt(handler.leftProp) then return
jqPanes[i].css(widthProp, handler.leftPaneWidth)
handler.css(leftProp, handler.leftProp)
jqPanes[i+1].css(leftProp, handler.rightPaneLeftProp)
jqPanes[i+1].css(widthProp, handler.rightPaneWidthProp)
return
rightPane = panes[i+1]
handler.leftPaneWidth = jqPanes[i].css(widthProp)
handler.leftProp = handler.css(leftProp)
handler.rightPaneLeftProp = jqPanes[i+1].css(leftProp)
handler.rightPaneWidthProp = jqPanes[i+1].css(widthProp)
if i==length-2 and length!=2
leftPaneWidth = elementRight-parseInt(handlers[i-1].css(leftProp))-rightPane.minWidth
jqPanes[i].css(widthProp, leftPaneWidth+'px')
pos = elementRight-rightPane.minWidth
handler.css(leftProp, pos + 'px')
jqPanes[i+1].css(leftProp, pos+'px')
jqPanes[i+1].css(widthProp, rightPane.minWidth + 'px')
else
leftPaneWidth = pane.minWidth
if i==0 then pos = elementLeft+leftPaneWidth
else pos = parseInt(handlers[i-1].css(leftProp))+leftPaneWidth
if length!=2 then right = parseInt(handlers[i+1].css(leftProp))
else right = elementRight
right_pos = right-pos
jqPanes[i].css(widthProp, leftPaneWidth+'px')
handler.css(leftProp, pos + 'px')
jqPanes[i+1].css(leftProp, pos+'px')
jqPanes[i+1].css(widthProp, right_pos+'px')
handler.clicked = true
element.bind 'mousemove', (ev) ->
if !drag then return
i = draggingHandler.index
draggingHandler.clicked = false
if i<length-2 then handlers[i+1].clicked = false
leftPane = panes[i]
rightPane = panes[i+1]
if i==0 then left = elementLeft
else left = parseInt(handlers[i-1].css(leftProp))
if i==length-2 then right = elementRight
else right = parseInt(handlers[i+1].css(leftProp))
pos = ev[clientXProp]
pos_left = pos-left
leftPaneWidth = pos-left
if (pos_left < leftPane.minWidth) then return
right_pos = right - pos
if (right_pos < rightPane.minWidth) then return
jqPanes[i].css(widthProp, leftPaneWidth + 'px')
draggingHandler.css(leftProp, pos + 'px')
jqPanes[i+1].css(leftProp, pos + 'px')
jqPanes[i+1].css(widthProp, right_pos + 'px')
angular.element(document).bind 'mouseup', (ev) -> drag = false
}