Skip to content

Commit

Permalink
javadoc
Browse files Browse the repository at this point in the history
  • Loading branch information
nicarran committed Feb 7, 2016
1 parent 9e473ba commit 9050790
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 65 deletions.
39 changes: 23 additions & 16 deletions src/main/java/jpen/PLevel.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@
import static java.lang.Math.*;

public class PLevel
extends TypedValuedClass<PLevel.Type, Float>
extends TypedValuedClass<PLevel.Type, Float>
implements java.io.Serializable {

private static final Logger L=Logger.getLogger(PLevel.class.getName());
//static{L.setLevel(Level.FINE);}
public static final long serialVersionUID=1l;

public enum Type{
public enum Type {

/**
X axis value in pixels. The X axis points to the right of the screen. It's a left handed coordinate system: the Z axis points upside.
*/
Expand Down Expand Up @@ -86,23 +88,28 @@ <li>Does the value grow (0 to 1) when the wheel is moved towards the pen tip?</l
public static final Set<Type> TILT_TYPES=Collections.unmodifiableSet(EnumSet.of(TILT_X, TILT_Y));

/**
Evaluates the azimuthX and altitude given the tilt values of the pen.
Evaluates the azimuthX and altitude given the tilt values of the pen, see {@link #evalAzimuthXAndAltitude(double[], double tiltX, double tiltY)}.
@see #evalAzimuthXAndAltitude(double[], double tiltX, double tiltY)
@param azimuthXAndAltitude array where the values (result) are going to be put in
@param pen where the necessary values to do the calculation (tilt values) are read from
*/
public static void evalAzimuthXAndAltitude(double[] azimuthXAndAltitude, PenState pen){
public static void evalAzimuthXAndAltitude(double[] azimuthXAndAltitude, PenState pen) {
evalAzimuthXAndAltitude(azimuthXAndAltitude, pen.getLevelValue(TILT_X), pen.getLevelValue(TILT_Y));
}

/**
Evaluates the azimuthX and the altitude given the tilt ({@link #TILT_X}, {@link #TILT_Y}) values. Where:<p>
{@code azimuthX} is the angle between the X axis and the projection of the pen against the X-Y plane. Clockwise direction. Range: -pi/2 and 3*pi/2 <p>
{@code azimuthX} is the angle between the X axis and the projection of the pen against the X-Y plane. Clockwise direction. Range: -pi/2 and 3*pi/2 <p>
And {@code altitude} is the angle between the pen and the projection of the pen against the X-Y plane. Range: 0 to pi/2.
@param azimuthXAndAltitude array where the values (result) are going to be put in
@param tiltX tilt value
@param tiltY tilt value
*/
public static void evalAzimuthXAndAltitude(double[] azimuthXAndAltitude, double tiltX, double tiltY){
public static void evalAzimuthXAndAltitude(double[] azimuthXAndAltitude, double tiltX, double tiltY) {
if(tiltX<0)
azimuthXAndAltitude[0]=PI;
else if(tiltX==0 && tiltY==0){
else if(tiltX==0 && tiltY==0) {
azimuthXAndAltitude[0]=0;
azimuthXAndAltitude[1]=PI_over_2;
return;
Expand All @@ -111,26 +118,26 @@ else if(tiltX==0 && tiltY==0){
double tanTiltY=tan(tiltY);
azimuthXAndAltitude[0]+=atan(tanTiltY/tan(tiltX));
azimuthXAndAltitude[1]=azimuthXAndAltitude[0]==0?
PI_over_2-tiltX:
Math.abs(atan(sin(azimuthXAndAltitude[0])/tanTiltY));
PI_over_2-tiltX:
Math.abs(atan(sin(azimuthXAndAltitude[0])/tanTiltY));
}

private static final double PI_over_2=PI/2;
public boolean isMovement(){

public boolean isMovement() {
return MOVEMENT_TYPES.contains(this);
}
public boolean isTilt(){

public boolean isTilt() {
return TILT_TYPES.contains(this);
}
}

public PLevel(PLevel level){
public PLevel(PLevel level) {
this(level.typeNumber, level.value);
}

public PLevel(Type type, float value){
public PLevel(Type type, float value) {
this(type.ordinal(), value);
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/jpen/PenDevice.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public interface PenDevice {
/**
Don't call this method. It is only for use by the {@link PenManager}. This method is called when the provider {@link PenProvider#getUseRelativeLocationFilter()} is {@code true} and this {@code PenDevice} must change its {@code useFractionalMovement} mode.
@see #getUseFractionalMovements()
@param useFractionalMovements new value of {@code useFractionalMovements} to be set, see {@link #getUseFractionalMovements()}
*/
void penManagerSetUseFractionalMovements(boolean useFractionalMovements);

Expand Down
21 changes: 20 additions & 1 deletion src/main/java/jpen/PenManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ private synchronized static void setSingletonMode(boolean singletonMode) {
private PenDevice systemMouseDevice; // may be null

/**
Creates an {@code AwtPenOwner} and calls the {@link #PenManager(PenOwner)} constructor. <b>Warning:</b> see {@link jpen.owner.awt.AwtPenOwner}.
Creates an {@code AwtPenOwner} and calls the {@link #PenManager(PenOwner)} constructor. <b>Warning:</b> see {@link AwtPenOwner}.
@param component where {@code PenEvent}s are going to be listened
*/
public PenManager(Component component) {
this(new AwtPenOwner(component));
Expand Down Expand Up @@ -267,6 +269,9 @@ public boolean getPaused() {

/**
Schedules button events. You must construct a new {@code PButton} each time you call this method (do not reuse).
@param device source device
@param deviceTime time of event creation on device
@param button button value
*/
public void scheduleButtonEvent(PenDevice device, long deviceTime, PButton button) {
if(paused)
Expand All @@ -276,6 +281,10 @@ public void scheduleButtonEvent(PenDevice device, long deviceTime, PButton butto

/**
Schedules scroll events. You must construct a new {@code PScroll} each time you call this method (do not reuse).
@param device source device
@param deviceTime time of event creation on device
@param scroll scroll value
*/
public void scheduleScrollEvent(PenDevice device, long deviceTime, PScroll scroll) {
if(paused)
Expand All @@ -289,6 +298,12 @@ public boolean scheduleLevelEvent(PenDevice device, long deviceTime, Collection<

/**
Schedules level events. You can reuse the levels {@code Collection} but you must construct new {@code PLevel}s each time you call this method.
@param device source device
@param deviceTime time of even creation on device
@param levels level values
@param levelsOnScreen {@code true} if the level movement values are on the screen coordinate system, {@code false} otherwise
@return {@code true} if an event was scheduled, {@code false} false if it was filter out
*/
public boolean scheduleLevelEvent(PenDevice device, long deviceTime, Collection<PLevel> levels, boolean levelsOnScreen) {
if(paused)
Expand All @@ -298,6 +313,10 @@ public boolean scheduleLevelEvent(PenDevice device, long deviceTime, Collection<

/**
Uses reflection to get the first provider of the given class.
@param providerClass class of {@link PenProvider} to search for
@param <T> {@code providerClass} parametrization
@return the first {@link PenProvider} matching
*/
public <T extends PenProvider> T getProvider(Class<T> providerClass) {
for(PenProvider.Constructor constructor: getProviderConstructors()) {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/jpen/PenProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ public interface Constructor {
*/
String getName();
/**
@param pm where the construction is being requested
@return {@code true} if the {@code PenProvider} can be constructed on this system, {@code false} otherwise.This method usually test for the name of the operating system and returns {@code true} if it matches an operating system in which this provider can run.
*/
boolean constructable(PenManager pm);
/**
This method constructs the {@code PenProvider}. It is called only when {@link #constructable(PenManager)} returns {@code true}. When this methods completes, it is expected that the {@link #getConstructed()} method returns the {@code PenProvider} constructed. If the {@code PenProvider} couldn't be constructed due to some condition (e.g. the required native drivers are not present) then the {@link #getConstructionException()} method is expected to return an exception describing the condition.
@param pm where the construction is being requested
@return {@code true} if the {@code PenProvider} was constructed. {@code false} if the {@code PenProvider} couldn't be constructed.
*/
boolean construct(PenManager pm);
Expand Down
1 change: 1 addition & 0 deletions src/main/java/jpen/event/PenListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Useful to detect if the listeners are taking too much time processing events ({@
The pen fires queued events at a given frequency (by default {@link jpen.Pen#DEFAULT_FREQUENCY}) in its own thread. Each cycle, after firing and processing the events, the pen calls jpen.event.PenListener.penTock(long availableMillis), where availableMillis is the time left of the period: {@code availableMillis=period-firingTime }, {@code period=1000/frequency}, and {@code firingTime} is the time spent in firing and processing events in the cycle.<p>
This method is called from the event dispatch thread if {@link Pen#getFirePenTockOnSwing()} is {@code true}.
@param availableMillis time of period left after processing events in milliseconds
@see Pen#setFirePenTockOnSwing(boolean)
*/
void penTock(long availableMillis); // TODO: Pen parameter??
Expand Down
98 changes: 53 additions & 45 deletions src/main/java/jpen/internal/filter/RelativeLocationFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,16 @@
import jpen.PenState;
import jpen.PLevel;

public final class RelativeLocationFilter{
public final class RelativeLocationFilter {

private static final Logger L=Logger.getLogger(RelativeLocationFilter.class.getName());
//static { L.setLevel(Level.ALL); }


private PenDevice penDevice;
private State state=State.UNDEFINED;
public enum State{
public enum State {

/**
The filter tries to see if the values are absolute or relative and sets the state if possible.
*/
Expand All @@ -59,16 +61,17 @@ The filter considers the sample values to be in relative mode and replace them w
final Point2D.Float reference=new Point2D.Float();
final SamplePoint samplePoint=new SamplePoint();
static class SamplePoint
implements Cloneable{
implements Cloneable {

PLevel levelX, levelY;
boolean isComplete;

boolean reset(Collection<PLevel> sample){
boolean reset(Collection<PLevel> sample) {
levelX=levelY=null;
int valuesCount=0;
out:
for(PLevel level: sample){
switch(level.getType()){
out:
for(PLevel level: sample) {
switch(level.getType()) {
case X:
valuesCount++;
levelX=level;
Expand All @@ -87,11 +90,11 @@ boolean reset(Collection<PLevel> sample){
return valuesCount>0;
}

private void set(float x, float y){
private void set(float x, float y) {
set(x, y, null);
}

private void set(float x, float y, Collection<PLevel> sample){
private void set(float x, float y, Collection<PLevel> sample) {
if(levelX!=null)
levelX.value=x;
else if(sample!=null)
Expand All @@ -103,51 +106,56 @@ else if(sample!=null)
}

@Override
public SamplePoint clone(){
try{
public SamplePoint clone() {
try {
SamplePoint clone=(SamplePoint)super.clone();
clone.levelX=new PLevel(levelX);
clone.levelY=new PLevel(levelY);
return clone;
}catch(CloneNotSupportedException ex){
} catch(CloneNotSupportedException ex) {
throw new AssertionError(ex);
}
}
}

final Point2D.Float deviation=new Point2D.Float();
final Point2D.Float absDeviation=new Point2D.Float();
private final Rule[] rules=new Rule[]{
//new LogToFileRule(),
new AbsoluteLocationRule(),
new AbsoluteOnARowRule(),
new RelativeOnSlopesRule(),
};
interface Rule{
private final Rule[] rules=new Rule[] {
//new LogToFileRule(),
new AbsoluteLocationRule(),
new AbsoluteOnARowRule(),
new RelativeOnSlopesRule(),
};
interface Rule {

void reset();
State evalFilterNextState(RelativeLocationFilter filter);
}

public void reset(){
public void reset() {
penDevice=null;
resetRules();
}

private void resetRules(){
for(Rule rule: rules){
private void resetRules() {
for(Rule rule: rules) {
rule.reset();
}
}

/**
@return {@code true} if the state changed to a definitive value.
@param penState the current pen values
@param penDevice where the {@code sample} levels are coming from
@param sample level values to be filtered/changed according to the {@code state} of this {@code RelativeLocationFilter}
@param levelsOnScreen {@code true} if the given {@code sample} levels are on the screen coordinate system
@return {@code true} if the state of this {@code RelativeLocationFilter} changed to a definitive value.
*/
public boolean filter(PenState penState, PenDevice penDevice, Collection<PLevel> sample, boolean levelsOnScreen){
if(!levelsOnScreen) // only levelsOnScreen is supported
public boolean filter(PenState penState, PenDevice penDevice, Collection<PLevel> sample, boolean levelsOnScreen) {
if(!levelsOnScreen) // only levelsOnScreen are supported
return false;
if(state.equals(State.OFF))
return false;
if(this.penDevice!=penDevice){
if(this.penDevice!=penDevice) {
this.penDevice=penDevice;
state=State.UNDEFINED;
resetRules();
Expand All @@ -162,32 +170,32 @@ public boolean filter(PenState penState, PenDevice penDevice, Collection<PLevel>
return true;

boolean stateChanged=false;
if(state.equals(State.UNDEFINED)){
if(state.equals(State.UNDEFINED)) {
setupDeviation();
stateChanged=evalStateFromRules();
}
switch(state){
switch(state) {
case ABSOLUTE:
break;
case RELATIVE:
samplePoint.set(reference.x, reference.y, sample);
break;
case UNDEFINED:
samplePoint.set(penState.getLevelValue(PLevel.Type.X),
penState.getLevelValue(PLevel.Type.Y)); // then it won't cause a level event because movement
penState.getLevelValue(PLevel.Type.Y)); // then it won't cause a level event because of movement
break;
default:
}
return stateChanged;
}

private static boolean evalIsSystemMouseDevice(PenDevice device){
private static boolean evalIsSystemMouseDevice(PenDevice device) {
return device.getProvider().getConstructor().getPenManager().isSystemMouseDevice(device);
}

private boolean setupReference(){
private boolean setupReference() {
PointerInfo pointerInfo=AccessController.doPrivileged(getPointerInfoAction);
if(pointerInfo==null){
if(pointerInfo==null) {
L.warning("No mouse found. Can not correct devices on relative (mouse) mode.");
state=State.OFF;
return false;
Expand All @@ -196,36 +204,36 @@ private boolean setupReference(){
return true;
}

private final PrivilegedAction<PointerInfo> getPointerInfoAction=new PrivilegedAction<PointerInfo>(){
//@Override
public PointerInfo run(){
return MouseInfo.getPointerInfo();
}
};
private final PrivilegedAction<PointerInfo> getPointerInfoAction=new PrivilegedAction<PointerInfo>() {
//@Override
public PointerInfo run() {
return MouseInfo.getPointerInfo();
}
};

private void setupDeviation(){
if(samplePoint.levelX!=null){
private void setupDeviation() {
if(samplePoint.levelX!=null) {
deviation.x=samplePoint.levelX.value-reference.x;
absDeviation.x=Math.abs(deviation.x);
}
if(samplePoint.levelY!=null){
if(samplePoint.levelY!=null) {
deviation.y=samplePoint.levelY.value-reference.y;
absDeviation.y=Math.abs(deviation.y);
}
}

private boolean evalStateFromRules(){
for(Rule rule: rules){
private boolean evalStateFromRules() {
for(Rule rule: rules) {
State nextState=rule.evalFilterNextState(this);
if(nextState!=null){
if(nextState!=null) {
this.state=nextState;
return true;
}
}
return false;
}

public State getState(){
public State getState() {
return state;
}
}
Loading

0 comments on commit 9050790

Please sign in to comment.