def combined_types(type, opts = nil)
      if type.to_sym == :grid && opts
        x = grid_range(opts[:x])
        y = grid_range(opts[:y])
        return [:grid] if x.nil? && y.nil?  # whole grid
        x ||= ['-']                         # whole row
        y ||= ['-']                         # whole column
        x.product(y).map {|x, y| :"grid#{x}#{y}"}
      else
        [type.to_sym]
      end
    end
def combined_types(type, opts = nil)
      if type.to_sym == :grid && opts
        x = grid_range(opts[:x])
        y = grid_range(opts[:y])
        return [:grid] if x.nil? && y.nil?  # whole grid
        x ||= ['-']                         # whole row
        y ||= ['-']                         # whole column
        x.product(y).map {|x, y| :"grid#{x}#{y}"}
      else
        [type.to_sym]
      end
    end
Returns a list of combined types for the type and opts specified. Combined
 types are just the type, except for grid, where the opts are interpreted
 and all combinations of x and y coordinates are added as a position suffix.

 Example:

 combined_types(:grid, :x => 1..2, y => 2) => [:grid12, :grid22]

 Parameters (see Launchpad for values):

 [+type+]  type of the button

 Optional options hash:

 [<tt>:x</tt>] x coordinate(s), can contain arrays and ranges, when specified
               without y coordinate, it's interpreted as a whole column
 [<tt>:y</tt>] y coordinate(s), can contain arrays and ranges, when specified
               without x coordinate, it's interpreted as a whole row