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

LayoutScrollable::setAxis()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
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
     * @return $this
51
     */
52
    public function setAxis($x, $y)
53
    {
54
        $this->scrollbarH = $x;
55
        $this->scrollbarV = $y;
56
57
        return $this;
58
    }
59
60
    /**
61
     * Forces container size.
62
     * @param $x
63
     * @param $y
64
     */
65
    public function forceContainerSize($x, $y)
66
    {
67
        $this->force = true;
68
        $this->_X = $x;
69
        $this->_Y = $y;
70
    }
71
72
    /**
73
     * Render the XML element
74
     *
75
     * @param \DOMDocument $domDocument DOMDocument for which the XML element should be rendered
76
     * @return \DOMElement
77
     */
78
    public function render(\DOMDocument $domDocument)
79
    {
80
        $container = new Frame();
81
        $container->setPosition($this->frame_posX, $this->frame_posY);
82
83
        $quad = new Quad();
84
        $quad->setStyles('Bgs1', 'BgColorContour')
85
            ->setSize($this->getWidth(), $this->getHeight());
86
87
        $contentFrame = new Frame();
88
        $contentFrame->addChild($this->parentFrame);
89
90
        $container->addChild($quad);
91
        $container->addChild($contentFrame);
92 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...
93
            $contentFrame->setSize($this->width - 5, $this->height);
94
            $this->offset = 5;
95
            $container->addChild(new Scrollbar(
96
                "Y",
97
                $this->getWidth(),
98
                0,
99
                10,
100
                $this->getHeight()
101
            ));
102
        }
103
104 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...
105
            $contentFrame->setSize($this->width - 5, $this->height - 5);
106
            $container->addChild(new Scrollbar(
107
                "X",
108
                0,
109
                -$this->getHeight(),
110
                10,
111
                $this->getWidth() - $this->offset
112
            ));
113
        }
114
115
116
        return $container->render($domDocument);
117
    }
118
119
    /**
120
     * Get the Script Features
121
     *
122
     * @return ScriptFeature[]
123
     */
124
    public function getScriptFeatures()
125
    {
126
        $features = [];
127
        if ($this->parentFrame instanceof ScriptFeatureable) {
128
            $features[] = $this->parentFrame->getScriptFeatures();
129
        }
130
        $features[] = $this;
131
132
        return ScriptFeature::collect($features);
133
    }
134
135
136
    /**
137
     * Prepare the given Script for rendering by adding the needed Labels, etc.
138
     *
139
     * @param Script $script Script to prepare
140
     * @return void
141
     */
142
    public function prepare(Script $script)
143
    {
144
        $script->addCustomScriptLabel(ScriptLabel::MouseClick, $this->getScriptMouseClick());
145
        $script->addCustomScriptLabel(ScriptLabel::OnInit, $this->getScriptInit());
146
        $script->addCustomScriptLabel(ScriptLabel::Loop, $this->getScriptLoop());
147
    }
148
149
    protected function getScriptInit()
150
    {
151
        $offset = number_format($this->offset, 1, ".", "");
152
153
        return /** @lang textmate */
154
            <<<EOL
155
            
156
            declare CMlFrame exp_scroll_frame = Null;
157
            declare CMlFrame exp_scroll_content = Null;
158
            declare Vec2 exp_scroll_content_size = <0.,0.>; 
159
            declare Boolean exp_scroll_activeY = False;
160
            declare Boolean exp_scroll_activeX = False;
161
            declare Vec2 exp_scroll_pos = <0.,0.>;
162
            declare Real exp_scroll_offset = $offset;
163
EOL;
164
    }
165
166
167
    protected function getScriptMouseClick()
168
    {
169
        return /** @lang textmate */
170
            <<<EOL
171
            
172
            if (Event.Control != Null && Event.Control.HasClass("uiScrollbar") )  {
173
                if (Event.Control.DataAttributeGet("axis") == "X") {
174
                    exp_scroll_activeX = True;
175
                    log(Now ^ "X");
176
                } else {
177
                    exp_scroll_activeY = True;																
178
                }
179
                exp_scroll_frame = Event.Control.Parent;
180
                exp_scroll_pos = <MouseX, MouseY> - Event.Control.RelativePosition_V3 ;
181
                exp_scroll_content = (exp_scroll_frame.Parent.Controls[1] as CMlFrame); // gets the bounding frame				
182
                exp_scroll_content_size = exp_scroll_content.Controls[0].Size;
183
                log(exp_scroll_content_size);
184
            }
185
EOL;
186
    }
187
188
189
    protected function getScriptLoop()
190
    {
191
        return /** @lang textmate */
192
            <<<EOL
193
194
        if (exp_scroll_activeY) {		
195
					declare Real pos = (MouseY - exp_scroll_pos.Y) ;
196
					declare Real upperLimit = exp_scroll_frame.RelativePosition_V3.Y - exp_scroll_frame.RelativePosition_V3.Y - 5.;
197
					declare Real lowerLimit =  upperLimit - exp_scroll_frame.Controls[3].Size.Y + exp_scroll_frame.Controls[0].Size.Y + 10.;
198
					
199
					if (pos > upperLimit) {
200
						pos = upperLimit;
201
					}
202
															
203
					if (pos < lowerLimit)  {  
204
						pos = lowerLimit;
205
					}
206
					
207
				declare Real start = (upperLimit - pos);
208
				declare Real diff = MathLib::Abs(lowerLimit - upperLimit);
209
								
210
				exp_scroll_frame.Controls[0].RelativePosition_V3.Y = pos; // update scrollbar position												
211
				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
212
		}
213
		
214
		if (exp_scroll_activeX) {		
215
					declare Real pos = ( MouseX - exp_scroll_pos.X);
216
					declare Real leftLimit = 5.;
217
					declare Real rightLimit =  leftLimit + exp_scroll_frame.Controls[3].Size.X - exp_scroll_frame.Controls[0].Size.X -10.;
218
					
219
					if (pos < leftLimit) {
220
						pos = leftLimit;
221
					}
222
															
223
					if (pos > rightLimit)  {  
224
						pos = rightLimit;
225
					}
226
					
227
				declare Real start =  (leftLimit - pos);
228
				declare Real diff = MathLib::Abs(leftLimit + rightLimit);
229
								
230
				exp_scroll_frame.Controls[0].RelativePosition_V3.X = pos; // update scrollbar position												
231
				exp_scroll_content.Controls[0].RelativePosition_V3.X = (start / diff) * (exp_scroll_content_size.X + 10);  //  gets the content frame
232
		}
233
		
234
		
235
		
236
		if (MouseLeftButton == False)  {
237
			exp_scroll_activeX = False;
238
			exp_scroll_activeY = False;
239
		}
240
241
EOL;
242
    }
243
244
}
245