/******************************************************************************* * Copyright (c) 2011, 2015 Frank Appel and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Frank Appel - initial API and implementation * EclipseSource - ongoing development ******************************************************************************/ package org.eclipse.rap.rwt.internal.textsize; import org.eclipse.rap.rwt.internal.lifecycle.LifeCycleUtil; import org.eclipse.rap.rwt.internal.service.ContextProvider; import org.eclipse.rap.rwt.internal.service.ServiceStore; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.internal.widgets.ControlUtil; import org.eclipse.swt.internal.widgets.IDisplayAdapter; import org.eclipse.swt.internal.widgets.IShellAdapter; import org.eclipse.swt.internal.widgets.WidgetTreeUtil; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; class TextSizeRecalculation { static final String TEMPORARY_RESIZE = TextSizeRecalculation.class.getName() + "#temporaryResize"; static final String KEY_SCROLLED_COMPOSITE_CONTENT_SIZE = "org.eclipse.rap.content-size"; static final String KEY_SCROLLED_COMPOSITE_ORIGIN = "org.eclipse.rap.sc-origin"; static final int RESIZE_OFFSET = 1000; static void execute() { for( Shell shell : getShells() ) { forceShellRecalculations( shell ); } } private static void forceShellRecalculations( Shell shell ) { boolean isPacked = ControlUtil.getControlAdapter( shell ).isPacked(); Rectangle boundsBuffer = shell.getBounds(); bufferScrolledCompositeOrigins( shell ); clearLayoutBuffers( shell ); setTemporaryResize( true ); enlargeShell( shell ); enlargeScrolledCompositeContent( shell ); setTemporaryResize( false ); clearLayoutBuffers( shell ); markLayoutNeeded( shell ); rePack( shell ); restoreScrolledCompositeOrigins( shell ); restoreShellSize( shell, boundsBuffer, isPacked ); } private static void rePack( Shell shell ) { WidgetTreeUtil.accept( shell, new RePackVisitor() ); } private static void clearLayoutBuffers( Shell shell ) { WidgetTreeUtil.accept( shell, new ClearLayoutBuffersVisitor() ); } private static void markLayoutNeeded( Shell shell ) { WidgetTreeUtil.accept( shell, new MarkLayoutNeededVisitor() ); } private static void bufferScrolledCompositeOrigins( Shell shell ) { WidgetTreeUtil.accept( shell, new BufferScrolledCompositeOriginsVisitor() ); } private static void enlargeScrolledCompositeContent( Shell shell ) { WidgetTreeUtil.accept( shell, new EnlargeScrolledCompositeContentVisitor() ); } private static void restoreScrolledCompositeOrigins( Shell shell ) { WidgetTreeUtil.accept( shell, new RestoreScrolledCompositeOriginsVisitor() ); } private static void restoreShellSize( Shell shell, Rectangle bufferedBounds, boolean isPacked ) { if( isPacked ) { shell.pack(); ControlUtil.getControlAdapter( shell ).clearPacked(); } else { setShellSize( shell, bufferedBounds ); } } private static void enlargeShell( Shell shell ) { Rectangle bounds = shell.getBounds(); int xPos = bounds.x; int yPos = bounds.y; int width = bounds.width + RESIZE_OFFSET; int height = bounds.height + RESIZE_OFFSET; setShellSize( shell, new Rectangle( xPos, yPos, width, height ) ); } private static Shell[] getShells() { return getShells( LifeCycleUtil.getSessionDisplay() ); } private static Shell[] getShells( Display display ) { return display.getAdapter( IDisplayAdapter.class ).getShells(); } private static void setShellSize( Shell shell, Rectangle bounds ) { shell.getAdapter( IShellAdapter.class ).setBounds( bounds ); } private static void setTemporaryResize( boolean value ) { ServiceStore serviceStore = ContextProvider.getServiceStore(); if( value ) { serviceStore.setAttribute( TEMPORARY_RESIZE, Boolean.TRUE ); } else { serviceStore.removeAttribute( TEMPORARY_RESIZE ); } } private TextSizeRecalculation() { // prevent instantiation } }