1 /*******************************************************************************
2 * Copyright (c) 2000, 2012 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 * This class provides the layout for ScrolledComposite
22 *
23 * @see ScrolledComposite
24 */
25 class ScrolledCompositeLayout extends Layout {
26
27 boolean inLayout = false;
28 static final int DEFAULT_WIDTH = 64;
29 static final int DEFAULT_HEIGHT = 64;
30
31 @Override
computeSize(Composite composite, int wHint, int hHint, boolean flushCache)32 protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
33 ScrolledComposite sc = (ScrolledComposite)composite;
34 Point size = new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT);
35 if (sc.content != null) {
36 Point preferredSize = sc.content.computeSize(wHint, hHint, flushCache);
37 Point currentSize = sc.content.getSize();
38 size.x = sc.getExpandHorizontal() ? preferredSize.x : currentSize.x;
39 size.y = sc.getExpandVertical() ? preferredSize.y : currentSize.y;
40 }
41 size.x = Math.max(size.x, sc.minWidth);
42 size.y = Math.max(size.y, sc.minHeight);
43 if (wHint != SWT.DEFAULT) size.x = wHint;
44 if (hHint != SWT.DEFAULT) size.y = hHint;
45 return size;
46 }
47
48 @Override
flushCache(Control control)49 protected boolean flushCache(Control control) {
50 return true;
51 }
52
53 @Override
layout(Composite composite, boolean flushCache)54 protected void layout(Composite composite, boolean flushCache) {
55 if (inLayout) return;
56 ScrolledComposite sc = (ScrolledComposite)composite;
57 if (sc.content == null) return;
58 ScrollBar hBar = sc.getHorizontalBar();
59 ScrollBar vBar = sc.getVerticalBar();
60 if (hBar != null) {
61 if (hBar.getSize().y >= sc.getSize().y) {
62 return;
63 }
64 }
65 if (vBar != null) {
66 if (vBar.getSize().x >= sc.getSize().x) {
67 return;
68 }
69 }
70 inLayout = true;
71 Rectangle contentRect = sc.content.getBounds();
72 if (!sc.alwaysShowScroll) {
73 boolean hVisible = sc.needHScroll(contentRect, false);
74 boolean vVisible = sc.needVScroll(contentRect, hVisible);
75 if (!hVisible && vVisible) hVisible = sc.needHScroll(contentRect, vVisible);
76 if (hBar != null) hBar.setVisible(hVisible);
77 if (vBar != null) vBar.setVisible(vVisible);
78 }
79 Rectangle hostRect = sc.getClientArea();
80 if (sc.expandHorizontal) {
81 contentRect.width = Math.max(sc.minWidth, hostRect.width);
82 }
83 if (sc.expandVertical) {
84 contentRect.height = Math.max(sc.minHeight, hostRect.height);
85 }
86
87 GC gc = new GC (sc);
88 if (hBar != null) {
89 hBar.setMaximum (contentRect.width);
90 hBar.setThumb (Math.min (contentRect.width, hostRect.width));
91 hBar.setIncrement ((int) gc.getFontMetrics ().getAverageCharacterWidth ());
92 hBar.setPageIncrement (hostRect.width);
93 int hPage = contentRect.width - hostRect.width;
94 int hSelection = hBar.getSelection ();
95 if (hSelection >= hPage) {
96 if (hPage <= 0) {
97 hSelection = 0;
98 hBar.setSelection(0);
99 }
100 contentRect.x = -hSelection;
101 }
102 }
103
104 if (vBar != null) {
105 vBar.setMaximum (contentRect.height);
106 vBar.setThumb (Math.min (contentRect.height, hostRect.height));
107 vBar.setIncrement (gc.getFontMetrics ().getHeight ());
108 vBar.setPageIncrement (hostRect.height);
109 int vPage = contentRect.height - hostRect.height;
110 int vSelection = vBar.getSelection ();
111 if (vSelection >= vPage) {
112 if (vPage <= 0) {
113 vSelection = 0;
114 vBar.setSelection(0);
115 }
116 contentRect.y = -vSelection;
117 }
118 }
119 gc.dispose ();
120
121 sc.content.setBounds (contentRect);
122 inLayout = false;
123 }
124 }
125