diff --git a/src/PHPNative/Core/src/Collection.php b/src/PHPNative/Core/src/Collection.php index a2f2665..83f50ec 100644 --- a/src/PHPNative/Core/src/Collection.php +++ b/src/PHPNative/Core/src/Collection.php @@ -101,6 +101,11 @@ abstract class Collection implements IteratorAggregate } } + public function sort(callable $callback): void + { + usort($this->elements, $callback); + } + public function removeItem($item): void { $temp = $this->filter(function ($value, $key) use($item){ diff --git a/src/PHPNative/Framework/src/Application/Window.php b/src/PHPNative/Framework/src/Application/Window.php index 730fda9..acd4e13 100644 --- a/src/PHPNative/Framework/src/Application/Window.php +++ b/src/PHPNative/Framework/src/Application/Window.php @@ -4,10 +4,12 @@ declare(strict_types=1); namespace PHPNative\Framework\Application; +use PHPNative\Framework\Component\Component; use PHPNative\UI\View; interface Window { public function getTitle(): string; - public function getView(): View; + + public function getView(): ?View; } diff --git a/src/PHPNative/Framework/src/Component/Component.php b/src/PHPNative/Framework/src/Component/Component.php new file mode 100644 index 0000000..48a1eab --- /dev/null +++ b/src/PHPNative/Framework/src/Component/Component.php @@ -0,0 +1,10 @@ +red, $color->green, $color->blue, $color->alpha); + } + + public static function roundedBoxRGBA($renderer, int $x1, int $y1, int $x2, int $y2, int $rad, + int $r, int $g, int $b, int $a) : void + { + $cx = 0; + $cy = $rad; + $ocx = 0xffff; + $ocy = 0xffff; + $df = 1 - $rad; + $d_e = 3; + $d_se = -2 * $rad + 5; + + if ($rad <= 1) { + self::boxRGBA($renderer, $x1, $y1, $x2, $y2, $r, $g, $b, $a); + } + + if ($x1 == $x2) { + if ($y1 == $y2) { + self::pixelRGBA($renderer, $x1, $y1, $r, $g, $b, $a); + } else { + self::vlineRGBA($renderer, $x1, $y1, $y2, $r, $g, $b, $a); + } + } else { + if ($y1 == $y2) { + self::hlineRGBA($renderer, $x1, $x2, $y1, $r, $g, $b, $a); + } + } + + if ($x1 > $x2) { + $tmp = $x1; + $x1 = $x2; + $x2 = $tmp; + } + + if ($y1 > $y2) { + $tmp = $y1; + $y1 = $y2; + $y2 = $tmp; + } + + $w = $x2 - $x1 + 1; + $h = $y2 - $y1 + 1; + + /* + * Maybe adjust radius + */ + $r2 = $rad + $rad; + if ($r2 > $w) + { + $rad = (int)($w / 2); + $r2 = $rad + $rad; + } + if ($r2 > $h) + { + $rad = $h / 2; + } + + $x = $x1 + $rad; + $y = $y1 + $rad; + $dx = $x2 - $x1 - $rad - $rad; + $dy = $y2 - $y1 - $rad - $rad; + + \SDL_SetRenderDrawBlendMode($renderer, ($a == 255)? \SDL_BLENDMODE_NONE: \SDL_BLENDMODE_BLEND); + \SDL_SetRenderDrawColor($renderer, $r, $g, $b, $a); + + do { + $xpcx = $x + $cx; + $xmcx = $x - $cx; + $xpcy = $x + $cy; + $xmcy = $x - $cy; + if ($ocy != $cy) { + if ($cy > 0) { + $ypcy = $y + $cy; + $ymcy = $y - $cy; + self::_hline($renderer, $xmcx, $xpcx + $dx, $ypcy + $dy); + self::_hline($renderer, $xmcx, $xpcx + $dx, $ymcy); + } else { + self::_hline($renderer, $xmcx, $xpcx + $dx, $y); + } + $ocy = $cy; + } + if ($ocx != $cx) { + if ($cx != $cy) { + if ($cx > 0) { + $ypcx = $y + $cx; + $ymcx = $y - $cx; + self::_hline($renderer, $xmcy, $xpcy + $dx, $ymcx); + self::_hline($renderer, $xmcy, $xpcy + $dx, $ypcx + $dy); + } else { + self::_hline($renderer, $xmcy, $xpcy + $dx, $y); + } + } + $ocx = $cx; + } + + /* + * Update + */ + if ($df < 0) { + $df += $d_e; + $d_e += 2; + $d_se += 2; + } else { + $df += $d_se; + $d_e += 2; + $d_se += 4; + $cy--; + } + $cx++; + } while ($cx <= $cy); + + /* Inside */ + if ($dx > 0 && $dy > 0) { + self::boxRGBA($renderer, $x1, $y1 + $rad + 1, $x2, $y2 - $rad, $r, $g, $b, $a); + } + + } + + public static function rectangleRGBA($renderer, int $x1, int $y1, int $x2, int $y2, int $r, int $g, int $b, int $a) + { + + if ($x1 == $x2) { + if ($y1 == $y2) { + return (self::pixelRGBA($renderer, $x1, $y1, $r, $g, $b, $a)); + } else { + return (self::vlineRGBA($renderer, $x1, $y1, $y2, $r, $g, $b, $a)); + } + } else { + if ($y1 == $y2) { + return (self::hlineRGBA($renderer, $x1, $x2, $y1, $r, $g, $b, $a)); + } + } + + if ($x1 > $x2) { + $tmp = $x1; + $x1 = $x2; + $x2 = $tmp; + } + + if ($y1 > $y2) { + $tmp = $y1; + $y1 = $y2; + $y2 = $tmp; + } + + $rect = new \SDL_FRect($x1, $y1, $x2 - $x1, $y2 - $y1); + + \SDL_SetRenderDrawBlendMode($renderer, ($a == 255)? \SDL_BLENDMODE_NONE: \SDL_BLENDMODE_BLEND); + \SDL_SetRenderDrawColor($renderer, $r, $g, $b, $a); + \SDL_RenderDrawRect($renderer, $rect); + } + + public static function boxRGBA($renderer, int $x1, int $y1, int $x2, int $y2, int $r, int $g, int $b, int $a): void + { + if ($x1 == $x2) { + if ($y1 == $y2) { + self::pixelRGBA($renderer, $x1, $y1, $r, $g, $b, $a); + } else { + self::vlineRGBA($renderer, $x1, $y1, $y2, $r, $g, $b, $a); + } + } else { + if ($y1 == $y2) { + self::hlineRGBA($renderer, $x1, $x2, $y1, $r, $g, $b, $a); + } + } + + if ($x1 > $x2) { + $tmp = $x1; + $x1 = $x2; + $x2 = $tmp; + } + + if ($y1 > $y2) { + $tmp = $y1; + $y1 = $y2; + $y2 = $tmp; + } + + $rect = new \SDL_FRect($x1, $y1, $x2 - $x1 + 1, $y2 - $y1 + 1); + + \SDL_SetRenderDrawBlendMode($renderer, ($a == 255)? \SDL_BLENDMODE_NONE: \SDL_BLENDMODE_BLEND); + \SDL_SetRenderDrawColor($renderer, $r, $g, $b, $a); + \SDL_RenderFillRect($renderer, $rect); + + } + + public static function roundedRectangleRGBA($renderer, int $x1, int $y1, int $x2, int $y2, int $rad, int $r, int $g, int $b, int $a):void + { + + /* + * Special case - no rounding + */ + if ($rad <= 1) { + self::rectangleRGBA($renderer, $x1, $y1, $x2, $y2, $r, $g, $b, $a); + } + + + if ($x1 == $x2) { + if ($y1 == $y2) { + self::pixelRGBA($renderer, $x1, $y1, $r, $g, $b, $a); + } else { + self::vlineRGBA($renderer, $x1, $y1, $y2, $r, $g, $b, $a); + } + } else { + if ($y1 == $y2) { + self::hlineRGBA($renderer, $x1, $x2, $y1, $r, $g, $b, $a); + } + } + + if ($x1 > $x2) { + $tmp = $x1; + $x1 = $x2; + $x2 = $tmp; + } + + if ($y1 > $y2) { + $tmp = $y1; + $y1 = $y2; + $y2 = $tmp; + } + + $w = $x2 - $x1; + $h = $y2 - $y1; + + if (($rad * 2) > $w) + { + $rad = $w / 2; + } + if (($rad * 2) > $h) + { + $rad = $h / 2; + } + + $xx1 = $x1 + $rad; + $xx2 = $x2 - $rad; + $yy1 = $y1 + $rad; + $yy2 = $y2 - $rad; + self::arcRGBA($renderer, $xx1, $yy1, $rad, 180, 270, $r, $g, $b, $a); + self::arcRGBA($renderer, $xx2, $yy1, $rad, 270, 360, $r, $g, $b, $a); + self::arcRGBA($renderer, $xx1, $yy2, $rad, 90, 180, $r, $g, $b, $a); + self::arcRGBA($renderer, $xx2, $yy2, $rad, 0, 90, $r, $g, $b, $a); + + if ($xx1 <= $xx2) { + self::hlineRGBA($renderer, $xx1, $xx2, $y1, $r, $g, $b, $a); + self::hlineRGBA($renderer, $xx1, $xx2, $y2, $r, $g, $b, $a); + } + if ($yy1 <= $yy2) { + self::vlineRGBA($renderer, $x1, $yy1, $yy2, $r, $g, $b, $a); + self::vlineRGBA($renderer, $x2, $yy1, $yy2, $r, $g, $b, $a); + } + } + public static function _hline($renderer, int $x1, int $x2, int $y): void + { + \SDL_RenderLine($renderer, $x1, $y, $x2, $y); + } + + public static function arcRGBA($renderer, int $x, int $y, int $rad, int $start, int $end, int $r, int $g, int $b, int $a): void + { + $cx = 0; + $cy = $rad; + $df = 1 - $rad; + $d_e = 3; + $d_se = -2 * $rad + 5; + $stopval_start = 0; $stopval_end = 0; + $temp = 0.; + + + /* + * Special case for rad=0 - draw a point + */ + if ($rad == 0) { + self::pixelRGBA($renderer, $x, $y, $r, $g, $b, $a); + } + + /* + Octant labeling + + \ 5 | 6 / + \ | / + 4 \ | / 7 + \|/ + ------+------ +x + /|\ + 3 / | \ 0 + / | \ + / 2 | 1 \ + +y + + Initially reset bitmask to 0x00000000 + the set whether or not to keep drawing a given octant. + For example: 0x00111100 means we're drawing in octants 2-5 + */ + $drawoct = 0; + + /* + * Fixup angles + */ + $start %= 360; + $end %= 360; + /* 0 <= start & end < 360; note that sometimes start > end - if so, arc goes back through 0. */ + while ($start < 0) $start += 360; + while ($end < 0) $end += 360; + $start %= 360; + $end %= 360; + + /* now, we find which octants we're drawing in. */ + $startoct = $start / 45; + $endoct = $end / 45; + $oct = $startoct - 1; + + /* stopval_start, stopval_end; what values of cx to stop at. */ + do { + $oct = ($oct + 1) % 8; + + if ($oct == $startoct) { + /* need to compute stopval_start for this octant. Look at picture above if this is unclear */ + $dstart = (double)$start; + switch ($oct) + { + case 0: + case 3: + $temp = sin($dstart * M_PI / 180.); + break; + case 1: + case 6: + $temp = cos($dstart * M_PI / 180.); + break; + case 2: + case 5: + $temp = -cos($dstart * M_PI / 180.); + break; + case 4: + case 7: + $temp = -sin($dstart * M_PI / 180.); + break; + } + $temp *= $rad; + $stopval_start = (int)$temp; + + /* + This isn't arbitrary, but requires graph paper to explain well. + The basic idea is that we're always changing drawoct after we draw, so we + stop immediately after we render the last sensible pixel at x = ((int)temp). + and whether to draw in this octant initially + */ + if ($oct % 2) $drawoct |= (1 << $oct); /* this is basically like saying drawoct[oct] = true, if drawoct were a bool array */ + else $drawoct &= 255 - (1 << $oct); /* this is basically like saying drawoct[oct] = false */ + } + if ($oct == $endoct) { + /* need to compute stopval_end for this octant */ + $dend = (double)$end; + switch ($oct) + { + case 0: + case 3: + $temp = sin($dend * M_PI / 180); + break; + case 1: + case 6: + $temp = cos($dend * M_PI / 180); + break; + case 2: + case 5: + $temp = -cos($dend * M_PI / 180); + break; + case 4: + case 7: + $temp = -sin($dend * M_PI / 180); + break; + } + $temp *= $rad; + $stopval_end = (int)$temp; + + /* and whether to draw in this octant initially */ + if ($startoct == $endoct) { + /* note: we start drawing, stop, then start again in this case */ + /* otherwise: we only draw in this octant, so initialize it to false, it will get set back to true */ + if ($start > $end) { + /* unfortunately, if we're in the same octant and need to draw over the whole circle, */ + /* we need to set the rest to true, because the while loop will end at the bottom. */ + $drawoct = 255; + } else { + $drawoct &= 255 - (1 << $oct); + } + } + else if ($oct % 2) $drawoct &= 255 - (1 << $oct); + else $drawoct |= (1 << $oct); + } else if ($oct != $startoct) { /* already verified that it's != endoct */ + $drawoct |= (1 << $oct); /* draw this entire segment */ + } + } while ($oct != $endoct); + + /* so now we have what octants to draw and when to draw them. all that's left is the actual raster code. */ + + /* + * Set color + */ + \SDL_SetRenderDrawBlendMode($renderer, ($a == 255) ? \SDL_BLENDMODE_NONE: \SDL_BLENDMODE_BLEND); + \SDL_SetRenderDrawColor($renderer, $r, $g, $b, $a); + + /* + * Draw arc + */ + do { + $ypcy = $y + $cy; + $ymcy = $y - $cy; + if ($cx > 0) { + $xpcx = $x + $cx; + $xmcx = $x - $cx; + + /* always check if we're drawing a certain octant before adding a pixel to that octant. */ + if ($drawoct & 4) self::pixel($renderer, $xmcx, $ypcy); + if ($drawoct & 2) self::pixel($renderer, $xpcx, $ypcy); + if ($drawoct & 32) self::pixel($renderer, $xmcx, $ymcy); + if ($drawoct & 64) self::pixel($renderer, $xpcx, $ymcy); + } else { + if ($drawoct & 96) self::pixel($renderer, $x, $ymcy); + if ($drawoct & 6) self::pixel($renderer, $x, $ypcy); + } + + $xpcy = $x + $cy; + $xmcy = $x - $cy; + if ($cx > 0 && $cx != $cy) { + $ypcx = $y + $cx; + $ymcx = $y - $cx; + if ($drawoct & 8) self::pixel($renderer, $xmcy, $ypcx); + if ($drawoct & 1) self::pixel($renderer, $xpcy, $ypcx); + if ($drawoct & 16) self::pixel($renderer, $xmcy, $ymcx); + if ($drawoct & 128) self::pixel($renderer, $xpcy, $ymcx); + } else if ($cx == 0) { + if ($drawoct & 24) self::pixel($renderer, $xmcy, $y); + if ($drawoct & 129) self::pixel($renderer, $xpcy, $y); + } + + /* + * Update whether we're drawing an octant + */ + if ($stopval_start == $cx) { + /* works like an on-off switch. */ + /* This is just in case start & end are in the same octant. */ + if ($drawoct & (1 << $startoct)) $drawoct &= 255 - (1 << $startoct); + else $drawoct |= (1 << $startoct); + } + if ($stopval_end == $cx) { + if ($drawoct & (1 << $endoct)) $drawoct &= 255 - (1 << $endoct); + else $drawoct |= (1 << $endoct); + } + + /* + * Update pixels + */ + if ($df < 0) { + $df += $d_e; + $d_e += 2; + $d_se += 2; + } else { + $df += $d_se; + $d_e += 2; + $d_se += 4; + $cy--; + } + $cx++; + } while ($cx <= $cy); + } + + public static function pixel($renderer, int $x, int $y): void + { + \SDL_RenderPoint($renderer, $x, $y); + } + + public static function hlineRGBA($renderer, int $x1, int $x2, int $y, int $r, int $g, int $b, int $a): void + { + \SDL_SetRenderDrawBlendMode($renderer, ($a == 255) ? \SDL_BLENDMODE_NONE: \SDL_BLENDMODE_BLEND); + \SDL_SetRenderDrawColor($renderer, $r, $g, $b, $a); + \SDL_RenderLine($renderer, $x1, $y, $x2, $y); + } + + public static function vlineRGBA($renderer, int $x, int $y1, int $y2, int $r, int $g, int $b, int $a): void + { + \SDL_SetRenderDrawBlendMode($renderer, ($a == 255) ? \SDL_BLENDMODE_NONE: \SDL_BLENDMODE_BLEND); + \SDL_SetRenderDrawColor($renderer, $r, $g, $b, $a); + \SDL_RenderLine($renderer, $x, $y1, $x, $y2); + } + + public static function pixelRGBA($renderer, int $x, int $y, int $r, int $g, int $b, int $a): void + { + \SDL_SetRenderDrawBlendMode($renderer, ($a == 255) ? \SDL_BLENDMODE_NONE: \SDL_BLENDMODE_BLEND); + \SDL_SetRenderDrawColor($renderer, $r, $g, $b, $a); + \SDL_RenderPoint($renderer, $x, $y); + } +} \ No newline at end of file diff --git a/src/PHPNative/Renderer/src/Item.php b/src/PHPNative/Renderer/src/Item.php new file mode 100644 index 0000000..21c143c --- /dev/null +++ b/src/PHPNative/Renderer/src/Item.php @@ -0,0 +1,10 @@ +eventStack = new EventCollection(); + $this->renderStack = new StackCollection(); } public function show(Window $window): void { $this->window = $window; - \SDL_Init(SDL_INIT_VIDEO); + \SDL_Init(\SDL_INIT_VIDEO); \SDL_TTF_Init(); $this->windowId = \SDL_CreateWindow($this->window->getTitle(), 800, 600, \SDL_WINDOW_HIGH_PIXEL_DENSITY); $this->rendererPtr = \SDL_CreateRenderer($this->windowId); @@ -53,8 +56,25 @@ class Thread $this->startRender(); Widget::render($this, $viewPort, $this->window->getView()); + $this->renderStack->sort(function(Item $itemA, Item $itemB) { + if($itemA->level == $itemB->level) { + return 0; + } + + return ($itemA->level < $itemB->level) ? -1 : 1; + }); + $this->renderStack->map(function(Item $item) { + \SDL_SetRenderTargetWindow($this->rendererPtr); + \SDL_RenderTexture($this->rendererPtr, $item->texture, null , $item->renderAt); + }); + $this->endRender(); + $this->renderStack->map(function(Item $item) { + \SDL_DestroyTexture($item->texture); + }); + + $this->renderStack = new StackCollection(); $this->eventStack->removeFirstItem(); } @@ -81,4 +101,10 @@ class Thread } return null; } + + public function addToRenderStack(Item $item): void + { + $this->renderStack->add($item); + } + } \ No newline at end of file diff --git a/src/PHPNative/Renderer/src/Visuals/Border.php b/src/PHPNative/Renderer/src/Visuals/Border.php new file mode 100644 index 0000000..8caff3b --- /dev/null +++ b/src/PHPNative/Renderer/src/Visuals/Border.php @@ -0,0 +1,43 @@ +renderPtr, \SDL_PIXELFORMAT_RGBA8888, \SDL_TEXTUREACCESS_TARGET, $targetViewport->width, $targetViewport->height); + \SDL_SetRenderTarget($targetViewport->renderPtr, $texture); + \SDL_SetRenderDrawColor($targetViewport->renderPtr, 255, 255, 255, 0); + \SDL_RenderClear($targetViewport->renderPtr); + + // Top + if($b->enabled && $b->top > 0) { + GFX::boxRGBA($targetViewport->renderPtr, 0, 0, + $targetViewport->width, $b->top, $b->color->red, $b->color->green, $b->color->blue, $b->color->alpha); + } + // Bottom + if($b->enabled && $b->bottom > 0) { + GFX::boxRGBA($targetViewport->renderPtr, 0, $targetViewport->height - $b->bottom, + $targetViewport->width, $targetViewport->height, $b->color->red, $b->color->green, $b->color->blue, $b->color->alpha); + } + // left + if($b->enabled && $b->left > 0) { + GFX::boxRGBA($targetViewport->renderPtr, 0, 0, + $b->left, $targetViewport->height, $b->color->red, $b->color->green, $b->color->blue, $b->color->alpha); + } + // right + if($b->enabled && $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); + } + $thread->addToRenderStack(new Item($texture, new \SDL_FRect($targetViewport->x, $targetViewport->y, $targetViewport->width, $targetViewport->height), 10)); + } + } +} \ No newline at end of file diff --git a/src/PHPNative/Renderer/src/Widget.php b/src/PHPNative/Renderer/src/Widget.php index c2aef63..6a8f7d8 100644 --- a/src/PHPNative/Renderer/src/Widget.php +++ b/src/PHPNative/Renderer/src/Widget.php @@ -6,6 +6,7 @@ use PHPNative\UI\BaseView; use PHPNative\UI\View; use PHPNative\UI\Widget\Button; use PHPNative\UI\Widget\Container; +use PHPNative\UI\Widget\Label; class Widget { @@ -17,6 +18,9 @@ class Widget if($view instanceof Button) { return \PHPNative\Renderer\Widgets\Button::render($thread, $viewPort, $view); } + if($view instanceof Label) { + return \PHPNative\Renderer\Widgets\Label::render($thread, $viewPort, $view); + } if($view instanceof Container) { return \PHPNative\Renderer\Widgets\Container::render($thread, $viewPort, $view); } diff --git a/src/PHPNative/Renderer/src/Widgets/BaseView.php b/src/PHPNative/Renderer/src/Widgets/BaseView.php index b0daef5..8ce0e0a 100644 --- a/src/PHPNative/Renderer/src/Widgets/BaseView.php +++ b/src/PHPNative/Renderer/src/Widgets/BaseView.php @@ -2,6 +2,7 @@ namespace PHPNative\Renderer\Widgets; +use PHPNative\Renderer\Item; use PHPNative\Renderer\Thread; use PHPNative\Renderer\Viewport; use PHPNative\Renderer\Widget; @@ -26,9 +27,16 @@ class BaseView } 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($texture, $rect, 0)); } if(isset($styles[Padding::class]) && $m = $styles[Padding::class]) { @@ -38,8 +46,8 @@ class BaseView $viewport->height -= ($m->bottom + $m->top); } - if($view->getView() !== null) { - Widget::render($thread, $viewport, $view->getView()); + if($view->getViews()->count() > 0) { + Widget::render($thread, $viewport, $view->getViews()->first()); } return $viewport; diff --git a/src/PHPNative/Renderer/src/Widgets/Button.php b/src/PHPNative/Renderer/src/Widgets/Button.php index ef4c283..6385a21 100644 --- a/src/PHPNative/Renderer/src/Widgets/Button.php +++ b/src/PHPNative/Renderer/src/Widgets/Button.php @@ -3,14 +3,19 @@ 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; @@ -20,48 +25,32 @@ class Button public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Button $view): Viewport { + $styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, $view->state); - $font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/segoe-ui.ttf' , 30); - - $color = new \SDL_Color(0,0,0,0); - - $surface = \SDL_TTF_RenderText_Blended($font, $view->label, $color); - $texture = \SDL_CreateTextureFromSurface($viewport->renderPtr, $surface); - - if(isset($styles[Width::class]) && $m = $styles[Width::class]) { - if($styles[Width::class]->unit === Unit::Pixel) { - $viewport->width = $styles[Width::class]->value; - }elseif($styles[Width::class]->unit === Unit::Percent) { - $viewport->width = $viewport->width/100*$styles[Width::class]->value; - } - + $font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/segoe-ui.ttf' , 20); + 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); }else{ - $viewport->width = $surface->w; - $viewport->height = $surface->h; + $color = new \SDL_Color(0, 0, 0, 255); } + $surface = \SDL_TTF_RenderText_Blended($font, $view->label, $color); + + $viewport->height = $surface->h; + + $textureWidth = $viewport->width; + $textureHeight = $viewport->height; + $textureX = $viewport->x; + $textureY = $viewport->y; if(isset($styles[Margin::class]) && $m = $styles[Margin::class]) { $viewport->x += $m->left; + $viewport->width -= ($m->right + $m->left); $viewport->y += $m->top; - $viewport->width += $m->right; - $viewport->height += $m->bottom; - } + $viewport->height += ($m->bottom + $m->top); - $bgX = $viewport->x; - $bgY = $viewport->y; - - if(isset($styles[Padding::class]) && $p = $styles[Padding::class]) { - $viewport->x += $p->left; - $viewport->width += ($p->right + $p->left); - $viewport->y += $p->top; - $viewport->height += ($p->bottom + $p->top); - } - - if(isset($styles[Background::class]) && $bg = $styles[Background::class]) { - $rect = new \SDL_FRect($bgX, $bgY, $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); + $textureX += $m->left; + $textureY += $m->top; } if($thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEMOVE) { @@ -76,13 +65,161 @@ class Button } 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 ) { + 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->onClick(); } } - $rect = new \SDL_FRect($viewport->x,$viewport->y,$surface->w,$surface->h); - \SDL_RenderTexture($viewport->renderPtr, $texture, null, $rect); + 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); + $textureWidth -= ($m->right + $m->left); + $textureHeight += ($m->bottom + $m->top); + } + + if((isset($styles[Width::class]) && $m = $styles[Width::class]) || (isset($styles[Basis::class]) && $m = $styles[Basis::class])) { + + if(isset($styles[Background::class]) && $bg = $styles[Background::class]) { + + $texture = \SDL_CreateTexture($viewport->renderPtr, \SDL_PIXELFORMAT_RGBA8888, \SDL_TEXTUREACCESS_TARGET, $textureWidth, $textureHeight); + \SDL_SetRenderTarget($viewport->renderPtr, $texture); + \SDL_SetRenderDrawColor($viewport->renderPtr, 255, 255, 255, 255); + \SDL_RenderClear($viewport->renderPtr); + + $rect = new \SDL_FRect(0, 0, $textureWidth, $textureHeight); + \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($texture, new \SDL_FRect($textureX, $textureY, $textureWidth, $textureHeight), 2)); + } + + \PHPNative\Renderer\Visuals\Border::render($thread, $styles, $viewport); + + $textureFont = \SDL_CreateTextureFromSurface($viewport->renderPtr, $surface); + $thread->addToRenderStack(new Item($textureFont, new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), 3)); + + + }else{ + + } + + + + return $viewport; + + $font = \SDL_TTF_OpenFont(__DIR__ . DIRECTORY_SEPARATOR . '../../../../../assets/segoe-ui.ttf' , 30); + $color = new \SDL_Color(0,0,0,0); + $surface = \SDL_TTF_RenderText_Blended($font, $view->label, $color); + $texture = \SDL_CreateTextureFromSurface($viewport->renderPtr, $surface); + \SDL_SetRenderTarget($viewport->renderPtr, $texture); + \SDL_SetRenderDrawColor($viewport->renderPtr, 255, 255, 255, 255); + \SDL_RenderClear($viewport->renderPtr); + if((isset($styles[Width::class]) && $m = $styles[Width::class]) || (isset($styles[Basis::class]) && $m = $styles[Basis::class])) { + $viewport->height = $surface->h; + + if(isset($styles[Margin::class]) && $m = $styles[Margin::class]) { + $viewport->x += $m->left; + $viewport->y += $m->top; + $viewport->width -= ($m->right + $m->left); + $viewport->height -= ($m->top + $m->bottom); + } + + $orgX = $viewport->x; + $orgY = $viewport->y; + + if(isset($styles[Padding::class]) && $p = $styles[Padding::class]) { + $viewport->x += $p->left; + //$viewport->width -= ($p->right + $p->left); + $viewport->y += $p->top; + $viewport->height += ($p->bottom + $p->top); + } + + if(isset($styles[Background::class]) && $bg = $styles[Background::class]) { + $rect = new \SDL_FRect($orgX, $orgY, $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); + } + + + + if($thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEMOVE) { + if( $orgX <= $thread->getEvent()->x && + $thread->getEvent()->x <= $orgX + $viewport->width && + $orgY <= $thread->getEvent()->y && + $thread->getEvent()->y <= $orgY + $viewport->height ) { + $view->state = StateEnum::hover; + }else{ + $view->state = StateEnum::normal; + } + } + + if($thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEBUTTON_UP) { + if( $orgX <= $thread->getEvent()->x && + $thread->getEvent()->x <= $orgX + $viewport->width && + $orgY <= $thread->getEvent()->y && $thread->getEvent()->y <= + $orgY + $viewport->height ) { + $view->onClick(); + } + } + + $rect = new \SDL_FRect($viewport->x,$viewport->y,$surface->w,$surface->h); + + //$thread->addToRenderStack(new Item($texture, new \SDL_FRect($viewport->x, $viewport->y, $viewport->width, $viewport->height))); + + + }else{ + /*$viewport->width = $surface->w; + $viewport->height = $surface->h; + + if(isset($styles[Margin::class]) && $m = $styles[Margin::class]) { + $viewport->x += $m->left; + $viewport->y += $m->top; + } + + $orgX = $viewport->x; + $orgY = $viewport->y; + + if(isset($styles[Padding::class]) && $p = $styles[Padding::class]) { + $viewport->x += $p->left; + $viewport->width += ($p->right + $p->left); + $viewport->y += $p->top; + $viewport->height += ($p->bottom + $p->top); + } + + if(isset($styles[Background::class]) && $bg = $styles[Background::class]) { + $rect = new \SDL_FRect($orgX, $orgY, $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); + } + + if($thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEMOVE) { + if( $orgX <= $thread->getEvent()->x && + $thread->getEvent()->x <= $orgX + $viewport->width && + $orgY <= $thread->getEvent()->y && + $thread->getEvent()->y <= $orgY + $viewport->height ) { + $view->state = StateEnum::hover; + }else{ + $view->state = StateEnum::normal; + } + } + + if($thread->getEvent() && $thread->getEvent()->getType() === EventType::MOUSEBUTTON_UP) { + if( $orgX <= $thread->getEvent()->x && + $thread->getEvent()->x <= $orgX + $viewport->width && + $orgY <= $thread->getEvent()->y && $thread->getEvent()->y <= + $orgY + $viewport->height ) { + $view->onClick(); + } + } + + $rect = new \SDL_FRect($viewport->x,$viewport->y,$surface->w,$surface->h); + //var_dump(\SDL_RenderTexture($viewport->renderPtr, $texture, null, $rect));*/ + } return $viewport; } diff --git a/src/PHPNative/Renderer/src/Widgets/Container.php b/src/PHPNative/Renderer/src/Widgets/Container.php index 8b23c7f..799f4d2 100644 --- a/src/PHPNative/Renderer/src/Widgets/Container.php +++ b/src/PHPNative/Renderer/src/Widgets/Container.php @@ -2,13 +2,19 @@ namespace PHPNative\Renderer\Widgets; +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\DirectionEnum; +use PHPNative\Tailwind\Style\Flex; use PHPNative\Tailwind\Style\Margin; use PHPNative\Tailwind\Style\Padding; use PHPNative\Tailwind\Style\StateEnum; +use PHPNative\Tailwind\Style\Unit; +use PHPNative\Tailwind\Style\Width; use PHPNative\Tailwind\StyleParser; class Container @@ -16,19 +22,24 @@ class Container public static function render(Thread $thread, Viewport $viewport, \PHPNative\UI\Widget\Container $view): Viewport { $styles = StyleParser::parse($view->style)->getValidStyles($viewport->windowMediaQuery, StateEnum::normal); + $textureWidth = $viewport->width; + $textureHeight = $viewport->height; + $textureX = $viewport->x; + $textureY = $viewport->y; 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); + + $textureX += $m->left; + $textureY += $m->top; + $textureWidth -= ($m->right + $m->left); + $textureHeight -= ($m->bottom + $m->top); } - if(isset($styles[Background::class]) && $bg = $styles[Background::class]) { - $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); - } + \PHPNative\Renderer\Visuals\Border::render($thread, $styles, $viewport); if(isset($styles[Padding::class]) && $m = $styles[Padding::class]) { $viewport->x += $m->left; @@ -37,8 +48,73 @@ class Container $viewport->height -= ($m->bottom + $m->top); } - foreach($view->subViews as $subView) { - Widget::render($thread, clone $viewport, $subView); + $flexStyles = []; + if($view->getViews() != null) { + foreach ($view->getViews() as $subView) { + $found = false; + $stylesSubView = StyleParser::parse($subView->style)->getValidStyles($viewport->windowMediaQuery, StateEnum::normal); + if (isset($stylesSubView[Basis::class]) && $b = $stylesSubView[Basis::class]) { + if ($b->unit == Unit::Percent) { + $width = round($viewport->width / 100 * $b->value); + } else { + $width = $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); + } else { + $width = $w->value; + } + $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->renderPtr, $viewport->x, $viewport->y, $width, $viewport->height, $viewport->windowWidth, $viewport->windowHeight, $viewport->windowMediaQuery); + } else { + $viepo = new Viewport($viewport->windowId, $viewport->renderPtr, $viewport->x + (count($flexStyles) === 0 ? 0 : $width), $viewport->y, $width, $viewport->height, $viewport->windowWidth, $viewport->windowHeight, $viewport->windowMediaQuery); + } + $flexStyles[] = $viepo; + } else { + $flexStyles[] = $viewport; + } + } + + $topHeight = 0; + foreach ($view->getViews() as $subView) { + if (isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::column) { + $subViewPort = array_shift($flexStyles); + $subViewPort->y = $viewport->y; + $vp = Widget::render($thread, $subViewPort, $subView); + $viewport->y += $vp->height; + $viewport->height -= $vp->height; + } else { + $vp = Widget::render($thread, array_shift($flexStyles), $subView); + $topHeight = max($topHeight, $vp->height); + } + } + if (isset($styles[Flex::class]) && $f = $styles[Flex::class] && $styles[Flex::class]->direction == DirectionEnum::column) { + $textureHeight = $viewport->y; + } else { + $textureHeight = $topHeight; + $viewport->y += $topHeight; + $viewport->height = $topHeight; + } + + if (isset($styles[Background::class]) && $bg = $styles[Background::class]) { + $texture = \SDL_CreateTexture($viewport->renderPtr, \SDL_PIXELFORMAT_RGBA8888, \SDL_TEXTUREACCESS_TARGET, $textureWidth, $textureHeight); + \SDL_SetRenderTarget($viewport->renderPtr, $texture); + \SDL_SetRenderDrawColor($viewport->renderPtr, 255, 255, 255, 255); + \SDL_RenderClear($viewport->renderPtr); + + $rect = new \SDL_FRect(0, 0, $textureWidth, $textureHeight); + \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($texture, new \SDL_FRect($textureX, $textureY, $textureWidth, $textureHeight), 1)); + } } return $viewport; diff --git a/src/PHPNative/Renderer/src/Widgets/Label.php b/src/PHPNative/Renderer/src/Widgets/Label.php new file mode 100644 index 0000000..0348aa7 --- /dev/null +++ b/src/PHPNative/Renderer/src/Widgets/Label.php @@ -0,0 +1,130 @@ +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]) { + $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); + + $viewport->height = $surface->h; + + $textureWidth = $viewport->width; + $textureHeight = $viewport->height; + $textureX = $viewport->x; + $textureY = $viewport->y; + + 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); + + $textureX += $m->left; + $textureY += $m->top; + } + + 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); + $textureWidth -= ($m->right + $m->left); + $textureHeight += ($m->bottom + $m->top); + } + + if((isset($styles[Width::class]) && $m = $styles[Width::class]) || (isset($styles[Basis::class]) && $m = $styles[Basis::class])) { + + if(isset($styles[Background::class]) && $bg = $styles[Background::class]) { + + $texture = \SDL_CreateTexture($viewport->renderPtr, \SDL_PIXELFORMAT_RGBA8888, \SDL_TEXTUREACCESS_TARGET, $textureWidth, $textureHeight); + \SDL_SetRenderTarget($viewport->renderPtr, $texture); + \SDL_SetRenderDrawColor($viewport->renderPtr, 255, 255, 255, 255); + \SDL_RenderClear($viewport->renderPtr); + + $rect = new \SDL_FRect(0, 0, $textureWidth, $textureHeight); + \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($texture, new \SDL_FRect($textureX, $textureY, $textureWidth, $textureHeight), 2)); + } + + if(isset($styles[Border::class]) && $b = $styles[Border::class]) { + $texture = \SDL_CreateTexture($viewport->renderPtr, \SDL_PIXELFORMAT_RGBA8888, \SDL_TEXTUREACCESS_TARGET, $textureWidth, $textureHeight); + \SDL_SetRenderTarget($viewport->renderPtr, $texture); + \SDL_SetRenderDrawColor($viewport->renderPtr, 255, 255, 255, 0); + \SDL_RenderClear($viewport->renderPtr); + + // Top + GFX::boxRGBA($viewport->renderPtr, 0, 0, + $textureWidth, 1, $b->color->red, $b->color->green, $b->color->blue, $b->color->alpha); + + // Bottom + GFX::boxRGBA($viewport->renderPtr, 0, $textureHeight-2, + $textureWidth, $textureHeight, $b->color->red, $b->color->green, $b->color->blue, $b->color->alpha); + + // left + GFX::boxRGBA($viewport->renderPtr, 0, 0, + 1, $textureHeight, $b->color->red, $b->color->green, $b->color->blue, $b->color->alpha); + + // right + GFX::boxRGBA($viewport->renderPtr, $textureWidth-2, 0, + $textureWidth, $textureHeight, $b->color->red, $b->color->green, $b->color->blue, $b->color->alpha); + + $thread->addToRenderStack(new Item($texture, new \SDL_FRect($textureX-1, $textureY-1, $textureWidth+2, $textureHeight+2), 10)); + } + + $textureFont = \SDL_CreateTextureFromSurface($viewport->renderPtr, $surface); + $thread->addToRenderStack(new Item($textureFont, new \SDL_FRect($viewport->x, $viewport->y, $surface->w, $surface->h), 3)); + + + }else{ + + } + + + + return $viewport; + } + +} \ No newline at end of file diff --git a/src/PHPNative/Tailwind/src/Model/StyleCollection.php b/src/PHPNative/Tailwind/src/Model/StyleCollection.php index 11d7375..3adddc9 100644 --- a/src/PHPNative/Tailwind/src/Model/StyleCollection.php +++ b/src/PHPNative/Tailwind/src/Model/StyleCollection.php @@ -3,6 +3,7 @@ namespace PHPNative\Tailwind\Model; use PHPNative\Core\TypedCollection; +use PHPNative\Tailwind\Style\Border; use PHPNative\Tailwind\Style\Margin; use PHPNative\Tailwind\Style\MediaQueryEnum; use PHPNative\Tailwind\Style\Padding; @@ -37,6 +38,8 @@ class StyleCollection extends TypedCollection \PHPNative\Tailwind\Parser\Padding::merge($tmp[$style->style::class], $style->style); }elseif(isset($tmp[$style->style::class]) && $style->style::class === Margin::class) { \PHPNative\Tailwind\Parser\Margin::merge($tmp[$style->style::class], $style->style); + }elseif(isset($tmp[$style->style::class]) && $style->style::class === Border::class) { + \PHPNative\Tailwind\Parser\Border::merge($tmp[$style->style::class], $style->style); }else{ $tmp[$style->style::class] = $style->style; } diff --git a/src/PHPNative/Tailwind/src/Parser/Background.php b/src/PHPNative/Tailwind/src/Parser/Background.php index 90acab6..8df86af 100644 --- a/src/PHPNative/Tailwind/src/Parser/Background.php +++ b/src/PHPNative/Tailwind/src/Parser/Background.php @@ -6,7 +6,7 @@ namespace PHPNative\Tailwind\Parser; class Background implements Parser { - public static function parse(string $style): \PHPNative\Tailwind\Style\Background + public static function parse(string $style): ?\PHPNative\Tailwind\Style\Background { $color = new \PHPNative\Tailwind\Style\Color(); @@ -14,9 +14,9 @@ class Background implements Parser if (count($output_array[0]) > 0) { $colorStyle = $output_array[1][0]; $color = Color::parse($colorStyle); - + return new \PHPNative\Tailwind\Style\Background($color); } - return new \PHPNative\Tailwind\Style\Background($color); + return null; } } diff --git a/src/PHPNative/Tailwind/src/Parser/Basis.php b/src/PHPNative/Tailwind/src/Parser/Basis.php new file mode 100644 index 0000000..ac83204 --- /dev/null +++ b/src/PHPNative/Tailwind/src/Parser/Basis.php @@ -0,0 +1,60 @@ + 0) { + $value1 = (int)$output_array[1][0]; + $value2 = (int)$output_array[2][0]; + $unit = Unit::Percent; + $value = (int)round(100/$value2*$value1,0); + $found = true; + } + + preg_match_all('/basis-(\d*)/', $style, $output_array); + if (!$found && count($output_array[0]) > 0) { + $value = (int)$output_array[1][0]; + } + + preg_match_all('/basis-full/', $style, $output_array); + if (!$found && count($output_array[0]) > 0) { + $value = 100; + $unit = Unit::Percent; + } + + + + if($value != -1) { + return new \PHPNative\Tailwind\Style\Basis($unit, $value); + } + + return null; + } + + public static function merge(\PHPNative\Tailwind\Style\Padding $class, \PHPNative\Tailwind\Style\Padding $style) + { + if($style->left != null) { + $class->left = $style->left; + } + if($style->right != null) { + $class->right = $style->right; + } + if($style->top != null) { + $class->top = $style->top; + } + if($style->bottom != null) { + $class->bottom = $style->bottom; + } + } +} diff --git a/src/PHPNative/Tailwind/src/Parser/Border.php b/src/PHPNative/Tailwind/src/Parser/Border.php new file mode 100644 index 0000000..7637565 --- /dev/null +++ b/src/PHPNative/Tailwind/src/Parser/Border.php @@ -0,0 +1,121 @@ + 0) { + $size = match ((string)$output_array[2][0]) { + 'none' => 0, + 'sm' => 2, + 'md' => 6, + 'lg' => 8, + 'xl' => 12, + '2xl' => 16, + '3xl' => 24 + }; + return match ((string)$output_array[1][0]) { + 't' => new \PHPNative\Tailwind\Style\Border(roundTop: $size), + 'b' => new \PHPNative\Tailwind\Style\Border(roundBottom: $size), + 'r' => new \PHPNative\Tailwind\Style\Border(roundRight: $size), + 'l' => new \PHPNative\Tailwind\Style\Border(roundLeft: $size), + }; + } + + preg_match_all('/rounded-(none|sm|md|lg|xl|2xl|3xl)/', $style, $output_array); + if (count($output_array[0]) > 0) { + $size = match ((string)$output_array[1][0]) { + 'none' => 0, + 'sm' => 2, + 'md' => 6, + 'lg' => 8, + 'xl' => 12, + '2xl' => 16, + '3xl' => 24 + }; + + return new \PHPNative\Tailwind\Style\Border(roundTop: $size, roundLeft: $size, roundRight: $size, roundBottom: $size); + } + + preg_match_all('/rounded/', $style, $output_array); + if (count($output_array[0]) > 0) { + $size = 4; + + return new \PHPNative\Tailwind\Style\Border(roundTop: $size, roundLeft: $size, roundRight: $size, roundBottom: $size); + } + + preg_match_all('/border-([tblr])-(.*)/', $style, $output_array); + if (count($output_array[0]) > 0) { + return match ((string)$output_array[1][0]) { + 't' => new \PHPNative\Tailwind\Style\Border(true, top: (int)$output_array[2][0]), + 'b' => new \PHPNative\Tailwind\Style\Border(true, bottom: (int)$output_array[2][0]), + 'r' => new \PHPNative\Tailwind\Style\Border(true, right: (int)$output_array[2][0]), + 'l' => new \PHPNative\Tailwind\Style\Border(true, left: (int)$output_array[2][0]) + }; + } + + preg_match_all('/border-(.*)/', $style, $output_array); + if (count($output_array[0]) > 0) { + $colorStyle = $output_array[1][0]; + $color = Color::parse($colorStyle); + return new \PHPNative\Tailwind\Style\Border(false, $color); + } + + preg_match_all('/border/', $style, $output_array); + if (count($output_array[0]) > 0) { + return new \PHPNative\Tailwind\Style\Border(enabled: true, left: 1, right: 1, top: 1, bottom: 1); + } + + return null; + } + + public static function merge(\PHPNative\Tailwind\Style\Border $style1, \PHPNative\Tailwind\Style\Border $style2): void + { + if($style2->enabled && !$style1->enabled) { + $style1->enabled = true; + } + 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->top != -1) { + $style1->top = $style2->top; + } + if($style2->bottom != -1) { + $style1->bottom = $style2->bottom; + } + if($style2->left != -1) { + $style1->left = $style2->left; + } + if($style2->right != -1) { + $style1->right = $style2->right; + } + if($style2->roundTop != -1) { + $style1->roundTop = $style2->roundTop; + } + if($style2->roundBottom != -1) { + $style1->roundBottom = $style2->roundBottom; + } + if($style2->roundRight != -1) { + $style1->roundRight = $style2->roundRight; + } + if($style2->roundLeft != -1) { + $style1->roundLeft = $style2->roundLeft; + } + } +} diff --git a/src/PHPNative/Tailwind/src/Parser/Flex.php b/src/PHPNative/Tailwind/src/Parser/Flex.php new file mode 100644 index 0000000..19c4cb3 --- /dev/null +++ b/src/PHPNative/Tailwind/src/Parser/Flex.php @@ -0,0 +1,25 @@ + 0) { + return new \PHPNative\Tailwind\Style\Flex(DirectionEnum::column); + } + + preg_match_all('/(?!flex-col)(flex-row|flex)/', $style, $output_array); + if (count($output_array[0]) > 0) { + return new \PHPNative\Tailwind\Style\Flex(DirectionEnum::row); + } + + return null; + + } +} \ No newline at end of file diff --git a/src/PHPNative/Tailwind/src/Parser/Height.php b/src/PHPNative/Tailwind/src/Parser/Height.php new file mode 100644 index 0000000..06aaf58 --- /dev/null +++ b/src/PHPNative/Tailwind/src/Parser/Height.php @@ -0,0 +1,60 @@ + 0) { + $value1 = (int)$output_array[1][0]; + $value2 = (int)$output_array[2][0]; + $unit = Unit::Percent; + $value = 100/$value2*$value1; + $found = true; + } + + preg_match_all('/h-(\d*)/', $style, $output_array); + if (!$found && count($output_array[0]) > 0) { + $value = (int)$output_array[1][0]; + } + + preg_match_all('/(h-full|h-screen)/', $style, $output_array); + if (!$found && count($output_array[0]) > 0) { + $value = 100; + $unit = Unit::Percent; + } + + + + if($value != -1) { + return new \PHPNative\Tailwind\Style\Height($unit, $value); + } + + return null; + } + + public static function merge(\PHPNative\Tailwind\Style\Padding $class, \PHPNative\Tailwind\Style\Padding $style) + { + if($style->left != null) { + $class->left = $style->left; + } + if($style->right != null) { + $class->right = $style->right; + } + if($style->top != null) { + $class->top = $style->top; + } + if($style->bottom != null) { + $class->bottom = $style->bottom; + } + } +} diff --git a/src/PHPNative/Tailwind/src/Parser/Text.php b/src/PHPNative/Tailwind/src/Parser/Text.php new file mode 100644 index 0000000..c53f161 --- /dev/null +++ b/src/PHPNative/Tailwind/src/Parser/Text.php @@ -0,0 +1,22 @@ + 0) { + $colorStyle = $output_array[1][0]; + $color = Color::parse($colorStyle); + return new \PHPNative\Tailwind\Style\Text($color); + } + + return null; + } +} diff --git a/src/PHPNative/Tailwind/src/Parser/Width.php b/src/PHPNative/Tailwind/src/Parser/Width.php index b8f89e0..348c48f 100644 --- a/src/PHPNative/Tailwind/src/Parser/Width.php +++ b/src/PHPNative/Tailwind/src/Parser/Width.php @@ -27,14 +27,12 @@ class Width implements Parser $value = (int)$output_array[1][0]; } - preg_match_all('/w-full/', $style, $output_array); + preg_match_all('/(w-screen|w-full)/', $style, $output_array); if (!$found && count($output_array[0]) > 0) { $value = 100; $unit = Unit::Percent; } - - if($value != -1) { return new \PHPNative\Tailwind\Style\Width($unit, $value); } diff --git a/src/PHPNative/Tailwind/src/Style/Basis.php b/src/PHPNative/Tailwind/src/Style/Basis.php new file mode 100644 index 0000000..952db59 --- /dev/null +++ b/src/PHPNative/Tailwind/src/Style/Basis.php @@ -0,0 +1,12 @@ +assertSame(203, $bg->color->red); $this->assertSame(213, $bg->color->green); $this->assertSame(225, $bg->color->blue); - $this->assertSame(0, $bg->color->alpha); + $this->assertSame(255, $bg->color->alpha); + } + + public function test_gray_background(): void + { + $bg = Background::parse("flex bg-gray-300"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Background::class, $bg); + $this->assertSame(209, $bg->color->red); + $this->assertSame(213, $bg->color->green); + $this->assertSame(219, $bg->color->blue); + $this->assertSame(255, $bg->color->alpha); } } diff --git a/src/PHPNative/Tailwind/tests/BasisTest.php b/src/PHPNative/Tailwind/tests/BasisTest.php new file mode 100644 index 0000000..dc5e758 --- /dev/null +++ b/src/PHPNative/Tailwind/tests/BasisTest.php @@ -0,0 +1,44 @@ +assertInstanceOf(\PHPNative\Tailwind\Style\Basis::class, $basis); + $this->assertSame(10, $basis->value); + $this->assertSame(Unit::Pixel, $basis->unit); + } + + public function test_basis_percent_full(): void + { + $basis = Basis::parse("basis-full"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Basis::class, $basis); + $this->assertSame(100, $basis->value); + $this->assertSame(Unit::Percent, $basis->unit); + } + + public function test_basis_percent_one_half(): void + { + $basis = Basis::parse("basis-1/2"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Basis::class, $basis); + $this->assertSame(50, $basis->value); + $this->assertSame(Unit::Percent, $basis->unit); + } + + public function test_basis_percent_second_third(): void + { + $basis = Basis::parse("basis-3/4"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Basis::class, $basis); + $this->assertSame(75, $basis->value); + $this->assertSame(Unit::Percent, $basis->unit); + } +} diff --git a/src/PHPNative/Tailwind/tests/BorderTest.php b/src/PHPNative/Tailwind/tests/BorderTest.php new file mode 100644 index 0000000..c49e760 --- /dev/null +++ b/src/PHPNative/Tailwind/tests/BorderTest.php @@ -0,0 +1,153 @@ +assertInstanceOf(\PHPNative\Tailwind\Style\Border::class, $border); + $this->assertSame(203, $border->color->red); + $this->assertSame(213, $border->color->green); + $this->assertSame(225, $border->color->blue); + $this->assertSame(255, $border->color->alpha); + $this->assertSame(false, $border->enabled); + } + + public function test_gray_border(): void + { + $border = Border::parse("flex border-gray-300"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Border::class, $border); + $this->assertSame(209, $border->color->red); + $this->assertSame(213, $border->color->green); + $this->assertSame(219, $border->color->blue); + $this->assertSame(255, $border->color->alpha); + $this->assertSame(-1, $border->left); + $this->assertSame(-1, $border->right); + $this->assertSame(-1, $border->top); + $this->assertSame(-1, $border->bottom); + + $this->assertSame(false, $border->enabled); + } + + public function test_enabled(): void + { + $border = Border::parse("flex border"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Border::class, $border); + $this->assertSame(true, $border->enabled); + } + + public function test_border_complex(): void + { + $styles = StyleParser::parse("flex border border-gray-300 hover:border-lime-400")->getValidStyles(MediaQueryEnum::lx, StateEnum::normal); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Border::class, $styles[\PHPNative\Tailwind\Style\Border::class]); + $this->assertSame(209, $styles[\PHPNative\Tailwind\Style\Border::class]->color->red); + $this->assertSame(213, $styles[\PHPNative\Tailwind\Style\Border::class]->color->green); + $this->assertSame(219, $styles[\PHPNative\Tailwind\Style\Border::class]->color->blue); + $this->assertSame(255, $styles[\PHPNative\Tailwind\Style\Border::class]->color->alpha); + $this->assertSame(1, $styles[\PHPNative\Tailwind\Style\Border::class]->left); + $this->assertSame(1, $styles[\PHPNative\Tailwind\Style\Border::class]->right); + $this->assertSame(1, $styles[\PHPNative\Tailwind\Style\Border::class]->top); + $this->assertSame(1, $styles[\PHPNative\Tailwind\Style\Border::class]->bottom); + + $this->assertSame(true, $styles[\PHPNative\Tailwind\Style\Border::class]->enabled); + } + + public function test_border_complex_hover(): void + { + $styles = StyleParser::parse("flex border border-gray-300 hover:border-lime-400")->getValidStyles(MediaQueryEnum::lx, StateEnum::hover); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Border::class, $styles[\PHPNative\Tailwind\Style\Border::class]); + $this->assertSame(163, $styles[\PHPNative\Tailwind\Style\Border::class]->color->red); + $this->assertSame(230, $styles[\PHPNative\Tailwind\Style\Border::class]->color->green); + $this->assertSame(53, $styles[\PHPNative\Tailwind\Style\Border::class]->color->blue); + $this->assertSame(255, $styles[\PHPNative\Tailwind\Style\Border::class]->color->alpha); + $this->assertSame(1, $styles[\PHPNative\Tailwind\Style\Border::class]->left); + $this->assertSame(1, $styles[\PHPNative\Tailwind\Style\Border::class]->right); + $this->assertSame(1, $styles[\PHPNative\Tailwind\Style\Border::class]->top); + $this->assertSame(1, $styles[\PHPNative\Tailwind\Style\Border::class]->bottom); + + $this->assertSame(true, $styles[\PHPNative\Tailwind\Style\Border::class]->enabled); + } + + public function test_border_top(): void + { + $styles = StyleParser::parse("flex border-t-4 border-gray-300")->getValidStyles(MediaQueryEnum::lx, StateEnum::normal); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Border::class, $styles[\PHPNative\Tailwind\Style\Border::class]); + $this->assertSame(209, $styles[\PHPNative\Tailwind\Style\Border::class]->color->red); + $this->assertSame(213, $styles[\PHPNative\Tailwind\Style\Border::class]->color->green); + $this->assertSame(219, $styles[\PHPNative\Tailwind\Style\Border::class]->color->blue); + $this->assertSame(255, $styles[\PHPNative\Tailwind\Style\Border::class]->color->alpha); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->left); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->right); + $this->assertSame(4, $styles[\PHPNative\Tailwind\Style\Border::class]->top); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->bottom); + + $this->assertSame(true, $styles[\PHPNative\Tailwind\Style\Border::class]->enabled); + } + + public function test_border_rounded(): void + { + $styles = StyleParser::parse("flex rounded border-t-4 border-gray-300")->getValidStyles(MediaQueryEnum::lx, StateEnum::normal); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Border::class, $styles[\PHPNative\Tailwind\Style\Border::class]); + $this->assertSame(209, $styles[\PHPNative\Tailwind\Style\Border::class]->color->red); + $this->assertSame(213, $styles[\PHPNative\Tailwind\Style\Border::class]->color->green); + $this->assertSame(219, $styles[\PHPNative\Tailwind\Style\Border::class]->color->blue); + $this->assertSame(255, $styles[\PHPNative\Tailwind\Style\Border::class]->color->alpha); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->left); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->right); + $this->assertSame(4, $styles[\PHPNative\Tailwind\Style\Border::class]->top); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->bottom); + $this->assertSame(4, $styles[\PHPNative\Tailwind\Style\Border::class]->roundLeft); + $this->assertSame(4, $styles[\PHPNative\Tailwind\Style\Border::class]->roundRight); + + $this->assertSame(true, $styles[\PHPNative\Tailwind\Style\Border::class]->enabled); + } + + public function test_border_rounded_xl(): void + { + $styles = StyleParser::parse("flex rounded-xl border-t-4 border-gray-300")->getValidStyles(MediaQueryEnum::lx, StateEnum::normal); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Border::class, $styles[\PHPNative\Tailwind\Style\Border::class]); + $this->assertSame(209, $styles[\PHPNative\Tailwind\Style\Border::class]->color->red); + $this->assertSame(213, $styles[\PHPNative\Tailwind\Style\Border::class]->color->green); + $this->assertSame(219, $styles[\PHPNative\Tailwind\Style\Border::class]->color->blue); + $this->assertSame(255, $styles[\PHPNative\Tailwind\Style\Border::class]->color->alpha); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->left); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->right); + $this->assertSame(4, $styles[\PHPNative\Tailwind\Style\Border::class]->top); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->bottom); + $this->assertSame(12, $styles[\PHPNative\Tailwind\Style\Border::class]->roundLeft); + $this->assertSame(12, $styles[\PHPNative\Tailwind\Style\Border::class]->roundRight); + $this->assertSame(true, $styles[\PHPNative\Tailwind\Style\Border::class]->enabled); + } + + public function test_border_rounded_top_xl(): void + { + $styles = StyleParser::parse("flex rounded-t-xl border-t-4 border-gray-300")->getValidStyles(MediaQueryEnum::lx, StateEnum::normal); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Border::class, $styles[\PHPNative\Tailwind\Style\Border::class]); + $this->assertSame(209, $styles[\PHPNative\Tailwind\Style\Border::class]->color->red); + $this->assertSame(213, $styles[\PHPNative\Tailwind\Style\Border::class]->color->green); + $this->assertSame(219, $styles[\PHPNative\Tailwind\Style\Border::class]->color->blue); + $this->assertSame(255, $styles[\PHPNative\Tailwind\Style\Border::class]->color->alpha); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->left); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->right); + $this->assertSame(4, $styles[\PHPNative\Tailwind\Style\Border::class]->top); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->bottom); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->roundLeft); + $this->assertSame(12, $styles[\PHPNative\Tailwind\Style\Border::class]->roundTop); + $this->assertSame(-1, $styles[\PHPNative\Tailwind\Style\Border::class]->roundRight); + $this->assertSame(true, $styles[\PHPNative\Tailwind\Style\Border::class]->enabled); + } +} diff --git a/src/PHPNative/Tailwind/tests/ColorTest.php b/src/PHPNative/Tailwind/tests/ColorTest.php index 16d7446..505ab1a 100644 --- a/src/PHPNative/Tailwind/tests/ColorTest.php +++ b/src/PHPNative/Tailwind/tests/ColorTest.php @@ -20,7 +20,7 @@ class ColorTest extends TestCase $this->assertSame(239, $color->red); $this->assertSame(68, $color->green); $this->assertSame(68, $color->blue); - $this->assertSame(0, $color->alpha); + $this->assertSame(255, $color->alpha); } public function test_name_variant(): void @@ -30,7 +30,7 @@ class ColorTest extends TestCase $this->assertSame(190, $color->red); $this->assertSame(242, $color->green); $this->assertSame(100, $color->blue); - $this->assertSame(0, $color->alpha); + $this->assertSame(255, $color->alpha); } public function test_white(): void @@ -40,7 +40,7 @@ class ColorTest extends TestCase $this->assertSame(255, $color->red); $this->assertSame(255, $color->green); $this->assertSame(255, $color->blue); - $this->assertSame(0, $color->alpha); + $this->assertSame(255, $color->alpha); } public function test_black(): void @@ -50,6 +50,6 @@ class ColorTest extends TestCase $this->assertSame(0, $color->red); $this->assertSame(0, $color->green); $this->assertSame(0, $color->blue); - $this->assertSame(0, $color->alpha); + $this->assertSame(255, $color->alpha); } } diff --git a/src/PHPNative/Tailwind/tests/FlexTest.php b/src/PHPNative/Tailwind/tests/FlexTest.php new file mode 100644 index 0000000..0a0b4c5 --- /dev/null +++ b/src/PHPNative/Tailwind/tests/FlexTest.php @@ -0,0 +1,33 @@ +assertInstanceOf(\PHPNative\Tailwind\Style\Flex::class, $flex); + $this->assertSame(DirectionEnum::row, $flex->direction); + } + + public function test_container_flex_row(): void + { + $flex = Flex::parse("flex flex-row"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Flex::class, $flex); + $this->assertSame(DirectionEnum::row, $flex->direction); + } + + public function test_container_flex_col(): void + { + $flex = Flex::parse("flex flex-col"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Flex::class, $flex); + $this->assertSame(DirectionEnum::column, $flex->direction); + } +} diff --git a/src/PHPNative/Tailwind/tests/HeightTest.php b/src/PHPNative/Tailwind/tests/HeightTest.php new file mode 100644 index 0000000..09bf9c1 --- /dev/null +++ b/src/PHPNative/Tailwind/tests/HeightTest.php @@ -0,0 +1,51 @@ +assertInstanceOf(\PHPNative\Tailwind\Style\Height::class, $height); + $this->assertSame(10, $height->value); + $this->assertSame(Unit::Pixel, $height->unit); + } + + public function test_height_percent_full(): void + { + $height = Height::parse("h-full"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Height::class, $height); + $this->assertSame(100, $height->value); + $this->assertSame(Unit::Percent, $height->unit); + } + + public function test_height_percent_screen(): void + { + $height = Height::parse("h-screen"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Height::class, $height); + $this->assertSame(100, $height->value); + $this->assertSame(Unit::Percent, $height->unit); + } + + public function test_height_percent_one_half(): void + { + $height = Height::parse("h-1/2"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Height::class, $height); + $this->assertSame(50, $height->value); + $this->assertSame(Unit::Percent, $height->unit); + } + + public function test_height_percent_second_third(): void + { + $height = Height::parse("h-3/4"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Height::class, $height); + $this->assertSame(75, $height->value); + $this->assertSame(Unit::Percent, $height->unit); + } +} diff --git a/src/PHPNative/Tailwind/tests/TextTest.php b/src/PHPNative/Tailwind/tests/TextTest.php new file mode 100644 index 0000000..be212b0 --- /dev/null +++ b/src/PHPNative/Tailwind/tests/TextTest.php @@ -0,0 +1,35 @@ +assertInstanceOf(\PHPNative\Tailwind\Style\Text::class, $text); + $this->assertSame(203, $text->color->red); + $this->assertSame(213, $text->color->green); + $this->assertSame(225, $text->color->blue); + $this->assertSame(255, $text->color->alpha); + } + + public function test_gray_text(): void + { + $text = Text::parse("flex text-gray-300"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Text::class, $text); + $this->assertSame(209, $text->color->red); + $this->assertSame(213, $text->color->green); + $this->assertSame(219, $text->color->blue); + $this->assertSame(255, $text->color->alpha); + } +} diff --git a/src/PHPNative/Tailwind/tests/WidthTest.php b/src/PHPNative/Tailwind/tests/WidthTest.php index ae30619..a950fd4 100644 --- a/src/PHPNative/Tailwind/tests/WidthTest.php +++ b/src/PHPNative/Tailwind/tests/WidthTest.php @@ -26,6 +26,14 @@ class WidthTest extends TestCase $this->assertSame(Unit::Percent, $width->unit); } + public function test_width_percent_screen(): void + { + $width = Width::parse("w-screen"); + $this->assertInstanceOf(\PHPNative\Tailwind\Style\Width::class, $width); + $this->assertSame(100, $width->value); + $this->assertSame(Unit::Percent, $width->unit); + } + public function test_width_percent_one_half(): void { $width = Width::parse("w-1/2"); diff --git a/src/PHPNative/UI/src/BaseView.php b/src/PHPNative/UI/src/BaseView.php index d08c50d..c36a685 100644 --- a/src/PHPNative/UI/src/BaseView.php +++ b/src/PHPNative/UI/src/BaseView.php @@ -2,20 +2,21 @@ namespace PHPNative\UI; +use PHPNative\UI\Collection\Views; use PHPNative\UI\Trait\Style; class BaseView implements View { use Style; - public ?View $view = null; + public ?Views $views = null; public function __construct() { } - public function getView(): ?View + public function getViews(): ?Views { - return $this->view; + return $this->views; } } \ No newline at end of file diff --git a/src/PHPNative/UI/src/Collection/Views.php b/src/PHPNative/UI/src/Collection/Views.php new file mode 100644 index 0000000..d0e2690 --- /dev/null +++ b/src/PHPNative/UI/src/Collection/Views.php @@ -0,0 +1,13 @@ +style = $style; } - public function getView(): ?View + public function getViews(): ?Views { return null; } diff --git a/src/PHPNative/UI/src/Widget/Label.php b/src/PHPNative/UI/src/Widget/Label.php new file mode 100644 index 0000000..e5cef33 --- /dev/null +++ b/src/PHPNative/UI/src/Widget/Label.php @@ -0,0 +1,25 @@ +style = $style; + } + + public function getViews(): ?\PHPNative\UI\Collection\Views + { + } +}