Class: MotionKit::Constraint

Inherits:
Object
  • Object
show all
Defined in:
lib/motion-kit-cocoa/constraints/constraint.rb

Direct Known Subclasses

CompoundConstraint

Constant Summary collapse

Priorities =
{
  required: 1000,  # NSLayoutPriorityRequired
  high: 750,  # NSLayoutPriorityDefaultHigh
  medium: 500,
  low: 250,  # NSLayoutPriorityDefaultLow
}
Relationships =

NSLayoutPriorityDefaultLow

{
  equal: NSLayoutRelationEqual,
  lte: NSLayoutRelationLessThanOrEqual,
  gte: NSLayoutRelationGreaterThanOrEqual,
}
Attributes =
{
  none: NSLayoutAttributeNotAnAttribute,
  left: NSLayoutAttributeLeft,
  right: NSLayoutAttributeRight,
  top: NSLayoutAttributeTop,
  bottom: NSLayoutAttributeBottom,
  leading: NSLayoutAttributeLeading,
  trailing: NSLayoutAttributeTrailing,
  width: NSLayoutAttributeWidth,
  height: NSLayoutAttributeHeight,
  center_x: NSLayoutAttributeCenterX,
  center_y: NSLayoutAttributeCenterY,
  baseline: NSLayoutAttributeBaseline,
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target, attribute = nil, relationship) ⇒ Constraint

Returns a new instance of Constraint.



46
47
48
49
50
51
52
53
54
55
56
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 46

def initialize(target, attribute=nil, relationship)
  @target = target
  @attribute = attribute
  @attribute2 = attribute
  @relative_to = nil
  @relationship = relationship
  @multiplier = 1
  @constant = 0
  @priority = nil
  @compare_flag = false
end

Instance Attribute Details

#attributeObject

Returns the value of attribute attribute.



11
12
13
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 11

def attribute
  @attribute
end

#attribute2Object

Returns the value of attribute attribute2.



14
15
16
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 14

def attribute2
  @attribute2
end

#constantObject

Returns the value of attribute constant.



16
17
18
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 16

def constant
  @constant
end

#identifier(identifier = nil) ⇒ Object Also known as: identified_by



234
235
236
237
238
239
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 234

def identifier(identifier=nil)
  return @identifier if identifier.nil?

  @identifier = identifier
  self
end

#multiplierObject

Returns the value of attribute multiplier.



15
16
17
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 15

def multiplier
  @multiplier
end

#priority(priority = nil) ⇒ Object



227
228
229
230
231
232
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 227

def priority(priority=nil)
  return @priority if priority.nil?

  @priority = priority
  self
end

#relationshipObject

Returns the value of attribute relationship.



12
13
14
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 12

def relationship
  @relationship
end

#relative_toObject

Returns the value of attribute relative_to.



13
14
15
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 13

def relative_to
  @relative_to
end

#targetObject

Returns the value of attribute target.



10
11
12
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 10

def target
  @target
end

Class Method Details

.attribute_lookup(attribute) ⇒ Object



317
318
319
320
321
322
323
324
325
326
327
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 317

def attribute_lookup(attribute)
  if attribute.is_a? Fixnum
    return attribute
  end

  unless Attributes.key? attribute
    raise InvalidAttributeError.new("Unsupported attribute #{attribute.inspect}")
  end

  Attributes[attribute]
end

.attribute_reverse(attribute) ⇒ Object



353
354
355
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 353

def attribute_reverse(attribute)
  Attributes.key(attribute) || :none
end

.axis_lookup(axis) ⇒ Object



281
282
283
284
285
286
287
288
289
290
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 281

def axis_lookup(axis)
  case axis
  when :horizontal
    UILayoutConstraintAxisHorizontal
  when :vertical
    UILayoutConstraintAxisVertical
  else
    axis
  end
end

.calculate?(value) ⇒ Boolean

Returns:

  • (Boolean)


361
362
363
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 361

def calculate?(value)
  value.is_a?(String)
end

.constant?(value) ⇒ Boolean

Returns:

  • (Boolean)


365
366
367
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 365

def constant?(value)
  value.is_a?(Numeric) || value.is_a?(Hash) || value.is_a?(Array)
end

.orientation_lookup(orientation) ⇒ Object



292
293
294
295
296
297
298
299
300
301
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 292

def orientation_lookup(orientation)
  case orientation
  when :horizontal
    NSLayoutConstraintOrientationHorizontal
  when :vertical
    NSLayoutConstraintOrientationVertical
  else
    orientation
  end
end

.priority_lookup(priority) ⇒ Object



329
330
331
332
333
334
335
336
337
338
339
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 329

def priority_lookup(priority)
  if priority.is_a? Fixnum
    return priority
  end

  unless Priorities.key? priority
    raise InvalidPriorityError.new("Unsupported priority #{priority.inspect}")
  end

  Priorities[priority]
end

.relationship_lookup(relationship) ⇒ Object



341
342
343
344
345
346
347
348
349
350
351
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 341

def relationship_lookup(relationship)
  if relationship.is_a? Fixnum
    return relationship
  end

  unless Relationships.key? relationship
    raise InvalidRelationshipError.new("Unsupported relationship #{relationship.inspect}")
  end

  Relationships[relationship]
end

.relationship_reverse(relationship) ⇒ Object



357
358
359
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 357

def relationship_reverse(relationship)
  Relationships.key(relationship)
end

.view_lookup(layout, view, target) ⇒ Object



