When I drag the mouse pointer outside the processing window, my program reacts in unexpected ways. How to reproduce:
Attention, this effect is observed only when the mouse pointer moves out of the area of the application window. Are there any options to eliminate this effect or how to avoid it?
If you do not move the mouse pointer over the window size area, then everything works without problems!
Сode:
import controlP5.*;
ControlP5 cp5;
// range constants
final float RANGE_MIN = 7.4;
final float RANGE_MAX = 16.8;
// the smallest allowed difference between min/max values
final float RANGE_MIN_DIFFERENCE = 1;
final float RANGE_MID = RANGE_MIN + ((RANGE_MAX - RANGE_MIN) / 2);
float minValue;
float maxValue;
Numberbox inputMin;
Numberbox inputMax;
void setup() {
size(700, 400);
PFont font = createFont("arial", 18);
cp5 = new ControlP5(this);
inputMin = cp5.addNumberbox("minValue")
.setPosition(360, 240)
.setSize(80, 30)
.setColorValue(0xffffff00)
.setFont(font)
.setScrollSensitivity(1.1)
// set initial acceptable range
.setMin(RANGE_MIN)
.setMax(RANGE_MAX)
// set default value
.setMultiplier(0.01)
.setDirection(Controller.HORIZONTAL)
.setValue(7.4);
Label labelinputMin = inputMin.getCaptionLabel();
labelinputMin.setFont(font);
labelinputMin.setColor(color(#00ffff));
labelinputMin.toUpperCase(false);
labelinputMin.setText("MIN");
labelinputMin.align(ControlP5.LEFT_OUTSIDE, CENTER);
labelinputMin.getStyle().setPaddingLeft(-100);
inputMax = cp5.addNumberbox("maxValue")
.setPosition(360, 300)
.setSize(80, 30)
.setColorValue(0xffffff00)
.setFont(font)
.setScrollSensitivity(1.1)
// set initial acceptable range
.setMin(RANGE_MIN)
.setMax(RANGE_MAX)
// set default value
.setMultiplier(0.01)
.setDirection(Controller.HORIZONTAL)
.setValue(RANGE_MID + 1);
Label labelinputMax= inputMax.getCaptionLabel();
labelinputMax.setFont(font);
labelinputMax.setColor(color(#00ffff));
labelinputMax.toUpperCase(false);
labelinputMax.setText("МAX");
labelinputMax.align(ControlP5.LEFT_OUTSIDE, CENTER);
labelinputMax.getStyle().setPaddingLeft(-93);
textFont(font);
}
void draw() {
constrainRangeInputs();
background(0);
fill(255);
text("minValue: " + minValue + "\n" +
"maxValue: " + maxValue, 10, 15);
}
void controlEvent(ControlEvent event) {
println(event.getController().getName(), "changed value to", event.getValue(), "RANGE_MIN = ", minValue, "RANGE_MAX = ", maxValue);
}
void constrainRangeInputs() {
float rangeMinInt = (float)inputMin.getValue();
float rangeMaxInt = (float)inputMax.getValue();
//
if (abs(rangeMaxInt - rangeMinInt) < RANGE_MIN_DIFFERENCE) {
if (rangeMaxInt > RANGE_MID) {
inputMin.setValue(rangeMaxInt - RANGE_MIN_DIFFERENCE);
} else {
inputMax.setValue(rangeMinInt + RANGE_MIN_DIFFERENCE);
}
}
}
This problem arises from a mix of something you wrote and the way Processing's draw()
loop is limited by it's FPS, probably 60 in your case as you haven't set it.
The constrainRangeInputs
method is called by the draw()
loop, but not the Numberbox.updateInternalEvents
method. If your FPS were veeery low, the numberbox could update several time between two loops of the draw()
method, even if we wouldn't see it as it's not visually updated.
Then, when it's time for the draw()
loop to do it's thing, it calls your constrainRangeInputs()
method.
The problem is here:
if (abs(rangeMaxInt - rangeMinInt) < RANGE_MIN_DIFFERENCE) {
The absolute number makes it possible that a rangeMinInt
be higher than a rangeMaxInt
if it's high enough. Here's an example of when it would happens:
Assuming these values:
rangeMinInt = 15
rangeMaxInt = 10
RANGE_MIN_DIFFERENCE = 1
// Reading these numbers, you already know that this is supposed to be corrected by the constrainRangeInputs() method, but...
// Doing the math reveals that:
rangeMaxInt - rangeMinInt = -5
// yet:
abs(rangeMaxInt - rangeMinInt) = 5
// So:
abs(rangeMaxInt - rangeMinInt) < RANGE_MIN_DIFFERENCE // false
// The program sees this as absolutely normal!
This has nothing to do with going out of the window (if you change the window's size to make it very wide you'll be able to reproduce the problem, I did it experimentally). The problem is that, when the constrainRangeInputs()
did it's job, the current number was already high enough to be conform to your conditions.
That's because the mouse moved fast enough to cover more than the RANGE_MIN_DIFFERENCE
in the time between two iterations of the draw()
loop.
You can fix this easily by getting rid of the abs()
. I have no idea why it would be relevant in the first place, but as you adapted this from existing code it's probably an artifact from the original code.
So: change this line
if (abs(rangeMaxInt - rangeMinInt) < RANGE_MIN_DIFFERENCE) {
for this instead:
if (rangeMaxInt - rangeMinInt < RANGE_MIN_DIFFERENCE) {
Hope it helps, that was trickier than it seems. Have fun!