comparison org.eclipse.ui.forms/src/org/eclipse/ui/forms/MasterDetailsBlock.d @ 12:bc29606a740c

Added dwt-addons in original directory structure of eclipse.org
author Frank Benoit <benoit@tionex.de>
date Sat, 14 Mar 2009 18:23:29 +0100
parents
children
comparison
equal deleted inserted replaced
11:43904fec5dca 12:bc29606a740c
1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 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.ui.forms.MasterDetailsBlock;
14
15 import org.eclipse.ui.forms.DetailsPart;
16 import org.eclipse.ui.forms.IManagedForm;
17 import org.eclipse.ui.forms.FormColors;
18 import org.eclipse.ui.forms.IFormColors;
19
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.custom.SashForm;
22 import org.eclipse.swt.graphics.GC;
23 import org.eclipse.swt.graphics.Point;
24 import org.eclipse.swt.layout.GridData;
25 import org.eclipse.swt.layout.GridLayout;
26 import org.eclipse.swt.widgets.Composite;
27 import org.eclipse.swt.widgets.Control;
28 import org.eclipse.swt.widgets.Event;
29 import org.eclipse.swt.widgets.Listener;
30 import org.eclipse.swt.widgets.Sash;
31 import org.eclipse.ui.forms.widgets.FormToolkit;
32 import org.eclipse.ui.forms.widgets.ScrolledForm;
33
34 import java.lang.all;
35 import java.util.ArrayList;
36 import java.util.Iterator;
37 import java.util.Set;
38
39 /**
40 * This class implements the 'master/details' UI pattern suitable for inclusion
41 * in a form. The block consists of two parts: 'master' and 'details' in a sash
42 * form that allows users to change the relative ratio on the page. The master
43 * part needs to be created by the users of this class. The details part is
44 * created by the block.
45 * <p>
46 * The master part is responsible for adding itself as a form part and firing
47 * selection events. The details part catches the selection events and tries to
48 * load a page registered to handle the selected object(s). The page shows the
49 * details of the selected object(s) and allows users to edit them.
50 * <p>
51 * Details pages can be registered statically using 'registerPage' or
52 * dynamically through the use of 'IDetailsPageProvider' in case where different
53 * pages need to be shown for objects of the same type depending on their state.
54 * <p>
55 * Subclasses are required to implement abstract methods of this class. Master
56 * part must be created and at least one details page should be registered in
57 * order to show details of the objects selected in the master part. Tool bar
58 * actions can be optionally added to the tool bar manager.
59 *
60 * @see DetailsPart
61 * @see IDetailsPage
62 * @see IDetailsPageProvider
63 * @since 3.0
64 */
65 public abstract class MasterDetailsBlock {
66 /**
67 * Details part created by the block. No attempt should be made to access
68 * this field inside <code>createMasterPart</code> because it has not been
69 * created yet and will be <code>null</code>.
70 */
71 protected DetailsPart detailsPart;
72
73 /**
74 * The form that is the parent of both master and details part. The form
75 * allows users to change the ratio between the two parts.
76 */
77 protected SashForm sashForm;
78
79 static const int DRAGGER_SIZE = 40;
80
81 class MDSashForm : SashForm {
82 ArrayList sashes;
83 Listener listener;
84 public this(Composite parent, int style) {
85 sashes = new ArrayList();
86 listener = dgListener ( (Event e){
87 switch (e.type) {
88 case SWT.MouseEnter:
89 e.widget.setData("hover", Boolean.TRUE); //$NON-NLS-1$
90 (cast(Control)e.widget).redraw();
91 break;
92 case SWT.MouseExit:
93 e.widget.setData("hover", null); //$NON-NLS-1$
94 (cast(Control)e.widget).redraw();
95 break;
96 case SWT.Paint:
97 onSashPaint(e);
98 break;
99 case SWT.Resize:
100 hookSashListeners();
101 break;
102 default:
103 }
104 });
105 super(parent, style);
106 }
107
108 public void layout(bool changed) {
109 super.layout(changed);
110 hookSashListeners();
111 }
112
113 public void layout(Control [] children) {
114 super.layout(children);
115 hookSashListeners();
116 }
117
118 private void hookSashListeners() {
119 purgeSashes();
120 Control [] children = getChildren();
121 for (int i=0; i<children.length; i++) {
122 if ( auto sash = cast(Sash)children[i] ) {
123 if (sashes.contains(sash))
124 continue;
125 sash.addListener(SWT.Paint, listener);
126 sash.addListener(SWT.MouseEnter, listener);
127 sash.addListener(SWT.MouseExit, listener);
128 sashes.add(sash);
129 }
130 }
131 }
132 private void purgeSashes() {
133 for (Iterator iter=sashes.iterator(); iter.hasNext();) {
134 Sash sash = cast(Sash)iter.next();
135 if (sash.isDisposed())
136 iter.remove();
137 }
138 }
139 }
140
141 /**
142 * Creates the content of the master/details block inside the managed form.
143 * This method should be called as late as possible inside the parent part.
144 *
145 * @param managedForm
146 * the managed form to create the block in
147 */
148 public void createContent(IManagedForm managedForm) {
149 final ScrolledForm form = managedForm.getForm();
150 FormToolkit toolkit = managedForm.getToolkit();
151 GridLayout layout = new GridLayout();
152 layout.marginWidth = 0;
153 layout.marginHeight = 0;
154 form.getBody().setLayout(layout);
155 sashForm = new MDSashForm(form.getBody(), SWT.NULL);
156 sashForm.setData("form", cast(Object)managedForm); //$NON-NLS-1$
157 toolkit.adapt(sashForm, false, false);
158 sashForm.setMenu(form.getBody().getMenu());
159 sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
160 createMasterPart(managedForm, sashForm);
161 createDetailsPart(managedForm, sashForm);
162 hookResizeListener();
163 createToolBarActions(managedForm);
164 form.updateToolBar();
165 }
166
167 private void hookResizeListener() {
168 Listener listener = (cast(MDSashForm)sashForm).listener;
169 Control [] children = sashForm.getChildren();
170 for (int i=0; i<children.length; i++) {
171 if (null !is cast(Sash)children[i] ) continue;
172 children[i].addListener(SWT.Resize, listener);
173 }
174 }
175
176 /**
177 * Implement this method to create a master part in the provided parent.
178 * Typical master parts are section parts that contain tree or table viewer.
179 *
180 * @param managedForm
181 * the parent form
182 * @param parent
183 * the parent composite
184 */
185 protected abstract void createMasterPart(IManagedForm managedForm,
186 Composite parent);
187
188 /**
189 * Implement this method to statically register pages for the expected
190 * object types. This mechanism can be used when there is 1-&gt;1 mapping
191 * between object classes and details pages.
192 *
193 * @param detailsPart
194 * the details part
195 */
196 protected abstract void registerPages(DetailsPart detailsPart);
197
198 /**
199 * Implement this method to create form tool bar actions and add them to the
200 * form tool bar if desired.
201 *
202 * @param managedForm
203 * the form that owns the tool bar
204 */
205 protected abstract void createToolBarActions(IManagedForm managedForm);
206
207 private void createDetailsPart(IManagedForm mform, Composite parent) {
208 detailsPart = new DetailsPart(mform, parent, SWT.NULL);
209 mform.addPart(detailsPart);
210 registerPages(detailsPart);
211 }
212
213 private void onSashPaint(Event e) {
214 Sash sash = cast(Sash)e.widget;
215 IManagedForm form = cast(IManagedForm)sash.getParent().getData("form"); //$NON-NLS-1$
216 FormColors colors = form.getToolkit().getColors();
217 bool vertical = (sash.getStyle() & SWT.VERTICAL) !is 0;
218 GC gc = e.gc;
219 Boolean hover = cast(Boolean)sash.getData("hover"); //$NON-NLS-1$
220 gc.setBackground(colors.getColor(IFormColors.TB_BG));
221 gc.setForeground(colors.getColor(IFormColors.TB_BORDER));
222 Point size = sash.getSize();
223 if (vertical) {
224 if (hover !is null)
225 gc.fillRectangle(0, 0, size.x, size.y);
226 //else
227 //gc.drawLine(1, 0, 1, size.y-1);
228 }
229 else {
230 if (hover !is null)
231 gc.fillRectangle(0, 0, size.x, size.y);
232 //else
233 //gc.drawLine(0, 1, size.x-1, 1);
234 }
235 }
236 }