Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Standard Widget Toolkit (SWT) » [SOLVED] Setting limit to Sash position doesn't work on Mac OS X(Setting minimum width to SashForm children)
icon5.gif  [SOLVED] Setting limit to Sash position doesn't work on Mac OS X [message #633984] Wed, 20 October 2010 07:36 Go to next message
Albert Pikus is currently offline Albert PikusFriend
Messages: 70
Registered: October 2009
Member
Hi, everybody,

I have encountered a strange behavior when setting minimum composite width when moving sash. I have two composites inside a SWT.HORIZONTAL style SashForm. When I want to set a limit how far to the right Sash can be moved, I'm using a code, which works on Windows and GTK, but when running this code on Mac OS X (10.6), once the sash is moved to this limit, "West-East" cursor won't appear anymore when hovering with a mouse over it, and Sash cannot be no longer moved. If I resize the shell, cursor reappears and Sash can be moved again.

Here is the snippet that can be used to reproduce this behavior:


import java.lang.reflect.Field;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.Shell;

public class SashFormTest
{
    // Minimum width of right composite
    final static int MIN_WIDTH = 200;
    
    public static void main (String [] args)
    {
        Display display = new Display ();
        
        final Shell shell = new Shell(display);        
        shell.setLayout(new FormLayout());        
        shell.setText("SashFormTest");
        
        final SashForm sashForm = new SashForm(shell, SWT.HORIZONTAL);
        
        sashForm.setLayout(new FormLayout());
        {
            FormData formData = new FormData();
            formData.top = new FormAttachment(0, 0);            
            formData.bottom = new FormAttachment(100, 0);
            formData.left = new FormAttachment(0, 0);            
            formData.right = new FormAttachment(100, 0);
            sashForm.setLayoutData(formData);
        }
        
        Composite leftComposite = new Composite(sashForm, SWT.NONE);
        leftComposite.setLayout(new FormLayout());
        {
            FormData formData = new FormData();
            formData.top = new FormAttachment(0, 0);            
            formData.bottom = new FormAttachment(100, 0);
            formData.left = new FormAttachment(0, 0);            
            formData.right = new FormAttachment(100, 0);
            leftComposite.setLayoutData(formData);
        }
        leftComposite.setBackground(new Color(shell.getDisplay(), 255, 0, 0));
                
        Composite rightComposite = new Composite(sashForm, SWT.NONE);        
        rightComposite.setLayout(new FormLayout());
        {
            FormData formData = new FormData();
            formData.top = new FormAttachment(0, 0);            
            formData.bottom = new FormAttachment(100, 0);
            formData.left = new FormAttachment(0, 0);            
            formData.right = new FormAttachment(100, 0);
            rightComposite.setLayoutData(formData);
        }
        rightComposite.setBackground(new Color(shell.getDisplay(), 0, 255, 0));
        
        sashForm.setWeights(new int[] {30, 70});
        
        shell.setSize(500, 200);
        
        // Get sashes using reflection
        Sash[] sashes = getSashes(sashForm);
        
        Sash sash = sashes[0];
        
        // Composite on the right side of the sash
        // is always at least 200 px wide, when sash is moved
        sash.addSelectionListener(new SelectionAdapter ()
        {                     
            public void widgetSelected(SelectionEvent event)
            {   
                if (event.x >= shell.getBounds().width - MIN_WIDTH)
                {   
                    int shellWidth = shell.getBounds().width;
                    
                    // Calculate new ratio for sashes weights                    
                    double ratio = (double)shellWidth / Math.abs(shell.getBounds().width - MIN_WIDTH);                                            
                    double percent = 100 / ratio;                  
                    
                    int percentRounded = (int) Math.floor(percent);
                    
                    sashForm.setWeights(new int[]{percentRounded, 100 - percentRounded});                                      
                    sashForm.layout();                      
                }
            }
        });
        
        shell.open ();
        
        while (!shell.isDisposed ())
        {
            if (!display.readAndDispatch())
            {
                display.sleep ();
            }   
        }
        display.dispose ();
    }
    
    private static Sash[] getSashes(SashForm sf)
    {
        Field fields[] = sf.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; ++i)
        {            
            if (fields[i].getName().equals("sashes"))
            {   
                try
                {   
                    fields[i].setAccessible(true);
                    return (Sash[]) fields[i].get(sf);
                }
                catch (IllegalAccessException e)
                {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}



I'm not sure if there is any better way to achieve this, but I couldn't find any other means to limit how far a Sash can be moved. Nevertheless, I can't see a reason why this wouldn't work. Am I missing something obvious here? Any suggestion would be helpful,


best regards,

Albert




[Updated on: Fri, 22 October 2010 12:24]

Report message to a moderator

Re: Setting limit to Sash position doesn't work on Mac OS X [message #634563 is a reply to message #633984] Fri, 22 October 2010 08:54 Go to previous messageGo to next message
Lakshmi ShanmugamFriend
Messages: 275
Registered: July 2009
Location: India
Senior Member
Hi,

Moving the sashForm.layout() inside display.asyncExec() seems to fix the problem.

Since this doesn't work only on Mac as it is, it may be a bug.
I suggest you to open a bug under SWT --> https://bugs.eclipse.org/bugs/enter_bug.cgi?product=Platform &component=SWT

Another way to do this is to use a controlListener to the composite and do the weight computation when control is resized.
rightComposite.addControlListener(new ControlListener() {
public void controlResized(ControlEvent e) {
if (rightComposite.getSize().x <= MIN_WIDTH) {
// weight computation code here
}
}}
note: SashForm is a composite, so you can use sashForm.getChildren() to get the sash (instead of using reflection).



Lakshmi P Shanmugam
Re: Setting limit to Sash position doesn't work on Mac OS X [message #634602 is a reply to message #634563] Fri, 22 October 2010 12:22 Go to previous messageGo to next message
Albert Pikus is currently offline Albert PikusFriend
Messages: 70
Registered: October 2009
Member
Hi, Lakshmi,

thank you for your quick answer, putting sashForm.layout(); inside an asyncExec() really fixed the problem. I'll report a bug on Eclipse Bugzilla.

I didn't look at the SashForm hierarchy, so I was completely unaware that SashForm is a Composite and I was using reflection instead of simple call to SashForm.getChildren() in order to get the sash.


Thanks again, best regards,

Albert

[Updated on: Fri, 22 October 2010 14:09]

Report message to a moderator

Re: [SOLVED] Setting limit to Sash position doesn't work on Mac OS X [message #639945 is a reply to message #633984] Thu, 18 November 2010 13:52 Go to previous message
Albert Pikus is currently offline Albert PikusFriend
Messages: 70
Registered: October 2009
Member
Hi,Lakshmi,

I'm sorry for the late reply, I totally forgot to report a bug on Eclipse Bugzilla. I reported it today, please see:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=330566

I searched Bugzilla before reporting and didn't find any similar entry.


Best regards,

Albert
Previous Topic:strange index update with virtual table
Next Topic:Context menu problems in Windows 7 and Linux
Goto Forum:
  


Current Time: Mon Oct 23 13:47:24 GMT 2017

Powered by FUDForum. Page generated in 0.01805 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software