--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/lcdui_qt/src/javax/microedition/lcdui/TextFieldLayouter.java Tue Aug 31 15:09:22 2010 +0300
@@ -0,0 +1,561 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package javax.microedition.lcdui;
+
+import org.eclipse.ercp.swt.mobile.TextExtension;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.internal.extension.TextExtensionExtension;
+/**
+ * Responsible for correct layout of TextField in a Form.
+ */
+class TextFieldLayouter extends ItemLayouter
+{
+
+ /**
+ * Key name for modify listener.
+ */
+ private static final String MODIFY_LISTENER = "modify";
+
+ /**
+ * Key name for key listener.
+ */
+ private static final String KEY_LISTENER = "key";
+
+ /**
+ * Key name for mouse listener.
+ */
+ private static final String MOUSE_LISTENER = "mouse";
+
+
+ /**
+ * Percentage of the whole screen.
+ */
+ private static final int TOTAL_PERCENTAGE = 100;
+
+
+ // private static Control[] staticControls = new Control[6];
+
+ private static boolean isCorrectText;
+
+ /**
+ * Constructor.
+ *
+ * @param aFormLayouter FormLayouter used for layouting.
+ */
+ TextFieldLayouter(FormLayouter aFormLayouter)
+ {
+ super(aFormLayouter);
+ }
+
+ /**
+ * Get static eSWT control (ConstraintText or TextExtension).
+ *
+ * @param constraint
+ */
+ static Control eswtGetStaticTextControl(int constraint)
+ {
+ Control ret = null;
+
+ /*
+ int maskedConstraint = constraint & TextField.CONSTRAINT_MASK;
+
+ if (staticControls[maskedConstraint] == null) {
+ staticControls[maskedConstraint] = TextWrapper.eswtConstructText(
+ eswtGetStaticShell(), SWT.MULTI | SWT.WRAP, constraint);
+ ret = staticControls[maskedConstraint];
+ }
+ */
+
+ if (constraint == TextField.NUMERIC) {
+ constraint = TextExtensionExtension.NUMERIC;
+ }
+ else if (constraint == TextField.DECIMAL) {
+ constraint = TextExtensionExtension.DECIMAL;
+ }
+ else if (constraint == TextField.PHONENUMBER) {
+ constraint = TextExtensionExtension.PHONENUMBER;
+ }
+ else
+ {
+ // TODO: eSWT support required - text validation on EMAIL and URL constraints
+ // default
+ constraint = 0;
+ }
+
+ return new TextExtensionExtension(eswtGetStaticShell(), SWT.MULTI | SWT.WRAP,constraint);
+ }
+
+ /**
+ * Check that text satisfies specified constraints.
+ *
+ * @param constraint TextField.NUMERIC etc.
+ * @return true if text is correct for specified constraint.
+ */
+ static boolean checkText(final int constraint, final String text)
+ {
+ isCorrectText = true;
+
+ try
+ {
+ if(constraint == TextField.NUMERIC && !text.equals(""))
+ {
+ Integer.parseInt(text);
+ }
+ else if(constraint == TextField.DECIMAL && !text.equals(""))
+ {
+ Float.parseFloat(text);
+ }
+ }
+ catch( NumberFormatException e )
+ {
+ // Illegal text
+ return false;
+ }
+
+ ESWTUIThreadRunner.syncExec(new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ TextWrapper.eswtSetContent(
+ eswtGetStaticTextControl(constraint), text);
+ }
+ catch(IllegalArgumentException e)
+ {
+ isCorrectText = false;
+ }
+ }
+ });
+ return isCorrectText;
+ }
+
+ /**
+ * eSWT specific calls to implement getControl.
+ *
+ * @param parent for the control.
+ * @param item TextField item.
+ */
+ Control eswtGetControl(Composite parent, Item item)
+ {
+ TextField textfield = (TextField) item;
+
+ Control te = TextWrapper.eswtConstructText(parent,
+ SWT.WRAP | SWT.MULTI, textfield.getConstraints());
+ TextWrapper.eswtSetMaxSize(te, textfield.getMaxSize());
+ TextWrapper.eswtSetContent(te, textfield.getString());
+ TextWrapper.eswtSetSelection(te,
+ textfield.getCaretPosition(), textfield.getCaretPosition());
+
+ if(textfield.getInitialInputMode() != null)
+ {
+ eswtUpdateItem(textfield, te, TextField.UPDATE_INITIALINPUTMODE,
+ null);
+ }
+ return te;
+ }
+
+ /**
+ * Returns true if this eSWT control is suitable to be used for updating.
+ *
+ * @param item Item.
+ * @param control eSWT control.
+ *
+ * @return true if this control is suitable for update
+ */
+ boolean eswtIsSpecificControl(Item item, Control control)
+ {
+ return (control instanceof TextExtension);
+ }
+
+ /**
+ * Updates the values of TextField.
+ *
+ * @param item Item.
+ * @param control eSWT control.
+ * @param reason reason to update.
+ */
+ void eswtUpdateItem(Item item, Control control, int reason, Object param)
+ {
+ TextField textfield = (TextField) item;
+ if(reason == TextField.UPDATE_INITIALINPUTMODE)
+ {
+ TextWrapper.eswtSetInputMode(control,
+ textfield.getInitialInputMode(),
+ textfield.getConstraints());
+ }
+ else
+ {
+ TextWrapper.eswtSetContent(control, textfield.getString());
+ }
+ }
+
+ /**
+ * Update size of TextField.
+ *
+ * @param item TextField.
+ * @param control Control which represents TextField.
+ * @param width which control must occupy.
+ */
+ void eswtResizeControl(Item item, Control control, int width, int height)
+ {
+ super.eswtResizeControl(item, control, width, height);
+ if(control instanceof TextExtension)
+ {
+ TextExtension te = (TextExtension) control;
+ ((TextField) item).internalSetLinesCount(te.getLineCount());
+ }
+ }
+
+ /**
+ * Returns true if that key was consumed by TextField.
+ *
+ * @param item TextField.
+ * @param key keyCode.
+ */
+ boolean eswtOfferKeyPressed(Item item, int key)
+ {
+ TextField tf = (TextField) item;
+ if(item.hasLayout(Item.LAYOUT_SHRINK))
+ {
+ if((key == SWT.ARROW_LEFT
+ && tf.getCaretPosition() == 0)
+ || (key == SWT.ARROW_RIGHT
+ && tf.getCaretPosition() == tf.size()))
+ {
+ return false;
+ }
+ }
+ if(((key == SWT.ARROW_UP)
+ && (tf.getCaretPosition() == 0))
+ || ((key == SWT.ARROW_DOWN)
+ && (tf.getCaretPosition() == tf.size())))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Responsible for reacting on focusGained event, and according to direction
+ * from which that event comes sets the caret of the TextField.
+ *
+ * @param item TextField.
+ * @param dir direction from which focus came, in case if it was set with
+ * setCurrentItem() default direction is used (-1).
+ */
+ void eswtFocusGained(Item item, int dir)
+ {
+ super.eswtFocusGained(item, dir);
+ TextField tf = (TextField) item;
+ // direction = dir;
+ resetCaretPosition(tf, dir);
+ Control control = eswtGetFirstSpecificControl(item);
+ TextWrapper.eswtSetSelection(control,
+ tf.getCaretPosition(), tf.getCaretPosition());
+ }
+
+ /**
+ * Returns the minimum area needed to display a TextField.
+ *
+ * @param textField TextField object
+ * @return Minimum area needed to display TextField.
+ */
+ static Point calculateMinimumBounds(final TextField textField)
+ {
+ final Point minSize = new Point(0, 0);
+ ESWTUIThreadRunner.syncExec(new Runnable()
+ {
+ public void run()
+ {
+ TextExtension tempExt = (TextExtension) eswtGetStaticTextControl(TextField.ANY);
+ tempExt.setText(ItemLayouter.MIN_TEXT);
+ tempExt.pack();
+ minSize.x = tempExt.getSize().x;
+ minSize.y = tempExt.getSize().y + Config.TEXTFIELD_MARGIN;
+ applyMinMargins(textField, minSize);
+ }
+ });
+ return minSize;
+ }
+
+ /**
+ * Returns the preferred area needed to display an Item.
+ *
+ * @param item Item.
+ * @return Preferred area needed to display Item. x is width and y is
+ * height.
+ */
+ static Point calculatePreferredBounds(Item item)
+ {
+ final TextField textfield = (TextField) item;
+ final Point prefSize = new Point(0, 0);
+ ESWTUIThreadRunner.syncExec(new Runnable()
+ {
+ public void run()
+ {
+ TextExtension te = (TextExtension) eswtGetStaticTextControl(TextField.ANY);
+ te.setText(textfield.getString());
+
+ int maxHeight = (formHeigh
+ * Config.TEXTFIELD_MAX_SCREEN_PERCENTAGE / TOTAL_PERCENTAGE)
+ - Config.TEXTFIELD_MARGIN;
+ textfield.internalSetMaxVisibleLines(maxHeight
+ / te.getLineHeight());
+
+ prefSize.x = getMaximumItemWidth(textfield);
+ prefSize.y = Config.TEXTFIELD_MARGIN + Math.min(
+ te.computeSize(prefSize.x, SWT.DEFAULT).y, maxHeight);
+ // prefSize.y = Math.min(calc.y, maxHeight) + MARGIN;
+ applyPrefMargins(textfield, prefSize);
+ }
+ });
+ return prefSize;
+ }
+
+ /**
+ * Update caret position based on direction.
+ *
+ * @param textfield TextField for which to update caret position.
+ * @param dir direction of scrolling.
+ */
+ private void resetCaretPosition(TextField textfield, int dir)
+ {
+ switch(dir)
+ {
+ case SWT.ARROW_DOWN:
+ textfield.internalSetCaretPosition(0);
+ break;
+ case SWT.ARROW_RIGHT:
+ textfield.internalSetCaretPosition(0);
+ break;
+ case SWT.ARROW_UP:
+ textfield.internalSetCaretPosition(textfield.size());
+ break;
+ case SWT.ARROW_LEFT:
+ textfield.internalSetCaretPosition(textfield.size());
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Add TextField listeners when form is activated.
+ *
+ * @param item TextField.
+ * @param control Control which represents TextField.
+ */
+ void eswtAddSpecificListeners(Item item, Control control)
+ {
+ super.eswtAddSpecificListeners(item, control);
+ TextField textfield = (TextField) item;
+ ModifyListener listener = new TextFieldModifyListener(textfield);
+ TextWrapper.eswtAddModListener(control, listener);
+ control.setData(MODIFY_LISTENER, listener);
+ KeyListener listener2 = new TextFieldKeyListener(textfield);
+ control.addKeyListener(listener2);
+ control.setData(KEY_LISTENER, listener2);
+ MouseListener listener4 = new AllMouseListener(textfield);
+ control.addMouseListener(listener4);
+ control.setData(MOUSE_LISTENER, listener4);
+ }
+
+ /**
+ * Remove listeners from a TextField if the form goes to background.
+ *
+ * @param item TextField.
+ * @param control Control which represents TextField.
+ */
+ void eswtRemoveSpecificListeners(Item item, Control control)
+ {
+ super.eswtRemoveSpecificListeners(item, control);
+ ModifyListener l1 = (ModifyListener) control.getData(MODIFY_LISTENER);
+ if(l1 != null)
+ {
+ TextWrapper.eswtRemoveModListener(control, l1);
+ control.setData(MODIFY_LISTENER, null);
+ }
+ KeyListener l2 = (KeyListener) control.getData(KEY_LISTENER);
+ if(l2 != null)
+ {
+ control.removeKeyListener(l2);
+ control.setData(KEY_LISTENER, null);
+ }
+ MouseListener l4 = (MouseListener) control.getData(MOUSE_LISTENER);
+ if(l4 != null)
+ {
+ control.removeMouseListener(l4);
+ control.setData(MOUSE_LISTENER, null);
+ }
+ }
+
+ /**
+ * Class that receives ModifyEvents from TextExtension and updates values of
+ * TextField.
+ */
+ class TextFieldModifyListener implements ModifyListener
+ {
+
+ private TextField textfield;
+
+ TextFieldModifyListener(TextField textField)
+ {
+ this.textfield = textField;
+ }
+
+ private void handleLinesChange(TextExtension te)
+ {
+ int lines = te.getLineCount();
+ int visibleLines = te.getSize().y / te.getLineHeight();
+ if(lines != textfield.internalGetLinesCount())
+ {
+ textfield.internalSetLinesCount(lines);
+ Control control = eswtGetFirstControl(textfield);
+ if(control.getSize().y + te.getLineHeight()
+ + Config.TEXTFIELD_MARGIN <= formLayouter.getFormHeight())
+ {
+ textfield.updateParent(Item.UPDATE_HEIGHT_CHANGED);
+ }
+ if(textfield.internalGetLinesCount() > lines)
+ {
+ if((te.getTopIndex() + visibleLines) > lines)
+ {
+ te.setTopIndex(Math.max(0, lines - visibleLines));
+ }
+ if(visibleLines > lines)
+ {
+ textfield.updateParent(Item.UPDATE_HEIGHT_CHANGED);
+ }
+ }
+
+ te.setTopIndex(Math.max(te.getCaretLineNumber() + 1
+ - textfield.internalGetMaxVisibleLines(), 0));
+ }
+ }
+
+ public void modifyText(ModifyEvent modifyEvent)
+ {
+ Control te = (Control) modifyEvent.widget;
+ if(textfield.internalSetString(TextWrapper.eswtGetContent(te)))
+ {
+ Logger.method(textfield, "modify", modifyEvent);
+ textfield.internalSetCaretPosition(
+ TextWrapper.eswtGetCaretPosition(te));
+ if(te instanceof TextExtension)
+ {
+ handleLinesChange((TextExtension) te);
+ }
+ textfield.notifyStateChanged();
+ }
+ }
+ }
+
+ /**
+ * Class that receives KeyEvents from TextExtension and updates
+ * caret position for TextField.
+ */
+ class TextFieldKeyListener implements KeyListener
+ {
+
+ private TextField textfield;
+
+ TextFieldKeyListener(TextField textField)
+ {
+ this.textfield = textField;
+ }
+
+ public void keyPressed(KeyEvent keyEvent)
+ {
+ Control te = (Control) keyEvent.widget;
+ int caretPos = TextWrapper.eswtGetCaretPosition(te);
+ int caretLine = TextWrapper.eswtGetCaretLine(te);
+
+ if(keyEvent.keyCode == SWT.ARROW_UP && caretLine == 0)
+ {
+ caretPos = 0;
+ TextWrapper.eswtSetSelection(te, caretPos, caretPos);
+ }
+ else if(keyEvent.keyCode == SWT.ARROW_DOWN
+ && (caretLine == (TextWrapper.eswtGetLineCount(te) - 1)))
+ {
+ caretPos = textfield.size();
+ TextWrapper.eswtSetSelection(te, caretPos, caretPos);
+ }
+
+ textfield.internalSetCaretPosition(caretPos);
+ }
+
+ public void keyReleased(KeyEvent keyEvent)
+ {
+ // this is needed if focus was changed with touch.
+ // so ne scrolling was done in DFI.
+ if(!formLayouter.isItemFullyVisible(textfield))
+ {
+ formLayouter.eswtScrollToItem(textfield);
+ }
+ textfield.internalSetCaretPosition(
+ TextWrapper.eswtGetCaretPosition((Control) keyEvent.widget));
+ }
+
+ }
+
+ class AllMouseListener implements MouseListener, MouseMoveListener
+ {
+
+ private TextField textfield;
+ private boolean isEnabled;
+
+ AllMouseListener(TextField tf)
+ {
+ textfield = tf;
+ }
+
+ public void enable(boolean enabled)
+ {
+ isEnabled = enabled;
+ }
+
+ public void mouseUp(MouseEvent me)
+ {
+ if(isEnabled)
+ {
+ //
+ }
+ }
+
+ public void mouseDown(MouseEvent me)
+ {
+ textfield.internalSetCaretPosition(
+ TextWrapper.eswtGetCaretPosition((Control) me.widget));
+ }
+
+ public void mouseMove(MouseEvent me)
+ {
+ }
+
+ public void mouseDoubleClick(MouseEvent me)
+ {
+ }
+
+ }
+
+}