Vuo  2.4.0
VuoInputEditorIntegerRange.cc
Go to the documentation of this file.
1
10
12#define IS_FINITE(value) (::abs(value) != INT_MAX)
13
18{
19 return new VuoInputEditorIntegerRange();
20}
21
25void VuoInputEditorIntegerRange::setupSpinBox(VuoSpinBox* spin, int min, int max, int step, int value)
26{
27// spin->setButtonMinimum(min);
28// spin->setButtonMaximum(max);
29 spin->setMinimum( -INT_MAX );
30 spin->setMaximum( INT_MAX );
31 spin->setSingleStep(step);
32 spin->setValue(value);
33}
34
38bool getDetails(json_object* details, VuoIntegerRange* suggestedMin, VuoIntegerRange* suggestedMax, VuoIntegerRange* suggestedStep)
39{
40 bool hasMin = false, hasMax = false;
41
42 if (details != NULL)
43 {
44 // "suggestedMin"
45 json_object *suggestedMinValue = NULL;
46 if (json_object_object_get_ex(details, "suggestedMin", &suggestedMinValue))
47 {
48 *suggestedMin = VuoIntegerRange_makeFromJson(suggestedMinValue);
49 hasMin = true;
50 }
51
52 // "suggestedMax"
53 json_object *suggestedMaxValue = NULL;
54 if (json_object_object_get_ex(details, "suggestedMax", &suggestedMaxValue))
55 {
56 *suggestedMax = VuoIntegerRange_makeFromJson(suggestedMaxValue);
57 hasMax = true;
58 }
59
60 // "suggestedStep"
61 json_object *suggestedStepValue = NULL;
62 if (json_object_object_get_ex(details, "suggestedStep", &suggestedStepValue))
63 *suggestedStep = VuoIntegerRange_makeFromJson(suggestedStepValue);
64 }
65
66 return hasMin && hasMax;
67}
68
72void VuoInputEditorIntegerRange::setUpDialog(QDialog &dialog, json_object *originalValue, json_object *details)
73{
74 suggestedMin = VuoIntegerRange_make( -INT_MAX, -INT_MAX );
75 suggestedMax = VuoIntegerRange_make( INT_MAX, INT_MAX );
76 suggestedStep = VuoIntegerRange_make(1, 1);
77
78 // get suggestedMin/Max/Step if provided, otherwise use the defaults
79 bool hasMinMax = getDetails(details, &suggestedMin, &suggestedMax, &suggestedStep);
80
81 bool tabCycleForward = true;
82
83 if(details)
84 {
85 json_object *forwardTabTraversal = NULL;
86 if (json_object_object_get_ex(details, "forwardTabTraversal", &forwardTabTraversal))
87 tabCycleForward = json_object_get_boolean(forwardTabTraversal);
88 }
89
90 QGridLayout* layout = new QGridLayout;
91
92 // left, top, right, bottom
93 // when showing sliders, add a little extra margin on the bottom since QSlider takes up the
94 // entire vertical spacing
95 layout->setContentsMargins(4, 6, 12, hasMinMax ? 6 : 4);
96 layout->setSpacing(8);
97
98 currentValue = VuoIntegerRange_makeFromJson(originalValue);
99 // Covnert from int64 to int32.
100 if (currentValue.minimum == VuoIntegerRange_NoMinimum)
101 currentValue.minimum = -INT_MAX;
102 if (currentValue.maximum == VuoIntegerRange_NoMaximum)
103 currentValue.maximum = INT_MAX;
104
105 lastValue.minimum = IS_FINITE(currentValue.minimum) ? currentValue.minimum : ( IS_FINITE(suggestedMin.minimum) ? suggestedMin.minimum : 0 );
106 lastValue.maximum = IS_FINITE(currentValue.maximum) ? currentValue.maximum : ( IS_FINITE(suggestedMin.maximum) ? suggestedMin.maximum : 10 );
107
108 // minimum checkbox & spinbox
109 {
110 checkbox_minimum = new QCheckBox("Minimum");
111 checkbox_minimum->setChecked( IS_FINITE(currentValue.minimum) );
112 checkbox_minimum->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
113 connect(checkbox_minimum, &QCheckBox::stateChanged, this, &VuoInputEditorIntegerRange::setMinBound);
114
115 layout->addWidget(checkbox_minimum, 0, 0 );
116
117 spinbox_minimum = new VuoSpinBox(&dialog);
118 setupSpinBox(spinbox_minimum, suggestedMin.minimum, MIN(suggestedMax.minimum, currentValue.maximum), suggestedStep.minimum, currentValue.minimum);
119 spinbox_minimum->installEventFilter(this);
120 connect(spinbox_minimum, static_cast<void (QSpinBox::*)(const QString &)>(&QSpinBox::valueChanged), this, &VuoInputEditorIntegerRange::setMinimum);
121
122 spinbox_minimum->setEnabled( checkbox_minimum->isChecked() );
123
124 layout->addWidget( spinbox_minimum, 0, 1 );
125 }
126
127 // maximum checkbox & spinbox
128 {
129 checkbox_maximum = new QCheckBox("Maximum");
130 checkbox_maximum->setChecked( IS_FINITE(currentValue.maximum) );
131 checkbox_maximum->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
132 connect(checkbox_maximum, &QCheckBox::stateChanged, this, &VuoInputEditorIntegerRange::setMaxBound);
133
134 layout->addWidget(checkbox_maximum, 1, 0 );
135
136 spinbox_maximum = new VuoSpinBox(&dialog);
137 setupSpinBox(spinbox_maximum, MAX(suggestedMin.maximum, currentValue.minimum), suggestedMax.maximum, suggestedStep.maximum, currentValue.maximum);
138 spinbox_maximum->installEventFilter(this);
139 connect(spinbox_maximum, static_cast<void (QSpinBox::*)(const QString &)>(&QSpinBox::valueChanged), this, &VuoInputEditorIntegerRange::setMaximum);
140
141 spinbox_maximum->setEnabled( checkbox_maximum->isChecked() );
142
143 layout->addWidget( spinbox_maximum, 1, 1 );
144 }
145
146 setMinBound(checkbox_minimum->isChecked() ? Qt::Checked : Qt::Unchecked);
147 setMaxBound(checkbox_maximum->isChecked() ? Qt::Checked : Qt::Unchecked);
148
149 dialog.setLayout(layout);
150
151 // line edit inputs should be 90px wide
152 dialog.setMaximumWidth(178);
153 dialog.setMaximumHeight(32);
154
155 dialog.adjustSize();
156
157 setFirstWidgetInTabOrder(spinbox_minimum);
158 setLastWidgetInTabOrder(spinbox_maximum);
159
160 (tabCycleForward ? spinbox_minimum : spinbox_maximum)->setFocus();
161 (tabCycleForward ? spinbox_minimum : spinbox_maximum)->selectAll();
162
163 return;
164}
165
169void VuoInputEditorIntegerRange::setMinBound(int state)
170{
171 if(state == Qt::Unchecked)
172 {
173 lastValue.minimum = currentValue.minimum;
174 spinbox_minimum->setValue( -INT_MAX );
175 spinbox_minimum->setSpecialValueText("-∞");
176 spinbox_minimum->setEnabled(false);
177 }
178 else
179 {
180 if( !IS_FINITE( currentValue.minimum ) )
181 {
182 if (!IS_FINITE(lastValue.minimum))
183 lastValue.minimum = 0;
184 lastValue.minimum = MIN(lastValue.minimum, currentValue.maximum);
185 spinbox_minimum->setValue( lastValue.minimum );
186 }
187 spinbox_minimum->setSpecialValueText("");
188 spinbox_minimum->setEnabled(true);
189 }
190
191// spinbox_maximum->setButtonMinimum( MAX(suggestedMin.maximum, currentValue.minimum) );
192}
193
197void VuoInputEditorIntegerRange::setMaxBound(int state)
198{
199 if(state == Qt::Unchecked)
200 {
201 lastValue.maximum = currentValue.maximum;
202 spinbox_maximum->setMinimum(INT_MAX);
203 spinbox_maximum->setValue( INT_MAX );
204 spinbox_maximum->setSpecialValueText("∞");
205 spinbox_maximum->setEnabled(false);
206 }
207 else
208 {
209 if( !IS_FINITE( currentValue.maximum ) )
210 {
211 if (!IS_FINITE(lastValue.maximum))
212 lastValue.maximum = 10;
213 lastValue.maximum = MAX(lastValue.maximum, currentValue.minimum);
214 spinbox_maximum->setMinimum(suggestedMin.maximum);
215 spinbox_maximum->setValue( lastValue.maximum );
216 }
217 spinbox_maximum->setSpecialValueText("");
218 spinbox_maximum->setEnabled(true);
219 }
220
221// spinbox_minimum->setButtonMaximum( MIN(suggestedMax.minimum, currentValue.maximum) );
222}
223
227void VuoInputEditorIntegerRange::setMinimum(QString newLineEditText)
228{
229 bool ok;
230 double newLineEditValue = QLocale().toDouble(newLineEditText, &ok);
231 if (ok)
232 {
233 currentValue.minimum = newLineEditValue;
234// currentValue.minimum = MIN(newLineEditValue, currentValue.maximum);
235// spinbox_maximum->setButtonMinimum( MAX(suggestedMin.maximum, currentValue.minimum) );
236 }
237
239}
240
244void VuoInputEditorIntegerRange::setMaximum(QString newLineEditText)
245{
246 bool ok;
247 double newLineEditValue = QLocale().toDouble(newLineEditText, &ok);
248 if (ok)
249 {
250 currentValue.maximum = newLineEditValue;
251// currentValue.maximum = MAX(newLineEditValue, currentValue.minimum);
252// spinbox_minimum->setButtonMaximum( MIN(suggestedMax.minimum, currentValue.maximum) );
253 }
254
256}
257
262{
263 // Covnert from int32 to int64.
264 VuoIntegerRange r = currentValue;
265 if (!IS_FINITE(r.minimum))
266 r.minimum = VuoIntegerRange_NoMinimum;
267 if (!IS_FINITE(r.maximum))
268 r.maximum = VuoIntegerRange_NoMaximum;
269
270 return VuoIntegerRange_getJson(r);
271}
272
276bool VuoInputEditorIntegerRange::eventFilter(QObject *object, QEvent *event)
277{
278 VuoSpinBox* spin = dynamic_cast<VuoSpinBox*>(object);
279
280 if (event->type() == QEvent::KeyPress && spin)
281 {
282 // Let the slider handle keypresses of the up and down arrows.
283 QKeyEvent *keyEvent = (QKeyEvent *)(event);
284
285 if (keyEvent->key() == Qt::Key_Up)
286 {
287 if(spin == spinbox_minimum)
288 spin->setValue( MIN(spin->value() + spin->singleStep(), MIN(suggestedMax.minimum, currentValue.maximum)) );
289 else if(spin == spinbox_maximum)
290 spin->setValue( MIN(spin->value() + spin->singleStep(), suggestedMax.minimum) );
291
292 return true;
293 }
294 else if (keyEvent->key() == Qt::Key_Down)
295 {
296 if(spin == spinbox_minimum)
297 spin->setValue( MAX(spin->value() - spin->singleStep(), suggestedMin.minimum) );
298 else if(spin == spinbox_maximum)
299 spin->setValue( MAX(spin->value() - spin->singleStep(), MAX(suggestedMin.maximum, currentValue.minimum)) );
300
301 return true;
302 }
303 }
304
305 return VuoInputEditorWithDialog::eventFilter(object, event);
306}
307