Class: Tuile::Component::Layout::Clamp

Inherits:
Object
  • Object
show all
Includes:
Constraint
Defined in:
lib/tuile/component/layout.rb,
sig/tuile.rbs

Overview

A Percent whose cells are bounded by #range — what Percent#clamp builds, and the way to say "half the width, but never more than 60 columns":

add(system, Percent[50].clamp(..60))

Only a Percent: a Fixed is already exact, one range already carries both bounds, and an Expand's share depends on its siblings, so capping it would have to hand cells back to them.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(percent:, range:) ⇒ Clamp

@param percent

@param range — see Percent#clamp.

Parameters:

  • percent: (Percent)
  • range: (::Range[untyped])


184
185
186
187
188
189
# File 'lib/tuile/component/layout.rb', line 184

def initialize(percent:, range:)
  raise ArgumentError, "Clamp expects a Percent, got #{percent.inspect}" unless percent.is_a?(Percent)

  validate_range(range)
  super
end

Instance Attribute Details

#percent ⇒ Percent (readonly)

@return — the share being bounded.

Returns:



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/tuile/component/layout.rb', line 178

class Clamp < Data.define(:percent, :range)
  include Constraint

  # @param percent [Percent]
  # @param range [Range] see {Percent#clamp}.
  # @raise [ArgumentError] unless `percent` is a {Percent}; see {Percent#clamp}.
  def initialize(percent:, range:)
    raise ArgumentError, "Clamp expects a Percent, got #{percent.inspect}" unless percent.is_a?(Percent)

    validate_range(range)
    super
  end

  # @api private
  # @param available [Integer]
  # @return [Integer] {#percent}'s cells, clamped to {#range}.
  def resolve(available) = percent.resolve(available).clamp(range)

  private

  # @param range [Object]
  # @raise [ArgumentError] unless an inclusive Range of non-negative
  #   Integers (or `nil`s), ascending, bounded on at least one end.
  # @return [void]
  def validate_range(range)
    valid = range.is_a?(Range) && !range.exclude_end? &&
            [range.begin, range.end].all? { _1.nil? || (_1.is_a?(Integer) && !_1.negative?) } &&
            !(range.begin.nil? && range.end.nil?) &&
            (range.begin.nil? || range.end.nil? || range.begin <= range.end)
    return if valid

    raise ArgumentError, "clamp expects an inclusive Range of non-negative Integers bounded on " \
                         "at least one end, like ..60 or 20..40, got #{range.inspect}"
  end
end

#range ⇒ ::Range[untyped] (readonly)

@return — the inclusive bounds, in cells.

Returns:

  • (::Range[untyped])


178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/tuile/component/layout.rb', line 178

class Clamp < Data.define(:percent, :range)
  include Constraint

  # @param percent [Percent]
  # @param range [Range] see {Percent#clamp}.
  # @raise [ArgumentError] unless `percent` is a {Percent}; see {Percent#clamp}.
  def initialize(percent:, range:)
    raise ArgumentError, "Clamp expects a Percent, got #{percent.inspect}" unless percent.is_a?(Percent)

    validate_range(range)
    super
  end

  # @api private
  # @param available [Integer]
  # @return [Integer] {#percent}'s cells, clamped to {#range}.
  def resolve(available) = percent.resolve(available).clamp(range)

  private

  # @param range [Object]
  # @raise [ArgumentError] unless an inclusive Range of non-negative
  #   Integers (or `nil`s), ascending, bounded on at least one end.
  # @return [void]
  def validate_range(range)
    valid = range.is_a?(Range) && !range.exclude_end? &&
            [range.begin, range.end].all? { _1.nil? || (_1.is_a?(Integer) && !_1.negative?) } &&
            !(range.begin.nil? && range.end.nil?) &&
            (range.begin.nil? || range.end.nil? || range.begin <= range.end)
    return if valid

    raise ArgumentError, "clamp expects an inclusive Range of non-negative Integers bounded on " \
                         "at least one end, like ..60 or 20..40, got #{range.inspect}"
  end
end

Instance Method Details

#resolve(available) ⇒ Integer

@param available

@return — #percent's cells, clamped to #range.

Parameters:

  • available (Integer)

Returns:

  • (Integer)


194
# File 'lib/tuile/component/layout.rb', line 194

def resolve(available) = percent.resolve(available).clamp(range)

#validate_range(range) ⇒ void

This method returns an undefined value.

@param range

Parameters:

  • range (Object)


202
203
204
205
206
207
208
209
210
211
# File 'lib/tuile/component/layout.rb', line 202

def validate_range(range)
  valid = range.is_a?(Range) && !range.exclude_end? &&
          [range.begin, range.end].all? { _1.nil? || (_1.is_a?(Integer) && !_1.negative?) } &&
          !(range.begin.nil? && range.end.nil?) &&
          (range.begin.nil? || range.end.nil? || range.begin <= range.end)
  return if valid

  raise ArgumentError, "clamp expects an inclusive Range of non-negative Integers bounded on " \
                       "at least one end, like ..60 or 20..40, got #{range.inspect}"
end