增加预览页介绍信息显示
This commit is contained in:
176
client/gui/dialogs/EntityIntroPopup.cpp
Normal file
176
client/gui/dialogs/EntityIntroPopup.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user