303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 303

def view_lookup(layout, view, target)
  if ! target || target.is_a?(MotionKit.base_view_class)
    target
  elsif target.is_a?(ConstraintPlaceholder)
    target.resolve(layout)
  elsif target == :self
    view
  elsif target == :superview
    view.superview
  else
    layout.get_view(target)
  end
end

Instance Method Details

#<=(compare) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 100

def <=(compare)
  if @compare_flag
    if @relationship && Constraint.relationship_lookup(@relationship) != NSLayoutRelationLessThanOrEqual
      raise InvalidRelationshipError.new("You cannot use `.is <=` on a constraint that is already defined as #{@relationship}")
    end

    lte(compare)

    self
  else
    super
  end
end

#==(compare) ⇒ Object



76
77
78
79
80
81
82
83
84
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 76

def ==(compare)
  if @compare_flag
    equals(compare)

    self
  else
    super
  end
end

#>=(compare) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 86

def >=(compare)
  if @compare_flag
    if @relationship && Constraint.relationship_lookup(@relationship) != NSLayoutRelationGreaterThanOrEqual
      raise InvalidRelationshipError.new("You cannot use `.is >=` on a constraint that is already defined as #{@relationship}")
    end

    gte(compare)

    self
  else
    super
  end
end

#divided_by(multiplier) ⇒ Object



204
205
206
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 204

def divided_by(multiplier)
  times 1.0/multiplier
end

#equals(target, attribute2 = nil) ⇒ Object Also known as: is_equal_to, equal_to



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 114

def equals(target, attribute2=nil)
  self.relationship ||= :equal
  if Constraint.constant?(target)
    self.constant = target
  elsif Constraint.calculate?(target)
    calc = Calculator.scan(target)
    self.multiplier = calc.factor
    self.constant = calc.constant || 0
  else
    self.relative_to = target
    if attribute2
      self.attribute2 = attribute2
    end
  end
  @compare_flag = false
  self
end

#gte(target, attribute2 = nil) ⇒ Object Also known as: is_at_least, at_least



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 154

def gte(target, attribute2=nil)
  self.relationship = :gte
  if Constraint.constant?(target)
    self.constant = target
  elsif Constraint.calculate?(target)
    calc = Calculator.scan(target)
    self.multiplier = calc.factor
    self.constant = calc.constant || 0
  else
    self.relative_to = target
    if attribute2
      self.attribute2 = attribute2
    end
  end
  @compare_flag = false
  self
end

#is(value = nil) ⇒ Object

like ‘equals`, but also sets `compare_flag` to true, so you can use ==, <=, and >=

Examples:

x.is(10)
x.is(10).priority(:required)
x.is == 10
(x.is == 10).priority :required
width.is >= 100
height.is <= 200


68
69
70
71
72
73
74
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 68

def is(value=nil)
  if value
    self.equals(value)
  end
  @compare_flag = true
  self
end

#lte(target, attribute2 = nil) ⇒ Object Also known as: is_at_most, at_most



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 134

def lte(target, attribute2=nil)
  self.relationship = :lte
  if Constraint.constant?(target)
    self.constant = target
  elsif Constraint.calculate?(target)
    calc = Calculator.scan(target)
    self.multiplier = calc.factor
    self.constant = calc.constant || 0
  else
    self.relative_to = target
    if attribute2
      self.attribute2 = attribute2
    end
  end
  @compare_flag = false
  self
end

#minus(constant) ⇒ Object



223
224
225
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 223

def minus(constant)
  plus -constant
end

#of(target, attribute2 = nil) ⇒ Object

width.is(‘100%’).of(:view, :width)



175
176
177
178
179
180
181
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 175

def of(target, attribute2=nil)
  self.relative_to = target
  if attribute2
    self.attribute2 = attribute2
  end
  self
end

#plus(constant) ⇒ Object

If no relationship has been set, the “use case” here is:

c.plus(10).equals(:view, :x)

Which is the same as

c.equals(:view, :x).minus(10)


215
216
217
218
219
220
221
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 215

def plus(constant)
  unless self.relationship
    constant = -constant
  end
  self.constant += constant
  self
end

#resolve_all(layout, view) ⇒ Object



250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 250

def resolve_all(layout, view)
  @resolved ||= begin
    item = Constraint.view_lookup(layout, view, self.target)
    rel_item = Constraint.view_lookup(layout, view, self.relative_to)
    relationship = Constraint.relationship_lookup(self.relationship)
    attribute1 = Constraint.attribute_lookup(self.attribute)
    attribute2 = Constraint.attribute_lookup(self.attribute2)

    nsconstraint = NSLayoutConstraint.constraintWithItem(item,
      attribute: attribute1,
      relatedBy: relationship,
      toItem: rel_item,
      attribute: attribute2,
      multiplier: self.multiplier,
      constant: self.constant
      )

    if self.priority
      nsconstraint.priority = Constraint.priority_lookup(self.priority)
    end

    if self.identifier
      nsconstraint.setIdentifier(self.identifier)
    end

    [nsconstraint]
  end
end

#times(multiplier) ⇒ Object



199
200
201
202
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 199

def times(multiplier)
  self.multiplier *= multiplier
  self
end

#update_constraintObject



242
243
244
245
246
247
248
# File 'lib/motion-kit-cocoa/constraints/constraint.rb', line 242

def update_constraint
  if @resolved
    constraint = @resolved[0]

    constraint.constant = self.constant
  end
end