d4tocchini
2/1/2012 - 10:11 PM

Cass Tests

Cass Tests

$ ->
  # run quaddemo?
  #runit()
  
  global = window
  BP = (options) ->
    console.log options
    alert options
  
  ERROR = (options) ->
    console.error options
  
  d4 = {}
  window.d4 = d4

  cexp = c.LinearExpression
  ceq = c.LinearEquation
  cieq = c.LinearInequality

  
  _weak = c.Strength.weak
  _medium = c.Strength.medium
  _strong = c.Strength.strong
  _required = c.Strength.required
  
  class d4.App
    constructor: ->
      @solver = new c.SimplexSolver()
      @solver.setAutosolve(true)
      @views = []
      
    staticDemo: ->
      
      box1 = new d4.View('#box1')
      @views.push box1
            
      box2 = new d4.View('#box2')
      @views.push box2
      
      box3 = new d4.View('#box3')
      @views.push box3

      @solver.addStay(box1.w).addStay(box1.h).addStay(box1.x).addStay(box1.y)
      
      # width bounds
      wMax = 500
      wMin = 250
      
      
      
      if box1.wNatural <= wMin
        @solver.addConstraint new cieq(box1.w, c.GEQ, wMin, _required)
        @solver.addConstraint new cieq(box1.w, c.LEQ, wMax, _required)        
      else  
        @solver.addConstraint new cieq(box1.w, c.LEQ, wMax, _required)
        @solver.addConstraint new cieq(box1.w, c.GEQ, wMin, _required)
      
      #@solver.addConstraint new ceq(box1.w, box1.wIntrinsic, _required)
      #@solver.addConstraint new cieq(box1.w, c.LEQ, ((wMin + wMax)/2) )
          
      
      # height bounds
      hMax = 500
      hMin = 10
      @solver.addConstraint new cieq(box1.h, c.LEQ, hMax, _required)
      @solver.addConstraint new cieq(box1.h, c.GEQ, hMin, _required)
      
      #for view in @views
      #  view._setupInternalConstraints( @solver )
      
      # left align
      
      @solver.addConstraint new ceq(box2.x, box1.r(), _required)
      @solver.addConstraint new ceq(box3.x, box1.r(), _required)
      @solver.addConstraint new ceq(box3.y, box1.y, _required)
      
      # top align w/ offset
      #@solver.addConstraint new ceq(box2.y, c.Plus(box1.y,10)) 
      
      @solver.addStay(box3.h).addStay(box3.y)
      @solver.addConstraint new ceq(box2.y, box1.b(), _weak)
      
      #@solver.addStay(box2.h).addStay(box2.y)
      #@solver.addConstraint new cieq(box1.y, c.LEQ, box2.b(), _weak)
      #box2.position {my:'y', at:'b', of:box3}, _required
      
      # window border
      for view in @views
        @solver.addConstraint new cieq(view.x, c.LEQ, 1200)
        @solver.addConstraint new cieq(view.x, c.GEQ, 100)
        $el = view.$el
          
      $(window).on 
        mousedown:(ev) =>
          view = $(ev.target).data()?.view?()
          if view
            @draggedView = view
            @draggedView.$el.addClass('dragging')
            @solver.addEditVar(@draggedView.x).addEditVar(@draggedView.y).beginEdit()
        mousemove: (ev) =>
          if @draggedView
            x = ev.pageX
            y = ev.pageY
            @solver.suggestValue(@draggedView.x,x).suggestValue(@draggedView.y,y).resolve()
            @render()
        mouseup: (ev) =>
          if @draggedView 
            @draggedView.$el.removeClass('dragging')
            @solver.endEdit()
            @render()
          @draggedView = null
        
      
          
      
      
      #box2.t = #box2.b !strong
      #@solver.addConstraint new ceq(box2.y, box3.b() )
      
      # equal widths
      #@solver.addConstraint new ceq(box1.w, box2.w)
      #@solver.addConstraint new ceq(box2.w, box3.w)


      @render()
      
      
    render: ->
      for view in @views
        view.render()
    
      
  class d4.View 
    constructor: (el) ->
      if _.isString(el) then $el = $(el)
      $el = $(el)
      $el.data().view = () =>
        return @
      @$el = $el
      @wNatural = 100
      @w = new c.Variable @wNatural
      @h = new c.Variable $el.height()
      #@wIntrinsic = new c.Variable $el.width()
      
      p = $el.position()
      @x = new c.Variable p.left
      @y = new c.Variable p.top
      @t = @y
      @cx = () ->
        exp = new cexp @w
        exp = exp.divide(2)
        exp.plus(@x)
      @cx.value = () ->
        return (@w.value() / 2)  + @x.value()
      @cy = () ->
        exp = new cexp @h
        exp = exp.divide(2)
        exp.plus(@y)
      @cy.value = () ->
        return (@h.value() / 2)  + @y.value()
      @b = () ->
        new cexp(@y).plus(@h)
      @b.value = () =>
        return @y.value() + @h.value()
      @l = @x
      @r = () ->
        new cexp(@x).plus(@w)
      @r.value = () =>
        return @x.value() + @w.value()
      #@tl = new c.Point p.left, p.top
      #@tr = new c.Point p.right, p.top

      
      $el.addClass 'cassowary-item'
          
    getSolver: () ->
      return app.solver
    
    stay:(prop)->
      
    
    position:(options, strength = _strong)->
      options or options = {}
      my = options.my or 'l'
      at = options.at or 'r'
      _of = options.of or ERROR 'position(of:)'
      offset = options.offset or 0
      solver = options.offset or @getSolver()
      if offset > 0
        solver.addConstraint new ceq( @[my], c.Plus(_of[at], offset), strength)
      else        
        solver.addConstraint new ceq( @[my], _of[at](), strength)
      #collision
      #using # ({x,y})
    lead: (options) ->
      _of = options.of 
      eq = options.eq
      offset = options.offset()
    tail: (view, eq = false) ->
    above: (view, eq = false) ->
    below: (view, eq = false) ->
        
    inside: (view, options)->       
      offset = options.offset
      
    render: () ->
      x = @x.value()
      y = @y.value()
      w = @w.value()
      h = @h.value()
      cssAttrs = 
        position: 'absolute'
        left: "0px"
        top: '0px'
        width:"#{w}px"
        height:"#{h}px"
        '-webkit-transform': "translate3d(#{x}px, #{y}px, 0px)"    
        '-moz-transform': "translate(#{x}px, #{y}px)"    
      @$el.css ( cssAttrs  )
      
      return @
    
    _setupInternalConstraints: (solver) ->
      #solver.addStay(@y)
      
      solver.addConstraint new c.LinearInequality(@w, c.LEQ, 500)
      solver.addConstraint new c.LinearInequality(@w, c.GEQ, 10)
      
      
      solver.addConstraint new c.LinearInequality(@h, c.LEQ, 500)
      solver.addConstraint new c.LinearInequality(@h, c.GEQ, 10)
      
      #solver.addConstraint new c.LinearInequality(@x, c.LEQ, 100)
      #solver.addConstraint new c.LinearInequality(@x, c.GEQ, 10)
      
      #solver.addConstraint new c.LinearInequality(@y, c.GEQ, 10)
      #solver.addConstraint new c.LinearInequality(@y, c.LEQ, 1000)
      
      
      #exp = new cexp @y
      #solver.addConstraint new c.LinearInequality(@y, c.LEQ, exp.plus(@h))
      
      #solver.addConstraint new c.LinearEquation(@tr.y, new c.LinearExpression(@tl.y))
      #solver.addConstraint new c.LinearEquation(@tr.y, new c.LinearExpression(@tl.y))
      # w = r - l
      # w <= wMax
      # w >= wMin
      # h <= hMax
      # h >= hMin
      # h = b - t
      # l = tl.x()
      # r = tr.x()
      # t = tr.y()
      # b = bl.y()
      # hMin <= b - t
      # hMax >= b - t
    
    css:(options)->
      @$el.css options
  
  
  app = new d4.App
  app.staticDemo()
  global.app = app
  ###
  
  TODO:
    - How
  
  ###
  
  
  
  
  
  
  #class rootWindowView
  #class containerView
  
  # [see](http://developer.apple.com/library/mac/#documentation/AppKit/Reference/NSLayoutConstraint_Class/NSLayoutConstraint/NSLayoutConstraint.html)
  # A constraint defines a relationship between two attributes of user interface objects that must be satisfied by the constraint-based layout system.
  # The relationship involves a first attribute, a relationship type, and a modified second value formed by multiplying an attribute by a constant factor and then adding another constant factor to it. In other words, constraints look very much like linear equations of the following form:
  # ```
  # attribute1 == multipler × attribute2 + constant
  # ```
  # The right side of this equation can be considered a modified attribute, so this equation could be described in words as “attribute one must be equal to the modified attribute two.”
  # Note that the constraint-based layout system is free to modify the attributes on either side of the equation as part of satisfying the system of constraints that apply to the objects being laid out.
  # They can also use greater than or equal (>=) or less than or equal (<=) to describe the relationship between the two attributes.
  # Constraints also have priorities, indicating to the layout system which constraint should take priority when two or more constraints are in conflict.
  #
  # Constraints can, with some restrictions, cross the view hierarchy
  #
  # A constraint cannot cross through a view that is manually laid out, or through a view that has a bounds transform. You can think of these views as barriers. There’s an inside world and an outside world, but the inside cannot be connected to the outside by constraints.
  #
  # Constraints are not directional, and there are no restrictions on cycles. Layout itself is neither top down nor bottom up. Instead, all constraints, and their relative priorities, are considered at the same time, and elements laid out in such a way that best satisfies all of the constraints.
  class LayoutConstraint
    
    constructor: ->
      #@priority = new LayoutPriority
      #@relation = new LayoutRelation
      
    # Unlike the other properties, the constant may be modified after constraint creation. Setting the constant on an existing constraint performs much better than removing the constraint and adding a new one that's just like the old but for having a new constant.
    constant: 0
    
    shouldBeArchived: true #false    
  
    _firstAttribute: null
      
    _secondAttribute: null
    
    _firstItem: null
    
    _secondItem: null
    
    setConstant: ->
  
  
  class LayoutConstraints
    add: ->
    remove: ->
  
  
  
  # [see](http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/Reference/NSView.html#//apple_ref/occ/instm/NSView/addConstraint:)
  # provides a structure for drawing, printing, and handling events
  #
  # View is perhaps the most important class in the Application Kit when it comes to subclassing and inheritance. 
  class View
    
    # left, right, top, bottom, leading, trailing, width, height, centerX, centerY, and baseline.
    
    constructor: () ->
      # Layout Operates on Alignment Rectangles
      @alignmentRect = null
      @tl = new c.Point()
      @tr = new c.Point()
      @bl = new c.Point()
      @br = new c.Point()
      
      #@constraints = new LayoutConstraints
    
    # The fittingSize method returns the ideal size for the view *considering only those constraints installed on the receiver’s subtree together with a preference for the view to be as small as possible*. 
    # The fitting size is not the “best” size for a view in a general sense—in the constraint-based system, a view’s “best” size if you consider everything has to be the size it currently has!
    fittingSize: ->
      
    
    # Returns the natural size for the receiving view, considering only properties of the view itself.
    # Custom views typically have content that they display of which the layout system is unaware. Overriding this method allows a custom view to communicate to the layout system what size it would like to be based on its content. This intrinsic size must be independent of the content frame, because there’s no way to dynamically communicate a changed width to the layout system based on a changed height, for example.
    intrinsicContentSize: ->
      # returns: A view can return absolute values for its width and height, or NSViewNoInstrinsicMetric for either or both to indicate that it has no preference for a given dimension.
      return null
    # Call this when something changes in your custom view that invalidates its intrinsic content size. This allows the constraint-based layout system to take the new intrinsic content size into account in its next layout pass.
    invalidateIntrinsicContentSize: ->
    
    setContentHuggingPriority:(priority, orientation)-> 
    setContentCompressionResistancePriority:(priority, orientation)->
      
    # Baseline Stuff
    #@key baseline
    #baselineOffsetFromBottom: ->
    # returns the distance between NSLayoutAttributeBottom and NSLayoutAttributeBaseline. This default return value for NSView is 0; the method is overridden by subclasses for which it makes sense to do so.
  
  # Views are arranged within an Window object, in a nested hierarchy of subviews.  
  #
  #
  
  class Views  
  
  class Window
    
  # handles dynamic views? [see](http://gentlebytes.com/2011/09/auto-layout-in-lion/)
  class ViewController