State
This commit is contained in:
parent
f3dd92d85b
commit
9f2b88e0eb
@ -34,7 +34,7 @@ $mainContainer->addComponent($button1);
|
||||
// Button with different padding
|
||||
$button2 = new 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 () {
|
||||
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 $pixelRatio;
|
||||
|
||||
protected string $styles = '';
|
||||
|
||||
protected bool $visible = true;
|
||||
|
||||
protected StateEnum $currentState = StateEnum::normal;
|
||||
|
||||
protected Viewport $viewport;
|
||||
|
||||
protected array $computedStyles = [];
|
||||
protected Viewport $contentViewport;
|
||||
|
||||
public function __construct(
|
||||
protected string $style = '',
|
||||
) {}
|
||||
|
||||
public function setViewport(Viewport $viewport): void
|
||||
{
|
||||
$this->viewport = $viewport;
|
||||
@ -83,9 +87,8 @@ abstract class Component
|
||||
{
|
||||
$this->computedStyles = StyleParser::parse($this->style)->getValidStyles(
|
||||
MediaQueryEnum::normal,
|
||||
StateEnum::normal,
|
||||
$this->currentState,
|
||||
);
|
||||
|
||||
if (isset($this->computedStyles[Margin::class]) && ($m = $this->computedStyles[Margin::class])) {
|
||||
$this->viewport->x = (int) ($this->viewport->x + $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
|
||||
{
|
||||
// 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) {
|
||||
$child->handleMouseMove($mouseX, $mouseY);
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ class Button extends Container
|
||||
|
||||
public function __construct(
|
||||
public string $text = '',
|
||||
public string $style = '',
|
||||
string $style = '',
|
||||
null|callable $onClick = null,
|
||||
) {
|
||||
parent::__construct($style);
|
||||
@ -57,7 +57,6 @@ class Button extends Container
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Propagate to parent if click was outside button
|
||||
return parent::handleMouseClick($mouseX, $mouseY, $button);
|
||||
}
|
||||
|
||||
@ -33,9 +33,10 @@ class Container extends Component
|
||||
private const SCROLLBAR_WIDTH = 12;
|
||||
private const SCROLLBAR_MIN_SIZE = 20;
|
||||
|
||||
public function __construct(
|
||||
public string $style = '',
|
||||
) {}
|
||||
public function __construct(string $style = '')
|
||||
{
|
||||
parent::__construct($style);
|
||||
}
|
||||
|
||||
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)
|
||||
$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::auto,
|
||||
]);
|
||||
$hasOverflowY = $overflow && in_array($overflow->y, [
|
||||
$hasOverflowY =
|
||||
$overflow &&
|
||||
in_array($overflow->y, [
|
||||
\PHPNative\Tailwind\Style\OverflowEnum::scroll,
|
||||
\PHPNative\Tailwind\Style\OverflowEnum::auto,
|
||||
]);
|
||||
@ -93,7 +98,7 @@ class Container extends Component
|
||||
width: $this->contentViewport->width,
|
||||
height: $this->contentViewport->height,
|
||||
windowWidth: $this->contentViewport->windowWidth,
|
||||
windowHeight: $this->contentViewport->windowHeight
|
||||
windowHeight: $this->contentViewport->windowHeight,
|
||||
);
|
||||
|
||||
$child->setViewport($childViewport);
|
||||
@ -200,7 +205,7 @@ class Container extends Component
|
||||
width: $size,
|
||||
height: $this->contentViewport->height,
|
||||
windowWidth: $this->contentViewport->windowWidth,
|
||||
windowHeight: $this->contentViewport->windowHeight
|
||||
windowHeight: $this->contentViewport->windowHeight,
|
||||
);
|
||||
$currentPosition += $size;
|
||||
} else {
|
||||
@ -211,7 +216,7 @@ class Container extends Component
|
||||
width: $this->contentViewport->width,
|
||||
height: $size,
|
||||
windowWidth: $this->contentViewport->windowWidth,
|
||||
windowHeight: $this->contentViewport->windowHeight
|
||||
windowHeight: $this->contentViewport->windowHeight,
|
||||
);
|
||||
$currentPosition += $size;
|
||||
}
|
||||
@ -324,10 +329,10 @@ class Container extends Component
|
||||
// Performance optimization: skip completely invisible children
|
||||
$childViewport = $child->getViewport();
|
||||
$isVisible =
|
||||
$childViewport->x + $childViewport->width > $scissorX &&
|
||||
$childViewport->x < $scissorX + $scissorW &&
|
||||
$childViewport->y + $childViewport->height > $scissorY &&
|
||||
$childViewport->y < $scissorY + $scissorH;
|
||||
($childViewport->x + $childViewport->width) > $scissorX &&
|
||||
$childViewport->x < ($scissorX + $scissorW) &&
|
||||
($childViewport->y + $childViewport->height) > $scissorY &&
|
||||
$childViewport->y < ($scissorY + $scissorH);
|
||||
|
||||
if ($isVisible) {
|
||||
// Render - batches draw calls
|
||||
@ -489,6 +494,7 @@ class Container extends Component
|
||||
|
||||
public function handleMouseMove(float $mouseX, float $mouseY): void
|
||||
{
|
||||
parent::handleMouseMove($mouseX, $mouseY);
|
||||
if ($this->isDraggingScrollbarY) {
|
||||
$deltaY = $mouseY - $this->dragStartY;
|
||||
$scrollbarHeight = $this->contentViewport->height;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user