Files
hfut-bishe/client/gui/dialogs/EntityIntroPopup.cpp

177 lines
5.0 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "dialogs/EntityIntroPopup.h"
#include <QDir>
#include <QFileInfo>
#include <QGuiApplication>
#include <QLabel>
#include <QScreen>
#include <QPainter>
#include <QPaintEvent>
#include <QPixmap>
#include <QStyleOption>
#include <QTextEdit>
#include <QVBoxLayout>
namespace gui {
namespace {
constexpr int kMaxThumb = 200;
QString elideLine(const QString& s, int maxChars) {
if (s.size() <= maxChars) {
return s;
}
return s.left(maxChars - 1) + QChar(0x2026);
}
} // namespace
EntityIntroPopup::EntityIntroPopup(QWidget* parent)
: QWidget(parent) {
setAttribute(Qt::WA_TranslucentBackground, false);
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
auto* root = new QVBoxLayout(this);
root->setContentsMargins(14, 12, 14, 12);
root->setSpacing(8);
m_title = new QLabel(this);
QFont tf = m_title->font();
tf.setBold(true);
tf.setPointSizeF(tf.pointSizeF() + 1.5);
m_title->setFont(tf);
m_title->setWordWrap(true);
root->addWidget(m_title);
m_body = new QTextEdit(this);
m_body->setReadOnly(true);
m_body->setFrameShape(QFrame::NoFrame);
m_body->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
m_body->setMaximumHeight(180);
m_body->setPlaceholderText(QStringLiteral("(无)"));
root->addWidget(m_body);
m_imagesHost = new QWidget(this);
m_imagesLayout = new QVBoxLayout(m_imagesHost);
m_imagesLayout->setContentsMargins(0, 0, 0, 0);
m_imagesLayout->setSpacing(6);
root->addWidget(m_imagesHost);
m_videoHint = new QLabel(this);
m_videoHint->setWordWrap(true);
m_videoHint->setStyleSheet(QStringLiteral("QLabel { color: palette(mid); font-size: 11px; }"));
root->addWidget(m_videoHint);
setMinimumWidth(280);
setMaximumWidth(420);
hide();
}
void EntityIntroPopup::setProjectDir(const QString& absoluteProjectDir) {
m_projectDirAbs = absoluteProjectDir;
}
void EntityIntroPopup::setContent(const core::EntityIntroContent& content) {
const QString t = content.title.trimmed().isEmpty()
? QStringLiteral("介绍")
: content.title.trimmed();
m_title->setText(elideLine(t, 200));
m_body->setPlainText(content.bodyText);
while (QLayoutItem* it = m_imagesLayout->takeAt(0)) {
if (QWidget* w = it->widget()) {
w->deleteLater();
}
delete it;
}
for (const QString& rel : content.imagePathsRelative) {
if (rel.isEmpty()) {
continue;
}
const QString abs =
m_projectDirAbs.isEmpty() ? QString() : QDir(m_projectDirAbs).filePath(rel);
auto* lab = new QLabel(m_imagesHost);
lab->setAlignment(Qt::AlignCenter);
if (!abs.isEmpty() && QFileInfo::exists(abs)) {
QPixmap pm(abs);
if (!pm.isNull()) {
if (pm.width() > kMaxThumb || pm.height() > kMaxThumb) {
pm = pm.scaled(kMaxThumb, kMaxThumb, Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
lab->setPixmap(pm);
} else {
lab->setText(QStringLiteral("(无法加载图片)"));
}
} else {
lab->setText(QStringLiteral("(缺少文件:%1").arg(rel));
}
lab->setWordWrap(true);
m_imagesLayout->addWidget(lab);
}
if (content.videoPathRelative.trimmed().isEmpty()) {
m_videoHint->setText(QStringLiteral("视频介绍"));
} else {
m_videoHint->setText(QStringLiteral("播放功能预留").arg(content.videoPathRelative));
}
adjustSize();
}
void EntityIntroPopup::showNearCanvasPoint(const QPoint& viewPos, QWidget* canvasWidget) {
if (!canvasWidget) {
return;
}
adjustSize();
const QPoint globalAnchor = canvasWidget->mapToGlobal(viewPos);
QScreen* scr = QGuiApplication::screenAt(globalAnchor);
if (!scr) {
scr = canvasWidget->screen();
}
const QRect screen = scr ? scr->availableGeometry() : QRect(0, 0, 1920, 1080);
int x = globalAnchor.x() + 18;
int y = globalAnchor.y() - height() / 3;
if (x + width() > screen.right()) {
x = globalAnchor.x() - width() - 18;
}
if (x < screen.left()) {
x = screen.left() + 8;
}
if (y + height() > screen.bottom()) {
y = screen.bottom() - height() - 8;
}
if (y < screen.top()) {
y = screen.top() + 8;
}
move(x, y);
show();
raise();
}
void EntityIntroPopup::clearAndHide() {
hide();
m_title->clear();
m_body->clear();
while (QLayoutItem* it = m_imagesLayout->takeAt(0)) {
if (QWidget* w = it->widget()) {
w->deleteLater();
}
delete it;
}
m_videoHint->clear();
}
void EntityIntroPopup::paintEvent(QPaintEvent* e) {
Q_UNUSED(e);
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing, true);
const QRect r = rect().adjusted(1, 1, -1, -1);
p.fillRect(r, palette().base());
p.setPen(QPen(palette().mid().color(), 1));
p.drawRoundedRect(r, 8, 8);
}
} // namespace gui