Skip to content

Commit

Permalink
Removed debugging text for safe area (#3024)
Browse files Browse the repository at this point in the history
Added some more nuance to layout of children inside scrollable containers with the constrainWidthWhenScrollable() and constrainHeightWhenScrollable() methods.
Moved DataChangeListener and DoneListener support into TextArea from TextField so that these are available for multi-line fields.
Changed behaviour of JavaSE multiline text areas when a done listener is assigned to the TextArea.  Enter will now fire done event.  Shift-enter will do what enter used to do - add a newline.
  • Loading branch information
shannah committed Feb 14, 2020
1 parent 9fc2b4b commit 03245c6
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 109 deletions.
74 changes: 67 additions & 7 deletions CodenameOne/src/com/codename1/ui/Container.java
Original file line number Diff line number Diff line change
Expand Up @@ -658,11 +658,11 @@ public void setShouldCalcPreferredSize(boolean shouldCalcPreferredSize) {
* @return the layout width
*/
public int getLayoutWidth() {
if (isScrollableX()) {
if (scrollableX) {
return Math.max(getWidth(), getPreferredW());
} else {
Container parent = getScrollableParent();
if (parent != null && parent.isScrollableX()) {
Container parent = getScrollableParentX();
if (parent != null && parent.scrollableX) {
return Math.max(getWidth(), getPreferredW());
}
int width = getWidth();
Expand All @@ -683,7 +683,7 @@ public int getLayoutHeight() {
if (scrollableY) {
return Math.max(getHeight(), getPreferredH());
} else {
Container parent = getScrollableParent();
Container parent = getScrollableParentY();
if (parent != null && parent.scrollableY) {
return Math.max(getHeight(), getPreferredH());
}
Expand Down Expand Up @@ -716,22 +716,82 @@ public void applyRTL(boolean rtl) {


/**
* Returns a parent container that is scrollable or null if no parent is
* Returns a parent container that is scrollableX or null if no parent is
* scrollable.
*
* NOTE: This is a utility method that is designed for the getLayoutWidth()
* method, which is why it obeys the constrainHeightWhenScrollable() attribute.
*
* @return a parent container that is scrollable or null if no parent is
* scrollable.
*/
private Container getScrollableParent() {
private Container getScrollableParentX() {
Container parent = getParent();
while (parent != null) {
if (parent.isScrollable()) {
if (parent.scrollableX && !parent.constrainWidthWhenScrollable()) {
return parent;
}
parent = parent.getParent();
}
return null;
}

/**
* Returns a parent container that is scrollableY or null if no parent is
* scrollable.
*
* NOTE: This is a utility method that is designed for the getLayoutHeight()
* method, which is why it obeys the constrainHeightWhenScrollable() attribute.
*
* @return a parent container that is scrollable or null if no parent is
* scrollable.
*/
private Container getScrollableParentY() {
Container parent = getParent();
while (parent != null) {
if (parent.scrollableY && !parent.constrainHeightWhenScrollable()) {
return parent;
}
parent = parent.getParent();
}
return null;
}



/**
* Indicates that children's widths should be calculated as if this component weren't
* scrollable-X, even when the component is scrollable X. Normally, when a component
* is figuring out its layout width, it will walk up the UI hierarchy to find the
* first scrollable container. If there is a scrollable container, then the component
* will try to grow as big as it wants. If there are no scrollable containers found,
* it will constrain itself to the space available. In some cases, we may want the children
* of a component to lay themselves out conservatively though because it wants to use its
* scrollability for other features.
* @return True if children should calculate their layout widgets as if the component
* weren't scrollable.
* @since 7.0
*/
protected boolean constrainWidthWhenScrollable() {
return false;
}

/**
* Indicates that children's widths should be calculated as if this component weren't
* scrollable-X, even when the component is scrollable Y. Normally, when a component
* is figuring out its layout width, it will walk up the UI hierarchy to find the
* first scrollable container. If there is a scrollable container, then the component
* will try to grow as big as it wants. If there are no scrollable containers found,
* it will constrain itself to the space available. In some cases, we may want the children
* of a component to lay themselves out conservatively though because it wants to use its
* scrollability for other features.
* @return True if children should calculate their layout widgets as if the component
* weren't scrollable.
* @since 7.0
*/
protected boolean constrainHeightWhenScrollable() {
return false;
}

/**
* Adds a Component to the Container
Expand Down
100 changes: 99 additions & 1 deletion CodenameOne/src/com/codename1/ui/TextArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
package com.codename1.ui;

import com.codename1.cloud.BindTarget;
import com.codename1.compat.java.util.Objects;
import com.codename1.impl.CodenameOneImplementation;
import com.codename1.io.Log;
import com.codename1.ui.TextSelection.Span;
import com.codename1.ui.TextSelection.Spans;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.events.ActionSource;
import com.codename1.ui.events.DataChangedListener;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.geom.Rectangle;
import com.codename1.ui.plaf.LookAndFeel;
Expand Down Expand Up @@ -60,6 +62,9 @@
* @author Chen Fishbein
*/
public class TextArea extends Component implements ActionSource {
private EventDispatcher listeners = new EventDispatcher();
private ActionListener doneListener;

private static int defaultValign = TOP;

/**
Expand Down Expand Up @@ -502,7 +507,9 @@ public void setText(String t) {
//zero the ArrayList in order to initialize it on the next paint
rowStrings=null;
}

if (!Objects.equals(text, old)) {
fireDataChanged(DataChangedListener.CHANGED, -1);
}
// while native editing we don't need the cursor animations
if(Display.getInstance().isNativeInputSupported() && Display.getInstance().isTextEditing(this)) {
if (!text.equals(old)) {
Expand Down Expand Up @@ -2112,6 +2119,97 @@ public Style getStyle() {
}
return super.getStyle();
}

/**
* Adds a listener for data change events it will be invoked for every change
* made to the text field, notice most platforms will invoke only the
* DataChangedListener.CHANGED event
*
* @param d the listener
*/
public void addDataChangedListener(DataChangedListener d) {
listeners.addListener(d);
}

/**
* Removes the listener for data change events
*
* @param d the listener
*/
public void removeDataChangedListener(DataChangedListener d) {
listeners.removeListener(d);
}

/**
* Adds a listener for data change events it will be invoked for every change
* made to the text field, notice most platforms will invoke only the
* DataChangedListener.CHANGED event
*
* @param d the listener
* @deprecated use #addDataChangedListener(DataChangedListener) instead
*/
public void addDataChangeListener(DataChangedListener d) {
listeners.addListener(d);
}

/**
* Removes the listener for data change events
*
* @param d the listener
* @deprecated use #removeDataChangedListener(DataChangedListener) instead
*/
public void removeDataChangeListener(DataChangedListener d) {
listeners.removeListener(d);
}

/**
* Alert the TextField listeners the text has been changed on the TextField
* @param type the event type: Added, Removed or Change
* @param index cursor location of the event
*/
public void fireDataChanged(int type, int index) {
if(listeners != null) {
listeners.fireDataChangeEvent(index, type);
}
}


/**
* Sets a Done listener on the TextField - notice this listener will be called
* only on supported platforms that supports done action on the keyboard
*
* @param l the listener
*/
public void setDoneListener(ActionListener l) {
doneListener = l;
}

/**
* Gets the done listener of this TextField.
*
* @return the done listener or null if not exists
*/
public ActionListener getDoneListener() {
return doneListener;
}

/**
* Fire the done event to done listener
*/
public void fireDoneEvent() {
if (doneListener != null) {
if (!Display.getInstance().isEdt()) {
Display.getInstance().callSerially(new Runnable() {

public void run() {
fireDoneEvent();
}
});
return;
}
doneListener.actionPerformed(new ActionEvent(this,ActionEvent.Type.Done));
}
}

/**
* This flag indicates that the text area should try to act as a label and try to fix more accurately within it's bounds
Expand Down
91 changes: 0 additions & 91 deletions CodenameOne/src/com/codename1/ui/TextField.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ public static void setUseNativeTextInput(boolean aUseNativeTextInput) {
private boolean qwerty = qwertyDevice;
private boolean replaceMenu = replaceMenuDefault;
private Command[] originalCommands;
private EventDispatcher listeners = new EventDispatcher();
private ActionListener doneListener;
private boolean overwriteMode;
private boolean enableInputScroll = true;

Expand Down Expand Up @@ -835,7 +833,6 @@ public int getCursorX() {
public void setText(String text) {
super.setText(text);
if(text != null) {
fireDataChanged(DataChangedListener.CHANGED, -1);
int pos = getCursorPosition();
if(pos < 0) {
pos = text.length();
Expand All @@ -846,7 +843,6 @@ public void setText(String text) {
}
setCursorPosition(pos);
} else {
fireDataChanged(DataChangedListener.CHANGED, -1);
setCursorPosition(0);
}
}
Expand Down Expand Up @@ -1707,95 +1703,8 @@ public void setUseSoftkeys(boolean useSoftkeys) {
this.useSoftkeys = useSoftkeys;
}

/**
* Sets a Done listener on the TextField - notice this listener will be called
* only on supported platforms that supports done action on the keyboard
*
* @param l the listener
*/
public void setDoneListener(ActionListener l) {
doneListener = l;
}

/**
* Gets the done listener of this TextField.
*
* @return the done listener or null if not exists
*/
public ActionListener getDoneListener() {
return doneListener;
}

/**
* Fire the done event to done listener
*/
public void fireDoneEvent() {
if (doneListener != null) {
if (!Display.getInstance().isEdt()) {
Display.getInstance().callSerially(new Runnable() {

public void run() {
fireDoneEvent();
}
});
return;
}
doneListener.actionPerformed(new ActionEvent(this,ActionEvent.Type.Done));
}
}

/**
* Adds a listener for data change events it will be invoked for every change
* made to the text field, notice most platforms will invoke only the
* DataChangedListener.CHANGED event
*
* @param d the listener
*/
public void addDataChangedListener(DataChangedListener d) {
listeners.addListener(d);
}

/**
* Removes the listener for data change events
*
* @param d the listener
*/
public void removeDataChangedListener(DataChangedListener d) {
listeners.removeListener(d);
}

/**
* Adds a listener for data change events it will be invoked for every change
* made to the text field, notice most platforms will invoke only the
* DataChangedListener.CHANGED event
*
* @param d the listener
* @deprecated use #addDataChangedListener(DataChangedListener) instead
*/
public void addDataChangeListener(DataChangedListener d) {
listeners.addListener(d);
}

/**
* Removes the listener for data change events
*
* @param d the listener
* @deprecated use #removeDataChangedListener(DataChangedListener) instead
*/
public void removeDataChangeListener(DataChangedListener d) {
listeners.removeListener(d);
}

/**
* Alert the TextField listeners the text has been changed on the TextField
* @param type the event type: Added, Removed or Change
* @param index cursor location of the event
*/
public void fireDataChanged(int type, int index) {
if(listeners != null) {
listeners.fireDataChangeEvent(index, type);
}
}

/**
* {@inheritDoc}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1144,10 +1144,9 @@ private synchronized void endEditing(int reason, boolean forceVKBOpen, boolean f
}
int imo = mEditText.getImeOptions() & 0xf; // Get rid of flags
if (reason == REASON_IME_ACTION
&& mEditText.mTextArea instanceof TextField
&& ((TextField) mEditText.mTextArea).getDoneListener() != null
&& (actionCode == EditorInfo.IME_ACTION_DONE)|| actionCode == EditorInfo.IME_ACTION_SEARCH || actionCode == EditorInfo.IME_ACTION_SEND || actionCode == EditorInfo.IME_ACTION_GO) {
((TextField) mEditText.mTextArea).fireDoneEvent();
((TextArea) mEditText.mTextArea).fireDoneEvent();

}

Expand Down
Loading

0 comments on commit 03245c6

Please sign in to comment.