Source code: com/barteo/emulator/app/ui/swt/SwtDeviceComponent.java
1 /*
2 * MicroEmulator
3 * Copyright (C) 2001-2003 Bartek Teodorczyk <barteo@it.pl>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 package com.barteo.emulator.app.ui.swt;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.util.Enumeration;
25
26 import javax.microedition.lcdui.Command;
27
28 import org.eclipse.swt.SWT;
29 import org.eclipse.swt.SWTException;
30 import org.eclipse.swt.events.KeyEvent;
31 import org.eclipse.swt.events.KeyListener;
32 import org.eclipse.swt.events.MouseAdapter;
33 import org.eclipse.swt.events.MouseEvent;
34 import org.eclipse.swt.events.MouseMoveListener;
35 import org.eclipse.swt.events.PaintEvent;
36 import org.eclipse.swt.events.PaintListener;
37 import org.eclipse.swt.graphics.Color;
38 import org.eclipse.swt.graphics.Font;
39 import org.eclipse.swt.graphics.FontMetrics;
40 import org.eclipse.swt.graphics.GC;
41 import org.eclipse.swt.graphics.Image;
42 import org.eclipse.swt.graphics.ImageData;
43 import org.eclipse.swt.graphics.Point;
44 import org.eclipse.swt.graphics.RGB;
45 import org.eclipse.swt.graphics.Rectangle;
46 import org.eclipse.swt.widgets.Canvas;
47 import org.eclipse.swt.widgets.Composite;
48
49 import com.barteo.emulator.CommandManager;
50 import com.barteo.emulator.DisplayComponent;
51 import com.barteo.emulator.device.DeviceFactory;
52 import com.barteo.emulator.device.SoftButton;
53 import com.barteo.emulator.device.swt.SwtButton;
54 import com.barteo.emulator.device.swt.SwtDevice;
55 import com.barteo.emulator.device.swt.SwtDeviceDisplay;
56 import com.barteo.emulator.device.swt.SwtInputMethod;
57
58
59 public class SwtDeviceComponent extends Canvas
60 {
61 private static SwtDeviceComponent instance;
62 private SwtDisplayComponent dc;
63
64 private Image fBuffer = null;
65
66 private SwtButton prevOverButton;
67 private SwtButton overButton;
68 private SwtButton pressedButton;
69
70 KeyListener keyListener = new KeyListener()
71 {
72 public void keyPressed(KeyEvent ev)
73 {
74 ((SwtInputMethod) DeviceFactory.getDevice().getInputMethod()).keyboardKeyPressed(ev);
75 pressedButton = getButton(ev);
76 redraw();
77 if (pressedButton instanceof SoftButton) {
78 Command cmd = ((SoftButton) pressedButton).getCommand();
79 if (cmd != null) {
80 CommandManager.getInstance().commandAction(cmd);
81 }
82 }
83 }
84
85 public void keyReleased(KeyEvent ev)
86 {
87 ((SwtInputMethod) DeviceFactory.getDevice().getInputMethod()).keyboardKeyReleased(ev);
88 prevOverButton = pressedButton;
89 pressedButton = null;
90 redraw();
91 }
92 };
93
94 MouseAdapter mouseListener = new MouseAdapter()
95 {
96 public void mouseDown(MouseEvent e)
97 {
98 pressedButton = getButton(e.x, e.y);
99 if (pressedButton != null) {
100 if (pressedButton instanceof SoftButton) {
101 Command cmd = ((SoftButton) pressedButton).getCommand();
102 if (cmd != null) {
103 CommandManager.getInstance().commandAction(cmd);
104 }
105 } else {
106 DeviceFactory.getDevice().getInputMethod().keyPressed(pressedButton.getKey());
107 }
108 redraw();
109 }
110 }
111
112 public void mouseUp(MouseEvent e)
113 {
114 SwtButton prevOverButton = getButton(e.x, e.y);
115 if (prevOverButton != null) {
116 DeviceFactory.getDevice().getInputMethod().keyReleased(prevOverButton.getKey());
117 }
118 pressedButton = null;
119 redraw();
120 }
121 };
122
123
124 MouseMoveListener mouseMoveListener = new MouseMoveListener()
125 {
126 public void mouseDragged(MouseEvent e)
127 {
128 }
129
130 public void mouseMove(MouseEvent e)
131 {
132 prevOverButton = overButton;
133 overButton = getButton(e.x, e.y);
134 if (overButton != prevOverButton) {
135 redraw();
136 }
137 }
138 };
139
140
141 public SwtDeviceComponent(Composite parent)
142 {
143 super(parent, SWT.NO_BACKGROUND);
144 instance = this;
145
146 dc = new SwtDisplayComponent(this);
147
148 addKeyListener(keyListener);
149 addMouseListener(mouseListener);
150 addMouseMoveListener(mouseMoveListener);
151 addPaintListener(new PaintListener()
152 {
153 public void paintControl(PaintEvent e)
154 {
155 SwtDeviceComponent.this.paintControl(e);
156 }
157 });
158 }
159
160
161 public DisplayComponent getDisplayComponent()
162 {
163 return dc;
164 }
165
166
167 public Point computeSize(int wHint, int hHint, boolean changed)
168 {
169 Rectangle tmp = ((SwtDevice) DeviceFactory.getDevice()).getNormalImage().getBounds();
170
171 return new Point(tmp.width, tmp.height);
172 }
173
174
175 public void paintControl(PaintEvent pe)
176 {
177 Point size= getSize();
178
179 if (size.x <= 0 || size.y <= 0)
180 return;
181
182 if (fBuffer != null) {
183 Rectangle r= fBuffer.getBounds();
184 if (r.width != size.x || r.height != size.y) {
185 fBuffer.dispose();
186 fBuffer= null;
187 }
188 }
189 if (fBuffer == null) {
190 fBuffer= new Image(getDisplay(), size.x, size.y);
191 }
192
193 SwtGraphics gc = new SwtGraphics(new GC(fBuffer));
194 try {
195 gc.drawImage(((SwtDevice) DeviceFactory.getDevice()).getNormalImage(), 0, 0);
196
197 Rectangle displayRectangle =
198 ((SwtDeviceDisplay) DeviceFactory.getDevice().getDeviceDisplay()).getDisplayRectangle();
199 gc.translate(displayRectangle.x, displayRectangle.y);
200 dc.paint(gc);
201 gc.translate(-displayRectangle.x, -displayRectangle.y);
202
203 Rectangle rect;
204 if (prevOverButton != null ) {
205 rect = prevOverButton.getRectangle();
206 gc.drawImage(((SwtDevice) DeviceFactory.getDevice()).getNormalImage(),
207 rect.x, rect.y, rect.width, rect.height,
208 rect.x, rect.y, rect.width, rect.height);
209 prevOverButton = null;
210 }
211 if (overButton != null) {
212 rect = overButton.getRectangle();
213 gc.drawImage(((SwtDevice) DeviceFactory.getDevice()).getOverImage(),
214 rect.x, rect.y, rect.width, rect.height,
215 rect.x, rect.y, rect.width, rect.height);
216 }
217 if (pressedButton != null) {
218 rect = pressedButton.getRectangle();
219 gc.drawImage(((SwtDevice) DeviceFactory.getDevice()).getPressedImage(),
220 rect.x, rect.y, rect.width, rect.height,
221 rect.x, rect.y, rect.width, rect.height);
222 }
223 } finally {
224 gc.dispose();
225 }
226
227 pe.gc.drawImage(fBuffer, 0, 0);
228 }
229
230
231 private SwtButton getButton(int x, int y)
232 {
233 for (Enumeration e = ((SwtDevice) DeviceFactory.getDevice()).getButtons().elements(); e.hasMoreElements(); ) {
234 SwtButton button = (SwtButton) e.nextElement();
235 Rectangle tmp = new Rectangle(button.getRectangle().x, button.getRectangle().y,
236 button.getRectangle().width, button.getRectangle().height);
237 if (x >= tmp.x && x < tmp.x + tmp.width && y >= tmp.y && y < tmp.y + tmp.height) {
238 return button;
239 }
240 }
241 return null;
242 }
243
244
245 private SwtButton getButton(KeyEvent ev)
246 {
247 for (Enumeration e = ((SwtDevice) DeviceFactory.getDevice()).getButtons().elements(); e.hasMoreElements(); ) {
248 SwtButton button = (SwtButton) e.nextElement();
249 if (ev.keyCode == button.getKey()) {
250 return button;
251 }
252 if (button.isChar(ev.character)) {
253 return button;
254 }
255 }
256
257 return null;
258 }
259
260
261 private class CreateImageRunnable implements Runnable
262 {
263 private ImageData data;
264 private Image image;
265
266 CreateImageRunnable(ImageData data)
267 {
268 this.data = data;
269 }
270
271 Image getImage()
272 {
273 return image;
274 }
275
276 public void run()
277 {
278 image = new Image(instance.getParent().getDisplay(), data);
279 }
280 }
281
282
283 public static Image createImage(int width, int height)
284 {
285 return new Image(instance.getDisplay(), width, height);
286 }
287
288
289 public static Image createImage(InputStream is)
290 {
291 ImageData data = new ImageData(is);
292
293 CreateImageRunnable createImageRunnable = instance.new CreateImageRunnable(data);
294 instance.getDisplay().syncExec(createImageRunnable);
295
296 return createImageRunnable.getImage();
297 }
298
299
300 public static Image createImage(InputStream is, ImageFilter filter)
301 throws IOException
302 {
303 try {
304 ImageData data = new ImageData(is);
305
306 RGB[] rgbs = data.getRGBs();
307 if (rgbs != null) {
308 for (int i = 0; i < rgbs.length; i++) {
309 rgbs[i] = filter.filterRGB(0, 0, rgbs[i]);
310 }
311 } else {
312 RGB rgb;
313 int pixel;
314 for (int y = 0; y < data.height; y++) {
315 for (int x = 0; x < data.width; x++) {
316 pixel = data.getPixel(x, y);
317 rgb = new RGB((pixel >> 16) & 255, (pixel >> 8) & 255, pixel & 255);
318 rgb = filter.filterRGB(x, y, rgb);
319 data.setPixel(x, y, (rgb.red << 16) + (rgb.green << 8) + rgb.blue);
320 }
321 }
322 }
323
324 CreateImageRunnable createImageRunnable = instance.new CreateImageRunnable(data);
325 instance.getDisplay().syncExec(createImageRunnable);
326
327 return createImageRunnable.getImage();
328 } catch (SWTException ex) {
329 throw new IOException(ex.toString());
330 }
331 }
332
333
334 private class CreateColorRunnable implements Runnable
335 {
336 private RGB rgb;
337 private Color color;
338
339 CreateColorRunnable(RGB rgb)
340 {
341 this.rgb = rgb;
342 }
343
344 Color getColor()
345 {
346 return color;
347 }
348
349 public void run()
350 {
351 color = new Color(instance.getParent().getDisplay(), rgb);
352 }
353 }
354
355
356 public static Color createColor(RGB rgb)
357 {
358 CreateColorRunnable createColorRunnable = instance.new CreateColorRunnable(rgb);
359
360 instance.getDisplay().syncExec(createColorRunnable);
361
362 return createColorRunnable.getColor();
363 }
364
365
366 private class GetFontMetricsRunnable implements Runnable
367 {
368 private Font font;
369 private FontMetrics fontMetrics;
370
371 GetFontMetricsRunnable(Font font)
372 {
373 this.font = font;
374 }
375
376 FontMetrics getFontMetrics()
377 {
378 return fontMetrics;
379 }
380
381 public void run()
382 {
383 SwtGraphics gc = new SwtGraphics(instance.getParent().getDisplay());
384 gc.setFont(font);
385 fontMetrics = gc.getFontMetrics();
386 gc.dispose();
387 }
388 }
389
390
391 private class GetFontRunnable implements Runnable
392 {
393 private String name;
394 private int size;
395 private int style;
396 private Font font;
397
398 GetFontRunnable(String name, int size, int style)
399 {
400 this.name = name;
401 this.size = size;
402 this.style = style;
403 }
404
405 Font getFont()
406 {
407 return font;
408 }
409
410 public void run()
411 {
412 SwtGraphics gc = new SwtGraphics(instance.getParent().getDisplay());
413 gc.setFont(new Font(instance.getParent().getDisplay(), name, size, style));
414 font = gc.getFont();
415 gc.dispose();
416 }
417 }
418
419
420 private class StringWidthRunnable implements Runnable
421 {
422 private Font font;
423 private String str;
424 private int stringWidth;
425
426 StringWidthRunnable(Font font, String str)
427 {
428 this.font = font;
429 this.str = str;
430 }
431
432 int stringWidth()
433 {
434 return stringWidth;
435 }
436
437 public void run()
438 {
439 SwtGraphics gc = new SwtGraphics(instance.getParent().getDisplay());
440 gc.setFont(font);
441 stringWidth = gc.stringWidth(str);
442 gc.dispose();
443 }
444 }
445
446
447 public static Font getFont(String name, int size, int style)
448 {
449 GetFontRunnable getFontRunnable = instance.new GetFontRunnable(name, size, style);
450
451 instance.getDisplay().syncExec(getFontRunnable);
452
453 return getFontRunnable.getFont();
454 }
455
456
457 public static FontMetrics getFontMetrics(Font font)
458 {
459 GetFontMetricsRunnable getFontMetricsRunnable = instance.new GetFontMetricsRunnable(font);
460
461 instance.getDisplay().syncExec(getFontMetricsRunnable);
462
463 return getFontMetricsRunnable.getFontMetrics();
464 }
465
466
467 public static int stringWidth(Font font, String str)
468 {
469 StringWidthRunnable stringWidthRunnable = instance.new StringWidthRunnable(font, str);
470
471 instance.getDisplay().syncExec(stringWidthRunnable);
472
473 return stringWidthRunnable.stringWidth();
474 }
475
476 }