Skip to content

Commit

Permalink
Merge pull request #2910 from ramsestom/gereric-releasable
Browse files Browse the repository at this point in the history
add a generic Interface for releasable Components
  • Loading branch information
shai-almog committed Sep 14, 2019
2 parents a3f3fa2 + 9cccc85 commit 597a58e
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 53 deletions.
19 changes: 11 additions & 8 deletions CodenameOne/src/com/codename1/ui/Button.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
*
* @author Chen Fishbein
*/
public class Button extends Label {
public class Button extends Label implements IReleasable {
/**
* Default value for the button ripple effect, this can be set with the theme constant buttonRippleBool
*/
Expand Down Expand Up @@ -366,6 +366,14 @@ void setState(int state) {
this.state = state;
}

/**
* Set the button in released and unfocused state
*/
public void setReleased() {
setState(Button.STATE_DEFAULT);
repaint();
}

/**
* Indicates the icon that is displayed on the button when the button is in
* pressed state
Expand Down Expand Up @@ -678,10 +686,7 @@ public void pointerPressed(int x, int y) {
Form f = getComponentForm();
// might happen when programmatically triggering press
if(f != null) {
if(f.buttonsAwatingRelease == null) {
f.buttonsAwatingRelease = new ArrayList<Component>();
}
f.buttonsAwatingRelease.add(this);
f.addComponentAwaitingRelease(this);
}
}

Expand All @@ -699,9 +704,7 @@ public void pointerReleased(int x, int y) {
Form f = getComponentForm();
// might happen when programmatically triggering press
if(f != null) {
if(f.buttonsAwatingRelease != null) {
f.buttonsAwatingRelease.remove(this);
}
f.removeComponentAwaitingRelease(this);
}

// button shouldn't fire an event when a pointer is dragged into it
Expand Down
4 changes: 1 addition & 3 deletions CodenameOne/src/com/codename1/ui/Component.java
Original file line number Diff line number Diff line change
Expand Up @@ -4296,9 +4296,7 @@ pullY < getHeight() / 4 &&
scrollableYFlag() && getScrollY() == 0) {
int mm = Display.INSTANCE.convertToPixels(1);
if(mm < y - pullY) {
if(p.buttonsAwatingRelease != null) {
p.buttonsAwatingRelease.clear();
}
p.clearComponentsAwaitingRelease();
Container c = p.getLayeredPane(InfiniteProgress.class, true);
c.setLayout(new FlowLayout(CENTER));
Motion rotationMotion;
Expand Down
101 changes: 62 additions & 39 deletions CodenameOne/src/com/codename1/ui/Form.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public class Form extends Container {

private TextSelection textSelection;

ArrayList<Component> buttonsAwatingRelease;
private ArrayList<Component> componentsAwatingRelease;

private VirtualInputDevice currentInputDevice;

Expand Down Expand Up @@ -2139,7 +2139,7 @@ void deinitializeImpl() {
}
super.deinitializeImpl();
animMananger.flush();
buttonsAwatingRelease = null;
componentsAwatingRelease = null;
dragged = null;
}

Expand Down Expand Up @@ -3224,33 +3224,54 @@ private boolean isCurrentlyScrolling(Component cmp) {
}
return false;
}


public <C extends Component & IReleasable> void addComponentAwaitingRelease(C c) {
if(componentsAwatingRelease == null) {
componentsAwatingRelease = new ArrayList<Component>();
}
componentsAwatingRelease.add(c);
}

public <C extends Component & IReleasable> void removeComponentAwaitingRelease(C c) {
if(componentsAwatingRelease != null) {
componentsAwatingRelease.remove(c);
}
}

public void clearComponentsAwaitingRelease() {
if (componentsAwatingRelease != null) {
componentsAwatingRelease.clear(); //componentsAwatingRelease = null; //can be set to null or cleared, would be the same. clear may save some unnecessary GC operations when some releasable components are pressed multiple times
}
}


private void autoRelease(int x, int y) {
if(buttonsAwatingRelease != null && buttonsAwatingRelease.size() == 1) {
if(componentsAwatingRelease != null && componentsAwatingRelease.size() == 1) {
// special case allowing drag within a button
Component atXY = getComponentAt(x, y);
if (atXY instanceof Container) {
atXY = atXY.getLeadComponent();
}
Component pendingButton = buttonsAwatingRelease.get(0);
if (atXY != pendingButton) {
if (pendingButton instanceof Button) {
Button b = (Button) pendingButton;
int relRadius = b.getReleaseRadius();
Component pendingC = componentsAwatingRelease.get(0);
if (atXY != pendingC) {
if (pendingC instanceof IReleasable) {
IReleasable rc = (IReleasable) pendingC;
int relRadius = rc.getReleaseRadius();
if (relRadius > 0) {
Rectangle r = new Rectangle(b.getAbsoluteX() - relRadius, b.getAbsoluteY() - relRadius, b.getWidth() + relRadius * 2, b.getHeight() + relRadius * 2);
Rectangle r = new Rectangle(pendingC.getAbsoluteX() - relRadius, pendingC.getAbsoluteY() - relRadius, pendingC.getWidth() + relRadius * 2, pendingC.getHeight() + relRadius * 2);
if (!r.contains(x, y)) {
buttonsAwatingRelease = null;
b.dragInitiated();
componentsAwatingRelease = null;
pendingC.dragInitiated();
}
return;
}
buttonsAwatingRelease = null;
b.dragInitiated();
componentsAwatingRelease = null;
pendingC.dragInitiated();
}
} else if (pendingButton instanceof Button && ((Button) pendingButton).isAutoRelease()) {
buttonsAwatingRelease = null;
((Button) pendingButton).dragInitiated();
} else if (pendingC instanceof IReleasable && ((IReleasable) pendingC).isAutoRelease()) {
componentsAwatingRelease = null;
pendingC.dragInitiated();
}
}
}
Expand Down Expand Up @@ -3514,22 +3535,22 @@ public void pointerReleased(int x, int y) {
setPressedCmp(null);
boolean isScrollWheeling = Display.INSTANCE.impl.isScrollWheeling();
Container actual = getActualPane(formLayeredPane, x, y);
if(buttonsAwatingRelease != null && buttonsAwatingRelease.size() == 1) {
if(componentsAwatingRelease != null && componentsAwatingRelease.size() == 1) {
// special case allowing drag within a button
Component atXY = actual.getComponentAt(x, y);

Component pendingButton = (Component)buttonsAwatingRelease.get(0);
if(atXY == pendingButton) {
buttonsAwatingRelease = null;
if (dragged == pendingButton) {
if (pendingButton.isDragAndDropInitialized()) {
pendingButton.dragFinishedImpl(x, y);
Component pendingC = componentsAwatingRelease.get(0);
if(atXY == pendingC) {
componentsAwatingRelease = null;
if (dragged == pendingC) {
if (pendingC.isDragAndDropInitialized()) {
pendingC.dragFinishedImpl(x, y);
} else {
pendingButton.pointerReleased(x, y);
pendingC.pointerReleased(x, y);
}
dragged = null;
} else {
pendingButton.pointerReleased(x, y);
pendingC.pointerReleased(x, y);
if (dragged != null) {
if (dragged.isDragAndDropInitialized()) {
dragged.dragFinishedImpl(x, y);
Expand All @@ -3543,14 +3564,14 @@ public void pointerReleased(int x, int y) {
return;
}

if(pendingButton instanceof Button) {
Button b = (Button)pendingButton;
int relRadius = b.getReleaseRadius();
if(relRadius > 0 || b.contains(x, y)) {
Rectangle r = new Rectangle(b.getAbsoluteX() - relRadius, b.getAbsoluteY() - relRadius, b.getWidth() + relRadius * 2, b.getHeight() + relRadius * 2);
if(pendingC instanceof IReleasable) {
IReleasable rc = (IReleasable) pendingC;
int relRadius = rc.getReleaseRadius();
if(relRadius > 0 || pendingC.contains(x, y)) {
Rectangle r = new Rectangle(pendingC.getAbsoluteX() - relRadius, pendingC.getAbsoluteY() - relRadius, pendingC.getWidth() + relRadius * 2, pendingC.getHeight() + relRadius * 2);
if(r.contains(x, y)) {
buttonsAwatingRelease = null;
pointerReleased(b.getAbsoluteX() + 1, b.getAbsoluteY() + 1);
componentsAwatingRelease = null;
pointerReleased(pendingC.getAbsoluteX() + 1, pendingC.getAbsoluteY() + 1);
return;
}
}
Expand Down Expand Up @@ -3685,13 +3706,15 @@ public void pointerReleased(int x, int y) {
}
}
stickyDrag = null;
if (buttonsAwatingRelease != null && !Display.getInstance().isRecursivePointerRelease()) {
for (int iter = 0; iter < buttonsAwatingRelease.size(); iter++) {
Button b = (Button) buttonsAwatingRelease.get(iter);
b.setState(Button.STATE_DEFAULT);
b.repaint();
}
buttonsAwatingRelease = null;
if (componentsAwatingRelease != null && !Display.getInstance().isRecursivePointerRelease()) {
for (int iter = 0; iter < componentsAwatingRelease.size(); iter++) {
Component c = componentsAwatingRelease.get(iter);
if (c instanceof IReleasable) {
IReleasable rc = (IReleasable) c;
rc.setReleased();
}
}
componentsAwatingRelease = null;
}
}

Expand Down
36 changes: 36 additions & 0 deletions CodenameOne/src/com/codename1/ui/IReleasable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.codename1.ui;

/** An Interface that any Component that could be released from the parent Form can implement */

public interface IReleasable {

/**
* Returns true if this is an auto-released Component.
* An Auto-released Component will be disarmed when a drag is happening within it
*/
public boolean isAutoRelease();

/**
* Sets the auto released mode of the Component
*/
public void setAutoRelease(boolean autoRelease);

/**
* Indicates a radius in which a pointer release will still have effect. Notice that this only applies to
* pointer release events and not to pointer press events
* @return the releaseRadius
*/
public int getReleaseRadius();

/**
* Indicates a radius in which a pointer release will still have effect. Notice that this only applies to
* pointer release events and not to pointer press events
* @param releaseRadius the releaseRadius to set
*/
public void setReleaseRadius(int releaseRadius);

/**
* Function that would be called by the parent Form to put the Component in its released state
*/
public void setReleased();
}
4 changes: 1 addition & 3 deletions CodenameOne/src/com/codename1/ui/Tabs.java
Original file line number Diff line number Diff line change
Expand Up @@ -1357,9 +1357,7 @@ public void actionPerformed(ActionEvent evt) {
// of weight.
dragStarted = Math.abs(x - initialX) > (contentPane.getWidth() / 8);
Form parent = getComponentForm();
if(parent.buttonsAwatingRelease != null) {
parent.buttonsAwatingRelease = null;
}
parent.clearComponentsAwaitingRelease();
}
}
}
Expand Down

0 comments on commit 597a58e

Please sign in to comment.