Adam Pippin
4 years ago
19 changed files with 510 additions and 316 deletions
@ -1,64 +1,119 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace App; |
|||
|
|||
use Symfony\Component\Yaml\Yaml; |
|||
|
|||
/** |
|||
* Represent the configuration containing screens and layouts |
|||
* |
|||
* @author Adam Pippin <hello@adampippin.ca> |
|||
*/ |
|||
class Configuration |
|||
{ |
|||
/** |
|||
* Represents the available screens and their configuration |
|||
* @var array<string, Screen> |
|||
*/ |
|||
protected $_screens; |
|||
|
|||
/** |
|||
* Represents the available layouts |
|||
* @var array<string, Layout> |
|||
*/ |
|||
protected $_layouts; |
|||
|
|||
/** |
|||
* Initialize an empty config |
|||
*/ |
|||
public function __construct() |
|||
{ |
|||
$this->_screens = []; |
|||
$this->_layouts = []; |
|||
} |
|||
|
|||
/** |
|||
* Load a configuration from a YAML file |
|||
* |
|||
* @param string $file |
|||
* @return void |
|||
*/ |
|||
public function load(string $file): void |
|||
{ |
|||
$config = Yaml::parseFile($file); |
|||
|
|||
foreach ($config['screens'] as $screen_name=>$screen) |
|||
foreach ($config['screens'] as $screen_name => $screen) |
|||
{ |
|||
$this->_screens[$screen_name] = app()->make(\App\Screen::class, [ |
|||
'outputs'=>is_array($screen['output']) ? $screen['output'] : [$screen['output']] |
|||
'outputs' => is_array($screen['output']) ? $screen['output'] : [$screen['output']] |
|||
]); |
|||
} |
|||
|
|||
foreach ($config['layouts'] as $layout=>$data) |
|||
foreach ($config['layouts'] as $layout => $data) |
|||
{ |
|||
$this->_layouts[$layout] = app()->make(\App\Layout::class, ['screens'=>$data['screens'], 'links'=>$data['links']]); |
|||
$this->_layouts[$layout] = app()->make(\App\Layout::class, ['screens' => $data['screens'], 'links' => $data['links']]); |
|||
} |
|||
} |
|||
|
|||
public function getScreen(string $screen): Screen |
|||
/** |
|||
* Fetch a specific screen |
|||
* |
|||
* @param string $screen_name |
|||
* @return Screen |
|||
*/ |
|||
public function getScreen(string $screen_name): Screen |
|||
{ |
|||
return $this->_screens[$screen]; |
|||
return $this->_screens[$screen_name]; |
|||
} |
|||
|
|||
/** |
|||
* Fetch the primary screen |
|||
* |
|||
* @return Screen |
|||
*/ |
|||
public function getPrimaryScreen(): Screen |
|||
{ |
|||
return $this->getScreen($this->getPrimaryScreenName()); |
|||
} |
|||
|
|||
/** |
|||
* Fetch the name of the primary screen |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getPrimaryScreenName(): string |
|||
{ |
|||
foreach ($this->_screens as $name=>$screen) |
|||
foreach ($this->_screens as $name => $screen) |
|||
{ |
|||
if ($screen->isPrimary()) |
|||
{ |
|||
return $name; |
|||
} |
|||
} |
|||
|
|||
throw new \Exception("No primary screen found"); |
|||
} |
|||
|
|||
/** |
|||
* Fetch a specific layout |
|||
* |
|||
* @param string $layout |
|||
* @return Layout |
|||
*/ |
|||
public function getLayout(string $layout): Layout |
|||
{ |
|||
return $this->_layouts[$layout]; |
|||
} |
|||
|
|||
/** |
|||
* Fetch all the layouts |
|||
* |
|||
* @return array<string, Layout> |
|||
*/ |
|||
public function getLayouts(): array |
|||
{ |
|||
return $this->_layouts; |
|||
} |
|||
|
|||
} |
|||
|
@ -1,71 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App; |
|||
|
|||
class Display |
|||
{ |
|||
protected $_names; |
|||
protected $_output; |
|||
protected $_width; |
|||
protected $_height; |
|||
protected $_x; |
|||
protected $_y; |
|||
|
|||
public function __construct(array $names) |
|||
{ |
|||
$this->_names = $names; |
|||
} |
|||
|
|||
public function read() |
|||
{ |
|||
foreach ($this->_names as $name) |
|||
{ |
|||
$xrandr = trim(shell_exec('xrandr | grep "^'.$name.'"')); |
|||
if (!empty($xrandr)) |
|||
break; |
|||
} |
|||
|
|||
if (empty($xrandr)) |
|||
throw new \Exception("Cannot load display: ".end($this->_names)); |
|||
|
|||
# DVI-I-2-1 connected 1920x1080+1920+1440 (normal left inverted right x axis y axis) 521mm x 293mm |
|||
if (!preg_match('/^(?<output>[^ ]+) connected (?<screen_w>[0-9]+)x(?<screen_h>[0-9]+)\\+(?<screen_x>[0-9]+)\\+(?<screen_y>[0-9]+) /', $xrandr, $matches)) |
|||
throw new \Exception("Cannot parse xrandr response for: ".$name); |
|||
|
|||
$this->_output = $matches['output']; |
|||
$this->_x = $matches['screen_x']; |
|||
$this->_y = $matches['screen_y']; |
|||
$this->_width = $matches['screen_w']; |
|||
$this->_height = $matches['screen_h']; |
|||
} |
|||
|
|||
public function getX(): int |
|||
{ |
|||
return (int)$this->_x; |
|||
} |
|||
|
|||
public function getY(): int |
|||
{ |
|||
return (int)$this->_y; |
|||
} |
|||
|
|||
public function getWidth(): int |
|||
{ |
|||
return (int)$this->_width; |
|||
} |
|||
|
|||
public function getHeight(): int |
|||
{ |
|||
return (int)$this->_height; |
|||
} |
|||
|
|||
public function setOffset(int $x, int $y): void |
|||
{ |
|||
shell_exec('xrandr --output '.$this->_output.' --pos '.$x.'x'.$y); |
|||
} |
|||
|
|||
public function setDimensions(int $width, int $height): void |
|||
{ |
|||
shell_exec('xrandr --output '.$this->_output.' --mode '.$width.'x'.$height); |
|||
} |
|||
} |
@ -1,14 +1,67 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace App; |
|||
|
|||
/** |
|||
* Provide an interface to manipulating outputs |
|||
* |
|||
* @author Adam Pippin <hello@adampippin.ca> |
|||
*/ |
|||
interface ILayoutDriver |
|||
{ |
|||
|
|||
/** |
|||
* Set the offset of an output |
|||
* |
|||
* @param string $output |
|||
* @param int $x |
|||
* @param int $y |
|||
* @return void |
|||
*/ |
|||
public function setOffset(string $output, int $x, int $y): void; |
|||
|
|||
/** |
|||
* Get the offset of an output |
|||
* |
|||
* @param string $output |
|||
* @return int[] x, y |
|||
*/ |
|||
public function getOffset(string $output): array; |
|||
|
|||
/** |
|||
* Set the dimensions of the output |
|||
* |
|||
* @param string $output |
|||
* @param int $x |
|||
* @param int $y |
|||
* @return void |
|||
*/ |
|||
public function setDimensions(string $output, int $x, int $y): void; |
|||
|
|||
/** |
|||
* Get the dimensions of an output |
|||
* |
|||
* @param string $output |
|||
* @return int[] x, y |
|||
*/ |
|||
public function getDimensions(string $output): array; |
|||
|
|||
/** |
|||
* Check whether an output is connected |
|||
* |
|||
* @param string $output |
|||
* @return bool |
|||
*/ |
|||
public function isConnected(string $output): bool; |
|||
|
|||
/** |
|||
* Check whether the output is considered primary |
|||
* |
|||
* @param string $output |
|||
* @return bool |
|||
*/ |
|||
public function isPrimary(string $output): bool; |
|||
} |
|||
|
|||
} |
|||
|
@ -1,28 +0,0 @@ |
|||
<?php |
|||
|
|||
namespace App\Providers; |
|||
|
|||
use Illuminate\Support\ServiceProvider; |
|||
|
|||
class AppServiceProvider extends ServiceProvider |
|||
{ |
|||
/** |
|||
* Bootstrap any application services. |
|||
* |
|||
* @return void |
|||
*/ |
|||
public function boot() |
|||
{ |
|||
// |
|||
} |
|||
|
|||
/** |
|||
* Register any application services. |
|||
* |
|||
* @return void |
|||
*/ |
|||
public function register() |
|||
{ |
|||
// |
|||
} |
|||
} |
@ -1,61 +1,62 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
return [ |
|||
|
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Application Name |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| This value is the name of your application. This value is used when the |
|||
| framework needs to place the application's name in a notification or |
|||
| any other location as required by the application or its packages. |
|||
| |
|||
*/ |
|||
|
|||
'name' => 'Monitor_layout', |
|||
|
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Application Version |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| This value determines the "version" your application is currently running |
|||
| in. You may want to follow the "Semantic Versioning" - Given a version |
|||
| number MAJOR.MINOR.PATCH when an update happens: https://semver.org. |
|||
| |
|||
*/ |
|||
|
|||
'version' => app('git.version'), |
|||
|
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Application Environment |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| This value determines the "environment" your application is currently |
|||
| running in. This may determine how you prefer to configure various |
|||
| services the application utilizes. This can be overridden using |
|||
| the global command line "--env" option when calling commands. |
|||
| |
|||
*/ |
|||
|
|||
'env' => 'development', |
|||
|
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Autoloaded Service Providers |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| The service providers listed here will be automatically loaded on the |
|||
| request to your application. Feel free to add your own services to |
|||
| this array to grant expanded functionality to your applications. |
|||
| |
|||
*/ |
|||
|
|||
'providers' => [ |
|||
App\Providers\AppServiceProvider::class, |
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Application Name |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| This value is the name of your application. This value is used when the |
|||
| framework needs to place the application's name in a notification or |
|||
| any other location as required by the application or its packages. |
|||
| |
|||
*/ |
|||
|
|||
'name' => 'Monitor_layout', |
|||
|
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Application Version |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| This value determines the "version" your application is currently running |
|||
| in. You may want to follow the "Semantic Versioning" - Given a version |
|||
| number MAJOR.MINOR.PATCH when an update happens: https://semver.org. |
|||
| |
|||
*/ |
|||
|
|||
'version' => app('git.version'), |
|||
|
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Application Environment |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| This value determines the "environment" your application is currently |
|||
| running in. This may determine how you prefer to configure various |
|||
| services the application utilizes. This can be overridden using |
|||
| the global command line "--env" option when calling commands. |
|||
| |
|||
*/ |
|||
|
|||
'env' => 'development', |
|||
|
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Autoloaded Service Providers |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| The service providers listed here will be automatically loaded on the |
|||
| request to your application. Feel free to add your own services to |
|||
| this array to grant expanded functionality to your applications. |
|||
| |
|||
*/ |
|||
|
|||
'providers' => [ |
|||
App\Providers\LayoutServiceProvider::class |
|||
], |
|||
], |
|||
|
|||
]; |
|||
|
@ -1,80 +1,82 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
return [ |
|||
|
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Default Command |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| Laravel Zero will always run the command specified below when no command name is |
|||
| provided. Consider update the default command for single command applications. |
|||
| You cannot pass arguments to the default command because they are ignored. |
|||
| |
|||
*/ |
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Default Command |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| Laravel Zero will always run the command specified below when no command name is |
|||
| provided. Consider update the default command for single command applications. |
|||
| You cannot pass arguments to the default command because they are ignored. |
|||
| |
|||
*/ |
|||
|
|||
'default' => NunoMaduro\LaravelConsoleSummary\SummaryCommand::class, |
|||
'default' => NunoMaduro\LaravelConsoleSummary\SummaryCommand::class, |
|||
|
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Commands Paths |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| This value determines the "paths" that should be loaded by the console's |
|||
| kernel. Foreach "path" present on the array provided below the kernel |
|||
| will extract all "Illuminate\Console\Command" based class commands. |
|||
| |
|||
*/ |
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Commands Paths |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| This value determines the "paths" that should be loaded by the console's |
|||
| kernel. Foreach "path" present on the array provided below the kernel |
|||
| will extract all "Illuminate\Console\Command" based class commands. |
|||
| |
|||
*/ |
|||
|
|||
'paths' => [app_path('Commands')], |
|||
'paths' => [app_path('Commands')], |
|||
|
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Added Commands |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| You may want to include a single command class without having to load an |
|||
| entire folder. Here you can specify which commands should be added to |
|||
| your list of commands. The console's kernel will try to load them. |
|||
| |
|||
*/ |
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Added Commands |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| You may want to include a single command class without having to load an |
|||
| entire folder. Here you can specify which commands should be added to |
|||
| your list of commands. The console's kernel will try to load them. |
|||
| |
|||
*/ |
|||
|
|||
'add' => [ |
|||
// .. |
|||
], |
|||
'add' => [ |
|||
// .. |
|||
], |
|||
|
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Hidden Commands |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| Your application commands will always be visible on the application list |
|||
| of commands. But you can still make them "hidden" specifying an array |
|||
| of commands below. All "hidden" commands can still be run/executed. |
|||
| |
|||
*/ |
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Hidden Commands |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| Your application commands will always be visible on the application list |
|||
| of commands. But you can still make them "hidden" specifying an array |
|||
| of commands below. All "hidden" commands can still be run/executed. |
|||
| |
|||
*/ |
|||
|
|||
'hidden' => [ |
|||
NunoMaduro\LaravelConsoleSummary\SummaryCommand::class, |
|||
Symfony\Component\Console\Command\HelpCommand::class, |
|||
Illuminate\Console\Scheduling\ScheduleRunCommand::class, |
|||
Illuminate\Console\Scheduling\ScheduleFinishCommand::class, |
|||
Illuminate\Foundation\Console\VendorPublishCommand::class, |
|||
], |
|||
'hidden' => [ |
|||
NunoMaduro\LaravelConsoleSummary\SummaryCommand::class, |
|||
Symfony\Component\Console\Command\HelpCommand::class, |
|||
Illuminate\Console\Scheduling\ScheduleRunCommand::class, |
|||
Illuminate\Console\Scheduling\ScheduleFinishCommand::class, |
|||
Illuminate\Foundation\Console\VendorPublishCommand::class, |
|||
], |
|||
|
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Removed Commands |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| Do you have a service provider that loads a list of commands that |
|||
| you don't need? No problem. Laravel Zero allows you to specify |
|||
| below a list of commands that you don't to see in your app. |
|||
| |
|||
*/ |
|||
/* |
|||
|-------------------------------------------------------------------------- |
|||
| Removed Commands |
|||
|-------------------------------------------------------------------------- |
|||
| |
|||
| Do you have a service provider that loads a list of commands that |
|||
| you don't need? No problem. Laravel Zero allows you to specify |
|||
| below a list of commands that you don't to see in your app. |
|||
| |
|||
*/ |
|||
|
|||
'remove' => [ |
|||
// .. |
|||
], |
|||
'remove' => [ |
|||
// .. |
|||
], |
|||
|
|||
]; |
|||
|
@ -1,22 +1,24 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace Tests; |
|||
|
|||
use Illuminate\Contracts\Console\Kernel; |
|||
|
|||
trait CreatesApplication |
|||
{ |
|||
/** |
|||
* Creates the application. |
|||
* |
|||
* @return \Illuminate\Foundation\Application |
|||
*/ |
|||
public function createApplication() |
|||
{ |
|||
$app = require __DIR__.'/../bootstrap/app.php'; |
|||
/** |
|||
* Creates the application. |
|||
* |
|||
* @return \Illuminate\Foundation\Application |
|||
*/ |
|||
public function createApplication() |
|||
{ |
|||
$app = require __DIR__.'/../bootstrap/app.php'; |
|||
|
|||
$app->make(Kernel::class)->bootstrap(); |
|||
$app->make(Kernel::class)->bootstrap(); |
|||
|
|||
return $app; |
|||
} |
|||
return $app; |
|||
} |
|||
} |
|||
|
@ -1,20 +1,27 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace Tests\Feature; |
|||
|
|||
use Tests\TestCase; |
|||
|
|||
/** |
|||
* @internal |
|||
* @coversNothing |
|||
*/ |
|||
class InspiringCommandTest extends TestCase |
|||
{ |
|||
/** |
|||
* A basic test example. |
|||
* |
|||
* @return void |
|||
*/ |
|||
public function testInspiringCommand() |
|||
{ |
|||
$this->artisan('inspiring') |
|||
->expectsOutput('Simplicity is the ultimate sophistication.') |
|||
->assertExitCode(0); |
|||
} |
|||
/** |
|||
* A basic test example. |
|||
* |
|||
* @return void |
|||
*/ |
|||
public function testInspiringCommand() |
|||
{ |
|||
$this->artisan('inspiring') |
|||
->expectsOutput('Simplicity is the ultimate sophistication.') |
|||
->assertExitCode(0) |
|||
; |
|||
} |
|||
} |
|||
|
@ -1,10 +1,12 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace Tests; |
|||
|
|||
use LaravelZero\Framework\Testing\TestCase as BaseTestCase; |
|||
|
|||
abstract class TestCase extends BaseTestCase |
|||
{ |
|||
use CreatesApplication; |
|||
use CreatesApplication; |
|||
} |
|||
|
@ -1,18 +1,24 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace Tests\Unit; |
|||
|
|||
use Tests\TestCase; |
|||
|
|||
/** |
|||
* @internal |
|||
* @coversNothing |
|||
*/ |
|||
class ExampleTest extends TestCase |
|||
{ |
|||
/** |
|||
* A basic test example. |
|||
* |
|||
* @return void |
|||
*/ |
|||
public function testBasicTest() |
|||
{ |
|||
$this->assertTrue(true); |
|||
} |
|||
/** |
|||
* A basic test example. |
|||
* |
|||
* @return void |
|||
*/ |
|||
public function testBasicTest() |
|||
{ |
|||
$this->assertTrue(true); |
|||
} |
|||
} |
|||
|
Loading…
Reference in new issue