All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sikuli.guide.SxCallout Maven / Gradle / Ivy

/**
 *
 */
package org.sikuli.guide;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.RoundRectangle2D;

import org.sikuli.script.Region;

public class SxCallout extends Visual {

  static final int TRIANGLE_SIZE = 20;
  static int defMaxWidth = 400;
  static int defFontSize = 14;
  static String defFont = "Verdana";
  HTMLTextPane textArea;
  RoundedBox rbox;
  Triangle triangle;
  int dx = 0;
  int dy = 0;

  public SxCallout(String text) {
    super();
    init(text);
  }

  void init(String text) {
    layout = Layout.RIGHT;
    maxWidth = defMaxWidth;
    fontName = defFont;
    fontSize = defFontSize;
    this.text = text;
    textArea = new HTMLTextPane(this);
    rbox = new RoundedBox(textArea.getBounds());
    add(textArea);
    add(rbox);
    triangle = new Triangle();
    add(triangle);
    targetRegion = null;
    setColors(null, Color.YELLOW, Color.YELLOW, null, null);
    makeComponent();
  }

  @Override
  public void updateComponent() {
    textArea.setText(text);
    textArea.setLocation(PADDING_X, PADDING_Y);
    Rectangle rect = textArea.getBounds();
    rect.grow(PADDING_X, PADDING_Y);
    rbox.setBounds(rect);
    makeComponent();
    triangle.setForeground(colorBack);
    rbox.setForeground(colorBack);
    if (targetRegion != null) {
      super.setLocationRelativeToRegion(targetRegion, layout);
    }
  }

  @Override
  public Visual setLocationRelativeToRegion(Region region, Layout side) {
    if (side != layout) {
      layout = side;
      updateComponent();
    }
    targetRegion = region;
    return super.setLocationRelativeToRegion(targetRegion, side);
  }

  private void makeComponent() {
    if (layout == Layout.TOP) {
      triangle.rotate(0);
      dx = 0; dy = 0;
      triangle.setLocationRelativeToComponent(rbox, Layout.BOTTOM);
    } else if (layout == Layout.BOTTOM) {
      dx = 0; dy = TRIANGLE_SIZE;
      triangle.rotate(Math.PI);
      triangle.setLocationRelativeToComponent(rbox, Layout.TOP);
    } else if (layout == Layout.LEFT) {
      dx = 0; dy = 0;
      triangle.rotate(-Math.PI / 2);
      triangle.setLocationRelativeToComponent(rbox, Layout.RIGHT);
    } else if (layout == Layout.RIGHT) {
      dx = TRIANGLE_SIZE; dy = 0;
      triangle.rotate(Math.PI / 2);
      triangle.setLocationRelativeToComponent(rbox, Layout.LEFT);
    }
    Rectangle bounds = rbox.getBounds();
    bounds.add(triangle.getBounds());
    setActualBounds(bounds);
  }

  @Override
  public void paintComponent(Graphics g) {
    g.translate(dx, dy);
    super.paintComponent(g);
  }

  class Triangle extends Visual {

    GeneralPath gp;

    public Triangle() {
      super();
      init();
    }

    private void init() {
      gp = new GeneralPath();
      gp.moveTo(TRIANGLE_SIZE * 0.45, 0);
      gp.lineTo(TRIANGLE_SIZE * 0.5, TRIANGLE_SIZE);
      gp.lineTo(TRIANGLE_SIZE * 0.85, 0);
      gp.closePath();
      setActualSize(new Dimension(TRIANGLE_SIZE, TRIANGLE_SIZE));
    }

    public void rotate(double radius) {
      init();
      AffineTransform rat = new AffineTransform();
      rat.rotate(radius, TRIANGLE_SIZE / 2, TRIANGLE_SIZE / 2);
      gp.transform(rat);
    }

    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
              RenderingHints.VALUE_ANTIALIAS_ON);
      g2d.fill(gp);
    }
  }

  class RoundedBox extends Visual {

    public RoundedBox(Rectangle rect) {
      super();
      setActualBounds(rect);
    }

    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
              RenderingHints.VALUE_ANTIALIAS_ON);
      RoundRectangle2D roundedRectangle = new RoundRectangle2D.Float(0, 0, getWidth(), getHeight(), 15, 15);
      g2d.fill(roundedRectangle);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy