State
This commit is contained in:
parent
f3dd92d85b
commit
9f2b88e0eb
@ -34,7 +34,7 @@ $mainContainer->addComponent($button1);
|
|||||||
// Button with different padding
|
// Button with different padding
|
||||||
$button2 = new Button(
|
$button2 = new Button(
|
||||||
text: 'Another Button',
|
text: 'Another Button',
|
||||||
style: 'm-5 p-15 bg-green-500 rounded-lg',
|
style: 'm-5 p-15 bg-green-500 hover:bg-green-200 rounded-lg',
|
||||||
onClick: function () {
|
onClick: function () {
|
||||||
echo 'test2';
|
echo 'test2';
|
||||||
},
|
},
|
||||||
|
|||||||
26
examples/SimpleButtonExample.php
Normal file
26
examples/SimpleButtonExample.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
use PHPNative\Framework\Application;
|
||||||
|
use PHPNative\Ui\Widget\Button;
|
||||||
|
use PHPNative\Ui\Widget\Container;
|
||||||
|
use PHPNative\Ui\Widget\Label;
|
||||||
|
|
||||||
|
// Check PHP version
|
||||||
|
if (PHP_VERSION_ID < 80100) {
|
||||||
|
die("This demo requires PHP 8.1+ for Fiber support.\nYour version: " . PHP_VERSION . "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$app = new Application('Button Example', 800, 600);
|
||||||
|
|
||||||
|
// Button with different padding
|
||||||
|
$button2 = new Button(
|
||||||
|
text: 'Another Button',
|
||||||
|
style: 'm-5 p-15 hover:bg-green-200',
|
||||||
|
onClick: function () {
|
||||||
|
echo 'test2';
|
||||||
|
},
|
||||||
|
);
|
||||||
|
$app->setRoot($button2);
|
||||||
|
$app->run();
|
||||||
@ -16,15 +16,19 @@ abstract class Component
|
|||||||
protected $window;
|
protected $window;
|
||||||
protected $pixelRatio;
|
protected $pixelRatio;
|
||||||
|
|
||||||
protected string $styles = '';
|
|
||||||
|
|
||||||
protected bool $visible = true;
|
protected bool $visible = true;
|
||||||
|
|
||||||
|
protected StateEnum $currentState = StateEnum::normal;
|
||||||
|
|
||||||
protected Viewport $viewport;
|
protected Viewport $viewport;
|
||||||
|
|
||||||
protected array $computedStyles = [];
|
protected array $computedStyles = [];
|
||||||
protected Viewport $contentViewport;
|
protected Viewport $contentViewport;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
protected string $style = '',
|
||||||
|
) {}
|
||||||
|
|
||||||
public function setViewport(Viewport $viewport): void
|
public function setViewport(Viewport $viewport): void
|
||||||
{
|
{
|
||||||
$this->viewport = $viewport;
|
$this->viewport = $viewport;
|
||||||
@ -83,9 +87,8 @@ abstract class Component
|
|||||||
{
|
{
|
||||||
$this->computedStyles = StyleParser::parse($this->style)->getValidStyles(
|
$this->computedStyles = StyleParser::parse($this->style)->getValidStyles(
|
||||||
MediaQueryEnum::normal,
|
MediaQueryEnum::normal,
|
||||||
StateEnum::normal,
|
$this->currentState,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isset($this->computedStyles[Margin::class]) && ($m = $this->computedStyles[Margin::class])) {
|
if (isset($this->computedStyles[Margin::class]) && ($m = $this->computedStyles[Margin::class])) {
|
||||||
$this->viewport->x = (int) ($this->viewport->x + $m->left);
|
$this->viewport->x = (int) ($this->viewport->x + $m->left);
|
||||||
$this->viewport->width = max(0, ($this->viewport->width - $m->right) - $m->left);
|
$this->viewport->width = max(0, ($this->viewport->width - $m->right) - $m->left);
|
||||||
@ -185,7 +188,26 @@ abstract class Component
|
|||||||
*/
|
*/
|
||||||
public function handleMouseMove(float $mouseX, float $mouseY): void
|
public function handleMouseMove(float $mouseX, float $mouseY): void
|
||||||
{
|
{
|
||||||
// Default implementation: propagate to children
|
// Check if mouse is over this component
|
||||||
|
$isMouseOver =
|
||||||
|
$mouseX >= $this->viewport->x &&
|
||||||
|
$mouseX <= ($this->viewport->x + $this->viewport->width) &&
|
||||||
|
$mouseY >= $this->viewport->y &&
|
||||||
|
$mouseY <= ($this->viewport->y + $this->viewport->height);
|
||||||
|
|
||||||
|
// Update state based on mouse position
|
||||||
|
$previousState = $this->currentState;
|
||||||
|
$this->currentState = $isMouseOver ? StateEnum::hover : StateEnum::normal;
|
||||||
|
|
||||||
|
// Recompute styles if state changed
|
||||||
|
if ($previousState !== $this->currentState) {
|
||||||
|
$this->computedStyles = StyleParser::parse($this->style)->getValidStyles(
|
||||||
|
MediaQueryEnum::normal,
|
||||||
|
$this->currentState,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Propagate to children
|
||||||
foreach ($this->children as $child) {
|
foreach ($this->children as $child) {
|
||||||
$child->handleMouseMove($mouseX, $mouseY);
|
$child->handleMouseMove($mouseX, $mouseY);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ class Button extends Container
|
|||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public string $text = '',
|
public string $text = '',
|
||||||
public string $style = '',
|
string $style = '',
|
||||||
null|callable $onClick = null,
|
null|callable $onClick = null,
|
||||||
) {
|
) {
|
||||||
parent::__construct($style);
|
parent::__construct($style);
|
||||||
@ -57,7 +57,6 @@ class Button extends Container
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Propagate to parent if click was outside button
|
// Propagate to parent if click was outside button
|
||||||
return parent::handleMouseClick($mouseX, $mouseY, $button);
|
return parent::handleMouseClick($mouseX, $mouseY, $button);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,9 +33,10 @@ class Container extends Component
|
|||||||
private const SCROLLBAR_WIDTH = 12;
|
private const SCROLLBAR_WIDTH = 12;
|
||||||
private const SCROLLBAR_MIN_SIZE = 20;
|
private const SCROLLBAR_MIN_SIZE = 20;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(string $style = '')
|
||||||
public string $style = '',
|
{
|
||||||
) {}
|
parent::__construct($style);
|
||||||
|
}
|
||||||
|
|
||||||
public function layout(null|TextRenderer $textRenderer = null): void
|
public function layout(null|TextRenderer $textRenderer = null): void
|
||||||
{
|
{
|
||||||
@ -47,11 +48,15 @@ class Container extends Component
|
|||||||
|
|
||||||
// Check if overflow is set (if yes, container should not auto-expand)
|
// Check if overflow is set (if yes, container should not auto-expand)
|
||||||
$overflow = $this->computedStyles[\PHPNative\Tailwind\Style\Overflow::class] ?? null;
|
$overflow = $this->computedStyles[\PHPNative\Tailwind\Style\Overflow::class] ?? null;
|
||||||
$hasOverflowX = $overflow && in_array($overflow->x, [
|
$hasOverflowX =
|
||||||
|
$overflow &&
|
||||||
|
in_array($overflow->x, [
|
||||||
\PHPNative\Tailwind\Style\OverflowEnum::scroll,
|
\PHPNative\Tailwind\Style\OverflowEnum::scroll,
|
||||||
\PHPNative\Tailwind\Style\OverflowEnum::auto,
|
\PHPNative\Tailwind\Style\OverflowEnum::auto,
|
||||||
]);
|
]);
|
||||||
$hasOverflowY = $overflow && in_array($overflow->y, [
|
$hasOverflowY =
|
||||||
|
$overflow &&
|
||||||
|
in_array($overflow->y, [
|
||||||
\PHPNative\Tailwind\Style\OverflowEnum::scroll,
|
\PHPNative\Tailwind\Style\OverflowEnum::scroll,
|
||||||
\PHPNative\Tailwind\Style\OverflowEnum::auto,
|
\PHPNative\Tailwind\Style\OverflowEnum::auto,
|
||||||
]);
|
]);
|
||||||
@ -93,7 +98,7 @@ class Container extends Component
|
|||||||
width: $this->contentViewport->width,
|
width: $this->contentViewport->width,
|
||||||
height: $this->contentViewport->height,
|
height: $this->contentViewport->height,
|
||||||
windowWidth: $this->contentViewport->windowWidth,
|
windowWidth: $this->contentViewport->windowWidth,
|
||||||
windowHeight: $this->contentViewport->windowHeight
|
windowHeight: $this->contentViewport->windowHeight,
|
||||||
);
|
);
|
||||||
|
|
||||||
$child->setViewport($childViewport);
|
$child->setViewport($childViewport);
|
||||||
@ -200,7 +205,7 @@ class Container extends Component
|
|||||||
width: $size,
|
width: $size,
|
||||||
height: $this->contentViewport->height,
|
height: $this->contentViewport->height,
|
||||||
windowWidth: $this->contentViewport->windowWidth,
|
windowWidth: $this->contentViewport->windowWidth,
|
||||||
windowHeight: $this->contentViewport->windowHeight
|
windowHeight: $this->contentViewport->windowHeight,
|
||||||
);
|
);
|
||||||
$currentPosition += $size;
|
$currentPosition += $size;
|
||||||
} else {
|
} else {
|
||||||
@ -211,7 +216,7 @@ class Container extends Component
|
|||||||
width: $this->contentViewport->width,
|
width: $this->contentViewport->width,
|
||||||
height: $size,
|
height: $size,
|
||||||
windowWidth: $this->contentViewport->windowWidth,
|
windowWidth: $this->contentViewport->windowWidth,
|
||||||
windowHeight: $this->contentViewport->windowHeight
|
windowHeight: $this->contentViewport->windowHeight,
|
||||||
);
|
);
|
||||||
$currentPosition += $size;
|
$currentPosition += $size;
|
||||||
}
|
}
|
||||||
@ -324,10 +329,10 @@ class Container extends Component
|
|||||||
// Performance optimization: skip completely invisible children
|
// Performance optimization: skip completely invisible children
|
||||||
$childViewport = $child->getViewport();
|
$childViewport = $child->getViewport();
|
||||||
$isVisible =
|
$isVisible =
|
||||||
$childViewport->x + $childViewport->width > $scissorX &&
|
($childViewport->x + $childViewport->width) > $scissorX &&
|
||||||
$childViewport->x < $scissorX + $scissorW &&
|
$childViewport->x < ($scissorX + $scissorW) &&
|
||||||
$childViewport->y + $childViewport->height > $scissorY &&
|
($childViewport->y + $childViewport->height) > $scissorY &&
|
||||||
$childViewport->y < $scissorY + $scissorH;
|
$childViewport->y < ($scissorY + $scissorH);
|
||||||
|
|
||||||
if ($isVisible) {
|
if ($isVisible) {
|
||||||
// Render - batches draw calls
|
// Render - batches draw calls
|
||||||
@ -489,6 +494,7 @@ class Container extends Component
|
|||||||
|
|
||||||
public function handleMouseMove(float $mouseX, float $mouseY): void
|
public function handleMouseMove(float $mouseX, float $mouseY): void
|
||||||
{
|
{
|
||||||
|
parent::handleMouseMove($mouseX, $mouseY);
|
||||||
if ($this->isDraggingScrollbarY) {
|
if ($this->isDraggingScrollbarY) {
|
||||||
$deltaY = $mouseY - $this->dragStartY;
|
$deltaY = $mouseY - $this->dragStartY;
|
||||||
$scrollbarHeight = $this->contentViewport->height;
|
$scrollbarHeight = $this->contentViewport->height;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user