Completed
Push — master ( 761de5...d7bebf )
by Aydin
12s
created

MenuStyle::getTitleSeparator()   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
10
//TODO: B/W fallback
11
12
/**
13
 * @author Michael Woodward <[email protected]>
14
 */
15
class MenuStyle
16
{
17
    /**
18
     * @var Terminal
19
     */
20
    protected $terminal;
21
22
    /**
23
     * @var string
24
     */
25
    protected $fg;
26
27
    /**
28
     * @var string
29
     */
30
    protected $bg;
31
32
    /**
33
     * @var int
34
     */
35
    protected $width;
36
37
    /**
38
     * @var int
39
     */
40
    protected $padding;
41
42
    /**
43
     * @var int
44
     */
45
    protected $margin;
46
47
    /**
48
     * @var int
49
     */
50
    protected $contentWidth;
51
52
    /**
53
     * @var string
54
     */
55
    private $selectedMarker;
56
57
    /**
58
     * @var string
59
     */
60
    private $unselectedMarker;
61
62
    /**
63
     * @var string
64
     */
65
    private $itemExtra;
66
67
    /**
68
     * @var bool
69
     */
70
    private $displaysExtra;
71
72
    /**
73
     * @var string
74
     */
75
    private $titleSeparator;
76
77
    /**
78
     * @var string
79
     */
80
    private $coloursSetCode;
81
82
    /**
83
     * @var string
84
     */
85
    private $invertedColoursSetCode = "\033[7m";
86
87
    /**
88
     * @var string
89
     */
90
    private $invertedColoursUnsetCode = "\033[27m";
91
92
    /**
93
     * @var string
94
     */
95
    private $coloursResetCode = "\033[0m";
96
97
    /**
98
     * @var int
99
     */
100
    private $borderTopWidth;
101
102
    /**
103
     * @var int
104
     */
105
    private $borderRightWidth;
106
107
    /**
108
     * @var int
109
     */
110
    private $borderBottomWidth;
111
112
    /**
113
     * @var int
114
     */
115
    private $borderLeftWidth;
116
117
    /**
118
     * @var string
119
     */
120
    private $borderColour = 'white';
121
122
    /**
123
     * @var array
124
     */
125
    private $borderTopRows = [];
126
127
    /**
128
     * @var array
129
     */
130
    private $borderBottomRows = [];
131
132
    /**
133
     * @var bool
134
     */
135
    private $marginAuto = false;
136
137
    /**
138
     * Default Values
139
     *
140
     * @var array
141
     */
142
    private static $defaultStyleValues = [
143
        'fg' => 'white',
144
        'bg' => 'blue',
145
        'width' => 100,
146
        'padding' => 2,
147
        'margin' => 2,
148
        'selectedMarker' => '●',
149
        'unselectedMarker' => '○',
150
        'itemExtra' => '✔',
151
        'displaysExtra' => false,
152
        'titleSeparator' => '=',
153
        'borderTopWidth' => 0,
154
        'borderRightWidth' => 0,
155
        'borderBottomWidth' => 0,
156
        'borderLeftWidth' => 0,
157
        'borderColour' => 'white',
158
        'marginAuto' => false,
159
    ];
160
161
    public static function getDefaultStyleValues() : array
162
    {
163
        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...
164
    }
165
166
    /**
167
     * @var array
168
     */
169
    private static $availableForegroundColors = array(
170
        'black'   => 30,
171
        'red'     => 31,
172
        'green'   => 32,
173
        'yellow'  => 33,
174
        'blue'    => 34,
175
        'magenta' => 35,
176
        'cyan'    => 36,
177
        'white'   => 37,
178
        'default' => 39,
179
    );
180
181
    /**
182
     * @var array
183
     */
184
    private static $availableBackgroundColors = array(
185
        'black'   => 40,
186
        'red'     => 41,
187
        'green'   => 42,
188
        'yellow'  => 43,
189
        'blue'    => 44,
190
        'magenta' => 45,
191
        'cyan'    => 46,
192
        'white'   => 47,
193
        'default' => 49,
194
    );
195
196
    /**
197
     * @var array
198
     */
199
    private static $availableOptions = array(
200
        'bold'       => array('set' => 1, 'unset' => 22),
201
        'dim'        => array('set' => 2, 'unset' => 22),
202
        'underscore' => array('set' => 4, 'unset' => 24),
203
        'blink'      => array('set' => 5, 'unset' => 25),
204
        'reverse'    => array('set' => 7, 'unset' => 27),
205
        'conceal'    => array('set' => 8, 'unset' => 28)
206
    );
207
208
    /**
209
     * Initialise style
210
     */
211
    public function __construct(Terminal $terminal = null)
212
    {
213
        $this->terminal = $terminal ?: TerminalFactory::fromSystem();
214
215
        $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...
216
        $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...
217
        
218
        $this->generateColoursSetCode();
219
        
220
        $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...
221
        $this->setPadding(static::$defaultStyleValues['padding']);
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...
222
        $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...
223
        $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...
224
        $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...
225
        $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...
226
        $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...
227
        $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...
228
        $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...
229
        $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...
230
        $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...
231
        $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...
232
        $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...
233
    }
234
235
    public function getDisabledItemText(string $text) : string
236
    {
237
        return sprintf(
238
            "\033[%sm%s\033[%sm",
239
            self::$availableOptions['dim']['set'],
240
            $text,
241
            self::$availableOptions['dim']['unset']
242
        );
243
    }
244
245
    /**
246
     * Generates the ansi escape sequence to set the colours
247
     */
248
    private function generateColoursSetCode() : void
249
    {
250
        if (!ctype_digit($this->fg)) {
251
            $fgCode = self::$availableForegroundColors[$this->fg];
252
        } else {
253
            $fgCode = sprintf("38;5;%s", $this->fg);
254
        }
255
256
        if (!ctype_digit($this->bg)) {
257
            $bgCode = self::$availableBackgroundColors[$this->bg];
258
        } else {
259
            $bgCode = sprintf("48;5;%s", $this->bg);
260
        }
261
262
        $this->coloursSetCode = sprintf("\033[%s;%sm", $fgCode, $bgCode);
263
    }
264
265
    /**
266
     * Get the colour code for Bg and Fg
267
     */
268
    public function getColoursSetCode() : string
269
    {
270
        return $this->coloursSetCode;
271
    }
272
273
    /**
274
     * Get the inverted escape sequence (used for selected elements)
275
     */
276
    public function getInvertedColoursSetCode() : string
277
    {
278
        return $this->invertedColoursSetCode;
279
    }
280
281
    /**
282
     * Get the inverted escape sequence (used for selected elements)
283
     */
284
    public function getInvertedColoursUnsetCode() : string
285
    {
286
        return $this->invertedColoursUnsetCode;
287
    }
288
289
    /**
290
     * Get the escape sequence used to reset colours to default
291
     */
292
    public function getColoursResetCode() : string
293
    {
294
        return $this->coloursResetCode;
295
    }
296
297
    /**
298
     * Calculate the contents width
299
     */
300
    protected function calculateContentWidth() : void
301
    {
302
        $this->contentWidth = $this->width
303
            - ($this->padding * 2)
304
            - ($this->borderRightWidth + $this->borderLeftWidth);
305
    }
306
307
    public function getFg()
308
    {
309
        return $this->fg;
310
    }
311
312 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...
313
    {
314
        $this->fg = ColourUtil::validateColour(
315
            $this->terminal,
316
            $fg,
317
            $fallback
318
        );
319
        $this->generateColoursSetCode();
320
321
        return $this;
322
    }
323
324
    public function getBg()
325
    {
326
        return $this->bg;
327
    }
328
329 View Code Duplication
    public function setBg(string $bg, 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->bg = ColourUtil::validateColour(
332
            $this->terminal,
333
            $bg,
334
            $fallback
335
        );
336
        $this->generateColoursSetCode();
337
338
        return $this;
339
    }
340
341
    public function getWidth() : int
342
    {
343
        return $this->width;
344
    }
345
346
    public function setWidth(int $width) : self
347
    {
348
        if ($width >= $this->terminal->getWidth()) {
349
            $width = $this->terminal->getWidth();
350
        }
351
352
        $this->width = $width;
353
        if ($this->marginAuto) {
354
            $this->setMarginAuto();
355
        }
356
357
        $this->calculateContentWidth();
358
        $this->generateBorderRows();
359
360
        return $this;
361
    }
362
363
    public function getPadding() : int
364
    {
365
        return $this->padding;
366
    }
367
368
    public function setPadding(int $padding) : self
369
    {
370
        $this->padding = $padding;
371
372
        $this->calculateContentWidth();
373
374
        return $this;
375
    }
376
377
    public function getMargin() : int
378
    {
379
        return $this->margin;
380
    }
381
382
    public function setMarginAuto() : self
383
    {
384
        $this->marginAuto = true;
385
        $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...
386
387
        $this->generateBorderRows();
388
389
        return $this;
390
    }
391
392
    public function setMargin(int $margin) : self
393
    {
394
        $this->marginAuto = false;
395
        $this->margin = $margin;
396
397
        $this->generateBorderRows();
398
399
        return $this;
400
    }
401
402
    public function getContentWidth() : int
403
    {
404
        return $this->contentWidth;
405
    }
406
407
    /**
408
     * Get padding for right had side of content
409
     */
410
    public function getRightHandPadding(int $contentLength) : int
411
    {
412
        return $this->getContentWidth() - $contentLength + $this->getPadding();
413
    }
414
415
    public function getSelectedMarker() : string
416
    {
417
        return $this->selectedMarker;
418
    }
419
420
    public function setSelectedMarker(string $marker) : self
421
    {
422
        $this->selectedMarker = mb_substr($marker, 0, 1);
423
424
        return $this;
425
    }
426
427
    public function getUnselectedMarker() : string
428
    {
429
        return $this->unselectedMarker;
430
    }
431
432
    public function setUnselectedMarker(string $marker) : self
433
    {
434
        $this->unselectedMarker = mb_substr($marker, 0, 1);
435
436
        return $this;
437
    }
438
439
    /**
440
     * Get the correct marker for the item
441
     */
442
    public function getMarker(bool $selected) : string
443
    {
444
        return $selected ? $this->selectedMarker : $this->unselectedMarker;
445
    }
446
447
    public function setItemExtra(string $itemExtra) : self
448
    {
449
        $this->itemExtra = $itemExtra;
450
451
        return $this;
452
    }
453
454
    public function getItemExtra() : string
455
    {
456
        return $this->itemExtra;
457
    }
458
459
    public function getDisplaysExtra() : bool
460
    {
461
        return $this->displaysExtra;
462
    }
463
464
    public function setDisplaysExtra(bool $displaysExtra) : self
465
    {
466
        $this->displaysExtra = $displaysExtra;
467
468
        return $this;
469
    }
470
471
    public function getTitleSeparator() : string
472
    {
473
        return $this->titleSeparator;
474
    }
475
476
    public function setTitleSeparator(string $actionSeparator) : self
477
    {
478
        $this->titleSeparator = $actionSeparator;
479
480
        return $this;
481
    }
482
483
    private function generateBorderRows() : void
484
    {
485
        $borderRow = sprintf(
486
            "%s%s%s%s%s\n",
487
            str_repeat(' ', $this->margin),
488
            $this->getBorderColourCode(),
489
            str_repeat(' ', $this->width),
490
            $this->coloursResetCode,
491
            str_repeat(' ', $this->margin)
492
        );
493
494
        $this->borderTopRows = array_fill(0, $this->borderTopWidth, $borderRow);
495
        $this->borderBottomRows = array_fill(0, $this->borderBottomWidth, $borderRow);
496
    }
497
498
    public function getBorderTopRows() : array
499
    {
500
        return $this->borderTopRows;
501
    }
502
503
    public function getBorderBottomRows() : array
504
    {
505
        return $this->borderBottomRows;
506
    }
507
508
    /**
509
     * Shorthand function to set all borders values at once
510
     */
511
    public function setBorder(
512
        int $topWidth,
513
        $rightWidth = null,
514
        $bottomWidth = null,
515
        $leftWidth = null,
516
        string $colour = null
517
    ) : self {
518 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...
519
            $colour = $rightWidth;
520
            $rightWidth = $bottomWidth = $leftWidth = $topWidth;
521
        } elseif (!is_int($bottomWidth)) {
522
            $colour = $bottomWidth;
523
            $bottomWidth = $topWidth;
524
            $leftWidth = $rightWidth;
525
        } elseif (!is_int($leftWidth)) {
526
            $colour = $leftWidth;
527
            $leftWidth = $rightWidth;
528
        }
529
530
        $this->borderTopWidth = $topWidth;
531
        $this->borderRightWidth = $rightWidth;
532
        $this->borderBottomWidth = $bottomWidth;
533
        $this->borderLeftWidth = $leftWidth;
534
535
        if (is_string($colour)) {
536
            $this->setBorderColour($colour);
537
        } elseif ($colour !== null) {
538
            throw new \InvalidArgumentException('Invalid colour');
539
        }
540
541
        $this->calculateContentWidth();
542
        $this->generateBorderRows();
543
544
        return $this;
545
    }
