/*
*
*
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program 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. See the GNU
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*/
package javax.microedition.lcdui;
/**
* Implementation class for TextFieldLF
*/
import com.sun.midp.lcdui.DynamicCharacterArray;
import com.sun.midp.lcdui.TextPolicy;
import com.sun.midp.configurator.Constants;
/**
* Look and feel implementation of <code>TextField</code> based on
* platform widget.
*/
class TextFieldLFImpl extends ItemLFImpl implements TextFieldLF {
/**
* Creates <code>TextFieldLF</code> for the passed in
* <code>TextField</code>.
*
* @param tf The <code>TextField</code> associated with this
* <code>TextFieldLF</code>
*/
TextFieldLFImpl(TextField tf) {
super(tf);
this.tf = tf;
}
// *****************************************************
// Public methods defined in interfaces
// *****************************************************
/**
* Update the character buffer in <code>TextField</code> with latest
* user input.
*
* @return <code>true</code> if there is new user input updated in
* the buffer
*/
public boolean lUpdateContents() {
// No pending user input when there is no native resource or not shown
if (nativeId == DisplayableLFImpl.INVALID_NATIVE_ID) {
return false;
}
// Query native resource for pending user input
return getString0(nativeId, tf.buffer);
}
/**
* Override the preferred width of this <code>Item</code>.
*
* @param h tentative locked height.
* Ignored here.
*
* @return the preferred width
*/
public int lGetPreferredWidth(int h) {
// note: h is not used
// For TextBox return all width available for the item
if (tf.owner instanceof TextBox) {
return ((DisplayableLFImpl)tf.owner.getLF()).width;
}
return super.lGetPreferredWidth(h);
}
/**
* Override the preferred height of this <code>Item</code>.
*
* @param w tentative locked width.
* Ignored here and preferred width is used always.
*
* @return the preferred height
*/
public int lGetPreferredHeight(int w) {
// note: w is not used
int h = super.lGetPreferredHeight(w);
// For TextBox return all height available for the item
if (tf.owner instanceof TextBox) {
if (((DisplayableLFImpl)tf.owner.getLF()).height > h) {
h = ((DisplayableLFImpl)tf.owner.getLF()).height;
}
}
return h;
}
/**
* Get current contents from native resource.
*
* @param nativeId native resource id of this <code>Item</code>
* @param buffer the char array to be populated
*
* @return <code>true</code> if there is new input
*/
private native boolean getString0(int nativeId,
DynamicCharacterArray buffer);
/**
* Update content and caret position of the TextField's native widget.
*
* @param nativeId native resource id of this <code>Item</code>
* @param buffer char array of the new contents
*/
private native void setString0(int nativeId, DynamicCharacterArray buffer);
/**
* Notifies L&F of a content change in the corresponding
* <code>TextField</code>.
* The parameters are not used. Instead, this function directly
* uses data from TextField.java.
*/
public void lSetChars() {
// Only update native resource if it exists.
if (nativeId != DisplayableLFImpl.INVALID_NATIVE_ID) {
setString0(nativeId, tf.buffer);
}
lRequestInvalidate(true, true);
}
/**
* Notifies L&F of a character insertion in the corresponding
* <code>TextField</code>.
*
* @param data the source of the character data. Not used.
* @param offset the beginning of the region of characters copied.
* Not used.
* @param length the number of characters copied. Not used.
* @param position the position at which insertion occurred
*/
public void lInsert(char data[], int offset, int length, int position) {
// Simplify porting layer by treating insert as setChars
lSetChars();
}
/**
* Notifies L&F of character deletion in the corresponding
* <code>TextField</code>.
*
* @param offset the beginning of the deleted region
* @param length the number of characters deleted
*/
public void lDelete(int offset, int length) {
// Simplify porting layer by treating delete as setChars
lSetChars();
}
/**
* Notifies L&F of a maximum size change in the corresponding
* <code>TextField</code>.
*
* @param maxSize the new maximum size
*/
public void lSetMaxSize(int maxSize) {
// Only update native resource if it exists.
if (nativeId != DisplayableLFImpl.INVALID_NATIVE_ID) {
setMaxSize0(nativeId, maxSize);
}
lRequestInvalidate(true, true);
}
/**
* Set new maximum size of the native widget.
*
* @param nativeId native resource id of this <code>Item</code>
* @param maxSize new maximum size
*/
private native void setMaxSize0(int nativeId, int maxSize);
/**
* Gets the current input position.
*
* @return the current caret position, <code>0</code> if at the beginning
*/
public int lGetCaretPosition() {
return (nativeId != DisplayableLFImpl.INVALID_NATIVE_ID)
? getCaretPosition0(nativeId)
: tf.buffer.length();
}
/**
* Gets the current input position from native widget.
*
* @param nativeId native resource id of this <code>Item</code>
* @return current caret position
*/
private native int getCaretPosition0(int nativeId);
/**
* Notifies L&F that constraints have to be changed.
*/
public void lSetConstraints() {
// Only update native resource if it exists.
if (nativeId != DisplayableLFImpl.INVALID_NATIVE_ID) {
setConstraints0(nativeId, tf.constraints);
}
// note: int some implementation this method call may affect
// the layout, and int this case such a call will be needed:
// lRequestInvalidate(true, true);
}
/**
* Set input constraints of the native widget.
*
* @param nativeId native resource id of this <code>Item</code>
* @param constraints the new input constraints
*/
private native void setConstraints0(int nativeId, int constraints);
/**
* Validate a given character array against a constraints.
*
* @param buffer a character array
* @param constraints text input constraints
*
* @return <code>true</code> if constraints is met by the character array
*/
public boolean lValidate(DynamicCharacterArray buffer, int constraints) {
return TextPolicy.isValidString(buffer, constraints);
}
/**
* Notifies L&F that preferred initial input mode was changed.
*
* @param characterSubset a string naming a Unicode character subset,
* or <code>null</code>
*/
public void lSetInitialInputMode(String characterSubset) {
// No visual impact
}
/**
* Notifies item that it has been recently deleted
* Traverse out the textFieldLF.
*/
public void itemDeleted() {
uCallTraverseOut();
}
// *****************************************************
// Package private methods
// *****************************************************
/**
* Called by event delivery to notify an <code>ItemLF</code> in current
* <code>FormLF</code> of a change in its peer state.
*
* @param hint any value means contents have changed in native
*
* @return always <code>true</code> to notify
* <code>ItemStateListener</code>
*/
boolean uCallPeerStateChanged(int hint) {
return true;
}
/**
* Determine if this <code>Item</code> should have a newline after it.
*
* @return <code>true</code> if it should have a newline after
*/
boolean equateNLA() {
if (super.equateNLA()) {
return true;
}
return ((tf.layout & Item.LAYOUT_2) != Item.LAYOUT_2);
}
/**
* Determine if this <code>Item</code> should have a newline before it.
*
* @return <code>true</code> if it should have a newline before
*/
boolean equateNLB() {
if (super.equateNLB()) {
return true;
}
return ((tf.layout & Item.LAYOUT_2) != Item.LAYOUT_2);
}
/**
* Create native resource for current <code>TextField</code>.
* Override function in <code>ItemLFImpl</code>.
*
* @param ownerId Owner screen's native resource id
*/
void createNativeResource(int ownerId) {
nativeId = createNativeResource0(ownerId,
tf.label,
(tf.owner instanceof TextBox ?
-1 : tf.layout),
tf.buffer,
tf.constraints,
tf.initialInputMode);
}
/**
* KNI function that create native resource for current
* <code>TextField</code>.
*
* @param ownerId Owner screen's native resource id
* (<code>MidpDisplayable *</code>)
* @param label label of the item
* @param layout layout directive associated with this <code>Item</code>
* @param buffer char array of the contents
* @param constraints input constraints
* @param initialInputMode suggested input mode on creation
*
* @return native resource id (<code>MidpItem *</code>) of this
* <code>Item</code>
*/
private native int createNativeResource0(int ownerId,
String label,
int layout,
DynamicCharacterArray buffer,
int constraints,
String initialInputMode);
/**
* Override <code>ItemLFImpl</code> method to sync with native resource
* before hiding the native resource.
*/
void lHideNativeResource() {
lUpdateContents();
super.lHideNativeResource();
}
/** <code>TextField</code> instance associated with this view. */
TextField tf;
} // TextFieldLFImpl