Initialize
[sdk/ide/product.git] / org.eclipse.jst.pagedesigner / src / org / eclipse / jst / pagedesigner / tools / ExposeHelper.java
1 /*******************************************************************************\r
2  * Copyright (c) 2006 Sybase, Inc. and others.\r
3  *\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     Sybase, Inc. - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.eclipse.jst.pagedesigner.tools;\r
13 \r
14 import org.eclipse.draw2d.FigureCanvas;\r
15 import org.eclipse.draw2d.IFigure;\r
16 import org.eclipse.draw2d.Viewport;\r
17 import org.eclipse.draw2d.geometry.Dimension;\r
18 import org.eclipse.draw2d.geometry.Point;\r
19 import org.eclipse.draw2d.geometry.Rectangle;\r
20 import org.eclipse.gef.EditPart;\r
21 import org.eclipse.gef.GraphicalEditPart;\r
22 import org.eclipse.gef.editpolicies.AbstractEditPolicy;\r
23 import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;\r
24 import org.eclipse.jface.viewers.ISelection;\r
25 import org.eclipse.jface.viewers.IStructuredSelection;\r
26 import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;\r
27 import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;\r
28 import org.w3c.dom.Node;\r
29 \r
30 /**\r
31  * This helper class expose an rectangle in design view, currentlly it is used\r
32  * to help expose caret.\r
33  * \r
34  * @author mengbo\r
35  */\r
36 public class ExposeHelper {\r
37         private static final int DEFAULT_OFFSET = 100;\r
38 \r
39         private static final int SCROLL_OFFSET = 8;\r
40 \r
41         IHTMLGraphicalViewer _viewer;\r
42 \r
43         /**\r
44          * @param viewer \r
45          */\r
46         public ExposeHelper(IHTMLGraphicalViewer viewer) {\r
47                 _viewer = viewer;\r
48         }\r
49 \r
50         /**\r
51          * Expose rectangle. (non-Javadoc)\r
52          * @param rect \r
53          * \r
54          * @see org.eclipse.gef.ExposeHelper#exposeDescendant(org.eclipse.gef.EditPart)\r
55          */\r
56         public void exposeArea(Rectangle rect) {\r
57                 if (_viewer == null) {\r
58                         return;\r
59                 }\r
60                 FigureCanvas canvas = (FigureCanvas) _viewer.getControl();\r
61                 Viewport port = _viewer.getViewport();\r
62 \r
63                 if (port == null) {\r
64                         return;\r
65                 }\r
66                 Rectangle exposeRegion = rect.getCopy();\r
67                 Rectangle portBounds = port.getBounds().getCopy();\r
68                 Point viewLocation = port.getViewLocation();\r
69                 Dimension diff = calculateDiff(portBounds, exposeRegion);\r
70                 if (diff != null) {\r
71                         viewLocation.x -= diff.width;\r
72                         viewLocation.y -= diff.height;\r
73                         canvas.scrollSmoothTo(viewLocation.x, viewLocation.y);\r
74                 }\r
75         }\r
76 \r
77         private void exposeVertical(int offset) {\r
78                 if (_viewer == null) {\r
79                         return;\r
80                 }\r
81                 FigureCanvas canvas = (FigureCanvas) _viewer.getControl();\r
82                 Viewport port = _viewer.getViewport();\r
83 \r
84                 if (port == null) {\r
85                         return;\r
86                 }\r
87                 Point viewLocation = port.getViewLocation();\r
88                 viewLocation.y += offset;\r
89                 canvas.scrollSmoothTo(viewLocation.x, viewLocation.y);\r
90         }\r
91 \r
92         private void exposeHorizontal(int offset) {\r
93                 if (_viewer == null) {\r
94                         return;\r
95                 }\r
96                 FigureCanvas canvas = (FigureCanvas) _viewer.getControl();\r
97                 Viewport port = _viewer.getViewport();\r
98 \r
99                 if (port == null) {\r
100                         return;\r
101                 }\r
102                 Point viewLocation = port.getViewLocation();\r
103                 viewLocation.x += offset;\r
104                 canvas.scrollSmoothTo(viewLocation.x, viewLocation.y);\r
105         }\r
106 \r
107         private int calculateX(Rectangle portBounds, Rectangle caretRect) {\r
108                 int result = 0;\r
109                 if (portBounds.x > caretRect.getRight().x) {\r
110                         result = portBounds.getLeft().getDifference(caretRect.getRight()).width;\r
111                         if (portBounds.width >= caretRect.width) {\r
112                                 result = portBounds.getLeft()\r
113                                                 .getDifference(caretRect.getLeft()).width;\r
114                         }\r
115                 } else if (portBounds.getRight().x < caretRect.getLeft().x) {\r
116                         result = portBounds.getRight().getDifference(caretRect.getLeft()).width;\r
117                         if (portBounds.width >= caretRect.width) {\r
118                                 result = portBounds.getRight().getDifference(\r
119                                                 caretRect.getRight()).width;\r
120                         }\r
121                 }\r
122                 return result;\r
123         }\r
124 \r
125         private int calculateY(Rectangle portBounds, Rectangle caretRect) {\r
126                 int result = 0;\r
127                 if (portBounds.y > caretRect.getBottom().y) {\r
128                         result = portBounds.getTop().getDifference(caretRect.getBottom()).height;\r
129                         if (portBounds.height >= caretRect.height) {\r
130                                 result = portBounds.getTop().getDifference(caretRect.getTop()).height;\r
131                         }\r
132                 } else if (portBounds.getBottom().y < caretRect.getTop().y) {\r
133                         result = portBounds.getBottom().getDifference(caretRect.getTop()).height;\r
134                         if (portBounds.height >= caretRect.height) {\r
135                                 result = portBounds.getBottom().getDifference(\r
136                                                 caretRect.getBottom()).height;\r
137                         }\r
138                 } else if (portBounds.getBottom().y < caretRect.getBottom().y) {\r
139                         if (portBounds.height >= caretRect.height) {\r
140                                 result = portBounds.getBottom().getDifference(\r
141                                                 caretRect.getBottom()).height;\r
142                         }\r
143                 } else if (portBounds.getTop().y > caretRect.getTop().y) {\r
144                         if (portBounds.height >= caretRect.height) {\r
145                                 result = portBounds.getTop().getDifference(caretRect.getTop()).height;\r
146                         }\r
147                 }\r
148                 return result;\r
149         }\r
150 \r
151         /**\r
152          * Calculate caretPoint's offset to posrBounds at both x coordinate and y\r
153          * coordinate.\r
154          * \r
155          * @param portBounds\r
156          * @param exposeRegion\r
157          * @param canvas\r
158          * @param caretPoint\r
159          */\r
160         private Dimension calculateDiff(Rectangle portBounds, Rectangle caretRect) {\r
161                 Dimension diff = new Dimension(0, 0);\r
162                 diff.width = calculateX(portBounds, caretRect);\r
163                 diff.height = calculateY(portBounds, caretRect);\r
164                 return diff;\r
165         }\r
166 \r
167         // /**\r
168         // * Calculate caretPoint's offset to posrBounds at both x coordinate and y\r
169         // coordinate.\r
170         // *\r
171         // * @param portBounds\r
172         // * @param exposeRegion\r
173         // * @param canvas\r
174         // * @param caretPoint\r
175         // */\r
176         // private Dimension calculateDiff(Rectangle portBounds, Point caretPoint)\r
177         // {\r
178         // int position = portBounds.getPosition(caretPoint);\r
179         // Dimension diff = null;\r
180         // Point containerPos = null;\r
181         // switch (position)\r
182         // {\r
183         // case PositionConstants.EAST:\r
184         // containerPos = new Point(portBounds.getRight().x, caretPoint.y);\r
185         // diff = containerPos.getDifference(caretPoint);\r
186         // break;\r
187         // case PositionConstants.NORTH_EAST:\r
188         // diff = portBounds.getTopRight().getDifference(caretPoint);\r
189         // break;\r
190         // case PositionConstants.WEST:\r
191         // containerPos = new Point(portBounds.getLeft().x, caretPoint.y);\r
192         // diff = containerPos.getDifference(caretPoint);\r
193         // break;\r
194         // case PositionConstants.NORTH_WEST:\r
195         // diff = portBounds.getTopLeft().getDifference(caretPoint);\r
196         // break;\r
197         // case PositionConstants.SOUTH_WEST:\r
198         // diff = portBounds.getBottomLeft().getDifference(caretPoint);\r
199         // break;\r
200         // case PositionConstants.SOUTH_EAST:\r
201         // diff = portBounds.getBottomRight().getDifference(caretPoint);\r
202         // break;\r
203         // case PositionConstants.NORTH:\r
204         // containerPos = new Point(caretPoint.x, portBounds.getTop().y);\r
205         // diff = containerPos.getDifference(caretPoint);\r
206         // break;\r
207         // case PositionConstants.SOUTH:\r
208         // containerPos = new Point(caretPoint.x, portBounds.getBottom().y);\r
209         // diff = containerPos.getDifference(caretPoint);\r
210         // break;\r
211         // }\r
212         // return diff;\r
213         // }\r
214         //\r
215         private static void expose(EditPart part, ScrollingGraphicalViewer viewer) {\r
216                 if (part != null && part.getModel() instanceof Node) {\r
217                         viewer.reveal(part);\r
218                 }\r
219         }\r
220 \r
221         private static void expose(Node element, ScrollingGraphicalViewer viewer) {\r
222                 if (element instanceof INodeNotifier) {\r
223                         EditPart editPart = (EditPart) ((INodeNotifier) element)\r
224                                         .getAdapterFor(EditPart.class);\r
225                         expose(editPart, viewer);\r
226                 }\r
227         }\r
228 \r
229         /**\r
230          * @param selection\r
231          * @param viewer\r
232          */\r
233         public static void expose(ISelection selection,\r
234                         ScrollingGraphicalViewer viewer) {\r
235                 if (selection instanceof IStructuredSelection) {\r
236                         Object element = ((IStructuredSelection) selection)\r
237                                         .getFirstElement();\r
238                         if (element instanceof Node) {\r
239                                 expose((Node) element, viewer);\r
240                         } else if (element instanceof EditPart) {\r
241                                 expose((EditPart) element, viewer);\r
242                         }\r
243                 }\r
244         }\r
245 \r
246         /**\r
247          * @param p\r
248          */\r
249         public void adjustVertical(Point p) {\r
250                 int offset = 0;\r
251                 if ((offset = getVerticalBoundsOffset(p, false)) < SCROLL_OFFSET) {\r
252                         exposeVertical(SCROLL_OFFSET - offset);\r
253                 } else if ((offset = getVerticalBoundsOffset(p, true)) < SCROLL_OFFSET) {\r
254                         exposeVertical(offset - SCROLL_OFFSET);\r
255                 }\r
256                 if ((offset = getHorizontalBoundsOffset(p, true)) < SCROLL_OFFSET) {\r
257                         exposeHorizontal(SCROLL_OFFSET - offset);\r
258                 } else if ((offset = getHorizontalBoundsOffset(p, false)) < SCROLL_OFFSET) {\r
259                         exposeHorizontal(offset - SCROLL_OFFSET);\r
260                 }\r
261         }\r
262 \r
263         /**\r
264          * @return the location of the view port\r
265          */\r
266         public Point getViewpostLocation() {\r
267                 if (_viewer != null) {\r
268                         Viewport port = _viewer.getViewport();\r
269 \r
270                         if (port != null) {\r
271                                 return port.getViewLocation();\r
272                         }\r
273                 }\r
274                 return null;\r
275         }\r
276 \r
277         /**\r
278          * @param figure\r
279          * @param p\r
280          * @return the translated point\r
281          */\r
282         public Point translateToViewport(IFigure figure, Point p) {\r
283                 Point vp = getViewpostLocation();\r
284                 return new Point(p.x - vp.x, p.y - vp.y);\r
285         }\r
286 \r
287         private int getHorizontalBoundsOffset(Point p, boolean forward) {\r
288                 if (_viewer == null) {\r
289                         return DEFAULT_OFFSET;\r
290                 }\r
291                 Viewport port = _viewer.getViewport();\r
292 \r
293                 if (port == null) {\r
294                         return DEFAULT_OFFSET;\r
295                 }\r
296                 if (forward) {\r
297                         Rectangle portBounds = port.getBounds().getCopy();\r
298                         return portBounds.getRight().x - p.x;\r
299                 }\r
300         return p.x;\r
301         }\r
302 \r
303         private int getVerticalBoundsOffset(Point p, boolean up) {\r
304                 if (_viewer == null) {\r
305                         return DEFAULT_OFFSET;\r
306                 }\r
307                 Viewport port = _viewer.getViewport();\r
308 \r
309                 if (port == null) {\r
310                         return DEFAULT_OFFSET;\r
311                 }\r
312                 if (!up) {\r
313                         Rectangle portBounds = port.getBounds().getCopy();\r
314                         return portBounds.getBottom().y - p.y;\r
315                 }\r
316         return p.y;\r
317         }\r
318 \r
319         /**\r
320          * @param rect\r
321          * @param policy\r
322          */\r
323         void exposeBorder(Rectangle rect, AbstractEditPolicy policy) {\r
324                 Point p = rect.getTopLeft();\r
325                 p = translateToViewport(((GraphicalEditPart) policy.getHost())\r
326                                 .getFigure(), p);\r
327                 adjustVertical(p);\r
328                 p = rect.getBottomRight();\r
329                 p = translateToViewport(((GraphicalEditPart) policy.getHost())\r
330                                 .getFigure(), p);\r
331                 adjustVertical(p);\r
332         }\r
333 }\r