Vuo  2.1.2
VuoInputEditorReal.cc
Go to the documentation of this file.
1 
10 #include "VuoInputEditorReal.hh"
11 
12 extern "C" {
13 }
14 
19 {
20  return new VuoInputEditorReal();
21 }
22 
26 QLabel* makeLabel(const char* text)
27 {
28  QLabel* label = new QLabel(text);
29  label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
30  return label;
31 }
32 
36 VuoDoubleSpinBox* VuoInputEditorReal::initSpinBox(QDialog& dialog, double initialValue)
37 {
38  VuoDoubleSpinBox* spin = new VuoDoubleSpinBox(&dialog, 11);
39  const int decimalPrecision = DBL_MAX_10_EXP + DBL_DIG;
40  spin->setDecimals(decimalPrecision);
41  spin->setFixedWidth(100);
42  spin->setButtonMinimum(suggestedMin);
43  spin->setButtonMaximum(suggestedMax);
44  spin->setSingleStep(suggestedStep);
45  spin->setValue(initialValue);
46  return spin;
47 }
48 
52 QSlider* VuoInputEditorReal::initSlider(QDialog& dialog, double initialValue)
53 {
54  double min = suggestedMin;
55  double max = suggestedMax;
56  double step = suggestedStep;
57  double range = max - min;
58 
59  QSlider* slider = new QSlider(&dialog);
60  slider->setOrientation(Qt::Horizontal);
61  slider->setFocusPolicy(Qt::NoFocus);
62  slider->setMinimum(0);
63  slider->setMaximum(slider->width());
64  slider->setSingleStep( fmax(1, step * (slider->maximum() - slider->minimum()) / range ) );
65  slider->setValue( VuoDoubleSpinBox::doubleToSlider(slider->minimum(), slider->maximum(), min, max, initialValue) );
66  return slider;
67 }
68 
73 void VuoInputEditorReal::setUpDialog(QDialog &dialog, json_object *originalValue, json_object *details)
74 {
75  current = VuoReal_makeFromJson(originalValue);
76 
77  suggestedMin = -DBL_MAX;
78  suggestedMax = DBL_MAX;
79  suggestedStep = 1.0;
80  previous = current;
81  defaultValue = 0;
82  automatic = -INFINITY;
83 
84  bool hasMinMax = true, hasAutoValue = false;
85 
86  // Parse supported port annotations from the port's "details" JSON object:
87  if (details)
88  {
89  // "default"
90  json_object *suggestedDefaultValue = NULL;
91  if (json_object_object_get_ex(details, "default", &suggestedDefaultValue))
92  defaultValue = VuoReal_makeFromJson(suggestedDefaultValue);
93 
94  // "suggestedMin"
95  json_object *suggestedMinValue = NULL;
96  if (json_object_object_get_ex(details, "suggestedMin", &suggestedMinValue))
97  suggestedMin = VuoReal_makeFromJson(suggestedMinValue);
98  else
99  hasMinMax = false;
100 
101  // "suggestedMax"
102  json_object *suggestedMaxValue = NULL;
103  if (json_object_object_get_ex(details, "suggestedMax", &suggestedMaxValue))
104  suggestedMax = VuoReal_makeFromJson(suggestedMaxValue);
105  else
106  hasMinMax = false;
107 
108  // "suggestedStep"
109  if (hasMinMax)
110  suggestedStep = (suggestedMax - suggestedMin)/10.;
111  json_object *suggestedStepValue = NULL;
112  if (json_object_object_get_ex(details, "suggestedStep", &suggestedStepValue))
113  suggestedStep = VuoReal_makeFromJson(suggestedStepValue);
114 
115  json_object *autoValue = NULL;
116  if(json_object_object_get_ex(details, "auto", &autoValue))
117  {
118  hasAutoValue = true;
119  automatic = VuoReal_makeFromJson(autoValue);
120  }
121 
122  json_object *autoSupersedesValue = NULL;
123  if(json_object_object_get_ex(details, "autoSupersedesDefault", &autoSupersedesValue))
124  autoSupersedesDefault = VuoBoolean_makeFromJson(autoSupersedesValue);
125  }
126 
127  spinbox = initSpinBox(dialog, current);
128  connect(spinbox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &VuoInputEditorReal::onSpinboxUpdate);
129 
130  if(hasMinMax)
131  {
132  slider = initSlider(dialog, current);
133  connect(slider, &QSlider::valueChanged, this, &VuoInputEditorReal::onSliderUpdate);
134  }
135 
136  // layout dialog
137  QGridLayout* layout = new QGridLayout;
138  dialog.setLayout(layout);
139 
140  // left, top, right, bottom
141  layout->setContentsMargins(4, 4, 12, 4);
142  layout->setSpacing(4);
143  if(hasAutoValue) layout->setHorizontalSpacing(8);
144 
145  int row = 0;
146 
147  if(hasAutoValue)
148  {
149  checkbox = new QCheckBox("Auto");
150  connect(checkbox, &QCheckBox::stateChanged, this, &VuoInputEditorReal::setIsAuto);
151  bool currentIsAuto = VuoReal_areEqual(current, automatic);
152  checkbox->setChecked(currentIsAuto);
153  if (currentIsAuto)
154  previous = defaultValue;
155 
156  layout->addWidget(checkbox, row++, 0);
157  checkbox->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
158  }
159 
160  layout->addWidget(spinbox, row++, 0);
161 
162  if(hasMinMax)
163  {
164  // stick the slider in a horizontal layout so that we can apply a separate margin.
165  // necessary because QSlider aligns itself with about 4px left padding and 0px right
166  QHBoxLayout* sliderLayout = new QHBoxLayout();
167  sliderLayout->setContentsMargins(-2, 0, 2, 0);
168  sliderLayout->addWidget(slider);
169  layout->addLayout(sliderLayout, row++, 0);
170  }
171 
172  dialog.setMaximumWidth(1);
173  dialog.setMaximumHeight(1);
174  dialog.adjustSize();
175 
178 
179  spinbox->setFocus();
180 }
181 
185 void VuoInputEditorReal::setIsAuto(int state)
186 {
187  if(state == Qt::Unchecked)
188  {
189  spinbox->setSpecialValueText("");
190  spinbox->setMinimum(suggestedMin);
191  spinbox->setMaximum(suggestedMax);
192 
193  if(previous != automatic)
194  current = previous;
195  else
196  current = (suggestedMax + suggestedMin) * .5;
197  }
198  else
199  {
200  previous = current;
201  current = automatic;
202 
203  spinbox->setSpecialValueText("Auto");
204  spinbox->setMinimum(automatic);
205  spinbox->setMaximum(automatic);
206  }
207 
208  spinbox->setValue(current);
209  spinbox->setEnabled(!checkbox->isChecked());
210  if(slider) slider->setEnabled(!checkbox->isChecked());
211 }
212 
216 void VuoInputEditorReal::onSliderUpdate(int sliderValue)
217 {
218  current = VuoDoubleSpinBox::sliderToDouble( slider->minimum(),
219  slider->maximum(),
220  suggestedMin,
221  suggestedMax,
222  sliderValue);
223 
224  // disconnect before setting spinbox value otherwise onSpinboxUpdate is called and the whole thing just cycles
225  disconnect(spinbox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &VuoInputEditorReal::onSpinboxUpdate);
226  spinbox->setValue( current );
227  connect(spinbox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &VuoInputEditorReal::onSpinboxUpdate);
228 
229  spinbox->setFocus();
230  spinbox->selectAll();
231 
232  emit valueChanged( getAcceptedValue() );
233 }
234 
238 void VuoInputEditorReal::onSpinboxUpdate(double spinboxValue)
239 {
240  current = spinboxValue;
241 
242  if(slider != NULL)
243  {
244  int sliderValue = VuoDoubleSpinBox::doubleToSlider(
245  slider->minimum(),
246  slider->maximum(),
247  suggestedMin,
248  suggestedMax,
249  current);
250 
251  disconnect(slider, &QSlider::valueChanged, this, &VuoInputEditorReal::onSliderUpdate);
252  slider->setValue( sliderValue );
253  connect(slider, &QSlider::valueChanged, this, &VuoInputEditorReal::onSliderUpdate);
254  }
255 
256  emit valueChanged( getAcceptedValue() );
257 }
258 
263 {
264  return VuoReal_getJson(current);
265 }