Vuo  2.1.2
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 
25 void 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 
38 bool 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 
72 void 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 
169 void 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 
197 void 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 
227 void 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 
244 void 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 
276 bool 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