|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 package javax.microedition.lcdui; |
|
18 |
|
19 import java.util.Enumeration; |
|
20 import java.util.Vector; |
|
21 |
|
22 import javax.microedition.lcdui.EventDispatcher.LCDUIEvent; |
|
23 |
|
24 import org.eclipse.ercp.swt.mobile.MobileShell; |
|
25 import org.eclipse.swt.SWT; |
|
26 import org.eclipse.swt.events.*; |
|
27 import org.eclipse.swt.graphics.Rectangle; |
|
28 import org.eclipse.swt.internal.extension.CompositeExtension; |
|
29 import org.eclipse.swt.widgets.*; |
|
30 import com.nokia.mj.impl.rt.support.ApplicationUtils; |
|
31 import com.nokia.mj.impl.rt.support.ApplicationInfo; |
|
32 |
|
33 /** |
|
34 * Implementation of LCDUI <code>Displayable</code> class. |
|
35 */ |
|
36 public abstract class Displayable { |
|
37 |
|
38 private EswtCommandListener eswtCommandListener = new EswtCommandListener(); |
|
39 |
|
40 private EswtShellListener eswtShellListener = new EswtShellListener(); |
|
41 |
|
42 private EswtControlListener eswtControlListener = new EswtControlListener(); |
|
43 |
|
44 private EswtDisposeListener eswtDisposeListener = new EswtDisposeListener(); |
|
45 |
|
46 /** |
|
47 * Are the commands enabled or not. |
|
48 */ |
|
49 private boolean isEnabledCmds = true; |
|
50 |
|
51 /** |
|
52 * Shell is activated/de-activated. Called by shell listener. |
|
53 */ |
|
54 private boolean isShellActive = true; |
|
55 |
|
56 /** |
|
57 * Visible from OpenLCDUI's point of view. Called by Display.setCurrent(). |
|
58 */ |
|
59 private boolean isLcduiVisible; |
|
60 |
|
61 /** |
|
62 * Owned mobile shell. |
|
63 */ |
|
64 private Shell shell; |
|
65 |
|
66 /** |
|
67 * Content composite. |
|
68 */ |
|
69 private Composite contentComp; |
|
70 |
|
71 private Rectangle contentArea; |
|
72 |
|
73 private boolean initialized; |
|
74 |
|
75 private boolean isShownReturnValue; |
|
76 |
|
77 private com.nokia.mj.impl.rt.support.Finalizer finalizer; |
|
78 |
|
79 private String title; |
|
80 |
|
81 private Vector commands = new Vector(); |
|
82 |
|
83 private CommandListener iCommandListener; |
|
84 |
|
85 private Ticker ticker; |
|
86 |
|
87 /** |
|
88 * eSWT Label which is used to display the Ticker. This is stored in |
|
89 * displayable because same Ticker may exists in many displayables but eSWT |
|
90 * Controls are always associated with only one Displayable. |
|
91 */ |
|
92 private Label tickerLabel; |
|
93 |
|
94 /** |
|
95 * Default Constructor. |
|
96 */ |
|
97 Displayable(String title) { |
|
98 this.title = title; |
|
99 finalizer = ((finalizer != null) ? finalizer |
|
100 : new com.nokia.mj.impl.rt.support.Finalizer() { |
|
101 public void finalizeImpl() { |
|
102 if (finalizer != null) { |
|
103 finalizer = null; |
|
104 if (!ESWTUIThreadRunner.isDisposed()) { |
|
105 dispose(); |
|
106 } |
|
107 } |
|
108 } |
|
109 }); |
|
110 ESWTUIThreadRunner.update(getClass().getName(), 1); |
|
111 } |
|
112 |
|
113 /** |
|
114 * Performs eSWT construction of shell and content composite. <br> |
|
115 * Should be called from child level constructors. |
|
116 */ |
|
117 final void construct() { |
|
118 ESWTUIThreadRunner.safeSyncExec(new Runnable() { |
|
119 public void run() { |
|
120 shell = eswtConstructShell(SWT.SYSTEM_MODAL); |
|
121 eswtSetTitle(); |
|
122 contentComp = eswtConstructContent(SWT.NONE); |
|
123 contentArea = eswtLayoutShellContent(); |
|
124 } |
|
125 }); |
|
126 } |
|
127 |
|
128 /** |
|
129 * Dispose Displayable. |
|
130 */ |
|
131 void dispose() { |
|
132 if (ticker != null) { |
|
133 ticker.removeLabel(tickerLabel); |
|
134 } |
|
135 ESWTUIThreadRunner.update(getClass().getName(), -1); |
|
136 ESWTUIThreadRunner.safeSyncExec(new Runnable() { |
|
137 public void run() { |
|
138 if (shell != null) { |
|
139 shell.dispose(); |
|
140 } |
|
141 } |
|
142 }); |
|
143 } |
|
144 |
|
145 /** |
|
146 * Constructs default eSWT Shell.<br> |
|
147 * Default SWT shell style is SWT.SYSTEM_MODAL |
|
148 * |
|
149 * @param style eSWT style |
|
150 * |
|
151 * @return eSWT shell |
|
152 */ |
|
153 Shell eswtConstructShell(int style) { |
|
154 return new MobileShell(ESWTUIThreadRunner.getInstance().getDisplay(), style); |
|
155 } |
|
156 |
|
157 /** |
|
158 * Creates content Composite. this Composite is placed inside of |
|
159 * shell and contains the actual displayable's content (excluding ticker). |
|
160 * |
|
161 * Child classes may override this is if for example scrollbar is needed. |
|
162 * |
|
163 * @return Composite where the content is placed. |
|
164 */ |
|
165 Composite eswtConstructContent(int style) { |
|
166 Composite comp = new CompositeExtension(shell, style); |
|
167 return comp; |
|
168 } |
|
169 |
|
170 /** |
|
171 * Called by Display when Displayable should become visible. |
|
172 */ |
|
173 void eswtHandleShowCurrentEvent() { |
|
174 if (!shell.isDisposed()) { |
|
175 eswtUpdateSizes(); |
|
176 shell.addShellListener(eswtShellListener); |
|
177 shell.addDisposeListener(eswtDisposeListener); |
|
178 shell.addControlListener(eswtControlListener); |
|
179 eswtAddSelectionListenerForCommands(); |
|
180 // calling open() causes a resize event to be sent |
|
181 shell.open(); |
|
182 isLcduiVisible = true; |
|
183 // shell.setVisible(true); |
|
184 // TODO: needed because of eSWT focus bug |
|
185 /*if (!isDialogShell()) { |
|
186 Shell[] shells = shell.getDisplay().getShells(); |
|
187 for (int i = 0; i < shells.length; i++) { |
|
188 if (shells[i] != shell && shells[i].isVisible()) { |
|
189 shells[i].setVisible(false); |
|
190 } |
|
191 } |
|
192 }*/ |
|
193 } |
|
194 } |
|
195 |
|
196 /** |
|
197 * Called by Display when Displayable should become hidden. |
|
198 */ |
|
199 void eswtHandleHideCurrentEvent() { |
|
200 isLcduiVisible = false; |
|
201 if (!shell.isDisposed()) { |
|
202 shell.removeShellListener(eswtShellListener); |
|
203 shell.removeDisposeListener(eswtDisposeListener); |
|
204 shell.removeControlListener(eswtControlListener); |
|
205 eswtRemoveSelectionListenerForCommands(); |
|
206 } |
|
207 } |
|
208 |
|
209 /** |
|
210 * Handle event. |
|
211 * |
|
212 * @param e eSWT event |
|
213 */ |
|
214 void eswtHandleEvent(Event e) { |
|
215 // implementation in child classes |
|
216 // Logger.method(this, "eswtHandleEvent", e); |
|
217 } |
|
218 |
|
219 /** |
|
220 * Called by ShellListener when shell gets activated. |
|
221 */ |
|
222 void handleShellActivatedEvent() { |
|
223 // Implementation in child-classes |
|
224 // Logger.method(this, "handleShellActivatedEvent"); |
|
225 if (ESWTUIThreadRunner.getInstance().getDisplay().getActiveShell() |
|
226 != null) { |
|
227 if ( JadAttributeUtil.isValue(JadAttributeUtil.ATTRIB_NOKIA_MIDLET_BACKGROUND_EVENT, |
|
228 JadAttributeUtil.VALUE_PAUSE)) { |
|
229 ApplicationUtils.getInstance().resumeApplication(); |
|
230 } |
|
231 isShellActive = true; |
|
232 } |
|
233 } |
|
234 |
|
235 /** |
|
236 * Called by ShellListener when shell gets de-activated. |
|
237 */ |
|
238 void handleShellDeActivatedEvent() { |
|
239 // Implementation in child-classes |
|
240 // Logger.method(this, "handleShellDeActivatedEvent"); |
|
241 if(isShellActive) { |
|
242 if (ESWTUIThreadRunner.getInstance().getDisplay().getActiveShell() |
|
243 == null) { |
|
244 if ( JadAttributeUtil.isValue(JadAttributeUtil.ATTRIB_NOKIA_MIDLET_BACKGROUND_EVENT, |
|
245 JadAttributeUtil.VALUE_PAUSE)) { |
|
246 ApplicationUtils.getInstance().pauseApplication(); |
|
247 isShellActive = false; |
|
248 } |
|
249 } |
|
250 } |
|
251 } |
|
252 |
|
253 /** |
|
254 * This is called if resolution or orientation was changed. This should be |
|
255 * overwritten by sub-classes to get notifications about size changes. |
|
256 * |
|
257 * @param width new width of Displayable. |
|
258 * @param height new height of Displayable. |
|
259 */ |
|
260 void eswtHandleResizeEvent(int width, int height) { |
|
261 Logger.method(this, "eswtHandleResizeEvent", |
|
262 String.valueOf(width), String.valueOf(height)); |
|
263 LCDUIEvent event = EventDispatcher.instance().newEvent(LCDUIEvent.DISPLAYABLE_SIZECHANGED, this); |
|
264 event.width = width; |
|
265 event.height = height; |
|
266 EventDispatcher.instance().postEvent(event); |
|
267 } |
|
268 |
|
269 /** |
|
270 * Returns if the shell is Dialog styled. |
|
271 */ |
|
272 private boolean isDialogShell() { |
|
273 return (shell.getStyle() & SWT.DIALOG_TRIM) == SWT.DIALOG_TRIM; |
|
274 } |
|
275 |
|
276 /** |
|
277 * Set content size. |
|
278 * |
|
279 * @param aWidth required width or -1 to ignore |
|
280 * @param aHeight required height or -1 to ignore |
|
281 */ |
|
282 void eswtSetPreferredContentSize(int aWidth, int aHeight) { |
|
283 if (isDialogShell()) { |
|
284 // aHeight += Config.DISPLAYABLE_DIALOGSHELL_HEIGHT_DISPLACEMENT; |
|
285 |
|
286 Logger.method(this, "eswtSetPreferredContentSize", |
|
287 String.valueOf(aWidth), String.valueOf(aHeight)); |
|
288 |
|
289 Rectangle contentBounds = contentComp.getBounds(); |
|
290 int newWidth = (aWidth > 0 ? aWidth : contentBounds.width); |
|
291 int newHeight = (aHeight > 0 ? aHeight : contentBounds.height); |
|
292 |
|
293 if (tickerLabel != null) { |
|
294 newHeight += tickerLabel.getBounds().height; |
|
295 } |
|
296 |
|
297 Rectangle shellBounds = shell.getBounds(); |
|
298 // compute the trimmed shell size |
|
299 Rectangle newSize = shell.computeTrim(0, 0, newWidth, newHeight); |
|
300 // set the new size |
|
301 shell.setSize(newSize.width, newSize.height); |
|
302 // set the location - attached to the bottom growing upwards |
|
303 shell.setLocation(shellBounds.x, (shellBounds.y + shellBounds.height) - newSize.height); |
|
304 } |
|
305 } |
|
306 |
|
307 Rectangle eswtLayoutShellContent() { |
|
308 Rectangle shellArea = shell.getClientArea(); |
|
309 if (tickerLabel != null) { |
|
310 int tickerHeight = tickerLabel.getBounds().height; |
|
311 contentComp.setBounds(0, tickerHeight, |
|
312 shellArea.width, shellArea.height - tickerHeight); |
|
313 } |
|
314 else { |
|
315 contentComp.setBounds(0, 0, shellArea.width, shellArea.height); |
|
316 } |
|
317 return contentComp.getClientArea(); |
|
318 } |
|
319 |
|
320 /** |
|
321 * Update internal size of Displayable. |
|
322 */ |
|
323 void eswtUpdateSizes() { |
|
324 Rectangle newArea = eswtLayoutShellContent(); |
|
325 // if the content size has changed or its not initialized |
|
326 if (!initialized |
|
327 || newArea.width != contentArea.width |
|
328 || newArea.height != contentArea.height) { |
|
329 contentArea = newArea; |
|
330 initialized = true; |
|
331 if (ticker != null) { |
|
332 ticker.updateSpeed(); |
|
333 } |
|
334 eswtHandleResizeEvent(contentArea.width, contentArea.height); |
|
335 } |
|
336 } |
|
337 |
|
338 /** |
|
339 * Tells is this Displayable visible. |
|
340 * |
|
341 * @return true if this Displayable is currently visible. |
|
342 */ |
|
343 public synchronized boolean isShown() { |
|
344 ESWTUIThreadRunner.syncExec(new Runnable() { |
|
345 public void run() { |
|
346 isShownReturnValue = eswtIsShown(); |
|
347 } |
|
348 }); |
|
349 return isShownReturnValue; |
|
350 } |
|
351 |
|
352 /** |
|
353 * eSWT call-back that verifies that the Displayable is shown. |
|
354 */ |
|
355 boolean eswtIsShown() { |
|
356 if (!isLcduiVisible || !isShellActive) { |
|
357 // shell.isVisible() doesn't return false if MIDlet |
|
358 // is in background. That's why isVisible-variable is |
|
359 // used instead. |
|
360 return false; |
|
361 } |
|
362 if (shell.isDisposed() || !shell.isEnabled()) { |
|
363 return false; |
|
364 } |
|
365 return true; |
|
366 } |
|
367 |
|
368 /** |
|
369 * Validates a Command. |
|
370 * |
|
371 * @param command a Command |
|
372 */ |
|
373 void validateCommand(Command command) { |
|
374 if (command == null) { |
|
375 throw new NullPointerException( |
|
376 MsgRepository.DISPLAYABLE_EXCEPTION_NULL_PARAMETER); |
|
377 } |
|
378 } |
|
379 |
|
380 /** |
|
381 * Set commands visibility. |
|
382 * |
|
383 * @param enableCmds visibility switch |
|
384 */ |
|
385 void setCommandsVisibility(boolean enableCmds) { |
|
386 if (enableCmds != isEnabledCmds) { |
|
387 isEnabledCmds = enableCmds; |
|
388 ESWTUIThreadRunner.syncExec(new Runnable() { |
|
389 public void run() { |
|
390 int numCmd = getNumCommands(); |
|
391 for (int i = 0; i < numCmd; i++) { |
|
392 if (isEnabledCmds) { |
|
393 eswtAddCommand(getCommand(i)); |
|
394 } |
|
395 else { |
|
396 eswtRemoveCommand(getCommand(i)); |
|
397 } |
|
398 } |
|
399 } |
|
400 }); |
|
401 } |
|
402 } |
|
403 |
|
404 /** |
|
405 * Adds a command to this Displayable. |
|
406 * |
|
407 * @param command The Command to be added. If the Command already is added |
|
408 * to this Displayable, nothing happens. |
|
409 * @throws NullPointerException If parameter is null. |
|
410 */ |
|
411 public void addCommand(Command command) { |
|
412 validateCommand(command); |
|
413 if (!commands.contains(command)) { |
|
414 commands.addElement(command); |
|
415 // Command is not yet added to this Displayable. |
|
416 if (isEnabledCmds) { |
|
417 final Command finalCommand = command; |
|
418 ESWTUIThreadRunner.syncExec(new Runnable() { |
|
419 public void run() { |
|
420 eswtAddCommand(finalCommand); |
|
421 } |
|
422 }); |
|
423 } |
|
424 } |
|
425 } |
|
426 |
|
427 /** |
|
428 * eSWT callback to add a Command. |
|
429 */ |
|
430 void eswtAddCommand(Command cmd) { |
|
431 cmd.eswtAddESWTCommand(shell, false); |
|
432 if (eswtIsShown()) { |
|
433 cmd.eswtAddCommandSelectionListener(shell, eswtCommandListener); |
|
434 } |
|
435 } |
|
436 |
|
437 /** |
|
438 * Removes command from the Displayable. |
|
439 * |
|
440 * @param command Command to be removed. If parameter is null or Command |
|
441 * isn't added to Displayable, nothing happens. |
|
442 */ |
|
443 public void removeCommand(Command command) { |
|
444 if (command != null && commands.contains(command)) { |
|
445 // Remove command from iCommands-vector |
|
446 commands.removeElement(command); |
|
447 if (isEnabledCmds) { |
|
448 final Command finalCommand = command; |
|
449 ESWTUIThreadRunner.syncExec(new Runnable() { |
|
450 public void run() { |
|
451 eswtRemoveCommand(finalCommand); |
|
452 } |
|
453 }); |
|
454 } |
|
455 } |
|
456 } |
|
457 |
|
458 /** |
|
459 * eSWT callback to remove a Command. |
|
460 */ |
|
461 void eswtRemoveCommand(Command cmd) { |
|
462 if (eswtIsShown()) { |
|
463 cmd.eswtRemoveCommandSelectionListener(shell, eswtCommandListener); |
|
464 } |
|
465 cmd.eswtRemoveESWTCommand(shell); |
|
466 } |
|
467 |
|
468 /** |
|
469 * Sets CommandListener. If CommandListener already exists, it is replaced |
|
470 * with the new one. |
|
471 * |
|
472 * @param commandListener New CommandListener. If null, existing |
|
473 * CommandListener is removed. If null and no CommandListener |
|
474 * exists, nothing happens. |
|
475 */ |
|
476 public void setCommandListener(CommandListener commandListener) { |
|
477 this.iCommandListener = commandListener; |
|
478 } |
|
479 |
|
480 public boolean hasCommandListener() { |
|
481 if(this.iCommandListener != null) { |
|
482 return true; |
|
483 } |
|
484 return false; |
|
485 } |
|
486 |
|
487 |
|
488 /** |
|
489 * Add command listener for all Commands added to this Displayable. |
|
490 */ |
|
491 void eswtAddSelectionListenerForCommands() { |
|
492 Command cmd = null; |
|
493 for (Enumeration e = commands.elements(); e.hasMoreElements();) { |
|
494 cmd = (Command) e.nextElement(); |
|
495 cmd.eswtAddCommandSelectionListener(shell, eswtCommandListener); |
|
496 } |
|
497 } |
|
498 |
|
499 /** |
|
500 * Remove command listener from Commands added to this Displayable. |
|
501 */ |
|
502 void eswtRemoveSelectionListenerForCommands() { |
|
503 Command cmd = null; |
|
504 for (Enumeration e = commands.elements(); e.hasMoreElements();) { |
|
505 cmd = (Command) e.nextElement(); |
|
506 cmd.eswtRemoveCommandSelectionListener(shell, eswtCommandListener); |
|
507 } |
|
508 } |
|
509 |
|
510 /** |
|
511 * Calls the command action on the current command listener. |
|
512 * |
|
513 * @param command the Command |
|
514 */ |
|
515 final void callCommandAction(Command command) { |
|
516 if (iCommandListener != null && command != null) { |
|
517 LCDUIEvent event = EventDispatcher.instance().newEvent(LCDUIEvent.DISPLAYABLE_COMMANDACTION, this); |
|
518 event.command = command; |
|
519 event.commandListener = iCommandListener; |
|
520 EventDispatcher.instance().postEvent(event); |
|
521 } |
|
522 } |
|
523 |
|
524 /** |
|
525 * Gets the number of commands. |
|
526 * |
|
527 * @return the number of commands in this Displayable |
|
528 */ |
|
529 final int getNumCommands() { |
|
530 return commands.size(); |
|
531 } |
|
532 |
|
533 /** |
|
534 * Gets a command in the command array. |
|
535 * |
|
536 * @param index index of command |
|
537 * @return the command |
|
538 */ |
|
539 final Command getCommand(int index) { |
|
540 return (Command) commands.elementAt(index); |
|
541 } |
|
542 |
|
543 /** |
|
544 * Gets width. |
|
545 * |
|
546 * @return Width of the Displayable in pixels. |
|
547 */ |
|
548 public int getWidth() { |
|
549 return contentArea.width; |
|
550 } |
|
551 |
|
552 /** |
|
553 * Gets height. |
|
554 * |
|
555 * @return Height of the Displayable in pixels. |
|
556 */ |
|
557 public int getHeight() { |
|
558 return contentArea.height; |
|
559 } |
|
560 |
|
561 /** |
|
562 * Sets ticker. If ticker is added already to other displayable(s), |
|
563 * it continues running from position where it was. Otherwise |
|
564 * it will start running from beginning when this method returns. |
|
565 * |
|
566 * @param newTicker New ticker. If null, current ticker is removed. |
|
567 */ |
|
568 public void setTicker(Ticker newTicker) { |
|
569 if (ticker == newTicker) { |
|
570 return; |
|
571 } |
|
572 if (ticker != null) { |
|
573 // Ticker exists, removing it: |
|
574 ticker.removeLabel(getTickerLabel()); |
|
575 } |
|
576 ticker = newTicker; |
|
577 if (ticker != null) { |
|
578 ticker.addLabel(getTickerLabel()); |
|
579 } |
|
580 |
|
581 final Ticker finalTicker = ticker; |
|
582 ESWTUIThreadRunner.syncExec(new Runnable() { |
|
583 public void run() { |
|
584 if (finalTicker != null) { |
|
585 // Setting ticker: |
|
586 tickerLabel.setText(finalTicker.getFormattedString()); |
|
587 tickerLabel.pack(); |
|
588 // Avoid ticker flashing by setting it out of the |
|
589 // screen first: |
|
590 tickerLabel.setBounds(Integer.MIN_VALUE, 0, |
|
591 tickerLabel.getBounds().width, |
|
592 tickerLabel.getBounds().height); |
|
593 } |
|
594 else { |
|
595 // Removing ticker: |
|
596 tickerLabel.setText(""); |
|
597 tickerLabel.setBounds(Integer.MIN_VALUE, 0, 0, 0); |
|
598 } |
|
599 eswtUpdateSizes(); |
|
600 } |
|
601 }); |
|
602 if (ticker != null) { |
|
603 // Start to scroll the ticker. Ticker may be already running |
|
604 // if it exists in some other displayable already, but |
|
605 // calling this again wont do any harm: |
|
606 ticker.start(); |
|
607 } |
|
608 } |
|
609 |
|
610 /** |
|
611 * Gets current ticker. |
|
612 * |
|
613 * @return Current ticker or null if no ticker set. |
|
614 */ |
|
615 public Ticker getTicker() { |
|
616 return ticker; |
|
617 } |
|
618 |
|
619 /** |
|
620 * Gets the current title. |
|
621 * |
|
622 * @return The title of the Displayable, or null if no title set. |
|
623 */ |
|
624 public String getTitle() { |
|
625 return title; |
|
626 } |
|
627 |
|
628 /** |
|
629 * Sets the title of this Displayable. |
|
630 * |
|
631 * @param newTitle new title or null for no title. |
|
632 */ |
|
633 public void setTitle(String newTitle) { |
|
634 this.title = newTitle; |
|
635 ESWTUIThreadRunner.syncExec(new Runnable() { |
|
636 public void run() { |
|
637 eswtSetTitle(); |
|
638 } |
|
639 }); |
|
640 } |
|
641 |
|
642 /** |
|
643 * Sets shell's title. Nulls are not allowed. |
|
644 */ |
|
645 void eswtSetTitle() { |
|
646 // eSWT Shell doesn't take null value as title |
|
647 shell.setText((title != null ? title : "")); |
|
648 } |
|
649 |
|
650 /** |
|
651 * Creates singleton Label instance used by Ticker. |
|
652 */ |
|
653 private Label getTickerLabel() { |
|
654 if (tickerLabel == null) { |
|
655 ESWTUIThreadRunner.syncExec(new Runnable() { |
|
656 public void run() { |
|
657 tickerLabel = new Label(shell, |
|
658 SWT.SHADOW_NONE | SWT.HORIZONTAL | SWT.CENTER); |
|
659 } |
|
660 }); |
|
661 } |
|
662 return tickerLabel; |
|
663 } |
|
664 |
|
665 /** |
|
666 * Called by underlying system when the size of the Displayable changes. |
|
667 * This might be overwritten by user-side classes. |
|
668 * |
|
669 * @param width new width of Displayable. |
|
670 * @param height new height of Displayable. |
|
671 */ |
|
672 protected void sizeChanged(int width, int height) { |
|
673 } |
|
674 |
|
675 /** |
|
676 * eSWT callback to get the Shell of the Displayable. |
|
677 */ |
|
678 final Shell getShell() { |
|
679 return this.shell; |
|
680 } |
|
681 |
|
682 /** |
|
683 * Gets composite that contains displayable's content. |
|
684 * |
|
685 * @return Composite. |
|
686 */ |
|
687 Composite getContentComp() { |
|
688 return contentComp; |
|
689 } |
|
690 |
|
691 /* |
|
692 * The client area. It's ensured that after the construction this is always |
|
693 * set. |
|
694 */ |
|
695 final Rectangle getContentArea() { |
|
696 return contentArea; |
|
697 } |
|
698 |
|
699 /* |
|
700 * Dispatcher thread calls. |
|
701 */ |
|
702 void doCallback(LCDUIEvent event) { |
|
703 switch(event.type) { |
|
704 case LCDUIEvent.DISPLAYABLE_SIZECHANGED: |
|
705 sizeChanged(event.width, event.height); |
|
706 break; |
|
707 case LCDUIEvent.DISPLAYABLE_COMMANDACTION: |
|
708 event.commandListener.commandAction(event.command, this); |
|
709 break; |
|
710 } |
|
711 } |
|
712 |
|
713 /** |
|
714 * Inner class which receives SelectionEvents from eSWT and convert and |
|
715 * forwards those events to LCDUI's CommandListener. |
|
716 */ |
|
717 class EswtCommandListener implements SelectionListener { |
|
718 |
|
719 public void widgetDefaultSelected(SelectionEvent e) { |
|
720 } |
|
721 |
|
722 /** |
|
723 * Executed by eSWT when event occurs. This method will then call |
|
724 * Displayable's CommandListener if event source matches with the |
|
725 * Commands added to the Displayable. |
|
726 */ |
|
727 public void widgetSelected(SelectionEvent event) { |
|
728 // Go through all Commands added to this Displayable: |
|
729 for (Enumeration e = commands.elements(); e.hasMoreElements();) { |
|
730 Command cmd = (Command) e.nextElement(); |
|
731 // Select eSWT Command from Command which is connected to |
|
732 // this Displayable and compare it to the widget which |
|
733 // launched the event: |
|
734 if (cmd.getESWTCommand(shell) == event.widget) { |
|
735 callCommandAction(cmd); |
|
736 break; |
|
737 } |
|
738 } |
|
739 } |
|
740 } |
|
741 |
|
742 /** |
|
743 * Every Displayable must listen shell events to be able to tell is the |
|
744 * MIDlet sent to background. |
|
745 */ |
|
746 class EswtShellListener implements ShellListener { |
|
747 |
|
748 public void shellActivated(ShellEvent e) { |
|
749 if (!isShellActive) { |
|
750 handleShellActivatedEvent(); |
|
751 } |
|
752 } |
|
753 |
|
754 public void shellDeactivated(ShellEvent e) { |
|
755 ESWTUIThreadRunner.getInstance().getDisplay() |
|
756 .asyncExec(new Runnable() { |
|
757 public void run() { |
|
758 handleShellDeActivatedEvent(); |
|
759 } |
|
760 }); |
|
761 |
|
762 } |
|
763 |
|
764 public void shellClosed(ShellEvent e) { |
|
765 } |
|
766 |
|
767 public void shellIconified(ShellEvent e) { |
|
768 } |
|
769 |
|
770 public void shellDeiconified(ShellEvent e) { |
|
771 } |
|
772 |
|
773 } |
|
774 |
|
775 class EswtDisposeListener implements DisposeListener { |
|
776 |
|
777 public void widgetDisposed(DisposeEvent e) { |
|
778 isShellActive = false; |
|
779 } |
|
780 } |
|
781 |
|
782 /** |
|
783 * Displayable must listen resize-events to be able to call |
|
784 * sizeChanged()-method at the right time. |
|
785 */ |
|
786 class EswtControlListener implements ControlListener { |
|
787 public void controlResized(ControlEvent e) { |
|
788 eswtUpdateSizes(); |
|
789 } |
|
790 |
|
791 public void controlMoved(ControlEvent e) { |
|
792 } |
|
793 } |
|
794 |
|
795 } |