0

In the sample code below (Modified TooltipExample.java from https://github.com/piccolo2d/piccolo2d.java/tree/master/examples/src/main/java/org/piccolo2d/examples), I created a curved line inside a rectangle. It appears that the area/bounds contained by this curve is not along the curve but the highlighted part in GREY. I am trying to find if there is a way we can show the tooltip of curve only along the curve. I tried resetting the underlying PBounds, but no luck. Does anyone know how to achieve this?

import org.piccolo2d.PCamera;
import org.piccolo2d.PCanvas;
import org.piccolo2d.PNode;
import org.piccolo2d.event.PBasicInputEventHandler;
import org.piccolo2d.event.PInputEvent;
import org.piccolo2d.extras.PFrame;
import org.piccolo2d.nodes.PPath;
import org.piccolo2d.nodes.PText;

import java.awt.*;
import java.awt.geom.Point2D;


/**
 * Simple example of one way to add tooltips
 *
 * @author jesse
 */
public class TooltipExample extends PFrame {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    public TooltipExample() {
        this(null);
    }

    public TooltipExample(final PCanvas aCanvas) {
        super("TooltipExample", false, aCanvas);
    }

    public void initialize() {
        final PNode n1 = PPath.createEllipse(0, 0, 100, 100);
        final PNode n2 = PPath.createRectangle(300, 200, 100, 100);

        PPath curve = new PPath.Float();
        curve.moveTo(318.0,222.0);
        curve.curveTo(318.0,222.0, 375.0,228.0, 352.0,278.0);
        curve.addAttribute("tooltip","Curve");
        curve.setPaint(Color.GRAY);

        n1.addAttribute("tooltip", "node 1");
        n2.addAttribute("tooltip", "node 2");
        getCanvas().getLayer().addChild(n1);
        getCanvas().getLayer().addChild(n2);
        getCanvas().getLayer().addChild(curve);

        final PCamera camera = getCanvas().getCamera();
        final PText tooltipNode = new PText();

        tooltipNode.setPickable(false);
        camera.addChild(tooltipNode);

        camera.addInputEventListener(new PBasicInputEventHandler() {
            public void mouseMoved(final PInputEvent event) {
                updateToolTip(event);
            }

            public void mouseDragged(final PInputEvent event) {
                updateToolTip(event);
            }

            public void mouseClicked(final PInputEvent event) {
                final Point2D p = event.getCanvasPosition();
                System.out.println(p.getX()+","+p.getY());
            }

            public void updateToolTip(final PInputEvent event) {
                final PNode n = event.getPickedNode();
                final String tooltipString = (String) n.getAttribute("tooltip");
                final Point2D p = event.getCanvasPosition();
                event.getPath().canvasToLocal(p, camera);

                tooltipNode.setText(tooltipString);
                tooltipNode.setOffset(p.getX() + 8, p.getY() - 8);
            }
        });
    }

    public static void main(final String[] argv) {
        new TooltipExample();
    }
}

enter image description here

The bigger picture: Let's say we have many such overlapping curves passing over one another. If there is another smaller shape placed in between the huge overlapping area of these curves, I am not able to get any events for that shape. Basically I am not able to click that shape. I would appreciate any suggestions to solve this problem. Thanks in advance.

Edit 1: Adding a new picture for problem elaboration:

enter image description here

tenorsax
  • 21,123
  • 9
  • 60
  • 107
Srvnti
  • 3
  • 4
  • If you comment out `curve.setPaint` you will have a curve only (not filled path), and the tooltip would work fine as the curve is above the rectangle. Look at `PInputEvent.getPickedNode()` if you need to get the node that is currently picked as nodes may obstruct each other. Also check `PPickPath`. – tenorsax Nov 08 '21 at 18:18
  • Thanks @tenorsax for replying. I already tried without the curve.setPaint(). I observed that mouse over on the gray area actually shows "curve". Thats when I changed the default color of the curve region to gray to show it explicitly. I checked the PPickPath when clicked in the gray region. The PPickPath's nodeStack shows only the curve and not the underlying rectangle. `pickPath = {PPickPath@2084} nodeStack = {PStack@2086} size = 3 0 = {PCamera@1991} 1 = {PLayer@2038} 2 = {PPath$Float@1663}` – Srvnti Nov 09 '21 at 03:28
  • I think I am misinterpreting your question. Please clarify what you are trying to achieve. Calling `setPaint` fills the `PPath` node. When you click on 'curve' the 'node 2' will not appear in the pickpath because 'curve' is not a child of 'node 2'. To get to "node 2" when you click on the "curve" you would call `pickPath.nextPickedNode()`. – tenorsax Nov 09 '21 at 18:59
  • Although what I am looking for is different, your tip helped me to solve part of the problem i.e. "If there is another smaller shape placed in between the huge overlapping area of these curves, I am not able to get any events for that shape. Basically I am not able to click that shape." - by using pickPath.nextPickedNode(). Many thanks for that. – Srvnti Nov 10 '21 at 10:23
  • Solution to problem mentioned in previous comment: By using pickPath.nextPickedNode(), I am checking if there are any more objs lying beneath, if so, grab the shape which is of interest. – Srvnti Nov 10 '21 at 10:55
  • The other part of my problem is: if I have overlapping curves (all separate, no parent-child relationship) like one curve falling within another. Assuming the outer curve is drawn in the end, over the inner curves. In this case, tooltip of inner curves is not shown due to overlap. I want to show tooltip of actual inner curve I am hovering over rather than the outer curve i.e show the tooltip of the curve to which the mouse pointer is closer to rather than going by the PBounds of the object. (Edited the question to add a picture illustrating this scenario). Hopefully I am more clear now :-) TIA – Srvnti Nov 10 '21 at 11:13
  • If the paint is null and you only have an outline of the curves, then the tooltips should work as you describe. However, If the objects are opaque then only the top object is picked. You could implement the tooltip mechanism the way it suits your scenario. For example, if you are over several objects that obscure each other you can display a combined tooltip of these objects. – tenorsax Nov 10 '21 at 21:10
  • Bingo!! This is what I was looking for.. **setPaint(null)** - worked like a charm. Appreciate your help @tenorsax. Many thanks!!! Not sure how to mark this as answer for my question. Pls help with that. – Srvnti Nov 12 '21 at 07:28
  • I am glad it helped you! I made the last comments an answer, you may accept it if you wish. – tenorsax Nov 12 '21 at 18:30

1 Answers1

1

If the paint is null and you only have an outline of the curves, then the tooltips should work as you describe. However, If the objects are opaque then only the top object is picked. You could implement the tooltip mechanism the way it suits your scenario. For example, if you are over several objects that obscure each other you can display a combined tooltip of these objects.

tenorsax
  • 21,123
  • 9
  • 60
  • 107