Vuo  2.3.1
VuoInputEditorWithDialog.cc
Go to the documentation of this file.
1 
12 
17  : VuoInputEditor()
18 {
19  dialogPointer = NULL;
20  firstWidgetInTabOrder = NULL;
21  lastWidgetInTabOrder = NULL;
22 }
23 
27 json_object * VuoInputEditorWithDialog::show(QPoint portLeftCenter, json_object *originalValue, json_object *details, map<QString, json_object *> portNamesAndValues)
28 {
29  json_object *o = NULL;
30 
31  isDark = false;
32  if (json_object_object_get_ex(details, "isDark", &o))
33  isDark = json_object_get_boolean(o);
34 
35  bool showArrow = true;
36  if (json_object_object_get_ex(details, "showArrow", &o))
37  showArrow = json_object_get_boolean(o);
38 
39  VuoDialogForInputEditor dialog(isDark, showArrow);
40  dialogPointer = &dialog;
41  setUpDialog(dialog, originalValue, details);
42 
43  // Workaround for the window background being opaque black on macOS 10.12 and prior.
44  // https://b33p.net/kosada/vuo/vuo/-/merge_requests/5#note_2117211
45  dialog.setFixedSize(dialog.layout() ? dialog.layout()->sizeHint() : dialog.sizeHint());
46 
47  // Move children to account for margins if no autolayout is used.
48  QMargins margin = dialog.getPopoverContentsMargins();
49 
50  if( dialog.layout() == 0 )
51  {
52  QPoint topLeftMargin = QPoint(margin.left(),margin.top());
53  foreach (QObject *widget, dialog.children())
54  static_cast<QWidget *>(widget)->move(static_cast<QWidget *>(widget)->pos() + topLeftMargin);
55  }
56 
57  // Resize dialog to enclose child widgets and margins.
58  dialog.adjustSize();
59 
60  // Position the right center of the dialog at the left center of the port, or wherever required
61  // so that the entire dialog fits within the available screenspace.
62  int availableSpaceLeftBoundary = QApplication::desktop()->availableGeometry(&dialog).left();
63  QPoint dialogTopLeft = portLeftCenter - QPoint(dialog.width() - (showArrow ? 0 : margin.right()), dialog.height()/2.);
64  bool screenSpaceLimitsPos = (availableSpaceLeftBoundary > dialogTopLeft.x());
65  if (screenSpaceLimitsPos)
66  {
67  dialogTopLeft = (screenSpaceLimitsPos? QPoint(availableSpaceLeftBoundary, dialogTopLeft.y()) :
68  dialogTopLeft);
69  showArrow = false;
70  }
71  dialog.setShowArrow(showArrow);
72  dialog.move(dialogTopLeft);
73 
74 
75  dialog.show(); // Needed to position the dialog. (https://bugreports.qt-project.org/browse/QTBUG-31406)
76  dialog.exec();
77 
78  dialogPointer = NULL;
79 
80  return (dialog.result() == QDialog::Accepted ? getAcceptedValue() : originalValue);
81 }
82 
87 {
88  return dialogPointer;
89 }
90 
97 {
98  if (firstWidgetInTabOrder)
99  firstWidgetInTabOrder->removeEventFilter(this);
100 
101  if (widget)
102  widget->installEventFilter(this);
103 
104  firstWidgetInTabOrder = widget;
105 }
106 
113 {
114  if (lastWidgetInTabOrder)
115  lastWidgetInTabOrder->removeEventFilter(this);
116 
117  if (widget)
118  widget->installEventFilter(this);
119 
120  lastWidgetInTabOrder = widget;
121 }
122 
126 bool VuoInputEditorWithDialog::eventFilter(QObject *object, QEvent *event)
127 {
128  // If the input editor's final tab cycle element has received a 'Tab' keypress,
129  // or its first tab cycle element has received a 'Shift'+'Tab' keypress,
130  // emit the appropriate signal and then treat the 'Tab' as an 'Return' to accept and
131  // close the input editor.
132  if (event->type() == QEvent::KeyPress)
133  {
134  QKeyEvent *keyEvent = (QKeyEvent *)(event);
135  bool tabPressed = (keyEvent->key() == Qt::Key_Tab);
136  bool shiftTabPressed = (keyEvent->key() == Qt::Key_Backtab);
137 
138  bool aboutToCompleteReverseTabCycle = ((object == firstWidgetInTabOrder) && shiftTabPressed);
139  bool aboutToCompleteTabCycle = ((object == lastWidgetInTabOrder) && tabPressed);
140 
141  if (aboutToCompleteReverseTabCycle || aboutToCompleteTabCycle)
142  {
143  QKeyEvent modifiedKeyEvent(event->type(), Qt::Key_Return, 0);
144  QApplication::sendEvent(object, &modifiedKeyEvent);
145 
146  if (aboutToCompleteReverseTabCycle)
147  {
150  }
151 
152  else // if (aboutToCompleteTabCycle)
153  {
155  emit tabbedPastLastWidget();
156  }
157 
158  return true;
159  }
160  }
161 
162  return VuoInputEditor::eventFilter(object, event);
163 }