125 lines
3.7 KiB
PHP
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);
|
|
}
|
|
}
|
|
}
|