总的来说,这听起来像是您试图让用户输入一系列有效值(其中最小值总是小于最大值)。已经有一个 ControlP5 控制器:范围
除了允许在一个范围内设置最小值和最大值之外,还有保持最大值和最小值之间的差异至少为 500 的约束。
您可以将 Range 滑块的句柄设置为 0px 宽,基本上禁用它们,这意味着您在开始时设置的范围(通过setRangeValues
)将保持不变:
import controlP5.*;
ControlP5 cp5;
Range range;
int rangeMinValue;
int rangeMaxValue;
void setup() {
size(700, 400);
PFont font = createFont("arial", 18);
cp5 = new ControlP5(this);
range = cp5.addRange("yourRange")
// disable broadcasting since setRange and setRangeValues will trigger an event
.setBroadcast(false)
.setFont(font)
.setPosition(50,50)
// notice the dimensions are proportional to the min/max range to avoid floating point values
.setSize(500,40)
// set minimum - maximum range here
.setRange(4000,5000)
// example: set initial (recommended) range values
.setRangeValues(4000, 4500)
// workaround to disable left/right handles contraining the range to 500
.setHandleSize(0)
// after the initialization we turn broadcast back on again
.setBroadcast(true)
;
textFont(font);
}
void draw() {
background(0);
fill(255);
}
void controlEvent(ControlEvent event) {
if(event.isFrom("yourRange")) {
// min and max values are stored in an array.
// access this array with controller().arrayValue().
// min is at index 0, max is at index 1.
rangeMinValue = int(event.getController().getArrayValue(0));
rangeMaxValue = int(event.getController().getArrayValue(1));
println("range:",rangeMinValue,"->",rangeMaxValue);
}
}

一个限制是范围不能> 500。如果这是一个要求,您仍然可以手动限制值(通过设置范围 min(low)/max(high) 值):
import controlP5.*;
// range constants
final int RANGE_MIN = 4000;
final int RANGE_MAX = 5000;
// the smallest allowed difference between min/max values
final int RANGE_MIN_DIFFERENCE = 500;
final int RANGE_MID = RANGE_MIN + ((RANGE_MAX - RANGE_MIN) / 2);
ControlP5 cp5;
Range range;
int rangeMinValue;
int rangeMaxValue;
void setup() {
size(700, 400);
PFont font = createFont("arial", 18);
cp5 = new ControlP5(this);
range = cp5.addRange("yourCustomRange")
// disable broadcasting since setRange and setRangeValues will trigger an event
.setBroadcast(false)
.setFont(font)
.setPosition(50,50)
// notice the dimensions are proportional to the min/max range to avoid floating point values
.setSize(500,40)
// set minimum - maximum range here
.setRange(RANGE_MIN, RANGE_MAX)
// example: set initial (recommended) range values
.setRangeValues(RANGE_MIN, RANGE_MIN + RANGE_MIN_DIFFERENCE)
// after the initialization we turn broadcast back on again
.setBroadcast(true)
;
textFont(font);
}
void draw() {
background(0);
fill(255);
}
void controlEvent(ControlEvent event) {
if(event.isFrom("yourCustomRange")) {
// min and max values are stored in an array.
// access this array with controller().arrayValue().
// min is at index 0, max is at index 1.
int rangeMinInt = int(event.getController().getArrayValue(0));
int rangeMaxInt = int(event.getController().getArrayValue(1));
// if the values are within the desired range, update global values
if(rangeMaxInt - rangeMinInt >= RANGE_MIN_DIFFERENCE){
rangeMinValue = rangeMinInt;
rangeMaxValue = rangeMaxInt;
}else{
// otherwise check which side of the range should be constrained (right/max) or (left/min) to overwrite user input
if(rangeMaxInt > RANGE_MID){
range.setLowValue(rangeMaxInt - RANGE_MIN_DIFFERENCE);
}else{
range.setHighValue(rangeMinInt + RANGE_MIN_DIFFERENCE);
}
}
// values to use
println("range:",rangeMinValue,"->",rangeMaxValue);
}
}

如果这占用太多空间,您可以使用Numberbox,与文本字段相比,它有一些优点:
- 您无需担心字符串到整数的转换(它默认处理数字)
- 您可以设置最小/最大值
这是一个例子:
import controlP5.*;
ControlP5 cp5;
// range constants
final int RANGE_MIN = 4000;
final int RANGE_MAX = 5000;
// the smallest allowed difference between min/max values
final int RANGE_MIN_DIFFERENCE = 500;
final int RANGE_MID = RANGE_MIN + ((RANGE_MAX - RANGE_MIN) / 2);
int minValue;
int maxValue;
Numberbox inputMin;
Numberbox inputMax;
void setup() {
size(700, 400);
PFont font = createFont("arial", 18);
cp5 = new ControlP5(this);
inputMin = cp5.addNumberbox("minValue")
.setPosition(100,100)
.setSize(100,20)
.setFont(font)
.setScrollSensitivity(1.1)
// set initial acceptable range
.setMin(RANGE_MIN)
.setMax(RANGE_MAX)
// set default value
.setValue(4000)
;
inputMax = cp5.addNumberbox("maxValue")
.setPosition(100,150)
.setSize(100,20)
.setFont(font)
.setScrollSensitivity(1.1)
// set initial acceptable range
.setMin(RANGE_MIN)
.setMax(RANGE_MAX)
// set default value
.setValue(RANGE_MID + 1)
;
textFont(font);
}
void draw() {
constrainRangeInputs();
background(0);
fill(255);
text("minValue: " + minValue + "\n" +
"maxValue: " + maxValue, 10, 15);
}
void constrainRangeInputs(){
int rangeMinInt = (int)inputMin.getValue();
int rangeMaxInt = (int)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);
}
}
}

逻辑约束值到最小 500 的差异并不是 100% 严格,可能还有一些我没有考虑过的其他边缘情况。它更多的是说明解决问题的方法,因此您更有能力这样做。
我建议通过Processing > Examples > Contributed Libraries > ControlP5并运行示例,特别是controllers。您可以优先考虑那些听起来更接近您当前问题的选项,但值得体验这些选项,以便您可以选择最适合您的问题的控制器/UI 元素。
该示例可能不包括控制器具有的每种方法的使用,但是底部有一个注释列表,您可以轻松地立即复制/粘贴/运行。此外,您当然还有完整的文档