138 lines
4.8 KiB
PHP
138 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace PHPNative\Ui\Widget;
|
|
|
|
use PHPNative\Framework\TextRenderer;
|
|
use PHPNative\Tailwind\Style\Padding;
|
|
use PHPNative\Tailwind\Style\Text;
|
|
use PHPNative\Ui\Component;
|
|
|
|
class Label extends Component
|
|
{
|
|
private int $intrinsicWidth = 0;
|
|
private int $intrinsicHeight = 0;
|
|
private mixed $textTexture = null;
|
|
private int $textWidth = 0;
|
|
private int $textHeight = 0;
|
|
|
|
public function __construct(
|
|
public string $text = '',
|
|
public string $style = '',
|
|
) {
|
|
parent::__construct($style);
|
|
}
|
|
|
|
public function setText(string $text): void
|
|
{
|
|
if ($this->text === $text) {
|
|
return;
|
|
}
|
|
|
|
$this->text = $text;
|
|
$this->clearTextTexture();
|
|
|
|
// $this->markDirty(true);
|
|
}
|
|
|
|
public function layout(null|TextRenderer $textRenderer = null): void
|
|
{
|
|
// Call parent to compute styles and setup viewports
|
|
parent::layout($textRenderer);
|
|
|
|
// Measure text to get intrinsic size
|
|
if ($textRenderer !== null && $textRenderer->isInitialized()) {
|
|
$textStyle = $this->computedStyles[Text::class] ?? new Text();
|
|
[$this->intrinsicWidth, $this->intrinsicHeight] = $textRenderer->measureText($this->text, $textStyle->size);
|
|
// Adjust viewport to fit text if no explicit size
|
|
if (!isset($this->computedStyles[\PHPNative\Tailwind\Style\Width::class])) {
|
|
$this->viewport->width = $this->intrinsicWidth;
|
|
$this->contentViewport->width = $this->intrinsicWidth;
|
|
if (isset($this->computedStyles[Padding::class]) && ($pd = $this->computedStyles[Padding::class])) {
|
|
$this->viewport->width = $this->intrinsicWidth + $pd->left + $pd->right;
|
|
$this->contentViewport->width = $this->intrinsicWidth + $pd->left + $pd->right;
|
|
}
|
|
}
|
|
|
|
if (!isset($this->computedStyles[\PHPNative\Tailwind\Style\Height::class])) {
|
|
$this->viewport->height = $this->intrinsicHeight;
|
|
$this->contentViewport->height = $this->intrinsicHeight;
|
|
|
|
if (isset($this->computedStyles[Padding::class]) && ($pd = $this->computedStyles[Padding::class])) {
|
|
$this->viewport->height = $this->intrinsicHeight + $pd->top + $pd->bottom;
|
|
$this->contentViewport->height = $this->intrinsicHeight + $pd->top + $pd->bottom;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public function renderContent(&$window, null|TextRenderer $textRenderer = null): void
|
|
{
|
|
if (!$this->visible || $textRenderer === null || !$textRenderer->isInitialized()) {
|
|
return;
|
|
}
|
|
|
|
// Get text style from computed styles
|
|
$textStyle = $this->computedStyles[Text::class] ?? new Text();
|
|
|
|
// Set text color
|
|
$color = $textStyle->color;
|
|
$red = $color->red >= 0 ? $color->red : 0;
|
|
$green = $color->green >= 0 ? $color->green : 0;
|
|
$blue = $color->blue >= 0 ? $color->blue : 0;
|
|
$alpha = max(0, min(255, $color->alpha));
|
|
|
|
$textRenderer->setColor($red / 255, $green / 255, $blue / 255, $alpha / 255);
|
|
|
|
if ($this->renderDirty || $this->textTexture === null) {
|
|
$this->clearTextTexture();
|
|
$textureData = $textRenderer->createTextTexture($this->text);
|
|
if ($textureData !== null) {
|
|
$this->textTexture = $textureData['texture'];
|
|
$this->textWidth = $textureData['width'];
|
|
$this->textHeight = $textureData['height'];
|
|
if (\function_exists('sdl_set_texture_alpha_mod')) {
|
|
sdl_set_texture_alpha_mod($this->textTexture, $alpha);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($this->textTexture !== null) {
|
|
sdl_render_texture($window, $this->textTexture, [
|
|
'x' => (int) $this->contentViewport->x,
|
|
'y' => (int) $this->contentViewport->y,
|
|
'w' => $this->textWidth,
|
|
'h' => $this->textHeight,
|
|
]);
|
|
} else {
|
|
// Fallback: render text directly if texture creation failed
|
|
$textRenderer->drawText(
|
|
$this->text,
|
|
(int) $this->contentViewport->x,
|
|
(int) $this->contentViewport->y,
|
|
$textStyle->size,
|
|
);
|
|
}
|
|
|
|
$this->renderDirty = false;
|
|
|
|
// Call parent to render children if any
|
|
parent::renderContent($window, $textRenderer);
|
|
}
|
|
|
|
public function __destruct()
|
|
{
|
|
$this->clearTextTexture();
|
|
parent::__destruct();
|
|
}
|
|
|
|
private function clearTextTexture(): void
|
|
{
|
|
if ($this->textTexture !== null) {
|
|
sdl_destroy_texture($this->textTexture);
|
|
$this->textTexture = null;
|
|
$this->textWidth = 0;
|
|
$this->textHeight = 0;
|
|
}
|
|
}
|
|
}
|