Index: graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java =================================================================== RCS file: /cvs/graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java,v retrieving revision 1.77 diff -u -r1.77 RunDialog.java --- graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java 19 Jul 2007 07:15:42 -0000 1.77 +++ graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java 26 Jul 2007 12:40:40 -0000 @@ -35,6 +35,7 @@ "javaone.demo6.LODDemo", "test.action.ActionMapActionTest", "test.action.SelectLockedActionTest", + "test.alignwith.AlignWithClientAreaTest", "test.alignwith.AlignWithMoveGuideLinesTest", "test.alignwith.AlignWithTest", "test.alignwith.AlignWithResizeTest", Index: graph/examples/src/test/alignwith/AlignWithClientAreaTest.java =================================================================== RCS file: graph/examples/src/test/alignwith/AlignWithClientAreaTest.java diff -N graph/examples/src/test/alignwith/AlignWithClientAreaTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ graph/examples/src/test/alignwith/AlignWithClientAreaTest.java 26 Jul 2007 12:40:40 -0000 @@ -0,0 +1,71 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the License at http://www.netbeans.org/cddl.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun + * Microsystems, Inc. All Rights Reserved. + */ + +package test.alignwith; + +import org.netbeans.api.visual.action.ActionFactory; +import org.netbeans.api.visual.action.WidgetAction; +import org.netbeans.api.visual.border.Border; +import org.netbeans.api.visual.border.BorderFactory; +import org.netbeans.api.visual.widget.LabelWidget; +import org.netbeans.api.visual.widget.LayerWidget; +import org.netbeans.api.visual.widget.Scene; +import test.SceneSupport; + +import java.awt.*; + +/** + * @author David Kaspar + */ +public class AlignWithClientAreaTest { + + public static void main (String[] args) { + Scene scene = new Scene (); + + LayerWidget mainLayer = new LayerWidget (scene); + scene.addChild (mainLayer); + LayerWidget interractionLayer = new LayerWidget (scene); + scene.addChild (interractionLayer); + + Border resizeBorder = BorderFactory.createResizeBorder (8); + WidgetAction moveAction = ActionFactory.createAlignWithMoveAction (mainLayer, interractionLayer, null, false); + WidgetAction resizeAction = ActionFactory.createAlignWithResizeAction (mainLayer, interractionLayer, null, false); + + createWidget (mainLayer, 100, 100, "Label 1 - Move, Resize", resizeBorder, resizeAction, moveAction); + createWidget (mainLayer, 200, 150, "Label 2 - Move, Resize", resizeBorder, resizeAction, moveAction); + createWidget (mainLayer, 100, 200, "Label 3 - Move, Resize", resizeBorder, resizeAction, moveAction); + + SceneSupport.show (scene); + } + + + private static void createWidget (LayerWidget mainLayer, int x, int y, String label, Border resizeBorder, WidgetAction resizeAction, WidgetAction moveAction) { + LabelWidget widget = new LabelWidget (mainLayer.getScene (), label); + widget.setAlignment (LabelWidget.Alignment.CENTER); + widget.setVerticalAlignment (LabelWidget.VerticalAlignment.CENTER); + widget.setPreferredLocation (new Point (x, y)); + widget.setOpaque (true); + widget.setBackground (Color.YELLOW); + widget.setBorder (resizeBorder); + widget.getActions ().addAction (resizeAction); + widget.getActions ().addAction (moveAction); + mainLayer.addChild (widget); + } + +} Index: graph/lib/apichanges.xml =================================================================== RCS file: /cvs/graph/lib/apichanges.xml,v retrieving revision 1.24 diff -u -r1.24 apichanges.xml --- graph/lib/apichanges.xml 18 Jul 2007 13:39:40 -0000 1.24 +++ graph/lib/apichanges.xml 26 Jul 2007 12:40:40 -0000 @@ -330,6 +330,21 @@ + + + + Added support to checking AlignWith-actions with client areas + + + + + + AlignWithMoveAction and AlignWithResizeAction allow checking client area of widget (widget boundary without border insets). + There are 4 new methods in ActionFactory class introduces to allow specifying outerBounds parameter. + + + + Index: graph/lib/manifest.mf =================================================================== RCS file: /cvs/graph/lib/manifest.mf,v retrieving revision 1.13 diff -u -r1.13 manifest.mf --- graph/lib/manifest.mf 25 Jun 2007 14:10:16 -0000 1.13 +++ graph/lib/manifest.mf 26 Jul 2007 12:40:40 -0000 @@ -1,4 +1,4 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.api.visual OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/visual/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 2.5 +OpenIDE-Module-Specification-Version: 2.7 Index: graph/lib/src/org/netbeans/api/visual/action/ActionFactory.java =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/api/visual/action/ActionFactory.java,v retrieving revision 1.24 diff -u -r1.24 ActionFactory.java --- graph/lib/src/org/netbeans/api/visual/action/ActionFactory.java 5 Jun 2007 08:43:25 -0000 1.24 +++ graph/lib/src/org/netbeans/api/visual/action/ActionFactory.java 26 Jul 2007 12:40:40 -0000 @@ -191,8 +191,22 @@ * @return the align-with move action */ public static WidgetAction createAlignWithMoveAction (LayerWidget collectionLayer, LayerWidget interractionLayer, AlignWithMoveDecorator decorator) { + return createAlignWithMoveAction (collectionLayer, interractionLayer, decorator, true); + } + + /** + * Creates a align-with move action. + * @param collectionLayer the layer with objects that the alignment is checked against. + * @param interractionLayer the interraction layer where the align-with hint lines are placed + * @param decorator the align-with move decorator + * @param outerBounds if true, then the align-with is check against whole bounds of widgets in collection layer; + * if false, then the align-with is check against client area (widget bounds without border insets + * @return the align-with move action + * @since 2.7 + */ + public static WidgetAction createAlignWithMoveAction (LayerWidget collectionLayer, LayerWidget interractionLayer, AlignWithMoveDecorator decorator, boolean outerBounds) { assert collectionLayer != null; - return createAlignWithMoveAction (new SingleLayerAlignWithWidgetCollector (collectionLayer), interractionLayer, decorator != null ? decorator : ALIGN_WITH_MOVE_DECORATOR_DEFAULT); + return createAlignWithMoveAction (new SingleLayerAlignWithWidgetCollector (collectionLayer, outerBounds), interractionLayer, decorator != null ? decorator : ALIGN_WITH_MOVE_DECORATOR_DEFAULT, outerBounds); } /** @@ -203,8 +217,22 @@ * @return the align-with move action */ public static WidgetAction createAlignWithMoveAction (AlignWithWidgetCollector collector, LayerWidget interractionLayer, AlignWithMoveDecorator decorator) { + return createAlignWithMoveAction (collector, interractionLayer, decorator, true); + } + + /** + * Creates a align-with move action. + * @param collector the collector of objects that the alignment is checked against. + * @param interractionLayer the interraction layer where the align-with hint lines are placed + * @param decorator the align-with move decorator + * @param outerBounds if true, then the align-with is check against whole bounds of widgets in collection layer; + * if false, then the align-with is check against client area (widget bounds without border insets + * @return the align-with move action + * @since 2.7 + */ + public static WidgetAction createAlignWithMoveAction (AlignWithWidgetCollector collector, LayerWidget interractionLayer, AlignWithMoveDecorator decorator, boolean outerBounds) { assert collector != null && interractionLayer != null && decorator != null; - AlignWithMoveStrategyProvider sp = new AlignWithMoveStrategyProvider (collector, interractionLayer, decorator); + AlignWithMoveStrategyProvider sp = new AlignWithMoveStrategyProvider (collector, interractionLayer, decorator, outerBounds); return createMoveAction (sp, sp); } @@ -216,8 +244,22 @@ * @return the align-with resize action */ public static WidgetAction createAlignWithResizeAction (LayerWidget collectionLayer, LayerWidget interractionLayer, AlignWithMoveDecorator decorator) { + return createAlignWithResizeAction (collectionLayer, interractionLayer, decorator, true); + } + + /** + * Creates a align-with resize action. + * @param collectionLayer the layer with objects that the alignment is checked against. + * @param interractionLayer the interraction layer where the align-with hint lines are placed + * @param decorator the align-with move decorator + * @param outerBounds if true, then the align-with is check against whole bounds of widgets in collection layer; + * if false, then the align-with is check against client area (widget bounds without border insets + * @return the align-with resize action + * @since 2.7 + */ + public static WidgetAction createAlignWithResizeAction (LayerWidget collectionLayer, LayerWidget interractionLayer, AlignWithMoveDecorator decorator, boolean outerBounds) { assert collectionLayer != null; - return createAlignWithResizeAction (new SingleLayerAlignWithWidgetCollector (collectionLayer), interractionLayer, decorator != null ? decorator : ALIGN_WITH_MOVE_DECORATOR_DEFAULT); + return createAlignWithResizeAction (new SingleLayerAlignWithWidgetCollector (collectionLayer, outerBounds), interractionLayer, decorator != null ? decorator : ALIGN_WITH_MOVE_DECORATOR_DEFAULT, outerBounds); } /** @@ -228,8 +270,22 @@ * @return the align-with resize action */ public static WidgetAction createAlignWithResizeAction (AlignWithWidgetCollector collector, LayerWidget interractionLayer, AlignWithMoveDecorator decorator) { + return createAlignWithResizeAction (collector, interractionLayer, decorator, true); + } + + /** + * Creates a align-with resize action. + * @param collector the collector of objects that the alignment is checked against. + * @param interractionLayer the interraction layer where the align-with hint lines are placed + * @param decorator the align-with move decorator + * @param outerBounds if true, then the align-with is check against whole bounds of widgets in collection layer; + * if false, then the align-with is check against client area (widget bounds without border insets + * @return the align-with resize action + * @since 2.7 + */ + public static WidgetAction createAlignWithResizeAction (AlignWithWidgetCollector collector, LayerWidget interractionLayer, AlignWithMoveDecorator decorator, boolean outerBounds) { assert collector != null && interractionLayer != null && decorator != null; - AlignWithResizeStrategyProvider sp = new AlignWithResizeStrategyProvider (collector, interractionLayer, decorator); + AlignWithResizeStrategyProvider sp = new AlignWithResizeStrategyProvider (collector, interractionLayer, decorator, outerBounds); return createResizeAction (sp, sp); } Index: graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html,v retrieving revision 1.20 diff -u -r1.20 documentation.html --- graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html 25 Jun 2007 14:10:19 -0000 1.20 +++ graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html 26 Jul 2007 12:40:40 -0000 @@ -858,6 +858,9 @@

