Completed
Pull Request — master (#95)
by
unknown
03:41
created

uiTooltip::getScriptFeatures()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
ccs 0
cts 4
cp 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
namespace eXpansion\Framework\Gui\Components;
4
5
use FML\Controls\Control;
6
use FML\Controls\Frame;
7
use FML\Controls\Label;
8
use FML\Controls\Quad;
9
use FML\Script\Features\ScriptFeature;
10
use FML\Script\Script;
11
use FML\Types\Container;
12
use FML\Types\ScriptFeatureable;
13
14
class uiTooltip extends abstractUiElement implements ScriptFeatureable
15
{
16
17
    protected $element;
18
19
    public function __construct()
20
    {
21
22
    }
23
24
    /**
25
     * @param $control
26
     * @param $text
27
     */
28
    public function addTooltip($control, $text)
29
    {
30
        if ($control instanceof Control) {
31
            $control->addDataAttribute("tooltip", $text);
32
            $control->addClass("tooltip");
33
            $control->setScriptEvents(true);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class FML\Controls\Control as the method setScriptEvents() does only exist in the following sub-classes of FML\Controls\Control: FML\Controls\Audio, FML\Controls\Entry, FML\Controls\FileEntry, FML\Controls\Frame3d, 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\Components\uiLabel. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
34
35
            return;
36
        }
37
38
        if ($control instanceof abstractUiElement) {
39
            $control->addDataAttribute("tooltip", $text);
40
            $control->addClass("tooltip");
41
42
            return;
43
        }
44
45
    }
46
47
    /**
48
     * Prepare the given Script for rendering by adding the needed Labels, etc.
49
     *
50
     * @param Script $script Script to prepare
51
     * @return static
52
     */
53
    public function prepare(Script $script)
54
    {
55
        $script->addScriptFunction("exp_tooltipFunctions", $this->getFunctions());
56
    }
57
58
59
    public function getFunctions()
60
    {
61
62
        return /** @lang textmate */
63
            <<<EOL
64
            
65
       ***FML_OnInit***
66
       ***
67
       declare CMlFrame exp_tooltip = (Page.GetFirstChild("exp_tooltip") as CMlFrame);	
68
	   declare Boolean exp_tooltip_move = False;
69
	   declare Boolean exp_tooltip_toggle = True;
70
	   declare Integer exp_tooltip_delay = 0;
71
	   declare Vec2 exp_tooltip_rel = <0., 0.>;     
72
       ***
73
                    
74
       ***FML_Loop***
75
       ***
76
       if (exp_tooltip_move) {         
77
            // exp_tooltip.RelativePosition_V3 =  <MouseX, MouseY> - exp_tooltip_rel + <0., 10.>;				
78
               exp_tooltip.RelativePosition_V3 = exp_tooltip_rel + <4., 10.>;
79
            if (exp_tooltip_delay + 1000 < Now) {
80
                if (exp_tooltip_toggle) {
81
                    AnimMgr.Add(exp_tooltip.Controls[0], "<elem scale=\"1\" />",  250, CAnimManager::EAnimManagerEasing::BackOut);
82
                    AnimMgr.Add(exp_tooltip.Controls[1], "<elem scale=\"1\" />",  250, CAnimManager::EAnimManagerEasing::BackOut);
83
                    exp_tooltip_toggle = False;
84
                }          	    					
85
            }								
86
	   }
87
       ***
88
       
89
       ***FML_MouseOver***      
90
       ***
91
       if (Event.Control != Null) {
92
			if (Event.Control.HasClass("tooltip") )  {
93
			declare tooltipLabel = (exp_tooltip.Controls[0] as CMlLabel);
94
			declare text = Event.Control.DataAttributeGet("tooltip");
95
			declare sizeX = tooltipLabel.ComputeWidth(text);			 			    						       
96
            tooltipLabel.Value = text;
97
            tooltipLabel.Size.X = sizeX;    
98
            (exp_tooltip.Controls[1] as CMlQuad).Size.X = sizeX;                            
99
            exp_tooltip_move = True;
100
            exp_tooltip_delay = Now;
101
            // exp_tooltip_toggle = True;	                    		            
102
            // exp_tooltip_rel = Event.Control.RelativePosition_V3 + Exp_Window.RelativePosition_V3;
103
            exp_tooltip_rel = Event.Control.AbsolutePosition_V3 - Exp_Window.RelativePosition_V3;                                                  
104
            }
105
        }
106
       ***
107
       
108
       ***FML_MouseOut***      
109
       ***
110
       if (Event.Control != Null) {
111
			if (Event.Control.HasClass("tooltip") )  {
112
                exp_tooltip_move = False;
113
                exp_tooltip_delay = 0;  
114
                exp_tooltip_toggle = True;                         
115
                //AnimMgr.Add(exp_tooltip.Controls[0], "<elem scale=\"0\" />",  30, CAnimManager::EAnimManagerEasing::Linear);
116
            	//AnimMgr.Add(exp_tooltip.Controls[1], "<elem scale=\"0\" />",  30, CAnimManager::EAnimManagerEasing::Linear);
117
            	 (exp_tooltip.Controls[0] as CMlLabel).Scale = 0.;
118
            	 (exp_tooltip.Controls[1] as CMlQuad).Scale = 0.;          	                                	
119
            }    
120
       }
121
       ***
122
                      
123
EOL;
124
125
    }
126
127
128
    /**
129
     * Get the Script Features
130
     *
131
     * @return ScriptFeature[]
132
     */
133
    public function getScriptFeatures()
134
    {
135
        return ScriptFeature::collect($this);
136
    }
137
138
    /**
139
     * Render the XML element
140
     *
141
     * @param \DOMDocument $domDocument DOMDocument for which the XML element should be rendered
142
     * @return \DOMElement
143
     */
144
    public function render(\DOMDocument $domDocument)
145
    {
146
        $frame = new Frame("exp_tooltip");
147
        $frame->setZ(100)->setAlign("left", "center");
148
149
        $label = new Label();
150
        $label->setSize(36, 5)
151
            ->setAlign("left", "center2")
152
            ->setTextFont('file://Media/Font/BiryaniDemiBold.Font.gbx')
153
            ->setTextSize(2)
154
            ->setTextColor("eee")
155
            ->setOpacity(1)
156
            ->setAreaFocusColor("0000")
157
            ->setAreaColor("0000")
158
            ->setScriptEvents(true)
159
            ->setScale(0);
160
161
        $quad = new Quad();
162
        $quad->setAlign("left", "center2")->setScale(0);
163
        $quad->setSize(36, 5)->setBackgroundColor('000')->setOpacity(1)->setScriptEvents(true);
164
165
166
        $frame->addChild($label);
167
        $frame->addChild($quad);
168
169
        return $frame->render($domDocument);
170
    }
171
}
172