Gérer les connecteurs dans les présentations sur Android

Un connecteur PowerPoint est une ligne spéciale qui relie deux formes et reste attachée aux formes même lorsqu’elles sont déplacées ou repositionnées sur une diapositive donnée.

Les connecteurs sont généralement connectés à points de connexion (points verts), qui existent par défaut sur toutes les formes. Les points de connexion apparaissent lorsqu’un curseur s’en rapproche.

Points d’ajustement (points orange), qui n’existent que sur certains connecteurs, sont utilisés pour modifier la position et la forme des connecteurs.

Types de connecteurs

Dans PowerPoint, vous pouvez utiliser des connecteurs droits, coudés (angulaires) et courbes.

Aspose.Slides fournit ces connecteurs :

Connecteur Image Nombre de points d’ajustement
ShapeType.Line type-de-forme-ligne-connecteur 0
ShapeType.StraightConnector1 type-de-forme-connexion-rapide1 0
ShapeType.BentConnector2 type-de-forme-connexion-courbée2 0
ShapeType.BentConnector3 type-de-forme-connexion-courbée3 1
ShapeType.BentConnector4 type-de-forme-connexion-courbée4 2
ShapeType.BentConnector5 type-de-forme-connexion-courbée5 3
ShapeType.CurvedConnector2 type-de-forme-connexion-courbe2 0
ShapeType.CurvedConnector3 type-de-forme-connexion-courbe3 1
ShapeType.CurvedConnector4 type-de-forme-connexion-courbe4 2
ShapeType.CurvedConnector5 type-de-forme-connexion-courbe5 3

Connecter des formes à l’aide de connecteurs

  1. Créez une instance de la classe Presentation.
  2. Obtenez la référence d’une diapositive via son indice.
  3. Ajoutez deux AutoShape à la diapositive en utilisant la méthode addAutoShape exposée par l’objet Shapes.
  4. Ajoutez un connecteur à l’aide de la méthode addConnector exposée par l’objet Shapes en précisant le type de connecteur.
  5. Connectez les formes avec le connecteur.
  6. Appelez la méthode reroute pour appliquer le chemin de connexion le plus court.
  7. Enregistrez la présentation.

Ce code Java montre comment ajouter un connecteur (un connecteur coudé) entre deux formes (une ellipse et un rectangle) :

// Instancie une classe de présentation qui représente le fichier PPTX
Presentation pres = new Presentation();
try {
    // Accède à la collection de formes d'une diapositive spécifique
    IShapeCollection shapes = pres.getSlides().get_Item(0).getShapes();
    
    // Ajoute une forme auto Ellipse
    IAutoShape ellipse = shapes.addAutoShape(ShapeType.Ellipse, 0, 100, 100, 100);
    
    // Ajoute une forme auto Rectangle
    IAutoShape rectangle = shapes.addAutoShape(ShapeType.Rectangle, 100, 300, 100, 100);
    
    // Ajoute une forme de connecteur à la collection de formes de la diapositive
    IConnector connector = shapes.addConnector(ShapeType.BentConnector2, 0, 0, 10, 10);
    
    // Connecte les formes à l'aide du connecteur
    connector.setStartShapeConnectedTo(ellipse);
    connector.setEndShapeConnectedTo(rectangle);
    
    // Appelle reroute qui définit le chemin le plus court automatique entre les formes
    connector.reroute();
    
    // Enregistre la présentation
    pres.save("output.pptx", SaveFormat.Pptx);
} finally {
    if (pres != null) pres.dispose();
}

Spécifier un point de connexion

Si vous souhaitez qu’un connecteur relie deux formes en utilisant des points précis sur les formes, vous devez spécifier vos points de connexion préférés de cette façon :

  1. Créez une instance de la classe Presentation.
  2. Obtenez la référence d’une diapositive via son indice.
  3. Ajoutez deux AutoShape à la diapositive en utilisant la méthode addAutoShape exposée par l’objet Shapes.
  4. Ajoutez un connecteur à l’aide de la méthode addConnector exposée par l’objet Shapes en précisant le type de connecteur.
  5. Connectez les formes avec le connecteur.
  6. Définissez vos points de connexion préférés sur les formes.
  7. Enregistrez la présentation.

Ce code Java montre une opération où un point de connexion préféré est spécifié :

