Vuo  2.0.2
VuoDetailsEditorNumeric.cc
Go to the documentation of this file.
1 
12 #include "VuoReal.h"
13 #include "VuoRendererFonts.hh"
14 #include "VuoType.hh"
15 
21  QWidget(parent)
22 {
23  this->type = type;
24 }
25 
29 json_object * VuoDetailsEditorNumeric::show(QPoint portLeftCenter, json_object *originalDetails)
30 {
31  json_object *o = NULL;
32 
33  bool isDark = false;
34  if (json_object_object_get_ex(originalDetails, "isDark", &o))
35  isDark = json_object_get_boolean(o);
36 
37  VuoDialogForInputEditor dialog(isDark, false);
38  dialog.setFont(getDefaultFont());
39  setUpDialog(dialog, originalDetails);
40 
41  // Move children to account for margins.
42  QMargins margin = dialog.getPopoverContentsMargins();
43  QPoint topLeftMargin = QPoint(margin.left(),margin.top());
44  foreach (QObject *widget, dialog.children())
45  static_cast<QWidget *>(widget)->move(static_cast<QWidget *>(widget)->pos() + topLeftMargin);
46 
47  // Resize dialog to enclose child widgets and margins.
48  dialog.resize(margin.left() + dialog.childrenRect().width() + margin.right(), margin.top() + dialog.childrenRect().height() + margin.bottom());
49 
50  // Position the right center of the dialog at the left center of the port.
51  QPoint dialogTopLeft = portLeftCenter - QPoint(dialog.width() - margin.right(), dialog.height()/2.);
52  dialog.move(dialogTopLeft);
53 
54  dialog.show(); // Needed to position the dialog. (https://bugreports.qt-project.org/browse/QTBUG-31406)
55  dialog.exec();
56 
57  return (dialog.result() == QDialog::Accepted ? getAcceptedValue() : originalDetails);
58 }
59 
63 void VuoDetailsEditorNumeric::setUpDialog(QDialog &dialog, json_object *originalDetails)
64 {
65  // See https://b33p.net/kosada/node/5724
66  const int decimalPrecision = 6;
67 
68  QValidator *validator = ((this->type->getModuleKey() == "VuoReal")?
69  static_cast<QValidator *>(new QDoubleValidator(NULL)) :
70  static_cast<QValidator *>(new QIntValidator(NULL)));
71 
72  json_object *suggestedMinValue = NULL;
73  json_object *suggestedMaxValue = NULL;
74  json_object *suggestedStepValue = NULL;
75 
76  // Parse supported port annotations from the port's "details" JSON object:
77  if (originalDetails)
78  {
79  // "suggestedMin"
80  json_object_object_get_ex(originalDetails, "suggestedMin", &suggestedMinValue);
81 
82  // "suggestedMax"
83  json_object_object_get_ex(originalDetails, "suggestedMax", &suggestedMaxValue);
84 
85  // "suggestedStep"
86  json_object_object_get_ex(originalDetails, "suggestedStep", &suggestedStepValue);
87  }
88 
89  // Layout details
90  const int widgetVerticalSpacing = 10;
91  const int widgetHorizontalSpacing = 8;
92 
93  labelForDetail[suggestedMin] = new QLabel(&dialog);
94  labelForDetail[suggestedMin]->setText(tr("Suggested Min"));
95  labelForDetail[suggestedMin]->adjustSize();
96 
97  labelForDetail[suggestedMax] = new QLabel(&dialog);
98  labelForDetail[suggestedMax]->setText(tr("Suggested Max"));
99  labelForDetail[suggestedMax]->adjustSize();
100 
101  labelForDetail[suggestedStep] = new QLabel(&dialog);
102  labelForDetail[suggestedStep]->setText(tr("Suggested Step"));
103  labelForDetail[suggestedStep]->adjustSize();
104 
105  if (dynamic_cast<QDoubleValidator *>(validator))
106  static_cast<QDoubleValidator *>(validator)->setDecimals(decimalPrecision);
107 
108  // suggestedMin value
109  lineEditForDetail[suggestedMin] = new QLineEdit(&dialog);
110  setUpLineEdit(lineEditForDetail[suggestedMin], suggestedMinValue);
111  lineEditForDetail[suggestedMin]->setValidator(validator);
112 
113  // suggestedMax value
114  lineEditForDetail[suggestedMax] = new QLineEdit(&dialog);
115  setUpLineEdit(lineEditForDetail[suggestedMax], suggestedMaxValue);
116  lineEditForDetail[suggestedMax]->setValidator(validator);
117 
118  // suggestedStep value
119  lineEditForDetail[suggestedStep] = new QLineEdit(&dialog);
120  setUpLineEdit(lineEditForDetail[suggestedStep], suggestedStepValue);
121  lineEditForDetail[suggestedStep]->setValidator(validator);
122 
123  lineEditForDetail[suggestedMin]->move(labelForDetail[suggestedMin]->pos().x()+labelForDetail[suggestedMin]->width()+2*widgetHorizontalSpacing, lineEditForDetail[suggestedMin]->pos().y());
124  labelForDetail[suggestedMin]->show();
125 
126  labelForDetail[suggestedMax]->move(0, labelForDetail[suggestedMin]->pos().y() + labelForDetail[suggestedMin]->height() + widgetVerticalSpacing);
127  lineEditForDetail[suggestedMax]->move(labelForDetail[suggestedMin]->pos().x()+labelForDetail[suggestedMin]->width()+2*widgetHorizontalSpacing, labelForDetail[suggestedMin]->pos().y() + labelForDetail[suggestedMin]->height() + widgetVerticalSpacing);
128  labelForDetail[suggestedMax]->show();
129 
130  labelForDetail[suggestedStep]->move(0, labelForDetail[suggestedMax]->pos().y() + labelForDetail[suggestedMax]->height() + widgetVerticalSpacing);
131  lineEditForDetail[suggestedStep]->move(labelForDetail[suggestedMin]->pos().x()+labelForDetail[suggestedMin]->width()+2*widgetHorizontalSpacing, labelForDetail[suggestedMax]->pos().y() + labelForDetail[suggestedMax]->height() + widgetVerticalSpacing);
132  labelForDetail[suggestedStep]->show();
133 
134  dialog.adjustSize();
135 
136  // Return focus to the topmost line edit.
137  lineEditForDetail[suggestedMin]->setFocus();
138  lineEditForDetail[suggestedMin]->selectAll();
139 }
140 
147 void VuoDetailsEditorNumeric::setUpLineEdit(QLineEdit *lineEdit, json_object *originalValue)
148 {
149  lineEdit->setText( convertToLineEditFormat(originalValue) );
150  lineEdit->setFocus();
151  lineEdit->selectAll();
152 
153  lineEdit->adjustSize();
154 }
155 
160 {
161  return convertFromLineEditsFormat(lineEditForDetail[suggestedMin]->text(),
162  lineEditForDetail[suggestedMax]->text(),
163  lineEditForDetail[suggestedStep]->text());
164 }
165 
170 {
171  if (!value)
172  return "";
173 
174  QString valueAsStringInDefaultLocale = json_object_to_json_string_ext(value, JSON_C_TO_STRING_PLAIN);
175  double realValue = ((this->type->getModuleKey() == "VuoReal")?
176  QLocale(QLocale::C).toDouble(valueAsStringInDefaultLocale) :
177  QLocale(QLocale::C).toInt(valueAsStringInDefaultLocale));
178  QString valueAsStringInUserLocale = QLocale::system().toString(realValue);
179 
180  if (qAbs(realValue) >= 1000.0)
181  valueAsStringInUserLocale.remove(QLocale::system().groupSeparator());
182 
183  return valueAsStringInUserLocale;
184 }
185 
189 json_object * VuoDetailsEditorNumeric::convertFromLineEditsFormat(const QString &suggestedMinValueAsString,
190  const QString &suggestedMaxValueAsString,
191  const QString &suggestedStepValueAsString)
192 {
193  // suggestedMin value
194  double suggestedMinValue = ((this->type->getModuleKey() == "VuoReal")?
195  QLocale::system().toDouble(suggestedMinValueAsString) :
196  QLocale::system().toInt(suggestedMinValueAsString));
197  QString suggestedMinValueAsStringInDefaultLocale = QLocale(QLocale::C).toString(suggestedMinValue);
198 
199  if (qAbs(suggestedMinValue) >= 1000.0)
200  suggestedMinValueAsStringInDefaultLocale.remove(QLocale(QLocale::C).groupSeparator());
201 
202  if (! suggestedMinValueAsStringInDefaultLocale.isEmpty() && suggestedMinValueAsStringInDefaultLocale[0] == '.')
203  suggestedMinValueAsStringInDefaultLocale = "0" + suggestedMinValueAsStringInDefaultLocale;
204 
205  // suggestedMax value
206  double suggestedMaxValue = ((this->type->getModuleKey() == "VuoReal")?
207  QLocale::system().toDouble(suggestedMaxValueAsString) :
208  QLocale::system().toInt(suggestedMaxValueAsString));
209  QString suggestedMaxValueAsStringInDefaultLocale = QLocale(QLocale::C).toString(suggestedMaxValue);
210 
211  if (qAbs(suggestedMaxValue) >= 1000.0)
212  suggestedMaxValueAsStringInDefaultLocale.remove(QLocale(QLocale::C).groupSeparator());
213 
214  if (! suggestedMaxValueAsStringInDefaultLocale.isEmpty() && suggestedMaxValueAsStringInDefaultLocale[0] == '.')
215  suggestedMaxValueAsStringInDefaultLocale = "0" + suggestedMaxValueAsStringInDefaultLocale;
216 
217  // suggestedStep value
218  double suggestedStepValue = ((this->type->getModuleKey() == "VuoReal")?
219  QLocale::system().toDouble(suggestedStepValueAsString) :
220  QLocale::system().toInt(suggestedStepValueAsString));
221  QString suggestedStepValueAsStringInDefaultLocale = QLocale(QLocale::C).toString(suggestedStepValue);
222 
223  if (qAbs(suggestedStepValue) >= 1000.0)
224  suggestedStepValueAsStringInDefaultLocale.remove(QLocale(QLocale::C).groupSeparator());
225 
226  if (! suggestedStepValueAsStringInDefaultLocale.isEmpty() && suggestedStepValueAsStringInDefaultLocale[0] == '.')
227  suggestedStepValueAsStringInDefaultLocale = "0" + suggestedStepValueAsStringInDefaultLocale;
228 
229  // details
230  struct json_object *details = json_object_new_object();
231 
232  if (this->type->getModuleKey() == "VuoReal")
233  {
234  if (!suggestedMinValueAsString.isEmpty())
235  json_object_object_add(details, "suggestedMin", VuoReal_getJson(VuoReal_makeFromString(suggestedMinValueAsStringInDefaultLocale.toUtf8().constData())));
236 
237  if (!suggestedMaxValueAsString.isEmpty())
238  json_object_object_add(details, "suggestedMax", VuoReal_getJson(VuoReal_makeFromString(suggestedMaxValueAsStringInDefaultLocale.toUtf8().constData())));
239 
240  if (!suggestedStepValueAsString.isEmpty())
241  json_object_object_add(details, "suggestedStep", VuoReal_getJson(VuoReal_makeFromString(suggestedStepValueAsStringInDefaultLocale.toUtf8().constData())));
242  }
243  else
244  {
245  if (!suggestedMinValueAsString.isEmpty())
246  json_object_object_add(details, "suggestedMin", VuoInteger_getJson(VuoInteger_makeFromString(suggestedMinValueAsStringInDefaultLocale.toUtf8().constData())));
247 
248  if (!suggestedMaxValueAsString.isEmpty())
249  json_object_object_add(details, "suggestedMax", VuoInteger_getJson(VuoInteger_makeFromString(suggestedMaxValueAsStringInDefaultLocale.toUtf8().constData())));
250 
251  if (!suggestedStepValueAsString.isEmpty())
252  json_object_object_add(details, "suggestedStep", VuoInteger_getJson(VuoInteger_makeFromString(suggestedStepValueAsStringInDefaultLocale.toUtf8().constData())));
253  }
254 
255  return details;
256 }
257 
261 QFont VuoDetailsEditorNumeric::getDefaultFont(void)
262 {
264  return fonts->dialogBodyFont();
265 }