Completed
Pull Request — master (#121)
by
unknown
02:08
created

MenuStyle::getBorderTopRows()   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
320
    public function getFg()
321
    {
322
        return $this->fg;
323
    }
324
325 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...
326
    {
327
        $this->fg = ColourUtil::validateColour(
328
            $this->terminal,
329
            $fg,
330
            $fallback
331
        );
332
        $this->generateColoursSetCode();
333
334
        return $this;
335
    }
336
337
    public function getBg()
338
    {
339
        return $this->bg;
340
    }
341
342
    public function setBg(string $bg, string $fallback = null) : self
343
    {
344
        $this->bg = ColourUtil::validateColour(
345
            $this->terminal,
346
            $bg,
347
            $fallback
348
        );
349
350
        $this->generateColoursSetCode();
351
        $this->generatePaddingTopBottomRows();
352
353
        return $this;
354
    }
355
356
    public function getWidth() : int
357
    {
358
        return $this->width;
359
    }
360
361
    public function setWidth(int $width) : self
362
    {
363
        Assertion::greaterOrEqualThan($width, 0);
364
365
        if ($width >= $this->terminal->getWidth()) {
366
            $width = $this->terminal->getWidth();
367
        }
368
369
        $this->width = $width;
370
        if ($this->marginAuto) {
371
            $this->setMarginAuto();
372
        }
373
374
        $this->calculateContentWidth();
375
        $this->generateBorderRows();
376
        $this->generatePaddingTopBottomRows();
377
378
        return $this;
379
    }
380
381
    public function getPaddingTopBottom() : int
382
    {
383
        return $this->paddingTopBottom;
384
    }
385
386
    public function getPaddingLeftRight() : int
387
    {
388
        return $this->paddingLeftRight;
389
    }
390
391
    private function generatePaddingTopBottomRows() : void
392
    {
393
        $paddingRow = sprintf(
394
            "%s%s%s%s%s%s%s%s%s%s\n",
395
            str_repeat(' ', $this->margin),
396
            $this->getBorderColourCode(),
397
            str_repeat(' ', $this->borderRightWidth),
398
            $this->getColoursSetCode(),
399
            str_repeat(' ', $this->paddingLeftRight),
400
            str_repeat(' ', $this->contentWidth),
401
            str_repeat(' ', $this->paddingLeftRight),
402
            $this->getBorderColourCode(),
403
            str_repeat(' ', $this->borderRightWidth),
404
            $this->coloursResetCode
405
        );
406
407
        $this->paddingTopBottomRows = array_fill(0, $this->paddingTopBottom, $paddingRow);
408
    }
409
410
    public function getPaddingTopBottomRows() : array
411
    {
412
        return $this->paddingTopBottomRows;
413
    }
414
415 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...
416
    {
417
        if ($leftRight === null) {
418
            $leftRight = $topBottom;
419
        }
420
421
        $this->setPaddingTopBottom($topBottom);
422
        $this->setPaddingLeftRight($leftRight);
423
424
        $this->calculateContentWidth();
425
        $this->generatePaddingTopBottomRows();
426
427
        return $this;
428
    }
429
430
    public function setPaddingTopBottom(int $topBottom) : self
431
    {
432
        Assertion::greaterOrEqualThan($topBottom, 0);
433
        $this->paddingTopBottom = $topBottom;
434
435
        $this->generatePaddingTopBottomRows();
436
437
        return $this;
438
    }
439
440
    public function setPaddingLeftRight(int $leftRight) : self
441
    {
442
        Assertion::greaterOrEqualThan($leftRight, 0);
443
        $this->paddingLeftRight = $leftRight;
444
445
        $this->calculateContentWidth();
446
        $this->generatePaddingTopBottomRows();
447
448
        return $this;
449
    }
450
451
    public function getMargin() : int
452
    {
453
        return $this->margin;
454
    }
455
456
    public function setMarginAuto() : self
457
    {
458
        $this->marginAuto = true;
459
        $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...
460
461
        $this->generateBorderRows();
462
        $this->generatePaddingTopBottomRows();
463
464
        return $this;
465
    }
466
467
    public function setMargin(int $margin) : self
468
    {
469
        Assertion::greaterOrEqualThan($margin, 0);
470
471
        $this->marginAuto = false;
472
        $this->margin = $margin;
473
474
        $this->generateBorderRows();
475
        $this->generatePaddingTopBottomRows();
476
477
        return $this;
478
    }
479
480
    public function getContentWidth() : int
481
    {
482
        return $this->contentWidth;
483
    }
484
485
    /**
486
     * Get padding for right had side of content
487
     */
488
    public function getRightHandPadding(int $contentLength) : int
489
    {
490
        $rightPadding = $this->getContentWidth() - $contentLength + $this->getPaddingLeftRight();
491
492
        if ($rightPadding < 0) {
493
            $rightPadding = 0;
494
        }
495
496
        return $rightPadding;
497
    }
498
499
    public function getSelectedMarker() : string
500
    {
501
        return $this->selectedMarker;
502
    }
503
504
    public function setSelectedMarker(string $marker) : self
505
    {
506
        $this->selectedMarker = mb_substr($marker, 0, 1);
507
508
        return $this;
509
    }
510
511
    public function getUnselectedMarker() : string
512
    {
513
        return $this->unselectedMarker;
514
    }
515
516
    public function setUnselectedMarker(string $marker) : self
517
    {
518
        $this->unselectedMarker = mb_substr($marker, 0, 1);
519
520
        return $this;
521
    }
522
523
    /**
524
     * Get the correct marker for the item
525
     */
526
    public function getMarker(bool $selected) : string
527
    {
528
        return $selected ? $this->selectedMarker : $this->unselectedMarker;
529
    }
530
531
    public function setItemExtra(string $itemExtra) : self
532
    {
533
        $this->itemExtra = $itemExtra;
534
535
        return $this;
536
    }
537
538
    public function getItemExtra() : string
539
    {
540
        return $this->itemExtra;
541
    }
542
543
    public function getDisplaysExtra() : bool
544
    {
545
        return $this->displaysExtra;
546
    }
547
548
    public function setDisplaysExtra(bool $displaysExtra) : self
549
    {
550
        $this->displaysExtra = $displaysExtra;
551
552
        return $this;
553
    }
554
555
    public function getTitleSeparator() : string
556
    {
557
        return $this->titleSeparator;
558
    }
559
560
    public function setTitleSeparator(string $actionSeparator) : self
561
    {
562
        $this->titleSeparator = $actionSeparator;
563
564
        return $this;
565
    }
566
567
    private function generateBorderRows() : void
568
    {
569
        $borderRow = sprintf(
570
            "%s%s%s%s\n",
571
            str_repeat(' ', $this->margin),
572
            $this->getBorderColourCode(),
573
            str_repeat(' ', $this->width),
574
            $this->coloursResetCode
575
        );
576
577
        $this->borderTopRows = array_fill(0, $this->borderTopWidth, $borderRow);
578
        $this->borderBottomRows = array_fill(0, $this->borderBottomWidth, $borderRow);
579
    }
580
581
    public function getBorderTopRows() : array
582
    {
583
        return $this->borderTopRows;
584
    }
585
586
    public function getBorderBottomRows() : array
587
    {
588
        return $this->borderBottomRows;
589
    }
590
591
    /**
592
     * Shorthand function to set all borders values at once
593
     */
594
    public function setBorder(
595
        int $topWidth,
596
        $rightWidth = null,
597
        $bottomWidth = null,
598
        $leftWidth = null,
599
        string $colour = null
600
    ) : self {
601 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...
602
            $colour = $rightWidth;
603
            $rightWidth = $bottomWidth = $leftWidth = $topWidth;
604
        } elseif (!is_int($bottomWidth)) {
605
            $colour = $bottomWidth;
606
            $bottomWidth = $topWidth;
607
            $leftWidth = $rightWidth;
608
        } elseif (!is_int($leftWidth)) {
609
            $colour = $leftWidth;
610
            $leftWidth = $rightWidth;
611
        }
612
613
        $this->borderTopWidth = $topWidth;
614
        $this->borderRightWidth = $rightWidth;
615
        $this->borderBottomWidth = $bottomWidth;
616
        $this->borderLeftWidth = $leftWidth;
617
618
        if (is_string($colour)) {
619
            $this->setBorderColour($colour);
620
        } elseif ($colour !== null) {
621
            throw new \InvalidArgumentException('Invalid colour');
622
        }
623
624
        $this->calculateContentWidth();
625
        $this->generateBorderRows();
626
        $this->generatePaddingTopBottomRows();
627
628
        return $this;
629
    }
