/******************************************************************************* * Copyright (c) 2002, 2009 Innoopract Informationssysteme GmbH. * 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: * Innoopract Informationssysteme GmbH - initial API and implementation * EclipseSource - ongoing development ******************************************************************************/ package org.eclipse.swt.internal.widgets.coolitemkit; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import org.eclipse.rwt.internal.lifecycle.IRenderRunnable; import org.eclipse.rwt.internal.lifecycle.JSConst; import org.eclipse.rwt.internal.service.ContextProvider; import org.eclipse.rwt.lifecycle.*; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.internal.widgets.*; import org.eclipse.swt.internal.widgets.coolbarkit.CoolBarLCA; import org.eclipse.swt.widgets.*; public class CoolItemLCA extends AbstractWidgetLCA { private static final String SET_CONTROL = "setControl"; static final String PROP_CONTROL = "control"; /* (intentionally not JavaDoc'ed) * Unnecesary to call ItemLCAUtil.preserve, CoolItem does neither use text * nor image */ public void preserveValues( final Widget widget ) { CoolItem coolItem = ( CoolItem )widget; IWidgetAdapter adapter = WidgetUtil.getAdapter( coolItem ); adapter.preserve( PROP_CONTROL, coolItem.getControl() ); adapter.preserve( Props.BOUNDS, coolItem.getBounds() ); WidgetLCAUtil.preserveCustomVariant( coolItem ); } public void readData( final Widget widget ) { // TODO [rh] clean up this mess final CoolItem coolItem = ( CoolItem )widget; HttpServletRequest request = ContextProvider.getRequest(); String movedWidgetId = request.getParameter( JSConst.EVENT_WIDGET_MOVED ); if( WidgetUtil.getId( coolItem ).equals( movedWidgetId ) ) { String value = WidgetLCAUtil.readPropertyValue( coolItem, "bounds.x" ); final int x = Integer.parseInt( value ); ProcessActionRunner.add( new Runnable() { public void run() { moveItem( coolItem, x ); } } ); } } public void renderInitialization( final Widget widget ) throws IOException { CoolItem coolItem = ( CoolItem )widget; JSWriter writer = JSWriter.getWriterFor( widget ); Object[] args = new Object[] { jsOrientation( coolItem ) }; writer.newWidget( "org.eclipse.swt.widgets.CoolItem", args ); writer.setParent( WidgetUtil.getId( coolItem.getParent() ) ); writer.set( "minWidth", 0 ); writer.set( "minHeight", 0 ); } public void renderChanges( final Widget widget ) throws IOException { CoolItem coolItem = ( CoolItem )widget; writeBounds( coolItem ); writeControl( coolItem ); writeLocked( coolItem ); WidgetLCAUtil.writeCustomVariant( coolItem ); } public void renderDispose( final Widget widget ) throws IOException { JSWriter writer = JSWriter.getWriterFor( widget ); writer.dispose(); } ////////////////// // Helping methods private static void writeBounds( final CoolItem coolItem ) throws IOException { Rectangle bounds = coolItem.getBounds(); WidgetLCAUtil.writeBounds( coolItem, coolItem.getParent(), bounds ); if( WidgetLCAUtil.hasChanged( coolItem, Props.BOUNDS, bounds, null ) ) { JSWriter writer = JSWriter.getWriterFor( coolItem ); writer.call( "updateHandleBounds", null ); } } private static void writeLocked( final CoolItem coolItem ) throws IOException { JSWriter writer = JSWriter.getWriterFor( coolItem ); CoolBar parent = coolItem.getParent(); String prop = CoolBarLCA.PROP_LOCKED; Boolean oldValue = Boolean.valueOf( parent.getLocked() ); Boolean defValue = Boolean.FALSE; if( WidgetLCAUtil.hasChanged( parent, prop, oldValue, defValue ) ) { writer.set( "locked", parent.getLocked() ); } } private static void writeControl( final CoolItem coolItem ) throws IOException { Control control = coolItem.getControl(); if( WidgetLCAUtil.hasChanged( coolItem, PROP_CONTROL, control, null ) ) { final JSWriter writer = JSWriter.getWriterFor( coolItem ); final Object[] args = new Object[] { control }; if( control != null ) { // defer call since controls are rendered after items WidgetAdapter adapter = ( WidgetAdapter )WidgetUtil.getAdapter( control ); adapter.setRenderRunnable( new IRenderRunnable() { public void afterRender() throws IOException { writer.call( SET_CONTROL, args ); } } ); } else { writer.call( SET_CONTROL, args ); } } } private static JSVar jsOrientation( final CoolItem coolItem ) { JSVar orientation; if( ( coolItem.getStyle() & SWT.VERTICAL ) != 0 ) { orientation = JSConst.QX_CONST_VERTICAL_ORIENTATION; } else { orientation = JSConst.QX_CONST_HORIZONTAL_ORIENTATION; } return orientation; } /////////////////////////////// // Methods for item re-ordering private static void moveItem( final CoolItem coolItem, final int newX ) { CoolItem[] items = coolItem.getParent().getItems(); boolean changed = false; int newOrder = -1; int maxX = 0; int minX = 0; for( int i = 0; newOrder == -1 && i < items.length; i++ ) { CoolItem item = items[ i ]; Rectangle itemBounds = item.getBounds(); if( item != coolItem && itemBounds.contains( newX, itemBounds.y ) ) { if( coolItem.getBounds().x > newX ) { newOrder = i + 1; } else { newOrder = i; } changed = changeOrder( coolItem, newOrder ); } maxX = Math.max( maxX, itemBounds.x + itemBounds.width ); minX = Math.min( minX, itemBounds.x ); } if( newOrder == -1 && newX > maxX ) { // item was moved after the last item int last = coolItem.getParent().getItemCount() - 1; changed = changeOrder( coolItem, last ); } else if( newOrder == -1 && newX < minX ) { // item was moved before the first item changed = changeOrder( coolItem, 0 ); } // In case an item was moved but that didn't cause it to change its order, // we need to let it 'snap back' to its previous position if( !changed ) { // TODO [rh] HACK: a decent solution would mark the item as 'bounds // changed' and that mark could be evaluated by writeBounds. // A more flexible writeBounds implementation on WidgetLCAUtil is // necessary therefore. IWidgetAdapter adapter = WidgetUtil.getAdapter( coolItem ); adapter.preserve( Props.BOUNDS, null ); } } private static boolean changeOrder( final CoolItem coolItem, final int newOrder ) { boolean result; CoolBar coolBar = coolItem.getParent(); int itemIndex = coolBar.indexOf( coolItem ); int[] itemOrder = coolBar.getItemOrder(); int length = itemOrder.length; int[] targetOrder = new int[ length ]; int index = 0; if ( itemIndex != newOrder ) { for( int i = 0; i < length; i++ ) { if( i == newOrder ) { targetOrder[ i ] = itemOrder[ itemIndex ]; } else { if( index == itemIndex ) { index++; } targetOrder[ i ] = itemOrder[ index ]; index++; } } Object adapter = coolBar.getAdapter( ICoolBarAdapter.class ); ICoolBarAdapter cba = (ICoolBarAdapter) adapter; cba.setItemOrder( targetOrder ); result = true; } else { result = false; } return result; } }