// Instancie une classe de présentation qui représente un fichier PPTX
Presentation pres = new Presentation();
try {
    // Accède à la collection de formes pour une diapositive spécifique
    IShapeCollection shapes = pres.getSlides().get_Item(0).getShapes();

    // Ajoute une forme auto Ellipse
    IAutoShape ellipse = shapes.addAutoShape(ShapeType.Ellipse, 0, 100, 100, 100);

    // Ajoute une forme auto Rectangle
    IAutoShape rectangle = shapes.addAutoShape(ShapeType.Rectangle, 100, 300, 100, 100);

    // Ajoute une forme de connecteur à la collection de formes de la diapositive
    IConnector connector = shapes.addConnector(ShapeType.BentConnector2, 0, 0, 10, 10);

    // Connecte les formes à l'aide du connecteur
    connector.setStartShapeConnectedTo(ellipse);
    connector.setEndShapeConnectedTo(rectangle);

    // Définit l'indice du point de connexion préféré sur la forme Ellipse
    int wantedIndex = 6;

    // Vérifie si l'indice préféré est inférieur au nombre maximal d'indices de sites
    if (ellipse.getConnectionSiteCount() > wantedIndex) 
    {
        // Définit le point de connexion préféré sur la forme auto Ellipse
        connector.setStartShapeConnectionSiteIndex(wantedIndex);
    }

    // Enregistre la présentation
    pres.save("output.pptx", SaveFormat.Pptx);
} finally {
    if (pres != null) pres.dispose();
}

Ajuster un point de connecteur

Vous pouvez ajuster un connecteur existant via ses points d’ajustement. Seuls les connecteurs possédant des points d’ajustement peuvent être modifiés de cette façon. Voir le tableau sous Types de connecteurs

Cas simple

Considérons un cas où un connecteur entre deux formes (A et B) passe par une troisième forme (C) :

obstruction-connecteur

Presentation pres = new Presentation();
try {

    ISlide sld = pres.getSlides().get_Item(0);
    IShape shape = sld.getShapes().addAutoShape(ShapeType.Rectangle, 300, 150, 150, 75);
    IShape shapeFrom = sld.getShapes().addAutoShape(ShapeType.Rectangle, 500, 400, 100, 50);
    IShape shapeTo = sld.getShapes().addAutoShape(ShapeType.Rectangle, 100, 100, 70, 30);

    IConnector connector = sld.getShapes().addConnector(ShapeType.BentConnector5, 20, 20, 400, 300);

    connector.getLineFormat().setEndArrowheadStyle(LineArrowheadStyle.Triangle);
    connector.getLineFormat().getFillFormat().setFillType(FillType.Solid);
    connector.getLineFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK);

    connector.setStartShapeConnectedTo(shapeFrom);
    connector.setEndShapeConnectedTo(shapeTo);
    connector.setStartShapeConnectionSiteIndex(2);
} finally {
    if (pres != null) pres.dispose();
}

Pour éviter ou contourner la troisième forme, nous pouvons ajuster le connecteur en déplaçant sa ligne verticale vers la gauche de cette façon :

obstruction-connecteur-réparée

IAdjustValue adj2 = connector.getAdjustments().get_Item(1);
adj2.setRawValue(adj2.getRawValue() + 10000);

Cas complexes

Pour réaliser des ajustements plus compliqués, il faut prendre en compte les éléments suivants :

  • Le point ajustable d’un connecteur est fortement lié à une formule qui calcule et détermine sa position. Ainsi, une modification de la position du point peut modifier la forme du connecteur.
  • Les points d’ajustement d’un connecteur sont définis dans un ordre strict dans un tableau. Ils sont numérotés depuis le point de départ du connecteur jusqu’à son point d’arrivée.
  • Les valeurs des points d’ajustement reflètent le pourcentage de la largeur/hauteur de la forme du connecteur.
    • La forme est bornée par les points de départ et d’arrivée du connecteur multipliés par 1000.
    • Le premier point, le deuxième point et le troisième point définissent respectivement le pourcentage de la largeur, le pourcentage de la hauteur et à nouveau le pourcentage de la largeur.
  • Pour les calculs déterminant les coordonnées des points d’ajustement, il faut tenir compte de la rotation du connecteur et de son reflet. Note : l’angle de rotation pour tous les connecteurs affichés sous Types de connecteurs est 0.

Cas 1

Considérons un cas où deux objets de zone de texte sont reliés par un connecteur :

connecteur-forme-complexe

