Mercurial > projects > dwt-addons
comparison dwtx/jface/text/source/projection/SourceViewerInformationControl.d @ 129:eb30df5ca28b
Added JFace Text sources
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 23 Aug 2008 19:10:48 +0200 |
parents | |
children | c4fb132a086c |
comparison
equal
deleted
inserted
replaced
128:8df1d4193877 | 129:eb30df5ca28b |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2008 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 dwtx.jface.text.source.projection.SourceViewerInformationControl; | |
14 | |
15 import dwt.dwthelper.utils; | |
16 | |
17 | |
18 | |
19 | |
20 import dwt.DWT; | |
21 import dwt.custom.StyledText; | |
22 import dwt.events.DisposeEvent; | |
23 import dwt.events.DisposeListener; | |
24 import dwt.events.FocusListener; | |
25 import dwt.events.KeyEvent; | |
26 import dwt.events.KeyListener; | |
27 import dwt.graphics.Color; | |
28 import dwt.graphics.Font; | |
29 import dwt.graphics.FontData; | |
30 import dwt.graphics.GC; | |
31 import dwt.graphics.Point; | |
32 import dwt.graphics.Rectangle; | |
33 import dwt.layout.GridData; | |
34 import dwt.layout.GridLayout; | |
35 import dwt.widgets.Composite; | |
36 import dwt.widgets.Control; | |
37 import dwt.widgets.Display; | |
38 import dwt.widgets.Label; | |
39 import dwt.widgets.Shell; | |
40 import dwtx.jface.resource.JFaceResources; | |
41 import dwtx.jface.text.Document; | |
42 import dwtx.jface.text.IDocument; | |
43 import dwtx.jface.text.IInformationControl; | |
44 import dwtx.jface.text.IInformationControlCreator; | |
45 import dwtx.jface.text.IInformationControlExtension; | |
46 import dwtx.jface.text.IInformationControlExtension3; | |
47 import dwtx.jface.text.IInformationControlExtension5; | |
48 import dwtx.jface.text.source.SourceViewer; | |
49 import dwtx.jface.text.source.SourceViewerConfiguration; | |
50 | |
51 /** | |
52 * Source viewer based implementation of {@link dwtx.jface.text.IInformationControl}. | |
53 * Displays information in a source viewer. | |
54 * | |
55 * @since 3.0 | |
56 */ | |
57 class SourceViewerInformationControl : IInformationControl, IInformationControlExtension, IInformationControlExtension3, IInformationControlExtension5, DisposeListener { | |
58 | |
59 /** The control's shell */ | |
60 private Shell fShell; | |
61 /** The control's text widget */ | |
62 private StyledText fText; | |
63 /** The symbolic font name of the text font */ | |
64 private final String fSymbolicFontName; | |
65 /** The text font (do not dispose!) */ | |
66 private Font fTextFont; | |
67 /** The control's source viewer */ | |
68 private SourceViewer fViewer; | |
69 /** The optional status field. */ | |
70 private Label fStatusField; | |
71 /** The separator for the optional status field. */ | |
72 private Label fSeparator; | |
73 /** The font of the optional status text label.*/ | |
74 private Font fStatusTextFont; | |
75 /** The maximal widget width. */ | |
76 private int fMaxWidth; | |
77 /** The maximal widget height. */ | |
78 private int fMaxHeight; | |
79 | |
80 | |
81 /** | |
82 * Creates a source viewer information control with the given shell as parent. The given shell | |
83 * styles are applied to the created shell. The given styles are applied to the created styled | |
84 * text widget. The text widget will be initialized with the given font. The status field will | |
85 * contain the given text or be hidden. | |
86 * | |
87 * @param parent the parent shell | |
88 * @param isResizable <code>true</code> if resizable | |
89 * @param symbolicFontName the symbolic font name | |
90 * @param statusFieldText the text to be used in the optional status field or <code>null</code> | |
91 * if the status field should be hidden | |
92 */ | |
93 public SourceViewerInformationControl(Shell parent, bool isResizable, String symbolicFontName, String statusFieldText) { | |
94 GridLayout layout; | |
95 GridData gd; | |
96 | |
97 int shellStyle= DWT.TOOL | DWT.ON_TOP | (isResizable ? DWT.RESIZE : 0); | |
98 int textStyle= isResizable ? DWT.V_SCROLL | DWT.H_SCROLL : DWT.NONE; | |
99 | |
100 fShell= new Shell(parent, DWT.NO_FOCUS | DWT.ON_TOP | shellStyle); | |
101 Display display= fShell.getDisplay(); | |
102 | |
103 Composite composite= fShell; | |
104 layout= new GridLayout(1, false); | |
105 layout.marginHeight= 0; | |
106 layout.marginWidth= 0; | |
107 composite.setLayout(layout); | |
108 gd= new GridData(GridData.FILL_HORIZONTAL); | |
109 composite.setLayoutData(gd); | |
110 | |
111 if (statusFieldText !is null) { | |
112 composite= new Composite(composite, DWT.NONE); | |
113 layout= new GridLayout(1, false); | |
114 layout.marginHeight= 0; | |
115 layout.marginWidth= 0; | |
116 composite.setLayout(layout); | |
117 gd= new GridData(GridData.FILL_BOTH); | |
118 composite.setLayoutData(gd); | |
119 composite.setForeground(display.getSystemColor(DWT.COLOR_INFO_FOREGROUND)); | |
120 composite.setBackground(display.getSystemColor(DWT.COLOR_INFO_BACKGROUND)); | |
121 } | |
122 | |
123 // Source viewer | |
124 fViewer= new SourceViewer(composite, null, textStyle); | |
125 fViewer.configure(new SourceViewerConfiguration()); | |
126 fViewer.setEditable(false); | |
127 | |
128 fText= fViewer.getTextWidget(); | |
129 gd= new GridData(GridData.BEGINNING | GridData.FILL_BOTH); | |
130 fText.setLayoutData(gd); | |
131 fText.setForeground(parent.getDisplay().getSystemColor(DWT.COLOR_INFO_FOREGROUND)); | |
132 fText.setBackground(parent.getDisplay().getSystemColor(DWT.COLOR_INFO_BACKGROUND)); | |
133 fSymbolicFontName= symbolicFontName; | |
134 fTextFont= JFaceResources.getFont(symbolicFontName); | |
135 fText.setFont(fTextFont); | |
136 | |
137 fText.addKeyListener(new KeyListener() { | |
138 | |
139 public void keyPressed(KeyEvent e) { | |
140 if (e.character is 0x1B) // ESC | |
141 fShell.dispose(); | |
142 } | |
143 | |
144 public void keyReleased(KeyEvent e) {} | |
145 }); | |
146 | |
147 // Status field | |
148 if (statusFieldText !is null) { | |
149 | |
150 // Horizontal separator line | |
151 fSeparator= new Label(composite, DWT.SEPARATOR | DWT.HORIZONTAL | DWT.LINE_DOT); | |
152 fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); | |
153 | |
154 // Status field label | |
155 fStatusField= new Label(composite, DWT.RIGHT); | |
156 fStatusField.setText(statusFieldText); | |
157 Font font= fStatusField.getFont(); | |
158 FontData[] fontDatas= font.getFontData(); | |
159 for (int i= 0; i < fontDatas.length; i++) | |
160 fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10); | |
161 fStatusTextFont= new Font(fStatusField.getDisplay(), fontDatas); | |
162 fStatusField.setFont(fStatusTextFont); | |
163 GridData gd2= new GridData(GridData.FILL_VERTICAL | GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING); | |
164 fStatusField.setLayoutData(gd2); | |
165 | |
166 // Regarding the color see bug 41128 | |
167 fStatusField.setForeground(display.getSystemColor(DWT.COLOR_WIDGET_DARK_SHADOW)); | |
168 | |
169 fStatusField.setBackground(display.getSystemColor(DWT.COLOR_INFO_BACKGROUND)); | |
170 } | |
171 | |
172 addDisposeListener(this); | |
173 } | |
174 | |
175 /** | |
176 * @see dwtx.jface.text.IInformationControlExtension2#setInput(java.lang.Object) | |
177 * @param input the input object | |
178 */ | |
179 public void setInput(Object input) { | |
180 if (input instanceof String) | |
181 setInformation((String)input); | |
182 else | |
183 setInformation(null); | |
184 } | |
185 | |
186 /* | |
187 * @see IInformationControl#setInformation(String) | |
188 */ | |
189 public void setInformation(String content) { | |
190 if (content is null) { | |
191 fViewer.setInput(null); | |
192 return; | |
193 } | |
194 | |
195 IDocument doc= new Document(content); | |
196 fViewer.setInput(doc); | |
197 } | |
198 | |
199 /* | |
200 * @see IInformationControl#setVisible(bool) | |
201 */ | |
202 public void setVisible(bool visible) { | |
203 fShell.setVisible(visible); | |
204 } | |
205 | |
206 /* | |
207 * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent) | |
208 */ | |
209 public void widgetDisposed(DisposeEvent event) { | |
210 if (fStatusTextFont !is null && !fStatusTextFont.isDisposed()) | |
211 fStatusTextFont.dispose(); | |
212 | |
213 fStatusTextFont= null; | |
214 fTextFont= null; | |
215 fShell= null; | |
216 fText= null; | |
217 } | |
218 | |
219 /* | |
220 * @see dwtx.jface.text.IInformationControl#dispose() | |
221 */ | |
222 public final void dispose() { | |
223 if (fShell !is null && !fShell.isDisposed()) | |
224 fShell.dispose(); | |
225 else | |
226 widgetDisposed(null); | |
227 } | |
228 | |
229 /* | |
230 * @see IInformationControl#setSize(int, int) | |
231 */ | |
232 public void setSize(int width, int height) { | |
233 | |
234 if (fStatusField !is null) { | |
235 GridData gd= (GridData)fViewer.getTextWidget().getLayoutData(); | |
236 Point statusSize= fStatusField.computeSize(DWT.DEFAULT, DWT.DEFAULT, true); | |
237 Point separatorSize= fSeparator.computeSize(DWT.DEFAULT, DWT.DEFAULT, true); | |
238 gd.heightHint= height - statusSize.y - separatorSize.y; | |
239 } | |
240 fShell.setSize(width, height); | |
241 | |
242 if (fStatusField !is null) | |
243 fShell.pack(true); | |
244 } | |
245 | |
246 /* | |
247 * @see IInformationControl#setLocation(Point) | |
248 */ | |
249 public void setLocation(Point location) { | |
250 fShell.setLocation(location); | |
251 } | |
252 | |
253 /* | |
254 * @see IInformationControl#setSizeConstraints(int, int) | |
255 */ | |
256 public void setSizeConstraints(int maxWidth, int maxHeight) { | |
257 fMaxWidth= maxWidth; | |
258 fMaxHeight= maxHeight; | |
259 } | |
260 | |
261 /* | |
262 * @see IInformationControl#computeSizeHint() | |
263 */ | |
264 public Point computeSizeHint() { | |
265 // compute the preferred size | |
266 int x= DWT.DEFAULT; | |
267 int y= DWT.DEFAULT; | |
268 Point size= fShell.computeSize(x, y); | |
269 if (size.x > fMaxWidth) | |
270 x= fMaxWidth; | |
271 if (size.y > fMaxHeight) | |
272 y= fMaxHeight; | |
273 | |
274 // recompute using the constraints if the preferred size is larger than the constraints | |
275 if (x !is DWT.DEFAULT || y !is DWT.DEFAULT) | |
276 size= fShell.computeSize(x, y, false); | |
277 | |
278 return size; | |
279 } | |
280 | |
281 /* | |
282 * @see IInformationControl#addDisposeListener(DisposeListener) | |
283 */ | |
284 public void addDisposeListener(DisposeListener listener) { | |
285 fShell.addDisposeListener(listener); | |
286 } | |
287 | |
288 /* | |
289 * @see IInformationControl#removeDisposeListener(DisposeListener) | |
290 */ | |
291 public void removeDisposeListener(DisposeListener listener) { | |
292 fShell.removeDisposeListener(listener); | |
293 } | |
294 | |
295 /* | |
296 * @see IInformationControl#setForegroundColor(Color) | |
297 */ | |
298 public void setForegroundColor(Color foreground) { | |
299 fText.setForeground(foreground); | |
300 } | |
301 | |
302 /* | |
303 * @see IInformationControl#setBackgroundColor(Color) | |
304 */ | |
305 public void setBackgroundColor(Color background) { | |
306 fText.setBackground(background); | |
307 } | |
308 | |
309 /* | |
310 * @see IInformationControl#isFocusControl() | |
311 */ | |
312 public bool isFocusControl() { | |
313 return fShell.getDisplay().getActiveShell() is fShell; | |
314 } | |
315 | |
316 /* | |
317 * @see IInformationControl#setFocus() | |
318 */ | |
319 public void setFocus() { | |
320 fShell.forceFocus(); | |
321 fText.setFocus(); | |
322 } | |
323 | |
324 /* | |
325 * @see IInformationControl#addFocusListener(FocusListener) | |
326 */ | |
327 public void addFocusListener(FocusListener listener) { | |
328 fText.addFocusListener(listener); | |
329 } | |
330 | |
331 /* | |
332 * @see IInformationControl#removeFocusListener(FocusListener) | |
333 */ | |
334 public void removeFocusListener(FocusListener listener) { | |
335 fText.removeFocusListener(listener); | |
336 } | |
337 | |
338 /* | |
339 * @see IInformationControlExtension#hasContents() | |
340 */ | |
341 public bool hasContents() { | |
342 return fText.getCharCount() > 0; | |
343 } | |
344 | |
345 /* | |
346 * @see dwtx.jface.text.IInformationControlExtension3#computeTrim() | |
347 * @since 3.4 | |
348 */ | |
349 public Rectangle computeTrim() { | |
350 Rectangle trim= fShell.computeTrim(0, 0, 0, 0); | |
351 addInternalTrim(trim); | |
352 return trim; | |
353 } | |
354 | |
355 /** | |
356 * Adds the internal trimmings to the given trim of the shell. | |
357 * | |
358 * @param trim the shell's trim, will be updated | |
359 * @since 3.4 | |
360 */ | |
361 private void addInternalTrim(Rectangle trim) { | |
362 if (fStatusField !is null) { | |
363 trim.height+= fSeparator.computeSize(DWT.DEFAULT, DWT.DEFAULT).y; | |
364 trim.height+= fStatusField.computeSize(DWT.DEFAULT, DWT.DEFAULT).y; | |
365 } | |
366 } | |
367 | |
368 /* | |
369 * @see dwtx.jface.text.IInformationControlExtension3#getBounds() | |
370 * @since 3.4 | |
371 */ | |
372 public Rectangle getBounds() { | |
373 return fShell.getBounds(); | |
374 } | |
375 | |
376 /* | |
377 * @see dwtx.jface.text.IInformationControlExtension3#restoresLocation() | |
378 * @since 3.4 | |
379 */ | |
380 public bool restoresLocation() { | |
381 return false; | |
382 } | |
383 | |
384 /* | |
385 * @see dwtx.jface.text.IInformationControlExtension3#restoresSize() | |
386 * @since 3.4 | |
387 */ | |
388 public bool restoresSize() { | |
389 return false; | |
390 } | |
391 | |
392 /* | |
393 * @see dwtx.jface.text.IInformationControlExtension5#getInformationPresenterControlCreator() | |
394 * @since 3.4 | |
395 */ | |
396 public IInformationControlCreator getInformationPresenterControlCreator() { | |
397 return new IInformationControlCreator() { | |
398 public IInformationControl createInformationControl(Shell parent) { | |
399 return new SourceViewerInformationControl(parent, true, fSymbolicFontName, null); | |
400 } | |
401 }; | |
402 } | |
403 | |
404 /* | |
405 * @see dwtx.jface.text.IInformationControlExtension5#containsControl(dwt.widgets.Control) | |
406 * @since 3.4 | |
407 */ | |
408 public bool containsControl(Control control) { | |
409 do { | |
410 if (control is fShell) | |
411 return true; | |
412 if (control instanceof Shell) | |
413 return false; | |
414 control= control.getParent(); | |
415 } while (control !is null); | |
416 return false; | |
417 } | |
418 | |
419 /* | |
420 * @see dwtx.jface.text.IInformationControlExtension5#isVisible() | |
421 * @since 3.4 | |
422 */ | |
423 public bool isVisible() { | |
424 return fShell !is null && !fShell.isDisposed() && fShell.isVisible(); | |
425 } | |
426 | |
427 /* | |
428 * @see dwtx.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int) | |
429 */ | |
430 public Point computeSizeConstraints(int widthInChars, int heightInChars) { | |
431 GC gc= new GC(fText); | |
432 gc.setFont(fTextFont); | |
433 int width= gc.getFontMetrics().getAverageCharWidth(); | |
434 int height = gc.getFontMetrics().getHeight(); | |
435 gc.dispose(); | |
436 | |
437 return new Point (widthInChars * width, heightInChars * height); | |
438 } | |
439 } |