JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
code cleanup
[crayon_mockup.git] / main.coffee
index 0a60f32..a1c09c5 100644 (file)
@@ -29,8 +29,6 @@ STATES = {
        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) ->
@@ -113,9 +111,9 @@ class Visible
                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
@@ -130,7 +128,6 @@ class Visible
 class Control extends Visible
        constructor: (args) ->
                super args
-               @type = TYPE_CONTROL
                @on_drag = args.drag
                @on_destruct = args.done ? null
        destruct: ->
@@ -165,7 +162,6 @@ class Widget extends Visible
        constructor: (args) ->
                super args
                @controls = []
-               @type = TYPE_WIDGET
        destruct: ->
                @kill_controls()
        clone: ->
@@ -206,6 +202,14 @@ class RectWidget extends Widget
                        @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()
@@ -238,8 +242,9 @@ class RectWidget extends Widget
                        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
@@ -301,6 +306,22 @@ class PolylineWidget extends Widget
                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: ->
@@ -372,9 +393,9 @@ class PolylineWidget extends Widget
        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
@@ -393,10 +414,9 @@ class PolylineWidget extends Widget
                        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]
@@ -410,6 +430,14 @@ class PolylineWidget extends Widget
                        }
                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
@@ -451,7 +479,7 @@ init = ->
        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: {} }
@@ -463,6 +491,65 @@ init = ->
        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()
@@ -556,6 +643,7 @@ init = ->
                        deselect_all widget_layer
                return
        mouseup = (e) ->
+               save()
                mousemove e
                if dragging
                        selected_count = 0
@@ -609,4 +697,7 @@ init = ->
                return true
        #($ document).keydown (e) ->
 
+       if window.location.hash
+               load window.location.hash
+
 $ init