kdf
Version:
376 lines (274 loc) • 10.6 kB
text/coffeescript
KDScrollView = require './../scrollview/scrollview.coffee'
KDTabHandleContainer = require './tabhandlecontainer.coffee'
KDTabHandleMoveNav = require './tabhandlemovenav.coffee'
module.exports = class KDTabView extends KDScrollView
constructor:(options = {}, data)->
options.resizeTabHandles ?= no
options.maxHandleWidth ?= 128
options.minHandleWidth ?= 30
options.lastTabHandleMargin ?= 0
options.sortable ?= no
options.hideHandleContainer ?= no
options.hideHandleCloseIcons ?= no
options.enableMoveTabHandle ?= no
options.detachPanes ?= yes
options.tabHandleContainer ?= null
options.tabHandleClass or= KDTabHandleView
options.paneData or= []
options.cssClass = KD.utils.curry "kdtabview", options.cssClass
# Is there a reason why are we setting those before super? ~ GG
= []
= []
= []
= options.tabClass ? KDTabPaneView
= 0
# ---
super options, data
= null
= no
= no
options.tabHandleContainer
if options.enableMoveTabHandle
if options.hideHandleCloseIcons
if options.hideHandleContainer
"PaneRemoved", =>
"PaneAdded", =>
= no
"PaneDidShow", "setActivePane"
if options.paneData.length > 0
"viewAppended", => options.paneData
.on "mouseleave", =>
if
= no
# ADD/REMOVE PANES
createPanes:(paneData = .paneData)->
for paneOptions in paneData
new paneOptions, null
addPane:(paneInstance, shouldShow = paneInstance.getOptions().shouldShow ? yes) ->
unless paneInstance instanceof KDTabPaneView
{name} = paneInstance?.constructor?
warn "You can't add #{name if name} as a pane, use KDTabPaneView instead"
return no
{ tabHandleClass, sortable, detachPanes } =
paneInstance.setOption 'detachable', detachPanes
.push paneInstance
{ name, title, hiddenHandle, tabHandleView, closable, lazy } = paneInstance.getOptions()
newTabHandle = paneInstance.tabHandle or new tabHandleClass
pane : paneInstance
title : name or title
hidden : hiddenHandle
cssClass : KD.utils.slugify name.toLowerCase()
view : tabHandleView
closable : closable
sortable : sortable
mousedown : (event) ->
{pane} =
tabView = pane.getDelegate()
tabView.handleClicked event, this
newTabHandle
paneInstance.tabHandle = newTabHandle
paneInstance
paneInstance if shouldShow and not lazy
'PaneAdded', paneInstance
{minHandleWidth, maxHandleWidth} =
newTabHandle.getDomElement().css
maxWidth : maxHandleWidth
minWidth : minHandleWidth
newTabHandle.on 'HandleIndexHasChanged', 'resortTabHandles'
return paneInstance
resortTabHandles: (index, dir) ->
return if (index is 0 and dir is 'left') or \
(index is .length - 1 and dir is 'right') or \
(index >= .length) or (index < 0)
[0].unsetClass 'first'
if dir is 'right'
methodName = 'insertAfter'
targetIndex = index + 1
else
methodName = 'insertBefore'
targetIndex = index - 1
[index].$()[methodName] [targetIndex].$()
newIndex = if dir is 'left' then index - 1 else index + 1
splicedHandle = .splice index, 1
splicedPane = .splice index, 1
.splice newIndex, 0, splicedHandle[0]
.splice newIndex, 0, splicedPane[0]
[0].setClass 'first'
'TabsSorted'
removePane:(pane, shouldDetach = no)->
pane.emit "KDTabPaneDestroy"
index = pane
isActivePane = is pane
.splice index, 1
handle = index
.splice index, 1
if shouldDetach
= .filter (p)-> p isnt pane
= .filter (h)-> h isnt handle
pane.detach()
handle.detach()
else
pane.destroy()
handle.destroy()
if isActivePane
if prevPane =
prevPane
else if firstPane = 0
firstPane
"PaneRemoved", { pane, handle }
return { pane, handle }
removePaneByName:(name)->
for pane in
if pane.name is name
pane
break
appendHandleContainer:->
appendPane:(pane)->
pane.setDelegate this
pane
appendHandle:(tabHandle)->
or= .getHeight()
tabHandle.setDelegate this
.tabs.addSubView tabHandle
{enableMoveTabHandle, maxHandleWidth} =
if enableMoveTabHandle
= .length * maxHandleWidth
# unless tabHandle.options.hidden
# tabHandle.$().css {marginTop : }
# tabHandle.$().animate({marginTop : 0},300)
# ADD/REMOVE HANDLES
addHandle: (handle) ->
unless handle instanceof KDTabHandleView
{name} = handle?.constructor?
warn "You can't add #{name if name?} as a pane, use KDTabHandleView instead"
return no
.push handle
handle
handle.setClass 'hidden' if handle.getOptions().hidden
return handle
removeHandle:->
#SHOW/HIDE ELEMENTS
showPane:(pane)->
return unless pane
activePane =
return if pane is activePane
= activePane if activePane
pane.show()
index = pane
handle = index
handle.makeActive()
pane.emit "PaneDidShow"
"PaneDidShow", pane, index
return pane
hideAllPanes:->
pane.hide() for pane in when pane
handle.makeInactive() for handle in when handle
hideHandleContainer:->
.hide()
= yes
showHandleContainer:->
.show()
= no
toggleHandleContainer:(duration = 0)->
.$().toggle duration
hideHandleCloseIcons:->
.$().addClass "hide-close-icons"
showHandleCloseIcons:->
.$().removeClass "hide-close-icons"
handleMouseDownDefaultAction:(clickedTabHandle, event)->
for handle, index in when clickedTabHandle is handle
index, event
# DEFAULT ACTIONS
handleClicked: (event, handle) ->
{pane} = handle.getOptions()
# fixme: make close icon a kdview and check the view instead.
if $(event.target).hasClass 'close-tab'
= yes
pane
return no
pane
# DEFINE CUSTOM or DEFAULT tabHandleContainer
setTabHandleContainer:(aViewInstance)->
if aViewInstance?
.destroy() if ?
= aViewInstance
else
= new KDTabHandleContainer
.setClass "kdtabhandlecontainer"
getTabHandleContainer:->
setTabHandleMoveNav:->
.addSubView new KDTabHandleMoveNav delegate : this
#TRAVERSING PANES/HANDLES
checkPaneExistenceById:(id)->
result = false
for pane in
result = true if pane.id is id
result
getPaneByName:(name)->
#FIXME: if there is a space in tabname it doesnt work
result = false
for pane in
result = pane if pane.name is name
result
getPaneById:(id)->
paneInstance = null
for pane in
paneInstance = pane if pane.id is id
paneInstance
getActivePane: ->
getActivePaneIndex: ->
setActivePane:( )->
getPaneByIndex:(index)-> [index]
getHandleByIndex:(index)-> [index]
getPaneIndex:(aPane)->
throw new Error "no pane provided!" unless aPane
.indexOf aPane
#NAVIGATING
showPaneByIndex:(index)->
index
showPaneByName:(name)->
name
showNextPane:->
activePane =
activeIndex = activePane
activeIndex + 1
showPreviousPane:->
activePane =
activeIndex = activePane
activeIndex - 1
#MODIFY PANES/HANDLES
setPaneTitle:(pane,title)->
handle = pane
handle.getDomElement().find("b").text title
handle.setAttribute "title", title
getHandleByPane: (pane) ->
index = pane
handle = index
hideCloseIcon:(pane)->
index = pane
handle = index
handle.getDomElement().addClass "hide-close-icon"
getVisibleHandles: ->
return .filter (handle) -> handle.isHidden() is no
getVisibleTabs: ->
return .filter (pane) -> pane.tabHandle.isHidden() is no
resizeTabHandles: ->
return if not .resizeTabHandles or \
or
{ lastTabHandleMargin } =
visibleHandles = []
visibleTotalSize = 0
outerWidth = .tabs.getElement().offsetWidth
return if outerWidth <= 0
containerSize = outerWidth - lastTabHandleMargin
containerMargin = 100 - (100 * lastTabHandleMargin / containerSize)
for handle in when not handle.isHidden()
visibleHandles.push handle
visibleTotalSize += handle.getElement().offsetWidth
possiblePercent = (containerMargin / visibleHandles.length).toFixed 2
handle.setWidth(possiblePercent, "%") for handle in visibleHandles