use of com.codename1.ui.util.xml.Entry in project CodenameOne by codenameone.
the class ResetableTextWatcher method edit.
/**
* Entry point for using this class
* @param impl The current running activity
* @param component Any subclass of com.codename1.ui.TextArea
* @param inputType One of the TextArea's input-type constants
*/
public static void edit(final AndroidImplementation impl, final Component component, final int inputType) {
if (impl.getActivity() == null) {
throw new IllegalArgumentException("activity is null");
}
if (component == null) {
throw new IllegalArgumentException("component is null");
}
if (!(component instanceof TextArea)) {
throw new IllegalArgumentException("component must be instance of TextArea");
}
final TextArea textArea = (TextArea) component;
final String initialText = textArea.getText();
textArea.putClientProperty("InPlaceEditView.initialText", initialText);
// 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.
String defaultAsyncEditingSetting = Display.getInstance().getProperty("android.VKBAlwaysOpen", null);
if (defaultAsyncEditingSetting == null) {
defaultAsyncEditingSetting = impl.isAsyncEditMode() ? "true" : "false";
Display.getInstance().setProperty("android.VKBAlwaysOpen", defaultAsyncEditingSetting);
}
boolean asyncEdit = "true".equals(defaultAsyncEditingSetting) ? true : false;
// Check if the form has any setting for asyncEditing that should override
// the application defaults.
final Form parentForm = component.getComponentForm();
if (parentForm == null) {
com.codename1.io.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("android.asyncEditing") != null) {
Object async = parentForm.getClientProperty("android.asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Form overriding asyncEdit due to ios.asyncEditing client property: "+asyncEdit);
}
}
if (parentForm.isFormBottomPaddingEditingMode()) {
asyncEdit = true;
}
// then this will override all other settings.
if (component.getClientProperty("asyncEditing") != null) {
Object async = component.getClientProperty("asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Overriding asyncEdit due to field asyncEditing client property: "+asyncEdit);
}
}
if (component.getClientProperty("android.asyncEditing") != null) {
Object async = component.getClientProperty("android.asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Overriding asyncEdit due to field ios.asyncEditing client property: "+asyncEdit);
}
}
// if true, then in async mode we are currently editing and are switching to another field
final boolean isEditedFieldSwitch;
// If we are already editing, we need to finish that up before we proceed to edit the next field.
synchronized (editingLock) {
if (mIsEditing) {
if (impl.isAsyncEditMode()) {
// Using isEditedFieldSwitch was causing issues with cursors not showing up.
// https://github.com/codenameone/CodenameOne/issues/2353
// https://stackoverflow.com/questions/49004370/focus-behaviour-in-textarea-in-cn1
// Disabling this feature by default now, but can be re-enabled by setting
// Display.getInstance().setProperty("android.reuseTextEditorOnSwitch", "true");
// This editedFieldSwitch feature was added a while back to improve experience on older
// Android devices where the field switching was going too slow.
// https://github.com/codenameone/CodenameOne/issues/2012
// This issue was resolved in this commit (https://github.com/jaanushansen/CodenameOne/commit/f3e53a80704149e4d7cde276d01c1368bcdcfe2c)
// which was submitted as part of a pull request. This fix has been the source of several
// regressions, mostly related to properties not being propagated properly when a text field is changed
// However, this issue (with the cursor not showing up), doesn't appear to have a simple solution
// so, I'm disabling this feature for now.
isEditedFieldSwitch = "true".equals(Display.getInstance().getProperty("android.reuseTextEditorOnSwitch", "false"));
final String[] out = new String[1];
TextArea prevTextArea = null;
if (sInstance != null && sInstance.mLastEditText != null) {
prevTextArea = sInstance.mLastEditText.getTextArea();
}
if (prevTextArea != null) {
final TextArea fPrevTextArea = prevTextArea;
final String retVal = sInstance.mLastEditText.getText().toString();
Display.getInstance().callSerially(new Runnable() {
public void run() {
Display.getInstance().onEditingComplete(fPrevTextArea, retVal);
}
});
}
InPlaceEditView.setEditedTextField(textArea);
nextTextArea = null;
} else {
isEditedFieldSwitch = false;
final InPlaceEditView instance = sInstance;
if (instance != null && instance.mEditText != null && instance.mEditText.mTextArea == textArea) {
instance.showTextEditorAgain();
return;
}
if (!isClosing && sInstance != null && sInstance.mEditText != null) {
isClosing = true;
impl.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
instance.endEditing(REASON_UNDEFINED, true, 0);
}
});
}
afterClose = new Runnable() {
@Override
public void run() {
impl.callHideTextEditor();
Display.getInstance().editString(component, textArea.getMaxSize(), inputType, textArea.getText());
}
};
return;
}
} else {
isEditedFieldSwitch = false;
}
mIsEditing = true;
isClosing = false;
afterClose = null;
}
impl.setAsyncEditMode(asyncEdit);
// textArea.setPreferredSize(prefSize);
if (!impl.isAsyncEditMode() && textArea instanceof TextField) {
((TextField) textArea).setEditable(false);
}
final boolean scrollableParent = isScrollableParent(textArea);
// We wrap the text area so that we can safely pass data across to the
// android UI thread.
final TextAreaData textAreaData = new TextAreaData(textArea);
impl.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (!isEditedFieldSwitch) {
releaseEdit();
if (sInstance == null) {
sInstance = new InPlaceEditView(impl);
impl.relativeLayout.addView(sInstance);
}
// Let's try something new here
// We'll ALWAYS try resize edit mode (since it just works better)
// But we'll detect whether the field is still covered by the keyboard
// and switch to pan mode if necessary.
}
if (scrollableParent || parentForm.isFormBottomPaddingEditingMode()) {
setEditMode(true);
} else {
trySetEditMode(true);
}
sInstance.startEditing(impl.getActivity(), textAreaData, initialText, inputType, isEditedFieldSwitch);
}
});
final String[] out = new String[1];
// In order to reuse the code the runs after edit completion, we will wrap it in a runnable
// For sync edit mode, we will just run onComplete.run() at the end of this method. For
// Async mode we add the Runnable to the textarea as a client property, then run it
// when editing eventually completes.
Runnable onComplete = new Runnable() {
public void run() {
if (!impl.isAsyncEditMode() && textArea instanceof TextField) {
((TextField) textArea).setEditable(true);
}
textArea.setPreferredSize(null);
if (sInstance != null && sInstance.mLastEditText != null && sInstance.mLastEditText.mTextArea == textArea) {
String retVal = sInstance.mLastEditText.getText().toString();
if (!impl.isAsyncEditMode()) {
sInstance.mLastEditText = null;
impl.getActivity().runOnUiThread(new Runnable() {
public void run() {
releaseEdit();
}
});
}
out[0] = retVal;
} else {
out[0] = initialText;
}
Display.getInstance().onEditingComplete(component, out[0]);
if (impl.isAsyncEditMode()) {
impl.callHideTextEditor();
} else {
// lock.
if (sInstance != null) {
Display.getInstance().invokeAndBlock(new Runnable() {
public void run() {
while (sInstance != null) {
com.codename1.io.Util.sleep(5);
}
}
});
}
}
// Release the editing flag
synchronized (editingLock) {
mIsEditing = false;
}
// as a runnable ... this should take priority over the "nextTextArea" setting
if (afterClose != null) {
Display.getInstance().callSerially(afterClose);
} else if (nextTextArea != null) {
final TextArea next = nextTextArea;
nextTextArea = null;
next.requestFocus();
Display.getInstance().callSerially(new Runnable() {
public void run() {
Display.getInstance().editString(next, next.getMaxSize(), next.getConstraint(), next.getText());
}
});
}
}
};
textArea.requestFocus();
textArea.repaint();
if (impl.isAsyncEditMode()) {
component.putClientProperty("android.onAsyncEditingComplete", onComplete);
return;
}
// Make this call synchronous
// We set this flag so that waitForEditCompletion can block on it.
// The flag will be released inside the endEditing method which will
// allow the method to proceed.
waitingForSynchronousEditingCompletion = true;
waitForEditCompletion();
onComplete.run();
}
use of com.codename1.ui.util.xml.Entry in project CodenameOne by codenameone.
the class RSSReader method showRSSEntry.
/**
* Shows a form containing the RSS entry
*
* @param h the parsed entry
*/
protected void showRSSEntry(Hashtable h) {
Form newForm = null;
if (targetContainer != null) {
if (targetContainer instanceof Form) {
newForm = (Form) targetContainer;
} else {
newForm = new Form((String) h.get("title"));
newForm.setLayout(new BorderLayout());
newForm.addComponent(BorderLayout.CENTER, targetContainer);
}
updateComponentValues(newForm, h);
} else {
newForm = new Form((String) h.get("title"));
newForm.setScrollable(false);
WebBrowser c = new WebBrowser();
String s = (String) h.get("description");
s = "<html><body>" + s + "</body></html>";
c.setPage(s, null);
newForm.setLayout(new BorderLayout());
newForm.addComponent(BorderLayout.CENTER, c);
}
if (addBackToTaget) {
final Form sourceForm = Display.getInstance().getCurrent();
Command back = new BackCommand(sourceForm);
newForm.addCommand(back);
newForm.setBackCommand(back);
}
newForm.show();
}
use of com.codename1.ui.util.xml.Entry in project CodenameOne by codenameone.
the class BlackBerryOS5Implementation method captureVideo.
public void captureVideo(ActionListener response) {
captureCallback = new EventDispatcher();
captureCallback.addListener(response);
UiApplication.getUiApplication().addFileSystemJournalListener(new FileSystemJournalListener() {
private long lastUSN;
private String videoPath;
public void fileJournalChanged() {
// next sequence number file system will use
long USN = FileSystemJournal.getNextUSN();
for (long i = USN - 1; i >= lastUSN && i < USN; --i) {
FileSystemJournalEntry entry = FileSystemJournal.getEntry(i);
if (entry == null) {
break;
}
String path = entry.getPath();
if (entry.getEvent() == FileSystemJournalEntry.FILE_ADDED && videoPath == null) {
int index = path.indexOf(".3GP");
if (index != -1) {
videoPath = path;
}
} else if (entry.getEvent() == FileSystemJournalEntry.FILE_RENAMED) {
if (path != null && path.equals(videoPath)) {
// close the camera
UiApplication.getUiApplication().removeFileSystemJournalListener(this);
try {
EventInjector.KeyEvent inject = new EventInjector.KeyEvent(EventInjector.KeyEvent.KEY_DOWN, Characters.ESCAPE, 0, 200);
inject.post();
inject.post();
} catch (Exception e) {
// try to close the camera
}
captureCallback.fireActionEvent(new ActionEvent("file://" + path));
captureCallback = null;
videoPath = null;
break;
}
}
}
lastUSN = USN;
}
});
app.setWaitingForReply(true);
synchronized (UiApplication.getEventLock()) {
Invoke.invokeApplication(Invoke.APP_TYPE_CAMERA, new CameraArguments(CameraArguments.ARG_VIDEO_RECORDER));
}
}
use of com.codename1.ui.util.xml.Entry in project CodenameOne by codenameone.
the class SideMenuBar method createSideNavigationPanel.
Container createSideNavigationPanel(Vector commands, String placement) {
Container menu = constructSideNavigationComponent();
if (getUIManager().isThemeConstant("paintsTitleBarBool", false)) {
Container bar = new Container();
bar.setUIID("StatusBarSideMenu");
addComponentToSideMenu(menu, bar);
}
if (!getUIManager().isThemeConstant("sideMenuTensileDragBool", true)) {
menu.setTensileDragEnabled(false);
}
for (int iter = commands.size() - 1; iter > -1; iter--) {
Command c = (Command) commands.elementAt(iter);
if (c.getClientProperty(COMMAND_PLACEMENT_KEY) != placement) {
continue;
}
Component cmp = (Component) c.getClientProperty(COMMAND_SIDE_COMPONENT);
if (cmp != null) {
if (cmp.getParent() != null) {
cmp.getParent().removeAll();
}
if (c.getClientProperty(COMMAND_ACTIONABLE) != null && c.getClientProperty(COMMAND_ACTIONABLE).equals(Boolean.TRUE)) {
Container cnt = new Container(new BorderLayout());
cnt.addComponent(BorderLayout.CENTER, cmp);
Button btn = createTouchCommandButton(c);
btn.setParent(cnt);
cnt.setLeadComponent(btn);
addComponentToSideMenu(menu, cnt);
} else {
addComponentToSideMenu(menu, cmp);
}
initTitleBarStatus();
} else {
// special case: hide back button that doesn't have text, icon or a side component entry
if (parent.getBackCommand() == c && (c.getCommandName() == null || c.getCommandName().length() == 0) && c.getIcon() == null) {
continue;
}
addComponentToSideMenu(menu, createTouchCommandButton(c));
}
}
boolean isRTLValue = isRTL();
if (placement == COMMAND_PLACEMENT_VALUE_RIGHT) {
isRTLValue = !isRTLValue;
}
UIManager uim = menu.getUIManager();
boolean shadowEnabled = uim.isThemeConstant("sideMenuShadowBool", true);
Image sh = (Image) uim.getThemeImageConstant("sideMenuShadowImage");
if (sh == null && shadowEnabled) {
sh = Resources.getSystemResource().getImage("sidemenu-shadow.png");
}
if (isRTLValue && sh != null) {
sh = sh.flipHorizontally(true);
}
final Image shadow = sh;
if (shadow == null) {
return menu;
} else {
Container main = new Container(new LayeredLayout());
Label shadowLabel = new Label();
shadowLabel.getStyle().setBackgroundType(Style.BACKGROUND_IMAGE_TILE_VERTICAL_ALIGN_CENTER);
shadowLabel.getStyle().setBgImage(shadow);
shadowLabel.getStyle().setPadding(0, 0, 0, 0);
shadowLabel.getStyle().setMargin(0, 0, 0, 0);
shadowLabel.getStyle().setBgTransparency(0);
Container c = new Container(new BorderLayout());
if (placement == COMMAND_PLACEMENT_VALUE_RIGHT) {
shadowLabel.setPreferredW(shadow.getWidth());
c.addComponent(BorderLayout.WEST, shadowLabel);
shadowLabel.getStyle().setBgImage(shadow.rotate180Degrees(true));
} else {
if (placement == COMMAND_PLACEMENT_VALUE_TOP) {
// shadowLabel.setPreferredH(shadow.getHeight());
// c.addComponent(BorderLayout.SOUTH, shadowLabel);
// shadowLabel.getStyle().setBgImage(shadow.rotate90Degrees(true));
} else {
shadowLabel.setPreferredW(shadow.getWidth());
c.addComponent(BorderLayout.EAST, shadowLabel);
}
}
main.addComponent(menu);
main.addComponent(c);
return main;
}
}
use of com.codename1.ui.util.xml.Entry in project CodenameOne by codenameone.
the class MultiButton method setInvertFirstTwoEntries.
/**
* Inverts the order of the first two entries so the second line appears first.
* This only works in horizontal mode!
*
* @param b true to place the second row entry as the first entry
*/
public void setInvertFirstTwoEntries(boolean b) {
if (b != invert) {
invert = b;
if (isHorizontalLayout()) {
Container c = firstRow.getParent();
c.removeComponent(secondRow);
if (invert) {
c.addComponent(BorderLayout.WEST, secondRow);
} else {
c.addComponent(BorderLayout.EAST, secondRow);
}
}
}
}
Aggregations