comparison dwtx/novocode/ishell/InternalShell.d @ 188:e3780acbbf80

Added ported sources from Novocode, thanks to WasserDragoon
author Frank Benoit <benoit@tionex.de>
date Sun, 26 Oct 2008 14:54:39 +0100
parents
children 71ca5bcf2307
comparison
equal deleted inserted replaced
187:293a2f22f944 188:e3780acbbf80
1 /*******************************************************************************
2 * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html
7 *
8 * Contributors:
9 * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation
10 *******************************************************************************/
11
12 module dwtx.novocode.ishell.InternalShell;
13
14 import dwt.DWT;
15 import dwt.DWTException;
16 import dwt.graphics.Image;
17 import dwt.graphics.Point;
18 import dwt.graphics.Rectangle;
19 import dwt.layout.FormAttachment;
20 import dwt.layout.FormData;
21 import dwt.layout.FormLayout;
22 import dwt.widgets.Composite;
23 import dwt.widgets.Control;
24 import dwt.widgets.Event;
25 import dwt.widgets.Listener;
26 import dwt.widgets.Menu;
27
28 import dwtx.novocode.SizeBorder;
29 import dwtx.novocode.SizeGrip;
30 import dwtx.novocode.ishell.DesktopForm;
31 import dwtx.novocode.ishell.internal.TitleBar;
32 import dwtx.novocode.ishell.internal.TitleBarButton;
33
34 alias char[] String;
35
36
37 /**
38 * An internal shell which can be placed on a DesktopForm.
39 * <p>
40 * <dl>
41 * <dt><b>Styles:</b></dt>
42 * <dd>RESIZE, CLOSE, MAX, ON_TOP, TOOL, NO_RADIO_GROUP</dd>
43 * <dt><b>Events:</b></dt>
44 * <dd>(none)</dd>
45 * </dl>
46 * </p>
47 *
48 * @author Stefan Zeiger (szeiger@novocode.com)
49 * @since Jan 21, 2005
50 * @version $Id: InternalShell.java 344 2005-07-09 22:37:51 +0000 (Sat, 09 Jul 2005) szeiger $
51 */
52
53 // [TODO] Support styles NO_TRIM, BORDER, TITLE
54 // [TODO] Separate "minimized" from "not visible"
55
56 class InternalShell : Composite
57 {
58 private static const int BORDER_SIZE = 4;
59
60 private Composite contentPane;
61 private TitleBar titleBar;
62 private SizeGrip sizeGrip;
63 private SizeBorder sizeBorder;
64 private int minWidth = 112;
65 private int minHeight;
66 private DesktopForm desktop;
67 private bool maximized;
68 private Rectangle pluralizedBounds;
69 private int titleHeight;
70 private int style;
71 private TitleBarButton closeButton, maxButton, minButton;
72
73 Control focusControl;
74
75
76 this(DesktopForm parent, int style)
77 {
78 super(parent, checkStyle(style));
79 this.desktop = parent;
80 this.style = style;
81 setBackground(getDisplay().getSystemColor(DWT.COLOR_WIDGET_BACKGROUND));
82 FormLayout layout = new FormLayout();
83 setLayout(layout);
84 FormData fd;
85
86 titleBar = new TitleBar(this, style & (DWT.CLOSE | DWT.RESIZE | DWT.MAX | DWT.TOOL | DWT.MIN));
87 titleHeight = titleBar.computeSize(DWT.DEFAULT, DWT.DEFAULT, true).y;
88
89 Control leftButton = null;
90
91 if((style & (DWT.CLOSE | DWT.MAX | DWT.MIN)) !is 0)
92 {
93 closeButton = new TitleBarButton(this, DWT.CLOSE);
94 if((style & DWT.CLOSE) is 0) closeButton.setEnabled(false);
95 closeButton.addListener(DWT.Selection, dgListener(&closeListener));
96 fd = new FormData(titleHeight, titleHeight);
97 if(leftButton !is null) fd.right = new FormAttachment(leftButton);
98 else fd.right = new FormAttachment(100, -BORDER_SIZE);
99 fd.top = new FormAttachment(0, BORDER_SIZE);
100 closeButton.setLayoutData(fd);
101 leftButton = closeButton;
102
103 if((style & (DWT.MAX|DWT.MIN)) !is 0)
104 {
105 maxButton = new TitleBarButton(this, DWT.MAX);
106 if((style & DWT.MAX) is 0) maxButton.setEnabled(false);
107 maxButton.addListener(DWT.Selection, dgListener(&maximizeListener));
108 fd = new FormData(titleHeight, titleHeight);
109 if(leftButton !is null) fd.right = new FormAttachment(leftButton);
110 else fd.right = new FormAttachment(100, -BORDER_SIZE);
111 fd.top = new FormAttachment(0, BORDER_SIZE);
112 maxButton.setLayoutData(fd);
113 leftButton = maxButton;
114
115 minButton = new TitleBarButton(this, DWT.MIN);
116 if((style & DWT.MIN) is 0) minButton.setEnabled(false);
117 minButton.addListener(DWT.Selection, dgListener(&minimizeListener));
118 fd = new FormData(titleHeight, titleHeight);
119 if(leftButton !is null) fd.right = new FormAttachment(leftButton);
120 else fd.right = new FormAttachment(100, -BORDER_SIZE);
121 fd.top = new FormAttachment(0, BORDER_SIZE);
122 minButton.setLayoutData(fd);
123 leftButton = minButton;
124 }
125 }
126
127 fd = new FormData();
128 fd.left = new FormAttachment(0, BORDER_SIZE);
129 if(leftButton !is null) fd.right = new FormAttachment(leftButton);
130 else fd.right = new FormAttachment(100, -BORDER_SIZE);
131 fd.top = new FormAttachment(0, BORDER_SIZE);
132 titleBar.setLayoutData(fd);
133
134 contentPane = new Composite(this, DWT.NONE);
135 fd = new FormData();
136 fd.left = new FormAttachment(0, BORDER_SIZE);
137 fd.right = new FormAttachment(100, -BORDER_SIZE);
138 fd.top = new FormAttachment(titleBar, 1);
139 fd.bottom = new FormAttachment(100, -BORDER_SIZE);
140 contentPane.setLayoutData(fd);
141
142 sizeBorder = new SizeBorder(this, this, DWT.BORDER);
143 sizeBorder.setBorderWidth(BORDER_SIZE);
144 fd = new FormData();
145 fd.left = new FormAttachment(0);
146 fd.right = new FormAttachment(100);
147 fd.top = new FormAttachment(0);
148 fd.bottom = new FormAttachment(100);
149 sizeBorder.setLayoutData(fd);
150
151 minHeight = titleHeight + 2*BORDER_SIZE;
152 sizeBorder.setMinimumShellSize(minWidth, minHeight);
153 sizeBorder.setCornerSize(titleHeight + BORDER_SIZE);
154 if((style & DWT.RESIZE) is 0) sizeBorder.setEnabled(false);
155
156 setSize(320, 240);
157 setVisible(false);
158
159 desktop.manage(this);
160 }
161
162
163 private void closeListener(Event event)
164 {
165 close();
166 }
167
168
169 private void maximizeListener(Event event)
170 {
171 setMaximized(!maximized);
172 }
173
174
175 private void minimizeListener(Event event)
176 {
177 setMinimized(true);
178 }
179
180
181 private static int checkStyle(int style)
182 {
183 int mask = DWT.NO_RADIO_GROUP;
184 style &= mask;
185 return style;
186 }
187
188
189 public int getStyle()
190 {
191 return style;
192 }
193
194
195 public Composite getContentPane() { return contentPane; }
196
197
198 public void setText(String s) { titleBar.setText(s); }
199
200 public String getText() { return titleBar.getText(); }
201
202
203 public void setCustomMenu(Menu menu) { titleBar.setMenu(menu); }
204
205 public Menu getCustomMenu() { return titleBar.getMenu(); }
206
207
208 public void setImage(Image image) { titleBar.setImage(image); }
209
210 public Image getImage() { return titleBar.getImage(); }
211
212
213 public void createSizeGrip(int style)
214 {
215 checkWidget();
216 if(sizeGrip !is null)
217 throw new DWTException("SizeGrip was already created");
218 if((this.style & DWT.RESIZE) is 0)
219 throw new DWTException("Cannot create SizeGrip for InternalShell without style RESIZE");
220 sizeGrip = new SizeGrip(this, this, style);
221 sizeGrip.setBackground(contentPane.getBackground());
222 sizeGrip.moveAbove(contentPane);
223 FormData fd = new FormData();
224 fd.right = new FormAttachment(100, -BORDER_SIZE);
225 fd.bottom = new FormAttachment(100, -BORDER_SIZE);
226 sizeGrip.setLayoutData(fd);
227 sizeGrip.setMinimumShellSize(minWidth, minHeight);
228 if(isVisible()) layout(true);
229 }
230
231
232 public Point computeSize(int wHint, int hHint, bool changed)
233 {
234 Point p = super.computeSize(wHint, hHint, changed);
235 if(p.x < minWidth) p.x = minWidth;
236 if(p.y < minHeight) p.y = minHeight;
237 return p;
238 }
239
240
241 public void setSize(int width, int height)
242 {
243 if(width < minWidth) width = minWidth;
244 if(height < minHeight) height = minHeight;
245 super.setSize(width, height);
246 }
247
248
249 public void setBounds(int x, int y, int width, int height)
250 {
251 if(width < minWidth) width = minWidth;
252 if(height < minHeight) height = minHeight;
253 super.setBounds(x, y, width, height);
254 }
255
256
257 public void setMinimumSize(int width, int height)
258 {
259 checkWidget();
260 minWidth = width;
261 minHeight = height;
262 sizeGrip.setMinimumShellSize(minWidth, minHeight);
263 sizeBorder.setMinimumShellSize(minWidth, minHeight);
264 Point size = getSize();
265 if(size.x < minWidth || size.y < minHeight)
266 setSize(Math.max(minWidth, size.x), Math.max(minHeight, size.y));
267 }
268
269
270 public void close()
271 {
272 Event event = new Event();
273 notifyListeners(DWT.Close, event);
274 if(event.doit && !isDisposed()) dispose();
275 }
276
277
278 public void open()
279 {
280 desktop.activate(this);
281 setVisible(true);
282 setFocus();
283 }
284
285
286 public void setVisible(bool visible)
287 {
288 if(!visible) desktop.shellVisibilityChanged(this, false);
289 super.setVisible(visible);
290 if(visible) desktop.shellVisibilityChanged(this, true);
291 }
292
293
294 public void setActive()
295 {
296 desktop.activate(this);
297 }
298
299
300 public void setMaximized(bool maximized)
301 {
302 checkWidget();
303 if(this.maximized is maximized) return;
304 setMaximizedWithoutNotification(maximized);
305 desktop.shellMaximizedOrRestored(this, maximized);
306 }
307
308
309 public void setMinimized(bool minimized)
310 {
311 checkWidget();
312 bool wasMaximized = maximized;
313 setVisible(!minimized);
314 maximized = wasMaximized;
315 }
316
317
318 public bool getMinimized()
319 {
320 return getVisible();
321 }
322
323
324 void setMaximizedWithoutNotification(bool maximized)
325 {
326 if(this.maximized is maximized) return;
327 this.maximized = maximized;
328 if(maximized)
329 {
330 pluralizedBounds = getBounds();
331 desktopResized(desktop.getClientArea());
332 }
333 else
334 {
335 setBounds(pluralizedBounds.x,pluralizedBounds.y,pluralizedBounds.width,pluralizedBounds.height);
336 }
337 // Note: This method may be called in a Dispose event for this object
338 if(sizeGrip !is null && !sizeGrip.isDisposed()) sizeGrip.setVisible(!maximized);
339 if(!sizeBorder.isDisposed()) sizeBorder.setEnabled(!maximized && (style & DWT.RESIZE) !is 0);
340 if(maxButton !is null && !maxButton.isDisposed()) maxButton.redraw();
341 }
342
343
344 public bool getMaximized()
345 {
346 checkWidget();
347 return maximized;
348 }
349
350
351 void redrawDecorationsAfterActivityChange()
352 {
353 // Note: This method may be called in a Dispose event for this object
354 if(!titleBar.isDisposed()) titleBar.redraw();
355 if(closeButton !is null && !closeButton.isDisposed()) closeButton.redraw();
356 if(maxButton !is null && !maxButton.isDisposed()) maxButton.redraw();
357 if(minButton !is null && !minButton.isDisposed()) minButton.redraw();
358 }
359
360
361 void desktopResized(Rectangle deskCA)
362 {
363 if(maximized)
364 {
365 int hideTitle = desktop.getShowMaximizedTitle() ? 0 : (titleHeight+1);
366 setBounds(deskCA.x - BORDER_SIZE,
367 deskCA.y - BORDER_SIZE - hideTitle,
368 deskCA.width + 2*BORDER_SIZE,
369 deskCA.height + 2*BORDER_SIZE + hideTitle);
370 }
371 else forceVisibleLocation(deskCA);
372 }
373
374
375 public bool setFocus()
376 {
377 if(focusControl !is null && focusControl !is this && !focusControl.isDisposed())
378 return focusControl.setFocus();
379 return super.setFocus();
380 }
381
382
383 public bool isActiveShell()
384 {
385 return desktop.getActiveShell() is this;
386 }
387
388
389 private void forceVisibleLocation(Rectangle deskCA)
390 {
391 Point p = getLocation();
392 Point minGrabSize = titleBar.getMinGrabSize();
393 int x = p.x, y = p.y;
394 int minX = minGrabSize.x + BORDER_SIZE, minY = minGrabSize.y + BORDER_SIZE;
395 x = Math.min(Math.max(x, deskCA.x+minY), deskCA.x+deskCA.width-minX);
396 y = Math.min(Math.max(y, deskCA.y+minY), deskCA.y+deskCA.height-minY);
397 if(x != p.x || y != p.y) setLocation(x, y);
398 }
399 }