57 lines
2.5 KiB
C++
57 lines
2.5 KiB
C++
#pragma once
|
||
// rect.h — the ONE concrete pixel rectangle (Q-W1, T2-05 ≡ T4-21).
|
||
//
|
||
// Before Q-W1 the codebase carried 12+ byte-identical {x, y, width, height} structs
|
||
// (ButtonRect / FooterRect / CellRect / KitBox / ...) plus a second LTRB grammar on
|
||
// the VST side (editor_geometry's left/top/right/bottom Rect). This is the single
|
||
// owner: one CONCRETE type (deliberately NOT a template — the role types differed in
|
||
// name only, so a template would model nothing), with per-role aliases at the old
|
||
// definition sites so call sites keep their semantic names
|
||
// (`using ButtonRect = ui::Rect;`).
|
||
//
|
||
// Grammar: XYWH storage (the majority grammar — every extension role struct), with
|
||
// right()/bottom() accessors and an ltrb() factory so the former LTRB call sites
|
||
// convert mechanically. Half-open on both axes: a rect covers
|
||
// [x, x+width) × [y, y+height) — the same convention LICE/SWELL RECTs use, and the
|
||
// one every hitTest* in the codebase already implements.
|
||
//
|
||
// PURE MODULE: standard library only. Header-only; behavior is covered by the role
|
||
// modules' own test executables (prune_button / footer_bar / bank_grid / ... and the
|
||
// instrument-ui suites), which exercise every alias against these semantics.
|
||
|
||
namespace reasampler::ui {
|
||
|
||
struct Rect {
|
||
int x = 0;
|
||
int y = 0;
|
||
int width = 0;
|
||
int height = 0;
|
||
|
||
// Exclusive edges (half-open convention).
|
||
int right() const { return x + width; }
|
||
int bottom() const { return y + height; }
|
||
|
||
// A zero-or-negative-area rect means "not placed / suppressed": the caller must
|
||
// not draw or hit-test it (the shared graceful-degradation contract).
|
||
bool empty() const { return width <= 0 || height <= 0; }
|
||
|
||
// The former LTRB grammar's constructor (editor_geometry and friends): edges in,
|
||
// extents stored. right/bottom exclusive, matching right()/bottom().
|
||
static Rect ltrb(int left, int top, int right, int bottom) {
|
||
return Rect{left, top, right - left, bottom - top};
|
||
}
|
||
|
||
bool operator==(const Rect& o) const {
|
||
return x == o.x && y == o.y && width == o.width && height == o.height;
|
||
}
|
||
bool operator!=(const Rect& o) const { return !(*this == o); }
|
||
};
|
||
|
||
// True iff (px, py) falls inside r under the half-open convention. An empty rect
|
||
// contains nothing, so a suppressed affordance can never claim a click.
|
||
inline bool contains(const Rect& r, int px, int py) {
|
||
return px >= r.x && px < r.x + r.width && py >= r.y && py < r.y + r.height;
|
||
}
|
||
|
||
} // namespace reasampler::ui
|