Helper-Beispiel: Persona
← 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
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