The action is similar to MoveAction but it allows snapping feature similar to Form Editor module. The AlignWithMoveDecorator supplies a graphic for snapping lines and the AlignWithWidgetCollector gathers all widgets that the snapping has to be checked against. +

+The outerBounds boolean parameter allows to specify whether client area or bounds of widgets is going to be checked. +

AlignWithResizeAction

@@ -865,6 +868,9 @@

The action is similar to ResizeAction but it allows snapping feature similar to Form Editor module. The AlignWithMoveDecorator supplies a graphic for snapping lines and the AlignWithWidgetCollector gathers all widgets that the snapping has to be checked against. + +

+The outerBounds boolean parameter allows to specify whether client area or bounds of widgets is going to be checked.

CycleFocusAction

Index: graph/lib/src/org/netbeans/modules/visual/action/AlignWithMoveStrategyProvider.java =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/modules/visual/action/AlignWithMoveStrategyProvider.java,v retrieving revision 1.3 diff -u -r1.3 AlignWithMoveStrategyProvider.java --- graph/lib/src/org/netbeans/modules/visual/action/AlignWithMoveStrategyProvider.java 21 Feb 2007 19:17:35 -0000 1.3 +++ graph/lib/src/org/netbeans/modules/visual/action/AlignWithMoveStrategyProvider.java 26 Jul 2007 12:40:40 -0000 @@ -29,16 +29,28 @@ */ public final class AlignWithMoveStrategyProvider extends AlignWithSupport implements MoveStrategy, MoveProvider { - public AlignWithMoveStrategyProvider (AlignWithWidgetCollector collector, LayerWidget interractionLayer, AlignWithMoveDecorator decorator) { + private boolean outerBounds; + + public AlignWithMoveStrategyProvider (AlignWithWidgetCollector collector, LayerWidget interractionLayer, AlignWithMoveDecorator decorator, boolean outerBounds) { super (collector, interractionLayer, decorator); + this.outerBounds = outerBounds; } public Point locationSuggested (Widget widget, Point originalLocation, Point suggestedLocation) { Point widgetLocation = widget.getLocation (); - Rectangle widgetBounds = widget.getBounds (); + Rectangle widgetBounds = outerBounds ? widget.getBounds () : widget.getClientArea (); Rectangle bounds = widget.convertLocalToScene (widgetBounds); bounds.translate (suggestedLocation.x - widgetLocation.x, suggestedLocation.y - widgetLocation.y); + Insets insets = widget.getBorder ().getInsets (); + if (! outerBounds) { + suggestedLocation.x += insets.left; + suggestedLocation.y += insets.top; + } Point point = super.locationSuggested (widget, bounds, suggestedLocation, true, true, true, true); + if (! outerBounds) { + point.x -= insets.left; + point.y -= insets.top; + } return widget.getParentWidget ().convertSceneToLocal (point); } Index: graph/lib/src/org/netbeans/modules/visual/action/AlignWithResizeStrategyProvider.java =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/modules/visual/action/AlignWithResizeStrategyProvider.java,v retrieving revision 1.1 diff -u -r1.1 AlignWithResizeStrategyProvider.java --- graph/lib/src/org/netbeans/modules/visual/action/AlignWithResizeStrategyProvider.java 21 Feb 2007 19:17:36 -0000 1.1 +++ graph/lib/src/org/netbeans/modules/visual/action/AlignWithResizeStrategyProvider.java 26 Jul 2007 12:40:40 -0000 @@ -32,8 +32,11 @@ */ public final class AlignWithResizeStrategyProvider extends AlignWithSupport implements ResizeStrategy, ResizeProvider { - public AlignWithResizeStrategyProvider (AlignWithWidgetCollector collector, LayerWidget interractionLayer, AlignWithMoveDecorator decorator) { + private boolean outerBounds; + + public AlignWithResizeStrategyProvider (AlignWithWidgetCollector collector, LayerWidget interractionLayer, AlignWithMoveDecorator decorator, boolean outerBounds) { super (collector, interractionLayer, decorator); + this.outerBounds = outerBounds; } public Rectangle boundsSuggested (Widget widget, Rectangle originalBounds, Rectangle suggestedBounds, ControlPoint controlPoint) { @@ -49,16 +52,30 @@ switch (controlPoint) { case BOTTOM_CENTER: suggestedLocation = new Point (suggestedBounds.x + suggestedBounds.width / 2, suggestedBounds.y + suggestedBounds.height); + if (! outerBounds) + suggestedLocation.y -= insets.bottom; point = super.locationSuggested (widget, new Rectangle (suggestedLocation), suggestedLocation, false, true, false, false); + if (! outerBounds) + point.y += insets.bottom; + suggestedBounds.height = Math.max (miny, point.y - suggestedBounds.y); break; case BOTTOM_LEFT: suggestedLocation = new Point (suggestedBounds.x, suggestedBounds.y + suggestedBounds.height); + if (! outerBounds) { + suggestedLocation.y -= insets.bottom; + suggestedLocation.x += insets.left; + } point = super.locationSuggested (widget, new Rectangle (suggestedLocation), suggestedLocation, true, true, false, false); + if (! outerBounds) { + point.y += insets.bottom; + point.x -= insets.left; + } + suggestedBounds.height = Math.max (miny, point.y - suggestedBounds.y); tempx = Math.min (point.x, suggestedBounds.x + suggestedBounds.width - minx); @@ -67,43 +84,76 @@ break; case BOTTOM_RIGHT: suggestedLocation = new Point (suggestedBounds.x + suggestedBounds.width, suggestedBounds.y + suggestedBounds.height); + if (! outerBounds) { + suggestedLocation.y -= insets.bottom; + suggestedLocation.x -= insets.right; + } point = super.locationSuggested (widget, new Rectangle (suggestedLocation), suggestedLocation, true, true, false, false); + if (! outerBounds) { + point.y += insets.bottom; + point.x += insets.right; + } + suggestedBounds.height = Math.max (miny, point.y - suggestedBounds.y); suggestedBounds.width = Math.max (minx, point.x - suggestedBounds.x); break; case CENTER_LEFT: suggestedLocation = new Point (suggestedBounds.x, suggestedBounds.y + suggestedBounds.height / 2); + if (! outerBounds) + suggestedLocation.x += insets.left; point = super.locationSuggested (widget, new Rectangle (suggestedLocation), suggestedLocation, true, false, false, false); + if (! outerBounds) + point.x -= insets.left; + tempx = Math.min (point.x, suggestedBounds.x + suggestedBounds.width - minx); suggestedBounds.width = suggestedBounds.x + suggestedBounds.width - tempx; suggestedBounds.x = tempx; break; case CENTER_RIGHT: suggestedLocation = new Point (suggestedBounds.x + suggestedBounds.width, suggestedBounds.y + suggestedBounds.height / 2); + if (! outerBounds) + suggestedLocation.x -= insets.right; point = super.locationSuggested (widget, new Rectangle (suggestedLocation), suggestedLocation, true, false, false, false); + if (! outerBounds) + point.x += insets.right; + suggestedBounds.width = Math.max (minx, point.x - suggestedBounds.x); break; case TOP_CENTER: suggestedLocation = new Point (suggestedBounds.x + suggestedBounds.width / 2, suggestedBounds.y); + if (! outerBounds) + suggestedLocation.y += insets.top; point = super.locationSuggested (widget, new Rectangle (suggestedLocation), suggestedLocation, false, true, false, false); + if (! outerBounds) + point.y -= insets.top; + tempy = Math.min (point.y, suggestedBounds.y + suggestedBounds.height - miny); suggestedBounds.height = suggestedBounds.y + suggestedBounds.height - tempy; suggestedBounds.y = tempy; break; case TOP_LEFT: suggestedLocation = new Point (suggestedBounds.x, suggestedBounds.y); + if (! outerBounds) { + suggestedLocation.y += insets.top; + suggestedLocation.x += insets.left; + } point = super.locationSuggested (widget, new Rectangle (suggestedLocation), suggestedLocation, true, true, false, false); + if (! outerBounds) { + point.y -= insets.top; + point.x -= insets.left; + } + tempy = Math.min (point.y, suggestedBounds.y + suggestedBounds.height - miny); suggestedBounds.height = suggestedBounds.y + suggestedBounds.height - tempy; suggestedBounds.y = tempy; @@ -114,8 +164,17 @@ break; case TOP_RIGHT: suggestedLocation = new Point (suggestedBounds.x + suggestedBounds.width, suggestedBounds.y); + if (! outerBounds) { + suggestedLocation.y += insets.top; + suggestedLocation.x -= insets.right; + } point = super.locationSuggested (widget, new Rectangle (suggestedLocation), suggestedLocation, true, true, false, false); + + if (! outerBounds) { + point.y -= insets.top; + point.x += insets.right; + } tempy = Math.min (point.y, suggestedBounds.y + suggestedBounds.height - miny); suggestedBounds.height = suggestedBounds.y + suggestedBounds.height - tempy; Index: graph/lib/src/org/netbeans/modules/visual/action/SingleLayerAlignWithWidgetCollector.java =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/modules/visual/action/SingleLayerAlignWithWidgetCollector.java,v retrieving revision 1.2 diff -u -r1.2 SingleLayerAlignWithWidgetCollector.java --- graph/lib/src/org/netbeans/modules/visual/action/SingleLayerAlignWithWidgetCollector.java 14 Nov 2006 10:04:22 -0000 1.2 +++ graph/lib/src/org/netbeans/modules/visual/action/SingleLayerAlignWithWidgetCollector.java 26 Jul 2007 12:40:40 -0000 @@ -31,9 +31,11 @@ public final class SingleLayerAlignWithWidgetCollector implements AlignWithWidgetCollector { private LayerWidget collectionLayer; + private boolean outerBounds; - public SingleLayerAlignWithWidgetCollector (LayerWidget collectionLayer) { + public SingleLayerAlignWithWidgetCollector (LayerWidget collectionLayer, boolean outerBounds) { this.collectionLayer = collectionLayer; + this.outerBounds = outerBounds; } public java.util.List getRegions (Widget movingWidget) { @@ -41,7 +43,7 @@ ArrayList regions = new ArrayList (children.size ()); for (Widget widget : children) if (widget != movingWidget) - regions.add (widget.convertLocalToScene (widget.getBounds ())); + regions.add (widget.convertLocalToScene (outerBounds ? widget.getBounds () : widget.getClientArea ())); return regions; } Index: graph/lib/src/org/netbeans/modules/visual/resources/vmd-pin.png =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/modules/visual/resources/vmd-pin.png,v retrieving revision 1.1 diff -u -r1.1 vmd-pin.png Binary files /tmp/cvsQZaqG1 and vmd-pin.png differ Index: graph/www/documentation.html =================================================================== RCS file: /cvs/graph/www/documentation.html,v retrieving revision 1.97 diff -u -r1.97 documentation.html --- graph/www/documentation.html 19 Jul 2007 07:15:43 -0000 1.97 +++ graph/www/documentation.html 26 Jul 2007 12:40:40 -0000 @@ -106,6 +106,7 @@
  • javaone.demo6.LODDemo - how to use LevelOfDetailsWidget. Zoom-in to see more.
  • test.action.ActionMapActionTest - how to use ActionMapAction
  • test.action.SelectLockedActionTest - example of proper cooperation of select (which opens another Swing windows) and locking action +
  • test.alignwith.AlignWithClientAreaTest - test of #105285 - align-with action with checking client area of widgets only
  • test.alignwith.AlignWithMoveGuideLinesTest - test of #97034 - incorrectly painted guide-lines for MoveAlignWithAction
  • test.alignwith.AlignWithTest - how to use MoveAlignWithAction
  • test.alignwith.AlignWithResizeTest - how to use AlignWithMoveAction and AlignWithResizeAction