001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.midp.chameleon.layers;
028:
029: import com.sun.midp.chameleon.*;
030: import com.sun.midp.lcdui.Text;
031:
032: import javax.microedition.lcdui.*;
033:
034: import com.sun.midp.chameleon.skins.SoftButtonSkin;
035: import com.sun.midp.chameleon.skins.ScreenSkin;
036: import com.sun.midp.chameleon.skins.ScrollIndSkin;
037: import com.sun.midp.chameleon.skins.resources.MenuResources;
038:
039: // EventConstants defines some constant values, such as
040: // key press, release, soft button codes, etc.
041: import com.sun.midp.lcdui.EventConstants;
042:
043: /**
044: * Soft button layer.
045: */
046: public class SoftButtonLayer extends CLayer implements CommandListener {
047:
048: /**
049: * Labels for each of the softbuttons.
050: */
051: protected String[] labels;
052:
053: /**
054: * A cached copy of the set of screen commands sent from
055: * the Display.
056: */
057: protected Command[] scrCmds;
058: /**
059: * The CommandListener to notify for any screen commands executed.
060: */
061: protected CommandListener scrListener;
062: /**
063: * A cached copy of the set of item commands sent from
064: * the Display.
065: */
066: protected Command[] itmCmds;
067: /**
068: * The ItemCommandListener to notify for any item commands executed.
069: */
070: protected ItemCommandListener itemListener;
071:
072: /**
073: * The command associated with soft button #1.
074: * null if there is no command associated with button #1.
075: */
076: protected Command soft1;
077:
078: /**
079: * The set of commands associated with soft button #2.
080: * null if there are no commands associated with button #2.
081: * If there is only one element in this array, there is no need
082: * for a menu and soft button #2 will behave similar to soft
083: * button #1 and invoke the listener directly upon button press.
084: */
085: protected Command[] soft2;
086:
087: /**
088: * When a sub menu is currently active, this reference is non-null.
089: */
090: protected SubMenuCommand subMenu;
091:
092: /**
093: * keep scrollable and scrollListener to recover them after menu dismiss
094: */
095: private CLayer cachedScrollable;
096: private ScrollListener cachedListener;
097:
098: /**
099: * A set of weights assigned to each of the types of Commands.
100: * The array is set up to return the weight of the Command type
101: * for each index, ie. Command.BACK has a defined value of 2 from
102: * the MIDP specification, cmdWieghts[Command.BACK] == 4, that is,
103: * there are three other Command types which sort higher than BACK
104: * (ITEM, SCREEN, and OK). The weighting is specified in the
105: * MIDP Human Interface Specification (Sun Internal).
106: */
107: static protected final int[] cmdWeights = { -1, // 0 is no value
108: 2, // Screen
109: 4, // Back
110: 6, // Cancel
111: 3, // Ok
112: 8, // Help
113: 7, // Stop
114: 5, // Exit
115: 1, // Item
116: };
117:
118: /**
119: * A System menu to popup and display when a set of commands
120: * needs to be displayed.
121: */
122: protected MenuLayer menuLayer;
123:
124: /**
125: * A flag indicating the system menu is up.
126: */
127: protected boolean menuUP;
128:
129: /**
130: * A flag indicating the alert is up.
131: */
132: protected boolean alertUP;
133:
134: /**
135: * A tunnel to utilize to notify of command invocation.
136: */
137: protected ChamDisplayTunnel tunnel;
138:
139: /**
140: * An internal variable defined once to avoid costly heap thrashing.
141: */
142: protected Command swap;
143:
144: /**
145: * Internal variables defined once to avoid costly heap thrashing.
146: */
147: protected int typeX, typeY;
148:
149: /**
150: * Internal variables for the paint loop.
151: */
152: protected int buttonx, buttony, buttonw, buttonh;
153:
154: /**
155: * True if user is interacting with the layer
156: */
157: private boolean isInteractive; // = false;
158:
159: /**
160: * Construct a SoftButtonLayer. The layer's background image and color
161: * information is obtained directly from the SoftButtonSkin class,
162: * such as background image, tile, and/or background color.
163: *
164: * @param tunnel channel for command notifications
165: */
166: public SoftButtonLayer(ChamDisplayTunnel tunnel) {
167: super (SoftButtonSkin.IMAGE_BG, SoftButtonSkin.COLOR_BG);
168: super .setSupportsInput(true);
169: super .setVisible(true);
170: this .tunnel = tunnel;
171:
172: labels = new String[SoftButtonSkin.NUM_BUTTONS];
173: }
174:
175: /**
176: * Returnes true if user is interacting with the layer,
177: * false otherwise.
178: *
179: * used by MIDPWindow to check if the layer should become
180: * visible.
181: */
182: public boolean isInteractive() {
183: return isInteractive;
184: }
185:
186: /**
187: * Assigns new value to isInteractive and signals MIDPWindow.
188: */
189: private void setInteractive(boolean interactive) {
190: if (isInteractive != interactive) {
191: isInteractive = interactive;
192: if (owner instanceof MIDPWindow) {
193: ((MIDPWindow) owner).updateLayout();
194: }
195: }
196: }
197:
198: /**
199: * Commandlistener interface implementation. Handle softbuton commands.
200: *
201: * @param c command
202: * @param d displayable
203: */
204: public void commandAction(Command c, Displayable d) {
205: dismissMenu();
206: }
207:
208: /**
209: * Dismiss menu layer.
210: */
211: public void dismissMenu() {
212: if (menuUP) {
213: menuUP = false;
214: menuLayer.dismiss();
215: if (owner != null) {
216: menuLayer.setScrollInd(null);
217: owner.removeLayer(menuLayer);
218: }
219: }
220: toggleMenu(menuUP);
221: }
222:
223: /**
224: * Returns true if system menu is currently up, false otherwise.
225: *
226: * @return true if system menu is up, false otherwise
227: */
228: public boolean systemMenuUp() {
229: return menuUP;
230: }
231:
232: /**
233: * Called by the system to update the set of commands associated
234: * with this button bar and its subsequent system menu.
235: *
236: * @param itemCmds an array of item specific commands
237: * @param numI the number of item specific commands
238: * @param itemListener the ItemCommandListener to notify if any
239: * item commands are selected
240: * @param screenCmds an array of screen specific commands
241: * @param numS the number of screen specific commands
242: * @param scrListener the CommandListener to notify if any
243: * screen commands are selected
244: */
245: public void updateCommandSet(Command[] itemCmds, int numI,
246: ItemCommandListener itemListener, Command[] screenCmds,
247: int numS, CommandListener scrListener) {
248: // Cache the values for later
249: this .itmCmds = new Command[numI];
250: if (numI > 0) {
251: System.arraycopy(itemCmds, 0, this .itmCmds, 0, numI);
252: }
253: this .itemListener = itemListener;
254:
255: this .scrCmds = new Command[numS];
256: if (numS > 0) {
257: System.arraycopy(screenCmds, 0, this .scrCmds, 0, numS);
258: }
259: this .scrListener = scrListener;
260:
261: // reset the commands
262: soft1 = null;
263:
264: if (numS > 0) {
265: int index = -1;
266: int type = -1;
267:
268: for (int i = 0; i < numS; i++) {
269: if (!(this .scrCmds[i] instanceof SubMenuCommand)) {
270: switch (this .scrCmds[i].getCommandType()) {
271: case Command.BACK:
272: index = i;
273: type = Command.BACK;
274: break;
275: case Command.EXIT:
276: if (type != Command.BACK) {
277: index = i;
278: type = Command.EXIT;
279: }
280: break;
281: case Command.CANCEL:
282: if (type != Command.BACK
283: && type != Command.EXIT) {
284: index = i;
285: type = Command.CANCEL;
286: }
287: break;
288: case Command.STOP:
289: if (type != Command.BACK
290: && type != Command.EXIT
291: && type != Command.CANCEL) {
292: index = i;
293: type = Command.STOP;
294: }
295: break;
296: default:
297: break;
298: }
299: } // if
300:
301: // We can short circuit the search if we find
302: // a BACK command, because that is the highest weighted
303: // Command for the left soft button
304: if (type == Command.BACK) {
305: break;
306: }
307: } // for
308:
309: // If we have a command for the left button, we pop it out
310: // of the array and decrement the number in the array - because
311: // we'll sort them all together to form the right button (or menu)
312: if (type > -1) {
313: numS--;
314: soft1 = this .scrCmds[index];
315: System.arraycopy(screenCmds, index + 1, scrCmds, index,
316: numS - index);
317: }
318: }
319:
320: // Now fill in the 'right' soft button, possibly with a menu
321: // of Commands
322: switch (numI + numS) {
323: case 0:
324: soft2 = null;
325: break;
326: case 1:
327: soft2 = new Command[1];
328: soft2[0] = (numI > 0) ? this .itmCmds[0] : this .scrCmds[0];
329: break;
330: default:
331: soft2 = new Command[numI + numS];
332:
333: if (setCommands(numI, 0, this .itmCmds)) {
334: numI--;
335: }
336:
337: setCommands(numS, numI, this .scrCmds);
338:
339: break;
340: }
341: setButtonLabels();
342: }
343:
344: /**
345: * Assigns the commands to soft1 and soft2 buttons .
346: *
347: * @param cmdNum Number of commands
348: * @param start Start index for soft2 commands array
349: * @param cmds Source commands array
350: * @return if any commnad has been assign to soft1 returns true,
351: * false otherwise
352: */
353: private boolean setCommands(int cmdNum, int start, Command[] cmds) {
354: int setSoft1 = 0;
355: if (cmdNum > 0) {
356: sortCommands(cmds, cmdNum);
357: for (int i = 0; i < cmdNum; i++) {
358: if (soft1 == null
359: && !(cmds[i] instanceof SubMenuCommand)) {
360: soft1 = cmds[i];
361: setSoft1++;
362: } else {
363: soft2[start + i - setSoft1] = cmds[i];
364: }
365: }
366: if (setSoft1 > 0) {
367: // decrement the soft2 array length
368: Command[] soft2temp = new Command[soft2.length - 1];
369: System.arraycopy(soft2, 0, soft2temp, 0,
370: soft2temp.length);
371: soft2 = soft2temp;
372: }
373: }
374: return setSoft1 > 0;
375: }
376:
377: /**
378: * Handle key input from a keypad. Parameters describe
379: * the type of key event and the platform-specific
380: * code for the key. (Codes are translated using the
381: * lcdui.Canvas)
382: *
383: * @param type the type of key event
384: * @param keyCode the numeric code assigned to the key
385: * @return true if this method processed the input,
386: * otherwise false.
387: */
388: public boolean keyInput(int type, int keyCode) {
389: // SoftButtonLayer absorbs soft button
390: // event only if corresponding soft button is "active".
391: // For further clarification please refer to
392: // isSoft1Active() and isSoft2Active() methods.
393:
394: boolean ret = false;
395: if (keyCode == EventConstants.SOFT_BUTTON1) {
396: if (isSoft1Active()) {
397: if (type == EventConstants.PRESSED) {
398: setInteractive(true);
399: ret = true;
400: } else if (type == EventConstants.RELEASED) {
401: soft1();
402: ret = true;
403: }
404: }
405: } else if (keyCode == EventConstants.SOFT_BUTTON2) {
406: if (isSoft2Active()) {
407: if (type == EventConstants.PRESSED) {
408: setInteractive(true);
409: ret = true;
410: } else if (type == EventConstants.RELEASED) {
411: soft2();
412: ret = true;
413: }
414: }
415: }
416: return ret;
417: }
418:
419: /**
420: * Handles pointer input events.
421: *
422: * @param type the event type for this input event
423: * @param x the x coordinate of the input event
424: * @param y the y coordinate of the input event
425: * @return true always
426: */
427: public boolean pointerInput(int type, int x, int y) {
428: if (type != EventConstants.PRESSED) {
429: return true;
430: }
431:
432: for (int i = 0; i < SoftButtonSkin.NUM_BUTTONS; i++) {
433: switch (SoftButtonSkin.BUTTON_ALIGN_X[i]) {
434: case Graphics.LEFT:
435: if (x < SoftButtonSkin.BUTTON_ANCHOR_X[i]
436: || (x > SoftButtonSkin.BUTTON_ANCHOR_X[i]
437: + SoftButtonSkin.BUTTON_MAX_WIDTH[i])) {
438: continue;
439: }
440: break;
441: case Graphics.RIGHT:
442: if (x > SoftButtonSkin.BUTTON_ANCHOR_X[i]
443: || (x < SoftButtonSkin.BUTTON_ANCHOR_X[i]
444: - SoftButtonSkin.BUTTON_MAX_WIDTH[i])) {
445: continue;
446: }
447: break;
448: default:
449: continue;
450: }
451: if (y >= SoftButtonSkin.BUTTON_ANCHOR_Y[i]
452: && y <= bounds[H]) {
453: softPress(i);
454: }
455: }
456:
457: // SoftButtonLayer always swallows any pointer input, as there is no
458: // need to forward the press on to any other layer.
459: return true;
460: }
461:
462: /**
463: * Selects a command.
464: *
465: * @param cmd the command selected
466: */
467: public void commandSelected(Command cmd) {
468: if (cmd == null) {
469: return;
470: }
471: dismissMenu();
472: processCommand(cmd);
473: }
474:
475: /**
476: * Toggles the alert. Grabs the background and requests a
477: * repaint.
478: *
479: * @param alertUp flag indicating the alaert has expired
480: */
481: public void toggleAlert(boolean alertUp) {
482: alertUP = alertUp;
483: setBackground();
484: requestRepaint();
485: }
486:
487: /**
488: * Sets the background based on current menu and alert
489: * settings.
490: */
491: private void setBackground() {
492: if (menuUP) {
493: setBackground(SoftButtonSkin.IMAGE_MU_BG,
494: SoftButtonSkin.COLOR_MU_BG);
495: } else if (alertUP) {
496: setBackground(SoftButtonSkin.IMAGE_AU_BG,
497: SoftButtonSkin.COLOR_AU_BG);
498: } else {
499: setBackground(SoftButtonSkin.IMAGE_BG,
500: SoftButtonSkin.COLOR_BG);
501: }
502: }
503:
504: /**
505: * Toggles the current menu selection.
506: * Grabs the background and requests a repaint.
507: *
508: * @param menuUp the flag indicating the menu selection
509: */
510: public void toggleMenu(boolean menuUp) {
511: if (owner instanceof MIDPWindow) {
512: ((MIDPWindow) owner).paintWash(menuUp);
513: }
514: setBackground();
515: requestRepaint();
516: }
517:
518: /**
519: * Sets the anchor constraints for rendering operation.
520: */
521: public void setAnchor() {
522: bounds[X] = 0;
523: bounds[Y] = ScreenSkin.HEIGHT - SoftButtonSkin.HEIGHT;
524: bounds[W] = ScreenSkin.WIDTH;
525: bounds[H] = SoftButtonSkin.HEIGHT;
526: }
527:
528: /**
529: * Switch based on soft button pressed.
530: *
531: * @param buttonID the button pushed
532: */
533: protected void softPress(int buttonID) {
534: switch (buttonID) {
535: case 0:
536: soft1();
537: break;
538: case 1:
539: soft2();
540: break;
541: }
542: }
543:
544: /**
545: * Soft button 1 handler.
546: */
547: protected void soft1() {
548: if (menuUP) {
549: dismissMenu();
550: subMenu = null;
551: requestRepaint();
552: setButtonLabels();
553: setInteractive(false);
554: } else {
555: processCommand(soft1);
556: }
557: }
558:
559: /**
560: * Initializes the menu from menu resources.
561: */
562: protected void initMenu() {
563: MenuResources.load();
564: menuLayer = new MenuLayer();
565: Command menuClose = new Command(SoftButtonSkin.TEXT_BACKCMD,
566: Command.BACK, 1);
567: menuLayer.setCommands(new Command[] { menuClose });
568: menuLayer.setCommandListener(this );
569: }
570:
571: /**
572: * Soft button 2 handler.
573: */
574: protected void soft2() {
575: if (soft2 != null) {
576: if (soft2.length == 1 && soft2[0] instanceof SubMenuCommand) {
577: subMenu = (SubMenuCommand) soft2[0];
578: }
579:
580: if (soft2.length > 1 || subMenu != null) {
581: if (menuLayer == null) {
582: initMenu();
583: }
584: menuLayer.setMenuCommands(soft2, this , 0);
585:
586: menuUP = true;
587: toggleMenu(menuUP);
588:
589: // Show the menu
590: if (owner != null) {
591: owner.addLayer(menuLayer);
592: menuLayer.setScrollInd(ScrollIndLayer
593: .getInstance(ScrollIndSkin.MODE));
594: }
595:
596: requestRepaint();
597:
598: } else if (soft2.length == 1) {
599: // command action
600: processCommand(soft2[0]);
601: }
602: } else {
603: setInteractive(false);
604: }
605: }
606:
607: /**
608: * Determines if soft button 2 will be processed by the layer.
609: * Called by keyInput to determine if the corresponding key event
610: * should be absorbed by SoftButtonLayer.
611: *
612: * @return true if soft2 command can be processed, false otherwise
613: */
614: protected boolean isSoft2Active() {
615: // when MIDPWindow is not in full screen mode, we absorb
616: // all key events reserved for the delivery of commands
617: if (!((MIDPWindow) owner).isInFullScreenMode()) {
618: return true;
619: }
620:
621: // for full screen mode we should check if soft key is useful
622: if (menuUP) {
623: return true;
624: } else if (soft2 != null) {
625: if (soft2.length == 1 && soft2[0] instanceof SubMenuCommand) {
626: return true;
627: }
628: // search for at least one active command
629: for (int i = 0; i < soft2.length; i++) {
630: if (isCommandActive(soft2[i])) {
631: return true;
632: }
633: }
634: }
635: return false;
636: }
637:
638: /**
639: * Determines if soft button 1 will be processed by the layer.
640: * Called by keyInput to determine if the corresponding key event
641: * should be absorbed by SoftButtonLayer.
642: *
643: * @return true if soft1 command can be processed, false otherwise
644: */
645: protected boolean isSoft1Active() {
646: // when MIDPWindow is not in full screen mode, we absorb
647: // all key events reserved for the delivery of commands
648: if (!((MIDPWindow) owner).isInFullScreenMode()) {
649: return true;
650: }
651:
652: // for full screen mode we should check if soft key is useful
653: if (menuUP) {
654: return true;
655: } else {
656: return isCommandActive(soft1);
657: }
658:
659: }
660:
661: /**
662: * Determines if it is possible to process the command.
663: *
664: * @param cmd the command to check
665: * @return true if command can be processed, false otherwise
666: */
667: protected boolean isCommandActive(Command cmd) {
668:
669: if (tunnel == null || cmd == null) {
670: return false;
671: }
672:
673: if ((isItemCommand(cmd) && (itemListener != null))
674: || (scrListener != null)) {
675: return true;
676: }
677:
678: return false;
679: }
680:
681: /**
682: * Processes commands.
683: *
684: * @param cmd the selected command
685: */
686: protected void processCommand(Command cmd) {
687:
688: setInteractive(false);
689:
690: if (tunnel == null || cmd == null) {
691: return;
692: }
693:
694: if (subMenu != null) {
695: subMenu.notifyListener(cmd);
696: subMenu = null;
697: } else if (isItemCommand(cmd)) {
698: tunnel.callItemListener(cmd, itemListener);
699: } else {
700: tunnel.callScreenListener(cmd, scrListener);
701: }
702: }
703:
704: /**
705: * Sets the button labels.
706: */
707: protected void setButtonLabels() {
708: // reset all the labels
709: for (int i = 0; i < SoftButtonSkin.NUM_BUTTONS; i++) {
710: labels[i] = null;
711: }
712:
713: // Port me : If a port had more than 2 soft buttons, adjust
714: // the behavior here for extra buttons
715: labels[0] = (soft1 == null) ? null : soft1.getLabel();
716: if (soft2 == null) {
717: labels[1] = null;
718: } else if (soft2.length == 1) {
719: labels[1] = soft2[0].getLabel();
720: } else {
721: labels[1] = SoftButtonSkin.TEXT_MENUCMD;
722: }
723: addDirtyRegion();
724: requestRepaint();
725: }
726:
727: /**
728: * Rearranges the commands based on weights and priority.
729: *
730: * @param cmds the commands to be sorted
731: * @param num the number of commands to check
732: */
733: protected void sortCommands(Command[] cmds, int num) {
734: // The number of commands is small, so we use a simple
735: // Insertion sort that requires little heap
736: for (int i = 1; i < num; i++) {
737: for (int j = i; j > 0; j--) {
738: if (compare(cmds[j], cmds[j - 1]) < 0) {
739: swap = cmds[j];
740: cmds[j] = cmds[j - 1];
741: cmds[j - 1] = swap;
742: } else
743: break;
744: }
745: }
746: }
747:
748: /**
749: * Compares two commands.
750: *
751: * @param a first command for comparison
752: * @param b second command for comparison
753: * @return 0 if commands are the same; negative
754: * if the first object is lower; positive is first
755: * command is higher.
756: */
757: protected int compare(Command a, Command b) {
758: if (a == null || b == null) {
759: return 0;
760: }
761:
762: typeX = a.getCommandType();
763: typeY = b.getCommandType();
764: if (typeX != typeY) {
765: return cmdWeights[typeX] - cmdWeights[typeY];
766: } else {
767: return a.getPriority() - b.getPriority();
768: }
769: }
770:
771: /**
772: * Checks if the item is a command.
773: *
774: * @param cmd the item to be checked
775: * @return true if the command is found in the
776: * list of item commands
777: */
778: protected boolean isItemCommand(Command cmd) {
779: if (itmCmds.length == 0) {
780: return false;
781: }
782:
783: for (int i = 0; i < itmCmds.length; i++) {
784: if (itmCmds[i] == cmd) {
785: return true;
786: }
787: }
788: return false;
789: }
790:
791: /**
792: * Initializes the soft button layer.
793: */
794: protected void initialize() {
795: super .initialize();
796: setAnchor();
797: }
798:
799: /**
800: * Renders the soft button layer.
801: *
802: * @param g the graphics context to be updated
803: */
804: protected void paintBody(Graphics g) {
805:
806: g.setFont(SoftButtonSkin.FONT);
807:
808: for (int i = 0; i < SoftButtonSkin.NUM_BUTTONS; i++) {
809: if (labels[i] == null) {
810: continue;
811: }
812:
813: buttonw = SoftButtonSkin.FONT.stringWidth(labels[i]);
814: if (buttonw > SoftButtonSkin.BUTTON_MAX_WIDTH[i]) {
815: buttonw = SoftButtonSkin.BUTTON_MAX_WIDTH[i];
816: }
817:
818: switch (SoftButtonSkin.BUTTON_ALIGN_X[i]) {
819: case Graphics.HCENTER:
820: buttonx = SoftButtonSkin.BUTTON_ANCHOR_X[i]
821: - (buttonw / 2);
822: break;
823: case Graphics.RIGHT:
824: buttonx = SoftButtonSkin.BUTTON_ANCHOR_X[i] - buttonw;
825: break;
826: case Graphics.LEFT:
827: default:
828: buttonx = SoftButtonSkin.BUTTON_ANCHOR_X[i];
829: break;
830: }
831: buttony = SoftButtonSkin.BUTTON_ANCHOR_Y[i];
832: //buttonh = SoftButtonSkin.FONT.getHeight();
833: g.translate(buttonx, buttony);
834:
835: Text.drawTruncStringShadowed(g, labels[i],
836: SoftButtonSkin.FONT, SoftButtonSkin.COLOR_FG,
837: SoftButtonSkin.COLOR_FG_SHD,
838: SoftButtonSkin.BUTTON_SHD_ALIGN, buttonw);
839: }
840: }
841:
842: /**
843: * Returns the left soft button (one).
844: *
845: * @return the command that's tied to the left soft button
846: */
847: public Command getSoftOne() {
848: return soft1;
849: }
850:
851: /**
852: * Returns the command array tied to the right soft button (two).
853: *
854: * @return the command array that's tied to the right soft button
855: */
856: public Command[] getSoftTwo() {
857: return soft2;
858: }
859:
860: /**
861: * Returns true if the point lies in the bounds of commnad layers
862: * subset like buttons, menu, submenu
863: * @param x the "x" coordinate of the point
864: * @param y the "y" coordinate of the point
865: * @return true if the point lies in the bounds of commnad layers
866: * subset
867: */
868: public boolean belongToCmdLayers(int x, int y) {
869: return containsPoint(x, y)
870: || (menuLayer != null && (menuLayer.containsPoint(x, y) || (menuLayer.cascadeMenu != null && menuLayer.cascadeMenu
871: .containsPoint(x, y))));
872: }
873:
874: /**
875: * Update bounds of layer
876: *
877: * @param layers - current layer can be dependant on this parameter
878: */
879: public void update(CLayer[] layers) {
880: super.update(layers);
881: setAnchor();
882: if (null != menuLayer) {
883: menuLayer.update(layers);
884: }
885: }
886: }
|