Completed
Pull Request — master (#270)
by
unknown
03:14
created

LayoutScrollable::render()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 40
Code Lines 28

Duplication

Lines 21
Ratio 52.5 %

Importance

Changes 0
Metric Value
dl 21
loc 40
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 28
nc 4
nop 1
1
<?php
2
3
namespace eXpansion\Framework\Gui\Layouts;
4
5
use eXpansion\Framework\Gui\Components\AbstractUiElement;
6
use eXpansion\Framework\Gui\Components\Scrollbar;
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 $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();
0 ignored issues
show
Documentation Bug introduced by
The property $frame_posX was declared of type integer, but $frame->getX() is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
38
        $this->frame_posY = $frame->getY();
0 ignored issues
show
Documentation Bug introduced by
The property $frame_posY was declared of type integer, but $frame->getY() is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
39
        $this->setSize($sizeX, $sizeY);
40
41
        $frame->setPosition(0, 0);
42
    }
43
44
    /**
45
     * Set the axis which supports scrolling
46
     * default all axis enabled
47
     * @param bool $x
48
     * @param bool $y
49
     */
50
    public function setAxis($x, $y)
51
    {
52
        $this->scrollbarH = $x;
53
        $this->scrollbarV = $y;
54
    }
55
56
    /**
57
     * Forces container size.
58
     * @param $x
59
     * @param $y
60
     */
61
    public function forceContainerSize($x, $y)
62
    {
63
        $this->force = true;
64
        $this->_X = $x;
65
        $this->_Y = $y;
66
    }
67
68
    /**
69
     * Render the XML element
70
     *
71
     * @param \DOMDocument $domDocument DOMDocument for which the XML element should be rendered
72
     * @return \DOMElement
73
     */
74
    public function render(\DOMDocument $domDocument)
75
    {
76
        $container = new Frame();
77
        $container->setPosition($this->frame_posX, $this->frame_posY);
78
79
        $quad = new Quad();
80
        $quad->setStyles('Bgs1', 'BgColorContour')
81
            ->setSize($this->getWidth(), $this->getHeight());
82
83
        $contentFrame = new Frame();
84
        $contentFrame->addChild($this->parentFrame);
85
86
        $container->addChild($quad);
87
        $container->addChild($contentFrame);
88 View Code Duplication
        if ($this->scrollbarV) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
89
            $contentFrame->setSize($this->width - 5, $this->height);
90
            $this->offset = 5;
91
            $container->addChild(new Scrollbar(
92
                "Y",
93
                $this->getWidth(),
94
                0,
95
                10,
96
                $this->getHeight()
97
            ));
98
        }
99
100 View Code Duplication
        if ($this->scrollbarH) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
101
            $contentFrame->setSize($this->width - 5, $this->height - 5);
102
            $container->addChild(new Scrollbar(
103
                "X",
104
                0,
105
                -$this->getHeight(),
106
                10,
107
                $this->getWidth() - $this->offset
108
            ));
109
        }
110
111
112
        return $container->render($domDocument);
113
    }
114
115
    /**
116
     * Get the Script Features
117
     *
118
     * @return ScriptFeature[]
119
     */
120
    public function getScriptFeatures()
121
    {
122
        $features = [];
123
        if ($this->parentFrame instanceof ScriptFeatureable) {
124
            $features[] = $this->parentFrame->getScriptFeatures();
125
        }
126
        $features[] = $this;
127
128
        return ScriptFeature::collect($features);
129
    }
130
131
132
    /**
133
     * Prepare the given Script for rendering by adding the needed Labels, etc.
134
     *
135
     * @param Script $script Script to prepare
136
     * @return void
137
     */
138
    public function prepare(Script $script)
139
    {
140
        $script->addCustomScriptLabel(ScriptLabel::MouseClick, $this->getScriptMouseClick());
141
        $script->addCustomScriptLabel(ScriptLabel::OnInit, $this->getScriptInit());
142
        $script->addCustomScriptLabel(ScriptLabel::Loop, $this->getScriptLoop());
143
    }
