1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  * Port to the D programming language:
11  *     Frank Benoit <benoit@tionex.de>
12  *******************************************************************************/
13 module org.eclipse.swt.custom.SashFormLayout;
14 
15 
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.graphics.Point;
18 import org.eclipse.swt.graphics.Rectangle;
19 import org.eclipse.swt.widgets.Composite;
20 import org.eclipse.swt.widgets.Control;
21 import org.eclipse.swt.widgets.Layout;
22 import org.eclipse.swt.widgets.Sash;
23 import org.eclipse.swt.custom.SashForm;
24 import org.eclipse.swt.custom.SashFormData;
25 import java.lang.all;
26 
27 /**
28  * This class provides the layout for SashForm
29  *
30  * @see SashForm
31  */
32 class SashFormLayout : Layout {
33 protected override Point computeSize(Composite composite, int wHint, int hHint, bool flushCache) {
34     SashForm sashForm = cast(SashForm)composite;
35     Control[] cArray = sashForm.getControls(true);
36     int width = 0;
37     int height = 0;
38     if (cArray.length is 0) {
39         if (wHint !is SWT.DEFAULT) width = wHint;
40         if (hHint !is SWT.DEFAULT) height = hHint;
41         return new Point(width, height);
42     }
43     // determine control sizes
44     bool vertical = sashForm.getOrientation() is SWT.VERTICAL;
45     int maxIndex = 0;
46     int maxValue = 0;
47     for (int i = 0; i < cArray.length; i++) {
48         if (vertical) {
49             Point size = cArray[i].computeSize(wHint, SWT.DEFAULT, flushCache);
50             if (size.y > maxValue) {
51                 maxIndex = i;
52                 maxValue = size.y;
53             }
54             width = Math.max(width, size.x);
55         } else {
56             Point size = cArray[i].computeSize(SWT.DEFAULT, hHint, flushCache);
57             if (size.x > maxValue) {
58                 maxIndex = i;
59                 maxValue = size.x;
60             }
61             height = Math.max(height, size.y);
62         }
63     }
64     // get the ratios
65     long[] ratios = new long[cArray.length];
66     long total = 0;
67     for (int i = 0; i < cArray.length; i++) {
68         Object data = cArray[i].getLayoutData();
69         if ( auto sfd = cast(SashFormData)data) {
70             ratios[i] = sfd.weight;
71         } else {
72             data = new SashFormData();
73             cArray[i].setLayoutData(data);
74             (cast(SashFormData)data).weight = ratios[i] = ((200 << 16) + 999) / 1000;
75 
76         }
77         total += ratios[i];
78     }
79     if (ratios[maxIndex] > 0) {
80         int sashwidth = sashForm.sashes.length > 0 ? sashForm.SASH_WIDTH + sashForm.sashes [0].getBorderWidth() * 2 : sashForm.SASH_WIDTH;
81         if (vertical) {
82             height += cast(int)(total * maxValue / ratios[maxIndex]) + (cArray.length - 1) * sashwidth;
83         } else {
84             width += cast(int)(total * maxValue / ratios[maxIndex]) + (cArray.length - 1) * sashwidth;
85         }
86     }
87     width += sashForm.getBorderWidth()*2;
88     height += sashForm.getBorderWidth()*2;
89     if (wHint !is SWT.DEFAULT) width = wHint;
90     if (hHint !is SWT.DEFAULT) height = hHint;
91     return new Point(width, height);
92 }
93 
94 protected override bool flushCache(Control control) {
95     return true;
96 }
97 
98 protected override void layout(Composite composite, bool flushCache) {
99     SashForm sashForm = cast(SashForm)composite;
100     Rectangle area = sashForm.getClientArea();
101     if (area.width <= 1 || area.height <= 1) return;
102 
103     Control[] newControls = sashForm.getControls(true);
104     if (sashForm.controls.length is 0 && newControls.length is 0) return;
105     sashForm.controls = newControls;
106 
107     Control[] controls = sashForm.controls;
108 
109     if (sashForm.maxControl !is null && !sashForm.maxControl.isDisposed()) {
110         for (int i= 0; i < controls.length; i++){
111             if (controls[i] !is sashForm.maxControl) {
112                 controls[i].setBounds(-200, -200, 0, 0);
113             } else {
114                 controls[i].setBounds(area);
115             }
116         }
117         return;
118     }
119 
120     // keep just the right number of sashes
121     if (sashForm.sashes.length < controls.length - 1) {
122         Sash[] newSashes = new Sash[controls.length - 1];
123         System.arraycopy(sashForm.sashes, 0, newSashes, 0, sashForm.sashes.length);
124         for (auto i = sashForm.sashes.length; i < newSashes.length; i++) {
125             newSashes[i] = new Sash(sashForm, sashForm.sashStyle);
126             newSashes[i].setBackground(sashForm.background);
127             newSashes[i].setForeground(sashForm.foreground);
128             newSashes[i].addListener(SWT.Selection, sashForm.sashListener);
129         }
130         sashForm.sashes = newSashes;
131     }
132     if (sashForm.sashes.length > controls.length - 1) {
133         if (controls.length is 0) {
134             for (int i = 0; i < sashForm.sashes.length; i++) {
135                 sashForm.sashes[i].dispose();
136             }
137             sashForm.sashes = new Sash[0];
138         } else {
139             Sash[] newSashes = new Sash[controls.length - 1];
140             System.arraycopy(sashForm.sashes, 0, newSashes, 0, newSashes.length);
141             for (auto i = controls.length - 1; i < sashForm.sashes.length; i++) {
142                 sashForm.sashes[i].dispose();
143             }
144             sashForm.sashes = newSashes;
145         }
146     }
147     if (controls.length is 0) return;
148     Sash[] sashes = sashForm.sashes;
149     // get the ratios
150     long[] ratios = new long[controls.length];
151     long total = 0;
152     for (int i = 0; i < controls.length; i++) {
153         Object data = controls[i].getLayoutData();
154         if ( auto sfd = cast(SashFormData)data ) {
155             ratios[i] = sfd.weight;
156         } else {
157             data = new SashFormData();
158             controls[i].setLayoutData(data);
159             (cast(SashFormData)data).weight = ratios[i] = ((200 << 16) + 999) / 1000;
160 
161         }
162         total += ratios[i];
163     }
164 
165     int sashwidth = sashes.length > 0 ? sashForm.SASH_WIDTH + sashes [0].getBorderWidth() * 2 : sashForm.SASH_WIDTH;
166     if (sashForm.getOrientation() is SWT.HORIZONTAL) {
167         int width = cast(int)(ratios[0] * (area.width - sashes.length * sashwidth) / total);
168         int x = area.x;
169         controls[0].setBounds(x, area.y, width, area.height);
170         x += width;
171         for (int i = 1; i < controls.length - 1; i++) {
172             sashes[i - 1].setBounds(x, area.y, sashwidth, area.height);
173             x += sashwidth;
174             width = cast(int)(ratios[i] * (area.width - sashes.length * sashwidth) / total);
175             controls[i].setBounds(x, area.y, width, area.height);
176             x += width;
177         }
178         if (controls.length > 1) {
179             sashes[sashes.length - 1].setBounds(x, area.y, sashwidth, area.height);
180             x += sashwidth;
181             width = area.width - x;
182             controls[controls.length - 1].setBounds(x, area.y, width, area.height);
183         }
184     } else {
185         int height = cast(int)(ratios[0] * (area.height - sashes.length * sashwidth) / total);
186         int y = area.y;
187         controls[0].setBounds(area.x, y, area.width, height);
188         y += height;
189         for (int i = 1; i < controls.length - 1; i++) {
190             sashes[i - 1].setBounds(area.x, y, area.width, sashwidth);
191             y += sashwidth;
192             height = cast(int)(ratios[i] * (area.height - sashes.length * sashwidth) / total);
193             controls[i].setBounds(area.x, y, area.width, height);
194             y += height;
195         }
196         if (controls.length > 1) {
197             sashes[sashes.length - 1].setBounds(area.x, y, area.width, sashwidth);
198             y += sashwidth;
199             height = area.height - y;
200             controls[controls.length - 1].setBounds(area.x, y, area.width, height);
201         }
202 
203     }
204 }
205 }