lib/geomotion/cg_rect.rb in geomotion-0.13.1 vs lib/geomotion/cg_rect.rb in geomotion-0.13.2
- old
+ new
@@ -1,78 +1,81 @@
class CGRect
- # CGRect.make # default rect: {origin: {x: 0, y: 0}, size: {width:0, height:0}}
- # # aka CGRectZero
- # CGRect.make(x: 10, y: 30) # default size: [0, 0]
- # CGRect.make(x: 10, y: 30, width:100, height: 20)
- #
- # point = CGPoint.make(x: 10, y: 30)
- # size = CGSize.make(width: 100, height: 20)
- # CGRect.make(origin: point, size: size)
- def self.make(options = {})
- if options[:origin]
- x = options[:origin][0]
- y = options[:origin][1]
- else
- x = options[:x] || 0
- y = options[:y] || 0
+ class << self
+ # CGRect.make # default rect: {origin: {x: 0, y: 0}, size: {width:0, height:0}}
+ # # aka CGRectZero
+ # CGRect.make(x: 10, y: 30) # default size: [0, 0]
+ # CGRect.make(x: 10, y: 30, width:100, height: 20)
+ #
+ # point = CGPoint.make(x: 10, y: 30)
+ # size = CGSize.make(width: 100, height: 20)
+ # CGRect.make(origin: point, size: size)
+ def make(options = {})
+ if options[:origin]
+ x = options[:origin][0]
+ y = options[:origin][1]
+ else
+ x = options[:x] || 0
+ y = options[:y] || 0
+ end
+ if options[:size]
+ w = options[:size][0]
+ h = options[:size][1]
+ else
+ w = options[:width] || 0
+ h = options[:height] || 0
+ end
+ self.new([x, y], [w, h])
end
- if options[:size]
- w = options[:size][0]
- h = options[:size][1]
- else
- w = options[:width] || 0
- h = options[:height] || 0
+
+ def zero
+ CGRect.new([0, 0], [0, 0])
end
- self.new([x, y], [w, h])
- end
+ alias empty zero
- def self.empty
- # Don't just return CGRectZero; can be mutated
- CGRectZero.dup
- end
+ def null
+ # Don't just return CGRectNull; can be mutated
+ CGRect.new([Float::INFINITY, Float::INFINITY], [0, 0])
+ end
- def self.null
- # Don't just return CGRectNull; can be mutated
- CGRectNull.dup
- end
+ def infinite
+ # This actually returns the not-very-infinite value of:
+ # [[-1.7014114289565e+38, -1.7014114289565e+38], [3.402822857913e+38, 3.402822857913e+38]]
+ # originally this method returned [[-Infinity, -Infinity], [Infinity, Infinity]],
+ # but that rect ended up returning `false` for any point in the method
+ # CGRect.infinite.contains?(point). CGRectInfinite returns `true` for any
+ # (sensible) point, so we'll go with that instead
+ CGRectInfinite.dup
+ end
- def self.infinite
- # This actually returns the not-very-infinite value of:
- # [[-1.7014114289565e+38, -1.7014114289565e+38], [3.402822857913e+38, 3.402822857913e+38]]
- # originally this method returned [[-Infinity, -Infinity], [Infinity, Infinity]],
- # but that rect ended up returning `false` for any point in the method
- # CGRect.infinite.contains?(point). CGRectInfinite returns `true` for any
- # (sensible) point, so we'll go with that instead
- CGRectInfinite.dup
- end
+ # OPTIONS: [:above, :below, :left_of, :right_of, :margins]
+ # :margins is array of [top, right, bottom, left]
+ # EX CGRect.layout(rect1, above: rect2, left_of: rect3, margins: [0, 10, 20, 0])
+ def layout(rect1, options)
+ if options.empty?
+ p "No options provided in #{self.class}.layout"
+ return rect1
+ end
- # OPTIONS: [:above, :below, :left_of, :right_of, :margins]
- # :margins is array of [top, right, bottom, left]
- # EX CGRect.layout(rect1, above: rect2, left_of: rect3, margins: [0, 10, 20, 0])
- def self.layout(rect1, options)
- if options.empty?
- p "No options provided in #{self.class}.layout"
- return rect1
- end
+ rect = self.new
+ rect.size = rect1.size
- rect = self.new
- rect.size = rect1.size
+ options[:margins] ||= []
+ margins = {}
+ [:top, :right, :bottom, :left].each_with_index do |margin, index|
+ margins[margin] = options[:margins][index] || 0
+ end
- options[:margins] ||= []
- margins = {}
- [:top, :right, :bottom, :left].each_with_index do |margin, index|
- margins[margin] = options[:margins][index] || 0
- end
+ rect.y = options[:above].up(rect.height + margins[:bottom]).y if options[:above]
+ rect.y = options[:below].below(margins[:top]).y if options[:below]
- rect.y = options[:above].up(rect.height + margins[:bottom]).y if options[:above]
- rect.y = options[:below].below(margins[:top]).y if options[:below]
+ rect.x = options[:left_of].left(rect.width + margins[:right]).x if options[:left_of]
+ rect.x = options[:right_of].beside(margins[:left]).x if options[:right_of]
- rect.x = options[:left_of].left(rect.width + margins[:right]).x if options[:left_of]
- rect.x = options[:right_of].beside(margins[:left]).x if options[:right_of]
+ rect
+ end
- rect
end
# bounds
def min_x
CGRectGetMinX(self)
@@ -97,48 +100,64 @@
def max_y
CGRectGetMaxY(self)
end
# getters/setters
- def x(setter = nil)
+ def x(setter=nil, options=nil)
if setter
- return CGRect.new([setter, self.origin.y], self.size)
+ rect = CGRect.new([setter, self.origin.y], self.size)
+ if options
+ return rect.apply(options)
+ end
+ return rect
end
- min_x
+ return min_x
end
def x=(_x)
self.origin.x = _x
end
- def y(setter = nil)
+ def y(setter=nil, options=nil)
if setter
- return CGRect.new([self.origin.x, setter], self.size)
+ rect = CGRect.new([self.origin.x, setter], self.size)
+ if options
+ return rect.apply(options)
+ end
+ return rect
end
- min_y
+ return min_y
end
def y=(_y)
self.origin.y = _y
end
- def width(setter = nil)
+ def width(setter=nil, options=nil)
if setter
- return CGRect.new(self.origin, [setter, self.size.height])
+ rect = CGRect.new(self.origin, [setter, self.size.height])
+ if options
+ return rect.apply(options)
+ end
+ return rect
end
- CGRectGetWidth(self)
+ return CGRectGetWidth(self)
end
def width=(_width)
self.size.width = _width
end
- def height(setter = nil)
+ def height(setter=nil, options=nil)
if setter
- return CGRect.new(self.origin, [self.size.width, setter])
+ rect = CGRect.new(self.origin, [self.size.width, setter])
+ if options
+ return rect.apply(options)
+ end
+ return rect
end
- CGRectGetHeight(self)
+ return CGRectGetHeight(self)
end
def height=(_height)
self.size.height = _height
end
@@ -215,106 +234,180 @@
NSLog("Using the default value of `0` in `CGRect#left` is deprecated.")
dist = 0
end
raise "You must specify an amount in `CGRect#left`" unless dist.is_a?(Numeric)
- options[:left] = dist
- self.apply(options)
+ self.apply({
+ left: dist
+ }.merge(options))
end
def right(dist=nil, options={})
if dist.nil?
NSLog("Using the default value of `0` in `CGRect#right` is deprecated.")
dist = 0
end
raise "You must specify an amount in `CGRect#right`" unless dist.is_a?(Numeric)
- options[:right] = dist
- self.apply(options)
+ self.apply({
+ right: dist
+ }.merge(options))
end
def up(dist=nil, options={})
if dist.nil?
NSLog("Using the default value of `0` in `CGRect#up` is deprecated.")
dist = 0
end
raise "You must specify an amount in `CGRect#up`" unless dist.is_a?(Numeric)
- options[:up] = dist
- self.apply(options)
+ self.apply({
+ up: dist
+ }.merge(options))
end
def down(dist=nil, options={})
if dist.nil?
NSLog("Using the default value of `0` in `CGRect#down` is deprecated.")
dist = 0
end
raise "You must specify an amount in `CGRect#down`" unless dist.is_a?(Numeric)
- options[:down] = dist
- self.apply(options)
+ self.apply({
+ down: dist
+ }.merge(options))
end
def wider(dist, options={})
raise "You must specify an amount in `CGRect#wider`" unless dist.is_a?(Numeric)
- options[:wider] = dist
- self.apply(options)
+ self.apply({
+ wider: dist
+ }.merge(options))
end
def thinner(dist, options={})
raise "You must specify an amount in `CGRect#thinner`" unless dist.is_a?(Numeric)
- options[:thinner] = dist
- self.apply(options)
+ self.apply({
+ thinner: dist
+ }.merge(options))
end
def taller(dist, options={})
raise "You must specify an amount in `CGRect#taller`" unless dist.is_a?(Numeric)
- options[:taller] = dist
- self.apply(options)
+ self.apply({
+ taller: dist
+ }.merge(options))
end
def shorter(dist, options={})
raise "You must specify an amount in `CGRect#shorter`" unless dist.is_a?(Numeric)
- options[:shorter] = dist
- self.apply(options)
+ self.apply({
+ shorter: dist
+ }.merge(options))
end
# adjacent rects
def above(margin = 0, options={})
margin, options = 0, margin if margin.is_a?(NSDictionary)
height = options[:height] || self.size.height
- options[:up] = height + margin
- self.apply(options)
+ self.apply({
+ up: height + margin
+ }.merge(options))
end
def below(margin = 0, options={})
margin, options = 0, margin if margin.is_a?(NSDictionary)
- options[:down] = self.size.height + margin
- self.apply(options)
+ self.apply({
+ down: self.size.height + margin
+ }.merge(options))
end
def before(margin = 0, options={})
margin, options = 0, margin if margin.is_a?(NSDictionary)
width = options[:width] || self.size.width
- options[:left] = width + margin
- self.apply(options)
+ self.apply({
+ left: width + margin
+ }.merge(options))
end
def beside(margin = 0, options={})
margin, options = 0, margin if margin.is_a?(NSDictionary)
- options[:right] = self.size.width + margin
- self.apply(options)
+ self.apply({
+ right: self.size.width + margin
+ }.merge(options))
end
+ # these methods create a rect INSIDE the receiver
+
+ # Create a rect inside the receiver, on the left side. If `margin` is
+ # supplied, the rect will be moved that number of points to the right.
+ def from_left(options={})
+ width = options[:width]
+ margin = options.delete(:margin) || 0
+ raise "You must specify a width in `CGRect#from_left`" unless width
+ offset = cgrect_offset(options.delete(:absolute))
+ self.apply({
+ x: offset.x + margin,
+ y: offset.y,
+ height: self.size.height,
+ width: width
+ }.merge(options))
+ end
+
+ # Create a rect inside the receiver, on the right side. If `margin` is
+ # supplied, the rect will be moved that number of points to the left.
+ def from_right(options={})
+ width = options[:width]
+ margin = options.delete(:margin) || 0
+ raise "You must specify a width in `CGRect#from_right`" unless width
+ offset = cgrect_offset(options.delete(:absolute))
+ self.apply({
+ x: offset.x + self.size.width - width - margin,
+ y: offset.y,
+ height: self.size.height,
+ width: width
+ }.merge(options))
+ end
+
+ # Create a rect inside the receiver, on the top side. If `margin` is
+ # supplied, the rect will be moved that number of points down.
+ def from_top(options={})
+ height = options[:height]
+ margin = options.delete(:margin) || 0
+ raise "You must specify a height in `CGRect#from_top`" unless height
+ offset = cgrect_offset(options.delete(:absolute))
+ self.apply({
+ x: offset.x,
+ y: offset.y + margin,
+ width: self.size.width,
+ height: height
+ }.merge(options))
+ end
+
+ # Create a rect inside the receiver, on the bottom side. If `margin` is
+ # supplied, the rect will be moved that number of points up.
+ def from_bottom(options={})
+ height = options[:height]
+ margin = options.delete(:margin) || 0
+ raise "You must specify a height in `CGRect#from_bottom`" unless height
+ offset = cgrect_offset(options.delete(:absolute))
+ self.apply({
+ x: offset.x,
+ y: offset.y + self.size.height - height - margin,
+ width: self.size.width,
+ height: height
+ }.merge(options))
+ end
+
# positions
private
def cgrect_offset(absolute)
if absolute
CGPoint.new(self.min_x, self.min_y)
@@ -434,30 +527,32 @@
end
return rect
end
alias grow_right wider
- def grow_left(amount, options=nil)
+ def grow_left(amount, options={})
raise "You must specify an amount in `CGRect#grow_left`" unless amount.is_a?(Numeric)
- options[:grow_left] = amount
- self.apply(options)
+ self.apply({
+ grow_left: amount
+ }.merge(options))
end
alias grow_down taller
- def grow_up(amount, options=nil)
+ def grow_up(amount, options={})
raise "You must specify an amount in `CGRect#grow_up`" unless amount.is_a?(Numeric)
- options[:grow_up] = amount
- self.apply(options)
+ self.apply({
+ grow_up: amount
+ }.merge(options))
end
- def grow_width(amount, options=nil)
+ def grow_width(amount, options={})
return self.grow([amount, 0], options)
end
- def grow_height(amount, options=nil)
+ def grow_height(amount, options={})
return self.grow([0, amount], options)
end
def shrink(size, options=nil)
if size.is_a? Numeric
@@ -472,19 +567,21 @@
alias shrink_left thinner
def shrink_right(amount, options={})
raise "You must specify an amount in `CGRect#shrink_right`" unless amount.is_a?(Numeric)
- options[:shrink_right] = amount
- self.apply(options)
+ self.apply({
+ shrink_right: amount
+ }.merge(options))
end
alias shrink_up shorter
def shrink_down(amount, options={})
raise "You must specify an amount in `CGRect#shrink_down`" unless amount.is_a?(Numeric)
- options[:shrink_down] = amount
- self.apply(options)
+ self.apply({
+ shrink_down: amount
+ }.merge(options))
end
def shrink_width(amount, options={})
return self.shrink([amount, 0], options)
end