546
547
    public function setBorderTopWidth(int $width) : self
548
    {
549
        $this->borderTopWidth = $width;
550
551
        $this->generateBorderRows();
552
553
        return $this;
554
    }
555
556
    public function setBorderRightWidth(int $width) : self
557
    {
558
        $this->borderRightWidth = $width;
559
        $this->calculateContentWidth();
560
561
        return $this;
562
    }
563
564
    public function setBorderBottomWidth(int $width) : self
565
    {
566
        $this->borderBottomWidth = $width;
567
568
        $this->generateBorderRows();
569
570
        return $this;
571
    }
572
573
    public function setBorderLeftWidth(int $width) : self
574
    {
575
        $this->borderLeftWidth = $width;
576
        $this->calculateContentWidth();
577
578
        return $this;
579
    }
580
581
    public function setBorderColour(string $colour, $fallback = null) : self
582
    {
583
        $this->borderColour = ColourUtil::validateColour(
584
            $this->terminal,
585
            $colour,
586
            $fallback
587
        );
588
589
        $this->generateBorderRows();
590
591
        return $this;
592
    }
593
594
    public function getBorderTopWidth() : int
595
    {
596
        return $this->borderTopWidth;
597
    }
598
599
    public function getBorderRightWidth() : int
600
    {
601
        return $this->borderRightWidth;
602
    }
603
604
    public function getBorderBottomWidth() : int
605
    {
606
        return $this->borderBottomWidth;
607
    }
608
609
    public function getBorderLeftWidth() : int
610
    {
611
        return $this->borderLeftWidth;
612
    }
613
614
    public function getBorderColour() : string
615
    {
616
        return $this->borderColour;
617
    }
618
619
    public function getBorderColourCode() : string
620
    {
621
        if (!ctype_digit($this->borderColour)) {
622
            $borderColourCode = self::$availableBackgroundColors[$this->borderColour];
623
        } else {
624
            $borderColourCode = sprintf("48;5;%s", $this->borderColour);
625
        }
626
627
        return sprintf("\033[%sm", $borderColourCode);
628
    }
629
}
630