144
145
    protected function getScriptInit()
146
    {
147
        $offset = number_format($this->offset, 1, ".", "");
148
149
        return /** @lang textmate */
150
            <<<EOL
151
            
152
            declare CMlFrame exp_scroll_frame = Null;
153
            declare CMlFrame exp_scroll_content = Null;
154
            declare Vec2 exp_scroll_content_size = <0.,0.>; 
155
            declare Boolean exp_scroll_activeY = False;
156
            declare Boolean exp_scroll_activeX = False;
157
            declare Vec2 exp_scroll_pos = <0.,0.>;
158
            declare Real exp_scroll_offset = $offset;
159
EOL;
160
    }
161
162
163
    protected function getScriptMouseClick()
164
    {
165
        return /** @lang textmate */
166
            <<<EOL
167
            
168
            if (Event.Control != Null && Event.Control.HasClass("uiScrollbar") )  {
169
                if (Event.Control.DataAttributeGet("axis") == "X") {
170
                    exp_scroll_activeX = True;
171
                    log(Now ^ "X");
172
                } else {
173
                    exp_scroll_activeY = True;																
174
                }
175
                exp_scroll_frame = Event.Control.Parent;
176
                exp_scroll_pos = <MouseX, MouseY> - Event.Control.RelativePosition_V3 ;
177
                exp_scroll_content = (exp_scroll_frame.Parent.Controls[1] as CMlFrame); // gets the bounding frame				
178
                exp_scroll_content_size = exp_scroll_content.Controls[0].Size;
179
                log(exp_scroll_content_size);
180
            }
181
EOL;
182
    }
183
184
185
    protected function getScriptLoop()
186
    {
187
        return /** @lang textmate */
188
            <<<EOL
189
190
        if (exp_scroll_activeY) {		
191
					declare Real pos = (MouseY - exp_scroll_pos.Y) ;
192
					declare Real upperLimit = exp_scroll_frame.RelativePosition_V3.Y - exp_scroll_frame.RelativePosition_V3.Y - 5.;
193
					declare Real lowerLimit =  upperLimit - exp_scroll_frame.Controls[3].Size.Y + exp_scroll_frame.Controls[0].Size.Y + 10.;
194
					
195
					if (pos > upperLimit) {
196
						pos = upperLimit;
197
					}
198
															
199
					if (pos < lowerLimit)  {  
200
						pos = lowerLimit;
201
					}
202
					
203
				declare Real start = (upperLimit - pos);
204
				declare Real diff = MathLib::Abs(lowerLimit - upperLimit);
205
								
206
				exp_scroll_frame.Controls[0].RelativePosition_V3.Y = pos; // update scrollbar position												
207
				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
208
		}
209
		
210
		if (exp_scroll_activeX) {		
211
					declare Real pos = ( MouseX - exp_scroll_pos.X);
212
					declare Real leftLimit = 5.;
213
					declare Real rightLimit =  leftLimit + exp_scroll_frame.Controls[3].Size.X - exp_scroll_frame.Controls[0].Size.X -10.;
214
					
215
					if (pos < leftLimit) {
216
						pos = leftLimit;
217
					}
218
															
219
					if (pos > rightLimit)  {  
220
						pos = rightLimit;
221
					}
222
					
223
				declare Real start =  (leftLimit - pos);
224
				declare Real diff = MathLib::Abs(leftLimit + rightLimit);
225
								
226
				exp_scroll_frame.Controls[0].RelativePosition_V3.X = pos; // update scrollbar position												
227
				exp_scroll_content.Controls[0].RelativePosition_V3.X = (start / diff) * (exp_scroll_content_size.X + 10);  //  gets the content frame
228
		}
229
		
230
		
231
		
232
		if (MouseLeftButton == False)  {
233
			exp_scroll_activeX = False;
234
			exp_scroll_activeY = False;
235
		}
236
237
EOL;
238
    }
239
240
}
241