如何避免鼠标焦点的字段故障
How to avoid field glitch with mouse focus
当我将鼠标指针拖出处理 window 时,我的程序以意想不到的方式做出反应。复现方式:
- 将鼠标指针悬停在“MIN”字段上并尝试更改字段中数字的值,同时按住鼠标左键。
- 以平均速度或急剧向左然后向右拖动鼠标指针,超出应用程序区域window而不松开鼠标左键。
- 现在不满足以下条件:
- 最小 < 最大
- 总是最小值 - 最大值为 500 个单位。
- 最大值 > 最小值
- MAX + 500 个单位从 MIN.
注意,只有当鼠标指针移出应用程序区域时才会观察到此效果window。是否有任何选项可以消除这种影响或如何避免这种影响?
如果您不将鼠标指针移到 window 尺寸区域,则一切正常!
代码:
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);
}
}
}
这个问题是由你写的东西和 Processing 的 draw()
循环受其 FPS 限制的方式混合引起的,在你的情况下可能是 60,因为你没有设置它。
constrainRangeInputs
方法被draw()
循环调用,而不是Numberbox.updateInternalEvents
方法。如果您的 FPS 非常低,数字框可能会在 draw()
方法的两次循环之间更新几次,即使我们看不到它,因为它没有在视觉上更新。
然后,当 draw()
循环执行它的任务时,它会调用您的 constrainRangeInputs()
方法。
问题在这里:
if (abs(rangeMaxInt - rangeMinInt) < RANGE_MIN_DIFFERENCE) {
如果足够高,绝对数使得 rangeMinInt
可能高于 rangeMaxInt
。这是何时发生的示例:
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!
这与离开 window 无关(如果您更改 window 的大小使其非常宽,您将能够重现该问题,我做到了它是实验性的)。问题是,当 constrainRangeInputs()
完成它的工作时,当前数字已经足够高以符合您的条件。
那是因为鼠标移动得足够快,在 draw()
循环的两次迭代之间的时间里覆盖了超过 RANGE_MIN_DIFFERENCE
。
您可以通过删除 abs()
轻松解决此问题。我不知道为什么它首先会相关,但是当你从现有代码中改编它时,它可能是原始代码的产物。
所以:更改此行
if (abs(rangeMaxInt - rangeMinInt) < RANGE_MIN_DIFFERENCE) {
为此:
if (rangeMaxInt - rangeMinInt < RANGE_MIN_DIFFERENCE) {
希望对您有所帮助,这比看起来要棘手。玩得开心!
当我将鼠标指针拖出处理 window 时,我的程序以意想不到的方式做出反应。复现方式:
- 将鼠标指针悬停在“MIN”字段上并尝试更改字段中数字的值,同时按住鼠标左键。
- 以平均速度或急剧向左然后向右拖动鼠标指针,超出应用程序区域window而不松开鼠标左键。
- 现在不满足以下条件:
- 最小 < 最大
- 总是最小值 - 最大值为 500 个单位。
- 最大值 > 最小值
- MAX + 500 个单位从 MIN.
注意,只有当鼠标指针移出应用程序区域时才会观察到此效果window。是否有任何选项可以消除这种影响或如何避免这种影响?
如果您不将鼠标指针移到 window 尺寸区域,则一切正常!
代码:
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);
}
}
}
这个问题是由你写的东西和 Processing 的 draw()
循环受其 FPS 限制的方式混合引起的,在你的情况下可能是 60,因为你没有设置它。
constrainRangeInputs
方法被draw()
循环调用,而不是Numberbox.updateInternalEvents
方法。如果您的 FPS 非常低,数字框可能会在 draw()
方法的两次循环之间更新几次,即使我们看不到它,因为它没有在视觉上更新。
然后,当 draw()
循环执行它的任务时,它会调用您的 constrainRangeInputs()
方法。
问题在这里:
if (abs(rangeMaxInt - rangeMinInt) < RANGE_MIN_DIFFERENCE) {
如果足够高,绝对数使得 rangeMinInt
可能高于 rangeMaxInt
。这是何时发生的示例:
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!
这与离开 window 无关(如果您更改 window 的大小使其非常宽,您将能够重现该问题,我做到了它是实验性的)。问题是,当 constrainRangeInputs()
完成它的工作时,当前数字已经足够高以符合您的条件。
那是因为鼠标移动得足够快,在 draw()
循环的两次迭代之间的时间里覆盖了超过 RANGE_MIN_DIFFERENCE
。
您可以通过删除 abs()
轻松解决此问题。我不知道为什么它首先会相关,但是当你从现有代码中改编它时,它可能是原始代码的产物。
所以:更改此行
if (abs(rangeMaxInt - rangeMinInt) < RANGE_MIN_DIFFERENCE) {
为此:
if (rangeMaxInt - rangeMinInt < RANGE_MIN_DIFFERENCE) {
希望对您有所帮助,这比看起来要棘手。玩得开心!