Completed
Push — master ( 1a3e42...97058e )
by Aydin
9s
created

MenuStyle::getUnselectedMarker()   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 PhpSchool\CliMenu;
4
5
use PhpSchool\CliMenu\Exception\InvalidInstantiationException;
6
use PhpSchool\CliMenu\Terminal\TerminalFactory;
7
use PhpSchool\CliMenu\Util\ColourUtil;
8
use PhpSchool\Terminal\Terminal;
9
use Assert\Assertion;
10
11
//TODO: B/W fallback
12
13
/**
14
 * @author Michael Woodward <[email protected]>
15
 */
16
class MenuStyle
17
{
18
    /**
19
     * @var Terminal
20
     */
21
    protected $terminal;
22
23
    /**
24
     * @var string
25
     */
26
    protected $fg;
27
28
    /**
29
     * @var string
30
     */
31
    protected $bg;
32
33
    /**
34
     * @var int
35
     */
36
    protected $width;
37
38
    /**
39
     * @var int
40
     */
41
    protected $margin;
42
43
    /**
44
     * @var int
45
     */
46
    protected $paddingTopBottom;
47
48
    /**
49
     * @var int
50
     */
51
    protected $paddingLeftRight;
52
53
    /**
54
     * @var array
55
     */
56
    private $paddingTopBottomRows = [];
57
58
    /**
59
     * @var int
60
     */
61
    protected $contentWidth;
62
63
    /**
64
     * @var string
65
     */
66
    private $selectedMarker;
67
68
    /**
69
     * @var string
70
     */
71
    private $unselectedMarker;
72
73
    /**
74
     * @var string
75
     */
76
    private $itemExtra;
77
78
    /**
79
     * @var bool
80
     */
81
    private $displaysExtra;
82
83
    /**
84
     * @var string
85
     */
86
    private $titleSeparator;
87
88
    /**
89
     * @var string
90
     */
91
    private $coloursSetCode;
92
93
    /**
94
     * @var string
95
     */
96
    private $invertedColoursSetCode = "\033[7m";
97
98
    /**
99
     * @var string
100
     */
101
    private $invertedColoursUnsetCode = "\033[27m";
102
103
    /**
104
     * @var string
105
     */
106
    private $coloursResetCode = "\033[0m";
107
108
    /**
109
     * @var int
110
     */
111
    private $borderTopWidth;
112
113
    /**
114
     * @var int
115
     */
116
    private $borderRightWidth;
117
118
    /**
119
     * @var int
120
     */
121
    private $borderBottomWidth;
122
123
    /**
124
     * @var int
125
     */
126
    private $borderLeftWidth;
127
128
    /**
129
     * @var string
130
     */
131
    private $borderColour = 'white';
132
133
    /**
134
     * @var array
135
     */
136
    private $borderTopRows = [];
137
138
    /**
139
     * @var array
140
     */
141
    private $borderBottomRows = [];
142
143
    /**
144
     * @var bool
145
     */
146
    private $marginAuto = false;
147
148
    /**
149
     * Default Values
150
     *
151
     * @var array
152
     */
153
    private static $defaultStyleValues = [
154
        'fg' => 'white',
155
        'bg' => 'blue',
156
        'width' => 100,
157
        'paddingTopBottom' => 1,
158
        'paddingLeftRight' => 2,
159
        'margin' => 2,
160
        'selectedMarker' => '●',
161
        'unselectedMarker' => '○',
162
        'itemExtra' => '✔',
163
        'displaysExtra' => false,
164
        'titleSeparator' => '=',
165
        'borderTopWidth' => 0,
166
        'borderRightWidth' => 0,
167
        'borderBottomWidth' => 0,
168
        'borderLeftWidth' => 0,
169
        'borderColour' => 'white',
170
        'marginAuto' => false,
171
    ];
172
173
    public static function getDefaultStyleValues() : array
174
    {
175
        return static::$defaultStyleValues;
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
176
    }
177
178
    /**
179
     * @var array
180
     */
181
    private static $availableForegroundColors = array(
182
        'black'   => 30,
183
        'red'     => 31,
184
        'green'   => 32,
185
        'yellow'  => 33,
186
        'blue'    => 34,
187
        'magenta' => 35,
188
        'cyan'    => 36,
189
        'white'   => 37,
190
        'default' => 39,
191
    );
192
193
    /**
194
     * @var array
195
     */
196
    private static $availableBackgroundColors = array(
197
        'black'   => 40,
198
        'red'     => 41,
199
        'green'   => 42,
200
        'yellow'  => 43,
201
        'blue'    => 44,
202
        'magenta' => 45,
203
        'cyan'    => 46,
204
        'white'   => 47,
205
        'default' => 49,
206
    );
207
208
    /**
209
     * @var array
210
     */
211
    private static $availableOptions = array(
212
        'bold'       => array('set' => 1, 'unset' => 22),
213
        'dim'        => array('set' => 2, 'unset' => 22),
214
        'underscore' => array('set' => 4, 'unset' => 24),
215
        'blink'      => array('set' => 5, 'unset' => 25),
216
        'reverse'    => array('set' => 7, 'unset' => 27),
217
        'conceal'    => array('set' => 8, 'unset' => 28)
218
    );
219
220
    /**
221
     * Initialise style
222
     */
223
    public function __construct(Terminal $terminal = null)
224
    {
225
        $this->terminal = $terminal ?: TerminalFactory::fromSystem();
226
227
        $this->fg = static::$defaultStyleValues['fg'];
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
228
        $this->bg = static::$defaultStyleValues['bg'];
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
229
230
        $this->generateColoursSetCode();
231
232
        $this->setWidth(static::$defaultStyleValues['width']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
233
        $this->setPaddingTopBottom(static::$defaultStyleValues['paddingTopBottom']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
234
        $this->setPaddingLeftRight(static::$defaultStyleValues['paddingLeftRight']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
235
        $this->setMargin(static::$defaultStyleValues['margin']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
236
        $this->setSelectedMarker(static::$defaultStyleValues['selectedMarker']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
237
        $this->setUnselectedMarker(static::$defaultStyleValues['unselectedMarker']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
238
        $this->setItemExtra(static::$defaultStyleValues['itemExtra']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
239
        $this->setDisplaysExtra(static::$defaultStyleValues['displaysExtra']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
240
        $this->setTitleSeparator(static::$defaultStyleValues['titleSeparator']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
241
        $this->setBorderTopWidth(static::$defaultStyleValues['borderTopWidth']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
242
        $this->setBorderRightWidth(static::$defaultStyleValues['borderRightWidth']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
243
        $this->setBorderBottomWidth(static::$defaultStyleValues['borderBottomWidth']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
244
        $this->setBorderLeftWidth(static::$defaultStyleValues['borderLeftWidth']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
245
        $this->setBorderColour(static::$defaultStyleValues['borderColour']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
246
    }
247
248
    public function getDisabledItemText(string $text) : string
249
    {
250
        return sprintf(
251
            "\033[%sm%s\033[%sm",
252
            self::$availableOptions['dim']['set'],
253
            $text,
254
            self::$availableOptions['dim']['unset']
255
        );
256
    }
257
258
    /**
259
     * Generates the ansi escape sequence to set the colours
260
     */
261
    private function generateColoursSetCode() : void
262
    {
263
        if (!ctype_digit($this->fg)) {
264
            $fgCode = self::$availableForegroundColors[$this->fg];
265
        } else {
266
            $fgCode = sprintf("38;5;%s", $this->fg);
267
        }
268
269
        if (!ctype_digit($this->bg)) {
270
            $bgCode = self::$availableBackgroundColors[$this->bg];
271
        } else {
272
            $bgCode = sprintf("48;5;%s", $this->bg);
273
        }
274
275
        $this->coloursSetCode = sprintf("\033[%s;%sm", $fgCode, $bgCode);
276
    }
277
278
    /**
279
     * Get the colour code for Bg and Fg
280
     */
281
    public function getColoursSetCode() : string
282
    {
283
        return $this->coloursSetCode;
284
    }
285
286
    /**
287
     * Get the inverted escape sequence (used for selected elements)
288
     */
289
    public function getInvertedColoursSetCode() : string
290
    {
291
        return $this->invertedColoursSetCode;
292
    }
293
294
    /**
295
     * Get the inverted escape sequence (used for selected elements)
296
     */
297
    public function getInvertedColoursUnsetCode() : string
298
    {
299
        return $this->invertedColoursUnsetCode;
300
    }
301
302
    /**
303
     * Get the escape sequence used to reset colours to default
304
     */
305
    public function getColoursResetCode() : string
306
    {
307
        return $this->coloursResetCode;
308
    }
309
310
    /**
311
     * Calculate the contents width
312
     */
313
    protected function calculateContentWidth() : void
314
    {
315
        $this->contentWidth = $this->width
316
            - ($this->paddingLeftRight * 2)
317
            - ($this->borderRightWidth + $this->borderLeftWidth);
318
319
        if ($this->contentWidth < 0) {
320
            $this->contentWidth = 0;
321
        }
322
    }
323
324
    public function getFg()
325
    {
326
        return $this->fg;
327
    }
328
329 View Code Duplication
    public function setFg(string $fg, string $fallback = null) : self
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...
330
    {
331
        $this->fg = ColourUtil::validateColour(
332
            $this->terminal,
333
            $fg,
334
            $fallback
335
        );
336
        $this->generateColoursSetCode();
337
338
        return $this;
339
    }
340
341
    public function getBg()
342
    {
343
        return $this->bg;
344
    }
345
346
    public function setBg(string $bg, string $fallback = null) : self
347
    {
348
        $this->bg = ColourUtil::validateColour(
349
            $this->terminal,
350
            $bg,
351
            $fallback
352
        );
353
354
        $this->generateColoursSetCode();
355
        $this->generatePaddingTopBottomRows();
356
357
        return $this;
358
    }
359
360
    public function getWidth() : int
361
    {
362
        return $this->width;
363
    }
364
365
    public function setWidth(int $width) : self
366
    {
367
        Assertion::greaterOrEqualThan($width, 0);
368
369
        if ($width >= $this->terminal->getWidth()) {
370
            $width = $this->terminal->getWidth();
371
        }
372
373
        $this->width = $width;
374
        if ($this->marginAuto) {
375
            $this->setMarginAuto();
376
        }
377
378
        $this->calculateContentWidth();
379
        $this->generateBorderRows();
380
        $this->generatePaddingTopBottomRows();
381
382
        return $this;
383
    }
384
385
    public function getPaddingTopBottom() : int
386
    {
387
        return $this->paddingTopBottom;
388
    }
389
390
    public function getPaddingLeftRight() : int
391
    {
392
        return $this->paddingLeftRight;
393
    }
394
395
    private function generatePaddingTopBottomRows() : void
396
    {
397
        if ($this->borderLeftWidth || $this->borderRightWidth) {
398
            $borderColour = $this->getBorderColourCode();
399
        } else {
400
            $borderColour = '';
401
        }
402
403
        $paddingRow = sprintf(
404
            "%s%s%s%s%s%s%s%s%s%s\n",
405
            str_repeat(' ', $this->margin),
406
            $borderColour,
407
            str_repeat(' ', $this->borderRightWidth),
408
            $this->getColoursSetCode(),
409
            str_repeat(' ', $this->paddingLeftRight),
410
            str_repeat(' ', $this->contentWidth),
411
            str_repeat(' ', $this->paddingLeftRight),
412
            $borderColour,
413
            str_repeat(' ', $this->borderRightWidth),
414
            $this->coloursResetCode
415
        );
416
417
        $this->paddingTopBottomRows = array_fill(0, $this->paddingTopBottom, $paddingRow);
418
    }
419
420
    public function getPaddingTopBottomRows() : array
421
    {
422
        return $this->paddingTopBottomRows;
423
    }
424
425 View Code Duplication
    public function setPadding(int $topBottom, int $leftRight = null) : self
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...
426
    {
427
        if ($leftRight === null) {
428
            $leftRight = $topBottom;
429
        }
430
431
        $this->setPaddingTopBottom($topBottom);
432
        $this->setPaddingLeftRight($leftRight);
433
434
        $this->calculateContentWidth();
435
        $this->generatePaddingTopBottomRows();
436
437
        return $this;
438
    }
439
440
    public function setPaddingTopBottom(int $topBottom) : self
441
    {
442
        Assertion::greaterOrEqualThan($topBottom, 0);
443
        $this->paddingTopBottom = $topBottom;
444
445
        $this->generatePaddingTopBottomRows();
446
447
        return $this;
448
    }
449
450
    public function setPaddingLeftRight(int $leftRight) : self
451
    {
452
        Assertion::greaterOrEqualThan($leftRight, 0);
453
        $this->paddingLeftRight = $leftRight;
454
455
        $this->calculateContentWidth();
456
        $this->generatePaddingTopBottomRows();
457
458
        return $this;
459
    }
460
461
    public function getMargin() : int
462
    {
463
        return $this->margin;
464
    }
465
466
    public function setMarginAuto() : self
467
    {
468
        $this->marginAuto = true;
469
        $this->margin = floor(($this->terminal->getWidth() - $this->width) / 2);
0 ignored issues
show
Documentation Bug introduced by
The property $margin was declared of type integer, but floor(($this->terminal->...() - $this->width) / 2) 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...
470
471
        $this->generateBorderRows();
472
        $this->generatePaddingTopBottomRows();
473
474
        return $this;
475
    }
476
477
    public function setMargin(int $margin) : self
478
    {
479
        Assertion::greaterOrEqualThan($margin, 0);
480
481
        $this->marginAuto = false;
482
        $this->margin = $margin;
483
484
        $this->generateBorderRows();
485
        $this->generatePaddingTopBottomRows();
486
487
        return $this;
488
    }
489
490
    public function getContentWidth() : int
491
    {
492
        return $this->contentWidth;
493
    }
494
495
    /**
496
     * Get padding for right had side of content
497
     */
498
    public function getRightHandPadding(int $contentLength) : int
499
    {
500
        $rightPadding = $this->getContentWidth() - $contentLength + $this->getPaddingLeftRight();
501
502
        if ($rightPadding < 0) {
503
            $rightPadding = 0;
504
        }
505
506
        return $rightPadding;
507
    }
508
509
    public function getSelectedMarker() : string
510
    {
511
        return $this->selectedMarker;
512
    }
513
514
    public function setSelectedMarker(string $marker) : self
515
    {
516
        $this->selectedMarker = mb_substr($marker, 0, 1);
517
518
        return $this;
519
    }
520
521
    public function getUnselectedMarker() : string
522
    {
523
        return $this->unselectedMarker;
524
    }
525
526
    public function setUnselectedMarker(string $marker) : self
527
    {
528
        $this->unselectedMarker = mb_substr($marker, 0, 1);
529
530
        return $this;
531
    }
532
533
    /**
534
     * Get the correct marker for the item
535
     */
536
    public function getMarker(bool $selected) : string
537
    {
538
        return $selected ? $this->selectedMarker : $this->unselectedMarker;
539
    }
540
541
    public function setItemExtra(string $itemExtra) : self
542
    {
543
        $this->itemExtra = $itemExtra;
544
545
        return $this;
546
    }
547
548
    public function getItemExtra() : string
549
    {
550
        return $this->itemExtra;
551
    }
552
553
    public function getDisplaysExtra() : bool
554
    {
555
        return $this->displaysExtra;
556
    }
557
558
    public function setDisplaysExtra(bool $displaysExtra) : self
559
    {
560
        $this->displaysExtra = $displaysExtra;
561
562
        return $this;
563
    }
564
565
    public function getTitleSeparator() : string
566
    {
567
        return $this->titleSeparator;
568
    }
569
570
    public function setTitleSeparator(string $actionSeparator) : self
571
    {
572
        $this->titleSeparator = $actionSeparator;
573
574
        return $this;
575
    }
576
577
    private function generateBorderRows() : void
578
    {
579
        $borderRow = sprintf(
580
            "%s%s%s%s\n",
581
            str_repeat(' ', $this->margin),
582
            $this->getBorderColourCode(),
583
            str_repeat(' ', $this->width),
584
            $this->coloursResetCode
585
        );
586
587
        $this->borderTopRows = array_fill(0, $this->borderTopWidth, $borderRow);
588
        $this->borderBottomRows = array_fill(0, $this->borderBottomWidth, $borderRow);
589
    }
590
591
    public function getBorderTopRows() : array
592
    {
593
        return $this->borderTopRows;
594
    }
595
596
    public function getBorderBottomRows() : array
597
    {
598
        return $this->borderBottomRows;
599
    }
600
601
    /**
602
     * Shorthand function to set all borders values at once
603
     */
604
    public function setBorder(
605
        int $topWidth,
606
        $rightWidth = null,
607
        $bottomWidth = null,
608
        $leftWidth = null,
609
        string $colour = null
610
    ) : self {
611 View Code Duplication
        if (!is_int($rightWidth)) {
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...
612
            $colour = $rightWidth;
613
            $rightWidth = $bottomWidth = $leftWidth = $topWidth;
614
        } elseif (!is_int($bottomWidth)) {
615
            $colour = $bottomWidth;
616
            $bottomWidth = $topWidth;
617
            $leftWidth = $rightWidth;
618
        } elseif (!is_int($leftWidth)) {
619
            $colour = $leftWidth;
620
            $leftWidth = $rightWidth;
621
        }
622
623
        $this->borderTopWidth = $topWidth;
624
        $this->borderRightWidth = $rightWidth;
625
        $this->borderBottomWidth = $bottomWidth;
626
        $this->borderLeftWidth = $leftWidth;
627
628
        if (is_string($colour)) {
629
            $this->setBorderColour($colour);
630
        } elseif ($colour !== null) {
631
            throw new \InvalidArgumentException('Invalid colour');
632
        }
633
634
        $this->calculateContentWidth();
635
        $this->generateBorderRows();
636
        $this->generatePaddingTopBottomRows();
637
638
        return $this;
639
    }
640
641
    public function setBorderTopWidth(int $width) : self
642
    {
643
        $this->borderTopWidth = $width;
644
645
        $this->generateBorderRows();
646
647
        return $this;
648
    }
649
650
    public function setBorderRightWidth(int $width) : self
651
    {
652
        $this->borderRightWidth = $width;
653
        $this->calculateContentWidth();
654
655
        $this->generatePaddingTopBottomRows();
656
657
        return $this;
658
    }
659
660
    public function setBorderBottomWidth(int $width) : self
661
    {
662
        $this->borderBottomWidth = $width;
663
664
        $this->generateBorderRows();
665
666
        return $this;
667
    }
668
669
    public function setBorderLeftWidth(int $width) : self
670
    {
671
        $this->borderLeftWidth = $width;
672
        $this->calculateContentWidth();
673
674
        $this->generatePaddingTopBottomRows();
675
676
        return $this;
677
    }
678
679
    public function setBorderColour(string $colour, $fallback = null) : self
680
    {
681
        $this->borderColour = ColourUtil::validateColour(
682
            $this->terminal,
683
            $colour,
684
            $fallback
685
        );
686
687
        $this->generateBorderRows();
688
        $this->generatePaddingTopBottomRows();
689
690
        return $this;
691
    }
692
693
    public function getBorderTopWidth() : int
694
    {
695
        return $this->borderTopWidth;
696
    }
697
698
    public function getBorderRightWidth() : int
699
    {
700
        return $this->borderRightWidth;
701
    }
702
703
    public function getBorderBottomWidth() : int
704
    {
705
        return $this->borderBottomWidth;
706
    }
707
708
    public function getBorderLeftWidth() : int
709
    {
710
        return $this->borderLeftWidth;
711
    }
712
713
    public function getBorderColour() : string
714
    {
715
        return $this->borderColour;
716
    }
717
718
    public function getBorderColourCode() : string
719
    {
720
        if (!ctype_digit($this->borderColour)) {
721
            $borderColourCode = self::$availableBackgroundColors[$this->borderColour];
722
        } else {
723
            $borderColourCode = sprintf("48;5;%s", $this->borderColour);
724
        }
725
726
        return sprintf("\033[%sm", $borderColourCode);
727
    }
728
}
729