Backup
This commit is contained in:
parent
7d4139234f
commit
401287a2a1
BIN
assets/symbol.ttf
Normal file
BIN
assets/symbol.ttf
Normal file
Binary file not shown.
@ -11,7 +11,9 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"ext-parallel": "*",
|
"ext-parallel": "*",
|
||||||
"ext-sdl": "*",
|
"ext-sdl": "*",
|
||||||
"php": "^8.3"
|
"php": "^8.3",
|
||||||
|
"symfony/serializer": "^7",
|
||||||
|
"zumba/json-serializer": "^3"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"friendsofphp/php-cs-fixer": "^3.21",
|
"friendsofphp/php-cs-fixer": "^3.21",
|
||||||
@ -28,6 +30,7 @@
|
|||||||
"phpnative/event": "self.version",
|
"phpnative/event": "self.version",
|
||||||
"phpnative/framework": "self.version",
|
"phpnative/framework": "self.version",
|
||||||
"phpnative/renderer": "self.version",
|
"phpnative/renderer": "self.version",
|
||||||
|
"phpnative/storage": "self.version",
|
||||||
"phpnative/support": "self.version",
|
"phpnative/support": "self.version",
|
||||||
"phpnative/tailwind": "self.version",
|
"phpnative/tailwind": "self.version",
|
||||||
"phpnative/ui": "self.version"
|
"phpnative/ui": "self.version"
|
||||||
@ -39,6 +42,7 @@
|
|||||||
"PHPNative\\Event\\": "src/PHPNative/Event/src",
|
"PHPNative\\Event\\": "src/PHPNative/Event/src",
|
||||||
"PHPNative\\Framework\\": "src/PHPNative/Framework/src",
|
"PHPNative\\Framework\\": "src/PHPNative/Framework/src",
|
||||||
"PHPNative\\Renderer\\": "src/PHPNative/Renderer/src",
|
"PHPNative\\Renderer\\": "src/PHPNative/Renderer/src",
|
||||||
|
"PHPNative\\Storage\\": "src/PHPNative/Storage/src",
|
||||||
"PHPNative\\Support\\": "src/PHPNative/Support/src",
|
"PHPNative\\Support\\": "src/PHPNative/Support/src",
|
||||||
"PHPNative\\Tailwind\\": "src/PHPNative/Tailwind/src",
|
"PHPNative\\Tailwind\\": "src/PHPNative/Tailwind/src",
|
||||||
"PHPNative\\UI\\": "src/PHPNative/UI/src"
|
"PHPNative\\UI\\": "src/PHPNative/UI/src"
|
||||||
@ -51,6 +55,7 @@
|
|||||||
"PHPNative\\Event\\Tests\\": "src/PHPNative/Event/tests",
|
"PHPNative\\Event\\Tests\\": "src/PHPNative/Event/tests",
|
||||||
"PHPNative\\Framework\\Tests\\": "src/PHPNative/Framework/tests",
|
"PHPNative\\Framework\\Tests\\": "src/PHPNative/Framework/tests",
|
||||||
"PHPNative\\Renderer\\Tests\\": "src/PHPNative/Renderer/tests",
|
"PHPNative\\Renderer\\Tests\\": "src/PHPNative/Renderer/tests",
|
||||||
|
"PHPNative\\Storage\\Tests\\": "src/PHPNative/Storage/tests",
|
||||||
"PHPNative\\Support\\Tests\\": "src/PHPNative/Support/tests",
|
"PHPNative\\Support\\Tests\\": "src/PHPNative/Support/tests",
|
||||||
"PHPNative\\Tailwind\\Tests\\": "src/PHPNative/Tailwind/tests",
|
"PHPNative\\Tailwind\\Tests\\": "src/PHPNative/Tailwind/tests",
|
||||||
"PHPNative\\UI\\Tests\\": "src/PHPNative/UI/tests"
|
"PHPNative\\UI\\Tests\\": "src/PHPNative/UI/tests"
|
||||||
|
|||||||
@ -120,4 +120,9 @@ abstract class Collection implements IteratorAggregate
|
|||||||
$this->elements = $temp->items();
|
$this->elements = $temp->items();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function clear(): void
|
||||||
|
{
|
||||||
|
$this->elements = [];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -12,11 +12,17 @@ class Driver
|
|||||||
public function pollEvent(): Event
|
public function pollEvent(): Event
|
||||||
{
|
{
|
||||||
\SDL_PollEvent($this->event);
|
\SDL_PollEvent($this->event);
|
||||||
|
if($this->event->type == \SDL_EVENT_KEY_UP) {
|
||||||
|
var_dump($this->event->key->key);
|
||||||
|
}
|
||||||
return match($this->event->type) {
|
return match($this->event->type) {
|
||||||
\SDL_EVENT_QUIT => new \PHPNative\Event\SystemEvent(EventType::QUIT),
|
\SDL_EVENT_QUIT => new \PHPNative\Event\SystemEvent(EventType::QUIT),
|
||||||
\SDL_EVENT_MOUSE_BUTTON_DOWN => new MouseDown(EventType::MOUSEBUTTON_DOWN, $this->event->button->x, $this->event->button->y ),
|
\SDL_EVENT_WINDOW_CLOSE_REQUESTED => new \PHPNative\Event\SystemEvent(EventType::WINDOW_CLOSE, $this->event->window->windowID),
|
||||||
\SDL_EVENT_MOUSE_BUTTON_UP => new MouseUp(EventType::MOUSEBUTTON_UP, $this->event->button->x, $this->event->button->y ),
|
\SDL_EVENT_KEY_UP => new \PHPNative\Event\KeyUp(EventType::KEYUP, $this->event->window->windowID, Key::tryFrom($this->event->key->key)),
|
||||||
\SDL_EVENT_MOUSE_MOTION => new MouseMove(EventType::MOUSEMOVE, $this->event->motion->x, $this->event->motion->y ),
|
\SDL_EVENT_TEXT_INPUT => new \PHPNative\Event\TextInput(EventType::TEXTINPUT, $this->event->window->windowID, mb_convert_encoding($this->event->text->text, 'ISO-8859-1', 'UTF-8')),
|
||||||
|
\SDL_EVENT_MOUSE_BUTTON_DOWN => new MouseDown(EventType::MOUSEBUTTON_DOWN, $this->event->window->windowID, $this->event->button->x, $this->event->button->y ),
|
||||||
|
\SDL_EVENT_MOUSE_BUTTON_UP => new MouseUp(EventType::MOUSEBUTTON_UP, $this->event->window->windowID, $this->event->button->x, $this->event->button->y ),
|
||||||
|
\SDL_EVENT_MOUSE_MOTION => new MouseMove(EventType::MOUSEMOVE, $this->event->window->windowID, $this->event->motion->x, $this->event->motion->y ),
|
||||||
default => new \PHPNative\Event\SystemEvent(EventType::NOOP)
|
default => new \PHPNative\Event\SystemEvent(EventType::NOOP)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,6 @@ enum EventType: int
|
|||||||
{
|
{
|
||||||
case NOOP = 0;
|
case NOOP = 0;
|
||||||
case QUIT = 1;
|
case QUIT = 1;
|
||||||
case CLOSE_WINDOW = 2;
|
|
||||||
case WINDOW_FOCUS_LOST = 1000;
|
case WINDOW_FOCUS_LOST = 1000;
|
||||||
case WINDOW_FOCUS_GAINED = 1001;
|
case WINDOW_FOCUS_GAINED = 1001;
|
||||||
case WINDOW_RESIZED = 1002;
|
case WINDOW_RESIZED = 1002;
|
||||||
|
|||||||
15
src/PHPNative/Event/src/Key.php
Normal file
15
src/PHPNative/Event/src/Key.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PHPNative\Event;
|
||||||
|
|
||||||
|
enum Key: int
|
||||||
|
{
|
||||||
|
|
||||||
|
case BACKSPACE = 8;
|
||||||
|
|
||||||
|
case SDLK_RIGHT = 1073741903;
|
||||||
|
case SDLK_LEFT = 1073741904;
|
||||||
|
case SDLK_UP = 1073741906;
|
||||||
|
case SDLK_DOWN = 1073741905;
|
||||||
|
|
||||||
|
}
|
||||||
17
src/PHPNative/Event/src/KeyUp.php
Normal file
17
src/PHPNative/Event/src/KeyUp.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace PHPNative\Event;
|
||||||
|
|
||||||
|
class KeyUp implements Event
|
||||||
|
{
|
||||||
|
public function __construct(public EventType $type = EventType::MOUSEBUTTON_UP, public int $windowId = 0, public ?Key $key = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getType(): EventType
|
||||||
|
{
|
||||||
|
return $this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -5,7 +5,7 @@ namespace PHPNative\Event;
|
|||||||
|
|
||||||
class MouseDown implements Event
|
class MouseDown implements Event
|
||||||
{
|
{
|
||||||
public function __construct(public EventType $type = EventType::MOUSEBUTTON_DOWN, public int $x = 0, public int $y = 0)
|
public function __construct(public EventType $type = EventType::MOUSEBUTTON_DOWN, public int $windowId = 0, public int $x = 0, public int $y = 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ namespace PHPNative\Event;
|
|||||||
|
|
||||||
class MouseMove implements Event
|
class MouseMove implements Event
|
||||||
{
|
{
|
||||||
public function __construct(public EventType $type = EventType::MOUSEMOVE, public int $x = 0, public int $y = 0)
|
public function __construct(public EventType $type = EventType::MOUSEMOVE, public int $windowId = 0, public int $x = 0, public int $y = 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ namespace PHPNative\Event;
|
|||||||
|
|
||||||
class MouseUp implements Event
|
class MouseUp implements Event
|
||||||
{
|
{
|
||||||
public function __construct(public EventType $type = EventType::MOUSEBUTTON_UP, public int $x = 0, public int $y = 0)
|
public function __construct(public EventType $type = EventType::MOUSEBUTTON_UP, public int $windowId = 0, public int $x = 0, public int $y = 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ namespace PHPNative\Event;
|
|||||||
|
|
||||||
class SystemEvent implements Event
|
class SystemEvent implements Event
|
||||||
{
|
{
|
||||||
public function __construct(public EventType $type = EventType::NOOP)
|
public function __construct(public EventType $type = EventType::NOOP, public int $windowId = 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
17
src/PHPNative/Event/src/TextInput.php
Normal file
17
src/PHPNative/Event/src/TextInput.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace PHPNative\Event;
|
||||||
|
|
||||||
|
class TextInput implements Event
|
||||||
|
{
|
||||||
|
public function __construct(public EventType $type = EventType::TEXTINPUT, public int $windowId = 0, public string $text = "")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getType(): EventType
|
||||||
|
{
|
||||||
|
return $this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -5,6 +5,6 @@ namespace PHPNative\Framework\Application;
|
|||||||
interface Application
|
interface Application
|
||||||
{
|
{
|
||||||
|
|
||||||
public function run(string|null $start): void;
|
public function run(): void;
|
||||||
|
|
||||||
}
|
}
|
||||||
7
src/PHPNative/Framework/src/Application/Config.php
Normal file
7
src/PHPNative/Framework/src/Application/Config.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace PHPNative\Framework\Application;
|
||||||
|
|
||||||
|
class Config
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -18,25 +18,29 @@ final readonly class Gui implements Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static function boot(
|
public static function boot(
|
||||||
string $name = 'PHPNative',
|
?string $app = null,
|
||||||
?string $root = null,
|
?string $root = null,
|
||||||
array $discoveryLocations = [],
|
array $discoveryLocations = [],
|
||||||
): self {
|
): self {
|
||||||
$container = PHPNative::boot($root);
|
|
||||||
|
|
||||||
|
$container = PHPNative::boot($root);
|
||||||
|
$container->register(App::class, function () use ($app, $container) {
|
||||||
|
return $container->get($app);
|
||||||
|
});
|
||||||
$application = $container->get(Gui::class);
|
$application = $container->get(Gui::class);
|
||||||
|
|
||||||
return $application;
|
return $application;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function run(string|null $start): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$application = $this->container->get(App::class);
|
||||||
$lifeCycle = $this->container->get(Lifecycle::class);
|
$lifeCycle = $this->container->get(Lifecycle::class);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$lifeCycle->show($this->container->get($start));
|
$lifeCycle->show($this->container->get($application->getStartWindow()));
|
||||||
$lifeCycle->run();
|
$lifeCycle->run();
|
||||||
} catch (ArgumentCountError $e) {
|
} catch (ArgumentCountError $e) {
|
||||||
var_dump($e->getMessage());
|
var_dump($e->getMessage());
|
||||||
|
|||||||
@ -6,9 +6,9 @@ namespace PHPNative\Framework\Application;
|
|||||||
|
|
||||||
use PHPNative\Container\Container;
|
use PHPNative\Container\Container;
|
||||||
use PHPNative\Container\GenericContainer;
|
use PHPNative\Container\GenericContainer;
|
||||||
use PHPNative\Framework\Discovery\DiscoveryLocationBootstrap;
|
|
||||||
use PHPNative\Framework\Discovery\LoadDiscoveryClasses;
|
use PHPNative\Framework\Discovery\LoadDiscoveryClasses;
|
||||||
use PHPNative\Framework\Discovery\LoadDiscoveryLocations;
|
use PHPNative\Framework\Discovery\LoadDiscoveryLocations;
|
||||||
|
use Zumba\JsonSerializer\JsonSerializer;
|
||||||
|
|
||||||
final class Kernel
|
final class Kernel
|
||||||
{
|
{
|
||||||
@ -34,6 +34,9 @@ final class Kernel
|
|||||||
private function registerKernel(): self
|
private function registerKernel(): self
|
||||||
{
|
{
|
||||||
$this->container->singleton(self::class, $this);
|
$this->container->singleton(self::class, $this);
|
||||||
|
$this->container->register(JsonSerializer::class, function () {
|
||||||
|
return new JsonSerializer();
|
||||||
|
});
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace PHPNative\Framework\Lifecycle;
|
namespace PHPNative\Framework\Lifecycle;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
use PHPNative\Event\Event;
|
use PHPNative\Event\Event;
|
||||||
use PHPNative\Framework\Application\Window;
|
use PHPNative\Framework\Application\Window;
|
||||||
use PHPNative\Renderer\Thread;
|
use PHPNative\Renderer\Thread;
|
||||||
@ -9,7 +10,7 @@ use PHPNative\Renderer\Thread;
|
|||||||
class Context
|
class Context
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct(private Thread $thread)
|
public function __construct(public Thread $thread, public ?Closure $onClose = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -26,7 +27,9 @@ class Context
|
|||||||
|
|
||||||
public function event(Event $event): void
|
public function event(Event $event): void
|
||||||
{
|
{
|
||||||
$this->thread->addEvent($event);
|
if($event->windowId == $this->thread->windowId) {
|
||||||
|
$this->thread->addEvent($event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render(float $delta): void
|
public function render(float $delta): void
|
||||||
@ -36,7 +39,10 @@ class Context
|
|||||||
|
|
||||||
public function unload(): void
|
public function unload(): void
|
||||||
{
|
{
|
||||||
//TODO: unload
|
if($this->onClose) {
|
||||||
|
($this->onClose)();
|
||||||
|
}
|
||||||
|
$this->thread->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -12,4 +12,15 @@ class ContextCollection extends TypedCollection
|
|||||||
{
|
{
|
||||||
return Context::class;
|
return Context::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function removeWindowFrom(string $windowId): void
|
||||||
|
{
|
||||||
|
$temp = $this->filter(function ($value, $key) use($windowId){
|
||||||
|
if($value->thread->windowId == $windowId) {
|
||||||
|
$value->unload();
|
||||||
|
}
|
||||||
|
return $value->thread->windowId != $windowId;
|
||||||
|
});
|
||||||
|
$this->setElements($temp->items());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -3,6 +3,7 @@
|
|||||||
namespace PHPNative\Framework\Lifecycle;
|
namespace PHPNative\Framework\Lifecycle;
|
||||||
|
|
||||||
use PHPNative\Container\Container;
|
use PHPNative\Container\Container;
|
||||||
|
use PHPNative\Container\Singleton;
|
||||||
use PHPNative\Event\Event;
|
use PHPNative\Event\Event;
|
||||||
use PHPNative\Event\EventType;
|
use PHPNative\Event\EventType;
|
||||||
use PHPNative\Framework\Application\Window;
|
use PHPNative\Framework\Application\Window;
|
||||||
@ -10,6 +11,7 @@ use PHPNative\Framework\Loop\OrderedEventLoop;
|
|||||||
use PHPNative\Framework\Loop\WorkerInterface;
|
use PHPNative\Framework\Loop\WorkerInterface;
|
||||||
use PHPNative\Renderer\Thread;
|
use PHPNative\Renderer\Thread;
|
||||||
|
|
||||||
|
#[Singleton]
|
||||||
class Lifecycle implements WorkerInterface
|
class Lifecycle implements WorkerInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
@ -20,14 +22,15 @@ class Lifecycle implements WorkerInterface
|
|||||||
$this->loop->use($this);
|
$this->loop->use($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show(Window $window, array $arguments = []): void
|
public function show(Window $window, array $arguments = [], ?callable $onClose = null): void
|
||||||
{
|
{
|
||||||
|
|
||||||
$context = $this->container->get(
|
$context = $this->container->get(
|
||||||
Context::class,
|
Context::class,
|
||||||
thread: $this->container->get(Thread::class)
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$context->onClose = $onClose;
|
||||||
$context->show($window);
|
$context->show($window);
|
||||||
|
|
||||||
$this->contextCollection->add($context);
|
$this->contextCollection->add($context);
|
||||||
@ -45,7 +48,9 @@ class Lifecycle implements WorkerInterface
|
|||||||
|
|
||||||
public function onRender(float $delta): void
|
public function onRender(float $delta): void
|
||||||
{
|
{
|
||||||
$this->contextCollection->map(fn(Context $context) => $context->render($delta));
|
$this->contextCollection->map(
|
||||||
|
fn(Context $context) => $context->render($delta)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onEvent( $event): void
|
public function onEvent( $event): void
|
||||||
@ -60,6 +65,9 @@ class Lifecycle implements WorkerInterface
|
|||||||
case EventType::WINDOW_FOCUS_LOST:
|
case EventType::WINDOW_FOCUS_LOST:
|
||||||
$this->loop->pause();
|
$this->loop->pause();
|
||||||
break;
|
break;
|
||||||
|
case EventType::WINDOW_CLOSE:
|
||||||
|
$this->closeWindow($event->windowId);
|
||||||
|
break;
|
||||||
case EventType::WINDOW_FOCUS_GAINED:
|
case EventType::WINDOW_FOCUS_GAINED:
|
||||||
$this->loop->resume();
|
$this->loop->resume();
|
||||||
break;
|
break;
|
||||||
@ -67,6 +75,7 @@ class Lifecycle implements WorkerInterface
|
|||||||
$this->contextCollection->map(fn(Context $context) => $context->unload());
|
$this->contextCollection->map(fn(Context $context) => $context->unload());
|
||||||
$this->contextCollection = new ContextCollection();
|
$this->contextCollection = new ContextCollection();
|
||||||
$this->loop->stop();
|
$this->loop->stop();
|
||||||
|
\SDL_Quit();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,4 +93,13 @@ class Lifecycle implements WorkerInterface
|
|||||||
$this->context->resume();
|
$this->context->resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function closeWindow($windowId)
|
||||||
|
{
|
||||||
|
if($this->contextCollection->count() == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->contextCollection->removeWindowFrom($windowId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -15,6 +15,8 @@ final class PHPNative
|
|||||||
): Container {
|
): Container {
|
||||||
$root ??= getcwd();
|
$root ??= getcwd();
|
||||||
|
|
||||||
|
\SDL_Init(\SDL_INIT_VIDEO);
|
||||||
|
\SDL_TTF_Init();
|
||||||
// Kernel
|
// Kernel
|
||||||
return (new Kernel(
|
return (new Kernel(
|
||||||
root: $root,
|
root: $root,
|
||||||
|
|||||||
8
src/PHPNative/Renderer/src/Cache/Image.php
Normal file
8
src/PHPNative/Renderer/src/Cache/Image.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PHPNative\Renderer\Cache;
|
||||||
|
|
||||||
|
class Image
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@ -13,10 +13,13 @@ use PHPNative\Tailwind\StyleParser;
|
|||||||
|
|
||||||
class Thread
|
class Thread
|
||||||
{
|
{
|
||||||
private ?\SDL_Window $windowId = null;
|
public ?\SDL_Window $windowPtr = null;
|
||||||
|
public ?int $windowId = null;
|
||||||
private $rendererPtr = null;
|
private $rendererPtr = null;
|
||||||
|
|
||||||
private Window $window;
|
private bool $shouldRenderd = true;
|
||||||
|
|
||||||
|
public Window $window;
|
||||||
|
|
||||||
private StackCollection $renderStack;
|
private StackCollection $renderStack;
|
||||||
|
|
||||||
@ -32,28 +35,32 @@ class Thread
|
|||||||
{
|
{
|
||||||
$this->window = $window;
|
$this->window = $window;
|
||||||
|
|
||||||
\SDL_Init(\SDL_INIT_VIDEO);
|
$this->windowPtr = \SDL_CreateWindow($this->window->getTitle(), 1000, 600, \SDL_WINDOW_HIGH_PIXEL_DENSITY);
|
||||||
\SDL_TTF_Init();
|
$this->rendererPtr = \SDL_CreateRenderer($this->windowPtr);
|
||||||
$this->windowId = \SDL_CreateWindow($this->window->getTitle(), 800, 600, \SDL_WINDOW_HIGH_PIXEL_DENSITY);
|
$this->windowId = \SDL_GetWindowID($this->windowPtr);
|
||||||
$this->rendererPtr = \SDL_CreateRenderer($this->windowId);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void
|
public function close(): void
|
||||||
{
|
{
|
||||||
|
$this->shouldRenderd = false;
|
||||||
\SDL_DestroyRenderer($this->rendererPtr);
|
\SDL_DestroyRenderer($this->rendererPtr);
|
||||||
\SDL_DestroyWindow($this->windowId);
|
\SDL_DestroyWindow($this->windowPtr);
|
||||||
\SDL_Quit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render(): void
|
public function render(): void
|
||||||
{
|
{
|
||||||
|
if(!$this->shouldRenderd) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$windowWidth = 0;
|
$windowWidth = 0;
|
||||||
$windowHeight = 0;
|
$windowHeight = 0;
|
||||||
\SDL_GetWindowSize($this->windowId, $windowWidth, $windowHeight);
|
\SDL_GetWindowSize($this->windowPtr, $windowWidth, $windowHeight);
|
||||||
|
|
||||||
$viewPort = new Viewport(
|
$viewPort = new Viewport(
|
||||||
windowId: $this->windowId,
|
windowId: $this->windowId,
|
||||||
|
windowPtr: $this->windowPtr,
|
||||||
renderPtr: $this->rendererPtr,
|
renderPtr: $this->rendererPtr,
|
||||||
x:0, y: 0,
|
x:0, y: 0,
|
||||||
width: $windowWidth, height: $windowHeight, windowWidth: $windowWidth, windowHeight: $windowHeight,
|
width: $windowWidth, height: $windowHeight, windowWidth: $windowWidth, windowHeight: $windowHeight,
|
||||||
@ -74,6 +81,7 @@ class Thread
|
|||||||
if($item->clipAt) {
|
if($item->clipAt) {
|
||||||
$item->renderAt->w = $item->clipAt->w;
|
$item->renderAt->w = $item->clipAt->w;
|
||||||
}
|
}
|
||||||
|
|
||||||
\SDL_RenderTexture($this->rendererPtr, $item->texture, $item->clipAt?? null , $item->renderAt);
|
\SDL_RenderTexture($this->rendererPtr, $item->texture, $item->clipAt?? null , $item->renderAt);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ class Viewport
|
|||||||
{
|
{
|
||||||
|
|
||||||
public function __construct(public $windowId,
|
public function __construct(public $windowId,
|
||||||
|
public $windowPtr,
|
||||||
public $renderPtr,
|
public $renderPtr,
|
||||||
public int $x = 0,
|
public int $x = 0,
|
||||||
public int $y = 0,
|
public int $y = 0,
|
||||||
@ -16,6 +17,8 @@ class Viewport
|
|||||||
public $height = 0,
|
public $height = 0,
|
||||||
public $windowWidth = 0,
|
public $windowWidth = 0,
|
||||||
public $windowHeight = 0,
|
public $windowHeight = 0,
|
||||||
|
public $addX = 0,
|
||||||
|
public $addY = 0,
|
||||||
public MediaQueryEnum $windowMediaQuery = MediaQueryEnum::normal)
|
public MediaQueryEnum $windowMediaQuery = MediaQueryEnum::normal)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,26 +2,37 @@
|
|||||||
|
|
||||||
namespace PHPNative\Renderer\Visuals;
|
namespace PHPNative\Renderer\Visuals;
|
||||||
|
|
||||||
|
use PHPNative\Renderer\GFX;
|
||||||
use PHPNative\Renderer\Item;
|
use PHPNative\Renderer\Item;
|
||||||
use PHPNative\Renderer\Thread;
|
use PHPNative\Renderer\Thread;
|
||||||
use PHPNative\Renderer\Viewport;
|
use PHPNative\Renderer\Viewport;
|
||||||
|
|
||||||
class Background
|
class Background
|
||||||
{
|
{
|
||||||
public static function render(string $widgetId, Thread $thread, array $styles, Viewport $targetViewport): void
|
public static function render(string $widgetId, Thread $thread, array $styles, Viewport $targetViewport, int $index = 0): void
|
||||||
{
|
{
|
||||||
if(isset($styles[\PHPNative\Tailwind\Style\Background::class]) && $bg = $styles[\PHPNative\Tailwind\Style\Background::class]) {
|
if(isset($styles[\PHPNative\Tailwind\Style\Background::class]) && $bg = $styles[\PHPNative\Tailwind\Style\Background::class]) {
|
||||||
|
|
||||||
$texture = \SDL_CreateTexture($targetViewport->renderPtr, \SDL_PIXELFORMAT_RGBA8888, \SDL_TEXTUREACCESS_TARGET, $targetViewport->width, $targetViewport->height);
|
$texture = \SDL_CreateTexture($targetViewport->renderPtr, \SDL_PIXELFORMAT_RGBA8888, \SDL_TEXTUREACCESS_TARGET, $targetViewport->width, $targetViewport->height);
|
||||||
\SDL_SetRenderTarget($targetViewport->renderPtr, $texture);
|
\SDL_SetRenderTarget($targetViewport->renderPtr, $texture);
|
||||||
\SDL_SetRenderDrawColor($targetViewport->renderPtr, 255, 255, 255, 255);
|
\SDL_SetRenderDrawColor($targetViewport->renderPtr, 0, 0, 0, 0);
|
||||||
\SDL_RenderClear($targetViewport->renderPtr);
|
\SDL_RenderClear($targetViewport->renderPtr);
|
||||||
|
|
||||||
$rect = new \SDL_FRect(0, 0, $targetViewport->width, $targetViewport->height);
|
|
||||||
\SDL_SetRenderDrawColor($targetViewport->renderPtr, $bg->color->red, $bg->color->green, $bg->color->blue, $bg->color->alpha);
|
|
||||||
\SDL_RenderFillRect($targetViewport->renderPtr, $rect);
|
|
||||||
|
|
||||||
$thread->addToRenderStack(new Item($widgetId, $texture, new \SDL_FRect($targetViewport->x, $targetViewport->y, $targetViewport->width, $targetViewport->height), 2));
|
if(isset($styles[\PHPNative\Tailwind\Style\Border::class]) && $border = $styles[\PHPNative\Tailwind\Style\Border::class]) {
|
||||||
|
if($border->roundTop > 0) {
|
||||||
|
GFX::roundedBoxRGBA($targetViewport->renderPtr, 0, 0,
|
||||||
|
$targetViewport->width, $targetViewport->height, $border->roundTop, $bg->color->red, $bg->color->green, $bg->color->blue, $bg->color->alpha);
|
||||||
|
}else{
|
||||||
|
GFX::boxRGBA($targetViewport->renderPtr, 0, 0,
|
||||||
|
$targetViewport->width, $targetViewport->height, $bg->color->red, $bg->color->green, $bg->color->blue, $bg->color->alpha);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
GFX::boxRGBA($targetViewport->renderPtr, 0, 0,
|
||||||
|
$targetViewport->width, $targetViewport->height, $bg->color->red, $bg->color->green, $bg->color->blue, $bg->color->alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
$thread->addToRenderStack(new Item($widgetId, $texture, new \SDL_FRect($targetViewport->x, $targetViewport->y, $targetViewport->width, $targetViewport->height), $index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10,7 +10,7 @@ use PHPNative\Renderer\Viewport;
|
|||||||
|
|
||||||
class Border
|
class Border
|
||||||
{
|
{
|
||||||
public static function render(string $widgetId, Thread $thread, array $styles, Viewport $targetViewport): void
|
public static function render(string $widgetId, Thread $thread, array $styles, Viewport $targetViewport, int $index): void
|
||||||
{
|
{
|
||||||
if(isset($styles[\PHPNative\Tailwind\Style\Border::class]) && $b = $styles[\PHPNative\Tailwind\Style\Border::class]) {
|
if(isset($styles[\PHPNative\Tailwind\Style\Border::class]) && $b = $styles[\PHPNative\Tailwind\Style\Border::class]) {
|
||||||
$texture = \SDL_CreateTexture($targetViewport->renderPtr, \SDL_PIXELFORMAT_RGBA8888, \SDL_TEXTUREACCESS_TARGET, $targetViewport->width, $targetViewport->height);
|
$texture = \SDL_CreateTexture($targetViewport->renderPtr, \SDL_PIXELFORMAT_RGBA8888, \SDL_TEXTUREACCESS_TARGET, $targetViewport->width, $targetViewport->height);
|
||||||
@ -38,7 +38,7 @@ class Border
|
|||||||
GFX::boxRGBA($targetViewport->renderPtr, $targetViewport->width - $b->right, 0,
|
GFX::boxRGBA($targetViewport->renderPtr, $targetViewport->width - $b->right, 0,
|
||||||
$targetViewport->width, $targetViewport->height, $b->color->red, $b->color->green, $b->color->blue, $b->color->alpha);
|
$targetViewport->width, $targetViewport->height, $b->color->red, $b->color->green, $b->color->blue, $b->color->alpha);
|
||||||
}
|
}
|
||||||
$thread->addToRenderStack(new Item($widgetId, $texture, new \SDL_FRect($targetViewport->x, $targetViewport->y, $targetViewport->width, $targetViewport->height), 10));
|
$thread->addToRenderStack(new Item($widgetId, $texture, new \SDL_FRect($targetViewport->x, $targetViewport->y, $targetViewport->width, $targetViewport->height), $index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
23
src/PHPNative/Renderer/src/Visuals/Cursor.php
Normal file
23
src/PHPNative/Renderer/src/Visuals/Cursor.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PHPNative\Renderer\Visuals;
|
||||||
|
|
||||||
|
use PHPNative\Renderer\GFX;
|
||||||
|
use PHPNative\Renderer\Item;
|
||||||
|
use PHPNative\Renderer\Thread;
|
||||||
|
use PHPNative\Renderer\Viewport;
|
||||||
|
|
||||||
|
class Cursor
|
||||||
|
{
|
||||||
|
public static function render(string $widgetId, Thread $thread, array $styles, Viewport $targetViewport, int $index = 0): void
|
||||||
|
{
|
||||||
|
$texture = \SDL_CreateTexture($targetViewport->renderPtr, \SDL_PIXELFORMAT_RGBA8888, \SDL_TEXTUREACCESS_TARGET, 4, $targetViewport->height);
|
||||||
|
\SDL_SetRenderTarget($targetViewport->renderPtr, $texture);
|
||||||
|
\SDL_SetRenderDrawColor($targetViewport->renderPtr, 0, 0, 0, 255);
|
||||||
|
\SDL_RenderClear($targetViewport->renderPtr);
|
||||||
|
|
||||||
|
GFX::boxRGBA($targetViewport->renderPtr, 0, 0, 4, $targetViewport->height, 128,128,128,255);
|
||||||
|
|
||||||
|
$thread->addToRenderStack(new Item($widgetId, $texture, new \SDL_FRect($targetViewport->x, $targetViewport->y, 4, $targetViewport->height), $index));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,10 +7,10 @@ use PHPNative\Renderer\Viewport;
|
|||||||
|
|
||||||
class Visuals
|
class Visuals
|
||||||
{
|
{
|
||||||
public static function render(string $widgetId, Thread $thread, array $styles, Viewport $targetViewport): void
|
public static function render(string $widgetId, Thread $thread, array $styles, Viewport $targetViewport, int $index = 0): void
|
||||||
{
|
{
|
||||||
Background::render($widgetId, $thread, $styles, $targetViewport);
|
Background::render($widgetId, $thread, $styles, $targetViewport, $index);
|
||||||
Border::render($widgetId, $thread, $styles, $targetViewport);
|
Border::render($widgetId, $thread, $styles, $targetViewport, $index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function changeViewport(string $widgetId, Thread $thread, array $styles, Viewport $viewport): void
|
public static function changeViewport(string $widgetId, Thread $thread, array $styles, Viewport $viewport): void
|
||||||
|
|||||||
@ -2,29 +2,40 @@
|
|||||||
|
|
||||||
namespace PHPNative\Renderer;
|
namespace PHPNative\Renderer;
|
||||||
|
|
||||||
|
use PHPNative\UI\Widget\Icon;
|
||||||
|
use PHPNative\UI\Widget\Image;
|
||||||
|
use PHPNative\UI\Widget\TextEdit;
|
||||||
use PHPNative\UI\BaseView;
|
use PHPNative\UI\BaseView;
|
||||||
use PHPNative\UI\View;
|
use PHPNative\UI\View;
|
||||||
use PHPNative\UI\Widget\Button;
|
use PHPNative\UI\Widget\Button;
|
||||||
use PHPNative\UI\Widget\Container;
|
use PHPNative\UI\Widget\Container;
|
||||||
use PHPNative\UI\Widget\Label;
|
use PHPNative\UI\Widget\Text;
|
||||||
|
|
||||||
class Widget
|
class Widget
|
||||||
{
|
{
|
||||||
public static function render(Thread $thread, ViewPort $viewPort, View $view): Viewport {
|
public static function render(Thread $thread, ViewPort $viewPort, View $view, int $index = 1): Viewport {
|
||||||
|
|
||||||
if($view instanceof BaseView) {
|
if($view instanceof BaseView) {
|
||||||
return \PHPNative\Renderer\Widgets\BaseView::render($thread, $viewPort, $view);
|
return \PHPNative\Renderer\Widgets\BaseView::render($thread, $viewPort, $view, $index);
|
||||||
}
|
}
|
||||||
if($view instanceof Button) {
|
if($view instanceof Button) {
|
||||||
return \PHPNative\Renderer\Widgets\Button::render($thread, $viewPort, $view);
|
return \PHPNative\Renderer\Widgets\Container::render($thread, $viewPort, $view, $index);
|
||||||
}
|
}
|
||||||
if($view instanceof Label) {
|
if($view instanceof Text) {
|
||||||
return \PHPNative\Renderer\Widgets\Label::render($thread, $viewPort, $view);
|
return \PHPNative\Renderer\Widgets\Text::render($thread, $viewPort, $view, $index);
|
||||||
|
}
|
||||||
|
if($view instanceof TextEdit) {
|
||||||
|
return \PHPNative\Renderer\Widgets\TextEdit::render($thread, $viewPort, $view, $index);
|
||||||
}
|
}
|
||||||
if($view instanceof Container) {
|
if($view instanceof Container) {
|
||||||
return \PHPNative\Renderer\Widgets\Container::render($thread, $viewPort, $view);
|
return \PHPNative\Renderer\Widgets\Container::render($thread, $viewPort, $view, $index);
|
||||||
|
}
|
||||||
|
if($view instanceof Image) {
|
||||||
|
return \PHPNative\Renderer\Widgets\Image::render($thread, $viewPort, $view, $index);
|
||||||
|
}
|
||||||
|
if($view instanceof Icon) {
|
||||||
|
return \PHPNative\Renderer\Widgets\Icon::render($thread, $viewPort, $view, $index);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -13,43 +13,7 @@ use PHPNative\Tailwind\Style\Padding;
|
|||||||
use PHPNative\Tailwind\Style\StateEnum;
|
use PHPNative\Tailwind\Style\StateEnum;
|
||||||
use PHPNative\Tailwind\StyleParser;
|
use PHPNative\Tailwind\StyleParser;
|
||||||
|
|
||||||
class BaseView
|
class BaseView extends Container
|
||||||
{
|
{
|
||||||
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\BaseView $view): Viewport
|
|
||||||
{
|
|
||||||
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, StateEnum::normal);
|
|
||||||
|
|
||||||
if(isset($styles[Margin::class]) && $m = $styles[Margin::class]) {
|
|
||||||
$viewport->x += $m->left;
|
|
||||||
$viewport->width -= ($m->right + $m->left);
|
|
||||||
$viewport->y += $m->top;
|
|
||||||
$viewport->height -= ($m->bottom + $m->top);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isset($styles[Background::class]) && $bg = $styles[Background::class]) {
|
|
||||||
$texture = \SDL_CreateTexture($viewport->renderPtr, \SDL_PIXELFORMAT_ARGB8888, \SDL_TEXTUREACCESS_TARGET, 200, 100);
|
|
||||||
\SDL_SetRenderTarget($viewport->renderPtr, $texture);
|
|
||||||
\SDL_SetRenderDrawColor($viewport->renderPtr, 0, 0, 0, 255);
|
|
||||||
\SDL_RenderClear($viewport->renderPtr);
|
|
||||||
$rect = new \SDL_FRect($viewport->x, $viewport->y, $viewport->width, $viewport->height);
|
|
||||||
|
|
||||||
\SDL_SetRenderDrawColor($viewport->renderPtr, $bg->color->red, $bg->color->green, $bg->color->blue, $bg->color->alpha);
|
|
||||||
\SDL_RenderFillRect($viewport->renderPtr, $rect);
|
|
||||||
|
|
||||||
$thread->addToRenderStack(new Item($view->getId(), $texture, $rect, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isset($styles[Padding::class]) && $m = $styles[Padding::class]) {
|
|
||||||
$viewport->x += $m->left;
|
|
||||||
$viewport->width -= ($m->right + $m->left);
|
|
||||||
$viewport->y += $m->top;
|
|
||||||
$viewport->height -= ($m->bottom + $m->top);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($view->getViews()->count() > 0) {
|
|
||||||
Widget::render($thread, $viewport, $view->getViews()->first());
|
|
||||||
}
|
|
||||||
|
|
||||||
return $viewport;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -8,6 +8,7 @@ use PHPNative\Renderer\Item;
|
|||||||
use PHPNative\Renderer\Thread;
|
use PHPNative\Renderer\Thread;
|
||||||
use PHPNative\Renderer\Viewport;
|
use PHPNative\Renderer\Viewport;
|
||||||
use PHPNative\Renderer\Widget;
|
use PHPNative\Renderer\Widget;
|
||||||
|
use PHPNative\Tailwind\Style\AlignEnum;
|
||||||
use PHPNative\Tailwind\Style\Background;
|
use PHPNative\Tailwind\Style\Background;
|
||||||
use PHPNative\Tailwind\Style\Basis;
|
use PHPNative\Tailwind\Style\Basis;
|
||||||
use PHPNative\Tailwind\Style\Border;
|
use PHPNative\Tailwind\Style\Border;
|
||||||
@ -23,15 +24,20 @@ use PHPNative\Tailwind\StyleParser;
|
|||||||
class Button
|
class Button
|
||||||
{
|
{
|
||||||
|
|
||||||
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Button $view): Viewport
|
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Button $view, int $index = 0): Viewport
|
||||||
{
|
{
|
||||||
|
|
||||||
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
|
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
|
||||||
|
|
||||||
$font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/segoe-ui.ttf' , 20);
|
|
||||||
if(isset($styles[Text::class]) && $t = $styles[Text::class]) {
|
if(isset($styles[Text::class]) && $t = $styles[Text::class]) {
|
||||||
$color = new \SDL_Color($t->color->red, $t->color->green, $t->color->blue, $t->color->alpha);
|
$font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/segoe-ui.ttf' , $t->size);
|
||||||
|
if($t->color->red != -1) {
|
||||||
|
$color = new \SDL_Color($t->color->red, $t->color->green, $t->color->blue, $t->color->alpha);
|
||||||
|
}else{
|
||||||
|
$color = new \SDL_Color(0, 0, 0, 255);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
|
$font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/segoe-ui.ttf' , 16);
|
||||||
$color = new \SDL_Color(0, 0, 0, 255);
|
$color = new \SDL_Color(0, 0, 0, 255);
|
||||||
}
|
}
|
||||||
$surface = \SDL_TTF_RenderText_Blended($font, $view->label, $color);
|
$surface = \SDL_TTF_RenderText_Blended($font, $view->label, $color);
|
||||||
@ -76,7 +82,7 @@ class Button
|
|||||||
$backdropViewport->height += ($m->top + $m->bottom);
|
$backdropViewport->height += ($m->top + $m->bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
\PHPNative\Renderer\Visuals\Visuals::render($view->getId(), $thread, $styles, $backdropViewport);
|
\PHPNative\Renderer\Visuals\Visuals::render($view->getId(), $thread, $styles, $backdropViewport, $index);
|
||||||
|
|
||||||
if((isset($styles[Width::class]) && $m = $styles[Width::class]) || (isset($styles[Basis::class]) && $m = $styles[Basis::class])) {
|
if((isset($styles[Width::class]) && $m = $styles[Width::class]) || (isset($styles[Basis::class]) && $m = $styles[Basis::class])) {
|
||||||
|
|
||||||
@ -87,10 +93,15 @@ class Button
|
|||||||
new \SDL_FRect(0, 0, $viewport->width, $surface->h)
|
new \SDL_FRect(0, 0, $viewport->width, $surface->h)
|
||||||
));
|
));
|
||||||
}else {
|
}else {
|
||||||
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), 3));
|
if(isset($styles[Text::class]) && $styles[Text::class]->align == AlignEnum::center) {
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x + (($viewport->width - $surface->w) /2), $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}elseif(isset($styles[Text::class]) && $styles[Text::class]->align == AlignEnum::right) {
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x + ($viewport->width - $surface->w), $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}else{
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,9 +22,9 @@ use PHPNative\Tailwind\StyleParser;
|
|||||||
|
|
||||||
class Container
|
class Container
|
||||||
{
|
{
|
||||||
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Container $view): Viewport
|
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Container $view, int $index = 0): Viewport
|
||||||
{
|
{
|
||||||
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, StateEnum::normal);
|
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
|
||||||
|
|
||||||
if(isset($styles[Margin::class]) && $m = $styles[Margin::class]) {
|
if(isset($styles[Margin::class]) && $m = $styles[Margin::class]) {
|
||||||
$viewport->x += $m->left;
|
$viewport->x += $m->left;
|
||||||
@ -46,6 +46,7 @@ class Container
|
|||||||
|
|
||||||
$flexStyles = [];
|
$flexStyles = [];
|
||||||
if($view->getViews() != null) {
|
if($view->getViews() != null) {
|
||||||
|
|
||||||
foreach ($view->getViews() as $subView) {
|
foreach ($view->getViews() as $subView) {
|
||||||
$found = false;
|
$found = false;
|
||||||
$stylesSubView = StyleParser::parse($subView->style)->getValidStyles($viewport->windowMediaQuery, StateEnum::normal);
|
$stylesSubView = StyleParser::parse($subView->style)->getValidStyles($viewport->windowMediaQuery, StateEnum::normal);
|
||||||
@ -68,13 +69,13 @@ class Container
|
|||||||
|
|
||||||
if ($found) {
|
if ($found) {
|
||||||
if (isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::column) {
|
if (isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::column) {
|
||||||
$viepo = new Viewport($viewport->windowId, $viewport->renderPtr, $viewport->x, $viewport->y, $width, $viewport->height, $viewport->windowWidth, $viewport->windowHeight, $viewport->windowMediaQuery);
|
$viepo = new Viewport($viewport->windowId, $viewport->windowPtr, $viewport->renderPtr, $viewport->x, $viewport->y, $width, $viewport->height, $viewport->windowWidth, $viewport->windowHeight, $viewport->windowMediaQuery);
|
||||||
} else {
|
} else {
|
||||||
$viepo = new Viewport($viewport->windowId, $viewport->renderPtr, $viewport->x + (count($flexStyles) === 0 ? 0 : end($flexStyles)->x+end($flexStyles)->width), $viewport->y, $width, $viewport->height, $viewport->windowWidth, $viewport->windowHeight, $viewport->windowMediaQuery);
|
$viepo = new Viewport($viewport->windowId, $viewport->windowPtr, $viewport->renderPtr, $viewport->x + (count($flexStyles) === 0 ? 0 : end($flexStyles)->x+end($flexStyles)->width), $viewport->y, $width, $viewport->height, $viewport->windowWidth, $viewport->windowHeight, $viewport->windowMediaQuery);
|
||||||
}
|
}
|
||||||
$flexStyles[] = $viepo;
|
$flexStyles[] = $viepo;
|
||||||
} else {
|
} else {
|
||||||
$flexStyles[] = $viewport;
|
$flexStyles[] = clone $viewport;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ class Container
|
|||||||
if (isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::column) {
|
if (isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::column) {
|
||||||
$subViewPort = array_shift($flexStyles);
|
$subViewPort = array_shift($flexStyles);
|
||||||
$subViewPort->y = $viewport->y - $view->getMoveToY();
|
$subViewPort->y = $viewport->y - $view->getMoveToY();
|
||||||
$vp = Widget::render($thread, $subViewPort, $subView);
|
$vp = Widget::render($thread, $subViewPort, $subView, $index+1);
|
||||||
if($vp->y < $targetViewport->y) {
|
if($vp->y < $targetViewport->y) {
|
||||||
$thread->clipFromStack($subView->getId(), y: $targetViewport->y-$vp->y);
|
$thread->clipFromStack($subView->getId(), y: $targetViewport->y-$vp->y);
|
||||||
}
|
}
|
||||||
@ -93,9 +94,19 @@ class Container
|
|||||||
|
|
||||||
$viewport->y += $vp->height;
|
$viewport->y += $vp->height;
|
||||||
$viewport->height -= $vp->height;
|
$viewport->height -= $vp->height;
|
||||||
} else {
|
} elseif(isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::row) {
|
||||||
$vp = Widget::render($thread, array_shift($flexStyles), $subView);
|
$vp = Widget::render($thread, array_shift($flexStyles), $subView, $index+1);
|
||||||
$topHeight = max($topHeight, $vp->height);
|
$topHeight = max($topHeight, $vp->height);
|
||||||
|
} else{
|
||||||
|
$sfs = array_shift($flexStyles);
|
||||||
|
$vp = Widget::render($thread, $sfs, $subView, $index+1);
|
||||||
|
$topHeight = max($topHeight, $vp->height);
|
||||||
|
if(count($flexStyles) > 0) {
|
||||||
|
if($vp->addX > 0) {
|
||||||
|
$flexStyles[0]->x += $vp->addX;
|
||||||
|
$flexStyles[0]->width -= $vp->addX;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::column) {
|
if (isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::column) {
|
||||||
@ -104,16 +115,43 @@ class Container
|
|||||||
$targetViewport->height = $topHeight;
|
$targetViewport->height = $topHeight;
|
||||||
$viewport->y += $topHeight;
|
$viewport->y += $topHeight;
|
||||||
$viewport->height = $topHeight;
|
$viewport->height = $topHeight;
|
||||||
|
if(isset($styles[Padding::class]) && $m = $styles[Padding::class]) {
|
||||||
|
$targetViewport->height += ($m->bottom + $m->top);
|
||||||
|
$viewport->height += ($m->bottom + $m->top);
|
||||||
|
}
|
||||||
|
if(isset($styles[Margin::class]) && $m = $styles[Margin::class]) {
|
||||||
|
$viewport->height += ($m->bottom + $m->top);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
\PHPNative\Renderer\Visuals\Visuals::render($view->getId(), $thread, $styles, $targetViewport);
|
if($thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEMOVE) {
|
||||||
|
if( $targetViewport->x <= $thread->getEvent()->x &&
|
||||||
|
$thread->getEvent()->x <= $targetViewport->x + $targetViewport->width &&
|
||||||
|
$targetViewport->y <= $thread->getEvent()->y &&
|
||||||
|
$thread->getEvent()->y <= $targetViewport->y + $targetViewport->height ) {
|
||||||
|
$view->state = StateEnum::hover;
|
||||||
|
}else{
|
||||||
|
$view->state = StateEnum::normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($view instanceof \PHPNative\UI\Widget\Button && $thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEBUTTON_UP) {
|
||||||
|
if( $targetViewport->x <= $thread->getEvent()->x &&
|
||||||
|
$thread->getEvent()->x <= $targetViewport->x + $targetViewport->width &&
|
||||||
|
$targetViewport->y <= $thread->getEvent()->y && $thread->getEvent()->y <=
|
||||||
|
$targetViewport->y + $targetViewport->height ) {
|
||||||
|
$view->onClick($thread->worker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\PHPNative\Renderer\Visuals\Visuals::render($view->getId(), $thread, $styles, $targetViewport, $index);
|
||||||
|
|
||||||
if (isset($styles[Overflow::class]) && $f = $styles[Overflow::class] && (
|
if (isset($styles[Overflow::class]) && $f = $styles[Overflow::class] && (
|
||||||
$styles[Overflow::class]->y == OverflowEnum::scroll ||
|
$styles[Overflow::class]->y == OverflowEnum::scroll ||
|
||||||
($styles[Overflow::class]->y == OverflowEnum::auto && $viewport->height < 0)
|
($styles[Overflow::class]->y == OverflowEnum::auto && $viewport->height < 0)
|
||||||
)) {
|
)) {
|
||||||
|
|
||||||
\PHPNative\Renderer\Visuals\Scrollbar::renderBackground($view->getId(), $thread, $styles, $targetViewport);
|
\PHPNative\Renderer\Visuals\Scrollbar::renderBackground($view->getId(), $thread, $styles, $targetViewport, $index);
|
||||||
|
|
||||||
if ($thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEBUTTON_DOWN) {
|
if ($thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEBUTTON_DOWN) {
|
||||||
if ($targetViewport->x + $targetViewport->width - 10 <= $thread->getEvent()->x &&
|
if ($targetViewport->x + $targetViewport->width - 10 <= $thread->getEvent()->x &&
|
||||||
@ -154,7 +192,7 @@ class Container
|
|||||||
$sliderViewport->y = $targetViewport->y + (int)($view->getMoveToY()*$ratio);
|
$sliderViewport->y = $targetViewport->y + (int)($view->getMoveToY()*$ratio);
|
||||||
$sliderViewport->height = (int)($ratio*100 * $ohP);
|
$sliderViewport->height = (int)($ratio*100 * $ohP);
|
||||||
|
|
||||||
\PHPNative\Renderer\Visuals\Scrollbar::renderSlider($view->getId(), $thread, $styles, $sliderViewport);
|
\PHPNative\Renderer\Visuals\Scrollbar::renderSlider($view->getId(), $thread, $styles, $sliderViewport, $index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
103
src/PHPNative/Renderer/src/Widgets/Icon.php
Normal file
103
src/PHPNative/Renderer/src/Widgets/Icon.php
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PHPNative\Renderer\Widgets;
|
||||||
|
|
||||||
|
use PHPNative\Event\EventType;
|
||||||
|
use PHPNative\Renderer\GFX;
|
||||||
|
use PHPNative\Renderer\Item;
|
||||||
|
use PHPNative\Renderer\Thread;
|
||||||
|
use PHPNative\Renderer\Viewport;
|
||||||
|
use PHPNative\Renderer\Widget;
|
||||||
|
use PHPNative\Tailwind\Style\Background;
|
||||||
|
use PHPNative\Tailwind\Style\Basis;
|
||||||
|
use PHPNative\Tailwind\Style\Border;
|
||||||
|
use PHPNative\Tailwind\Style\Margin;
|
||||||
|
use PHPNative\Tailwind\Style\MediaQueryEnum;
|
||||||
|
use PHPNative\Tailwind\Style\Padding;
|
||||||
|
use PHPNative\Tailwind\Style\StateEnum;
|
||||||
|
use PHPNative\Tailwind\Style\Text;
|
||||||
|
use PHPNative\Tailwind\Style\Unit;
|
||||||
|
use PHPNative\Tailwind\Style\Width;
|
||||||
|
use PHPNative\Tailwind\StyleParser;
|
||||||
|
|
||||||
|
class Icon
|
||||||
|
{
|
||||||
|
|
||||||
|
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Icon $view, int $index = 0): Viewport
|
||||||
|
{
|
||||||
|
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
|
||||||
|
|
||||||
|
if(isset($styles[\PHPNative\Tailwind\Style\Text::class]) && $t = $styles[\PHPNative\Tailwind\Style\Text::class]) {
|
||||||
|
$font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/symbol.ttf' , $view->size);
|
||||||
|
if($t->color->red != -1) {
|
||||||
|
$color = new \SDL_Color($t->color->red, $t->color->green, $t->color->blue, $t->color->alpha);
|
||||||
|
}else{
|
||||||
|
$color = new \SDL_Color(0, 0, 0, 255);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/symbol.ttf' , $view->size);
|
||||||
|
$color = new \SDL_Color(0, 0, 0, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
$surface = \SDL_TTF_RenderGlyph_Blended($font, $view->icon->value, $color);
|
||||||
|
|
||||||
|
if(!isset($styles[Basis::class]) && !isset($styles[Width::class])) {
|
||||||
|
$viewport->width = $surface->w;
|
||||||
|
}
|
||||||
|
$viewport->height = $surface->h;
|
||||||
|
|
||||||
|
if(isset($styles[Margin::class]) && $m = $styles[Margin::class]) {
|
||||||
|
$viewport->x += $m->left;
|
||||||
|
$viewport->width -= ($m->right + $m->left);
|
||||||
|
$viewport->y += $m->top;
|
||||||
|
$viewport->height += ($m->bottom + $m->top);
|
||||||
|
}
|
||||||
|
|
||||||
|
$backdropViewport = clone $viewport;
|
||||||
|
$backdropViewport->height = $surface->h;
|
||||||
|
|
||||||
|
if($thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEMOVE) {
|
||||||
|
if( $viewport->x <= $thread->getEvent()->x &&
|
||||||
|
$thread->getEvent()->x <= $viewport->x + $viewport->width &&
|
||||||
|
$viewport->y <= $thread->getEvent()->y &&
|
||||||
|
$thread->getEvent()->y <= $viewport->y + $viewport->height ) {
|
||||||
|
$view->state = StateEnum::hover;
|
||||||
|
}else{
|
||||||
|
$view->state = StateEnum::normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($styles[Padding::class]) && $m = $styles[Padding::class]) {
|
||||||
|
$viewport->x += $m->left;
|
||||||
|
$viewport->width -= ($m->right + $m->left);
|
||||||
|
$viewport->y += $m->top;
|
||||||
|
$viewport->height += ($m->bottom + $m->top);
|
||||||
|
$backdropViewport->height += ($m->bottom + $m->top);
|
||||||
|
}
|
||||||
|
|
||||||
|
\PHPNative\Renderer\Visuals\Visuals::render($view->getId(), $thread, $styles, $backdropViewport, $index);
|
||||||
|
|
||||||
|
if((isset($styles[Width::class]) && $m = $styles[Width::class]) || (isset($styles[Basis::class]) && $m = $styles[Basis::class])) {
|
||||||
|
|
||||||
|
$textureFont = \SDL_CreateTextureFromSurface($viewport->renderPtr, $surface);
|
||||||
|
if($surface->w > $viewport->width) {
|
||||||
|
$thread->addToRenderStack(new Item($textureFont,
|
||||||
|
new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), 3,
|
||||||
|
new \SDL_FRect(0, 0, $viewport->width, $surface->h)
|
||||||
|
));
|
||||||
|
}else{
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$textureFont = \SDL_CreateTextureFromSurface($viewport->renderPtr, $surface);
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isset($styles[Basis::class]) && !isset($styles[Width::class])) {
|
||||||
|
$viewport->addX = $viewport->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $viewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -20,20 +20,17 @@ use PHPNative\Tailwind\Style\Unit;
|
|||||||
use PHPNative\Tailwind\Style\Width;
|
use PHPNative\Tailwind\Style\Width;
|
||||||
use PHPNative\Tailwind\StyleParser;
|
use PHPNative\Tailwind\StyleParser;
|
||||||
|
|
||||||
class Label
|
class Image
|
||||||
{
|
{
|
||||||
|
|
||||||
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Label $view): Viewport
|
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Image $view, int $index = 0): Viewport
|
||||||
{
|
{
|
||||||
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
|
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
|
||||||
|
|
||||||
$font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/segoe-ui.ttf' , 20);
|
if(!file_exists($view->src)) {
|
||||||
if(isset($styles[Text::class]) && $t = $styles[Text::class]) {
|
return $viewport;
|
||||||
$color = new \SDL_Color($t->color->red, $t->color->green, $t->color->blue, $t->color->alpha);
|
|
||||||
}else{
|
|
||||||
$color = new \SDL_Color(0, 0, 0, 255);
|
|
||||||
}
|
}
|
||||||
$surface = \SDL_TTF_RenderText_Blended($font, $view->label, $color);
|
$surface = \SDL_IMG_Load($view->src);
|
||||||
|
|
||||||
$viewport->height = $surface->h;
|
$viewport->height = $surface->h;
|
||||||
|
|
||||||
@ -66,7 +63,7 @@ class Label
|
|||||||
$backdropViewport->height += ($m->bottom + $m->top);
|
$backdropViewport->height += ($m->bottom + $m->top);
|
||||||
}
|
}
|
||||||
|
|
||||||
\PHPNative\Renderer\Visuals\Visuals::render($view->getId(), $thread, $styles, $backdropViewport);
|
\PHPNative\Renderer\Visuals\Visuals::render($view->getId(), $thread, $styles, $backdropViewport, $index);
|
||||||
|
|
||||||
if((isset($styles[Width::class]) && $m = $styles[Width::class]) || (isset($styles[Basis::class]) && $m = $styles[Basis::class])) {
|
if((isset($styles[Width::class]) && $m = $styles[Width::class]) || (isset($styles[Basis::class]) && $m = $styles[Basis::class])) {
|
||||||
|
|
||||||
@ -77,10 +74,11 @@ class Label
|
|||||||
new \SDL_FRect(0, 0, $viewport->width, $surface->h)
|
new \SDL_FRect(0, 0, $viewport->width, $surface->h)
|
||||||
));
|
));
|
||||||
}else{
|
}else{
|
||||||
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), 3));
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
$textureFont = \SDL_CreateTextureFromSurface($viewport->renderPtr, $surface);
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $viewport;
|
return $viewport;
|
||||||
119
src/PHPNative/Renderer/src/Widgets/Text.php
Normal file
119
src/PHPNative/Renderer/src/Widgets/Text.php
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PHPNative\Renderer\Widgets;
|
||||||
|
|
||||||
|
use PHPNative\Event\EventType;
|
||||||
|
use PHPNative\Renderer\GFX;
|
||||||
|
use PHPNative\Renderer\Item;
|
||||||
|
use PHPNative\Renderer\Thread;
|
||||||
|
use PHPNative\Renderer\Viewport;
|
||||||
|
use PHPNative\Tailwind\Style\AlignEnum;
|
||||||
|
use PHPNative\Tailwind\Style\Basis;
|
||||||
|
use PHPNative\Tailwind\Style\Border;
|
||||||
|
use PHPNative\Tailwind\Style\Margin;
|
||||||
|
use PHPNative\Tailwind\Style\MediaQueryEnum;
|
||||||
|
use PHPNative\Tailwind\Style\Padding;
|
||||||
|
use PHPNative\Tailwind\Style\StateEnum;
|
||||||
|
use PHPNative\Tailwind\Style\Width;
|
||||||
|
use PHPNative\Tailwind\StyleParser;
|
||||||
|
|
||||||
|
class Text
|
||||||
|
{
|
||||||
|
|
||||||
|
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Text $view, int $index = 0): Viewport
|
||||||
|
{
|
||||||
|
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
|
||||||
|
|
||||||
|
if(isset($styles[\PHPNative\Tailwind\Style\Text::class]) && $t = $styles[\PHPNative\Tailwind\Style\Text::class]) {
|
||||||
|
$font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/segoe-ui.ttf' , $t->size);
|
||||||
|
if($t->color->red != -1) {
|
||||||
|
$color = new \SDL_Color($t->color->red, $t->color->green, $t->color->blue, $t->color->alpha);
|
||||||
|
}else{
|
||||||
|
$color = new \SDL_Color(0, 0, 0, 255);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/segoe-ui.ttf' , 16);
|
||||||
|
$color = new \SDL_Color(0, 0, 0, 255);
|
||||||
|
}
|
||||||
|
$surface = \SDL_TTF_RenderText_Blended($font, $view->text, $color);
|
||||||
|
|
||||||
|
if(!isset($styles[Basis::class]) && !isset($styles[Width::class])) {
|
||||||
|
$viewport->width = $surface->w;
|
||||||
|
}
|
||||||
|
$viewport->height = $surface->h;
|
||||||
|
|
||||||
|
if(isset($styles[Margin::class]) && $m = $styles[Margin::class]) {
|
||||||
|
$viewport->x += $m->left;
|
||||||
|
if(!isset($styles[Basis::class]) && !isset($styles[Width::class])) {
|
||||||
|
$viewport->width += ($m->right + $m->left);
|
||||||
|
}else{
|
||||||
|
$viewport->width -= ($m->right + $m->left);
|
||||||
|
}
|
||||||
|
$viewport->y += $m->top;
|
||||||
|
$viewport->height += ($m->bottom + $m->top);
|
||||||
|
}
|
||||||
|
|
||||||
|
$backdropViewport = clone $viewport;
|
||||||
|
$backdropViewport->height = $surface->h;
|
||||||
|
|
||||||
|
if($thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEMOVE) {
|
||||||
|
if( $viewport->x <= $thread->getEvent()->x &&
|
||||||
|
$thread->getEvent()->x <= $viewport->x + $viewport->width &&
|
||||||
|
$viewport->y <= $thread->getEvent()->y &&
|
||||||
|
$thread->getEvent()->y <= $viewport->y + $viewport->height ) {
|
||||||
|
$view->state = StateEnum::hover;
|
||||||
|
}else{
|
||||||
|
$view->state = StateEnum::normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($styles[Padding::class]) && $m = $styles[Padding::class]) {
|
||||||
|
$viewport->x += $m->left;
|
||||||
|
$viewport->width -= ($m->right + $m->left);
|
||||||
|
$viewport->y += $m->top;
|
||||||
|
$viewport->height += ($m->bottom + $m->top);
|
||||||
|
$backdropViewport->height += ($m->top + $m->bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
\PHPNative\Renderer\Visuals\Visuals::render($view->getId(), $thread, $styles, $backdropViewport, $index);
|
||||||
|
|
||||||
|
if((isset($styles[Width::class]) && $m = $styles[Width::class]) || (isset($styles[Basis::class]) && $m = $styles[Basis::class])) {
|
||||||
|
|
||||||
|
$textureFont = \SDL_CreateTextureFromSurface($viewport->renderPtr, $surface);
|
||||||
|
if($surface->w > $viewport->width) {
|
||||||
|
$thread->addToRenderStack(new Item($textureFont,
|
||||||
|
new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), 3,
|
||||||
|
new \SDL_FRect(0, 0, $viewport->width, $surface->h)
|
||||||
|
));
|
||||||
|
}else {
|
||||||
|
if(isset($styles[\PHPNative\Tailwind\Style\Text::class]) && $styles[\PHPNative\Tailwind\Style\Text::class]->align == AlignEnum::center) {
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x + (($viewport->width - $surface->w) /2), $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}elseif(isset($styles[Text::class]) && $styles[Text::class]->align == AlignEnum::right) {
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x + ($viewport->width - $surface->w), $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}else{
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
$textureFont = \SDL_CreateTextureFromSurface($viewport->renderPtr, $surface);
|
||||||
|
if($surface->w > $viewport->width) {
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont,
|
||||||
|
new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), 3,
|
||||||
|
new \SDL_FRect(0, 0, $viewport->width, $surface->h)
|
||||||
|
));
|
||||||
|
}else {
|
||||||
|
if(isset($styles[\PHPNative\Tailwind\Style\Text::class]) && $styles[\PHPNative\Tailwind\Style\Text::class]->align == AlignEnum::center) {
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x + (($viewport->width - $surface->w) /2), $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}elseif(isset($styles[Text::class]) && $styles[Text::class]->align == AlignEnum::right) {
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x + ($viewport->width - $surface->w), $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}else{
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $viewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
179
src/PHPNative/Renderer/src/Widgets/TextEdit.php
Normal file
179
src/PHPNative/Renderer/src/Widgets/TextEdit.php
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PHPNative\Renderer\Widgets;
|
||||||
|
|
||||||
|
use PHPNative\Event\EventType;
|
||||||
|
use PHPNative\Event\Key;
|
||||||
|
use PHPNative\Renderer\GFX;
|
||||||
|
use PHPNative\Renderer\Item;
|
||||||
|
use PHPNative\Renderer\Thread;
|
||||||
|
use PHPNative\Renderer\Viewport;
|
||||||
|
use PHPNative\Renderer\Visuals\Cursor;
|
||||||
|
use PHPNative\Renderer\Widget;
|
||||||
|
use PHPNative\Tailwind\Style\AlignEnum;
|
||||||
|
use PHPNative\Tailwind\Style\Background;
|
||||||
|
use PHPNative\Tailwind\Style\Basis;
|
||||||
|
use PHPNative\Tailwind\Style\Border;
|
||||||
|
use PHPNative\Tailwind\Style\Margin;
|
||||||
|
use PHPNative\Tailwind\Style\MediaQueryEnum;
|
||||||
|
use PHPNative\Tailwind\Style\Padding;
|
||||||
|
use PHPNative\Tailwind\Style\StateEnum;
|
||||||
|
use PHPNative\Tailwind\Style\Text;
|
||||||
|
use PHPNative\Tailwind\Style\Unit;
|
||||||
|
use PHPNative\Tailwind\Style\Width;
|
||||||
|
use PHPNative\Tailwind\StyleParser;
|
||||||
|
|
||||||
|
class TextEdit
|
||||||
|
{
|
||||||
|
|
||||||
|
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\TextEdit $view, int $index = 0): Viewport
|
||||||
|
{
|
||||||
|
|
||||||
|
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
|
||||||
|
|
||||||
|
if(isset($styles[Text::class]) && $t = $styles[Text::class]) {
|
||||||
|
$font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/segoe-ui.ttf' , $t->size);
|
||||||
|
if($t->color->red != -1) {
|
||||||
|
$color = new \SDL_Color($t->color->red, $t->color->green, $t->color->blue, $t->color->alpha);
|
||||||
|
}else{
|
||||||
|
$color = new \SDL_Color(0, 0, 0, 255);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/segoe-ui.ttf' , 16);
|
||||||
|
$color = new \SDL_Color(0, 0, 0, 255);
|
||||||
|
}
|
||||||
|
if($view->value == "" && $view->placeholder != null) {
|
||||||
|
$color = new \SDL_Color(0, 0, 0, 128);
|
||||||
|
$surface = \SDL_TTF_RenderText_Blended($font, $view->placeholder, $color);
|
||||||
|
$cursorWidth = 0;
|
||||||
|
}else{
|
||||||
|
$surface = \SDL_TTF_RenderText_Blended($font, $view->value, $color);
|
||||||
|
$surfaceCursor = \SDL_TTF_RenderText_Blended($font, mb_substr($view->value, 0, $view->textEditIndex), $color);
|
||||||
|
$cursorWidth = $surfaceCursor->w;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$viewport->height = $surface->h;
|
||||||
|
|
||||||
|
if(isset($styles[Margin::class]) && $m = $styles[Margin::class]) {
|
||||||
|
$viewport->x += $m->left;
|
||||||
|
$viewport->width -= ($m->right + $m->left);
|
||||||
|
$viewport->y += $m->top;
|
||||||
|
$viewport->height += ($m->bottom + $m->top);
|
||||||
|
}
|
||||||
|
|
||||||
|
$backdropViewport = clone $viewport;
|
||||||
|
$backdropViewport->height = $surface->h;
|
||||||
|
|
||||||
|
if($thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEMOVE) {
|
||||||
|
if( $viewport->x <= $thread->getEvent()->x &&
|
||||||
|
$thread->getEvent()->x <= $viewport->x + $viewport->width &&
|
||||||
|
$viewport->y <= $thread->getEvent()->y &&
|
||||||
|
$thread->getEvent()->y <= $viewport->y + $viewport->height ) {
|
||||||
|
if($view->state == StateEnum::focus || $view->state == StateEnum::hoverfocus) {
|
||||||
|
$view->state = StateEnum::hoverfocus;
|
||||||
|
}else{
|
||||||
|
$view->state = StateEnum::hover;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if($view->state == StateEnum::hoverfocus ) {
|
||||||
|
$view->state = StateEnum::focus;
|
||||||
|
}
|
||||||
|
if($view->state != StateEnum::focus ) {
|
||||||
|
$view->state = StateEnum::normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEBUTTON_UP) {
|
||||||
|
if( $viewport->x <= $thread->getEvent()->x &&
|
||||||
|
$thread->getEvent()->x <= $viewport->x + $viewport->width &&
|
||||||
|
$viewport->y <= $thread->getEvent()->y && $thread->getEvent()->y <=
|
||||||
|
$viewport->y + $viewport->height ) {
|
||||||
|
$view->state = StateEnum::focus;
|
||||||
|
\SDL_StartTextInput($thread->windowPtr);
|
||||||
|
}else{
|
||||||
|
\SDL_StopTextInput($thread->windowPtr);
|
||||||
|
$view->state = StateEnum::normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($thread->getEvent() && $thread->getEvent()->getType() === EventType::KEYUP && $thread->getEvent()->key == Key::BACKSPACE) {
|
||||||
|
if($view->textEditIndex > 0) {
|
||||||
|
$view->value = self::str_delete($view->value, $view->textEditIndex);
|
||||||
|
$view->textEditIndex -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($thread->getEvent() && $thread->getEvent()->getType() === EventType::TEXTINPUT && $view->state === StateEnum::focus) {
|
||||||
|
if($view->value != "") {
|
||||||
|
$view->value = self::str_insert($view->value, $thread->getEvent()->text, $view->textEditIndex);
|
||||||
|
}else {
|
||||||
|
$view->value = $view->value . $thread->getEvent()->text;
|
||||||
|
}
|
||||||
|
$view->textEditIndex += mb_strlen($thread->getEvent()->text);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($thread->getEvent() && $thread->getEvent()->getType() === EventType::KEYUP && $thread->getEvent()->key == Key::SDLK_LEFT) {
|
||||||
|
if($view->textEditIndex > 0) {
|
||||||
|
$view->textEditIndex -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($thread->getEvent() && $thread->getEvent()->getType() === EventType::KEYUP && $thread->getEvent()->key == Key::SDLK_RIGHT) {
|
||||||
|
if($view->textEditIndex < mb_strlen($view->value)) {
|
||||||
|
$view->textEditIndex += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(isset($styles[Padding::class]) && $m = $styles[Padding::class]) {
|
||||||
|
$viewport->x += $m->left;
|
||||||
|
$viewport->width -= ($m->right + $m->left);
|
||||||
|
$viewport->y += $m->top;
|
||||||
|
$viewport->height += ($m->bottom + $m->top);
|
||||||
|
$backdropViewport->height += ($m->top + $m->bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
\PHPNative\Renderer\Visuals\Visuals::render($view->getId(), $thread, $styles, $backdropViewport, $index);
|
||||||
|
|
||||||
|
$currentTime = \SDL_GetTicks() / 500;
|
||||||
|
|
||||||
|
if (((int)$currentTime & 1) && ($view->state == StateEnum::focus || $view->state == StateEnum::hoverfocus)) {
|
||||||
|
$viewportCorsor = clone $viewport;
|
||||||
|
$viewportCorsor->height = $surface->h;
|
||||||
|
$viewportCorsor->x += $cursorWidth;
|
||||||
|
Cursor::render($view->getId(), $thread, $styles, $viewportCorsor, $index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((isset($styles[Width::class]) && $m = $styles[Width::class]) || (isset($styles[Basis::class]) && $m = $styles[Basis::class])) {
|
||||||
|
|
||||||
|
$textureFont = \SDL_CreateTextureFromSurface($viewport->renderPtr, $surface);
|
||||||
|
if($surface->w > $viewport->width) {
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont,
|
||||||
|
new \SDL_FRect($viewport->x, $viewport->y, $viewport->width, $surface->h), 3,
|
||||||
|
new \SDL_FRect($surface->w - $viewport->width, 0, $viewport->width, $surface->h)
|
||||||
|
));
|
||||||
|
}else {
|
||||||
|
if(isset($styles[Text::class]) && $styles[Text::class]->align == AlignEnum::center) {
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x + (($viewport->width - $surface->w) /2), $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}elseif(isset($styles[Text::class]) && $styles[Text::class]->align == AlignEnum::right) {
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x + ($viewport->width - $surface->w), $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}else{
|
||||||
|
$thread->addToRenderStack(new Item($view->getId(), $textureFont, new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), ++$index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $viewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function str_delete(string $str, int $pos = 0) {
|
||||||
|
return mb_substr($str, 0, $pos-1) . mb_substr($str, $pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function str_insert(string $oldString, string $newString, int $pos = 0) {
|
||||||
|
return mb_substr($oldString, 0, $pos) . $newString . mb_substr($oldString, $pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/PHPNative/Storage/composer.json
Normal file
18
src/PHPNative/Storage/composer.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "phpnative/storage",
|
||||||
|
"license": "MIT",
|
||||||
|
"require": {
|
||||||
|
"php": "^8.3",
|
||||||
|
"zumba/json-serializer": "^3"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"PHPNative\\Storage\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"PHPNative\\Storage\\Tests\\": "tests"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
67
src/PHPNative/Storage/src/Storage.php
Normal file
67
src/PHPNative/Storage/src/Storage.php
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace PHPNative\Storage;
|
||||||
|
|
||||||
|
use PHPNative\Framework\App;
|
||||||
|
use Zumba\JsonSerializer\JsonSerializer;
|
||||||
|
|
||||||
|
class Storage
|
||||||
|
{
|
||||||
|
public function __construct(private JsonSerializer $jsonSerializer, private App $appConfig)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveModel(object $model): void
|
||||||
|
{
|
||||||
|
$path = $this->getLocalAppData() . DIRECTORY_SEPARATOR . md5($model::class). '.json';
|
||||||
|
if(!file_exists($this->getLocalAppData())) {
|
||||||
|
mkdir($this->getLocalAppData(), 0777, true);
|
||||||
|
}
|
||||||
|
file_put_contents($path, $this->jsonSerializer->serialize($model));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template T
|
||||||
|
* @param class-string<T> $className
|
||||||
|
* @return T
|
||||||
|
*/
|
||||||
|
public function loadModel(string $className): object
|
||||||
|
{
|
||||||
|
$path = $this->getLocalAppData() . DIRECTORY_SEPARATOR . md5($className). '.json';
|
||||||
|
if(file_exists($path)) {
|
||||||
|
return $this->jsonSerializer->unserialize(file_get_contents($path));
|
||||||
|
}else{
|
||||||
|
return new $className();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function getLocalAppData() {
|
||||||
|
$homeDir = $_SERVER['HOME'] ?? '';
|
||||||
|
|
||||||
|
if(empty($homeDir)) {
|
||||||
|
$homeDir = getenv('HOME');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(empty($homeDir) && $this->is_windows()) {
|
||||||
|
$homeData = $_SERVER['LOCALAPPDATA'] ?? '';
|
||||||
|
|
||||||
|
$homeDir = $homeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(empty($homeDir) && function_exists('exec')) {
|
||||||
|
if($this->is_windows()) {
|
||||||
|
$homeDir = exec('echo %userprofile%');
|
||||||
|
} else {
|
||||||
|
$homeDir = exec('echo ~');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(DIRECTORY_SEPARATOR ,[$homeDir, $this->appConfig->getName()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function is_windows() {
|
||||||
|
return strncasecmp(PHP_OS, "WIN", 3) === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
8
src/PHPNative/Tailwind/src/Data/Icon.php
Normal file
8
src/PHPNative/Tailwind/src/Data/Icon.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PHPNative\Tailwind\Data;
|
||||||
|
|
||||||
|
enum Icon:int
|
||||||
|
{
|
||||||
|
case plus = 57669;
|
||||||
|
}
|
||||||
@ -8,6 +8,7 @@ use PHPNative\Tailwind\Style\Margin;
|
|||||||
use PHPNative\Tailwind\Style\MediaQueryEnum;
|
use PHPNative\Tailwind\Style\MediaQueryEnum;
|
||||||
use PHPNative\Tailwind\Style\Padding;
|
use PHPNative\Tailwind\Style\Padding;
|
||||||
use PHPNative\Tailwind\Style\StateEnum;
|
use PHPNative\Tailwind\Style\StateEnum;
|
||||||
|
use PHPNative\Tailwind\Style\Text;
|
||||||
|
|
||||||
class StyleCollection extends TypedCollection
|
class StyleCollection extends TypedCollection
|
||||||
{
|
{
|
||||||
@ -40,6 +41,8 @@ class StyleCollection extends TypedCollection
|
|||||||
\PHPNative\Tailwind\Parser\Margin::merge($tmp[$style->style::class], $style->style);
|
\PHPNative\Tailwind\Parser\Margin::merge($tmp[$style->style::class], $style->style);
|
||||||
}elseif(isset($tmp[$style->style::class]) && $style->style::class === Border::class) {
|
}elseif(isset($tmp[$style->style::class]) && $style->style::class === Border::class) {
|
||||||
\PHPNative\Tailwind\Parser\Border::merge($tmp[$style->style::class], $style->style);
|
\PHPNative\Tailwind\Parser\Border::merge($tmp[$style->style::class], $style->style);
|
||||||
|
}elseif(isset($tmp[$style->style::class]) && $style->style::class === Text::class) {
|
||||||
|
\PHPNative\Tailwind\Parser\Text::merge($tmp[$style->style::class], $style->style);
|
||||||
}else{
|
}else{
|
||||||
$tmp[$style->style::class] = $style->style;
|
$tmp[$style->style::class] = $style->style;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,12 +4,43 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace PHPNative\Tailwind\Parser;
|
namespace PHPNative\Tailwind\Parser;
|
||||||
|
|
||||||
|
use PHPNative\Tailwind\Style\AlignEnum;
|
||||||
|
|
||||||
class Text implements Parser
|
class Text implements Parser
|
||||||
{
|
{
|
||||||
public static function parse(string $style): ?\PHPNative\Tailwind\Style\Text
|
public static function parse(string $style): ?\PHPNative\Tailwind\Style\Text
|
||||||
{
|
{
|
||||||
$color = new \PHPNative\Tailwind\Style\Color();
|
$color = new \PHPNative\Tailwind\Style\Color();
|
||||||
|
|
||||||
|
preg_match_all('/text-(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)/', $style, $output_array);
|
||||||
|
if (count($output_array[0]) > 0) {
|
||||||
|
$size = match ((string)$output_array[1][0]) {
|
||||||
|
'xs' => 12,
|
||||||
|
'sm' => 14,
|
||||||
|
'base' => 16,
|
||||||
|
'lg' => 18,
|
||||||
|
'xl' => 20,
|
||||||
|
'2xl' => 24,
|
||||||
|
'3xl' => 30,
|
||||||
|
'4xl' => 36,
|
||||||
|
'5xl' => 48,
|
||||||
|
'6xl' => 60,
|
||||||
|
'7xl' => 72,
|
||||||
|
'8xl' => 96,
|
||||||
|
'9xl' => 128,
|
||||||
|
};
|
||||||
|
return new \PHPNative\Tailwind\Style\Text(size: $size);
|
||||||
|
}
|
||||||
|
|
||||||
|
preg_match_all('/text-(center|right|left)/', $style, $output_array);
|
||||||
|
if (count($output_array[0]) > 0) {
|
||||||
|
return match ((string)$output_array[1][0]) {
|
||||||
|
'left' => new \PHPNative\Tailwind\Style\Text(align: AlignEnum::left),
|
||||||
|
'right' => new \PHPNative\Tailwind\Style\Text(align: AlignEnum::right),
|
||||||
|
'center' => new \PHPNative\Tailwind\Style\Text(align: AlignEnum::center),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
preg_match_all('/text-(.*)/', $style, $output_array);
|
preg_match_all('/text-(.*)/', $style, $output_array);
|
||||||
if (count($output_array[0]) > 0) {
|
if (count($output_array[0]) > 0) {
|
||||||
$colorStyle = $output_array[1][0];
|
$colorStyle = $output_array[1][0];
|
||||||
@ -19,4 +50,26 @@ class Text implements Parser
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function merge(\PHPNative\Tailwind\Style\Text $style1, \PHPNative\Tailwind\Style\Text $style2): void
|
||||||
|
{
|
||||||
|
if($style2->color->red != -1) {
|
||||||
|
$style1->color->red = $style2->color->red;
|
||||||
|
}
|
||||||
|
if($style2->color->green != -1) {
|
||||||
|
$style1->color->green = $style2->color->green;
|
||||||
|
}
|
||||||
|
if($style2->color->blue != -1) {
|
||||||
|
$style1->color->blue = $style2->color->blue;
|
||||||
|
}
|
||||||
|
if($style2->color->alpha != -1) {
|
||||||
|
$style1->color->alpha = $style2->color->alpha;
|
||||||
|
}
|
||||||
|
if($style2->size != 16) {
|
||||||
|
$style1->size = $style2->size;
|
||||||
|
}
|
||||||
|
if($style2->align != AlignEnum::left) {
|
||||||
|
$style1->align = $style2->align;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/PHPNative/Tailwind/src/Style/AlignEnum.php
Normal file
10
src/PHPNative/Tailwind/src/Style/AlignEnum.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PHPNative\Tailwind\Style;
|
||||||
|
|
||||||
|
enum AlignEnum
|
||||||
|
{
|
||||||
|
case left;
|
||||||
|
case center;
|
||||||
|
case right;
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@ enum StateEnum
|
|||||||
{
|
{
|
||||||
case normal;
|
case normal;
|
||||||
case hover;
|
case hover;
|
||||||
|
case hoverfocus;
|
||||||
case focus;
|
case focus;
|
||||||
case active;
|
case active;
|
||||||
}
|
}
|
||||||
@ -6,7 +6,7 @@ namespace PHPNative\Tailwind\Style;
|
|||||||
|
|
||||||
class Text implements Style
|
class Text implements Style
|
||||||
{
|
{
|
||||||
public function __construct(public Color $color = new Color())
|
public function __construct(public Color $color = new Color(), public AlignEnum $align = AlignEnum::left, public int $size = 16)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace PHPNative\Tailwind\Tests;
|
namespace PHPNative\Tailwind\Tests;
|
||||||
|
|
||||||
use PHPNative\Tailwind\Parser\Text;
|
use PHPNative\Tailwind\Parser\Text;
|
||||||
|
use PHPNative\Tailwind\Style\AlignEnum;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,4 +33,18 @@ class TextTest extends TestCase
|
|||||||
$this->assertSame(219, $text->color->blue);
|
$this->assertSame(219, $text->color->blue);
|
||||||
$this->assertSame(255, $text->color->alpha);
|
$this->assertSame(255, $text->color->alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_text_align(): void
|
||||||
|
{
|
||||||
|
/** @var \PHPNative\Tailwind\Style\Text $text */
|
||||||
|
$text = Text::parse("flex text-center");
|
||||||
|
$this->assertInstanceOf(\PHPNative\Tailwind\Style\Text::class, $text);
|
||||||
|
$this->assertSame(AlignEnum::center, $text->align);
|
||||||
|
$text = Text::parse("flex text-left");
|
||||||
|
$this->assertInstanceOf(\PHPNative\Tailwind\Style\Text::class, $text);
|
||||||
|
$this->assertSame(AlignEnum::left, $text->align);
|
||||||
|
$text = Text::parse("flex text-right");
|
||||||
|
$this->assertInstanceOf(\PHPNative\Tailwind\Style\Text::class, $text);
|
||||||
|
$this->assertSame(AlignEnum::right, $text->align);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,18 +5,15 @@ namespace PHPNative\UI;
|
|||||||
use PHPNative\UI\Collection\Views;
|
use PHPNative\UI\Collection\Views;
|
||||||
use PHPNative\UI\Trait\Id;
|
use PHPNative\UI\Trait\Id;
|
||||||
use PHPNative\UI\Trait\Style;
|
use PHPNative\UI\Trait\Style;
|
||||||
|
use PHPNative\UI\Widget\Container;
|
||||||
|
|
||||||
class BaseView implements View
|
class BaseView extends Container
|
||||||
{
|
{
|
||||||
use Style;
|
use Style;
|
||||||
use Id;
|
use Id;
|
||||||
|
|
||||||
public ?Views $views = null;
|
public ?Views $views = null;
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getViews(): ?Views
|
public function getViews(): ?Views
|
||||||
{
|
{
|
||||||
return $this->views;
|
return $this->views;
|
||||||
|
|||||||
@ -4,24 +4,24 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace PHPNative\UI\Widget;
|
namespace PHPNative\UI\Widget;
|
||||||
|
|
||||||
|
use PHPNative\UI\Collection\Views;
|
||||||
use PHPNative\UI\Trait\Action\Click;
|
use PHPNative\UI\Trait\Action\Click;
|
||||||
use PHPNative\UI\Trait\Id;
|
use PHPNative\UI\Trait\Id;
|
||||||
use PHPNative\UI\Trait\State;
|
use PHPNative\UI\Trait\State;
|
||||||
use PHPNative\UI\Trait\Style;
|
use PHPNative\UI\Trait\Style;
|
||||||
use PHPNative\UI\View;
|
use PHPNative\UI\View;
|
||||||
|
|
||||||
class Button implements View
|
class Button extends Container implements View
|
||||||
{
|
{
|
||||||
use Style;
|
|
||||||
use Click;
|
use Click;
|
||||||
use State;
|
|
||||||
use Id;
|
|
||||||
|
|
||||||
public function __construct(public string $label)
|
public function __construct(public ?Views $views = null, string $style = "")
|
||||||
{
|
{
|
||||||
|
parent::__construct($style);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getViews(): ?\PHPNative\UI\Collection\Views
|
public function getViews(): ?\PHPNative\UI\Collection\Views
|
||||||
{
|
{
|
||||||
|
return $this->views;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ namespace PHPNative\UI\Widget;
|
|||||||
use PHPNative\UI\Collection\Views;
|
use PHPNative\UI\Collection\Views;
|
||||||
use PHPNative\UI\Trait\Action\Scrollbar;
|
use PHPNative\UI\Trait\Action\Scrollbar;
|
||||||
use PHPNative\UI\Trait\Id;
|
use PHPNative\UI\Trait\Id;
|
||||||
|
use PHPNative\UI\Trait\State;
|
||||||
use PHPNative\UI\Trait\Style;
|
use PHPNative\UI\Trait\Style;
|
||||||
use PHPNative\UI\View;
|
use PHPNative\UI\View;
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ class Container implements View
|
|||||||
{
|
{
|
||||||
use Style;
|
use Style;
|
||||||
use Scrollbar;
|
use Scrollbar;
|
||||||
|
use State;
|
||||||
use Id;
|
use Id;
|
||||||
|
|
||||||
public function __construct(string $style = "")
|
public function __construct(string $style = "")
|
||||||
|
|||||||
26
src/PHPNative/UI/src/Widget/Icon.php
Normal file
26
src/PHPNative/UI/src/Widget/Icon.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PHPNative\UI\Widget;
|
||||||
|
|
||||||
|
use PHPNative\UI\Collection\Views;
|
||||||
|
use PHPNative\UI\Trait\Id;
|
||||||
|
use PHPNative\UI\Trait\State;
|
||||||
|
use PHPNative\UI\Trait\Style;
|
||||||
|
use PHPNative\UI\View;
|
||||||
|
|
||||||
|
class Icon implements View
|
||||||
|
{
|
||||||
|
use Style;
|
||||||
|
use State;
|
||||||
|
use Id;
|
||||||
|
|
||||||
|
public function __construct(public \PHPNative\Tailwind\Data\Icon $icon = \PHPNative\Tailwind\Data\Icon::plus, public int $size = 30, string $style = '')
|
||||||
|
{
|
||||||
|
$this->style = $style;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getViews(): ?Views
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/PHPNative/UI/src/Widget/Image.php
Normal file
26
src/PHPNative/UI/src/Widget/Image.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PHPNative\UI\Widget;
|
||||||
|
|
||||||
|
use PHPNative\UI\Collection\Views;
|
||||||
|
use PHPNative\UI\Trait\Id;
|
||||||
|
use PHPNative\UI\Trait\State;
|
||||||
|
use PHPNative\UI\Trait\Style;
|
||||||
|
use PHPNative\UI\View;
|
||||||
|
|
||||||
|
class Image implements View
|
||||||
|
{
|
||||||
|
use Style;
|
||||||
|
use State;
|
||||||
|
use Id;
|
||||||
|
|
||||||
|
public function __construct(public string $src = "", string $style = '')
|
||||||
|
{
|
||||||
|
$this->style = $style;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getViews(): ?Views
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,13 +9,13 @@ use PHPNative\UI\Trait\State;
|
|||||||
use PHPNative\UI\Trait\Style;
|
use PHPNative\UI\Trait\Style;
|
||||||
use PHPNative\UI\View;
|
use PHPNative\UI\View;
|
||||||
|
|
||||||
class Label implements View
|
class Text implements View
|
||||||
{
|
{
|
||||||
use Style;
|
use Style;
|
||||||
use State;
|
use State;
|
||||||
use Id;
|
use Id;
|
||||||
|
|
||||||
public function __construct(public string $label, string $style = '')
|
public function __construct(public ?string $text, string $style = '')
|
||||||
{
|
{
|
||||||
$this->style = $style;
|
$this->style = $style;
|
||||||
}
|
}
|
||||||
28
src/PHPNative/UI/src/Widget/TextEdit.php
Normal file
28
src/PHPNative/UI/src/Widget/TextEdit.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace PHPNative\UI\Widget;
|
||||||
|
|
||||||
|
use PHPNative\UI\Trait\Id;
|
||||||
|
use PHPNative\UI\Trait\State;
|
||||||
|
use PHPNative\UI\Trait\Style;
|
||||||
|
use PHPNative\UI\View;
|
||||||
|
|
||||||
|
class TextEdit implements View
|
||||||
|
{
|
||||||
|
use Style;
|
||||||
|
use State;
|
||||||
|
use Id;
|
||||||
|
|
||||||
|
public int $textEditIndex = 0;
|
||||||
|
|
||||||
|
public function __construct(public string $value = "", public ?string $placeholder = null, string $style = '')
|
||||||
|
{
|
||||||
|
$this->style = $style;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getViews(): ?\PHPNative\UI\Collection\Views
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user