How to determine the correct position of an Image inside of a CTabItem

196 Views Asked by At

I add some CTabItems with Images to a CTabFolder:

CTabFolder tabFolder = new CTabFolder(someSection, SWT.BORDER);
ImageDescriptor deleteImageDesc = sharedImages.getImageDescriptor(ISharedImages.IMG_ETOOL_DELETE);
Image deleteImage = deleteImageDesc.createImage();
CTabItem tabItem = new CTabItem(tabFolder, SWT.NONE);
tabItem.setImage(deleteImage);
// add more tabs...

tabItems

Then I want to create a ToolTip which appears if user moves mouse over a deleteImage.

ToolTip deleteToolTip = new ToolTip(getShell(), SWT.BALOON);
deleteToolTip.setMessage("Delete");
tabFolder.addMouseTrackListener(new MouseTrackAdapter()
{
    @Override
    public void mouseHover(MouseEvent e)
    {
        toolTip.setLocation(tabFolder.toDisplay(e.x, e.y));
        toolTip.setVisible(doesAnyOfTabImagesContainPoint(mousePosition));
    }
});

To implement method doesAnyOfTabImagesContainPoint I need to determine the position of every deleteImage. Since CTabItem isn't a Control I cannot use method toDisplay. I try to solve this by manually determining the position of deleteImage relative to tabFolder. It would help because the mouse position held by MouseEvent is also relative to tabFolder.

private boolean doesAnyOfTabImagesContainPoint(Point p)
{
    for (CTabItem tabItem : tabFolder.getItems())
    {
        Image i = tabItem.getImage();
        Rectangle tabItemBounds = tabItem.getBounds();
        Rectangle imageBounds = i.getBounds();
        imageBounds.x += tabItemBounds.x;
        imageBounds.y += tabItemBounds.y;
        if (imageBounds.contains(p))
            return true;
    }
    return false;
}

The requirement for working this properly is that Rectangle returned by i.getBounds() has correct location relative to tabItem. However it returns (0, 0, 16, 16) which cannot be right.

A dirty way to fix this would be to just add some constants:

imageBounds.x += bsTabBounds.x + 4;
imageBounds.y += bsTabBounds.y + 3;

But I am wondering if there's better way. I'm trying to investigate how CTabFolder positions images of the tabs but without success by now. Any help would be appreciated. Thanks in advance.

edit: for testing purposes here's the extracted image which i get from ISharedImages modified to see its border: delete.png

1

There are 1 best solutions below

14
On

Give the code below a shot. It's based on my answer here.

public static void main(String[] args)
{
    Display display = Display.getDefault();
    final Shell shell = new Shell(display);
    shell.setLayout(new FillLayout());

    final TabFolder folder = new TabFolder(shell, SWT.NONE);

    TabItem item = new TabItem(folder, SWT.NONE);
    item.setImage(display.getSystemImage(SWT.ICON_ERROR));
    item.setText("Text");

    folder.addListener(SWT.MouseMove, event -> {
        TabFolder curFolder = (TabFolder) event.widget;
        Point eventLocation = new Point(event.x, event.y);
        TabItem theItem = curFolder.getItem(eventLocation);

        if (theItem == null)
            return;

        Image image = theItem.getImage();

        if (eventLocation.x >= curFolder.getClientArea().x + theItem.getBounds().x + image.getBounds().x
                && eventLocation.x <= curFolder.getClientArea().x + theItem.getBounds().x + image.getBounds().x + image.getBounds().width
                && eventLocation.y >= theItem.getBounds().y + image.getBounds().y
                && eventLocation.y <= theItem.getBounds().y + image.getBounds().y + image.getBounds().height)
        {
            System.out.println("show tooltip");
        }
    });


    shell.pack();
    shell.open();
    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
            display.sleep();
    }
}

I've tested it on Windows 7 and it seems to be working fine.