Completed
Pull Request — master (#254)
by
unknown
03:30
created

uiTooltip::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

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