/******************************************************************************* * Copyright (c) 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.internal.layout; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CBanner; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.CoolBar; import org.eclipse.swt.widgets.Layout; /** * This class wraps a control with a complex computeSize method. It uses caching * to reduce the number of times the control's computeSize method is called. This * allows controls (such as Coolbars and wrapping text) with slow computeSize * operations to be used inside layouts and composites that use inefficient caching. *

* For example, you want to use Coolbar A inside composite B. Rather than making A * a direct child of B, place it inside a CacheWrapper and insert the CacheWrapper * into B. Any layout data that would normally be attached to the control itself * should be attached to the wrapper instead: *

* * * // Unoptimized code * Toolbar myToolbar = new Toolbar(someParent, SWT.WRAP); * myToolbar.setLayoutData(someLayoutData); * * * * // Optimized code * CacheWrapper myWrapper = new CacheWrapper(someParent); * Toolbar myToolbar = new Toolbar(myWrapper.getControl(), SWT.WRAP); * myWrapper.getControl().setLayoutData(someLayoutData); * *

* CacheWrapper creates a Composite which should have exactly one child: the control * whose size should be cached. Note that CacheWrapper does NOT respect the flushCache * argument to layout() and computeSize(). This is intentional, since the whole point of * this class is to workaround layouts with poor caching, and such layouts will typically * be too eager about flushing the caches of their children. However, this means that you * MUST manually call flushCache() whenver the child's preferred size changes (and before * the parent is layed out). *

* * @since 3.0 */ public class CacheWrapper { private Composite proxy; private SizeCache cache = new SizeCache(); private Rectangle lastBounds = new Rectangle(0,0,0,0); private class WrapperLayout extends Layout implements ICachingLayout { protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { Control[] children = composite.getChildren(); if (children.length != 1) { return new Point(0,0); } //redpath //The SWT.DEFAULT for CoolBar is SWT.DEFAULT_WIDTH which is //64 pels which is too much and hence why you have so much //margin. System.out.println("redpath edited WrapperLayout() in CacheWrapper.java"); Point temp = cache.computeSize(wHint,hHint); if ( (hHint==SWT.DEFAULT) && (cache.getControl() instanceof CoolBar)) temp = cache.computeSize(wHint,24); cache.setControl(children[0]); return temp; //return cache.computeSize(wHint, hHint); } protected void layout(Composite composite, boolean flushCache) { Control[] children = composite.getChildren(); if (children.length != 1) { return; } Control child = children[0]; Rectangle newBounds = composite.getClientArea(); if (!newBounds.equals(lastBounds)) { child.setBounds(newBounds); lastBounds = newBounds; } } /* (non-Javadoc) * @see org.eclipse.ui.internal.layout.ICachingLayout#flush(org.eclipse.swt.widgets.Control) */ public void flush(Control dirtyControl) { flushCache(); } } /** * Creates a CacheWrapper with the given parent * * @param parent */ public CacheWrapper(Composite parent) { proxy = new Composite(parent, SWT.NONE); proxy.setLayout(new WrapperLayout()); } /** * Flush the cache. Call this when the child has changed in order to force * the size to be recomputed in the next resize event. */ public void flushCache() { cache.flush(); } /** * Use this as the parent of the real control. * * @return the proxy contol. It should be given exactly one child. */ public Composite getControl() { return proxy; } }