Mouse-zone tracker for clickable UIs
Wrap rendered chunks with named markers, let CandyZone discover their bounding boxes, then ask zones whether a MouseMsg fell inside them. Markers are APC escape sequences โ terminals ignore them, so they don't affect layout.
composer require candycore/candy-zone
use CandyCore\Zone\Manager;
use CandyCore\Sprinkles\Style;
$z = Manager::newGlobal();
$btnOk = $z->mark('btn:ok', Style::new()->padding(0, 2)->render('OK'));
$btnCancel = $z->mark('btn:cancel', Style::new()->padding(0, 2)->render('Cancel'));
$frame = $btnOk . ' ' . $btnCancel;
// Scan once before printing โ Manager records marker positions and strips them.
$displayable = $z->scan($frame);
echo $displayable;
// Later, when a MouseMsg arrives:
if ($z->get('btn:ok')?->inBounds($mouseMsg)) {
// ...
}
$z->mark('btn:ok', $rendered) wraps the chunk in invisible APC delimiters.$z->scan($frame) records every marker's 1-based cell bounding box and strips them in one pass.$z->get('btn:ok')?->inBounds($mouseMsg) โ clean predicate, no coordinate math.view() call rescans, every MouseMsg routes.