Mercurial > projects > dwt-addons
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 } |