[AI] extend ProFileGenerator with macro, media, and label creation

This commit is contained in:
Thorsten Bus 2026-03-01 18:46:10 +01:00
parent 3a33597bcf
commit cb219ea139
2 changed files with 191 additions and 10 deletions

View file

@ -6,11 +6,15 @@ namespace ProPresenter\Parser;
use Rv\Data\Action;
use Rv\Data\Action\ActionType;
use Rv\Data\Action\LayerType;
use Rv\Data\Action\MacroType;
use Rv\Data\Action\MediaType;
use Rv\Data\Action\SlideType;
use Rv\Data\ApplicationInfo;
use Rv\Data\ApplicationInfo\Application;
use Rv\Data\ApplicationInfo\Platform;
use Rv\Data\Color;
use Rv\Data\CollectionElementType;
use Rv\Data\Cue;
use Rv\Data\Graphics\Element as GraphicsElement;
use Rv\Data\Graphics\Feather;
@ -30,6 +34,9 @@ use Rv\Data\Graphics\Stroke\Style as StrokeStyle;
use Rv\Data\Graphics\Text;
use Rv\Data\Graphics\Text\VerticalAlignment;
use Rv\Data\Group;
use Rv\Data\Media;
use Rv\Data\Media\ImageTypeProperties;
use Rv\Data\Media\Metadata;
use Rv\Data\Presentation;
use Rv\Data\Presentation\Arrangement;
use Rv\Data\Presentation\CCLI;
@ -38,6 +45,8 @@ use Rv\Data\PresentationSlide;
use Rv\Data\Slide;
use Rv\Data\Slide\Element as SlideElement;
use Rv\Data\Slide\Element\TextScroller;
use Rv\Data\URL;
use Rv\Data\URL\Platform as UrlPlatform;
use Rv\Data\UUID;
use Rv\Data\Version;
@ -71,7 +80,7 @@ final class ProFileGenerator
foreach ($groupData['slides'] as $slideData) {
$cueUuid = self::newUuidString();
$cueIdentifiers[] = self::uuidFromString($cueUuid);
$cues[] = self::buildCue($cueUuid, $slideData['text'], $slideData['translation'] ?? null);
$cues[] = self::buildCue($cueUuid, $slideData);
}
$cueGroup = new CueGroup();
@ -139,11 +148,14 @@ final class ProFileGenerator
return $applicationInfo;
}
private static function buildCue(string $cueUuid, string $text, ?string $translation): Cue
private static function buildCue(string $cueUuid, array $slideData): Cue
{
$elements = [self::buildSlideElement('Orginal', $text)];
if ($translation !== null) {
$elements[] = self::buildSlideElement('Deutsch', $translation);
$elements = [];
if (isset($slideData['text'])) {
$elements[] = self::buildSlideElement('Orginal', (string) $slideData['text']);
if (isset($slideData['translation']) && $slideData['translation'] !== null) {
$elements[] = self::buildSlideElement('Deutsch', (string) $slideData['translation']);
}
}
$slide = new Slide();
@ -156,18 +168,90 @@ final class ProFileGenerator
$slideType = new SlideType();
$slideType->setPresentation($presentationSlide);
$actions = [self::buildSlideAction($slideType)];
if (isset($slideData['media'])) {
$actions[] = self::buildMediaAction(
(string) $slideData['media'],
(string) ($slideData['format'] ?? 'JPG'),
);
}
if (isset($slideData['macro']) && is_array($slideData['macro'])) {
$actions[] = self::buildMacroAction($slideData['macro']);
}
$cue = new Cue();
$cue->setUuid(self::uuidFromString($cueUuid));
$cue->setActions($actions);
$cue->setIsEnabled(true);
if (isset($slideData['label'])) {
$cue->setName((string) $slideData['label']);
}
return $cue;
}
private static function buildSlideAction(SlideType $slideType): Action
{
$action = new Action();
$action->setUuid(self::newUuid());
$action->setType(ActionType::ACTION_TYPE_PRESENTATION_SLIDE);
$action->setSlide($slideType);
$action->setIsEnabled(true);
$cue = new Cue();
$cue->setUuid(self::uuidFromString($cueUuid));
$cue->setActions([$action]);
$cue->setIsEnabled(true);
return $action;
}
return $cue;
private static function buildMacroAction(array $macroData): Action
{
$parentCollection = new CollectionElementType();
$parentCollection->setParameterName((string) ($macroData['collectionName'] ?? '--MAIN--'));
$parentCollection->setParameterUuid(self::uuidFromString((string) ($macroData['collectionUuid'] ?? '')));
$identification = new CollectionElementType();
$identification->setParameterName((string) ($macroData['name'] ?? ''));
$identification->setParameterUuid(self::uuidFromString((string) ($macroData['uuid'] ?? '')));
$identification->setParentCollection($parentCollection);
$macroType = new MacroType();
$macroType->setIdentification($identification);
$action = new Action();
$action->setUuid(self::newUuid());
$action->setType(ActionType::ACTION_TYPE_MACRO);
$action->setMacro($macroType);
$action->setIsEnabled(true);
return $action;
}
private static function buildMediaAction(string $absoluteUrl, string $format): Action
{
$url = new URL();
$url->setAbsoluteString($absoluteUrl);
$url->setPlatform(UrlPlatform::PLATFORM_MACOS);
$metadata = new Metadata();
$metadata->setFormat($format);
$mediaElement = new Media();
$mediaElement->setUuid(self::newUuid());
$mediaElement->setUrl($url);
$mediaElement->setMetadata($metadata);
$mediaElement->setImage(new ImageTypeProperties());
$mediaType = new MediaType();
$mediaType->setLayerType(LayerType::LAYER_TYPE_FOREGROUND);
$mediaType->setElement($mediaElement);
$action = new Action();
$action->setUuid(self::newUuid());
$action->setType(ActionType::ACTION_TYPE_MEDIA);
$action->setMedia($mediaType);
$action->setIsEnabled(true);
return $action;
}
private static function buildSlideElement(string $name, string $text): SlideElement

View file

@ -318,4 +318,101 @@ class ProFileGeneratorTest extends TestCase
$song = ProFileReader::read($filePath);
$this->assertSame('Write Song', $song->getName());
}
#[Test]
public function testGenerateWithMacro(): void
{
$song = ProFileGenerator::generate(
'Macro Song',
[
[
'name' => 'Verse 1',
'color' => [0.1, 0.2, 0.3, 1.0],
'slides' => [
[
'text' => 'Line 1',
'macro' => [
'name' => 'Macro Name',
'uuid' => '11111111-2222-3333-4444-555555555555',
'collectionName' => '--MAIN--',
'collectionUuid' => '8D02FC57-83F8-4042-9B90-81C229728426',
],
],
],
],
],
[
['name' => 'normal', 'groupNames' => ['Verse 1']],
],
);
$slide = $song->getSlides()[0];
$this->assertTrue($slide->hasMacro());
$this->assertSame('Macro Name', $slide->getMacroName());
$this->assertSame('11111111-2222-3333-4444-555555555555', $slide->getMacroUuid());
}
#[Test]
public function testGenerateMediaSlide(): void
{
$song = ProFileGenerator::generate(
'Media Song',
[
[
'name' => 'Verse 1',
'color' => [0.1, 0.2, 0.3, 1.0],
'slides' => [
[
'media' => 'file:///tmp/test-image.jpg',
'format' => 'JPG',
],
],
],
],
[
['name' => 'normal', 'groupNames' => ['Verse 1']],
],
);
$slide = $song->getSlides()[0];
$this->assertTrue($slide->hasMedia());
$this->assertSame('file:///tmp/test-image.jpg', $slide->getMediaUrl());
$this->assertSame('JPG', $slide->getMediaFormat());
$this->assertSame('', $slide->getPlainText());
}
#[Test]
public function testGenerateMediaSlideWithLabelAndMacro(): void
{
$song = ProFileGenerator::generate(
'Media Macro Song',
[
[
'name' => 'Verse 1',
'color' => [0.1, 0.2, 0.3, 1.0],
'slides' => [
[
'media' => 'file:///tmp/test-image-2.jpg',
'format' => 'JPG',
'label' => 'Image Slide Label',
'macro' => [
'name' => 'Image Macro',
'uuid' => 'AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE',
],
],
],
],
],
[
['name' => 'normal', 'groupNames' => ['Verse 1']],
],
);
$slide = $song->getSlides()[0];
$this->assertTrue($slide->hasMedia());
$this->assertSame('Image Slide Label', $slide->getLabel());
$this->assertTrue($slide->hasMacro());
$this->assertSame('Image Macro', $slide->getMacroName());
$this->assertSame('AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE', $slide->getMacroUuid());
}
}