GraphicsGrid.frink

Download or view GraphicsGrid.frink in plain text format


/** This is a class for laying out graphics objects in a grid.

    See GraphicsGridTest.frink for examples of its use.
*/

class GraphicsGrid
{
   // Array of graphics objects
   var garray = new array

   // Desired number of colums or undef.
   var cols = undef

   // Insets for each graphic object from 0 to 1
   var insets = 0.95

   // flag indicating if we're going to draw grid lines
   var drawGrid = true

   /** Construct a GraphicsGrid with arbitrary number of columns.  The number
       of columns is chosen perhaps from the square root of the number of items.
   */

   new[] :=
   {
   }

   /** Construct a GraphicsGrid with a desired maximum number of columns. */
   new[cols] :=
   {
      this.cols = cols
   }

   /** Add a graphics object to the grid. */
   add[g1] :=
   {
      // TODO:  Test for GraphicsExpression and turn other expression types
      // into graphics
      garray.push[g1]
   }

   /** Sets the flagi if we're going to draw boxes around each cell. */
   drawBoxes[flag] :=
   {
      drawGrid = flag
   }

   /** Lay out the grid (with equal-sized rectangles) and return a graphics
       object. */

   layout[] :=
   {
      g = new graphics
      verts = new OrderedList
      horiz = new OrderedList
      //g.color[0,0,0]
      CELL:
      for i = rangeOf[garray]
      {
         g1 = garray@i
         if g1 == undef
            next CELL
         
         [cx, cy, width, height, left, right, top, bottom] = getCenter[i]
         verts.insertUnique[left]
         verts.insertUnique[right]
         horiz.insertUnique[top]
         horiz.insertUnique[bottom]
         
         if g1 != undef
         {
            //g.save[]      // save and restore are already done by addCenter
            g.addCenter[g1, cx, cy, width, height]
            //g.restore[]
         }
      }

      if drawGrid
      {
         // Draw borders
         // Draw vertical lines
         g.color[0,0,0,.5]
         minx = first[verts]
         maxx = last[verts]
         miny = first[horiz]
         maxy = last[horiz]

         for x = verts
            g.line[x, miny, x, maxy]

         for y = horiz
            g.line[minx, y, maxx, y]
      }

      return g
   }

   /** Sets the inset size of each box from 0 to 1.  If insets is 0.95, each
       grid box will take up 95% of width and height. If insets is 1, each
       grid box will take up 100% of width and height. */

   setInsets[n] :=
   {
      insets = n
   }

   /** Private method to return the center coordinates and size for the
       specified index.

       Returns [cx, cy, width, height, left, right, top, bottom]
   */

   getCenter[index] :=
   {
      wcols = cols   // Working columns value
      if wcols == undef   // Try to make approximately square if undefined
         wcols = ceil[sqrt[length[garray]]]

      // This is laying out left-to-right with specified number of columns
      row = index div wcols
      col = index mod wcols
      return [col, row, 1 insets, 1 insets, col-1/2, col+1/2, row-1/2, row+1/2]
   }
}


Download or view GraphicsGrid.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen, eliasen@mindspring.com