99 lines
3.1 KiB
PHP
99 lines
3.1 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace PhpQml\Bridge\Maker;
|
||
|
|
|
||
|
|
use Symfony\Bundle\MakerBundle\ConsoleStyle;
|
||
|
|
use Symfony\Bundle\MakerBundle\DependencyBuilder;
|
||
|
|
use Symfony\Bundle\MakerBundle\Generator;
|
||
|
|
use Symfony\Bundle\MakerBundle\InputConfiguration;
|
||
|
|
use Symfony\Bundle\MakerBundle\Maker\AbstractMaker;
|
||
|
|
use Symfony\Bundle\MakerBundle\Str;
|
||
|
|
use Symfony\Component\Console\Command\Command;
|
||
|
|
use Symfony\Component\Console\Input\InputArgument;
|
||
|
|
use Symfony\Component\Console\Input\InputInterface;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* `make:bridge:window <Name>` — emits a top-level QML Window that
|
||
|
|
* wraps `AppShell` and a content slot. Application code opens it via
|
||
|
|
* `Qt.createComponent("<Name>Window.qml")` (or by importing it) for
|
||
|
|
* the first window and as many extra instances as it wants for the
|
||
|
|
* multi-window test from PLAN.md §9 / §13 Phase 3.
|
||
|
|
*
|
||
|
|
* Generated file goes to `qml_path` (default: `../qml/`).
|
||
|
|
*/
|
||
|
|
final class BridgeWindowMaker extends AbstractMaker
|
||
|
|
{
|
||
|
|
public function __construct(
|
||
|
|
private readonly string $qmlPath = '../qml/',
|
||
|
|
) {
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function getCommandName(): string
|
||
|
|
{
|
||
|
|
return 'make:bridge:window';
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function getCommandDescription(): string
|
||
|
|
{
|
||
|
|
return 'Generate a top-level QML Window scaffold (AppShell + content slot).';
|
||
|
|
}
|
||
|
|
|
||
|
|
public function configureCommand(Command $command, InputConfiguration $inputConfig): void
|
||
|
|
{
|
||
|
|
$command
|
||
|
|
->addArgument(
|
||
|
|
'name',
|
||
|
|
InputArgument::OPTIONAL,
|
||
|
|
'Singular name of the window (e.g. Todo, Settings).',
|
||
|
|
)
|
||
|
|
->setHelp(
|
||
|
|
"Creates one file:\n\n"
|
||
|
|
." • <info>{qml_path}/<Name>Window.qml</info> — Window subclass with AppShell\n"
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function interact(InputInterface $input, ConsoleStyle $io, Command $command): void
|
||
|
|
{
|
||
|
|
if (null === $input->getArgument('name')) {
|
||
|
|
$name = $io->ask('Window name?', null, static function (?string $v): string {
|
||
|
|
if (null === $v || '' === trim($v)) {
|
||
|
|
throw new \RuntimeException('Window name cannot be empty.');
|
||
|
|
}
|
||
|
|
|
||
|
|
return ucfirst(trim($v));
|
||
|
|
});
|
||
|
|
$input->setArgument('name', $name);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator): void
|
||
|
|
{
|
||
|
|
$rawName = (string) $input->getArgument('name');
|
||
|
|
$singular = ucfirst(Str::asCamelCase($rawName));
|
||
|
|
$resource = strtolower($singular);
|
||
|
|
|
||
|
|
$vars = [
|
||
|
|
'singular' => $singular,
|
||
|
|
'resource' => $resource,
|
||
|
|
];
|
||
|
|
|
||
|
|
$target = rtrim($this->qmlPath, '/').'/'.$singular.'Window.qml';
|
||
|
|
$generator->generateFile(
|
||
|
|
$target,
|
||
|
|
__DIR__.'/templates/Window.tpl.php',
|
||
|
|
$vars,
|
||
|
|
);
|
||
|
|
|
||
|
|
$generator->writeChanges();
|
||
|
|
$this->writeSuccessMessage($io);
|
||
|
|
$io->text("Window scaffold at <info>{$target}</info>.");
|
||
|
|
}
|
||
|
|
|
||
|
|
public function configureDependencies(DependencyBuilder $dependencies): void
|
||
|
|
{
|
||
|
|
// Pure-QML output — no PHP runtime deps.
|
||
|
|
}
|
||
|
|
}
|