Vuo  2.0.3
VuoErrorPopover.cc
Go to the documentation of this file.
1 
10 #include "VuoErrorPopover.hh"
11 
12 #include "VuoCompilerIssue.hh"
13 #include "VuoRendererFonts.hh"
14 #include "VuoEditor.hh"
15 
20  : VuoPopover(parent)
21 {
22  QString summary = QString::fromStdString(issue.getSummary());
23  QString details = QString::fromStdString(issue.getDetails(true));
24  helpPath = QString::fromStdString(issue.getHelpPath());
25 
26  QString text = QString("<h3>%1</h3><p>%2</p>").arg(summary).arg(details);
27  textLabel = new QLabel(text, this);
28 
29  textLabel->installEventFilter(this);
30  textLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard); // not Qt::TextBrowserInteraction since it makes text selectable
31  textLabel->setOpenExternalLinks(true);
32 
33  layout = new QVBoxLayout(this);
34  layout->addWidget(textLabel, 0, Qt::AlignTop);
35 
36  if (!issue.getHelpPath().empty())
37  {
38  QToolButton *helpButton = new QToolButton(textLabel);
39  helpButton->setIcon(QIcon(":/Icons/question-circle.svg"));
40  helpButton->setStyleSheet("QToolButton { border: none; }");
41  helpButton->setCursor(Qt::PointingHandCursor);
42  connect(helpButton, &QToolButton::clicked, this, &VuoErrorPopover::helpButtonClicked);
43 
44  // Place the button in the top-right corner of the popover.
45  QVBoxLayout *innerLayout = new QVBoxLayout(textLabel);
46  innerLayout->setContentsMargins(0, 4, 4, 0);
47  innerLayout->addWidget(helpButton, 0, Qt::AlignTop | Qt::AlignRight);
48  textLabel->setLayout(innerLayout);
49  }
50 
51  setLayout(layout);
52 
53  setStyle();
54 
55  dragInProgress = false;
56 
57  VuoEditor *editor = (VuoEditor *)qApp;
58  connect(editor, &VuoEditor::darkInterfaceToggled, this, &VuoErrorPopover::updateColor);
59 }
60 
64 void VuoErrorPopover::setStyle()
65 {
66  textLabel->setFont(VuoRendererFonts::getSharedFonts()->portPopoverFont());
67  textLabel->setMargin(5);
68  textLabel->setWordWrap(true);
69 
70  Qt::WindowFlags flags = windowFlags();
71  flags |= Qt::FramelessWindowHint;
72  flags |= Qt::Tool;
73  setWindowFlags(flags);
74 
75  // Transparent background behind rounded corners
76  setAttribute(Qt::WA_TranslucentBackground, true);
77 
78  setArrowSide(Qt::AnchorTop);
79  arrowTipY = -1; // Disable arrow.
80 
81  VuoEditor *editor = (VuoEditor *)qApp;
82  bool isDark = editor->isInterfaceDark();
83  updateColor(isDark);
84 }
85 
89 void VuoErrorPopover::paintEvent(QPaintEvent *event)
90 {
91  VuoEditor *editor = (VuoEditor *)qApp;
92  bool isDark = editor->isInterfaceDark();
93  QColor backgroundColor = isDark ? QColor("#282828") : QColor("#f9f9f9");
94 
95  QPainter painter(this);
96 
97  // Workaround to ensure that transparent background behind rounded corners works consistently
98  painter.setCompositionMode(QPainter::CompositionMode_Clear);
99  painter.setBrush(backgroundColor);
100  painter.drawRect(QRect(0, 0, width(), height()));
101  painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
102 
103  painter.setRenderHint(QPainter::Antialiasing, true);
104 
105  painter.setPen(Qt::NoPen);
106  painter.fillPath(getPopoverPath(arrowSide, arrowTipY), backgroundColor);
107 }
108 
113 bool VuoErrorPopover::eventFilter(QObject *obj, QEvent *event)
114 {
115  if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseMove || event->type() == QEvent::MouseButtonRelease)
116  {
117  QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
118 
119  if (mouseEvent->type() == QEvent::MouseButtonPress && mouseEvent->button() == Qt::LeftButton)
120  {
121  dragInProgress = true;
122  positionBeforeDrag = mouseEvent->globalPos();
123  }
124  else if (mouseEvent->type() == QEvent::MouseMove && (mouseEvent->buttons() & Qt::LeftButton) && dragInProgress)
125  {
126  QPoint delta = mouseEvent->globalPos() - positionBeforeDrag;
127  move(x() + delta.x(), y() + delta.y());
128  positionBeforeDrag = mouseEvent->globalPos();
129  }
130  else if (mouseEvent->type() == QEvent::MouseButtonRelease && mouseEvent->button() == Qt::LeftButton)
131  {
132  dragInProgress = false;
133  }
134  }
135 
136  return false;
137 }
138 
139 void VuoErrorPopover::helpButtonClicked()
140 {
141  QDesktopServices::openUrl("vuo-help:" + helpPath);
142 }
143 
147 void VuoErrorPopover::setArrowSide(Qt::AnchorPoint arrowSide)
148 {
149  this->arrowSide = arrowSide;
150  layout->setContentsMargins(getPopoverContentsMargins(arrowSide));
151 }
152 
159 {
161 }
162 
168 {
169  VuoPopover::setWindowLevel(top, this);
170 }
171 
175 void VuoErrorPopover::updateColor(bool isDark)
176 {
177  QString textColor = isDark ? "#cacaca" : "#000000";
178  textLabel->setStyleSheet(QString("color: %1;").arg(textColor));
179 
180  emit repaint();
181 }