When I drag the mouse pointer outside the processing window, my program reacts in unexpected ways. How to reproduce:
- Hover the mouse pointer over the "MIN" field and try to change the value of the numbers in the field, while holding the left mouse button.
- Drag the mouse pointer at an average speed or sharply to the left and then to the right, beyond the area of the application window without releasing the left button mouse.
- Now the following conditions are not met:
- MIN < MAX
- Always MIN - 500 units from MAX.
- MAX > MIN
- MAX + 500 units from MIN.
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 thedraw()
loop, but not theNumberbox.updateInternalEvents
method. If your FPS were veeery low, the numberbox could update several time between two loops of thedraw()
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 yourconstrainRangeInputs()
method.The problem is here:
The absolute number makes it possible that a
rangeMinInt
be higher than arangeMaxInt
if it's high enough. Here's an example of when it would happens: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 thedraw()
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
for this instead:
Hope it helps, that was trickier than it seems. Have fun!