Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 93977 - SWT Tree computeSize is broken
Summary: SWT Tree computeSize is broken
Status: RESOLVED DUPLICATE of bug 49724
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.0.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Veronika Irvine CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-05-06 14:41 EDT by Vitaliy Stulski CLA
Modified: 2005-05-09 15:47 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vitaliy Stulski CLA 2005-05-06 14:41:52 EDT
Eclipse SWT Tree control does not include its visible children when computing
the control size. When a tree control is inside a section part and the tree node
is expanded the section part is not being resized properly. What happens after
tree node expansion - layout calls computeSize for the tree and computeSize for
the tree does not take into account newly expanded tree node(s). I attached an
interim fix for the problem we did in our application.


===============================================================================
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;

public class SAPTree extends Tree {

    static boolean useBugFix = true;

    public SAPTree(Composite parent, int style) {
        super(parent, style);
    }

    public Point computeSize(int wHint, int hHint, boolean changed) {
        if (useBugFix) {
            try {
                checkWidget();
                return OSSAPTree.computeSize(this, wHint, hHint, changed);
            } catch (Throwable ignore) {
                useBugFix = false;
            }
        }
        return super.computeSize(wHint, hHint, changed);
    }
}
===============================================================================
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Tree;

import org.eclipse.swt.internal.win32.OS;
import org.eclipse.swt.internal.win32.RECT;

public class OSSAPTree {

    public OSSAPTree() {
        super();
    }

    /**
     * Recursivelly computes the size of the give item and it's visible children
     * 
     * @param hItem
     * @return
     */
    static Point internalComputeSize(Tree tree,int hItem) {
        int width = 0, height = 0;
        RECT rect = new RECT();
        Point childSize;
        while (hItem != 0) {
            rect.left = hItem;
            if (OS.SendMessage(tree.handle, OS.TVM_GETITEMRECT, 1, rect) != 0) {
                width = Math.max(width, rect.right);
                height += rect.bottom - rect.top;

                // compute children size
                int hChild = OS.SendMessage(tree.handle, OS.TVM_GETNEXTITEM,
OS.TVGN_CHILD, hItem);
                if (hChild != 0) {
                    childSize = internalComputeSize(tree, hChild);
                    width = Math.max(width, childSize.x);
                    height += childSize.y;
                }
            }
            hItem = OS.SendMessage(tree.handle, OS.TVM_GETNEXTITEM,
OS.TVGN_NEXT, hItem);
        }

        return new Point(width, height);
    }

    /* (non-Javadoc)
     * @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean)
     */
    static Point computeSize(Tree tree, int wHint, int hHint, boolean changed) {
        int width = 0, height = 0;
        int hItem = OS.SendMessage(tree.handle, OS.TVM_GETNEXTITEM,
OS.TVGN_ROOT, 0);

        // Compute the size of the root item and all visible children
        Point p = internalComputeSize(tree,  hItem);
        
        width = p.x;
        height = p.y;
        if (width == 0)
            width = 64;
        if (height == 0)
            height = 64;
        if (wHint != SWT.DEFAULT)
            width = wHint;
        if (hHint != SWT.DEFAULT)
            height = hHint;
        int border = tree.getBorderWidth();
        width += border * 2;
        height += border * 2;
        if ((tree.getStyle() & SWT.V_SCROLL) != 0) {
            width += OS.GetSystemMetrics(OS.SM_CXVSCROLL);
        }
        if ((tree.getStyle() & SWT.H_SCROLL) != 0) {
            height += OS.GetSystemMetrics(OS.SM_CYHSCROLL);
        }
        return new Point(width, height);
    }
}
===============================================================================
Comment 1 Vitaliy Stulski CLA 2005-05-06 14:44:10 EDT
It's not only 3.0.1 issue. The same issue exists in 3.0.2 and 3.1 (I checked it
with M6 build). More over our fix does not work with 3.1 because it's impossible
to inherit Tree class.
Comment 2 Steve Northover CLA 2005-05-09 10:07:11 EDT
SN, VI and GG to discuss.
Comment 3 Veronika Irvine CLA 2005-05-09 11:26:52 EDT
Sounds like a duplicate of bug 49724.
Comment 4 Vitaliy Stulski CLA 2005-05-09 14:54:38 EDT
I've read description of a 49724. I think this issue is not a duplicate. It is
different behavior because in the case I described tree is not being resized
vertically. So instead of taking whole screen like in 49724 it may take only one
line for the only root node (e.g. for XML file display) and this is not right in
my opinion.
Comment 5 Veronika Irvine CLA 2005-05-09 15:34:03 EDT
The first part of Bug 49724 is actually fixed.  I was referring to Bug 49724 
Comment #1: "Leaving bug open for the minute because there are platform 
differences in the behaviour of Tree.computeSize"

*** This bug has been marked as a duplicate of 49724 ***
Comment 6 Vitaliy Stulski CLA 2005-05-09 15:47:30 EDT
(In reply to comment #3)
> *** Bug 93977 has been marked as a duplicate of this bug. ***

Is behavior "Windows/Mac/Motif/Photon - width and height based on root items
only" is the right one? Let the container decide optimal size of the tree based
on a layout selected and correct children size returned by Tree control. This is
critical for us.