This commit is contained in:
Thomas Peterson 2024-10-13 21:39:04 +02:00
parent 401287a2a1
commit a6afd7d601
50 changed files with 773 additions and 101 deletions

View File

@ -11,8 +11,11 @@
"require": {
"ext-parallel": "*",
"ext-sdl": "*",
"monolog/monolog": "^3.7.0",
"php": "^8.3",
"psr/log": "^3.0.0",
"symfony/serializer": "^7",
"symfony/var-dumper": "^7.1",
"zumba/json-serializer": "^3"
},
"require-dev": {
@ -27,8 +30,10 @@
"replace": {
"phpnative/container": "self.version",
"phpnative/core": "self.version",
"phpnative/debug": "self.version",
"phpnative/event": "self.version",
"phpnative/framework": "self.version",
"phpnative/log": "self.version",
"phpnative/renderer": "self.version",
"phpnative/storage": "self.version",
"phpnative/support": "self.version",
@ -39,8 +44,10 @@
"psr-4": {
"PHPNative\\Container\\": "src/PHPNative/Container/src",
"PHPNative\\Core\\": "src/PHPNative/Core/src",
"PHPNative\\Debug\\": "src/PHPNative/Debug/src",
"PHPNative\\Event\\": "src/PHPNative/Event/src",
"PHPNative\\Framework\\": "src/PHPNative/Framework/src",
"PHPNative\\Log\\": "src/PHPNative/Log/src",
"PHPNative\\Renderer\\": "src/PHPNative/Renderer/src",
"PHPNative\\Storage\\": "src/PHPNative/Storage/src",
"PHPNative\\Support\\": "src/PHPNative/Support/src",
@ -52,8 +59,10 @@
"psr-4": {
"PHPNative\\Container\\Tests\\": "src/PHPNative/Container/tests",
"PHPNative\\Core\\Tests\\": "src/PHPNative/Core/tests",
"PHPNative\\Debug\\Tests\\": "src/PHPNative/Debug/tests",
"PHPNative\\Event\\Tests\\": "src/PHPNative/Event/tests",
"PHPNative\\Framework\\Tests\\": "src/PHPNative/Framework/tests",
"PHPNative\\Log\\Tests\\": "src/PHPNative/Log/tests",
"PHPNative\\Renderer\\Tests\\": "src/PHPNative/Renderer/tests",
"PHPNative\\Storage\\Tests\\": "src/PHPNative/Storage/tests",
"PHPNative\\Support\\Tests\\": "src/PHPNative/Support/tests",

View File

@ -271,7 +271,7 @@ final class GenericContainer implements Container
$dependencies[] = $this->clone()->autowireDependency(
parameter: $parameter,
tag: $parameter->getAttribute(Tag::class)?->name,
providedValue: $parameters[$parameter->getName()] ?? null,
providedValue: $parameters['params'][$parameter->getName()] ?? null,
);
}

View File

@ -0,0 +1,18 @@
{
"name": "phpnative/debug",
"license": "MIT",
"require": {
"php": "^8.3",
"symfony/var-dumper": "^7.1"
},
"autoload": {
"psr-4": {
"PHPNative\\Debug\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"PHPNative\\Debug\\Tests\\": "tests"
}
}
}

View File

@ -0,0 +1,131 @@
<?php
declare(strict_types=1);
namespace PHPNative\Debug;
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
use Symfony\Component\VarDumper\VarDumper;
use PHPNative\Container\GenericContainer;
use PHPNative\Log\LogConfig;
final readonly class Debug
{
private function __construct(private ?LogConfig $logConfig = null)
{
}
public static function resolve(): self
{
if (! class_exists(GenericContainer::class)) {
return new self();
}
if (! class_exists(LogConfig::class)) {
return new self();
}
$container = GenericContainer::instance();
$logConfig = $container?->get(LogConfig::class);
return new self($logConfig);
}
public function log(array $items, bool $writeToLog = true, bool $writeToOut = true): void
{
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$callPath = $trace[1]['file'] . ':' . $trace[1]['line'];
if ($writeToLog) {
$this->writeToLog($items, $callPath);
}
if ($writeToOut) {
$this->writeToOut($items, $callPath);
}
}
private function writeToLog(array $items, string $callPath): void
{
if ($this->logConfig === null) {
return;
}
if (! $this->logConfig->debugLogPath) {
return;
}
$handle = @fopen($this->logConfig->debugLogPath, 'a');
if (! $handle) {
return;
}
foreach ($items as $key => $item) {
$output = $this->createDump($item) . $callPath;
fwrite($handle, "{$key} " . $output . PHP_EOL);
}
fclose($handle);
}
private function writeToOut(array $items, string $callPath): void
{
foreach ($items as $key => $item) {
if (defined('STDOUT')) {
fwrite(STDOUT, $key);
$output = $this->createDump($item);
fwrite(STDOUT, $output);
fwrite(STDOUT, $callPath . PHP_EOL);
} else {
echo sprintf(
'<span style="
display:inline-block;
color: #fff;
font-family: %s;
padding: 2px 4px;
font-size: 0.8rem;
margin-bottom: -12px;
background: #0071BC;"
>%s (%s)</span>',
'Source Code Pro, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace',
$key,
$callPath,
);
VarDumper::dump($item);
}
}
}
private function createDump(mixed $input): string
{
$cloner = new VarCloner();
$output = '';
$dumper = new CliDumper(function ($line, $depth) use (&$output): void {
if ($depth < 0) {
return;
}
$output .= str_repeat(' ', $depth) . $line . "\n";
});
$dumper->setColors(true);
$dumper->dump($cloner->cloneVar($input));
return preg_replace(
pattern: '/\e](.*)\e]8;;\e/',
replacement: '',
subject: $output,
);
}
}

View File

@ -9,12 +9,9 @@ class Driver
{
}
public function pollEvent(): Event
public function pollEvent(): ?Event
{
\SDL_PollEvent($this->event);
if($this->event->type == \SDL_EVENT_KEY_UP) {
var_dump($this->event->key->key);
}
return match($this->event->type) {
\SDL_EVENT_QUIT => new \PHPNative\Event\SystemEvent(EventType::QUIT),
\SDL_EVENT_WINDOW_CLOSE_REQUESTED => new \PHPNative\Event\SystemEvent(EventType::WINDOW_CLOSE, $this->event->window->windowID),
@ -23,7 +20,7 @@ class Driver
\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 => null
};
}
}

View File

@ -40,7 +40,7 @@ final readonly class Gui implements Application
$lifeCycle = $this->container->get(Lifecycle::class);
try {
$lifeCycle->show($this->container->get($application->getStartWindow()));
$lifeCycle->show($application->getStartWindow());
$lifeCycle->run();
} catch (ArgumentCountError $e) {
var_dump($e->getMessage());

View File

@ -4,12 +4,15 @@ declare(strict_types=1);
namespace PHPNative\Framework\Application;
use Closure;
use PHPNative\Framework\Component\Component;
use PHPNative\UI\View;
interface Window
{
public function getTitle(): string;
public function getView(): ?View;
}

View File

@ -3,6 +3,7 @@
namespace PHPNative\Framework\Lifecycle;
use Closure;
use PHPNative\Container\Container;
use PHPNative\Event\Event;
use PHPNative\Framework\Application\Window;
use PHPNative\Renderer\Thread;
@ -10,13 +11,15 @@ use PHPNative\Renderer\Thread;
class Context
{
public function __construct(public Thread $thread, public ?Closure $onClose = null)
public function __construct(public Thread $thread, private Container $container, public ?Closure $onClose = null )
{
}
public function show(Window $window): void
public function show(string $window): void
{
$window = $this->container->get($window, thread: $this->thread);
$this->thread->show($window);
}

View File

@ -16,10 +16,17 @@ class ContextCollection extends TypedCollection
public function removeWindowFrom(string $windowId): void
{
$temp = $this->filter(function ($value, $key) use($windowId){
if($value->thread->windowId == $windowId) {
if($value->thread->windowId == $windowId && !$value->thread->shouldClosed) {
$value->unload();
return true;
}elseif($value->thread->windowId == $windowId && $value->thread->shouldClosed) {
\SDL_DestroyWindow($value->thread->windowPtr);
\SDL_DestroyRenderer($value->thread->rendererPtr);
return false;
}else{
return true;
}
return $value->thread->windowId != $windowId;
});
$this->setElements($temp->items());
}

View File

@ -22,7 +22,7 @@ class Lifecycle implements WorkerInterface
$this->loop->use($this);
}
public function show(Window $window, array $arguments = [], ?callable $onClose = null): void
public function show(string $window, array $arguments = [], ?callable $onClose = null): void
{
$context = $this->container->get(
@ -48,9 +48,17 @@ class Lifecycle implements WorkerInterface
public function onRender(float $delta): void
{
$this->contextCollection->map(
fn(Context $context) => $context->render($delta)
);
$windowClose = 0;
$this->contextCollection->map(function(Context $context) use (&$delta, &$windowClose) {
if($context->thread->shouldClosed) {
$windowClose = $context->thread->windowId;
}else {
$context->render($delta);
}
});
if($windowClose != 0) {
$this->contextCollection->removeWindowFrom($windowClose);
}
}
public function onEvent( $event): void
@ -94,7 +102,7 @@ class Lifecycle implements WorkerInterface
}
}
private function closeWindow($windowId)
public function closeWindow($windowId)
{
if($this->contextCollection->count() == 1) {
return;

View File

@ -4,9 +4,9 @@ namespace PHPNative\Framework\Loop;
interface LoopInterface
{
public const DEFAULT_FRAME_RATE = 60;
public const DEFAULT_FRAME_RATE = 5;
public const DEFAULT_UPDATE_RATE = 60;
public const DEFAULT_UPDATE_RATE = 5;
public function run(int $frameRate = self::DEFAULT_FRAME_RATE, int $updateRate = self::DEFAULT_UPDATE_RATE): void;

View File

@ -34,9 +34,10 @@ class OrderedEventLoop extends EventLoop
}
while ($event = $this->eventDriver->pollEvent()) {
if($event->getType() == EventType::NOOP) break;
if($event == null) break;
$this->poll($event);
}
usleep(20);
}
}
}

View File

@ -8,7 +8,7 @@ use function microtime;
class Timer
{
public const DEFAULT_UPDATE_RATE = 60;
public const DEFAULT_UPDATE_RATE = 20;
public float $ops = 0;

View File

@ -0,0 +1,20 @@
{
"name": "phpnative/log",
"license": "MIT",
"require": {
"php": "^8.3",
"monolog/monolog": "^3.7.0",
"psr/log": "^3.0.0",
"phpnative/container": "dev-main"
},
"autoload": {
"psr-4": {
"PHPNative\\Log\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"PHPNative\\Log\\Tests\\": "tests"
}
}
}

View File

@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace PHPNative\Log;
use Monolog\Handler\HandlerInterface;
use Monolog\Level;
use Monolog\Processor\ProcessorInterface;
interface LogChannel
{
/**
* @return array<array-key, HandlerInterface>
*/
public function getHandlers(Level $level): array;
/**
* @return array<array-key, ProcessorInterface>
*/
public function getProcessors(): array;
}

View File

@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace PHPNative\Log;
final class LogConfig
{
public function __construct(
/** @var LogChannel[] */
public array $channels = [],
public string $prefix = 'tempest',
public ?string $debugLogPath = null,
public ?string $serverLogPath = null,
) {
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace PHPNative\Renderer\Cache;
use PHPNative\Container\Singleton;
use PHPNative\Tailwind\Style\MediaQueryEnum;
use PHPNative\Tailwind\Style\StateEnum;
use PHPNative\Tailwind\StyleParser;
#[Singleton]
class Styles
{
private array $styles = [];
public function getStyle(string $widgetId, MediaQueryEnum $mediaQueryEnum, StateEnum $state, $style): array
{
if(!isset($this->styles[$widgetId])) {
$this->styles[$widgetId] = [];
}
if(!isset($this->styles[$widgetId][$mediaQueryEnum->name])) {
$this->styles[$widgetId][$mediaQueryEnum->name] = [];
}
if(!isset($this->styles[$widgetId][$mediaQueryEnum->name][$state->name])) {
$this->styles[$widgetId][$mediaQueryEnum->name][$state->name] = StyleParser::parse($style)->getValidStyles($mediaQueryEnum, $state);
}
return $this->styles[$widgetId][$mediaQueryEnum->name][$state->name];
}
}

View File

@ -6,6 +6,7 @@ use PHPNative\Event\Event;
use PHPNative\Event\EventCollection;
use PHPNative\Framework\Application\Window;
use PHPNative\Framework\Parallel\Worker;
use PHPNative\Renderer\Cache\Styles;
use PHPNative\Tailwind\Style\Background;
use PHPNative\Tailwind\Style\MediaQueryEnum;
use PHPNative\Tailwind\Style\Padding;
@ -15,9 +16,9 @@ class Thread
{
public ?\SDL_Window $windowPtr = null;
public ?int $windowId = null;
private $rendererPtr = null;
public $rendererPtr = null;
private bool $shouldRenderd = true;
public bool $shouldClosed = false;
public Window $window;
@ -25,7 +26,7 @@ class Thread
private EventCollection $eventStack;
public function __construct(public Worker $worker)
public function __construct(public Worker $worker, private Styles $styleCache)
{
$this->eventStack = new EventCollection();
$this->renderStack = new StackCollection();
@ -35,7 +36,7 @@ class Thread
{
$this->window = $window;
$this->windowPtr = \SDL_CreateWindow($this->window->getTitle(), 1000, 600, \SDL_WINDOW_HIGH_PIXEL_DENSITY);
$this->windowPtr = \SDL_CreateWindow($this->window->getTitle(), 1000, 800, \SDL_WINDOW_HIGH_PIXEL_DENSITY);
$this->rendererPtr = \SDL_CreateRenderer($this->windowPtr);
$this->windowId = \SDL_GetWindowID($this->windowPtr);
@ -43,17 +44,12 @@ class Thread
public function close(): void
{
$this->shouldRenderd = false;
\SDL_DestroyRenderer($this->rendererPtr);
\SDL_DestroyWindow($this->windowPtr);
$this->shouldClosed = true;
}
public function render(): void
{
if(!$this->shouldRenderd) {
return;
}
$windowWidth = 0;
$windowHeight = 0;
\SDL_GetWindowSize($this->windowPtr, $windowWidth, $windowHeight);
@ -68,7 +64,7 @@ class Thread
$this->startRender();
Widget::render($this, $viewPort, $this->window->getView());
Widget::render($this->styleCache, $this, $viewPort, $this->window->getView($this->window));
$this->renderStack->sort(function(Item $itemA, Item $itemB) {
if($itemA->level == $itemB->level) {
return 0;
@ -99,7 +95,8 @@ class Thread
private function startRender(): void
{
\SDL_SetRenderDrawColor($this->rendererPtr, 255, 255, 255, 255);
\SDL_RenderClear($this->rendererPtr);
}
private function endRender(): void
@ -131,17 +128,41 @@ class Thread
$this->renderStack->removeWidgetIdFromRender($widgetId);
}
public function clipFromStack(string $widgetId, $x = null, $y = null): void
public function clipFromStackB(string $widgetId, $width = null, $height = null, $y = null, $x = null): void
{
foreach($this->renderStack->items() as $item) {
if($item->widgetId == $widgetId && ($y != null || $y != null)) {
if($item->widgetId == $widgetId && ($width != null || $height != null)) {
$w =0;$h = 0;
\SDL_GetTextureSize($item->texture, $w, $h);
$clip = clone $item->renderAt;
if($y) {
echo sprintf("Texture W: %d H: %d%s V-W: %d V-H: %d V-X: %d V-Y: %d%s R-AT-X: %d R-AT-Y: %d R-AT-W: %d R-AT-H: %d%s CLIP AT H %d Y %d", $w, $h, PHP_EOL, $width, $height, $x, $y, PHP_EOL, $item->renderAt->x, $item->renderAt->y, $item->renderAt->w, $item->renderAt->h, PHP_EOL, $height-$item->renderAt->y, $item->renderAt->y + $y).PHP_EOL;
if($height) {
$clip->x = 0;
$clip->y = $y;
$clip->h = $clip->h-$y;
$item->renderAt->y += $y;
$item->renderAt->h = $clip->h;
$clip->h = $height-$item->renderAt->y;
$item->renderAt->y = $item->renderAt->y + $y;
$item->renderAt->h = $height-$item->renderAt->y;
$item->clipAt = $clip;
}
}
}
}
public function clipFromStackT(string $widgetId, $y = null): void
{
foreach($this->renderStack->items() as $item) {
if($item->widgetId == $widgetId) {
$w =0;$h = 0;
\SDL_GetTextureSize($item->texture, $w, $h);
$clip = clone $item->renderAt;
$height = $item->renderAt->h;
echo sprintf("Texture W: %d H: %d%s V-X: %d%s R-AT-X: %d R-AT-Y: %d R-AT-W: %d R-AT-H: %d%s CLIP AT H %d Y %d", $w, $h, PHP_EOL, $y, PHP_EOL, $item->renderAt->x, $item->renderAt->y, $item->renderAt->w, $item->renderAt->h, PHP_EOL, $height-($y-$item->renderAt->y), $item->renderAt->y + $y).PHP_EOL;
if($y && $y > $item->renderAt->y) {
$clip->x = 0;
$clip->y = $y-$item->renderAt->y;
$clip->h = $height-($y-$item->renderAt->y);
$item->renderAt->h = $height-($y-$item->renderAt->y);
$item->renderAt->y = $y;
$item->clipAt = $clip;
}
}

View File

@ -8,9 +8,9 @@ use PHPNative\Tailwind\Style\MediaQueryEnum;
class Viewport
{
public function __construct(public $windowId,
public $windowPtr,
public $renderPtr,
public function __construct(public $windowId = null,
public $windowPtr = null,
public $renderPtr= null,
public int $x = 0,
public int $y = 0,
public $width = 0,

View File

@ -2,6 +2,7 @@
namespace PHPNative\Renderer;
use PHPNative\Renderer\Cache\Styles;
use PHPNative\UI\Widget\Icon;
use PHPNative\UI\Widget\Image;
use PHPNative\UI\Widget\TextEdit;
@ -13,28 +14,28 @@ use PHPNative\UI\Widget\Text;
class Widget
{
public static function render(Thread $thread, ViewPort $viewPort, View $view, int $index = 1): Viewport {
public static function render(Styles $styleCache, Thread $thread, ViewPort $viewPort, View $view, int $index = 1): Viewport {
if($view instanceof BaseView) {
return \PHPNative\Renderer\Widgets\BaseView::render($thread, $viewPort, $view, $index);
return \PHPNative\Renderer\Widgets\BaseView::render($styleCache, $thread, $viewPort, $view, $index);
}
if($view instanceof Button) {
return \PHPNative\Renderer\Widgets\Container::render($thread, $viewPort, $view, $index);
return \PHPNative\Renderer\Widgets\Container::render($styleCache, $thread, $viewPort, $view, $index);
}
if($view instanceof Text) {
return \PHPNative\Renderer\Widgets\Text::render($thread, $viewPort, $view, $index);
return \PHPNative\Renderer\Widgets\Text::render($styleCache, $thread, $viewPort, $view, $index);
}
if($view instanceof TextEdit) {
return \PHPNative\Renderer\Widgets\TextEdit::render($thread, $viewPort, $view, $index);
return \PHPNative\Renderer\Widgets\TextEdit::render($styleCache, $thread, $viewPort, $view, $index);
}
if($view instanceof Container) {
return \PHPNative\Renderer\Widgets\Container::render($thread, $viewPort, $view, $index);
return \PHPNative\Renderer\Widgets\Container::render($styleCache, $thread, $viewPort, $view, $index);
}
if($view instanceof Image) {
return \PHPNative\Renderer\Widgets\Image::render($thread, $viewPort, $view, $index);
return \PHPNative\Renderer\Widgets\Image::render($styleCache, $thread, $viewPort, $view, $index);
}
if($view instanceof Icon) {
return \PHPNative\Renderer\Widgets\Icon::render($thread, $viewPort, $view, $index);
return \PHPNative\Renderer\Widgets\Icon::render($styleCache, $thread, $viewPort, $view, $index);
}
}

View File

@ -12,8 +12,8 @@ use PHPNative\Tailwind\Style\MediaQueryEnum;
use PHPNative\Tailwind\Style\Padding;
use PHPNative\Tailwind\Style\StateEnum;
use PHPNative\Tailwind\StyleParser;
use PHPNative\UI\Trait\Id;
class BaseView extends Container
{
}

View File

@ -2,15 +2,21 @@
namespace PHPNative\Renderer\Widgets;
use PHPNative\Debug\Debug;
use PHPNative\Event\EventType;
use PHPNative\Renderer\Cache\Styles;
use PHPNative\Renderer\Item;
use PHPNative\Renderer\Thread;
use PHPNative\Renderer\Viewport;
use PHPNative\Renderer\Widget;
use PHPNative\Renderer\Widgets\Container\Column;
use PHPNative\Tailwind\LayoutParser;
use PHPNative\Tailwind\Style\Background;
use PHPNative\Tailwind\Style\Basis;
use PHPNative\Tailwind\Style\DirectionEnum;
use PHPNative\Tailwind\Style\Flex;
use PHPNative\Tailwind\Style\FlexTypeEnum;
use PHPNative\Tailwind\Style\Height;
use PHPNative\Tailwind\Style\Margin;
use PHPNative\Tailwind\Style\Overflow;
use PHPNative\Tailwind\Style\OverflowEnum;
@ -22,9 +28,10 @@ use PHPNative\Tailwind\StyleParser;
class Container
{
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Container $view, int $index = 0): Viewport
public static function render(Styles $stylesCache, Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Container $view, int $index = 0): Viewport
{
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
$styles = $stylesCache->getStyle($view->getId(), $viewport->windowMediaQuery, $view->state, $view->style);
if(isset($styles[Margin::class]) && $m = $styles[Margin::class]) {
$viewport->x += $m->left;
@ -35,6 +42,7 @@ class Container
$targetViewport = clone $viewport;
\PHPNative\Renderer\Visuals\Visuals::render($view->getId(), $thread, $styles, $viewport, $index);
\PHPNative\Renderer\Visuals\Visuals::changeViewport($view->getId(), $thread, $styles, $viewport);
if(isset($styles[Padding::class]) && $m = $styles[Padding::class]) {
@ -44,62 +52,129 @@ class Container
$viewport->height -= ($m->bottom + $m->top);
}
$flexStyles = [];
$view = LayoutParser::sortByStyles($stylesCache, $view, $viewport);
if($view->getViews() != null) {
if (isset($styles[Flex::class]) && $styles[Flex::class]->direction == DirectionEnum::column) {
//Debug::resolve()->log(['Styles' => $styles]);
Column::render($stylesCache, $thread, $viewport, $view->getViews(), $index);
}
if (isset($styles[Flex::class]) && $styles[Flex::class]->direction == DirectionEnum::row) {
}
}
/*
if($view->getViews() != null) {
$viewportWidth = $viewport->width;
$viewportHeight = $viewport->height;
$width = $viewport->width;
$height = $viewport->height;
$viewPortY = $viewport->y;
foreach ($view->getViews() as $subView) {
$found = false;
$stylesSubView = StyleParser::parse($subView->style)->getValidStyles($viewport->windowMediaQuery, StateEnum::normal);
$stylesSubView = $stylesCache->getStyle($subView->getId(), $viewport->windowMediaQuery, $subView->state, $subView->style);
if (isset($stylesSubView[Basis::class]) && $b = $stylesSubView[Basis::class]) {
if ($b->unit == Unit::Percent) {
$width = round($viewport->width / 100 * $b->value);
$width = round($viewportWidth / 100 * $b->value);
} else {
$width = $b->value;
$viewportWidth -= $b->value;
}
$found = true;
}
if (isset($stylesSubView[Width::class]) && $w = $stylesSubView[Width::class]) {
if ($w->unit == Unit::Percent) {
$width = round($viewport->width / 100 * $w->value);
$width = round($viewportWidth / 100 * $w->value);
} else {
$width = $w->value;
$viewportWidth -= $w->value;
}
$found = true;
}
if (isset($stylesSubView[Height::class]) && $h = $stylesSubView[Height::class]) {
if ($h->unit == Unit::Percent) {
$height = round($viewportHeight / 100 * $h->value);
} else {
$height = $h->value;
$viewportHeight -= $h->value;
}
$found = true;
}
if (isset($styles[Flex::class]) && $styles[Flex::class]->direction == DirectionEnum::column &&
isset($stylesSubView[Flex::class]) && $stylesSubView[Flex::class]->type == FlexTypeEnum::one
) {
$height = round($viewportHeight / $view->getViews()->countOne);
$found = true;
}
if (isset($styles[Flex::class]) && $styles[Flex::class]->direction == DirectionEnum::row &&
isset($stylesSubView[Flex::class]) && $stylesSubView[Flex::class]->type == FlexTypeEnum::one
) {
$width = round($viewportWidth / $view->getViews()->countOne);
$found = true;
}
if ($found) {
if (isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::column) {
$viepo = new Viewport($viewport->windowId, $viewport->windowPtr, $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, $height, $viewport->windowWidth, $viewport->windowHeight, $viewport->windowMediaQuery);
$flexStyles[$subView->getRenderSort()] = $viepo;
} else {
$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;
} else {
$flexStyles[] = clone $viewport;
$flexStyles[$subView->getRenderSort()] = clone $viewport;
}
}
LayoutParser::sortByRenderSort($view);
$topHeight = 0;
foreach ($view->getViews() as $subView) {
$stylesSubView = $stylesCache->getStyle($subView->getId(), $viewport->windowMediaQuery, $subView->state, $subView->style);
if (isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::column) {
$subViewPort = array_shift($flexStyles);
$subViewPort = $flexStyles[$subView->getRenderSort()];
$subViewPort->y = $viewport->y - $view->getMoveToY();
$vp = Widget::render($thread, $subViewPort, $subView, $index+1);
if($vp->y < $targetViewport->y) {
$thread->clipFromStack($subView->getId(), y: $targetViewport->y-$vp->y);
if($viewport->height < $subViewPort->height) {
$subViewPort->height = $viewport->height;
}
if($vp->y + $vp->height < $targetViewport->y) {
$vp = Widget::render($stylesCache, $thread, clone $subViewPort, $subView, $index+1);
echo sprintf('RENDER: %s SV-X %d SV-Y %d SV-W %d SV-H %d%sVP-Y %d VP-H %d ViewportY %d ViewportHeight %d', $subView->getId(), $subViewPort->x, $subViewPort->y, $subViewPort->width, $subViewPort->height, PHP_EOL, $vp->y, $vp->height, $viewPortY, $viewportHeight).PHP_EOL;
if((($vp->y + $vp->height) < $viewPortY) &&
!isset($stylesSubView[Overflow::class])) {
echo sprintf('REMOVE: %s V-Y: %d V-H: %d S-Y: %d S-H: %d VP-Y: %d VP-H: %d', $subView->getId(), $viewport->y, $viewport->height, $subViewPort->y, $subViewPort->height, $vp->y, $vp->height).PHP_EOL;
$thread->removeFromStack($subView->getId());
}
if(
($vp->y <= ($viewport->y + $viewport->height) && $vp->height > $viewport->height)
) {
echo sprintf('CLIP-B: %s V-Y: %d V-H: %d S-Y: %d S-H: %d VP-Y: %d VP-H: %d', $subView->getId(), $viewport->y, $viewport->height, $subViewPort->y, $subViewPort->height, $vp->y, $vp->height).PHP_EOL;
$thread->clipFromStackB($subView->getId(), y: 0, height: ($viewport->y+$viewport->height));
}
if( ($vp->y + $vp->height >= $viewPortY) && $subViewPort->y < $viewPortY) {
echo sprintf('CLIP-T: %s V-Y: %d V-H: %d S-Y: %d S-H: %d VP-Y: %d VP-H: %d', $subView->getId(), $viewport->y, $viewport->height, $subViewPort->y, $subViewPort->height, $vp->y, $vp->height).PHP_EOL;
$thread->clipFromStackT($subView->getId(), y: $viewPortY);
}
if(!isset($stylesSubView[Flex::class])) {
$viewport->y += $vp->height;
$viewport->height -= $vp->height;
}else{
$viewport->y += $subViewPort->height;
$viewport->height -= $subViewPort->height;
}
} elseif(isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::row) {
$vp = Widget::render($thread, array_shift($flexStyles), $subView, $index+1);
$subViewPort = $flexStyles[$subView->getRenderSort()];
$subViewPort->x = $viewport->x - $view->getMoveToX();
$vp = Widget::render($stylesCache, $thread, clone $subViewPort, $subView, $index+1);
if(!isset($stylesSubView[Flex::class])) {
$viewport->x += $vp->width;
}else{
$viewport->x += $subViewPort->width;
}
$topHeight = max($topHeight, $vp->height);
// $viewport->width -= $vp->width;
} else{
$sfs = array_shift($flexStyles);
$vp = Widget::render($thread, $sfs, $subView, $index+1);
$sfs = $flexStyles[$subView->getRenderSort()];
$vp = Widget::render($stylesCache, $thread, $sfs, $subView, $index+1);
$topHeight = max($topHeight, $vp->height);
if(count($flexStyles) > 0) {
if($vp->addX > 0) {
@ -109,6 +184,7 @@ class Container
}
}
}
if (isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::column) {
} else {
@ -144,8 +220,6 @@ class Container
}
}
\PHPNative\Renderer\Visuals\Visuals::render($view->getId(), $thread, $styles, $targetViewport, $index);
if (isset($styles[Overflow::class]) && $f = $styles[Overflow::class] && (
$styles[Overflow::class]->y == OverflowEnum::scroll ||
($styles[Overflow::class]->y == OverflowEnum::auto && $viewport->height < 0)
@ -195,6 +269,7 @@ class Container
\PHPNative\Renderer\Visuals\Scrollbar::renderSlider($view->getId(), $thread, $styles, $sliderViewport, $index);
}
}
*/
return $viewport;
}

View File

@ -0,0 +1,21 @@
<?php
namespace PHPNative\Renderer\Widgets\Container;
use PHPNative\Renderer\Cache\Styles;
use PHPNative\Renderer\Thread;
use PHPNative\Renderer\Viewport;
use PHPNative\UI\Collection\Views;
class Column
{
public static function render(Styles $stylesCache, Thread $thread, Viewport $viewport, Views $views, int $index = 0): Viewport
{
foreach($views as $view) {
}
return $viewport;
}
}

View File

@ -0,0 +1,8 @@
<?php
namespace PHPNative\Renderer\Widgets\Container;
class Row
{
}

View File

@ -3,6 +3,7 @@
namespace PHPNative\Renderer\Widgets;
use PHPNative\Event\EventType;
use PHPNative\Renderer\Cache\Styles;
use PHPNative\Renderer\GFX;
use PHPNative\Renderer\Item;
use PHPNative\Renderer\Thread;
@ -23,9 +24,10 @@ use PHPNative\Tailwind\StyleParser;
class Icon
{
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Icon $view, int $index = 0): Viewport
public static function render(Styles $stylesCache, Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Icon $view, int $index = 0): Viewport
{
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
$styles = $stylesCache->getStyle($view->getId(), $viewport->windowMediaQuery, $view->state, $view->style);
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);

View File

@ -3,6 +3,7 @@
namespace PHPNative\Renderer\Widgets;
use PHPNative\Event\EventType;
use PHPNative\Renderer\Cache\Styles;
use PHPNative\Renderer\GFX;
use PHPNative\Renderer\Item;
use PHPNative\Renderer\Thread;
@ -23,9 +24,10 @@ use PHPNative\Tailwind\StyleParser;
class Image
{
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Image $view, int $index = 0): Viewport
public static function render(Styles $stylesCache, Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Image $view, int $index = 0): Viewport
{
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
$styles = $stylesCache->getStyle($view->getId(), $viewport->windowMediaQuery, $view->state, $view->style);
if(!file_exists($view->src)) {
return $viewport;

View File

@ -3,6 +3,7 @@
namespace PHPNative\Renderer\Widgets;
use PHPNative\Event\EventType;
use PHPNative\Renderer\Cache\Styles;
use PHPNative\Renderer\GFX;
use PHPNative\Renderer\Item;
use PHPNative\Renderer\Thread;
@ -10,6 +11,8 @@ use PHPNative\Renderer\Viewport;
use PHPNative\Tailwind\Style\AlignEnum;
use PHPNative\Tailwind\Style\Basis;
use PHPNative\Tailwind\Style\Border;
use PHPNative\Tailwind\Style\Flex;
use PHPNative\Tailwind\Style\Height;
use PHPNative\Tailwind\Style\Margin;
use PHPNative\Tailwind\Style\MediaQueryEnum;
use PHPNative\Tailwind\Style\Padding;
@ -20,9 +23,10 @@ use PHPNative\Tailwind\StyleParser;
class Text
{
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Text $view, int $index = 0): Viewport
public static function render(Styles $stylesCache, Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Text $view, int $index = 0): Viewport
{
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
$styles = $stylesCache->getStyle($view->getId(), $viewport->windowMediaQuery, $view->state, $view->style);
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);
@ -37,21 +41,25 @@ class Text
}
$surface = \SDL_TTF_RenderText_Blended($font, $view->text, $color);
if(!isset($styles[Basis::class]) && !isset($styles[Width::class])) {
if(!isset($styles[Basis::class]) && !isset($styles[Width::class]) && !isset($styles[Flex::class])) {
$viewport->width = $surface->w;
}
if(!isset($styles[Height::class])) {
$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->y += $m->top;
if(isset($styles[Basis::class]) || isset($styles[Width::class]) || isset($styles[Flex::class])) {
$viewport->width -= ($m->right + $m->left);
}
$viewport->y += $m->top;
if(isset($styles[Height::class])) {
$viewport->height -= ($m->bottom + $m->top);
}else{
$viewport->height += ($m->bottom + $m->top);
}
}
$backdropViewport = clone $viewport;
$backdropViewport->height = $surface->h;
@ -69,10 +77,15 @@ class Text
if(isset($styles[Padding::class]) && $m = $styles[Padding::class]) {
$viewport->x += $m->left;
$viewport->width -= ($m->right + $m->left);
$viewport->width += ($m->right + $m->left);
$viewport->y += $m->top;
if(!isset($styles[Height::class])) {
$viewport->height += ($m->bottom + $m->top);
}
$backdropViewport->height += ($m->top + $m->bottom);
if(!isset($styles[Basis::class]) && !isset($styles[Width::class]) && !isset($styles[Flex::class])) {
$backdropViewport->width += ($m->left + $m->right);
}
}
\PHPNative\Renderer\Visuals\Visuals::render($view->getId(), $thread, $styles, $backdropViewport, $index);

View File

@ -4,6 +4,7 @@ namespace PHPNative\Renderer\Widgets;
use PHPNative\Event\EventType;
use PHPNative\Event\Key;
use PHPNative\Renderer\Cache\Styles;
use PHPNative\Renderer\GFX;
use PHPNative\Renderer\Item;
use PHPNative\Renderer\Thread;
@ -26,10 +27,10 @@ use PHPNative\Tailwind\StyleParser;
class TextEdit
{
public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\TextEdit $view, int $index = 0): Viewport
public static function render(Styles $stylesCache, Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\TextEdit $view, int $index = 0): Viewport
{
$styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state);
$styles = $stylesCache->getStyle($view->getId(), $viewport->windowMediaQuery, $view->state, $view->style);
if(isset($styles[Text::class]) && $t = $styles[Text::class]) {
$font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/segoe-ui.ttf' , $t->size);

View File

@ -5,4 +5,6 @@ namespace PHPNative\Tailwind\Data;
enum Icon:int
{
case plus = 57669;
case save = 57697;
}

View File

@ -0,0 +1,55 @@
<?php
namespace PHPNative\Tailwind;
use PHPNative\Renderer\Cache\Styles;
use PHPNative\Renderer\Viewport;
use PHPNative\Tailwind\Style\DirectionEnum;
use PHPNative\Tailwind\Style\Flex;
use PHPNative\Tailwind\Style\FlexTypeEnum;
use PHPNative\UI\View;
class LayoutParser
{
public static function sortByStyles(Styles $stylesCache, View $container, Viewport $viewport): View
{
$i = 0;
$flexOne = 0;
$container->getViews()->map(function (View $a) use (&$flexOne, &$i, &$stylesCache, $viewport) {
$aStyles = $stylesCache->getStyle($a->getId(), $viewport->windowMediaQuery, $a->getState(), $a->getStyle());
if(isset($aStyles[Flex::class]) && $aStyles[Flex::class]->type == FlexTypeEnum::one) {
$flexOne++;
}
$a->setRenderSort($i);
$i++;
});
$container->getViews()->sort(function (View $a, View $b) use (&$stylesCache, $viewport) {
$aStyles = $stylesCache->getStyle($a->getId(), $viewport->windowMediaQuery, $a->getState(), $a->getStyle());
$bStyles = $stylesCache->getStyle($b->getId(), $viewport->windowMediaQuery, $b->getState(), $b->getStyle());
if(isset($aStyles[Flex::class]) && $aStyles[Flex::class]->type == FlexTypeEnum::none &&
isset($bStyles[Flex::class]) && $bStyles[Flex::class]->type == FlexTypeEnum::one) {
return -1;
}
return 1;
});
$container->getViews()->countOne = $flexOne;
return $container;
}
public static function sortByRenderSort(View $container)
{
$container->getViews()->sort(function (View $a, View $b) {
if($a->getRenderSort() == $b->getRenderSort()) {
return 0;
}
return $a->getRenderSort() <=> $b->getRenderSort();
});
}
}

View File

@ -4,6 +4,7 @@ namespace PHPNative\Tailwind\Model;
use PHPNative\Core\TypedCollection;
use PHPNative\Tailwind\Style\Border;
use PHPNative\Tailwind\Style\Flex;
use PHPNative\Tailwind\Style\Margin;
use PHPNative\Tailwind\Style\MediaQueryEnum;
use PHPNative\Tailwind\Style\Padding;
@ -43,6 +44,8 @@ class StyleCollection extends TypedCollection
\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);
}elseif(isset($tmp[$style->style::class]) && $style->style::class === Flex::class) {
\PHPNative\Tailwind\Parser\Flex::merge($tmp[$style->style::class], $style->style);
}else{
$tmp[$style->style::class] = $style->style;
}

View File

@ -3,12 +3,25 @@
namespace PHPNative\Tailwind\Parser;
use PHPNative\Tailwind\Style\DirectionEnum;
use PHPNative\Tailwind\Style\FlexTypeEnum;
class Flex implements Parser
{
public static function parse(string $style): ?\PHPNative\Tailwind\Style\Style
{
preg_match_all('/flex-none/', $style, $output_array);
if (count($output_array[0]) > 0) {
return new \PHPNative\Tailwind\Style\Flex(type:FlexTypeEnum::none);
}
preg_match_all('/flex-1/', $style, $output_array);
if (count($output_array[0]) > 0) {
return new \PHPNative\Tailwind\Style\Flex(type:FlexTypeEnum::one);
}
preg_match_all('/flex-auto/', $style, $output_array);
if (count($output_array[0]) > 0) {
return new \PHPNative\Tailwind\Style\Flex(type:FlexTypeEnum::auto);
}
preg_match_all('/flex-col/', $style, $output_array);
if (count($output_array[0]) > 0) {
return new \PHPNative\Tailwind\Style\Flex(DirectionEnum::column);
@ -22,4 +35,14 @@ class Flex implements Parser
return null;
}
public static function merge(\PHPNative\Tailwind\Style\Flex $class, \PHPNative\Tailwind\Style\Flex $style)
{
if($style->type != FlexTypeEnum::none) {
$class->type = $style->type;
}
if($style->direction != DirectionEnum::row) {
$class->direction = $style->direction;
}
}
}

View File

@ -6,7 +6,7 @@ namespace PHPNative\Tailwind\Style;
class Flex implements Style
{
public function __construct(public DirectionEnum $direction = DirectionEnum::row)
public function __construct(public DirectionEnum $direction = DirectionEnum::row, public FlexTypeEnum $type = FlexTypeEnum::none)
{
}
}

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace PHPNative\Tailwind\Style;
enum FlexTypeEnum
{
case none;
case auto;
case initial;
case one;
}

View File

@ -10,7 +10,7 @@ use PHPNative\Tailwind\Style\Style;
class StyleParser
{
public static function parse($style, int $width = 0): StyleCollection
public static function parse($style): StyleCollection
{
$computed = new StyleCollection();
if($style === null || strlen(trim($style)) === 0) {

View File

@ -0,0 +1,43 @@
<?php
namespace PHPNative\Tailwind\Tests;
use PHPNative\Renderer\Cache\Styles;
use PHPNative\Renderer\Viewport;
use PHPNative\Tailwind\LayoutParser;
use PHPNative\UI\Collection\Views;
use PHPUnit\Framework\TestCase;
class FlexLayoutTest extends TestCase
{
private Styles $stylesCache;
public function setUp(): void
{
parent::setUp(); // TODO: Change the autogenerated stub
$this->stylesCache = new Styles();
}
public function testFlexLayout(): void
{
$container = new Item(style: 'flex flex-row');
$subItems = new Views([
new Item('flex-1'),
new Item('flex-none w-100')
]);
$container->items = $subItems;
LayoutParser::sortByStyles($this->stylesCache, $container, new Viewport(width: 800, height: 600));
$this->assertEquals(1, $subItems->values()[0]->renderSort);
$this->assertEquals(0, $subItems->values()[1]->renderSort);
LayoutParser::sortByRenderSort($container);
$this->assertEquals(0, $subItems->values()[0]->renderSort);
$this->assertEquals(1, $subItems->values()[1]->renderSort);
}
}

View File

@ -6,6 +6,7 @@ namespace PHPNative\Tailwind\Tests;
use PHPNative\Tailwind\Parser\Flex;
use PHPNative\Tailwind\Style\DirectionEnum;
use PHPNative\Tailwind\Style\FlexTypeEnum;
use PHPUnit\Framework\TestCase;
class FlexTest extends TestCase
@ -30,4 +31,25 @@ class FlexTest extends TestCase
$this->assertInstanceOf(\PHPNative\Tailwind\Style\Flex::class, $flex);
$this->assertSame(DirectionEnum::column, $flex->direction);
}
public function test_container_flex_none(): void
{
$flex = Flex::parse("flex-none");
$this->assertInstanceOf(\PHPNative\Tailwind\Style\Flex::class, $flex);
$this->assertSame(FlexTypeEnum::none, $flex->type);
}
public function test_container_flex_one(): void
{
$flex = Flex::parse("flex-1");
$this->assertInstanceOf(\PHPNative\Tailwind\Style\Flex::class, $flex);
$this->assertSame(FlexTypeEnum::one, $flex->type);
}
public function test_container_flex_auto(): void
{
$flex = Flex::parse("flex-auto");
$this->assertInstanceOf(\PHPNative\Tailwind\Style\Flex::class, $flex);
$this->assertSame(FlexTypeEnum::auto, $flex->type);
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace PHPNative\Tailwind\Tests;
use PHPNative\Renderer\Viewport;
use PHPNative\Tailwind\Style\MediaQueryEnum;
use PHPNative\Tailwind\Style\StateEnum;
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 Item implements View
{
use Style;
use Id;
use State;
public function __construct(string $style = "", public ?Views $items = null, public int $renderSort = 0)
{
$this->style = $style;
}
public function getViews(): ?Views
{
return $this->items;
}
}

View File

@ -14,9 +14,10 @@ class BaseView extends Container
public ?Views $views = null;
public ?Window $window = null;
public function getViews(): ?Views
{
return $this->views;
}
}

View File

@ -6,6 +6,8 @@ use PHPNative\Core\TypedCollection;
class Views extends TypedCollection
{
public int $countOne = 0;
protected function type(): string
{
return \PHPNative\UI\View::class;

View File

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace PHPNative\UI\Trait;
trait RenderSort
{
private int $renderSort = 0;
public function getRenderSort(): int
{
return $this->renderSort;
}
public function setRenderSort(int $renderSort = 0): void
{
$this->renderSort = $renderSort;
}
}

View File

@ -10,4 +10,9 @@ trait State
{
public StateEnum $state = StateEnum::normal;
public function getState(): StateEnum
{
return $this->state;
}
}

View File

@ -4,8 +4,19 @@ declare(strict_types=1);
namespace PHPNative\UI\Trait;
use PHPNative\Tailwind\Style\Flex;
use PHPNative\Tailwind\Style\Width;
trait Style
{
public string $style = "";
public Flex $flex;
public Width $width;
public function getStyle(): string
{
return $this->style;
}
}

View File

@ -4,9 +4,20 @@ declare(strict_types=1);
namespace PHPNative\UI;
use PHPNative\Tailwind\Style\MediaQueryEnum;
use PHPNative\Tailwind\Style\StateEnum;
use PHPNative\UI\Collection\Views;
interface View
{
public function getRenderSort(): int;
public function setRenderSort(int $renderSort = 0): void;
public function getState(): ?StateEnum;
public function getStyle(): ?string;
public function getViews(): ?Views;
public function getId(): string;
}

View File

@ -6,9 +6,6 @@ namespace PHPNative\UI\Widget;
use PHPNative\UI\Collection\Views;
use PHPNative\UI\Trait\Action\Click;
use PHPNative\UI\Trait\Id;
use PHPNative\UI\Trait\State;
use PHPNative\UI\Trait\Style;
use PHPNative\UI\View;
class Button extends Container implements View

View File

@ -7,6 +7,7 @@ namespace PHPNative\UI\Widget;
use PHPNative\UI\Collection\Views;
use PHPNative\UI\Trait\Action\Scrollbar;
use PHPNative\UI\Trait\Id;
use PHPNative\UI\Trait\RenderSort;
use PHPNative\UI\Trait\State;
use PHPNative\UI\Trait\Style;
use PHPNative\UI\View;
@ -17,14 +18,16 @@ class Container implements View
use Scrollbar;
use State;
use Id;
use RenderSort;
public function __construct(string $style = "")
public function __construct(?string $id = null, string $style = "", public ?Views $views = null)
{
$this->style = $style;
$this->id = $id;
}
public function getViews(): ?Views
{
return null;
return $this->views;
}
}

View File

@ -4,6 +4,7 @@ namespace PHPNative\UI\Widget;
use PHPNative\UI\Collection\Views;
use PHPNative\UI\Trait\Id;
use PHPNative\UI\Trait\RenderSort;
use PHPNative\UI\Trait\State;
use PHPNative\UI\Trait\Style;
use PHPNative\UI\View;
@ -13,6 +14,7 @@ class Icon implements View
use Style;
use State;
use Id;
use RenderSort;
public function __construct(public \PHPNative\Tailwind\Data\Icon $icon = \PHPNative\Tailwind\Data\Icon::plus, public int $size = 30, string $style = '')
{

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace PHPNative\UI\Widget;
use PHPNative\UI\Trait\Id;
use PHPNative\UI\Trait\RenderSort;
use PHPNative\UI\Trait\State;
use PHPNative\UI\Trait\Style;
use PHPNative\UI\View;
@ -14,10 +15,12 @@ class Text implements View
use Style;
use State;
use Id;
use RenderSort;
public function __construct(public ?string $text, string $style = '')
public function __construct(public ?string $text, string $style = '', ?string $id = null)
{
$this->style = $style;
$this->id = $id;
}
public function getViews(): ?\PHPNative\UI\Collection\Views

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace PHPNative\UI\Widget;
use PHPNative\UI\Trait\Id;
use PHPNative\UI\Trait\RenderSort;
use PHPNative\UI\Trait\State;
use PHPNative\UI\Trait\Style;
use PHPNative\UI\View;
@ -14,6 +15,7 @@ class TextEdit implements View
use Style;
use State;
use Id;
use RenderSort;
public int $textEditIndex = 0;

View File

@ -0,0 +1,12 @@
<?php
namespace PHPNative\UI;
abstract class Window implements \PHPNative\Framework\Application\Window
{
abstract public function getTitle(): string;
abstract public function getView(): ?View;
}