Completed
Push — master ( 1c1eb2...054cc9 )
by
unknown
9s
created

layoutLine::getId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace eXpansion\Framework\Gui\Layouts;
4
5
use FML\Controls\Control;
6
use FML\Controls\Frame;
7
use FML\Elements\Format;
8
use FML\Script\Features\ScriptFeature;
9
use FML\Types\Container;
10
use FML\Types\Renderable;
11
use FML\Types\ScriptFeatureable;
12
13
class layoutLine implements Renderable, ScriptFeatureable, Container
14
{
15
    protected $frameClasses = [];
16
17
    protected $frameId = null;
18
19
    /** @var float */
20
    protected $width = 0.;
21
22
    /** @var float */
23
    protected $height = 0.;
24
25
    /** @var Control[] */
26
    protected $elements = [];
27
28
    /** @var float */
29
    private $margin = 2.;
30
    /**
31
     * @var float
32
     */
33
    protected $startX = 0.;
34
    /**
35
     * @var float
36
     */
37
    protected $startY = 0.;
38
39
    /** @var string */
40
    protected $hAlign = "left";
41
42
    /** @var string */
43
    protected $vAlign = "top";
44
45
    /**
46
     * layoutLine constructor.
47
     * @param float    $startX
48
     * @param float    $startY
49
     * @param object[] $elements
50
     * @param float    $margin
51
     * @throws \Exception
52
     */
53
    public function __construct($startX, $startY, $elements = [], $margin = 0.)
54
    {
55
        if (!is_array($elements)) {
56
            throw new \Exception('not an array');
57
        }
58
        $this->margin = $margin;
59
        $this->elements = $elements;
60
        $this->startX = $startX;
61
        $this->startY = $startY;
62
        $sizeY = 0;
63
        foreach ($this->elements as $idx => $element) {
64
            $this->width += $element->getWidth() + $this->margin;
65
            if ($element->getY() + $element->getHeight() > $sizeY) {
66
                $this->setHeight($element->getHeight());
67
            }
68
        }
69
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
        $frame = new Frame();
81
        $frame->setId($this->frameId);
82
        $frame->setAlign($this->hAlign, $this->vAlign);
83
        $frame->setPosition($this->startX, $this->startY);
84
        $frame->addClasses($this->frameClasses);
85
86
87
        $sizeY = 0;
88
        /** @var Control $oldElement */
89
        $oldElement = null;
90
        foreach ($this->elements as $idx => $element) {
91
            if ($idx === 0) {
92
                $start = $this->getRelativeStartPosition($element);
93
            } else {
94
                $start = $this->getStartPosition($oldElement) + $this->getRelativeWidth($oldElement) + $this->margin;
95
            }
96
97
            if ($oldElement && $element->getHorizontalAlign() == "left" && $oldElement->getHorizontalAlign() == "center") {
98
                $element->setX($start - ($oldElement->getWidth() / 2) + ($element->getWidth() / 2));
99
            } elseif ($oldElement && $element->getHorizontalAlign() == "center" && $oldElement->getHorizontalAlign() == "left") {
100
                $element->setX($start - ($oldElement->getWidth() / 2) + ($element->getWidth() / 2));
101
            } else {
102
                $element->setX($start);
103
            }
104
105
            if ($element->getY() + $element->getHeight() > $sizeY) {
106
                $this->setHeight($element->getHeight());
107
            }
108
            $frame->addChild($element);
109
            $oldElement = $element;
110
        }
111
112
        return $frame->render($domDocument);
113
    }
114
115
    /**
116
     * @param Control $element
117
     * @return float|int
118
     */
119
    private function getRelativeStartPosition($element)
120
    {
121
        if (is_null($element)) {
122
            return 0;
123
        }
124
        switch ($element->getHorizontalAlign()) {
125
            case "left":
126
                return 0;
127
128
            case "center":
129
                return 0.5 * $element->getWidth();
130
131
            case "right":
132
                return -($element->getWidth() * 2);
133
134
            default:
135
                return 0;
136
137
        }
138
    }
139
140
    /**
141
     * @param Control $element
142
     * @return float|int
143
     */
144
    private function getRelativeWidth($element)
145
    {
146
        if (is_null($element)) {
147
            return 0;
148
        }
149
        switch ($element->getHorizontalAlign()) {
150
            case "right":
151
                return -$element->getWidth();
152
            case "center":
153
                return $element->getWidth();
154
            case "left":
155
                return $element->getWidth();
156
            default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
157
                return $element->getWidth();
158
        }
159
    }
160
161
    /**
162
     * @param Control $element
163
     * @return float|int
164
     */
165
    private function getStartPosition($element)
166
    {
167
        if (is_null($element)) {
168
            return 0;
169
        }
170
171
        return $element->getX();
172
    }
173
174
    /**
175
     * Get the Script Features
176
     *
177
     * @return ScriptFeature[]
178
     */
179 View Code Duplication
    public function getScriptFeatures()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
180
    {
181
        $features = [];
182
        foreach ($this->elements as $element) {
183
            if ($element instanceof ScriptFeatureable) {
184
                $features[] = $element->getScriptFeatures();
185
            }
186
        }
187
188
        return ScriptFeature::collect($features);
189
    }
190
191
    /**
192
     * @param mixed $startX
193
     * @return layoutLine
194
     */
195
    public function setX($startX)
196
    {
197
        $this->startX = $startX;
198
199
        return $this;
200
    }
201
202
    /**
203
     * @param mixed $startY
204
     * @return layoutLine
205
     */
206
    public function setY($startY)
207
    {
208
        $this->startY = $startY;
209
210
        return $this;
211
    }
212
213
    /**
214
     * @return float
215
     */
216
    public function getX()
217
    {
218
        return $this->startX;
219
    }
220
221
    /**
222
     * @return mixed
223
     */
224
    public function getY()
225
    {
226
        return $this->startY;
227
    }
228
229
    /**
230
     * @return float
231
     */
232
    public function getWidth()
233
    {
234
        return $this->width;
235
    }
236
237
    /**
238
     * @param float $width
239
     */
240
    public function setWidth($width)
241
    {
242
        $this->width = $width;
243
    }
244
245
    /**
246
     * @return float
247
     */
248
    public function getHeight()
249
    {
250
        return $this->height;
251
    }
252
253
    /**
254
     * @param float $height
255
     */
256
    public function setHeight($height)
257
    {
258
        $this->height = $height;
259
    }
260
261
    /**
262
     * @param Renderable $element
263
     */
264
    public function addChild(Renderable $element)
265
    {
266
        $this->elements[] = $element;
267
        $this->width += $element->getWidth() + $this->margin;
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface FML\Types\Renderable as the method getWidth() does only exist in the following implementations of said interface: ControlStub, FML\Controls\Audio, FML\Controls\Control, FML\Controls\Entry, FML\Controls\FileEntry, FML\Controls\Frame, FML\Controls\Frame3d, FML\Controls\FrameInstance, FML\Controls\Gauge, FML\Controls\Graph, FML\Controls\Label, FML\Controls\Labels\Label_Button, FML\Controls\Labels\Label_Text, FML\Controls\Quad, FML\Controls\Quads\Quad_321Go, FML\Controls\Quads\Quad_BgRaceScore2, FML\Controls\Quads\Quad_Bgs1, FML\Controls\Quads\Quad_Bgs1InRace, FML\Controls\Quads\Quad_BgsButtons, FML\Controls\Quads\Quad_BgsChallengeMedals, FML\Controls\Quads\Quad_BgsPlayerCard, FML\Controls\Quads\Quad_Copilot, FML\Controls\Quads\Quad_Emblems, FML\Controls\Quads\Quad_EnergyBar, FML\Controls\Quads\Quad_Hud3dEchelons, FML\Controls\Quads\Quad_Hud3dIcons, FML\Controls\Quads\Quad_Icons128x128_1, FML\Controls\Quads\Quad_Icons128x128_Blink, FML\Controls\Quads\Quad_Icons128x32_1, FML\Controls\Quads\Quad_Icons64x64_1, FML\Controls\Quads\Quad_Icons64x64_2, FML\Controls\Quads\Quad_ManiaPlanetLogos, FML\Controls\Quads\Quad_ManiaPlanetMainMenu, FML\Controls\Quads\Quad_ManiaplanetSystem, FML\Controls\Quads\Quad_MedalsBig, FML\Controls\Quads\Quad_TitleLogos, FML\Controls\Quads\Quad_...structionBullet_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons2, FML\Controls\Quads\Quad_UiSMSpectatorScoreBig, FML\Controls\TextEdit, FML\Controls\Video, eXpansion\Framework\Gui\Builders\WidgetBackground, eXpansion\Framework\Gui\...nents\abstractUiElement, eXpansion\Framework\Gui\Components\uiAnimation, eXpansion\Framework\Gui\Components\uiButton, eXpansion\Framework\Gui\Components\uiCheckbox, eXpansion\Framework\Gui\Components\uiConfirmButton, eXpansion\Framework\Gui\Components\uiDropdown, eXpansion\Framework\Gui\Components\uiInput, eXpansion\Framework\Gui\Components\uiInputMasked, eXpansion\Framework\Gui\Components\uiLabel, eXpansion\Framework\Gui\Components\uiLine, eXpansion\Framework\Gui\Components\uiScrollbar, eXpansion\Framework\Gui\Components\uiTextbox, eXpansion\Framework\Gui\Components\uiTooltip, eXpansion\Framework\Gui\Layouts\layoutLine, eXpansion\Framework\Gui\Layouts\layoutRow, eXpansion\Framework\Gui\Layouts\layoutScrollable.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
268
        $this->height += $element->getHeight();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface FML\Types\Renderable as the method getHeight() does only exist in the following implementations of said interface: ControlStub, FML\Controls\Audio, FML\Controls\Control, FML\Controls\Entry, FML\Controls\FileEntry, FML\Controls\Frame, FML\Controls\Frame3d, FML\Controls\FrameInstance, FML\Controls\Gauge, FML\Controls\Graph, FML\Controls\Label, FML\Controls\Labels\Label_Button, FML\Controls\Labels\Label_Text, FML\Controls\Quad, FML\Controls\Quads\Quad_321Go, FML\Controls\Quads\Quad_BgRaceScore2, FML\Controls\Quads\Quad_Bgs1, FML\Controls\Quads\Quad_Bgs1InRace, FML\Controls\Quads\Quad_BgsButtons, FML\Controls\Quads\Quad_BgsChallengeMedals, FML\Controls\Quads\Quad_BgsPlayerCard, FML\Controls\Quads\Quad_Copilot, FML\Controls\Quads\Quad_Emblems, FML\Controls\Quads\Quad_EnergyBar, FML\Controls\Quads\Quad_Hud3dEchelons, FML\Controls\Quads\Quad_Hud3dIcons, FML\Controls\Quads\Quad_Icons128x128_1, FML\Controls\Quads\Quad_Icons128x128_Blink, FML\Controls\Quads\Quad_Icons128x32_1, FML\Controls\Quads\Quad_Icons64x64_1, FML\Controls\Quads\Quad_Icons64x64_2, FML\Controls\Quads\Quad_ManiaPlanetLogos, FML\Controls\Quads\Quad_ManiaPlanetMainMenu, FML\Controls\Quads\Quad_ManiaplanetSystem, FML\Controls\Quads\Quad_MedalsBig, FML\Controls\Quads\Quad_TitleLogos, FML\Controls\Quads\Quad_...structionBullet_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons, FML\Controls\Quads\Quad_UIConstruction_Buttons2, FML\Controls\Quads\Quad_UiSMSpectatorScoreBig, FML\Controls\TextEdit, FML\Controls\Video, eXpansion\Framework\Gui\Builders\WidgetBackground, eXpansion\Framework\Gui\...nents\abstractUiElement, eXpansion\Framework\Gui\Components\uiAnimation, eXpansion\Framework\Gui\Components\uiButton, eXpansion\Framework\Gui\Components\uiCheckbox, eXpansion\Framework\Gui\Components\uiConfirmButton, eXpansion\Framework\Gui\Components\uiDropdown, eXpansion\Framework\Gui\Components\uiInput, eXpansion\Framework\Gui\Components\uiInputMasked, eXpansion\Framework\Gui\Components\uiLabel, eXpansion\Framework\Gui\Components\uiLine, eXpansion\Framework\Gui\Components\uiScrollbar, eXpansion\Framework\Gui\Components\uiTextbox, eXpansion\Framework\Gui\Components\uiTooltip, eXpansion\Framework\Gui\Layouts\layoutLine, eXpansion\Framework\Gui\Layouts\layoutRow, eXpansion\Framework\Gui\Layouts\layoutScrollable.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
269
    }
270
271
    public function getChildren()
272
    {
273
        return $this->elements;
274
    }
275
276
277
    public function addClass($class)
278
    {
279
        $this->frameClasses [] = $class;
280
    }
281
282
    /**
283
     * Add a new child
284
     *
285
     * @api
286
     * @param Renderable $child Child Control to add
287
     * @return void
288
     * @deprecated Use addChild()
289
     * @see        Container::addChild()
290
     */
291
    public function add(Renderable $child)
292
    {
293
        // do nothing
294
    }
295
296
    /**
297
     * Add new children
298
     *
299
     * @api
300
     * @param Renderable[] $children Child Controls to add
301
     * @return void
302
     */
303
    public function addChildren(array $children)
304
    {
305
        foreach ($children as $child) {
306
            $this->addChild($child);
307
        }
308
    }
309
310
    /**
311
     * Remove all children
312
     *
313
     * @api
314
     * @return static
315
     */
316
    public function removeAllChildren()
317
    {
318
        $this->width = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $width was declared of type double, but 0 is of type integer. 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...
319
        $this->height = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $height was declared of type double, but 0 is of type integer. 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...
320
        $this->elements = [];
321
322
        return $this;
323
    }
324
325
    /**
326
     * Remove all children
327
     *
328
     * @api
329
     * @return void
330
     * @deprecated Use removeAllChildren()
331
     * @see        Container::removeAllChildren()
332
     */
333
    public function removeChildren()
334
    {
335
        // do nothing
336
    }
337
338
    /**
339
     * Get the Format
340
     *
341
     * @api
342
     * @param bool $createIfEmpty If the format should be created if it doesn't exist yet
343
     * @return void
344
     * @deprecated Use Style
345
     * @see        Style
346
     */
347
    public function getFormat($createIfEmpty = true)
348
    {
349
350
    }
351
352
    /**
353
     * Set the Format
354
     *
355
     * @api
356
     * @param Format $format New Format
357
     * @return void
358
     * @deprecated Use Style
359
     * @see        Style
360
     */
361
    public function setFormat(Format $format = null)
362
    {
363
364
    }
365
366
    public function setAlign($hAling = "left", $vAlign = "top")
367
    {
368
        $this->hAlign = $hAling;
369
        $this->vAlign = $vAlign;
370
371
        return $this;
372
    }
373
374
375
    public function setPosition($x, $y)
376
    {
377
        $this->setX($x);
378
        $this->setY($y);
379
380
        return $this;
381
    }
382
383
    /**
384
     * @return null|string
385
     */
386
    public function getId()
387
    {
388
        return $this->frameId;
389
    }
390
391
    /**
392
     * @param null|string $frameId
393
     * @return layoutLine
394
     */
395
    public function setId($frameId)
396
    {
397
        $this->frameId = $frameId;
398
399
        return $this;
400
    }
401
402
    /**
403
     * @return string
404
     */
405
    public function getHorizontalAlign(): string
406
    {
407
        return $this->hAlign;
408
    }
409
410
    /**
411
     * @param string $hAlign
412
     * @return layoutLine
413
     */
414
    public function setHorizontalAlign(string $hAlign)
415
    {
416
        $this->hAlign = $hAlign;
417
418
        return $this;
419
    }
420
421
}
422