@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PHUIFormationView
4 extends AphrontAutoIDView {
5
6 private $items = array();
7
8 public function newFlankColumn() {
9 $item = $this->newItem(new PHUIFormationFlankView());
10 return $item->getColumn();
11 }
12
13 public function newContentColumn() {
14 $item = $this->newItem(new PHUIFormationContentView());
15 return $item->getColumn();
16 }
17
18 private function newItem(PHUIFormationColumnView $column) {
19 $item = id(new PHUIFormationColumnItem())
20 ->setColumn($column);
21
22 $column->setColumnItem($item);
23
24 $this->items[] = $item;
25
26 return $item;
27 }
28
29 public function render() {
30 require_celerity_resource('phui-formation-view-css');
31
32 $items = $this->items;
33
34 $items = $this->generateControlBindings($items);
35 $items = $this->generateExpanders($items);
36 $items = $this->generateResizers($items);
37
38 $cells = array();
39 foreach ($items as $item) {
40 $style = array();
41
42 $column = $item->getColumn();
43
44 $width = $column->getWidth();
45 if ($width !== null) {
46 $style[] = sprintf('width: %dpx;', $width);
47 }
48
49 if (!$column->getIsVisible()) {
50 $style[] = 'display: none;';
51 }
52
53 $classes = array();
54 if ($column->getIsDesktopOnly()) {
55 $classes[] = 'phui-formation-desktop-only';
56 }
57
58 $cells[] = phutil_tag(
59 'td',
60 array(
61 'id' => $item->getID(),
62 'style' => implode(' ', $style),
63 'class' => implode(' ', $classes),
64 ),
65 array(
66 $column,
67 $item->getExpanders(),
68 ));
69 }
70
71 $phuix_items = array();
72 foreach ($items as $item) {
73 $phuix_items[] = $item->newClientProperties();
74 }
75
76 $table_row = phutil_tag('tr', array(), $cells);
77 $table_body = phutil_tag('tbody', array(), $table_row);
78 $table = javelin_tag(
79 'table',
80 array(
81 'id' => $this->getID(),
82 'class' => 'phui-formation-view',
83 'role' => 'presentation',
84 'sigil' => 'phuix-formation-view',
85 'meta' => array(
86 'items' => $phuix_items,
87 ),
88 ),
89 $table_body);
90
91 return $table;
92 }
93
94 private function newColumnExpanderView() {
95 return new PHUIFormationExpanderView();
96 }
97
98 private function newResizerItem() {
99 return $this->newItem(new PHUIFormationResizerView());
100 }
101
102 private function generateControlBindings(array $items) {
103 $count = count($items);
104
105 if (!$count) {
106 return $items;
107 }
108
109 $last_control = null;
110
111 for ($ii = 0; $ii < $count; $ii++) {
112 $item = $items[$ii];
113 $column = $item->getColumn();
114
115 $is_control = $column->getIsControlColumn();
116 if ($is_control) {
117 $last_control = $ii;
118 }
119 }
120
121 if ($last_control === null) {
122 return $items;
123 }
124
125 for ($ii = ($count - 1); $ii >= 0; $ii--) {
126 $item = $items[$ii];
127 $column = $item->getColumn();
128
129 $is_control = $column->getIsControlColumn();
130 if ($is_control) {
131 $last_control = $ii;
132 continue;
133 }
134
135 $is_right = ($last_control < $ii);
136
137 $item
138 ->setControlItem($items[$last_control])
139 ->setIsRightAligned($is_right);
140 }
141
142 return $items;
143 }
144
145 private function generateResizers(array $items) {
146 $result = array();
147 foreach ($items as $item) {
148 $column = $item->getColumn();
149
150 $resizer_item = null;
151 if ($column->getIsResizable()) {
152 $resizer_item = $this->newResizerItem();
153 $item->setResizerItem($resizer_item);
154
155 $resizer_item->getColumn()
156 ->setIsDesktopOnly($column->getIsDesktopOnly())
157 ->setIsVisible($column->getIsVisible());
158 }
159
160 if (!$resizer_item) {
161 $result[] = $item;
162 } else if ($item->getIsRightAligned()) {
163 $result[] = $resizer_item;
164 $result[] = $item;
165 } else {
166 $result[] = $item;
167 $result[] = $resizer_item;
168 }
169 }
170
171 return $result;
172 }
173
174 private function generateExpanders(array $items) {
175 foreach ($items as $item) {
176 $control_item = $item->getControlItem();
177 if (!$control_item) {
178 continue;
179 }
180
181 $expander = $this->newColumnExpanderView();
182
183 $tip = $item->getColumn()->getExpanderTooltip();
184 $expander->setTooltip($tip);
185
186 $expander->setColumnItem($item);
187 $item->setExpander($expander);
188
189 $control_item->appendExpander($expander);
190 }
191
192 return $items;
193 }
194
195 public function setFooter($footer) {
196 foreach ($this->items as $item) {
197 if ($item->getColumn() instanceof PHUIFormationContentView) {
198 $item->getColumn()->appendChild($footer);
199 return $this;
200 }
201 }
202
203 throw new Exception(
204 pht('Unable to find a content column to place the footer inside.'));
205 }
206
207}