Sketcher: Tooltip when hovering expression driven constraint (#25954)
This commit is contained in:
@@ -34,11 +34,13 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFontMetricsF>
|
||||
#include <QHelpEvent>
|
||||
#include <QListWidget>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QScreen>
|
||||
#include <QTextStream>
|
||||
#include <QToolTip>
|
||||
#include <QWindow>
|
||||
|
||||
#include <limits>
|
||||
@@ -2414,6 +2416,48 @@ bool ViewProviderSketch::detectAndShowPreselection(SoPickedPoint* Point)
|
||||
{
|
||||
assert(isInEditMode());
|
||||
|
||||
// Event filter to intercept the delayed tooltip event from Qt
|
||||
class ToolTipFilter : public QObject {
|
||||
public:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override {
|
||||
if (event->type() == QEvent::ToolTip) {
|
||||
// When Qt's idle timer fires, this event is sent.
|
||||
// We intercept it to show the tooltip.
|
||||
QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
|
||||
QWidget *widget = qobject_cast<QWidget *>(obj);
|
||||
if (widget && !widget->toolTip().isEmpty()) {
|
||||
QToolTip::showText(helpEvent->globalPos(), widget->toolTip(), widget);
|
||||
return true; // Mark as handled so default processing doesn't hide it
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
};
|
||||
static ToolTipFilter filter;
|
||||
|
||||
auto updateToolTip = [this](const QString& text = QString()) {
|
||||
auto* view = qobject_cast<Gui::View3DInventor*>(this->getActiveView());
|
||||
QWidget* widget = view ? view->getViewer()->getGLWidget() : nullptr;
|
||||
|
||||
if (!widget) return;
|
||||
|
||||
if (text.isEmpty()) {
|
||||
// Hide tooltip and cleanup
|
||||
QToolTip::hideText();
|
||||
widget->removeEventFilter(&filter);
|
||||
widget->setToolTip(QString());
|
||||
} else {
|
||||
// 1. Set the tooltip text on the widget.
|
||||
// This arm's Qt's internal timer to fire QEvent::ToolTip after the standard delay.
|
||||
widget->setToolTip(text);
|
||||
|
||||
// 2. Install the filter to catch that event.
|
||||
// We remove it first to ensure we don't install it multiple times.
|
||||
widget->removeEventFilter(&filter);
|
||||
widget->installEventFilter(&filter);
|
||||
}
|
||||
};
|
||||
|
||||
if (Point) {
|
||||
|
||||
EditModeCoinManager::PreselectionResult result = editCoinManager->detectPreselection(Point);
|
||||
@@ -2429,6 +2473,7 @@ bool ViewProviderSketch::detectAndShowPreselection(SoPickedPoint* Point)
|
||||
preselection.blockedPreselection = !accepted;
|
||||
if (accepted) {
|
||||
setPreselectPoint(result.PointIndex);
|
||||
updateToolTip(); // Clear tooltip on point selection
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2450,6 +2495,7 @@ bool ViewProviderSketch::detectAndShowPreselection(SoPickedPoint* Point)
|
||||
if (accepted) {
|
||||
resetPreselectPoint();
|
||||
preselection.PreselectCurve = result.GeoIndex;
|
||||
updateToolTip(); // Clear tooltip on curve selection
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2483,6 +2529,7 @@ bool ViewProviderSketch::detectAndShowPreselection(SoPickedPoint* Point)
|
||||
resetPreselectPoint();
|
||||
preselection.PreselectCross =
|
||||
static_cast<Preselection::Axes>(static_cast<int>(result.Cross));
|
||||
updateToolTip(); // Clear tooltip on axis selection
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2503,12 +2550,24 @@ bool ViewProviderSketch::detectAndShowPreselection(SoPickedPoint* Point)
|
||||
!= 0;
|
||||
|
||||
preselection.blockedPreselection = !accepted;
|
||||
// TODO: Should we clear preselections that went through, if one fails?
|
||||
}
|
||||
if (accepted) {
|
||||
resetPreselectPoint();
|
||||
preselection.PreselectConstraintSet = result.ConstrIndices;
|
||||
|
||||
// Build tooltip text for expressions
|
||||
QString tooltipText;
|
||||
for (int id : result.ConstrIndices) {
|
||||
if (constraintHasExpression(id)) {
|
||||
std::string expr = getSketchObject()->getConstraintExpression(id);
|
||||
if (!expr.empty()) {
|
||||
tooltipText = QString::fromUtf8("\U0001D453\U0001D465 = ") + QString::fromStdString(expr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateToolTip(tooltipText);
|
||||
|
||||
return true;// Preselection changed
|
||||
}
|
||||
}
|
||||
@@ -2522,6 +2581,7 @@ bool ViewProviderSketch::detectAndShowPreselection(SoPickedPoint* Point)
|
||||
// we have just left a preselection
|
||||
resetPreselectPoint();
|
||||
preselection.blockedPreselection = false;
|
||||
updateToolTip(); // Clear tooltip when leaving preselection
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2533,6 +2593,7 @@ bool ViewProviderSketch::detectAndShowPreselection(SoPickedPoint* Point)
|
||||
|| preselection.blockedPreselection) {
|
||||
resetPreselectPoint();
|
||||
preselection.blockedPreselection = false;
|
||||
updateToolTip(); // Clear tooltip when no point picked
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user