1 #!/usr/bin/env dub
2 /+
3 dub.sdl:
4     name "snippet212"
5     dependency "dwt" path="../../../../../../"
6     libs \
7       "atk-1.0" \
8       "cairo" \
9       "dl" \
10       "fontconfig" \
11       "gdk-x11-2.0" \
12       "gdk_pixbuf-2.0" \
13       "glib-2.0" \
14       "gmodule-2.0" \
15       "gnomeui-2" \
16       "gnomevfs-2" \
17       "gobject-2.0" \
18       "gthread-2.0" \
19       "gtk-x11-2.0" \
20       "pango-1.0" \
21       "pangocairo-1.0" \
22       "X11" \
23       "Xcomposite" \
24       "Xcursor" \
25       "Xdamage" \
26       "Xext" \
27       "Xfixes" \
28       "Xi" \
29       "Xinerama" \
30       "Xrandr" \
31       "Xrender" \
32       "Xtst" \
33       platform="linux"
34 +/
35 
36 /*******************************************************************************
37  * Copyright (c) 2000, 2004 IBM Corporation and others.
38  * All rights reserved. This program and the accompanying materials
39  * are made available under the terms of the Eclipse Public License v1.0
40  * which accompanies this distribution, and is available at
41  * http://www.eclipse.org/legal/epl-v10.html
42  *
43  * Contributors:
44  *     IBM Corporation - initial API and implementation
45  * Port to the D programming language:
46  *     yidabu at gmail dot com  ( D China http://www.d-programming-language-china.org/ )
47  *******************************************************************************/
48 
49 module org.eclipse.swt.snippets.Snippet212;
50 /**
51  * StyledText snippet: embed images
52  *
53  * For a list of all SWT example snippets see
54  * http://www.eclipse.org/swt/snippets/
55  * 
56  * @since 3.2
57  */
58 
59 import org.eclipse.swt.SWT;
60 import org.eclipse.swt.custom.StyledText;
61 import org.eclipse.swt.custom.StyleRange;
62 import org.eclipse.swt.layout.GridLayout;
63 import org.eclipse.swt.layout.GridData;
64 import org.eclipse.swt.widgets.Display;
65 import org.eclipse.swt.widgets.Shell;
66 import org.eclipse.swt.widgets.Button;
67 import org.eclipse.swt.widgets.FileDialog;
68 import org.eclipse.swt.widgets.Event;
69 import org.eclipse.swt.widgets.Listener;
70 import org.eclipse.swt.custom.PaintObjectEvent;
71 import org.eclipse.swt.custom.PaintObjectListener;
72 import org.eclipse.swt.events.VerifyEvent;
73 import org.eclipse.swt.events.VerifyListener;
74 import org.eclipse.swt.graphics.FontData;
75 import org.eclipse.swt.graphics.Font;
76 import org.eclipse.swt.graphics.Rectangle;
77 import org.eclipse.swt.graphics.GC;
78 import org.eclipse.swt.graphics.Image;
79 import org.eclipse.swt.graphics.GlyphMetrics;
80 import java.lang.all;
81 
82 const String OBJ_MARKER = "\uFFFC";
83 
84 void main() {
85     static StyledText styledText;
86     static String text = 
87         "This snippet shows how to embed images in a StyledText.\n" ~
88         "Here is one: " ~ OBJ_MARKER ~ ", and here is another: " ~ OBJ_MARKER ~ "." ~
89         "Use the add button to add an image from your filesystem to the StyledText at the current caret offset.";
90     static Image[] images;
91     static int[] offsets;
92 
93     static void addImage(Image image, int offset) {
94         StyleRange style = new StyleRange ();
95         style.start = offset;
96         style.length = OBJ_MARKER.length;
97         Rectangle rect = image.getBounds();
98         style.metrics = new GlyphMetrics(rect.height, 0, rect.width);
99         styledText.setStyleRange(style);        
100     }
101 
102     Display display = new Display();
103     Shell shell = new Shell(display);
104     shell.setLayout(new GridLayout());
105     styledText = new StyledText(shell, SWT.WRAP | SWT.BORDER);
106     styledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
107     styledText.setText(text);
108     images = [
109         display.getSystemImage(SWT.ICON_QUESTION),
110         display.getSystemImage(SWT.ICON_INFORMATION)
111     ];
112     offsets = new int[images.length];
113     int lastOffset = 0;
114     for (int i = 0; i < images.length; i++) {
115         int offset = text.indexOf(OBJ_MARKER, lastOffset);
116         offsets[i] = offset;
117         addImage(images[i], offset);
118         lastOffset = offset + 1;
119     }
120     
121     void onVerify(Event e) {
122         int start = e.start;
123         int replaceCharCount = e.end - e.start;
124         ptrdiff_t newCharCount = e.text.length;
125         for (int i = 0; i < offsets.length; i++) {
126             int offset = offsets[i];
127             if (start <= offset && offset < start + replaceCharCount) {
128                 // this image is being deleted from the text
129                 if (images[i] !is null && !images[i].isDisposed()) {
130                     images[i].dispose();
131                     images[i] = null;
132                 }
133                 offset = -1;
134             }
135             if (offset != -1 && offset >= start) offset += newCharCount - replaceCharCount;
136             offsets[i] = offset;
137         }
138     }    
139     // use a verify listener to keep the offsets up to date
140     styledText.addListener(SWT.Verify, dgListener(&onVerify));
141 
142     styledText.addPaintObjectListener(new class PaintObjectListener {
143         public void paintObject(PaintObjectEvent event) {
144             GC gc = event.gc;
145             StyleRange style = event.style;
146             int start = style.start;
147             for (int i = 0; i < offsets.length; i++) {
148                 int offset = offsets[i];
149                 if (start == offset) {
150                     Image image = images[i];
151                     int x = event.x;
152                     int y = event.y + event.ascent - style.metrics.ascent;						
153                     gc.drawImage(image, x, y);
154                 }
155             }
156         }
157     });    
158     
159     Button button = new Button (shell, SWT.PUSH);
160     button.setText("Add Image");
161     button.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
162     
163     void onSelection(Event e) {
164        FileDialog dialog = new FileDialog(shell);
165         String filename = dialog.open();
166         if (filename !is null) {
167             try {
168                 Image image = new Image(display, filename);
169                 int offset = styledText.getCaretOffset();
170                 styledText.replaceTextRange(offset, 0, OBJ_MARKER);
171                 int index = 0;
172                 while (index < offsets.length) {
173                     if (offsets[index] == -1 && images[index] is null) break;
174                     index++;
175                 }
176                 if (index == offsets.length) {
177                     int[] tmpOffsets = new int[index + 1];
178                     System.arraycopy(offsets, 0, tmpOffsets, 0, offsets.length);
179                     offsets = tmpOffsets;
180                     Image[] tmpImages = new Image[index + 1];
181                     System.arraycopy(images, 0, tmpImages, 0, images.length);
182                     images = tmpImages;
183                 }
184                 offsets[index] = offset;
185                 images[index] = image;
186                 addImage(image, offset);
187             } catch (Exception e) {
188                 ExceptionPrintStackTrace(e);
189             }
190         }
191     }
192     button.addListener(SWT.Selection, dgListener(&onSelection));
193     shell.setSize(400, 400);
194     shell.open();
195     while (!shell.isDisposed()) {
196         if (!display.readAndDispatch())
197             display.sleep();
198     }
199     for (int i = 0; i < images.length; i++) {
200         Image image = images[i];
201         if (image !is null && !image.isDisposed()) {
202             image.dispose();
203         }
204     }
205     display.dispose();
206 
207 }
208