DRAGGING: { txt: 'dragging' }
EDITING: { txt: 'editing' }
}
-TYPE_WIDGET = 1
-TYPE_CONTROL = 2
# json (compiled to javascript and minified) is ~8% smaller than the resulting xml
json_to_svg = (json) ->
if @hover
css_class += " hover"
@el.setAttribute 'class', css_class
- set_hover: (tf) ->
- if tf != @hover
- @hover = tf
+ set_hover: (bool) ->
+ if bool != @hover
+ @hover = bool
@update_class()
move: (xy) -> # just move
@x = xy.x
class Control extends Visible
constructor: (args) ->
super args
- @type = TYPE_CONTROL
@on_drag = args.drag
@on_destruct = args.done ? null
destruct: ->
constructor: (args) ->
super args
@controls = []
- @type = TYPE_WIDGET
destruct: ->
@kill_controls()
clone: ->
@svg.removeChild @el
clone: ->
return new RectWidget @
+ as_array: ->
+ return [@x, @y, @width, @height]
+ from_array: (args, a) ->
+ args.x = a[0]
+ args.y = a[1]
+ args.width = a[2]
+ args.height = a[3]
+ return new RectWidget args
set_state: (state) ->
super state
@update_class()
new_prox *= new_prox
if new_prox < prox
prox = new_prox
- if in_x and in_y and prox > PROX_MAX
- prox = PROX_MAX - 1
+ # "hit" anything inside
+ #if in_x and in_y and prox > PROX_MAX
+ # prox = PROX_MAX - 1
return prox
resize: (wh) ->
dw = wh.w - @width
super()
if @el?
@svg.removeChild @el
+ as_array: ->
+ ret = []
+ for n in @nodes
+ ret.push @x + n.x
+ ret.push @y + n.y
+ return ret
+ from_array: (args, a) ->
+ args.x = a[0]
+ args.y = a[1]
+ args.nodes = []
+ while a.length
+ xy = {}
+ xy.x = a.shift() - args.x
+ xy.y = a.shift() - args.y
+ args.nodes.push xy
+ return new PolylineWidget args
clone: ->
return new PolylineWidget @
my_path_d: ->
node_dragger: (i) ->
if i is 0
return (dxy) =>
- for i in [1...@nodes.length]
- @nodes[i].x -= dxy.x
- @nodes[i].y -= dxy.y
+ for j in [1...@nodes.length]
+ @nodes[j].x -= dxy.x
+ @nodes[j].y -= dxy.y
@move x: @x + dxy.x, y: @y + dxy.y
return (dxy) =>
@nodes[i].x += dxy.x
ret.push x: @x + n.x, y: @y + n.y
return ret
make_controls: (args) -> # create controls, return them
- console.log 'make line controls'
if @controls.length > 0
if console?.log?
- console.log "warning: re-adding controls"
+ console.log "warning: re-adding line controls"
@kill_controls()
positions = @control_positions()
for i in [0...positions.length]
}
return @controls
+CSS_CLASS_TO_PICKLE_TYPE = {
+ box: '0'
+ polyline: '1'
+}
+PICKLE_TYPE_TO_WIDGET_CLASS = [
+ RectWidget
+ PolylineWidget
+]
# called automatically on domcontentloaded
init = ->
svg_offset = null
supply_add PolylineWidget, y: 25, nodes: [{x: 0, y: 0}, {x: 50, y: 0}]
supply_add PolylineWidget, x: 25, nodes: [{x: 0, y: 0}, {x: 0, y: 50}]
supply_add PolylineWidget, x: 10, nodes: [{x: 0, y: 0}, {x: 15, y: 50}, {x: 30, y: 0}]
- supply_add PolylineWidget, x: 0, nodes: [{x: 0, y: 50}, {x: 17, y: 0}, {x: 33, y: 50}, {x: 50, y: 0}]
+ supply_add PolylineWidget, y: 50, nodes: [{x: 0, y: 0}, {x: 17, y: -50}, {x: 33, y: 0}, {x: 50, y: -50}]
# editor state
controls_layer = { all: {}, selected: {} }
drag_from = x: 0, y: 0 # mouse was here at last frame of drag
shift_key_down = false
+ lc = "abcdefghijklmnopqrstuvwxyz"
+ uc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ cc_lca = lc.charCodeAt 0
+ cc_lcz = lc.charCodeAt 25
+ cc_uca = uc.charCodeAt 0
+ cc_ucz = uc.charCodeAt 25
+ cc_0 = '0'.charCodeAt 0
+ cc_9 = '9'.charCodeAt 0
+ # takes an array of positive integers, and encodes it as a string
+ pickle = (a) ->
+ ret = ''
+ for i in a
+ cs = lc
+ r = ''
+ while i > 0 or r is ''
+ digit = i % cs.length
+ i -= digit
+ i /= cs.length
+ r = cs.charAt(digit) + r
+ cs = uc
+ ret += r
+ return ret
+ pickle_widgets = ->
+ ret = '0' # version of this encoding scheme
+ for id, w of widget_layer.all
+ if CSS_CLASS_TO_PICKLE_TYPE[w.css_class]?
+ ret += CSS_CLASS_TO_PICKLE_TYPE[w.css_class]
+ ret += pickle w.as_array()
+ return ret
+ save = ->
+ window.location.hash = pickle_widgets()
+ load = (str) ->
+ return if str.charAt(1) isnt '0'
+ wtype = null
+ args = []
+ ii = 0
+ load_1 = (next_type) ->
+ unless wtype?
+ if next_type?
+ wtype = next_type
+ return
+ w = PICKLE_TYPE_TO_WIDGET_CLASS[wtype]::from_array svg: svg, args
+ widget_layer.all[w.id] = w
+ wtype = next_type
+ args = []
+ ii = 0
+ for i in [2...str.length]
+ c = str.charCodeAt(i)
+ if cc_0 <= c <= cc_9
+ load_1 c - cc_0
+ else if cc_lca <= c <= cc_lcz
+ ii *= lc.length
+ ii += c - cc_lca
+ args.push ii
+ ii = 0
+ else if cc_uca <= c <= cc_ucz
+ ii *= lc.length
+ ii += c - cc_uca
+ load_1 null
stop_editing = ->
if widget_layer.editing
widget_layer.editing.kill_controls()
deselect_all widget_layer
return
mouseup = (e) ->
+ save()
mousemove e
if dragging
selected_count = 0
return true
#($ document).keydown (e) ->
+ if window.location.hash
+ load window.location.hash
+
$ init