// Instancie une classe de présentation qui représente un fichier PPTX
Presentation pres = new Presentation();
try {
    // Obtient la première diapositive de la présentation
    ISlide sld = pres.getSlides().get_Item(0);
    // Ajoute des formes qui seront jointes ensemble via un connecteur
    IAutoShape shapeFrom = sld.getShapes().addAutoShape(ShapeType.Rectangle, 100, 100, 60, 25);
    shapeFrom.getTextFrame().setText("From");
    IAutoShape shapeTo = sld.getShapes().addAutoShape(ShapeType.Rectangle, 500, 100, 60, 25);
    shapeTo.getTextFrame().setText("To");
    // Ajoute un connecteur
    IConnector connector = sld.getShapes().addConnector(ShapeType.BentConnector4, 20, 20, 400, 300);
    // Définit la direction du connecteur
    connector.getLineFormat().setEndArrowheadStyle(LineArrowheadStyle.Triangle);
    // Définit la couleur du connecteur
    connector.getLineFormat().getFillFormat().setFillType(FillType.Solid);
    connector.getLineFormat().getFillFormat().getSolidFillColor().setColor(Color.RED);
    // Définit l'épaisseur de la ligne du connecteur
    connector.getLineFormat().setWidth(3);
    
    // Relie les formes ensemble avec le connecteur
    connector.setStartShapeConnectedTo(shapeFrom);
    connector.setStartShapeConnectionSiteIndex(3);
    connector.setEndShapeConnectedTo(shapeTo);
    connector.setEndShapeConnectionSiteIndex(2);
    
    // Obtient les points d'ajustement du connecteur
    IAdjustValue adjValue_0 = connector.getAdjustments().get_Item(0);
    IAdjustValue adjValue_1 = connector.getAdjustments().get_Item(1);

} finally {
    if (pres != null) pres.dispose();
}

Ajustement

Nous pouvons modifier les valeurs des points d’ajustement du connecteur en augmentant respectivement le pourcentage de largeur et le pourcentage de hauteur de 20 % et 200 % :

// Modifie les valeurs des points d'ajustement
adjValue_0.setRawValue(adjValue_0.getRawValue() + 20000);
adjValue_1.setRawValue(adjValue_1.getRawValue() + 200000);

Le résultat :

connecteur-ajusté-1

Pour définir un modèle nous permettant de déterminer les coordonnées et la forme des différentes parties du connecteur, créons une forme correspondant à la composante horizontale du connecteur au point connector.getAdjustments().get_Item(0) :

// Dessine la composante verticale du connecteur
float x = connector.getX() + connector.getWidth() * adjValue_0.getRawValue() / 100000;
float y = connector.getY();
float height = connector.getHeight() * adjValue_1.getRawValue() / 100000;
sld.getShapes().addAutoShape( ShapeType .Rectangle, x, y, 0, height);

Le résultat :

connecteur-ajusté-2

Cas 2

Dans le Cas 1, nous avons démontré une opération simple d’ajustement de connecteur en utilisant des principes de base. Dans des situations normales, il faut prendre en compte la rotation du connecteur et son affichage (qui sont définis par connector.getRotation(), connector.getFrame().getFlipH() et connector.getFrame().getFlipV()). Nous allons maintenant montrer le processus.

Tout d’abord, ajoutons un nouvel objet de zone de texte (To 1) à la diapositive (pour la connexion) et créons un nouveau connecteur (vert) qui le relie aux objets déjà créés.

// Crée un nouvel objet de liaison
IAutoShape shapeTo_1 = sld.getShapes().addAutoShape(ShapeType.Rectangle, 100, 400, 60, 25);
shapeTo_1.getTextFrame().setText("To 1");
// Crée un nouveau connecteur
connector = sld.getShapes().addConnector(ShapeType.BentConnector4, 20, 20, 400, 300);
connector.getLineFormat().setEndArrowheadStyle(LineArrowheadStyle.Triangle);
connector.getLineFormat().getFillFormat().setFillType(FillType.Solid);
connector.getLineFormat().getFillFormat().getSolidFillColor().setColor(Color.CYAN);
connector.getLineFormat().setWidth(3);
// Connecte les objets en utilisant le connecteur nouvellement créé
connector.setStartShapeConnectedTo(shapeFrom);
connector.setStartShapeConnectionSiteIndex(2);
connector.setEndShapeConnectedTo(shapeTo_1);
connector.setEndShapeConnectionSiteIndex(3);
// Obtient les points d'ajustement du connecteur
adjValue_0 = connector.getAdjustments().get_Item(0);
adjValue_1 = connector.getAdjustments().get_Item(1);
// Modifie les valeurs des points d'ajustement
adjValue_0.setRawValue(adjValue_0.getRawValue() + 20000);
adjValue_1.setRawValue(adjValue_1.getRawValue() + 200000);

Le résultat :

connecteur-ajusté-3

Ensuite, créons une forme qui correspondra à la composante horizontale du connecteur passant par le nouveau point d’ajustement connector.getAdjustments().get_Item(0). Nous utiliserons les valeurs du connecteur pour connector.getRotation(), connector.getFrame().getFlipH() et connector.getFrame().getFlipV() et appliquerons la formule de conversion de coordonnées pour une rotation autour d’un point x₀ :

X = (x — x0) * cos(alpha) — (y — y0) * sin(alpha) + x0;

Y = (x — x0) * sin(alpha) + (y — y0) * cos(alpha) + y0;

