/******************************************************************************* * Copyright © 2008, 2013 IBM Corporation 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: * IBM Corporation - initial API and implementation * *******************************************************************************/ package org.eclipse.edt.ide.rui.visualeditor.internal.widget.layout; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.eclipse.edt.ide.rui.visualeditor.internal.editor.EvDesignOverlay; import org.eclipse.edt.ide.rui.visualeditor.internal.editor.EvDesignOverlayDropLocation; import org.eclipse.edt.ide.rui.visualeditor.internal.widget.WidgetPart; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; public class RootWidgetLayout extends AbstractWidgetLayout { public void setupDropLocations(Collection listDropLocations) { List listChildren = widgetRoot.getChildren(); if( listChildren.size() > 0 ){ // First child //------------ WidgetPart widget = (WidgetPart)listChildren.get( 0 ); if( widget != _widgetDragging ) { String strType = widget.getTypeName(); Rectangle rectBounds = widget.getBounds(); if( strType.equalsIgnoreCase( "Box" ) == true ) { // Top side //--------- EvDesignOverlayDropLocation location = new EvDesignOverlayDropLocation(); location.setBounds( rectBounds.x, rectBounds.y, rectBounds.width - 1, EvDesignOverlay.DROP_THICKNESS ); location.iIndex = 0; location.iLocation = SWT.TOP; location.widgetParent = widgetRoot; listDropLocations.add( location ); } else { // Left side //---------- EvDesignOverlayDropLocation location = new EvDesignOverlayDropLocation(); location.setBounds( rectBounds.x, rectBounds.y, DROP_THICKNESS, rectBounds.height - 1 ); location.iIndex = 0; location.iLocation = SWT.LEFT; location.widgetParent = widgetRoot; listDropLocations.add( location ); } } // Middle children //---------------- for( int i=0; i<listChildren.size() - 1; ++i ){ WidgetPart widgetA = (WidgetPart)listChildren.get( i ); WidgetPart widgetB = (WidgetPart)listChildren.get( i + 1 ); if( widgetA != _widgetDragging && widgetB != _widgetDragging ) { Rectangle rectA = widgetA.getBounds(); String strTypeA = widgetA.getTypeName(); boolean bBoxA = strTypeA.equalsIgnoreCase( "Box" ) == true; Rectangle rectB = widgetB.getBounds(); String strTypeB = widgetB.getTypeName(); boolean bBoxB = strTypeB.equalsIgnoreCase( "Box" ) == true; // Box next to Box //---------------- if( bBoxA && bBoxB ) { // Between //-------- EvDesignOverlayDropLocation location = new EvDesignOverlayDropLocation(); location.rectDrop.y = rectA.y + rectA.height; location.rectDrop.x = Math.min( rectA.x, rectB.x ); location.rectDrop.height = rectB.y - ( rectA.y + rectA.height ); location.rectDrop.height = Math.max( location.rectDrop.height, DROP_THICKNESS ); location.rectDrop.width = Math.max( rectA.x + rectA.width - 1, rectB.x + rectB.width - 1 ) - location.rectDrop.x; location.rectDrop.width = Math.max( location.rectDrop.width, DROP_THICKNESS ); location.iIndex = i + 1; location.iLocation = SWT.CENTER; location.widgetParent = widgetRoot; listDropLocations.add( location ); } // Box next to non-Box: Left side of non-Box //------------------------------------------ else if( bBoxA && !bBoxB ) { EvDesignOverlayDropLocation location = new EvDesignOverlayDropLocation(); location.setBounds( rectB.x, rectB.y, DROP_THICKNESS, rectB.height - 1 ); location.iIndex = i + 1; location.iLocation = SWT.CENTER; location.widgetParent = widgetRoot; listDropLocations.add( location ); } // Non-Box next to Box: Right side of non-Box //------------------------------------------- else if( !bBoxA && bBoxB ) { EvDesignOverlayDropLocation location = new EvDesignOverlayDropLocation(); location.setBounds( rectA.x + rectA.width - 1 - DROP_THICKNESS, rectA.y, DROP_THICKNESS, rectA.height - 1 ); location.iIndex = i + 1; location.iLocation = SWT.CENTER; location.widgetParent = widgetRoot; listDropLocations.add( location ); } // Non-Boxes: Between //------------------- else {// !BoxA && !BoxB EvDesignOverlayDropLocation location = new EvDesignOverlayDropLocation(); location.rectDrop.x = rectA.x + rectA.width; location.rectDrop.y = Math.min( rectA.y, rectB.y ); location.rectDrop.width = rectB.x - ( rectA.x + rectA.width ); if( location.rectDrop.width < 0 ){ location.rectDrop.width = DROP_THICKNESS; location.rectDrop.height = rectA.height; } else{ location.rectDrop.height = Math.max( rectA.y + rectA.height - 1, rectB.y + rectB.height - 1 ) - location.rectDrop.y; location.rectDrop.height = Math.max( location.rectDrop.height, DROP_THICKNESS ); } location.iIndex = i + 1; location.iLocation = SWT.CENTER; location.widgetParent = widgetRoot; listDropLocations.add( location ); } } } // Last child //----------- widget = (WidgetPart)listChildren.get( listChildren.size() - 1 ); if( widget != _widgetDragging ) { String strType = widget.getTypeName(); Rectangle rectBounds = widget.getBounds(); if( strType.equalsIgnoreCase( "Box" ) == true ) { // Bottom side //------------ EvDesignOverlayDropLocation location = new EvDesignOverlayDropLocation(); location.setBounds( rectBounds.x, rectBounds.y + rectBounds.height - 1 - DROP_THICKNESS, rectBounds.width - 1, DROP_THICKNESS ); location.iIndex = listChildren.size(); location.iLocation = SWT.BOTTOM; location.widgetParent = widgetRoot; listDropLocations.add( location ); } else { // Right side //----------- EvDesignOverlayDropLocation location = new EvDesignOverlayDropLocation(); location.setBounds( rectBounds.x + rectBounds.width - 1 - DROP_THICKNESS, rectBounds.y, DROP_THICKNESS, rectBounds.height - 1 ); location.iIndex = listChildren.size(); location.iLocation = SWT.RIGHT; location.widgetParent = widgetRoot; listDropLocations.add( location ); } } } // Below all other widgets //------------------------ setupDropLocationsForRootEnd( widgetRoot, listDropLocations ); } /** * Creates a location below the other widgets where a person can drop a new or existing widget for a RUI Handler */ protected void setupDropLocationsForRootEnd( WidgetPart widgetRoot, Collection listDropLocations ) { // If the widget being dragged is the last child, it cannot be added after itself //------------------------------------------------------------------------------- List listRootChildren = widgetRoot.getChildren(); if( _widgetDragging != null && listRootChildren.get( listRootChildren.size() - 1 ) == _widgetDragging ) return; // Compute union of child widgets //------------------------------- Rectangle rectUnion = new Rectangle( 0, 0, 0, 0 ); Iterator iterWidgets = getWidgets(); while( iterWidgets.hasNext() == true ){ WidgetPart widget = (WidgetPart)iterWidgets.next(); rectUnion = rectUnion.union( widget.getBounds() ); } // Compute bounds which is the client area that is showing minus margins //---------------------------------------------------------------------- int iMargin = 16; Rectangle rectBounds = parentComposite.getClientArea(); Point ptOrigin = parentComposite.getOrigin(); rectBounds.x = ptOrigin.x + iMargin; rectBounds.y = ptOrigin.y + iMargin; rectBounds.width -= ( iMargin * 2 + 1 ); rectBounds.height -= ( iMargin * 2 + 1 ); rectBounds.y = rectUnion.y + rectUnion.height + 16; rectBounds.height = Math.max( rectBounds.height, 32 ); // Create the drop location //------------------------- EvDesignOverlayDropLocation location = new EvDesignOverlayDropLocation(); location.setBounds( rectBounds.x, rectBounds.y, rectBounds.width, rectBounds.height ); location.iIndex = widgetRoot.getChildren().size(); location.iLocation = SWT.CENTER; location.widgetParent = widgetRoot; listDropLocations.add( location ); } }