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 CTabFolder
22  *
23  * @see CTabFolder
24  */
25 class CTabFolderLayout extends Layout {
26 @Override
computeSize(Composite composite, int wHint, int hHint, boolean flushCache)27 protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
28 	CTabFolder folder = (CTabFolder)composite;
29 	CTabItem[] items = folder.items;
30 	CTabFolderRenderer renderer = folder.renderer;
31 	// preferred width of tab area to show all tabs
32 	int tabW = 0;
33 	int selectedIndex = folder.selectedIndex;
34 	if (selectedIndex == -1) selectedIndex = 0;
35 	GC gc = new GC(folder);
36 	for (int i = 0; i < items.length; i++) {
37 		if (folder.single) {
38 			tabW = Math.max(tabW, renderer.computeSize(i, SWT.SELECTED, gc, SWT.DEFAULT, SWT.DEFAULT).x);
39 		} else {
40 			int state = 0;
41 			if (i == selectedIndex) state |= SWT.SELECTED;
42 			tabW += renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
43 		}
44 	}
45 
46 	int width = 0, wrapHeight = 0;
47 	boolean leftControl = false, rightControl = false;
48 	if (wHint == SWT.DEFAULT) {
49 		for (int i = 0; i < folder.controls.length; i++) {
50 			Control control = folder.controls[i];
51 			if (!control.isDisposed() && control.getVisible()) {
52 				if ((folder.controlAlignments[i] & SWT.LEAD) != 0) {
53 					leftControl = true;
54 				} else {
55 					rightControl = true;
56 				}
57 				width += control.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
58 			}
59 		}
60 	} else {
61 		Point size = new Point (wHint, hHint);
62 		boolean[][] positions = new boolean[1][];
63 		Rectangle[] rects = folder.computeControlBounds(size, positions);
64 		int minY = Integer.MAX_VALUE, maxY = 0;
65 		for (int i = 0; i < rects.length; i++) {
66 			if (positions[0][i]) {
67 				minY = Math.min(minY, rects[i].y);
68 				maxY = Math.max(maxY, rects[i].y + rects[i].height);
69 				wrapHeight = maxY - minY;
70 			} else {
71 				if ((folder.controlAlignments[i] & SWT.LEAD) != 0) {
72 					leftControl = true;
73 				} else {
74 					rightControl = true;
75 				}
76 				width += rects[i].width;
77 			}
78 		}
79 	}
80 	if (leftControl) width += CTabFolder.SPACING * 2;
81 	if (rightControl) width += CTabFolder.SPACING * 2;
82 	tabW += width;
83 
84 	gc.dispose();
85 
86 	int controlW = 0;
87 	int controlH = 0;
88 	// preferred size of controls in tab items
89 	for (CTabItem item : items) {
90 		Control control = item.control;
91 		if (control != null && !control.isDisposed()){
92 			Point size = control.computeSize (wHint, hHint, flushCache);
93 			controlW = Math.max (controlW, size.x);
94 			controlH = Math.max (controlH, size.y);
95 		}
96 	}
97 
98 	int minWidth = Math.max(tabW, controlW + folder.marginWidth);
99 	int minHeight = (folder.minimized) ? 0 : controlH + wrapHeight;
100 	if (minWidth == 0) minWidth = CTabFolder.DEFAULT_WIDTH;
101 	if (minHeight == 0) minHeight = CTabFolder.DEFAULT_HEIGHT;
102 
103 	if (wHint != SWT.DEFAULT) minWidth  = wHint;
104 	if (hHint != SWT.DEFAULT) minHeight = hHint;
105 
106 	return new Point (minWidth, minHeight);
107 }
108 @Override
flushCache(Control control)109 protected boolean flushCache(Control control) {
110 	return true;
111 }
112 @Override
layout(Composite composite, boolean flushCache)113 protected void layout(Composite composite, boolean flushCache) {
114 	CTabFolder folder = (CTabFolder)composite;
115 	// resize content
116 	if (folder.selectedIndex != -1) {
117 		Control control = folder.items[folder.selectedIndex].control;
118 		if (control != null && !control.isDisposed()) {
119 			control.setBounds(folder.getClientArea());
120 		}
121 	}
122 }
123 }
124