]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/custom/ScrolledComposite.java
Remove invalid SHA-256-Digests
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / custom / ScrolledComposite.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2016 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.swt.custom;
15
16 import org.eclipse.swt.*;
17 import org.eclipse.swt.graphics.*;
18 import org.eclipse.swt.widgets.*;
19
20 /**
21  * A ScrolledComposite provides scrollbars and will scroll its content when the user
22  * uses the scrollbars.
23  *
24  *
25  * <p>There are two ways to use the ScrolledComposite:
26  *
27  * </p>
28  * <ol>
29  * <li> Set the size of the control that is being scrolled and the ScrolledComposite
30  * will show scrollbars when the contained control can not be fully seen.</li>
31  *
32  * <li>The second way imitates the way a browser would work.  Set the minimum size of
33  * the control and the ScrolledComposite will show scroll bars if the visible area is
34  * less than the minimum size of the control and it will expand the size of the control
35  * if the visible area is greater than the minimum size.  This requires invoking
36  * both setMinWidth(), setMinHeight() and setExpandHorizontal(), setExpandVertical().</li>
37  * </ol>
38  *
39  * <pre><code>
40  * public static void main (String [] args) {
41  *      Display display = new Display ();
42  *      Color red = display.getSystemColor(SWT.COLOR_RED);
43  *      Color blue = display.getSystemColor(SWT.COLOR_BLUE);
44  *      Shell shell = new Shell (display);
45  *      shell.setLayout(new FillLayout());
46  *
47  *      // set the size of the scrolled content - method 1
48  *      final ScrolledComposite sc1 = new ScrolledComposite(shell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
49  *      final Composite c1 = new Composite(sc1, SWT.NONE);
50  *      sc1.setContent(c1);
51  *      c1.setBackground(red);
52  *      GridLayout layout = new GridLayout();
53  *      layout.numColumns = 4;
54  *      c1.setLayout(layout);
55  *      Button b1 = new Button (c1, SWT.PUSH);
56  *      b1.setText("first button");
57  *      c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));
58  *
59  *      // set the minimum width and height of the scrolled content - method 2
60  *      final ScrolledComposite sc2 = new ScrolledComposite(shell, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
61  *      sc2.setExpandHorizontal(true);
62  *      sc2.setExpandVertical(true);
63  *      final Composite c2 = new Composite(sc2, SWT.NONE);
64  *      sc2.setContent(c2);
65  *      c2.setBackground(blue);
66  *      layout = new GridLayout();
67  *      layout.numColumns = 4;
68  *      c2.setLayout(layout);
69  *      Button b2 = new Button (c2, SWT.PUSH);
70  *      b2.setText("first button");
71  *      sc2.setMinSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT));
72  *
73  *      Button add = new Button (shell, SWT.PUSH);
74  *      add.setText("add children");
75  *      final int[] index = new int[]{0};
76  *      add.addListener(SWT.Selection, new Listener() {
77  *          public void handleEvent(Event e) {
78  *              index[0]++;
79  *              Button button = new Button(c1, SWT.PUSH);
80  *              button.setText("button "+index[0]);
81  *              // reset size of content so children can be seen - method 1
82  *              c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));
83  *              c1.layout();
84  *
85  *              button = new Button(c2, SWT.PUSH);
86  *              button.setText("button "+index[0]);
87  *              // reset the minimum width and height so children can be seen - method 2
88  *              sc2.setMinSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT));
89  *              c2.layout();
90  *          }
91  *      });
92  *
93  *      shell.open ();
94  *      while (!shell.isDisposed ()) {
95  *          if (!display.readAndDispatch ()) display.sleep ();
96  *      }
97  *      display.dispose ();
98  * }
99  * </code></pre>
100  *
101  * <dl>
102  * <dt><b>Styles:</b><dd>H_SCROLL, V_SCROLL
103  * </dl>
104  *
105  * @see <a href="http://www.eclipse.org/swt/snippets/#scrolledcomposite">ScrolledComposite snippets</a>
106  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
107  */
108 public class ScrolledComposite extends Composite {
109
110         Control content;
111         Listener contentListener;
112         Listener filter;
113
114         int minHeight = 0;
115         int minWidth = 0;
116         boolean expandHorizontal = false;
117         boolean expandVertical = false;
118         boolean alwaysShowScroll = false;
119         boolean showFocusedControl = false;
120         boolean showNextFocusedControl = true;
121
122 /**
123  * Constructs a new instance of this class given its parent
124  * and a style value describing its behavior and appearance.
125  * <p>
126  * The style value is either one of the style constants defined in
127  * class <code>SWT</code> which is applicable to instances of this
128  * class, or must be built by <em>bitwise OR</em>'ing together
129  * (that is, using the <code>int</code> "|" operator) two or more
130  * of those <code>SWT</code> style constants. The class description
131  * lists the style constants that are applicable to the class.
132  * Style bits are also inherited from superclasses.
133  * </p>
134  *
135  * @param parent a widget which will be the parent of the new instance (cannot be null)
136  * @param style the style of widget to construct
137  *
138  * @exception IllegalArgumentException <ul>
139  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
140  * </ul>
141  * @exception SWTException <ul>
142  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
143  * </ul>
144  *
145  * @see SWT#H_SCROLL
146  * @see SWT#V_SCROLL
147  * @see #getStyle()
148  */
149 public ScrolledComposite(Composite parent, int style) {
150         super(parent, checkStyle(style));
151         super.setLayout(new ScrolledCompositeLayout());
152         ScrollBar hBar = getHorizontalBar ();
153         if (hBar != null) {
154                 hBar.setVisible(false);
155                 hBar.addListener (SWT.Selection, e -> hScroll());
156         }
157
158         ScrollBar vBar = getVerticalBar ();
159         if (vBar != null) {
160                 vBar.setVisible(false);
161                 vBar.addListener (SWT.Selection, e -> vScroll());
162         }
163
164         contentListener = e -> {
165                 if (e.type != SWT.Resize) return;
166                 layout(false);
167         };
168
169         filter = event -> {
170                 if (event.type == SWT.FocusIn) {
171                         if (!showNextFocusedControl) {
172                                 showNextFocusedControl = true;
173                         } else if (event.widget instanceof Control) {
174                                 Control control = (Control) event.widget;
175                                 if (contains(control)) showControl(control);
176                         }
177                 } else {
178                         Widget w = event.widget;
179                         if (w instanceof Control) {
180                                 showNextFocusedControl = w.getDisplay().getActiveShell() == ((Control) w).getShell();
181                         }
182                 }
183         };
184
185         addDisposeListener(e -> {
186                 getDisplay().removeFilter(SWT.FocusIn, filter);
187                 getDisplay().removeFilter(SWT.FocusOut, filter);
188         });
189 }
190
191 static int checkStyle (int style) {
192         int mask = SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
193         return style & mask;
194 }
195
196 boolean contains(Control control) {
197         if (control == null || control.isDisposed()) return false;
198
199         Composite parent = control.getParent();
200         while (parent != null && !(parent instanceof Shell)) {
201                 if (this == parent) return true;
202                 parent = parent.getParent();
203         }
204         return false;
205 }
206
207 /**
208  * Returns the Always Show Scrollbars flag.  True if the scrollbars are
209  * always shown even if they are not required.  False if the scrollbars are only
210  * visible when some part of the composite needs to be scrolled to be seen.
211  * The H_SCROLL and V_SCROLL style bits are also required to enable scrollbars in the
212  * horizontal and vertical directions.
213  *
214  * @return the Always Show Scrollbars flag value
215  */
216 public boolean getAlwaysShowScrollBars() {
217         /*
218          * This call is intentionally commented out, to allow this getter method to be
219          * called from a thread which is different from one that created the widget.
220          */
221         //checkWidget();
222         return alwaysShowScroll;
223 }
224
225 /**
226  * Returns <code>true</code> if the content control
227  * will be expanded to fill available horizontal space.
228  *
229  * @return the receiver's horizontal expansion state
230  *
231  * @exception SWTException <ul>
232  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
233  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
234  * </ul>
235  *
236  * @since 3.2
237  */
238 public boolean getExpandHorizontal() {
239         checkWidget();
240         return expandHorizontal;
241 }
242
243 /**
244  * Returns <code>true</code> if the content control
245  * will be expanded to fill available vertical space.
246  *
247  * @return the receiver's vertical expansion state
248  *
249  * @exception SWTException <ul>
250  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
251  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
252  * </ul>
253  *
254  * @since 3.2
255  */
256 public boolean getExpandVertical() {
257         checkWidget();
258         return expandVertical;
259 }
260
261 /**
262  * Returns the minimum width of the content control.
263  *
264  * @return the minimum width
265  *
266  * @exception SWTException <ul>
267  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
268  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
269  * </ul>
270  *
271  * @since 3.2
272  */
273 public int getMinWidth() {
274         checkWidget();
275         return minWidth;
276 }
277
278 /**
279  * Returns the minimum height of the content control.
280  *
281  * @return the minimum height
282  *
283  * @exception SWTException <ul>
284  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
285  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
286  * </ul>
287  *
288  * @since 3.2
289  */
290 public int getMinHeight() {
291         checkWidget();
292         return minHeight;
293 }
294
295 /**
296  * Get the content that is being scrolled.
297  *
298  * @return the control displayed in the content area
299  */
300 public Control getContent() {
301         /*
302          * This call is intentionally commented out, to allow this getter method to be
303          * called from a thread which is different from one that created the widget.
304          */
305         //checkWidget();
306         return content;
307 }
308
309 /**
310  * Returns <code>true</code> if the receiver automatically scrolls to a focused child control
311  * to make it visible. Otherwise, returns <code>false</code>.
312  *
313  * @return a boolean indicating whether focused child controls are automatically scrolled into the viewport
314  *
315  * @exception SWTException <ul>
316  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
317  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
318  * </ul>
319  *
320  * @since 3.4
321  */
322 public boolean getShowFocusedControl() {
323         checkWidget();
324         return showFocusedControl;
325 }
326
327 void hScroll() {
328         if (content == null) return;
329         Point location = content.getLocation ();
330         ScrollBar hBar = getHorizontalBar ();
331         int hSelection = hBar.getSelection ();
332         content.setLocation (-hSelection, location.y);
333 }
334 boolean needHScroll(Rectangle contentRect, boolean vVisible) {
335         ScrollBar hBar = getHorizontalBar();
336         if (hBar == null) return false;
337
338         Rectangle hostRect = getBounds();
339         int border = getBorderWidth();
340         hostRect.width -= 2*border;
341         ScrollBar vBar = getVerticalBar();
342         if (vVisible && vBar != null) hostRect.width -= vBar.getSize().x;
343
344         if (!expandHorizontal && contentRect.width > hostRect.width) return true;
345         if (expandHorizontal && minWidth > hostRect.width) return true;
346         return false;
347 }
348
349 boolean needVScroll(Rectangle contentRect, boolean hVisible) {
350         ScrollBar vBar = getVerticalBar();
351         if (vBar == null) return false;
352
353         Rectangle hostRect = getBounds();
354         int border = getBorderWidth();
355         hostRect.height -= 2*border;
356         ScrollBar hBar = getHorizontalBar();
357         if (hVisible && hBar != null) hostRect.height -= hBar.getSize().y;
358
359         if (!expandVertical && contentRect.height > hostRect.height) return true;
360         if (expandVertical && minHeight > hostRect.height) return true;
361         return false;
362 }
363
364 /**
365  * Return the point in the content that currently appears in the top left
366  * corner of the scrolled composite.
367  *
368  * @return the point in the content that currently appears in the top left
369  * corner of the scrolled composite.  If no content has been set, this returns
370  * (0, 0).
371  *
372  * @exception SWTException <ul>
373  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
374  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
375  * </ul>
376  *
377  * @since 2.0
378  */
379 public Point getOrigin() {
380         checkWidget();
381         if (content == null) return new Point(0, 0);
382         Point location = content.getLocation();
383         return new Point(-location.x, -location.y);
384 }
385 /**
386  * Scrolls the content so that the specified point in the content is in the top
387  * left corner.  If no content has been set, nothing will occur.
388  *
389  * Negative values will be ignored.  Values greater than the maximum scroll
390  * distance will result in scrolling to the end of the scrollbar.
391  *
392  * @param origin the point on the content to appear in the top left corner
393  *
394  * @exception SWTException <ul>
395  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
396  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
397  *    <li>ERROR_INVALID_ARGUMENT - value of origin is outside of content
398  * </ul>
399  * @since 2.0
400  */
401 public void setOrigin(Point origin) {
402         setOrigin(origin.x, origin.y);
403 }
404 /**
405  * Scrolls the content so that the specified point in the content is in the top
406  * left corner.  If no content has been set, nothing will occur.
407  *
408  * Negative values will be ignored.  Values greater than the maximum scroll
409  * distance will result in scrolling to the end of the scrollbar.
410  *
411  * @param x the x coordinate of the content to appear in the top left corner
412  *
413  * @param y the y coordinate of the content to appear in the top left corner
414  *
415  * @exception SWTException <ul>
416  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
417  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
418  * </ul>
419  *
420  * @since 2.0
421  */
422 public void setOrigin(int x, int y) {
423         checkWidget();
424         if (content == null) return;
425         ScrollBar hBar = getHorizontalBar ();
426         if (hBar != null) {
427                 hBar.setSelection(x);
428                 x = -hBar.getSelection ();
429         } else {
430                 x = 0;
431         }
432         ScrollBar vBar = getVerticalBar ();
433         if (vBar != null) {
434                 vBar.setSelection(y);
435                 y = -vBar.getSelection ();
436         } else {
437                 y = 0;
438         }
439         content.setLocation(x, y);
440 }
441 /**
442  * Set the Always Show Scrollbars flag.  True if the scrollbars are
443  * always shown even if they are not required.  False if the scrollbars are only
444  * visible when some part of the composite needs to be scrolled to be seen.
445  * The H_SCROLL and V_SCROLL style bits are also required to enable scrollbars in the
446  * horizontal and vertical directions.
447  *
448  * @param show true to show the scrollbars even when not required, false to show scrollbars only when required
449  *
450  * @exception SWTException <ul>
451  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
452  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
453  * </ul>
454  */
455 public void setAlwaysShowScrollBars(boolean show) {
456         checkWidget();
457         if (show == alwaysShowScroll) return;
458         alwaysShowScroll = show;
459         ScrollBar hBar = getHorizontalBar ();
460         if (hBar != null && alwaysShowScroll) hBar.setVisible(true);
461         ScrollBar vBar = getVerticalBar ();
462         if (vBar != null && alwaysShowScroll) vBar.setVisible(true);
463         layout(false);
464 }
465
466 /**
467  * Set the content that will be scrolled.
468  *
469  * @param content the control to be displayed in the content area
470  *
471  * @exception SWTException <ul>
472  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
473  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
474  * </ul>
475  */
476 public void setContent(Control content) {
477         checkWidget();
478         if (this.content != null && !this.content.isDisposed()) {
479                 this.content.removeListener(SWT.Resize, contentListener);
480                 this.content.setBounds(new Rectangle(-200, -200, 0, 0));
481         }
482
483         this.content = content;
484         ScrollBar vBar = getVerticalBar ();
485         ScrollBar hBar = getHorizontalBar ();
486         if (this.content != null) {
487                 if (vBar != null) {
488                         vBar.setMaximum (0);
489                         vBar.setThumb (0);
490                         vBar.setSelection(0);
491                 }
492                 if (hBar != null) {
493                         hBar.setMaximum (0);
494                         hBar.setThumb (0);
495                         hBar.setSelection(0);
496                 }
497                 content.setLocation(0, 0);
498                 layout(false);
499                 this.content.addListener(SWT.Resize, contentListener);
500         } else {
501                 if (hBar != null) hBar.setVisible(alwaysShowScroll);
502                 if (vBar != null) vBar.setVisible(alwaysShowScroll);
503         }
504 }
505 /**
506  * Configure the ScrolledComposite to resize the content object to be as wide as the
507  * ScrolledComposite when the width of the ScrolledComposite is greater than the
508  * minimum width specified in setMinWidth.  If the ScrolledComposite is less than the
509  * minimum width, the content will not be resized and instead the horizontal scroll bar will be
510  * used to view the entire width.
511  * If expand is false, this behaviour is turned off.  By default, this behaviour is turned off.
512  *
513  * @param expand true to expand the content control to fill available horizontal space
514  *
515  * @exception SWTException <ul>
516  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
517  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
518  * </ul>
519  */
520 public void setExpandHorizontal(boolean expand) {
521         checkWidget();
522         if (expand == expandHorizontal) return;
523         expandHorizontal = expand;
524         layout(false);
525 }
526 /**
527  * Configure the ScrolledComposite to resize the content object to be as tall as the
528  * ScrolledComposite when the height of the ScrolledComposite is greater than the
529  * minimum height specified in setMinHeight.  If the ScrolledComposite is less than the
530  * minimum height, the content will not be resized and instead the vertical scroll bar will be
531  * used to view the entire height.
532  * If expand is false, this behaviour is turned off.  By default, this behaviour is turned off.
533  *
534  * @param expand true to expand the content control to fill available vertical space
535  *
536  * @exception SWTException <ul>
537  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
538  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
539  * </ul>
540  */
541 public void setExpandVertical(boolean expand) {
542         checkWidget();
543         if (expand == expandVertical) return;
544         expandVertical = expand;
545         layout(false);
546 }
547 /**
548  * Sets the layout which is associated with the receiver to be
549  * the argument which may be null.
550  * <p>
551  * Note: No Layout can be set on this Control because it already
552  * manages the size and position of its children.
553  * </p>
554  *
555  * @param layout the receiver's new layout or null
556  *
557  * @exception SWTException <ul>
558  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
559  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
560  * </ul>
561  */
562 @Override
563 public void setLayout (Layout layout) {
564         checkWidget();
565         return;
566 }
567 /**
568  * Specify the minimum height at which the ScrolledComposite will begin scrolling the
569  * content with the vertical scroll bar.  This value is only relevant if
570  * setExpandVertical(true) has been set.
571  *
572  * @param height the minimum height or 0 for default height
573  *
574  * @exception SWTException <ul>
575  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
576  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
577  * </ul>
578  */
579 public void setMinHeight(int height) {
580         setMinSize(minWidth, height);
581 }
582 /**
583  * Specify the minimum width and height at which the ScrolledComposite will begin scrolling the
584  * content with the horizontal scroll bar.  This value is only relevant if
585  * setExpandHorizontal(true) and setExpandVertical(true) have been set.
586  *
587  * @param size the minimum size or null for the default size
588  *
589  * @exception SWTException <ul>
590  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
591  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
592  * </ul>
593  */
594 public void setMinSize(Point size) {
595         if (size == null) {
596                 setMinSize(0, 0);
597         } else {
598                 setMinSize(size.x, size.y);
599         }
600 }
601 /**
602  * Specify the minimum width and height at which the ScrolledComposite will begin scrolling the
603  * content with the horizontal scroll bar.  This value is only relevant if
604  * setExpandHorizontal(true) and setExpandVertical(true) have been set.
605  *
606  * @param width the minimum width or 0 for default width
607  * @param height the minimum height or 0 for default height
608  *
609  * @exception SWTException <ul>
610  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
611  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
612  * </ul>
613  */
614 public void setMinSize(int width, int height) {
615         checkWidget();
616         if (width == minWidth && height == minHeight) return;
617         minWidth = Math.max(0, width);
618         minHeight = Math.max(0, height);
619         layout(false);
620 }
621 /**
622  * Specify the minimum width at which the ScrolledComposite will begin scrolling the
623  * content with the horizontal scroll bar.  This value is only relevant if
624  * setExpandHorizontal(true) has been set.
625  *
626  * @param width the minimum width or 0 for default width
627  *
628  * @exception SWTException <ul>
629  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
630  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
631  * </ul>
632  */
633 public void setMinWidth(int width) {
634         setMinSize(width, minHeight);
635 }
636
637 /**
638  * Configure the receiver to automatically scroll to a focused child control
639  * to make it visible.
640  *
641  * If show is <code>false</code>, show a focused control is off.
642  * By default, show a focused control is off.
643  *
644  * @param show <code>true</code> to show a focused control.
645  *
646  * @exception SWTException <ul>
647  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
648  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
649  * </ul>
650  *
651  * @since 3.4
652  */
653 public void setShowFocusedControl(boolean show) {
654         checkWidget();
655         if (showFocusedControl == show) return;
656         Display display = getDisplay();
657         display.removeFilter(SWT.FocusIn, filter);
658         display.removeFilter(SWT.FocusOut, filter);
659         showFocusedControl = show;
660         if (!showFocusedControl) return;
661         display.addFilter(SWT.FocusIn, filter);
662         display.addFilter(SWT.FocusOut, filter);
663         Control control = display.getFocusControl();
664         if (contains(control)) showControl(control);
665 }
666
667 /**
668  * Scrolls the content of the receiver so that the control is visible.
669  *
670  * @param control the control to be shown
671  *
672  * @exception IllegalArgumentException <ul>
673  *    <li>ERROR_NULL_ARGUMENT - if the control is null</li>
674  *    <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
675  * </ul>
676  * @exception SWTException <ul>
677  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
678  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
679  * </ul>
680  *
681  * @since 3.4
682  */
683 public void showControl(Control control) {
684         checkWidget ();
685         if (control == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
686         if (control.isDisposed ()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
687         if (!contains(control)) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
688
689         Rectangle itemRect = getDisplay().map(control.getParent(), this, control.getBounds());
690         Rectangle area = getClientArea();
691         Point origin = getOrigin();
692         if (itemRect.x < 0) {
693                 origin.x = Math.max(0, origin.x + itemRect.x);
694         } else {
695                 if (area.width < itemRect.x + itemRect.width) origin.x = Math.max(0, origin.x + itemRect.x + Math.min(itemRect.width, area.width) - area.width);
696         }
697         if (itemRect.y < 0) {
698                 origin.y = Math.max(0, origin.y + itemRect.y);
699         } else {
700                 if (area.height < itemRect.y + itemRect.height) origin.y = Math.max(0, origin.y + itemRect.y + Math.min(itemRect.height, area.height) - area.height);
701         }
702         setOrigin(origin);
703 }
704
705 void vScroll() {
706         if (content == null) return;
707         Point location = content.getLocation ();
708         ScrollBar vBar = getVerticalBar ();
709         int vSelection = vBar.getSelection ();
710         content.setLocation (location.x, -vSelection);
711 }
712 }