sdl3/src/Ui/Widget/Checkbox.php
2025-11-17 13:28:24 +01:00

125 lines
3.7 KiB
PHP

<?php
namespace PHPNative\Ui\Widget;
use PHPNative\Framework\TextRenderer;
use PHPNative\Tailwind\Style\Text as TextStyle;
use PHPNative\Ui\Component;
class Checkbox extends Component
{
private bool $checked = false;
private $onChange = null;
private string $labelText = '';
public function __construct(
string $label = '',
bool $checked = false,
string $style = '',
$onChange = null,
) {
parent::__construct($style);
$this->checked = $checked;
$this->onChange = $onChange;
$this->labelText = $label;
}
public function isChecked(): bool
{
return $this->checked;
}
public function setChecked(bool $checked): void
{
$this->checked = $checked;
if ($this->onChange !== null) {
($this->onChange)($checked);
}
}
public function setOnChange(callable $onChange): void
{
$this->onChange = $onChange;
}
public function layout(null|TextRenderer $textRenderer = null): void
{
parent::layout($textRenderer);
// Force a compact, fixed size for the checkbox
$checkboxSize = 20;
$this->viewport->width = $checkboxSize;
$this->viewport->height = $checkboxSize;
$this->contentViewport->width = $checkboxSize;
$this->contentViewport->height = $checkboxSize;
}
public function handleMouseClick(float $mouseX, float $mouseY, int $button): bool
{
// Check if click is within checkbox bounds (not label)
$checkboxSize = 20;
if (
$mouseX >= $this->viewport->x &&
$mouseX <= ($this->viewport->x + $checkboxSize) &&
$mouseY >= $this->viewport->y &&
$mouseY <= ($this->viewport->y + $checkboxSize)
) {
$this->checked = !$this->checked;
if ($this->onChange !== null) {
($this->onChange)($this->checked);
}
return true;
}
return parent::handleMouseClick($mouseX, $mouseY, $button);
}
public function render(&$renderer, null|TextRenderer $textRenderer = null): void
{
$checkboxSize = 20;
// Draw checkbox border
sdl_set_render_draw_color($renderer, 156, 163, 175, 255); // Gray-400
sdl_render_fill_rect($renderer, [
'x' => $this->viewport->x,
'y' => $this->viewport->y,
'w' => $checkboxSize,
'h' => $checkboxSize,
]);
// Draw white background
sdl_set_render_draw_color($renderer, 255, 255, 255, 255);
sdl_render_fill_rect($renderer, [
'x' => $this->viewport->x + 2,
'y' => $this->viewport->y + 2,
'w' => $checkboxSize - 4,
'h' => $checkboxSize - 4,
]);
// Draw checkmark if checked
if ($this->checked) {
sdl_set_render_draw_color($renderer, 37, 99, 235, 255); // Blue-600
sdl_render_fill_rect($renderer, [
'x' => $this->viewport->x + 4,
'y' => $this->viewport->y + 4,
'w' => $checkboxSize - 8,
'h' => $checkboxSize - 8,
]);
}
// Render label text if present
if (!empty($this->labelText) && $textRenderer !== null && $textRenderer->isInitialized()) {
$textX = $this->viewport->x + $checkboxSize + 8; // Checkbox + margin
$textY = $this->viewport->y + 2;
$textStyle = $this->computedStyles[\PHPNative\Tailwind\Style\Text::class] ?? new TextStyle();
$textRenderer->setColor(0, 0, 0, 1.0); // Black
$textRenderer->drawText($this->labelText, (int) $textX, (int) $textY, $textStyle->size);
}
}
}