diff --git a/data/gui/normalStyle.css b/data/gui/normalStyle.css index f1609f94808a2..8a8a895dd3974 100644 --- a/data/gui/normalStyle.css +++ b/data/gui/normalStyle.css @@ -32,11 +32,13 @@ QFrame[frameShape="5"] { /* QFrame::VLine == 0x0005 */ border: 1px solid rgb(31, 31, 31); } +#StelToolTip, QToolTip { color: rgb(4, 5, 9); font-size: 100%; padding: 2px; background: rgb(143, 143, 143); + border: 1px solid rgb(0, 0, 0); } *[nightMode="true"] QToolTip { diff --git a/src/StelMainView.cpp b/src/StelMainView.cpp index 96a8cd6fe1c0a..0a84de0a79513 100644 --- a/src/StelMainView.cpp +++ b/src/StelMainView.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -349,6 +350,47 @@ class StelGraphicsScene : public QGraphicsScene //pass event on to items otherwise QGraphicsScene::keyPressEvent(event); } + void helpEvent(QGraphicsSceneHelpEvent* event) override + { + const QPoint pos(parent->mapFromGlobal(event->screenPos())); + QList itemsToCheck; + if (parent->isTransformed()) + { + const auto xform = parent->viewportTransform(); + itemsToCheck = items(xform.inverted().map(pos), Qt::IntersectsItemShape, + Qt::DescendingOrder, xform); + } + else + { + itemsToCheck = items(pos, Qt::IntersectsItemShape, Qt::DescendingOrder); + } + QString text; + QPoint point; + for (auto*const item : itemsToCheck) + { + if (const auto proxy = dynamic_cast(item)) + { + const auto itemWidget = proxy->widget(); + if (!itemWidget) continue; + const auto child = itemWidget->childAt(pos); + if (child && !child->toolTip().isEmpty()) + { + text = child->toolTip(); + point = pos; + break; + } + } + if (!item->toolTip().isEmpty()) + { + text = item->toolTip(); + point = pos; + break; + } + } + + parent->showToolTip(point, text); + event->setAccepted(!text.isEmpty()); + } private: StelMainView* parent; @@ -1990,6 +2032,11 @@ Vec3f StelMainView::getSkyBackgroundColor() const return rootItem->getSkyBackgroundColor(); } +void StelMainView::showToolTip(const QPoint& scenePos, const QString& text) +{ + gui->showToolTip(scenePos, text); +} + QRectF StelMainView::setWindowSize(int width, int height) { // Make sure to leave fullscreen if necessary. diff --git a/src/StelMainView.hpp b/src/StelMainView.hpp index ce0a0e085c672..5cfa719df6ed0 100644 --- a/src/StelMainView.hpp +++ b/src/StelMainView.hpp @@ -232,6 +232,8 @@ public slots: //! Get the sky background color. (Actually retrieves from the StelRootItem.) Everything else than black creates a work of art! Vec3f getSkyBackgroundColor() const; + void showToolTip(const QPoint& scenePos, const QString& text); + protected: //! Hack to determine current monitor pixel ratio //! @todo Find a better way to handle this diff --git a/src/core/StelGuiBase.hpp b/src/core/StelGuiBase.hpp index 7f0e3867e3c9b..9c3fcf65f9d6f 100644 --- a/src/core/StelGuiBase.hpp +++ b/src/core/StelGuiBase.hpp @@ -35,6 +35,8 @@ class StelGuiBase virtual void init(QGraphicsWidget *atopLevelGraphicsWidget); + virtual void showToolTip(const QPoint& scenePos, const QString& text) = 0; + //! Load color scheme matching the section name. virtual void setStelStyle(const QString& section) =0; diff --git a/src/gui/StelGui.cpp b/src/gui/StelGui.cpp index f0ff400a363d6..492bae646e8f3 100644 --- a/src/gui/StelGui.cpp +++ b/src/gui/StelGui.cpp @@ -238,6 +238,8 @@ void StelGui::init(QGraphicsWidget *atopLevelGraphicsWidget) astroCalcDialog = new AstroCalcDialog(atopLevelGraphicsWidget); obsListDialog = new ObsListDialog(atopLevelGraphicsWidget); + toolTip = new StelToolTip(atopLevelGraphicsWidget); + /////////////////////////////////////////////////////////////////////// // Create all the main actions of the program, associated with shortcuts @@ -646,6 +648,11 @@ void StelGui::update() } } +void StelGui::showToolTip(const QPoint& scenePos, const QString& text) +{ + toolTip->showToolTip(scenePos, text); +} + void StelGui::displayAllInfo() { setInfoTextFilters(StelObject::InfoStringGroup(StelObject::AllInfo)); diff --git a/src/gui/StelGui.hpp b/src/gui/StelGui.hpp index 5e6f18f6fa202..a713d775e841d 100644 --- a/src/gui/StelGui.hpp +++ b/src/gui/StelGui.hpp @@ -32,6 +32,7 @@ class QGraphicsSceneMouseEvent; class QTimeLine; class StelButton; +class StelToolTip; class BottomStelBar; class InfoPanel; class ConfigurationDialog; @@ -90,6 +91,8 @@ class StelGui : public QObject, public StelGuiBase void init(QGraphicsWidget* topLevelGraphicsWidget) override; void update(); + void showToolTip(const QPoint& scenePos, const QString& text) override; + StelStyle getStelStyle() const {return currentStelStyle;} /////////////////////////////////////////////////////////////////////////// @@ -379,6 +382,8 @@ private slots: AstroCalcDialog* astroCalcDialog; ObsListDialog* obsListDialog; + StelToolTip* toolTip; + bool flagShowFlipButtons; StelButton* flipVert; StelButton* flipHoriz; diff --git a/src/gui/StelGuiItems.cpp b/src/gui/StelGuiItems.cpp index c2485ca899915..e5cef549fabd7 100644 --- a/src/gui/StelGuiItems.cpp +++ b/src/gui/StelGuiItems.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,52 @@ #include #include +StelToolTip::StelToolTip(QGraphicsItem* parent) + : QGraphicsProxyWidget(parent) + , label(new QLabel("")) +{ + setZValue(1e38); // Show on top + label->setObjectName("StelToolTip"); + setWidget(label); + setVisible(false); + + setSizePolicy({QSizePolicy::Minimum, QSizePolicy::Fixed}); + connect(dynamic_cast(StelApp::getInstance().getGui()), + &StelGui::guiStyleChanged, this, + [this](const QString &style){ label->setStyleSheet(style); }); + + connect(&StelApp::getInstance(), &StelApp::guiFontSizeChanged, + this, &StelToolTip::setFontSizeFromApp); + setFontSizeFromApp(StelApp::getInstance().getGuiFontSize()); +} + +void StelToolTip::setFontSizeFromApp(const int size) +{ + auto font = QGuiApplication::font(); + font.setPixelSize(size); + setFont(font); +} + +void StelToolTip::showToolTip(const QPoint& scenePos, const QString& text) +{ + if (isVisible() && label->text() == text) + { + // Avoid moving the tooltip when the text doesn't change + return; + } + + label->setText(text); + // The shift avoids clicking the tooltip instead of the control it's annotating + const QPoint shift(2, 2); + setPos(scenePos + shift); + updateGeometry(); + setVisible(!text.isEmpty()); +} + +void StelToolTip::mousePressEvent(QGraphicsSceneMouseEvent*) +{ + showToolTip({}, ""); +} void StelButton::brightenImage(QImage &img, float factor) { diff --git a/src/gui/StelGuiItems.hpp b/src/gui/StelGuiItems.hpp index 0b97966628647..5de24d4d82c1f 100644 --- a/src/gui/StelGuiItems.hpp +++ b/src/gui/StelGuiItems.hpp @@ -20,6 +20,7 @@ #ifndef STELGUIITEMS_HPP #define STELGUIITEMS_HPP +#include #include #include #include @@ -29,9 +30,23 @@ class QGraphicsSceneMouseEvent; class QTimeLine; class QGraphicsTextItem; class QTimer; +class QLabel; class StelProgressController; class QProgressBar; +class StelToolTip : public QGraphicsProxyWidget +{ +public: + StelToolTip(QGraphicsItem* parent); + void showToolTip(const QPoint& scenePos, const QString& text); +protected: + void mousePressEvent(QGraphicsSceneMouseEvent* event) override; +private: + void setFontSizeFromApp(int size); + + QLabel* label = nullptr; +}; + // Progress bars in the lower right corner class StelProgressBarMgr : public QGraphicsWidget {