|
Layer.prototype.destroyRecursively = -> |
|
layer.destroyRecursively() for layer in @subLayers |
|
@destroy() |
|
|
|
class Configurator |
|
|
|
constructor: (options) -> |
|
@values = {} |
|
@options = options |
|
@callbacks = {} |
|
@_createLayer() |
|
@_draw() |
|
|
|
destroy: -> |
|
@layer.destroyRecursively() |
|
delete this |
|
# this = null |
|
|
|
_createLayer: -> |
|
@layer = new Layer x: 20, y: 20, width: 260, height: 400, backgroundColor: 'rgba(79, 79, 79, 0.87)' |
|
@layer.draggable.enabled = true |
|
@layer.on Events.TouchStart, (e) => @layer.draggable.enabled = e.offsetY < 60 |
|
@layer.on Events.DragEnd, (e) => @layer.draggable.enabled = true |
|
@layer.style = |
|
"border": "1px solid rgba(86, 86, 86, 0.87)" |
|
"-webkit-border-radius": "6px" |
|
"-moz-box-shadow": "0 2px 7px rgba(0, 0, 0, 0.81)" |
|
"box-shadow": "0 2px 7px rgba(0, 0, 0, 0.81)" |
|
"border-bottom": "1px solid rgba(66, 66, 66, 0.87)" |
|
"border-top": "none" |
|
"cursor": "default" |
|
"pointer-events": "auto" |
|
"max-height": "400px" |
|
"padding-bottom": "10px" |
|
|
|
@content = new Layer superLayer: @layer, y: 0, height: 350, width: @layer.width |
|
@content.style = |
|
"width": "100%" |
|
"background-color": "transparent" |
|
"height": "100%" |
|
"padding-bottom": "1px" |
|
"z-index": "1000" |
|
"overflow-x": "none" |
|
"overflow-y": "auto" |
|
"pointer-events": "none" |
|
"-webkit-border-radius": "6px" |
|
"padding-bottom": "5px" |
|
|
|
@header = new Layer x: 0, y: 0, width: @layer.width - 2, height: 20, superLayer: @layer |
|
@header.style = |
|
"position": "relative" |
|
"top": "0px" |
|
"box-shadow": "none" |
|
"font": "11px/15px 'Lucida Grande'" |
|
"border-top": "1px solid rgba(151, 151, 151, 0.92)" |
|
"height": "20px" |
|
"-webkit-border-top-left-radius": "6px" |
|
"-webkit-border-top-right-radius": "6px" |
|
"-webkit-border-bottom-left-radius": "0px" |
|
"-webkit-border-bottom-right-radius": "0px" |
|
"background-image": "-webkit-gradient(linear, left top, left bottom, from(rgba(108, 108, 108, 0.9)), color-stop(0.5, rgba(87, 87, 87, 0.88)), color-stop(0.5, rgba(75, 75, 75, 0.86)), to(rgba(75, 75, 75, 0.86)))" |
|
|
|
@close = new Layer x: 4, y: 2, width: 13, height: 13, superLayer: @header, image: 'images/close.png' |
|
@close.style = |
|
"border-radius": "10px" |
|
"opacity": 1 |
|
"background-color": "black" |
|
"width": "13px" |
|
"height": "13px" |
|
"display": "block" |
|
"position": "absolute" |
|
"margin-top": "1px" |
|
"-webkit-transition-duration": "0.1s" |
|
"-webkit-transition-property": "opacity" |
|
"cursor": "pointer" |
|
|
|
@close.on Events.Click, => |
|
@layer.animateStop() |
|
@close.animateStop() |
|
if @layer.height == 20 |
|
@close.animate time: 0.1, properties: rotationZ: 0 |
|
@layer.animate time: 0.2, properties: height: @oldHeight |
|
@_draw() |
|
else |
|
@oldHeight ||= @layer.height |
|
@close.animate time: 0.1, properties: rotationZ: -45 |
|
@layer.animate time: 0.2, properties: height: 20 |
|
|
|
@layer |
|
|
|
_line: (options, name) -> |
|
l = new Layer width: @layer.width, height: 24, backgroundColor: 'transparent' |
|
l.on Events.TouchStart, (e) -> e.stopPropagation() |
|
l._element.className += " row" |
|
l.style = |
|
"pointer-events": "auto" |
|
"font": 'normal 11px/18px "Lucida Grande"' |
|
"color": "rgba(255, 255, 255, 0.85)" |
|
"-webkit-transition-duration": "0.07s" |
|
"-webkit-transition-property": "background" |
|
"font-size": "12px" |
|
"border-bottom": "1px solid rgba(255, 255, 255, 0.1)" |
|
"padding-bottom": "4px" |
|
"padding-left": "10px" |
|
|
|
html = $("<div><label style='width: 100px; display: inline-block'>#{name}:</label></div>") |
|
|
|
# Range slider |
|
if options.range or options.object && options.property |
|
options.range ||= [0..255] |
|
max = options.range[options.range.length - 1] |
|
|
|
if !options.property |
|
if options.value |
|
value = options.value |
|
else |
|
value = options.object[options.property] |
|
max = value * 2 if value > max |
|
html.append $ "<input step='0.01' type='range' value='#{value}' min='#{options.range[0]}' max='#{max}'>" |
|
|
|
# Boolean |
|
else if options.value in [true, false] |
|
html.append $ "<input checked='#{options.value}' type='checkbox' style='position: relative; top: 0px' />" |
|
|
|
# Select |
|
else if options.options |
|
html.append $ "<select>#{name}</select>" |
|
for option in options.options |
|
$("select", html).append $("<option>#{option}</option>") |
|
|
|
if options.object && options.property |
|
options.object?.on "change:#{options.property}", (value) => |
|
$("input, select", html).val value |
|
|
|
_this = this |
|
$("input, select", html).on "input change", () -> |
|
val = parseFloat $(this).val() |
|
options.change? _this.values[name] = val |
|
options.object?[options.property] = val if options.object && options.property |
|
callback?(val) for callback in _this.callbacks["change:#{name}"]? |
|
|
|
$(l._element).append html |
|
l |
|
|
|
_draw: () -> |
|
options = @options |
|
line = false |
|
for layer in @content.subLayers |
|
layer.removeAllListeners() |
|
layer.destroyRecursively() |
|
|
|
lines = Object.keys(options) |
|
for name, i in lines |
|
do (name) => |
|
line = @_line(options[name], name) |
|
line.y = i * line.height + @header.height + 5 |
|
line.superLayer = @content |
|
if i == lines.length - 1 |
|
line.style.borderBottom = 'none' |
|
|
|
@layer.height = lines.length * line.height + @header.height + 6 |
|
@content.height = lines.length * line.height + @header.height + 100 |
|
|
|
on: (events, callback) -> |
|
events = _.flatten [events] |
|
for eventName in events |
|
for event in eventName.split(" ") |
|
console.log "Adding a #{event} callback" |
|
(@callbacks[event] ||= []).push callback |
|
|
|
exports = window if typeof exports == 'undefined' |
|
exports.Configurator = Configurator |