Completed
Push — master ( 9ab95e...749b1f )
by De Cramer
03:50
created

Dropdown::render()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 59
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 59
rs 8.9846
c 0
b 0
f 0
cc 4
eloc 46
nc 4
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace eXpansion\Framework\Gui\Components;
4
5
use eXpansion\Framework\Gui\Layouts\LayoutRow;
6
use FML\Controls\Entry;
7
use FML\Controls\Frame;
8
use FML\Controls\Label as FMLLabel;
9
use FML\Script\Features\ScriptFeature;
10
use FML\Script\Script;
11
use FML\Script\ScriptLabel;
12
use FML\Types\ScriptFeatureable;
13
14
class Dropdown extends AbstractUiElement implements ScriptFeatureable
15
{
16
    /** @var int */
17
    protected $selectedIndex;
18
19
    /** @var bool */
20
    protected $isOpened;
21
22
    /** @var string */
23
    protected $name;
24
25
    /** @var string[] */
26
    protected $options;
27
28
    /** @var string */
29
    protected $id = "";
30
31
    /**
32
     * uiDropdown constructor \n
33
     *
34
     * Options ["display name" => "value"], both needs to be string
35
     *
36
     * @param string $name entry name for return value
37
     * @param array  $options Options ["display name" => "value"], both needs to be string
38
     * @param int    $selectedIndex -1 for none
39
     * @param bool   $isOpened is the box opened by default
40
     */
41
    public function __construct($name, $options, $selectedIndex = -1, $isOpened = false)
42
    {
43
        $this->name = $name;
44
        $this->options = $options;
45
        $this->selectedIndex = $selectedIndex;
46
        $this->isOpened = $isOpened;
47
        $this->setSize(30, 4);
48
    }
49
50
    /**
51
     * Prepare the given Script for rendering by adding the needed Labels, etc.
52
     *
53
     * @param Script $script Script to prepare
54
     * @return void
55
     */
56
    public function prepare(Script $script)
57
    {
58
        $script->addScriptFunction("uiDropdownFunctions", $this->getScriptDropdown());
59
        $script->addCustomScriptLabel(ScriptLabel::MouseClick, $this->getScriptMouseClick());
60
        $script->addCustomScriptLabel(ScriptLabel::OnInit, $this->getScriptInit());
61
    }
62
63
    protected function getScriptInit()
64
    {
65
        return /** language=textmate  prefix=#RequireContext\n */
66
            <<<'EOD'
67
            Page.GetClassChildren ("uiContainer", Page.MainFrame, True);
68
            foreach (frame in Page.GetClassChildren_Result) {
69
               if (frame.HasClass("uiDropdown")) {
70
					uiRenderDropdown((frame as CMlFrame));				
71
				}					
72
            }
73
74
EOD;
75
    }
76
77
    /**
78
     * @return string
79
     */
80
    protected function getScriptMouseClick()
81
    {
82
        return /** language=textmate  prefix=#RequireContext\n */
83
            <<<'EOD'
84
            
85
            if (Event.Control.HasClass("uiSelectElement")) {
86
                if (Event.Control.Parent.HasClass("uiDropdown")) {									
87
                    uiToggleDropdown(Event.Control.Parent);	
88
                }		
89
                if (Event.Control.Parent.HasClass("uiDropdownSelect")) {			
90
                    uiSelectDropdown((Event.Control as CMlLabel));	
91
                }
92
		    }	
93
		    																
94
EOD;
95
    }
96
97
98
    /**
99
     * @return string
100
     */
101
    protected function getScriptDropdown()
102
    {
103
        return /** @lang textmate */
104
            <<<'EOD'
105
106
            Void uiRenderDropdown(CMlFrame frame) {
107
                declare selected = TextLib::ToInteger(frame.DataAttributeGet("selected"));
108
                declare index = 0;
109
                
110
                declare options = (frame.Controls[3] as CMlFrame);
111
                
112
                    if (frame.DataAttributeGet("open") == "1") {		   
113
                        frame.Controls[3].Show();
114
                    } else {
115
                         frame.Controls[3].Hide();
116
                    }
117
                
118
                    foreach (option in options.Controls) {
119
                        if (selected == index) {
120
                            (frame.Controls[1] as CMlLabel).Value = (option as CMlLabel).Value;
121
                            (frame.Controls[2] as CMlEntry).Value = option.DataAttributeGet("value");
122
                        }										
123
                    index+= 1;
124
                }
125
            }	
126
            
127
            Void uiToggleDropdown (CMlFrame frame) { 
128
                if (frame.DataAttributeGet("open") == "1") {	
129
                    frame.DataAttributeSet("open","0");
130
                } else {
131
                    frame.DataAttributeSet("open","1");
132
                }
133
                 uiRenderDropdown(frame);
134
            }
135
            
136
            Void uiSelectDropdown (CMlLabel label) {
137
                declare uiDropdown = label.Parent.Parent;
138
                uiDropdown.DataAttributeSet("selected", label.DataAttributeGet("index"));
139
                uiDropdown.DataAttributeSet("value", label.DataAttributeGet("value"));
140
                uiRenderDropdown(uiDropdown);
141
                uiToggleDropdown(uiDropdown);
142
                +++onSelectDropdown+++
143
            }
144
145
EOD;
146
    } // end of getScriptRenderCheckbox
147
148
    /**
149
     * Render the XML element
150
     *
151
     * @param \DOMDocument $domDocument DOMDocument for which the XML element should be rendered
152
     * @return \DOMElement
153
     *
154
     * <frame pos="40 20" class="uiContainer uiDropdown" data-selected="1" data-open="0">
155
     * <label pos="20 0" z-index="0" size="5 5" text="⏷"  focusareacolor1="0000" focusareacolor2="0000"/>
156
     * <label pos="0 0" z-index="0" size="25 5" text="select" focusareacolor1="000" focusareacolor2="111" scriptevents="1" class="uiElement"/>
157
     * <entry pos="45 -3" z-index="0" size="26 6" textemboss="1" text="1" textsize="3" valign="center2" halign="center" textformat="Basic" name="checkbox"  hidden="0"/>
158
     * <frame pos="0 -5" class="uiDropdownSelect" size="40 40">
159
     * <label pos="0 0" z-index="0" size="25 5" text="option 1" data-value="asd" data-index="0" focusareacolor1="000" focusareacolor2="222" scriptevents="1" class="uiElement"/>
160
     * <label pos="0 -5" z-index="0" size="25 5" text="option 2" data-value="das" data-index="1" focusareacolor1="000" focusareacolor2="222" scriptevents="1" class="uiElement"/>
161
     * <label pos="0 -10" z-index="0" size="25 5" text="option 3" data-value="sad" data-index="2" focusareacolor1="000" focusareacolor2="222" scriptevents="1" class="uiElement"/>
162
     * </frame>
163
     * </frame>
164
     * @throws \Exception
165
     */
166
    public function render(\DOMDocument $domDocument)
167
    {
168
        $frame = new Frame();
169
        $frame->addClasses(['uiContainer uiDropdown'])
170
            ->setPosition($this->posX, $this->posY, $this->posZ)
171
            ->addDataAttribute("selected", $this->selectedIndex)
172
            ->addDataAttribute("open", $this->isOpened ? "1" : "0");
173
174
        if ($this->id) {
175
            $frame->setId($this->id);
176
        }
177
178
        $labelMark = new Label("⏷");
179
        $labelMark->setAlign("right", "center");
180
        $labelMark->setPosition($this->width - 0.5, -($this->height / 2));
181
        $labelMark->setTextColor("fff");
182
        $labelMark->setZ(2);
183
        $labelMark->setSize(5, 4);
184
        $labelMark->setScriptEvents(false)->addClass("uiSelectElement");
185
186
        $baseLabel = new FMLLabel();
187
        $baseLabel->setAreaColor("000")->setAreaFocusColor("333")
188
            ->setScriptEvents(true)->addClass("uiSelectElement")
189
            ->setSize($this->width, $this->height)
190
            ->setPosition(0, -($this->height / 2))
191
            ->setTextPrefix(" ")
192
            ->setTextSize(1)
193
            ->setAlign("left", "center")
194
            ->addClasses($this->_classes)
195
            ->setDataAttributes($this->_dataAttributes);
196
197
        $labelTitle = clone $baseLabel;
198
        $labelTitle->setText("Select...")
199
            ->setSize($this->width, $this->height);
200
201
        $entry = new Entry();
202
        $entry->setPosition(900, 900)
203
            ->setName($this->name);
204
205
        $frameOptions = new LayoutRow(0, -$this->height,[],0, $this->height);
206
        $frameOptions->setStartY($this->height * -0.5);
207
        $frameOptions->addClass('uiDropdownSelect');
208
209
        $idx = 0;
210
        foreach ($this->options as $key => $value) {
211
            $option = clone $baseLabel;
212
            $option->setText($key)->addDataAttribute('value', $value)
213
                ->addDataAttribute("index", $idx);
214
            $frameOptions->addChild($option);
215
            $idx += 1;
216
        }
217
218
        $frame->addChild($labelMark);
219
        $frame->addChild($labelTitle);
220
        $frame->addChild($entry);
221
        $frame->addChild($frameOptions);
222
223
        return $frame->render($domDocument);
224
    }
225
226
    /**
227
     * @return mixed
228
     */
229
    public function getIsOpened()
230
    {
231
        return $this->isOpened;
232
    }
233
234
    /**
235
     * @param mixed $isOpened
236
     */
237
    public function setIsOpened($isOpened)
238
    {
239
        $this->isOpened = $isOpened;
240
    }
241
242
    /**
243
     * @return mixed
244
     */
245
    public function getSelectedIndex()
246
    {
247
        return $this->selectedIndex;
248
    }
249
250
    public function getSelectedValue()
251
    {
252
        $x = 0;
253
        foreach ($this->options as $option) {
254
            if ($x == $this->selectedIndex) {
255
                return $option;
256
            }
257
            $x++;
258
        }
259
260
        return "";
261
    }
262
263
    /**
264
     * @param mixed $selectedIndex
265
     */
266
    public function setSelectedIndex($selectedIndex)
267
    {
268
        $this->selectedIndex = $selectedIndex;
269
    }
270
271
272
    /**
273
     * Sets selected index by entry return value
274
     * @param $value
275
     */
276
    public function setSelectedByValue($value)
277
    {
278
        $x = 0;
279
        foreach ($this->options as $idx => $data) {
280
            if ($value == $data) {
281
                $this->setSelectedIndex($x);
282
283
                return;
284
            }
285
            $x++;
286
        }
287
288
        $this->setSelectedIndex(-1);
289
    }
290
291
    /**
292
     * Get the Script Features
293
     *
294
     * @return ScriptFeature[]
295
     */
296
    public function getScriptFeatures()
297
    {
298
        return ScriptFeature::collect($this);
299
    }
300
301
    /**
302
     * @return string
303
     */
304
    public function getId(): string
305
    {
306
        return $this->id;
307
    }
308
309
    /**
310
     * @param string $id
311
     */
312
    public function setId(string $id)
313
    {
314
        $this->id = $id;
315
    }
316
}
317