Dans notre cas, l’angle de rotation de l’objet est de 90 degrés et le connecteur est affiché verticalement, voici le code correspondant :

// Enregistre les coordonnées du connecteur
x = connector.getX();
y = connector.getY();
// Corrige les coordonnées du connecteur si nécessaire
if (connector.getFrame().getFlipH() == NullableBool.True)
{
    x += connector.getWidth();
}
if (connector.getFrame().getFlipV() == NullableBool.True)
{
    y += connector.getHeight();
}
// Utilise la valeur du point d'ajustement comme coordonnée
x += connector.getWidth() * adjValue_0.getRawValue() / 100000;
//  Convertit les coordonnées puisque Sin(90) = 1 et Cos(90) = 0
float xx = connector.getFrame().getCenterX() - y + connector.getFrame().getCenterY();
float yy = x - connector.getFrame().getCenterX() + connector.getFrame().getCenterY();
// Détermine la largeur de la composante horizontale en utilisant la valeur du deuxième point d'ajustement
float width = connector.getHeight() * adjValue_1.getRawValue() / 100000;
IAutoShape shape = sld.getShapes().addAutoShape(ShapeType.Rectangle, xx, yy, width, 0);
shape.getLineFormat().getFillFormat().setFillType(FillType.Solid);
shape.getLineFormat().getFillFormat().getSolidFillColor().setColor(Color.RED);

Le résultat :

connecteur-ajusté-4

Nous avons démontré des calculs impliquant des ajustements simples et des points d’ajustement compliqués (points d’ajustement avec angles de rotation). En vous appuyant sur ces connaissances, vous pouvez développer votre propre modèle (ou écrire du code) afin d’obtenir un objet GraphicsPath ou même de définir les valeurs des points d’ajustement d’un connecteur selon des coordonnées de diapositive spécifiques.

Trouver l’angle des lignes de connecteur

  1. Créez une instance de la classe.
  2. Obtenez la référence d’une diapositive via son indice.
  3. Accédez à la forme de ligne du connecteur.
  4. Utilisez la largeur, la hauteur, la hauteur du cadre de forme et la largeur du cadre de forme pour calculer l’angle.

Ce code Java montre une opération où nous avons calculé l’angle d’une forme de ligne de connecteur :

Presentation pres = new Presentation("ConnectorLineAngle.pptx");
try {
    Slide slide = (Slide)pres.getSlides().get_Item(0);
    
    for (int i = 0; i < slide.getShapes().size(); i++)
    {
        double dir = 0.0;
        Shape shape = (Shape)slide.getShapes().get_Item(i);
        if (shape instanceof AutoShape)
        {
            AutoShape ashp = (AutoShape)shape;
            if (ashp.getShapeType() == ShapeType.Line)
            {
                dir = getDirection(ashp.getWidth(), ashp.getHeight(),
                        ashp.getFrame().getFlipH() > 0, ashp.getFrame().getFlipV() > 0);
            }
        }
        else if (shape instanceof Connector)
        {
            Connector ashp = (Connector)shape;
            dir = getDirection(ashp.getWidth(), ashp.getHeight(),
                    ashp.getFrame().getFlipH() > 0, ashp.getFrame().getFlipV() > 0);
        }

        System.out.println(dir);
    }
} finally {
    if (pres != null) pres.dispose();
}
public static double getDirection(float w, float h, boolean flipH, boolean flipV)
{
    float endLineX = w * (flipH ? -1 : 1);
    float endLineY = h * (flipV ? -1 : 1);
    float endYAxisX = 0;
    float endYAxisY = h;
    double angle = (Math.atan2(endYAxisY, endYAxisX) - Math.atan2(endLineY, endLineX));
    if (angle < 0) angle += 2 * Math.PI;
    return angle * 180.0 / Math.PI;
}

FAQ

Comment savoir si un connecteur peut être « collé » à une forme spécifique ?

Vérifiez que la forme expose des sites de connexion. S’il n’y en a aucun ou si le nombre est zéro, le collage n’est pas disponible ; dans ce cas, utilisez des extrémités libres et positionnez‑les manuellement. Il est judicieux de vérifier le nombre de sites avant de les attacher.

Que se passe‑t‑il pour un connecteur si je supprime l’une des formes connectées ?

Ses extrémités seront détachées ; le connecteur reste sur la diapositive comme une ligne ordinaire avec un départ/arrivée libres. Vous pouvez soit le supprimer, soit réaffecter les connexions et, si nécessaire, le rerouter.

Les liaisons de connecteur sont‑elles conservées lors de la copie d’une diapositive vers une autre présentation ?

Généralement oui, à condition que les formes cibles soient également copiées. Si la diapositive est insérée dans un autre fichier sans les formes connectées, les extrémités deviennent libres et vous devrez les rattacher à nouveau.