KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > help > ui > internal > views > ContextHelpWindow


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Sebastian Davids <sdavids@gmx.de> - bug 93374
11  *******************************************************************************/

12 package org.eclipse.help.ui.internal.views;
13
14 import org.eclipse.core.runtime.Platform;
15 import org.eclipse.help.IContext;
16 import org.eclipse.help.ui.internal.IHelpUIConstants;
17 import org.eclipse.help.ui.internal.Messages;
18 import org.eclipse.jface.action.ToolBarManager;
19 import org.eclipse.jface.dialogs.IDialogPage;
20 import org.eclipse.jface.dialogs.IPageChangeProvider;
21 import org.eclipse.jface.dialogs.IPageChangedListener;
22 import org.eclipse.jface.dialogs.PageChangedEvent;
23 import org.eclipse.jface.window.Window;
24 import org.eclipse.swt.SWT;
25 import org.eclipse.swt.events.ControlEvent;
26 import org.eclipse.swt.events.ControlListener;
27 import org.eclipse.swt.graphics.Rectangle;
28 import org.eclipse.swt.layout.GridData;
29 import org.eclipse.swt.layout.GridLayout;
30 import org.eclipse.swt.widgets.Composite;
31 import org.eclipse.swt.widgets.Control;
32 import org.eclipse.swt.widgets.Display;
33 import org.eclipse.swt.widgets.Event;
34 import org.eclipse.swt.widgets.Label;
35 import org.eclipse.swt.widgets.Listener;
36 import org.eclipse.swt.widgets.Shell;
37 import org.eclipse.swt.widgets.TabFolder;
38 import org.eclipse.swt.widgets.TabItem;
39 import org.eclipse.ui.PlatformUI;
40 import org.eclipse.ui.forms.HyperlinkGroup;
41 import org.eclipse.ui.forms.widgets.FormToolkit;
42
43 public class ContextHelpWindow extends Window implements IPageChangedListener {
44     private ReusableHelpPart helpPart;
45
46     private static final int DOCK_MARGIN = 10;
47
48     private static final int CLIP_ALLOWANCE = 5;
49
50     private FormToolkit toolkit;
51
52     private Listener listener;
53
54     private ControlListener parentListener;
55
56     private Rectangle savedPbounds;
57
58     private Rectangle savedBounds;
59
60     private boolean parentResizeBlocked = false;
61
62     public ContextHelpWindow(Shell parent) {
63         super(parent);
64         setShellStyle(SWT.CLOSE | SWT.RESIZE);
65         if (!Platform.getWS().equals(Platform.WS_GTK)) {
66             parentListener = new ControlListener() {
67                 public void controlMoved(ControlEvent e) {
68                     maintainRelativePosition();
69                 }
70
71                 public void controlResized(ControlEvent e) {
72                     onParentWindowResize();
73                 }
74             };
75             listener = new Listener() {
76                 public void handleEvent(Event e) {
77                     switch (e.type) {
78                     case SWT.FocusIn:
79                     case SWT.Selection:
80                         update((Control) e.widget);
81                         break;
82                     case SWT.Move:
83                         if (onWindowMove())
84                             e.doit = false;
85                         break;
86                     case SWT.Resize:
87                         onWindowResize();
88                         break;
89                     }
90                 }
91             };
92         }
93     }
94     
95     public void showSearch() {
96         helpPart.showPage(IHelpUIConstants.HV_FSEARCH_PAGE, true);
97     }
98
99     private void maintainRelativePosition() {
100         if (savedPbounds == null || isDocked())
101             dock(true);
102         else {
103             Rectangle pbounds = getShell().getParent().getBounds();
104             Rectangle bounds = getShell().getBounds();
105             int deltaX = pbounds.x - savedPbounds.x;
106             int deltaY = pbounds.y - savedPbounds.y;
107             int newX = bounds.x + deltaX;
108             int newY = bounds.y + deltaY;
109             boolean doDock = false;
110             Rectangle dbounds = getShell().getDisplay().getBounds();
111             if (newX > dbounds.width - bounds.width) {
112                 newX = dbounds.width - bounds.width;
113                 if (pbounds.x + pbounds.width > newX)
114                     doDock = true;
115             } else if (newX < 0)
116                 doDock = true;
117             if (newY > dbounds.height - bounds.height) {
118                 newY = dbounds.height - bounds.height;
119             } else if (newY < 0)
120                 newY = 0;
121             if (doDock) {
122                 dock(true);
123                 return;
124             }
125             getShell().setLocation(newX, newY);
126             savedPbounds = pbounds;
127             savedBounds = getShell().getBounds();
128         }
129     }
130
131     protected Control createContents(Composite parent) {
132         toolkit = new FormToolkit(parent.getDisplay());
133         toolkit.getHyperlinkGroup().setHyperlinkUnderlineMode(
134                 HyperlinkGroup.UNDERLINE_HOVER);
135         toolkit.getColors().initializeSectionToolBarColors();
136         Composite container = new Composite(parent, SWT.NULL);
137         GridLayout layout = new GridLayout();
138         layout.marginWidth = layout.marginHeight = 0;
139         layout.verticalSpacing = 0;
140         container.setLayout(layout);
141
142         GridData gd;
143         ToolBarManager tbm = new ToolBarManager(SWT.FLAT);
144         tbm.createControl(container);
145         gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
146         gd.grabExcessHorizontalSpace = true;
147         tbm.getControl().setLayoutData(gd);
148         Label separator = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
149         gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
150         gd.heightHint = 1;
151         separator.setLayoutData(gd);
152         helpPart = new ReusableHelpPart(PlatformUI.getWorkbench()
153                 .getProgressService());
154         helpPart.init(null, tbm, null, null);
155         helpPart.setDefaultContextHelpText(Messages.HelpView_defaultText); //$NON-NLS-1$
156
helpPart.createControl(container, toolkit);
157         helpPart.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
158         if (!Platform.getWS().equals(Platform.WS_GTK))
159             hookListeners();
160         helpPart.showPage(IHelpUIConstants.HV_CONTEXT_HELP_PAGE);
161         container.setLayoutData(new GridData(GridData.FILL_BOTH));
162         return container;
163     }
164
165     private void hookListeners() {
166         Shell shell = getShell();
167         shell.addListener(SWT.Move, listener);
168         shell.addListener(SWT.Resize, listener);
169         hookPageChangeListener(shell.getParent(), listener);
170         shell.getParent().addControlListener(parentListener);
171     }
172
173     private void unhookListeners() {
174         Shell shell = getShell();
175         shell.getParent().removeControlListener(parentListener);
176         unhookPageChangeListener(shell.getParent(), listener);
177         shell.removeListener(SWT.Move, listener);
178         shell.removeListener(SWT.Resize, listener);
179     }
180
181     private void hookPageChangeListener(Composite parent, Listener listener) {
182         Object JavaDoc data = parent.getData();
183         if (data instanceof IPageChangeProvider) {
184             ((IPageChangeProvider) data).addPageChangedListener(this);
185         }
186     }
187
188     private void unhookPageChangeListener(Composite parent, Listener listener) {
189         Object JavaDoc data = parent.getData();
190         if (data instanceof IPageChangeProvider) {
191             ((IPageChangeProvider) data).removePageChangedListener(this);
192         }
193     }
194
195     public void dock(boolean changeSides) {
196         getShell().setBounds(computeDockedBounds(changeSides));
197     }
198
199     public Rectangle computeDockedBounds(boolean changeSides) {
200         Display d = getShell().getDisplay();
201         Rectangle dbounds = d.getBounds();
202         Rectangle pbounds = getShell().getParent().getBounds();
203
204         int leftMargin = pbounds.x;
205         int rightMargin = dbounds.width - pbounds.x - pbounds.width;
206         int centeredLeftMargin = dbounds.width / 2 - pbounds.width / 2;
207         boolean rightParent = leftMargin > centeredLeftMargin;
208         int currentX = getShell().getLocation().x;
209         int newSize = getShell().getSize().x;
210         boolean leftOK = newSize <= leftMargin + CLIP_ALLOWANCE;
211         boolean rightOK = newSize <= rightMargin + CLIP_ALLOWANCE;
212         int x;
213         // first try to keep the same side
214
if (currentX < pbounds.x && leftOK && (!changeSides || !rightParent)) {
215             x = pbounds.x - newSize;
216         } else if (currentX > pbounds.x && rightOK
217                 && (!changeSides || rightParent)) {
218             x = pbounds.x + pbounds.width;
219         }
220         // must switch side
221
else if (changeSides) {
222             if (rightOK)
223                 x = pbounds.x + pbounds.width;
224             else if (leftOK)
225                 x = pbounds.x - newSize;
226             else {
227                 // pick the margin that has more space, reduce size
228
if (leftMargin > rightMargin) {
229                     newSize = leftMargin;
230                     x = pbounds.x - newSize;
231                 } else {
232                     newSize = rightMargin;
233                     x = dbounds.width - newSize;
234                 }
235             }
236         } else {
237             if (currentX < pbounds.x) {
238                 newSize = leftMargin;
239                 x = pbounds.x - newSize;
240             } else {
241                 newSize = rightMargin;
242                 x = dbounds.width - newSize;
243             }
244         }
245         savedPbounds = pbounds;
246         savedBounds = getShell().getBounds();
247         return new Rectangle(x, pbounds.y, newSize, pbounds.height);
248     }
249
250     private boolean onWindowMove() {
251         if (savedBounds == null) {
252             savedBounds = getShell().getBounds();
253             savedPbounds = getShell().getParent().getBounds();
254             return false;
255         }
256         Rectangle bounds = getShell().getBounds();
257         Rectangle pbounds = getShell().getParent().getBounds();
258         if (bounds.y != savedBounds.y) {
259             // vertical move
260
if (bounds.y + bounds.height == savedBounds.y + savedBounds.height) {
261                 // upper edge resize
262
if (isDocked()) {
263                     savedBounds = bounds;
264                     savedPbounds = pbounds;
265                     return false;
266                 }
267             }
268         }
269         boolean doDock = false;
270
271         if (bounds.x < pbounds.x) {
272             // left
273
int deltaX = bounds.x - savedBounds.x;
274             if (deltaX > 0 || bounds.x + bounds.width > pbounds.x) {
275                 // moving closer - check for dock snap
276
int distance = pbounds.x - bounds.x - bounds.width;
277                 if (Math.abs(distance) <= DOCK_MARGIN)
278                     doDock = true;
279             }
280         } else {
281             // right
282
int deltaX = bounds.x - savedBounds.x;
283             if (deltaX < 0 || bounds.x < pbounds.x + pbounds.width) {
284                 // moving closer - check for dock snap
285
int distance = bounds.x - pbounds.x - pbounds.width;
286                 if (Math.abs(distance) <= DOCK_MARGIN)
287                     doDock = true;
288             }
289         }
290         if (bounds.y + bounds.height < pbounds.y) // above
291
doDock = false;
292         if (pbounds.y + pbounds.height < bounds.y) // below
293
doDock = false;
294         if (doDock)
295             dock(false);
296         savedBounds = getShell().getBounds();
297         savedPbounds = getShell().getParent().getBounds();
298         return doDock;
299     }
300
301     private void onWindowResize() {
302         if (isDocked()) {
303             Rectangle bounds = getShell().getBounds();
304             Rectangle pbounds = getShell().getParent().getBounds();
305             if (bounds.height != savedBounds.height) {
306                 Shell parent = (Shell) getShell().getParent();
307                 if ((parent.getStyle() & SWT.RESIZE) != 0) {
308                     parentResizeBlocked = true;
309                     parent.setBounds(pbounds.x, bounds.y, pbounds.width,
310                             bounds.height);
311                     parentResizeBlocked = false;
312                 }
313             }
314         }
315         savedBounds = getShell().getBounds();
316     }
317
318     private void onParentWindowResize() {
319         if (!parentResizeBlocked && isDocked()) {
320             Rectangle bounds = getShell().getBounds();
321             Rectangle pbounds = getShell().getParent().getBounds();
322             if (bounds.x == savedPbounds.x + savedPbounds.width) {
323                 // right
324
if (savedPbounds.x + savedPbounds.width != pbounds.x
325                         + pbounds.width)
326                     // right edge moved
327
dock(false);
328             } else {
329             }
330             getShell().setSize(getShell().getSize().x,
331                     getShell().getParent().getSize().y);
332         }
333         savedPbounds = getShell().getParent().getBounds();
334     }
335
336     public void update(Control c) {
337         helpPart.update(null, c);
338     }
339
340     public void update(IContext context, Control c) {
341         helpPart.showPage(IHelpUIConstants.HV_CONTEXT_HELP_PAGE);
342         helpPart.update(context, null, c);
343     }
344
345     public boolean close() {
346         if (!Platform.getWS().equals(Platform.WS_GTK))
347             unhookListeners();
348         if (super.close()) {
349             if (toolkit != null) {
350                 toolkit.dispose();
351                 toolkit = null;
352             }
353             if (helpPart != null) {
354                 helpPart.dispose();
355                 helpPart = null;
356             }
357             return true;
358         }
359         return false;
360     }
361
362     private boolean isDocked() {
363         if (savedPbounds == null)
364             return false;
365         return isDocked(savedBounds, savedPbounds);
366     }
367
368     private boolean isDocked(Rectangle bounds, Rectangle pbounds) {
369         if (pbounds.height != bounds.height)
370             return false;
371         if (bounds.y + bounds.height < pbounds.y) // above
372
return false;
373         if (pbounds.y + pbounds.height < bounds.y) // below
374
return false;
375         return bounds.x == pbounds.x + pbounds.width
376                 || bounds.x == pbounds.x - bounds.width;
377     }
378
379     public void pageChanged(PageChangedEvent event) {
380         Object JavaDoc page = event.getSelectedPage();
381         Control c = null;
382         if (page instanceof IDialogPage) {
383             c = ((IDialogPage) page).getControl();
384         } else {
385             c = getShell().getDisplay().getFocusControl();
386             if (c instanceof TabFolder) {
387                 TabFolder folder = (TabFolder) c;
388                 TabItem[] selection = folder.getSelection();
389                 if (selection.length == 1) {
390                     c = selection[0].getControl();
391                 }
392             }
393         }
394         update(null, c);
395     }
396 }
Popular Tags