1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
#include "FieldTip.h"
#include "HerculesStudio.h"
#include <QPainter>
const QBrush backgroundBrush(QColor(255, 255, 225));
const QPen outlinePen(Qt::black, 1);
const int textPadding = 6;
int tipHeight = 20;
FieldTip::FieldTip(QWidget *parent, bool top) :
QWidget(parent), mTop(top),attachedField()
{
setAttribute(Qt::WA_TranslucentBackground);
expireTimer.setSingleShot(true);
connect(&expireTimer, SIGNAL(timeout()), this, SLOT(deleteLater()));
}
FieldTip::~FieldTip()
{
}
void FieldTip::showMessage(const QString& message, int timeout/*ms*/) {
if (!attachedField) return;
setWindowTitle(message);
calculatePosition();
expireTimer.start(timeout);
show();
update();
}
QSize FieldTip::findBestSize(const QFontMetrics& fontMetrics, const QString& message) {
int width = 100;
QRect rect = fontMetrics.boundingRect(0, 0, width, 0,
Qt::AlignLeft | Qt::TextWordWrap, message);
int count = 0;
float ratio = float(rect.width())/float(rect.height());
while ((ratio < 3.0 || ratio > 4.0) && count < 50) {
width = ratio < 3.0 ? width+20 : width-20;
rect = fontMetrics.boundingRect(0, 0, width, 0,
Qt::AlignLeft | Qt::TextWordWrap, message);
ratio = float(rect.width())/float(rect.height());
count++;
}
return rect.size();
}
void FieldTip::calculatePosition() {
if (!attachedField) return;
QPoint fieldPos = attachedField->mapToParent(QPoint(0,0));
QSize size = findBestSize(this->fontMetrics(), windowTitle());
hOutDebug(1,"size: " << size.width() << "," << size.height());
size.setWidth(size.width() + (textPadding*2));
size.setHeight(size.height() + (textPadding*2) + tipHeight);
if (mTop)
{
int x = fieldPos.x() + attachedField->width()/2 - size.width() +15;
int y = fieldPos.y() + attachedField->height() ;
move(x, y); resize(size);
hOutDebug(2,fieldPos.x() << "," << fieldPos.y());
hOutDebug(2,"size: " << size.width() << "," << size.height());
hOutDebug(2,x << "," << y);
}
else
{
int x = fieldPos.x() + attachedField->width()/2 - size.width() + 15;
int y = fieldPos.y() - size.height();
move(x, y); resize(size);
hOutDebug(2,fieldPos.x() << "," << fieldPos.y());
hOutDebug(2,"size: " << size.width() << "," << size.height());
hOutDebug(2,x << "," << y);
}
}
void FieldTip::paintEvent(QPaintEvent*) {
QPainter painter(this);
const int roundness = 12;
painter.setRenderHint(QPainter::Antialiasing);
int xbase = width()-15;
int ybase = height() - tipHeight;
QPoint p1, p2, p3;
if (mTop)
{
p1 = QPoint(width()-tipHeight-15, tipHeight+2); // bottom left
p2 = QPoint(xbase, 0); // top
p3 = QPoint(xbase, tipHeight+2); // bottom right
}
else
{
p1 = QPoint(width()-tipHeight-15, ybase-2); // top right
p2 = QPoint(xbase, height()); // bottom
p3 = QPoint(xbase, ybase-2); // top left
}
QPolygon triangle;
triangle << p1 << p2 << p3;
painter.setBrush(backgroundBrush);
painter.setPen(outlinePen);
if (mTop)
painter.drawRoundedRect(1, 1+tipHeight, width()-2, ybase-2, roundness, roundness);
else
painter.drawRoundedRect(1, 1, width()-2, ybase-2, roundness, roundness);
painter.setPen(Qt::transparent);
painter.drawPolygon(triangle);
painter.setPen(outlinePen);
painter.drawLine(p1, p2);
painter.drawLine(p2, p3);
painter.drawText(textPadding, textPadding,
width()-textPadding, mTop ? ybase+textPadding + tipHeight : ybase-textPadding ,
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap,
windowTitle());
}
|