/********************************************************************************* * TotalCross Software Development Kit * * Copyright (C) 2000-2012 SuperWaba Ltda. * * All Rights Reserved * * * * This library and virtual machine is distributed in the hope that it will * * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * * * This file is covered by the GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0 * * A copy of this license is located in file license.txt at the root of this * * SDK or can be downloaded here: * * http://www.gnu.org/licenses/lgpl-3.0.txt * * * *********************************************************************************/ package totalcross.ui.dialog; import totalcross.ui.*; import totalcross.ui.event.*; import totalcross.ui.gfx.*; import totalcross.sys.*; /** A popup keyboard to be used with the Edit and MultiEdit class. */ public class KeyboardBox extends Window // guich@102 { private Control destControl; private Rect destRect; private Container destCont; private PushButtonGroup pbs[] = new PushButtonGroup[4]; private KeyEvent ke = new KeyEvent(); /** Event issued by this keybard on the onUnpop method. The edit must call pushPosState. */ public static final int KEYBOARD_ON_UNPOP = 1001; // guich@320_34 /** Event issued by this keybard on the postUnpop method. The edit must call popPosState. */ public static final int KEYBOARD_POST_UNPOP = 1002; // guich@320_34 private boolean isCaps, isShift; /** Used to access the names member. */ public final static int TEXT_PAD = 0; /** Used to access the names member. */ public final static int CAPS_PAD = 1; /** Used to access the names member. */ public final static int SPACE_PAD = 2; /** Used to access the names member. */ public final static int SPECIAL_PAD = 3; public static String names[][] = // guich@400_4: made static and public { {"123 +$&() ����456 -#@[] ����789 *%|{} ����.0, /=\\<> ���� qwertyuiop'_ asdfghjkl:~^ zxcvbnm!?;\"` "}, // will be parsed later {"Caps","Shift"}, {" "}, {"�","Done"}, }; public static String namesUp[] = { null, null, }; public KeyboardBox() { super(" Keyboard ",RECT_BORDER); uiAdjustmentsBasedOnFontHeightIsSupported = false; fadeOtherWindows = Settings.fadeOtherWindows; transitionEffect = Settings.enableWindowTransitionEffects ? TRANSITION_OPEN : TRANSITION_NONE; setBackColor(UIColors.keyboardBack); // before control definitions! if (names[0].length == 1) // still not parsed? { String s = names[0][0]; String[] to = names[0] = new String[s.length()]; for (int i = s.length()-1; i >= 0; i--) { char c = s.charAt(i); if (c != ' ') to[i] = Convert.toString(c); } } } private void convertToUpper() // guich@564_8 { String []from = names[TEXT_PAD]; String []to = new String[from.length]; for (int i= from.length-1; i >= 0; i--) try {to[i] = from[i].toUpperCase();} catch (NullPointerException e) {} namesUp = to; } protected void onWindowPaintFinished() { destControl.requestFocus(); } protected void onPopup() { destControl = Window.topMost.getFocus(); destRect = destControl.getRect(); destCont = destControl.getParent(); if (pbs[0] == null) { int glue = -1; for (int i =0; i < pbs.length; i++) { add(pbs[i] = new PushButtonGroup(names[i], false, -1, i == TEXT_PAD ? glue : 1, i >= CAPS_PAD ? 8 : 4, i == TEXT_PAD ? 8 : 1, i != SPECIAL_PAD, (i != CAPS_PAD) ? PushButtonGroup.BUTTON : PushButtonGroup.CHECK)); pbs[i].setBackColor(i < CAPS_PAD ? UIColors.keyboardFore : UIColors.keyboardAction); pbs[i].appId = i; pbs[i].setFocusLess(true); // guich@320_32 pbs[i].setFont(font); } pbs[CAPS_PAD].checkAppearsRaised = true; convertToUpper(); } add(destControl); // repositions the window and the controls based in the control's size. Note that a MultiEdit has a different height of an Edit, so this must be dinamically computed int hh = pbs[TEXT_PAD].getPreferredHeight() + pbs[CAPS_PAD].getPreferredHeight() + destControl.getPreferredHeight() + getPreferredHeight() + 4*3 + fmH/2; int ww = Math.min(Settings.screenWidth,Settings.screenHeight)-4; setRect(CENTER,CENTER,ww,hh); destControl.setRect(CENTER,TOP+2,Math.min(destRect.width,width-10),PREFERRED); pbs[TEXT_PAD].setRect(LEFT+2, AFTER+4, FILL-3, PREFERRED); pbs[CAPS_PAD].setRect(LEFT+2, BOTTOM-2, PREFERRED, PREFERRED); pbs[SPECIAL_PAD].setRect(RIGHT-2, SAME, PREFERRED, SAME); pbs[SPACE_PAD].setRect(AFTER+1,SAME,FIT-2,SAME,pbs[CAPS_PAD]); ke.target = destControl; } protected void onUnpop() { destControl._onEvent(new ControlEvent(KEYBOARD_ON_UNPOP, destControl)); // guich@320_34 destControl.setRect(destRect.x,destRect.y,destRect.width,destRect.height); destCont.add(destControl); } protected void postUnpop() { destControl._onEvent(new ControlEvent(KEYBOARD_POST_UNPOP, destControl)); // guich@320_34 postPressedEvent(); // guich@580_27 } public void onEvent(Event event) { switch (event.type) { case KeyEvent.SPECIAL_KEY_PRESS: switch (((KeyEvent)event).key) { case SpecialKeys.KEYBOARD_ABC: case SpecialKeys.KEYBOARD_123: unpop(); break; } break; case ControlEvent.PRESSED: if (event.target instanceof PushButtonGroup) { PushButtonGroup pb = (PushButtonGroup)event.target; int sel = pb.getSelectedIndex(); if (sel >= 0) // guich@200b4_105: fix ArrayIndexOutOfBounds exception { String st = pb.getSelectedItem(); if (pb.appId == SPECIAL_PAD || pb.appId == CAPS_PAD || pb.appId == SPACE_PAD) // special char? { int key = -1; switch (st.charAt(0)) { case 'D': pb.setSelectedIndex(-1); unpop(); break; case ' ': key = ' '; break; case 'S': isShift = !isShift; isCaps = false; break; case 'C': isCaps = !isCaps; isShift = false; break; case '�': // guich@200b4: this char is not being recognized correctly in the SPT1700. default : key = SpecialKeys.BACKSPACE; break; } if (key != -1) insertKey(key); else if (pb.appId == CAPS_PAD) // guich@564_8 updateShiftPad(isShift || isCaps); } else { insertKey(st.charAt(0)); cancelShift(); } } } break; } } private void updateShiftPad(boolean shift) // guich@564_8 { // we assume that the uppercase will have almost the same width of the lowercase pbs[TEXT_PAD].names = shift ? namesUp : names[TEXT_PAD]; Window.needsPaint = true; } private void cancelShift() { if (isShift) { isShift = false; pbs[CAPS_PAD].setSelectedIndex(-1); updateShiftPad(false); } } private void insertKey(int key) { ke.key = key; destControl._onEvent(ke); } }