Console::Geom

console 0.2.0 · app/console/geom.rb · 223 lines · view source

Console::Geom -- rect/point helpers.

Everything here is pure: it takes numbers and hashes and returns numbers or hashes. Nothing touches DragonRuby's outputs.

NOTE: DragonRuby gives engine-built hashes (eg. Layout.rect) a center key, but a plain {x:, y:, w:, h:} hash returns nil for .center. So every helper in this library uses Console::Geom.center instead of .center so that it works uniformly on hand-built hashes.

def rect(x, y, w, h)
line 14
def center(r)

The geometric centre of a rect.

This is the middle of the box, NOT the anchor point: DragonRuby's own Layout.rect reports a center of that shape, and mixing the two up is the classic off-by-half-a-sprite bug. Anchors describe where x/y sit, so they deliberately do not affect the centre.

def center_x(r)
line 29
def center_y(r)
line 33
def top(r)
line 41
def area(r)
line 45
def inset(r, amount)

Shrink (or grow, with negative padding) a rect on all sides.

def inset_xy(r, dx, dy)
line 54
def columns(r, count, gap = 0)

Split a rect into a row of count columns, leaving gap px between. Used by UI::Bar and UI::Menu so spacing logic lives in one place.

def rows(r, count, gap = 0)
line 77
def place(bounds, spec)

Position a rect inside bounds using fractional placement. This is the workhorse behind every place: option in the UI toolkit.

place(bounds, {x: 0.5, y: 0.5, anchor_x: 0.5, anchor_y: 0.5})
def screen_rect(grid)

The full screen as a rect, using the live logical grid. Preferred over Layout.allscreen_rect, which does not track the actual viewport.

def from_grid_pct(grid, x_pct, y_pct, w_pct = 1.0, h_pct = 1.0)
line 116
def safe_rect(grid, margin)

Margin all four edges of the screen inward.

def clamp_inside(r, bounds)

Clamp a rect so it fits inside bounds without changing its size.

def contains?(r, px, py)
line 136
def contain(inner, outer)

Shrink a rect until it fits a square, preserving aspect ratio. Handy for letterboxing artwork inside a panel.

def perc(value, max)

Fraction of max that value represents, clamped to 0..1.

A max of zero (or nil) means "no scale to divide by", and yields 0 rather than Infinity/NaN. Shared by Draw#bar and UI#bar so the two can never disagree.

top-down layout

def top(y, grid = nil)

DragonRuby's origin is bottom-left, which is correct for game worlds but awkward for menus: counting upward from the bottom edge of a list is nobody's mental model. These helpers think from the top of the screen, which is how UI is normally specified. Convert "y pixels down from the top of the screen" into the bottom-left origin y that DragonRuby expects.

def anchored_top(x, top_y, w, h, grid = nil)

Build a rect whose TOP edge sits top_y pixels below the top of the screen. This is the shape you want for UI: "this panel starts 120px from the top", instead of the far more error-prone "y = screen_h - 120 - h".

def spec_top(opts, w, h, grid = nil)

Read a rect out of a widget/draw spec, honouring either y: (DragonRuby bottom-left) or top: (distance from the top of the screen).

Returns nil when the spec carries neither, so callers can tell "anchored to the top" from "anchored to the bottom".

def row_from_top(top_y, index, width, line_h, gap = 0)

Lay out count rows downward from the top, returning the rect for row index. Rows are as tall as they need to be for line_h.

def strip(top_y, h, width = nil)

A full-width strip at top_y, h tall, running from the left edge.

def distance(a, b)
line 215
def angle(a, b)
line 219