mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 21:10:05 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			185 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include <scwx/qt/util/tooltip.hpp>
 | |
| #include <scwx/qt/manager/font_manager.hpp>
 | |
| #include <scwx/qt/settings/text_settings.hpp>
 | |
| #include <scwx/qt/util/imgui.hpp>
 | |
| #include <scwx/util/logger.hpp>
 | |
| 
 | |
| #include <TextFlow.hpp>
 | |
| #include <QGuiApplication>
 | |
| #include <QLabel>
 | |
| #include <QScreen>
 | |
| #include <QToolTip>
 | |
| 
 | |
| namespace scwx
 | |
| {
 | |
| namespace qt
 | |
| {
 | |
| namespace util
 | |
| {
 | |
| namespace tooltip
 | |
| {
 | |
| 
 | |
| static const std::string logPrefix_ = "scwx::qt::util::tooltip";
 | |
| static const auto        logger_    = scwx::util::Logger::Create(logPrefix_);
 | |
| 
 | |
| static std::unique_ptr<QLabel>  tooltipLabel_  = nullptr;
 | |
| static std::unique_ptr<QWidget> tooltipParent_ = nullptr;
 | |
| 
 | |
| void Initialize()
 | |
| {
 | |
|    static bool initialized = false;
 | |
| 
 | |
|    if (initialized)
 | |
|    {
 | |
|       return;
 | |
|    }
 | |
| 
 | |
|    tooltipParent_ = std::make_unique<QWidget>();
 | |
|    tooltipParent_->setStyleSheet(
 | |
|       "QToolTip"
 | |
|       "{"
 | |
|       "background-color: rgba(15, 15, 15, 191);"
 | |
|       "border: 1px solid rgba(110, 110, 128, 128);"
 | |
|       "color: rgba(255, 255, 255, 204);"
 | |
|       "}");
 | |
| 
 | |
|    tooltipLabel_ = std::make_unique<QLabel>();
 | |
|    tooltipLabel_->setWindowFlag(Qt::ToolTip);
 | |
|    tooltipLabel_->setContentsMargins(6, 4, 6, 4);
 | |
|    tooltipLabel_->setStyleSheet(
 | |
|       "background-color: rgba(15, 15, 15, 191);"
 | |
|       "border: 1px solid rgba(110, 110, 128, 128);"
 | |
|       "color: rgba(255, 255, 255, 204);");
 | |
| 
 | |
|    initialized = true;
 | |
| }
 | |
| 
 | |
| void Show(const std::string& text, const QPointF& mouseGlobalPos)
 | |
| {
 | |
|    Initialize();
 | |
| 
 | |
|    auto& textSettings = settings::TextSettings::Instance();
 | |
| 
 | |
|    std::size_t textWidth =
 | |
|       static_cast<std::size_t>(textSettings.hover_text_wrap().GetValue());
 | |
|    types::TooltipMethod tooltipMethod =
 | |
|       types::GetTooltipMethod(textSettings.tooltip_method().GetValue());
 | |
| 
 | |
|    // Wrap text if enabled
 | |
|    std::string wrappedText {};
 | |
|    if (textWidth > 0)
 | |
|    {
 | |
|       wrappedText = TextFlow::Column(text).width(textWidth).toString();
 | |
|    }
 | |
| 
 | |
|    // Display text is either wrapped or unwrapped text (do this to avoid copy
 | |
|    // when not wrapping)
 | |
|    const std::string& displayText = (textWidth > 0) ? wrappedText : text;
 | |
| 
 | |
|    if (tooltipMethod == types::TooltipMethod::ImGui)
 | |
|    {
 | |
|       util::ImGui::Instance().DrawTooltip(displayText);
 | |
|    }
 | |
|    else if (tooltipMethod == types::TooltipMethod::QToolTip)
 | |
|    {
 | |
|       QString fontFamily = QString::fromStdString(
 | |
|          textSettings.font_family(types::FontCategory::Tooltip).GetValue());
 | |
|       QString fontStyle = QString::fromStdString(
 | |
|          textSettings.font_style(types::FontCategory::Tooltip).GetValue());
 | |
|       double fontPointSize =
 | |
|          textSettings.font_point_size(types::FontCategory::Tooltip).GetValue();
 | |
| 
 | |
|       static std::size_t id = 0;
 | |
|       QToolTip::showText(
 | |
|          mouseGlobalPos.toPoint(),
 | |
|          QString("<span id='%1' style='font-family:\"%2\"; font-style:\"%3\"; "
 | |
|                  "font-size:\"%4pt\";'>%5</span>")
 | |
|             .arg(++id)
 | |
|             .arg(fontFamily)
 | |
|             .arg(fontStyle)
 | |
|             .arg(fontPointSize)
 | |
|             .arg(QString::fromStdString(displayText).replace("\n", "<br/>")),
 | |
|          tooltipParent_.get(),
 | |
|          {},
 | |
|          std::numeric_limits<int>::max());
 | |
|    }
 | |
|    else if (tooltipMethod == types::TooltipMethod::QLabel)
 | |
|    {
 | |
|       // Configure the label
 | |
|       QFont font = manager::FontManager::Instance().GetQFont(
 | |
|          types::FontCategory::Tooltip);
 | |
|       tooltipLabel_->setFont(font);
 | |
|       tooltipLabel_->setText(QString::fromStdString(displayText));
 | |
|       tooltipLabel_->resize(tooltipLabel_->sizeHint());
 | |
| 
 | |
|       // Get the screen the label will be displayed on
 | |
|       QScreen* screen = QGuiApplication::screenAt(mouseGlobalPos.toPoint());
 | |
|       if (screen == nullptr)
 | |
|       {
 | |
|          screen = QGuiApplication::primaryScreen();
 | |
|       }
 | |
| 
 | |
|       // Default offset for label
 | |
|       const QPoint offset {25, 0};
 | |
| 
 | |
|       // Get starting label position (below and to the right)
 | |
|       QPoint p = mouseGlobalPos.toPoint() + offset;
 | |
| 
 | |
|       // Adjust position if necessary
 | |
|       const QRect r = screen->geometry();
 | |
|       if (p.x() + tooltipLabel_->width() > r.x() + r.width())
 | |
|       {
 | |
|          // If the label extends beyond the right of the screen, move it left
 | |
|          p.rx() -= offset.x() * 2 + tooltipLabel_->width();
 | |
|       }
 | |
|       if (p.y() + tooltipLabel_->height() > r.y() + r.height())
 | |
|       {
 | |
|          // If the label extends beyond the bottom of the screen, move it up
 | |
|          // p.ry() -= offset.y() * 2 + tooltipLabel_->height();
 | |
|          // Don't, let it fall through and clamp instead
 | |
|       }
 | |
| 
 | |
|       // Clamp the label within the screen
 | |
|       if (p.y() < r.y())
 | |
|       {
 | |
|          p.setY(r.y());
 | |
|       }
 | |
|       if (p.x() + tooltipLabel_->width() > r.x() + r.width())
 | |
|       {
 | |
|          p.setX(r.x() + r.width() - tooltipLabel_->width());
 | |
|       }
 | |
|       if (p.x() < r.x())
 | |
|       {
 | |
|          p.setX(r.x());
 | |
|       }
 | |
|       if (p.y() + tooltipLabel_->height() > r.y() + r.height())
 | |
|       {
 | |
|          p.setY(r.y() + r.height() - tooltipLabel_->height());
 | |
|       }
 | |
| 
 | |
|       // Move the tooltip to the calculated offset
 | |
|       tooltipLabel_->move(p);
 | |
| 
 | |
|       // Show the tooltip
 | |
|       if (tooltipLabel_->isHidden())
 | |
|       {
 | |
|          tooltipLabel_->show();
 | |
|       }
 | |
|    }
 | |
| }
 | |
| 
 | |
| void Hide()
 | |
| {
 | |
|    Initialize();
 | |
| 
 | |
|    // TooltipMethod::QToolTip
 | |
|    QToolTip::hideText();
 | |
| 
 | |
|    // TooltipMethod::QLabel
 | |
|    tooltipLabel_->hide();
 | |
| }
 | |
| 
 | |
| } // namespace tooltip
 | |
| } // namespace util
 | |
| } // namespace qt
 | |
| } // namespace scwx
 | 