630
631
    public function setBorderTopWidth(int $width) : self
632
    {
633
        $this->borderTopWidth = $width;
634
635
        $this->generateBorderRows();
636
637
        return $this;
638
    }
639
640
    public function setBorderRightWidth(int $width) : self
641
    {
642
        $this->borderRightWidth = $width;
643
        $this->calculateContentWidth();
644
645
        $this->generatePaddingTopBottomRows();
646
647
        return $this;
648
    }
649
650
    public function setBorderBottomWidth(int $width) : self
651
    {
652
        $this->borderBottomWidth = $width;
653
654
        $this->generateBorderRows();
655
656
        return $this;
657
    }
658
659
    public function setBorderLeftWidth(int $width) : self
660
    {
661
        $this->borderLeftWidth = $width;
662
        $this->calculateContentWidth();
663
664
        $this->generatePaddingTopBottomRows();
665
666
        return $this;
667
    }
668
669
    public function setBorderColour(string $colour, $fallback = null) : self
670
    {
671
        $this->borderColour = ColourUtil::validateColour(
672
            $this->terminal,
673
            $colour,
674
            $fallback
675
        );
676
677
        $this->generateBorderRows();
678
        $this->generatePaddingTopBottomRows();
679
680
        return $this;
681
    }
682
683
    public function getBorderTopWidth() : int
684
    {
685
        return $this->borderTopWidth;
686
    }
687
688
    public function getBorderRightWidth() : int
689
    {
690
        return $this->borderRightWidth;
691
    }
692
693
    public function getBorderBottomWidth() : int
694
    {
695
        return $this->borderBottomWidth;
696
    }
697
698
    public function getBorderLeftWidth() : int
699
    {
700
        return $this->borderLeftWidth;
701
    }
702
703
    public function getBorderColour() : string
704
    {
705
        return $this->borderColour;
706
    }
707
708
    public function getBorderColourCode() : string
709
    {
710
        if (!ctype_digit($this->borderColour)) {
711
            $borderColourCode = self::$availableBackgroundColors[$this->borderColour];
712
        } else {
713
            $borderColourCode = sprintf("48;5;%s", $this->borderColour);
714
        }
715
716
        return sprintf("\033[%sm", $borderColourCode);
717
    }
718
}
719