coffeescript-ui
Version:
Coffeescript User Interface System
517 lines (401 loc) • 10.9 kB
text/coffeescript
###
* coffeescript-ui - Coffeescript User Interface System (CUI)
* Copyright (c) 2013 - 2016 Programmfabrik GmbH
* MIT Licence
* https://github.com/programmfabrik/coffeescript-ui, http://www.coffeescript-ui.org
###
# this class initializes a flex handle
class CUI.FlexHandle extends CUI.Element
constructor: (opts) ->
super(opts)
= null
children = .parentNode.children
for c, idx in children
if CUI.dom.is(c, )
= c
= idx
if CUI.dom.is(c, )
= idx
= null
if >
if < children.length-1
= children[+1]
else
if > 0
= children[-1]
=
=
= null
= null
CUI.util.assert(, "new #{@__cls}", "pane \"#{@_pane}\" not found in parent element of cui-flex-handle element.", opts: , children: children)
CUI.dom.data(, "flexHandle", @)
CUI.dom.setAttribute(, "flex-handled-pane", )
readOpts: ->
super()
if in ["horizontal", "row"]
= "row"
else if in ["vertical", "column"]
= "column"
CUI.util.assert( in ["row", "column"], "new #{@__cls}", "opts.direction needs to be set", opts: , element: )
if
return
initOpts: ->
super()
element:
mandatory: true
check: (v) ->
CUI.util.isElement(v)
pane:
mandatory: true
check: String
name:
mandatory: true
check: String
closed:
check: Boolean
closable:
mandatory: true
default: false
check: Boolean
label:
check: (v) ->
v instanceof CUI.Label or CUI.util.isPlainObject(v)
hidden:
check: Boolean
direction:
check: ["horizontal", "vertical", "row", "column"]
manage_state:
default: true
check: Boolean
state_name:
check: String
class:
check: String
init: ->
if
return
CUI.dom.addClass(, "cui-flex-handle cui-flex-handle-#{@__direction} cui-flex-handle-#{@_name}")
if
if
if
CUI.dom.addClass(, )
if == "row"
axis = "x"
= "Width"
else
axis = "y"
= "Height"
CUI.Events.listen
type: "dblclick"
node:
call: (ev) =>
if == null # CUI.util.isEmpty([0].style[])
if
else if
else
return
CUI.Events.listen
type: ["click"]
node:
call: (ev) =>
if not
return
if
return
# console.debug , cursor, axis, css_value, ,
drag_start_size = null
new CUI.Draggable
element:
axis: axis
support_touch: true
create: =>
if
return false
# helper_remove_always: true
dragstart: (ev, gd) =>
if <
flip = 1
else
flip = -1
get_data = (pane) =>
dim = CUI.dom.getDimensions(pane)
min = dim["min"+]
if min < 10
min = 10
min: min
max: dim["max"+]
value: dim["contentBox"+]
data = get_data()
if
adj_data = get_data()
max_diff = adj_data.value - adj_data.min # this is the maximum change for the adj value
data.max = Math.max(0, data.value+max_diff)
drag_start_size = .style[.toLowerCase()]
gd.__pane_data =
flip: flip
axis: axis
min: data.min
max: data.max
value: data.value
gd.isFlexHandleDrag = true
gd
get_cursor: (gd) ->
if gd.__pane_data.axis == "x"
return "ew-resize"
else
return "ns-resize"
dragend: (ev, gd) =>
dragging(gd)
= CUI.dom.getDimension(, "contentBox"+)
dragstop: =>
.style[.toLowerCase()] = drag_start_size
drag_start_size = null
dragging: (ev, gd) =>
if !CUI.__ng__ || CUI.browser.ie
return
dragging(gd)
dragging = (gd) =>
new_value = gd.__pane_data.value + gd.dragDiff[gd.__pane_data.axis] * gd.__pane_data.flip
if gd.__pane_data.min
new_value = Math.max(gd.__pane_data.min, new_value)
if gd.__pane_data.max
new_value = Math.min(gd.__pane_data.max, new_value)
if
if not
console.error "new CUI.FlexHandle()", "opts.state_name missing, state will not be stored.",
=
@
__setSize: (size) ->
if CUI.util.isNull(size)
CUI.dom.setStyleOne(, .toLowerCase(), "")
if
if CUI.dom.getDimension(, "contentBox"+) == 0
console.error("FlexHandle.__setSize: Pane size is 0 if unset, this needs to be fixed in CSS.", )
CUI.dom.setDimension(, "contentBox"+, 100)
.classList.remove("cui-is-manually-sized")
.classList.remove("cui-is-manually-sized")
= null
else
.classList.add("cui-is-manually-sized")
.classList.add("cui-is-manually-sized")
CUI.dom.setDimension(, "contentBox"+, size)
= size
resetSize: ->
@
__getSize: ->
__isAlive: ->
if or not CUI.dom.isInDOM()
false
else
true
__resize: ->
# console.debug "FlexHandle.__resize", , , ,
if not
return
# console.info "FlexHandle[#{@getName()}].resize."
CUI.Events.trigger
type: "viewport-resize"
info:
FlexHandle: true
__getState: ->
value = CUI.getLocalStorage()
if not CUI.util.isNull(value)
state = JSON.parse(value)
else
state = {}
state
__setState: ->
if not
return
state =
if not CUI.util.isUndef(state.closed) and
if state.closed
else
if not CUI.util.isUndef(state.size)
# console.debug "setState", state
@
storeState: ->
if not
return
state =
closed:
size:
value = JSON.stringify(state)
CUI.setLocalStorage(, value)
console.info("FlexHandle.storeState: ", , value)
@
isStretched: ->
stretch: (direction, do_stretch = true) ->
if do_stretch
if == direction
return
else
pane =
switch direction
when "west", "north"
els = CUI.dom.findPreviousSiblings(pane)
when "east", "south"
els = CUI.dom.findNextSiblings(pane)
switch direction
when "west", "east"
set = "width"
when "north", "south"
set = "height"
if do_stretch
# first we set all the value to explicit "px"
# so that the transition works
for el in els
el.classList.add("cui-flex-handle-hide-for-stretch")
el.classList.add("cui-flex-handle-hide-for-stretch-#{direction}")
CUI.dom[set](, "")
pane.classList.add("cui-flex-handle-stretched")
pane.classList.add("cui-flex-handle-stretched-#{direction}")
CUI.Events.trigger
node: pane
type: "flex-stretch-start"
= direction
else
for el in els
el.classList.remove("cui-flex-handle-hide-for-stretch")
el.classList.remove("cui-flex-handle-hide-for-stretch-#{direction}")
= null
if
[set]()
pane.classList.remove("cui-flex-handle-stretched")
pane.classList.remove("cui-flex-handle-stretched-#{direction}")
CUI.Events.trigger
node: pane
type: "flex-stretch-end"
@
unstretch: ->
if not
return
getLabel: ->
if not
return null
addLabel: (opts={}) ->
if opts instanceof CUI.Label
= opts
else
if == "row"
opts.rotate_90 = true
= new CUI.defaults.class.Label(opts)
CUI.dom.append(, .DOM)
CUI.dom.addClass(, "cui-flex-handle-has-label")
getName: ->
getHandle: ->
getPane: ->
isShown: ->
not
isHidden: ->
.classList.contains("cui-flex-handle-hidden")
isClosed: ->
.classList.contains("cui-flex-handle-closed")
isOpen: ->
not
close: ->
if
return @
CUI.Events.trigger
node:
type: "flex-close"
.classList.add("cui-flex-handle-closed")
CUI.dom.setStyleOne(, "display", "none")
@
open: ->
if
return @
CUI.Events.trigger
node:
type: "flex-open"
.classList.remove("cui-flex-handle-closed")
CUI.dom.setStyleOne(, "display", "")
delete()
@
hide: ->
if
return @
.classList.add("cui-flex-handle-hidden")
@
show: ->
if
return @
.classList.remove("cui-flex-handle-hidden")
delete()
@
destroy: ->
CUI.dom.removeData(, "flexHandle")
CUI.dom.removeAttribute(, "flex-handled-pane")
CUI.dom.remove()
super()
: (_opts={}) ->
opts = CUI.Element.readOpts _opts, "FlexHandle.getPushButton",
direction:
check: ["west","east","north","south"]
text:
check: String
flexHandle:
check: CUI.FlexHandle
button:
default: {}
activedir =
west: "east"
east: "west"
north: "south"
south: "north"
btn_opts = opts.button
for k, v of {
icon_active: activedir[opts.direction]
icon_inactive: opts.direction
class: "cui-pane-stretch-button"
text: opts.text
switch: true
onClick: (ev, btn) =>
if opts.flexHandle
fh = opts.flexHandle
else
fh_els = CUI.dom.closest(btn.DOM, "[flex-handled-pane]")
CUI.util.assert(fh_els, "FlexHandle.getStretchButton", "FlexHandle not or more than one found, name: #{opts.name}.", opts: opts, flexHandles: fh_els)
fh = CUI.dom.data(fh_els, "flexHandle")
if fh.isStretched()
fh.unstretch()
else
fh.stretch(opts.direction)
}
btn_opts[k] = v
new CUI.defaults.class.Button(btn_opts)
CUI.Events.registerEvent
type: ["flex-stretch-start", "flex-stretch-end", "flex-close", "flex-open"]
sink: true