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.ui.internal.browser;
15 
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.custom.ScrolledComposite;
18 import org.eclipse.swt.graphics.Color;
19 import org.eclipse.swt.graphics.Font;
20 import org.eclipse.swt.graphics.Point;
21 import org.eclipse.swt.graphics.Rectangle;
22 import org.eclipse.swt.widgets.Composite;
23 import org.eclipse.swt.widgets.Control;
24 import org.eclipse.swt.widgets.ScrollBar;
25 
26 public abstract class FallbackScrolledComposite extends ScrolledComposite {
27 	private static final int H_SCROLL_INCREMENT = 5;
28 
29 	private static final int V_SCROLL_INCREMENT = 64;
30 
31 	/**
32 	 * Creates the new instance.
33 	 *
34 	 * @param parent
35 	 *            the parent composite
36 	 * @param style
37 	 *            the style to use
38 	 */
FallbackScrolledComposite(Composite parent, int style)39 	public FallbackScrolledComposite(Composite parent, int style) {
40 		super(parent, style);
41 		addListener(SWT.Resize, e -> reflow(true));
42 		setExpandVertical(true);
43 		setExpandHorizontal(true);
44 		initializeScrollBars();
45 	}
46 
47 	/**
48 	 * Sets the foreground of the control and its content.
49 	 *
50 	 * @param fg
51 	 *            the new foreground color
52 	 */
53 	@Override
setForeground(Color fg)54 	public void setForeground(Color fg) {
55 		super.setForeground(fg);
56 		if (getContent() != null)
57 			getContent().setForeground(fg);
58 	}
59 
60 	/**
61 	 * Sets the background of the control and its content.
62 	 *
63 	 * @param bg
64 	 *            the new background color
65 	 */
66 	@Override
setBackground(Color bg)67 	public void setBackground(Color bg) {
68 		super.setBackground(bg);
69 		if (getContent() != null)
70 			getContent().setBackground(bg);
71 	}
72 
73 	/**
74 	 * Sets the font of the form. This font will be used to render the title
75 	 * text. It will not affect the body.
76 	 */
77 	@Override
setFont(Font font)78 	public void setFont(Font font) {
79 		super.setFont(font);
80 		if (getContent() != null)
81 			getContent().setFont(font);
82 	}
83 
84 	/**
85 	 * Overrides 'super' to pass the proper colors and font
86 	 */
87 	@Override
setContent(Control content)88 	public void setContent(Control content) {
89 		super.setContent(content);
90 		if (content != null) {
91 			content.setForeground(getForeground());
92 			content.setBackground(getBackground());
93 			content.setFont(getFont());
94 		}
95 	}
96 
97 	/**
98 	 * If content is set, transfers focus to the content.
99 	 */
100 	@Override
setFocus()101 	public boolean setFocus() {
102 		if (getContent() != null)
103 			return getContent().setFocus();
104 		return super.setFocus();
105 	}
106 
107 	/**
108 	 * Recomputes the body layout and the scroll bars. The method should be used
109 	 * when changes somewhere in the form body invalidate the current layout
110 	 * and/or scroll bars.
111 	 *
112 	 * @param flushCache
113 	 *            if <code>true</code>, drop the cached data
114 	 */
reflow(boolean flushCache)115 	public void reflow(boolean flushCache) {
116 		Composite c = (Composite) getContent();
117 		Rectangle clientArea = getClientArea();
118 		if (c == null)
119 			return;
120 
121 		Point newSize = c
122 				.computeSize(clientArea.width, SWT.DEFAULT, flushCache);
123 
124 		setMinSize(newSize);
125 		updatePageIncrement();
126 		layout(flushCache);
127 	}
128 
updatePageIncrement()129 	private void updatePageIncrement() {
130 		ScrollBar vbar = getVerticalBar();
131 		if (vbar != null) {
132 			Rectangle clientArea = getClientArea();
133 			int increment = clientArea.height - 5;
134 			vbar.setPageIncrement(increment);
135 		}
136 	}
137 
initializeScrollBars()138 	private void initializeScrollBars() {
139 		ScrollBar hbar = getHorizontalBar();
140 		if (hbar != null) {
141 			hbar.setIncrement(H_SCROLL_INCREMENT);
142 		}
143 		ScrollBar vbar = getVerticalBar();
144 		if (vbar != null) {
145 			vbar.setIncrement(V_SCROLL_INCREMENT);
146 		}
147 		updatePageIncrement();
148 	}
149 }
150