|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace eXpansion\Framework\Gui\Layouts; |
|
4
|
|
|
|
|
5
|
|
|
use eXpansion\Framework\Gui\Components\abstractUiElement; |
|
6
|
|
|
use eXpansion\Framework\Gui\Components\uiScrollbar; |
|
7
|
|
|
use FML\Controls\Frame; |
|
8
|
|
|
use FML\Controls\Quad; |
|
9
|
|
|
use FML\Script\Features\ScriptFeature; |
|
10
|
|
|
use FML\Script\Script; |
|
11
|
|
|
use FML\Script\ScriptLabel; |
|
12
|
|
|
use FML\Types\Renderable; |
|
13
|
|
|
use FML\Types\ScriptFeatureable; |
|
14
|
|
|
|
|
15
|
|
|
class layoutScrollable extends abstractUiElement implements Renderable, ScriptFeatureable |
|
16
|
|
|
{ |
|
17
|
|
|
|
|
18
|
|
|
protected $force = false; |
|
19
|
|
|
protected $_X = 0; |
|
20
|
|
|
protected $_Y = 0; |
|
21
|
|
|
protected $offset = 0; |
|
22
|
|
|
protected $scrollbarH = true; |
|
23
|
|
|
protected $scrollbarV = true; |
|
24
|
|
|
protected $parentFrame = null; |
|
25
|
|
|
protected $frame_posX = 0; |
|
26
|
|
|
protected $frame_posY = 0; |
|
27
|
|
|
|
|
28
|
|
|
/** |
|
29
|
|
|
* layoutScrollable constructor. |
|
30
|
|
|
* @param $frame |
|
31
|
|
|
* @param $sizeX |
|
32
|
|
|
* @param $sizeY |
|
33
|
|
|
*/ |
|
34
|
|
|
public function __construct($frame, $sizeX, $sizeY) |
|
35
|
|
|
{ |
|
36
|
|
|
$this->parentFrame = $frame; |
|
37
|
|
|
$this->frame_posX = $frame->getX(); |
|
38
|
|
|
$this->frame_posY = $frame->getY(); |
|
39
|
|
|
$this->setSize($sizeX, $sizeY); |
|
40
|
|
|
|
|
41
|
|
|
$frame->setPosition(0, 0); |
|
42
|
|
|
} |
|
43
|
|
|
|
|
44
|
|
|
/** |
|
45
|
|
|
* @param bool $x |
|
46
|
|
|
* @param bool $y |
|
47
|
|
|
*/ |
|
48
|
|
|
public function setAxis($x, $y) |
|
49
|
|
|
{ |
|
50
|
|
|
$this->scrollbarH = $x; |
|
51
|
|
|
$this->scrollbarV = $y; |
|
52
|
|
|
} |
|
53
|
|
|
|
|
54
|
|
|
public function forceContainerSize($x, $y) |
|
55
|
|
|
{ |
|
56
|
|
|
$this->force = true; |
|
57
|
|
|
$this->_X = $x; |
|
58
|
|
|
$this->_Y = $y; |
|
59
|
|
|
} |
|
60
|
|
|
|
|
61
|
|
|
/** |
|
62
|
|
|
* Render the XML element |
|
63
|
|
|
* |
|
64
|
|
|
* @param \DOMDocument $domDocument DOMDocument for which the XML element should be rendered |
|
65
|
|
|
* @return \DOMElement |
|
66
|
|
|
*/ |
|
67
|
|
|
public function render(\DOMDocument $domDocument) |
|
68
|
|
|
{ |
|
69
|
|
|
$container = new Frame(); |
|
70
|
|
|
$container->setPosition($this->frame_posX, $this->frame_posY); |
|
71
|
|
|
|
|
72
|
|
|
$quad = new Quad(); |
|
73
|
|
|
$quad->setStyles('Bgs1', 'BgColorContour') |
|
74
|
|
|
->setSize($this->getWidth(), $this->getHeight()); |
|
75
|
|
|
|
|
76
|
|
|
$contentFrame = new Frame(); |
|
77
|
|
|
$contentFrame->addChild($this->parentFrame); |
|
78
|
|
|
|
|
79
|
|
|
$container->addChild($quad); |
|
80
|
|
|
$container->addChild($contentFrame); |
|
81
|
|
View Code Duplication |
if ($this->scrollbarV) { |
|
|
|
|
|
|
82
|
|
|
$contentFrame->setSize($this->width - 5, $this->height); |
|
83
|
|
|
$this->offset = 5; |
|
84
|
|
|
$container->addChild(new uiScrollbar( |
|
85
|
|
|
"Y", |
|
86
|
|
|
$this->getWidth(), |
|
87
|
|
|
0, |
|
88
|
|
|
10, |
|
89
|
|
|
$this->getHeight() |
|
90
|
|
|
)); |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
View Code Duplication |
if ($this->scrollbarH) { |
|
|
|
|
|
|
94
|
|
|
$contentFrame->setSize($this->width - 5, $this->height - 5); |
|
95
|
|
|
$container->addChild(new uiScrollbar( |
|
96
|
|
|
"X", |
|
97
|
|
|
0, |
|
98
|
|
|
-$this->getHeight(), |
|
99
|
|
|
10, |
|
100
|
|
|
$this->getWidth() - $this->offset |
|
101
|
|
|
)); |
|
102
|
|
|
} |
|
103
|
|
|
|
|
104
|
|
|
|
|
105
|
|
|
return $container->render($domDocument); |
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
/** |
|
109
|
|
|
* Get the Script Features |
|
110
|
|
|
* @todo write recursion for frames... |
|
111
|
|
|
* @return ScriptFeature[] |
|
112
|
|
|
*/ |
|
113
|
|
|
public function getScriptFeatures() |
|
114
|
|
|
{ |
|
115
|
|
|
$features = []; |
|
116
|
|
|
if ($this->parentFrame instanceof ScriptFeatureable) { |
|
117
|
|
|
$features[] = $this->parentFrame->getScriptFeatures(); |
|
118
|
|
|
} |
|
119
|
|
|
$features[] = $this; |
|
120
|
|
|
|
|
121
|
|
|
return ScriptFeature::collect($features); |
|
122
|
|
|
} |
|
123
|
|
|
|
|
124
|
|
|
|
|
125
|
|
|
/** |
|
126
|
|
|
* Prepare the given Script for rendering by adding the needed Labels, etc. |
|
127
|
|
|
* |
|
128
|
|
|
* @param Script $script Script to prepare |
|
129
|
|
|
* @return static |
|
130
|
|
|
*/ |
|
131
|
|
|
public function prepare(Script $script) |
|
132
|
|
|
{ |
|
133
|
|
|
$script->addCustomScriptLabel(ScriptLabel::MouseClick, $this->getScriptMouseClick()); |
|
134
|
|
|
$script->addCustomScriptLabel(ScriptLabel::OnInit, $this->getScriptInit()); |
|
135
|
|
|
$script->addCustomScriptLabel(ScriptLabel::Loop, $this->getScriptLoop()); |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
protected function getScriptInit() |
|
139
|
|
|
{ |
|
140
|
|
|
$offset = number_format($this->offset, 1, ".", ""); |
|
141
|
|
|
|
|
142
|
|
|
return /** @lang textmate */ |
|
143
|
|
|
<<<EOL |
|
144
|
|
|
|
|
145
|
|
|
declare CMlFrame exp_scroll_frame = Null; |
|
146
|
|
|
declare CMlFrame exp_scroll_content = Null; |
|
147
|
|
|
declare Vec2 exp_scroll_content_size = <0.,0.>; |
|
148
|
|
|
declare Boolean exp_scroll_activeY = False; |
|
149
|
|
|
declare Boolean exp_scroll_activeX = False; |
|
150
|
|
|
declare Vec2 exp_scroll_pos = <0.,0.>; |
|
151
|
|
|
declare Real exp_scroll_offset = $offset; |
|
152
|
|
|
EOL; |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
|
|
|
|
156
|
|
|
protected function getScriptMouseClick() |
|
157
|
|
|
{ |
|
158
|
|
|
return /** @lang textmate */ |
|
159
|
|
|
<<<EOL |
|
160
|
|
|
|
|
161
|
|
|
if (Event.Control != Null && Event.Control.HasClass("uiScrollbar") ) { |
|
162
|
|
|
if (Event.Control.DataAttributeGet("axis") == "X") { |
|
163
|
|
|
exp_scroll_activeX = True; |
|
164
|
|
|
log(Now ^ "X"); |
|
165
|
|
|
} else { |
|
166
|
|
|
exp_scroll_activeY = True; |
|
167
|
|
|
} |
|
168
|
|
|
exp_scroll_frame = Event.Control.Parent; |
|
169
|
|
|
exp_scroll_pos = <MouseX, MouseY> - Event.Control.RelativePosition_V3 ; |
|
170
|
|
|
exp_scroll_content = (exp_scroll_frame.Parent.Controls[1] as CMlFrame); // gets the bounding frame |
|
171
|
|
|
exp_scroll_content_size = exp_scroll_content.Controls[0].Size; |
|
172
|
|
|
log(exp_scroll_content_size); |
|
173
|
|
|
} |
|
174
|
|
|
EOL; |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
|
|
178
|
|
|
protected function getScriptLoop() |
|
179
|
|
|
{ |
|
180
|
|
|
return /** @lang textmate */ |
|
181
|
|
|
<<<EOL |
|
182
|
|
|
|
|
183
|
|
|
if (exp_scroll_activeY) { |
|
184
|
|
|
declare Real pos = (MouseY - exp_scroll_pos.Y) ; |
|
185
|
|
|
declare Real upperLimit = exp_scroll_frame.RelativePosition_V3.Y - exp_scroll_frame.RelativePosition_V3.Y - 5.; |
|
186
|
|
|
declare Real lowerLimit = upperLimit - exp_scroll_frame.Controls[3].Size.Y + exp_scroll_frame.Controls[0].Size.Y + 10.; |
|
187
|
|
|
|
|
188
|
|
|
if (pos > upperLimit) { |
|
189
|
|
|
pos = upperLimit; |
|
190
|
|
|
} |
|
191
|
|
|
|
|
192
|
|
|
if (pos < lowerLimit) { |
|
193
|
|
|
pos = lowerLimit; |
|
194
|
|
|
} |
|
195
|
|
|
|
|
196
|
|
|
declare Real start = (upperLimit - pos); |
|
197
|
|
|
declare Real diff = MathLib::Abs(lowerLimit - upperLimit); |
|
198
|
|
|
|
|
199
|
|
|
exp_scroll_frame.Controls[0].RelativePosition_V3.Y = pos; // update scrollbar position |
|
200
|
|
|
exp_scroll_content.Controls[0].RelativePosition_V3.Y = (start / diff) * (exp_scroll_content_size.Y - exp_scroll_frame.Parent.Controls[0].Size.Y + 10.); // gets the content frame |
|
201
|
|
|
} |
|
202
|
|
|
|
|
203
|
|
|
if (exp_scroll_activeX) { |
|
204
|
|
|
declare Real pos = ( MouseX - exp_scroll_pos.X); |
|
205
|
|
|
declare Real leftLimit = 5.; |
|
206
|
|
|
declare Real rightLimit = leftLimit + exp_scroll_frame.Controls[3].Size.X - exp_scroll_frame.Controls[0].Size.X -10.; |
|
207
|
|
|
|
|
208
|
|
|
if (pos < leftLimit) { |
|
209
|
|
|
pos = leftLimit; |
|
210
|
|
|
} |
|
211
|
|
|
|
|
212
|
|
|
if (pos > rightLimit) { |
|
213
|
|
|
pos = rightLimit; |
|
214
|
|
|
} |
|
215
|
|
|
|
|
216
|
|
|
declare Real start = (leftLimit - pos); |
|
217
|
|
|
declare Real diff = MathLib::Abs(leftLimit + rightLimit); |
|
218
|
|
|
|
|
219
|
|
|
exp_scroll_frame.Controls[0].RelativePosition_V3.X = pos; // update scrollbar position |
|
220
|
|
|
exp_scroll_content.Controls[0].RelativePosition_V3.X = (start / diff) * (exp_scroll_content_size.X + 10); // gets the content frame |
|
221
|
|
|
} |
|
222
|
|
|
|
|
223
|
|
|
|
|
224
|
|
|
|
|
225
|
|
|
if (MouseLeftButton == False) { |
|
226
|
|
|
exp_scroll_activeX = False; |
|
227
|
|
|
exp_scroll_activeY = False; |
|
228
|
|
|
} |
|
229
|
|
|
|
|
230
|
|
|
EOL; |
|
231
|
|
|
} |
|
232
|
|
|
|
|
233
|
|
|
} |
|
234
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.