1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace Atk4\Ui;
6:
7: class GridLayout extends View
8: {
9: public $ui = 'grid';
10:
11: public $defaultTemplate = 'grid-layout.html';
12:
13: /** @var int Number of rows */
14: protected $rows = 1;
15:
16: /** @var int<1, 16> Number of columns */
17: protected $columns = 2;
18:
19: /** @var array<int, string> */
20: protected $cssWideClasses = [
21: 1 => 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',
22: 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen',
23: ];
24:
25: /** @var HtmlTemplate */
26: protected $tWrap;
27: /** @var HtmlTemplate */
28: protected $tRow;
29: /** @var HtmlTemplate */
30: protected $tCol;
31:
32: /** @var string CSS class for columns view */
33: public $columnClass = '';
34:
35: #[\Override]
36: protected function init(): void
37: {
38: parent::init();
39:
40: $this->template->set('columnClass', $this->columnClass);
41:
42: // extract template parts
43: $this->tWrap = clone $this->template;
44: $this->tRow = $this->template->cloneRegion('row');
45: $this->tCol = $this->template->cloneRegion('column');
46:
47: // clean them
48: $this->tRow->del('column');
49: $this->tWrap->del('rows');
50:
51: // will need to manipulate template a little
52: $this->buildTemplate();
53: }
54:
55: protected function buildTemplate(): void
56: {
57: $this->tWrap->del('rows');
58: $this->tWrap->dangerouslyAppendHtml('rows', '{rows}');
59:
60: for ($row = 1; $row <= $this->rows; ++$row) {
61: $this->tRow->del('column');
62:
63: for ($col = 1; $col <= $this->columns; ++$col) {
64: $this->tCol->set('Content', '{$r' . $row . 'c' . $col . '}');
65:
66: $this->tRow->dangerouslyAppendHtml('column', $this->tCol->renderToHtml());
67: }
68:
69: $this->tWrap->dangerouslyAppendHtml('rows', $this->tRow->renderToHtml());
70: }
71: $this->tWrap->dangerouslyAppendHtml('rows', '{/rows}');
72: $tmp = new HtmlTemplate($this->tWrap->renderToHtml());
73:
74: // TODO replace later, the only use of direct template tree manipulation
75: $t = $this->template;
76: \Closure::bind(static function () use ($t, $tmp) {
77: $cloneTagTreeFx = static function (HtmlTemplate\TagTree $src) use (&$cloneTagTreeFx, $t) {
78: $tagTree = $src->clone($t);
79: $t->tagTrees[$src->getTag()] = $tagTree;
80: \Closure::bind(static function () use ($tagTree, $cloneTagTreeFx, $src) {
81: foreach ($tagTree->children as $v) {
82: if (is_string($v)) {
83: $cloneTagTreeFx($src->getParentTemplate()->getTagTree($v));
84: }
85: }
86: }, null, HtmlTemplate\TagTree::class)();
87: };
88: $cloneTagTreeFx($tmp->getTagTree('rows'));
89:
90: // TODO prune unreachable nodes
91: // $template->rebuildTagsIndex();
92: }, null, HtmlTemplate::class)();
93:
94: $this->addClass($this->cssWideClasses[$this->columns] . ' column');
95: }
96: }
97: