Helper-Beispiel: Persona

Erstellt: 2026-05-29 · Aktualisiert: 2026-05-29

Helper-Referenz · Advanced Snippet Editor

Parametrisierte Persona-Figur (Körper aus Freeform Bezier-Kurven + Kopf-Oval + Namensfeld). Zeigt Freeform mit msoEditingAuto, Nodes.SetPosition, Group und Scale.


Verwendete ppptools-Methoden

Methode Verwendungszweck
ppptools.BuildFreeform(editingType, x, y) Torso als Bezier-Freeform
ppptools.AddOval(x, y, w, h) Kopf
ppptools.AddRect(x, y, w, h) Namensfeld (transparent)
ppptools.Group(shape1, ...) Alle drei Shapes gruppieren
ppptools.SlideWidth / SlideHeight Zentrieren

Parameter

@param Typ Standard Beschreibung
Groesse enum "Mittel" Klein (25%), Mittel (50%), Gross (100%)
Koerperfarbe color #4472C4 Körper- und Kopffarbe
Schriftfarbe color #262626 Schriftfarbe des Namenstexts
PersonaName string "Persona" Text unterhalb der Figur
Zentrieren bool true Auf Folie zentrieren

Ergebnis

Persona

Vollständiger Code

// @help https://ppptools.happy-pc.ch/help/de/helper-beispiel-persona
// @param enum   Groesse      "Grösse"               options="Klein|Mittel|Gross"  default="Mittel"
// @param color  Koerperfarbe "Körperfarbe"          default=#4472C4
// @param color  Schriftfarbe "Schriftfarbe"         default=#262626
// @param string PersonaName  "Name"                 default="Persona"
// @param bool   Zentrieren   "Auf Folie zentrieren" default=true

string groesse     = Params.GetString("Groesse",      "Mittel");
var    bodyColor   = Params.GetColor("Koerperfarbe",  Color.FromArgb(68, 114, 196));
var    fontColor   = Params.GetColor("Schriftfarbe",  Color.FromArgb(38,  38,  38));
string personaName = Params.GetString("PersonaName",  "Persona");
bool   zentrieren  = Params.GetBool("Zentrieren",    true);

int bodyRgb = System.Drawing.ColorTranslator.ToOle(bodyColor);
int fontRgb = System.Drawing.ColorTranslator.ToOle(fontColor);

// ── Körper (Freeform Torso) ───────────────────────────────────────────
var ff = ppptools.BuildFreeform(MsoEditingType.msoEditingAuto, 272.9073f, 363.8064f);
ff.AddNodes(MsoSegmentType.msoSegmentCurve, MsoEditingType.msoEditingCorner,
    320.5420f, 363.8064f, 359.7210f, 399.0247f, 364.4324f, 444.1556f);
ff.AddNodes(MsoSegmentType.msoSegmentLine,  MsoEditingType.msoEditingCorner,
    364.9130f, 452.5568f);
ff.AddNodes(MsoSegmentType.msoSegmentCurve, MsoEditingType.msoEditingAuto,
    364.9130f, 473.3365f, 323.7406f, 490.1818f, 272.9519f, 490.1818f);
ff.AddNodes(MsoSegmentType.msoSegmentCurve, MsoEditingType.msoEditingCorner,
    222.1631f, 490.1818f, 180.9908f, 473.3365f, 180.9908f, 452.5568f);
ff.AddNodes(MsoSegmentType.msoSegmentLine,  MsoEditingType.msoEditingCorner,
    181.3824f, 444.1556f);
ff.AddNodes(MsoSegmentType.msoSegmentCurve, MsoEditingType.msoEditingAuto,
    186.0936f, 399.0247f, 225.2728f, 363.8064f, 272.9073f, 363.8064f);

var oBody = ff.ConvertToShape();

// Knotenkorrektur (exakte Bezier-Positionen sicherstellen)
oBody.Nodes.SetPosition(1,  272.9073f, 363.8064f);
oBody.Nodes.SetPosition(2,  320.5420f, 363.8064f);
oBody.Nodes.SetPosition(3,  359.7210f, 399.0247f);
oBody.Nodes.SetPosition(4,  364.4324f, 444.1556f);
oBody.Nodes.SetPosition(5,  364.9130f, 452.5568f);
oBody.Nodes.SetPosition(6,  364.9130f, 473.3365f);
oBody.Nodes.SetPosition(7,  323.7406f, 490.1818f);
oBody.Nodes.SetPosition(8,  272.9519f, 490.1818f);
oBody.Nodes.SetPosition(9,  222.1631f, 490.1818f);
oBody.Nodes.SetPosition(10, 180.9908f, 473.3365f);
oBody.Nodes.SetPosition(11, 180.9908f, 452.5568f);
oBody.Nodes.SetPosition(12, 181.3824f, 444.1556f);
oBody.Nodes.SetPosition(13, 186.0936f, 399.0247f);
oBody.Nodes.SetPosition(14, 225.2728f, 363.8064f);
oBody.Nodes.SetPosition(15, 272.9073f, 363.8064f);

oBody.Name = "Persona_Body";
oBody.Fill.ForeColor.RGB = bodyRgb;
oBody.Fill.Transparency  = 0f;
oBody.Line.Visible = MsoTriState.msoFalse;

// ── Kopf (Oval) ───────────────────────────────────────────────────────
var oHead = ppptools.AddOval(224.9519f, 260.5564f, 96f, 96f);
oHead.Name = "Persona_Head";
oHead.Fill.ForeColor.RGB = bodyRgb;
oHead.Fill.Transparency  = 0f;
oHead.Line.Visible = MsoTriState.msoFalse;

// ── Namensfeld (transparente Textbox) ─────────────────────────────────
var oText = ppptools.AddRect(180.9908f, 497.4318f, 183.9222f, 30f);
oText.Name = "Persona_Text";
oText.Fill.ForeColor.RGB = 16777215;
oText.Fill.Transparency  = 1f;
oText.Line.Visible = MsoTriState.msoFalse;

oText.TextFrame.TextRange.Text = personaName;
oText.TextFrame.TextRange.Font.Name  = "Arial";
oText.TextFrame.TextRange.Font.Size  = 12;
oText.TextFrame.TextRange.Font.Bold  = MsoTriState.msoFalse;
oText.TextFrame.TextRange.Font.Color.RGB = fontRgb;
oText.TextFrame2.TextRange.Font.Fill.Solid();
oText.TextFrame.TextRange.ParagraphFormat.Alignment         = PpParagraphAlignment.ppAlignCenter;
oText.TextFrame.TextRange.ParagraphFormat.BaseLineAlignment = PpBaselineAlignment.ppBaselineAlignCenter;
oText.TextFrame2.VerticalAnchor   = MsoVerticalAnchor.msoAnchorMiddle;
oText.TextFrame.VerticalAnchor    = MsoVerticalAnchor.msoAnchorMiddle;
oText.TextFrame2.Orientation      = MsoTextOrientation.msoTextOrientationHorizontal;
oText.TextFrame2.MarginTop    = 3.6f;
oText.TextFrame2.MarginRight  = 7.2f;
oText.TextFrame2.MarginBottom = 3.6f;
oText.TextFrame2.MarginLeft   = 7.2f;
oText.TextFrame.WordWrap      = MsoTriState.msoTrue;
oText.TextFrame2.Column.Number    = 1;
oText.TextFrame2.Column.Spacing   = 0;
oText.TextFrame2.AutoSize = MsoAutoSize.msoAutoSizeTextToFitShape;

// ── Gruppieren ────────────────────────────────────────────────────────
dynamic oGroup = ppptools.Group(oBody, oHead, oText);
oGroup.Name = "Persona";

// ── Skalieren ─────────────────────────────────────────────────────────
float scale = groesse == "Klein" ? 0.25f : groesse == "Gross" ? 1.0f : 0.5f;
oGroup.Width  = (float)oGroup.Width  * scale;
oGroup.Height = (float)oGroup.Height * scale;

// ── Zentrieren ────────────────────────────────────────────────────────
if (zentrieren)
{
    oGroup.Left = (ppptools.SlideWidth  - (float)oGroup.Width)  / 2f;
    oGroup.Top  = (ppptools.SlideHeight - (float)oGroup.Height) / 2f;
}

Schritt-für-Schritt

1. Körper als Bezier-Freeform mit ppptools.BuildFreeform

var ff = ppptools.BuildFreeform(MsoEditingType.msoEditingAuto, 272.9073f, 363.8064f);
ff.AddNodes(MsoSegmentType.msoSegmentCurve, MsoEditingType.msoEditingCorner,
    320.54f, 363.81f, 359.72f, 399.02f, 364.43f, 444.16f);
// ... weitere Nodes ...
var oBody = ff.ConvertToShape();

msoEditingAuto ermöglicht gemischte Kurven- und Liniensegmente im selben Freeform. Der Startpunkt wird bereits im BuildFreeform-Aufruf übergeben.

Bei Kurven-Nodes (msoSegmentCurve) werden drei Punkte übergeben: Bezier-Kontrollpunkt 1, Bezier-Kontrollpunkt 2, Endpunkt.


2. Knotenkorrektur mit Nodes.SetPosition

oBody.Nodes.SetPosition(1,  272.9073f, 363.8064f);
oBody.Nodes.SetPosition(2,  320.5420f, 363.8064f);
// ...

Nach ConvertToShape() setzt PowerPoint die Nodes intern leicht anders. SetPosition stellt die exakten Bezier-Positionen sicher — wichtig für pixelgenaue Reproduzierbarkeit.

Freeform Nodes (Besonderheit)

PowerPoint kann Nodes intern neu ordnen oder anpassen. SetPosition nach ConvertToShape garantiert die gewünschten Koordinaten. Detaillierte Erklärung: FreeForm Vertices/Nodes


3. Oval und Rect mit ppptools.AddOval / ppptools.AddRect

var oHead = ppptools.AddOval(224.9519f, 260.5564f, 96f, 96f);   // Kreis 96×96
var oText = ppptools.AddRect(180.9908f, 497.4318f, 183.9222f, 30f);

Der Kopf ist ein Kreis (w=h=96), direkt auf den Torso positioniert. Das Textfeld ist ein Rechteck mit Transparency = 1f (100% transparent) — nur der Text ist sichtbar.


4. Alle drei Shapes in einem Aufruf gruppieren mit ppptools.Group

dynamic oGroup = ppptools.Group(oBody, oHead, oText);

ppptools.Group(params dynamic[] shapes) selektiert alle übergebenen Shapes und ruft dann GroupSelected() auf. Kein manuelles Select/Select nötig. Gibt die fertige Gruppe zurück.


5. Skalieren und Zentrieren

float scale = groesse == "Klein" ? 0.25f : groesse == "Gross" ? 1.0f : 0.5f;
oGroup.Width  = (float)oGroup.Width  * scale;
oGroup.Height = (float)oGroup.Height * scale;

if (zentrieren)
{
    oGroup.Left = (ppptools.SlideWidth  - (float)oGroup.Width)  / 2f;
    oGroup.Top  = (ppptools.SlideHeight - (float)oGroup.Height) / 2f;
}

Die Basisgrösse ist auf "Gross = 100%" ausgelegt (Torso ca. 185×230pt). ppptools.SlideWidth/Height ersetzt aPowerPoint.ActivePresentation.PageSetup.*.

Alternativ: ppptools.CenterOnSlide(oGroup) für Zentrieren in einer Zeile.


Warum Freeform statt AutoShape?

Der menschliche Torso lässt sich nicht mit einem MsoAutoShapeType darstellen. Freeform mit Bezier-Segmenten (Code-Generator-Output) ergibt eine präzise, skalierbare Vektorgrafik in PowerPoint.


Zurück: Helper-Referenz · Alle Beispiele