1 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); 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 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 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 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 else if (changeSides) { 222 if (rightOK) 223 x = pbounds.x + pbounds.width; 224 else if (leftOK) 225 x = pbounds.x - newSize; 226 else { 227 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 if (bounds.y + bounds.height == savedBounds.y + savedBounds.height) { 261 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 int deltaX = bounds.x - savedBounds.x; 274 if (deltaX > 0 || bounds.x + bounds.width > pbounds.x) { 275 int distance = pbounds.x - bounds.x - bounds.width; 277 if (Math.abs(distance) <= DOCK_MARGIN) 278 doDock = true; 279 } 280 } else { 281 int deltaX = bounds.x - savedBounds.x; 283 if (deltaX < 0 || bounds.x < pbounds.x + pbounds.width) { 284 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) doDock = false; 292 if (pbounds.y + pbounds.height < bounds.y) 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 if (savedPbounds.x + savedPbounds.width != pbounds.x 325 + pbounds.width) 326 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) return false; 373 if (pbounds.y + pbounds.height < bounds.y) 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 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 |