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 }