use of com.codename1.rad.models.Property in project CodenameOne by codenameone.
the class IOSImplementation method editString.
public void editString(final Component cmp, final int maxSize, final int constraint, final String text, final int i) {
// The very first time we try to edit a string, let's determine if the
// system default is to do async editing. If the system default
// is not yet set, we set it here, and it will be used as the default from now on
// We do this because the nativeInstance.isAsyncEditMode() value changes
// to reflect the currently edited field so it isn't a good way to keep a
// system default.
pendingEditingText = false;
String defaultAsyncEditingSetting = Display.getInstance().getProperty("ios.VKBAlwaysOpen", null);
if (defaultAsyncEditingSetting == null) {
defaultAsyncEditingSetting = nativeInstance.isAsyncEditMode() ? "true" : "false";
Display.getInstance().setProperty("ios.VKBAlwaysOpen", defaultAsyncEditingSetting);
}
boolean asyncEdit = "true".equals(defaultAsyncEditingSetting) ? true : false;
try {
if (currentEditing != cmp && currentEditing != null && currentEditing instanceof TextArea) {
Display.getInstance().onEditingComplete(currentEditing, ((TextArea) currentEditing).getText());
currentEditing = null;
callHideTextEditor();
if (nativeInstance.isAsyncEditMode()) {
nativeInstance.setNativeEditingComponentVisible(false);
}
synchronized (EDITING_LOCK) {
EDITING_LOCK.notify();
}
Display.getInstance().callSerially(new Runnable() {
public void run() {
pendingEditingText = true;
Display.getInstance().editString(cmp, maxSize, constraint, text, i);
}
});
return;
}
if (cmp.isFocusable() && !cmp.hasFocus()) {
doNotHideTextEditorSemaphore++;
try {
cmp.requestFocus();
} finally {
doNotHideTextEditorSemaphore--;
}
// of our upcoming field.
if (isAsyncEditMode()) {
// flush the EDT so the focus will work...
Display.getInstance().callSerially(new Runnable() {
public void run() {
pendingEditingText = true;
Display.getInstance().editString(cmp, maxSize, constraint, text, i);
}
});
return;
}
}
// Check if the form has any setting for asyncEditing that should override
// the application defaults.
Form parentForm = cmp.getComponentForm();
if (parentForm == null) {
// Log.p("Attempt to edit text area that is not on a form. This is not supported");
return;
}
if (parentForm.getClientProperty("asyncEditing") != null) {
Object async = parentForm.getClientProperty("asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Form overriding asyncEdit due to asyncEditing client property: "+asyncEdit);
}
}
if (parentForm.getClientProperty("ios.asyncEditing") != null) {
Object async = parentForm.getClientProperty("ios.asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Form overriding asyncEdit due to ios.asyncEditing client property: "+asyncEdit);
}
}
// editing - and should instead revert to legacy editing mode.
if (asyncEdit && !parentForm.isFormBottomPaddingEditingMode()) {
Container p = cmp.getParent();
// A crude estimate of how far the component needs to be able to scroll to make
// async editing viable. We start with half-way down the screen.
int keyboardClippingThresholdY = Display.getInstance().getDisplayWidth() / 2;
while (p != null) {
if (Accessor.scrollableYFlag(p) && p.getAbsoluteY() < keyboardClippingThresholdY) {
break;
}
p = p.getParent();
}
// no scrollabel parent automatically configure the text field for legacy mode
// nativeInstance.setAsyncEditMode(p != null);
asyncEdit = p != null;
// Log.p("Overriding asyncEdit due to form scrollability: "+asyncEdit);
} else if (parentForm.isFormBottomPaddingEditingMode()) {
// If form uses bottom padding mode, then we will always
// use async edit (unless the field explicitly overrides it).
asyncEdit = true;
// Log.p("Overriding asyncEdit due to form bottom padding edit mode: "+asyncEdit);
}
// then this will override all other settings.
if (cmp.getClientProperty("asyncEditing") != null) {
Object async = cmp.getClientProperty("asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Overriding asyncEdit due to field asyncEditing client property: "+asyncEdit);
}
}
if (cmp.getClientProperty("ios.asyncEditing") != null) {
Object async = cmp.getClientProperty("ios.asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Overriding asyncEdit due to field ios.asyncEditing client property: "+asyncEdit);
}
}
// Finally we set the async edit mode for this field.
// System.out.println("Async edit mode is "+asyncEdit);
nativeInstance.setAsyncEditMode(asyncEdit);
textEditorHidden = false;
currentEditing = (TextArea) cmp;
// register the edited TextArea to support moving to the next field
TextEditUtil.setCurrentEditComponent(cmp);
final NativeFont fnt = f(cmp.getStyle().getFont().getNativeFont());
boolean forceSlideUpTmp = false;
final Form current = Display.getInstance().getCurrent();
if (current instanceof Dialog && !isTablet()) {
// special case, if we are editing a small dialog we want to move it
// so the bottom of the dialog shows within the screen. This is
// described in issue 505
Dialog dlg = (Dialog) current;
Component c = dlg.getDialogComponent();
if (c.getHeight() < Display.getInstance().getDisplayHeight() / 2 && c.getAbsoluteY() + c.getHeight() > Display.getInstance().getDisplayHeight() / 2) {
forceSlideUpTmp = true;
}
}
final boolean forceSlideUp = forceSlideUpTmp;
cmp.repaint();
// give the repaint one cycle to "do its magic...
final Style stl = currentEditing.getStyle();
final boolean rtl = UIManager.getInstance().getLookAndFeel().isRTL();
final Style hintStyle = currentEditing.getHintLabel() != null ? currentEditing.getHintLabel().getStyle() : stl;
if (current != null) {
Component nextComponent = current.getNextComponent(cmp);
TextEditUtil.setNextEditComponent(nextComponent);
}
Display.getInstance().callSerially(new Runnable() {
@Override
public void run() {
int x = cmp.getAbsoluteX() + cmp.getScrollX();
int y = cmp.getAbsoluteY() + cmp.getScrollY();
int w = cmp.getWidth();
int h = cmp.getHeight();
int pt = stl.getPaddingTop();
int pb = stl.getPaddingBottom();
int pl = stl.getPaddingLeft(rtl);
int pr = stl.getPaddingRight(rtl);
/*
if(currentEditing != null && currentEditing.isSingleLineTextArea()) {
switch(currentEditing.getVerticalAlignment()) {
case TextArea.CENTER:
if(h > cmp.getPreferredH()) {
y += (h / 2 - cmp.getPreferredH() / 2);
}
break;
case TextArea.BOTTOM:
if(h > cmp.getPreferredH()) {
y += (h - cmp.getPreferredH());
}
break;
}
}
*/
String hint = null;
if (currentEditing != null && currentEditing.getUIManager().isThemeConstant("nativeHintBool", true) && currentEditing.getHint() != null) {
hint = currentEditing.getHint();
}
int hintColor = hintStyle.getFgColor();
if (isAsyncEditMode()) {
// request focus triggers a scroll which flicks the textEditorHidden flag
doNotHideTextEditorSemaphore++;
try {
cmp.requestFocus();
} finally {
doNotHideTextEditorSemaphore--;
}
textEditorHidden = false;
}
boolean showToolbar = cmp.getClientProperty("iosHideToolbar") == null;
if (showToolbar && Display.getInstance().getProperty("iosHideToolbar", "false").equalsIgnoreCase("true")) {
showToolbar = false;
}
if (currentEditing != null) {
nativeInstance.editStringAt(x, y, w, h, fnt.peer, currentEditing.isSingleLineTextArea(), currentEditing.getRows(), maxSize, constraint, text, forceSlideUp, // peer,
stl.getFgColor(), // peer,
0, pt, pb, pl, pr, hint, hintColor, showToolbar, Boolean.TRUE.equals(cmp.getClientProperty("blockCopyPaste")), currentEditing.getStyle().getAlignment(), currentEditing.getVerticalAlignment());
}
}
});
if (isAsyncEditMode()) {
return;
}
editNext = false;
Display.getInstance().invokeAndBlock(new Runnable() {
@Override
public void run() {
synchronized (EDITING_LOCK) {
while (instance.currentEditing == cmp) {
try {
EDITING_LOCK.wait(20);
} catch (InterruptedException ex) {
}
}
}
}
});
if (cmp instanceof TextArea && !((TextArea) cmp).isSingleLineTextArea()) {
Form form = cmp.getComponentForm();
if (form != null) {
form.revalidate();
}
}
if (editNext) {
editNext = false;
TextEditUtil.editNextTextArea();
}
} finally {
}
}
use of com.codename1.rad.models.Property in project CodeRAD by shannah.
the class FieldNode method getProperty.
/**
* Gets the property for this field. First this will check for an explicit
* property setting using {@link #getProperty()}, and if none is foune, it will
* resolve the tags against the given entity type to find the appropriate property
* of the entity type.
* @param context The entity type to find the property from, in case no property is explicitly set.
* @return The property or null.
*/
public Property getProperty(EntityType context) {
PropertyNode explicitProperty = getProperty();
if (explicitProperty != null) {
return explicitProperty.getValue();
}
if (context == null) {
return null;
}
Tags tags = getTags();
if (tags != null && !tags.isEmpty()) {
for (Property prop : context) {
Tags propTags = prop.getTags();
if (tags.intersects(propTags)) {
return prop;
}
}
}
return null;
}
use of com.codename1.rad.models.Property in project CodeRAD by shannah.
the class FieldNode method getPropertySelector.
/**
* Gets a property selector for this field node. If the field contained
* a PropertyNode or a Tags node, then it will construct a selector from those.
*
* Otherwise it will check for a {@link ProeprtySelectorAttribute}, and return
* a selector constructed form that, with the provided entity root.
* @param context
* @return A property selector, or null if no property or tag is set, and no property selector is set.
*/
public PropertySelector getPropertySelector(Entity context) {
if (context == null) {
return null;
}
Property prop = getProperty(context.getEntity().getEntityType());
if (prop != null) {
return new PropertySelector(context, prop);
}
Tags tags = getTags();
if (tags != null) {
return new PropertySelector(context, tags.toArray());
}
PropertySelectorAttribute selectorProvider = (PropertySelectorAttribute) findAttribute(PropertySelectorAttribute.class);
if (selectorProvider != null) {
return selectorProvider.getValue(context);
}
return null;
}
use of com.codename1.rad.models.Property in project CodeRAD by shannah.
the class ResultParser method parseRow.
/**
* Parse a single row of a result into the given row entity.
* @param rowResult The rowResult.
* @param rowEntity The row entity.
* @return The resulting entity. Same as input rowEntity.
* @throws IOException if parsing fails.
*/
public Entity parseRow(Result rowResult, Entity rowEntity) throws IOException {
if (rowEntity.getEntity().getEntityType() != entityType) {
ResultParser matchingParser = getParserFor(rowEntity.getEntity().getEntityType());
if (matchingParser == null) {
throw new IOException("No parser found for type " + rowEntity.getEntity().getEntityType());
}
return matchingParser.parseRow(rowResult, rowEntity);
}
for (PropertyParser propertyParser : propertyParsers) {
String rs = propertyParser.resultPropertySelector;
Property prop = propertyParser.property;
if (prop == null) {
if (propertyParser.tags != null) {
prop = rowEntity.getEntity().findProperty(propertyParser.tags);
}
}
if (prop == null) {
throw new IOException("Property not found for property selector when parsing selector " + rs);
}
if (propertyParser.entityParser != null) {
// same row data - not a sub-object in the dataset.
if (prop.getContentType().isEntity()) {
EntityProperty eProp = (EntityProperty) prop;
Class cls = eProp.getRepresentationClass();
Entity e;
try {
e = createEntity(cls);
} catch (Throwable t) {
throw new IOException("Failed to create new entity instance for property " + prop + " of type " + cls);
}
e = propertyParser.entityParser.parseRow(rowResult, e);
rowEntity.getEntity().set(prop, e);
} else {
throw new IOException("Property " + prop + " is assigned an EntityParser, but the property is not an entity type.");
}
continue;
}
// This is just a simple property selector
Getter getter = propertyParser.getter;
if (getter == null && propertyParser.parserCallback == null) {
getter = createGetter(prop);
}
Object val;
if (getter == null) {
val = rowResult.get(rs);
} else {
val = getter.get(rowResult, rs);
}
if (propertyParser.parserCallback != null) {
val = propertyParser.parserCallback.parse(val);
}
if (val == null) {
rowEntity.getEntity().set(val, null);
} else if (val.getClass() == Double.class) {
rowEntity.getEntity().setDouble(prop, (Double) val);
} else if (val.getClass() == Integer.class) {
rowEntity.getEntity().setInt(prop, (Integer) val);
} else if (val.getClass() == Long.class) {
rowEntity.getEntity().setLong(prop, (Long) val);
} else if (val.getClass() == Float.class) {
rowEntity.getEntity().setFloat(prop, (Float) val);
} else if (val.getClass() == Boolean.class) {
rowEntity.getEntity().setBoolean(prop, (Boolean) val);
} else if (val.getClass() == String.class) {
rowEntity.getEntity().setText(prop, (String) val);
} else if (val.getClass() == Date.class) {
rowEntity.getEntity().setDate(prop, (Date) val);
} else if (val instanceof List) {
if (prop.getContentType().isEntityList()) {
parse((List) val, rowEntity.getEntity().getEntityListNonNull(prop));
} else {
throw new IOException("Property type mismatch. Value " + val + " for property selector " + rs + " is a list, but the property " + prop + " is not an entity list type.");
}
} else if (val instanceof Map) {
if (prop.getContentType().isEntity()) {
EntityProperty eProp = (EntityProperty) prop;
Class cls = eProp.getRepresentationClass();
Entity e;
try {
e = createEntity(cls);
} catch (Throwable t) {
throw new IOException("Failed to create new entity instance for property " + prop + " of type " + cls);
}
e = parseRow(Result.fromContent((Map) val), e);
rowEntity.getEntity().set(prop, e);
} else {
throw new IOException("Property type mismatch. Value " + val + " for property selector " + rs + " is a map, but the property " + prop + " is not an entity type.");
}
} else if (val instanceof Element) {
if (prop.getContentType().isEntity()) {
EntityProperty eProp = (EntityProperty) prop;
Class cls = eProp.getRepresentationClass();
Entity e;
try {
e = createEntity(cls);
} catch (Throwable t) {
throw new IOException("Failed to create new entity instance for property " + prop + " of type " + cls);
}
e = parseRow(Result.fromContent((Element) val), e);
rowEntity.getEntity().set(prop, e);
} else {
throw new IOException("Property type mismatch. Value " + val + " for property selector " + rs + " is a map, but the property " + prop + " is not an entity type.");
}
} else {
throw new IOException("Unsupported content type for property " + prop + ". Value was " + val + " of type " + val.getClass());
}
}
return rowEntity;
}
use of com.codename1.rad.models.Property in project CodeRAD by shannah.
the class Node method createPropertySelector.
/**
* Creates a property selector on the given entity using (in order of decreasing precedence):
*
* 1. A {@link PropertyNode} attribute on the node.
* 2. A {@link Tags} attribute on the node.
* 3. A {@link PropertySelectorAttribute} on the node.
*
* @param entity The entity on which the property selector should be created.
* @return The property selector.
*/
public PropertySelector createPropertySelector(Entity entity) {
PropertyNode prop = findAttribute(PropertyNode.class);
if (prop != null) {
return new PropertySelector(entity, prop.getValue());
}
Tags tags = findAttribute(Tags.class);
if (tags != null) {
return new PropertySelector(entity, tags.toArray());
}
PropertySelectorAttribute att = (PropertySelectorAttribute) findAttribute(PropertySelectorAttribute.class);
if (att != null) {
return att.getValue(entity);
}
return null;
}
Aggregations