QRect findBestSize
(const QFontMetrics
& fontMetrics,
const String
& message
) { QRect rect
= fontMetrics.
boundingRect(0,
0,
100,
50,
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, message);
float ratio = float(rect.width())/float(rect.height());
while(ratio < 1.5 || ratio > 2.0) {
rect.adjust(0, 0, 10, 5);
rect = fontMetrics.boundingRect(0, 0, rect.width(), rect.height(),
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, message);
ratio = float(rect.width())/float(rect.height());
}
return rect;
}
QRect findBestSize(const QFontMetrics& fontMetrics, const String& message) {
QRect rect = fontMetrics.boundingRect(0, 0, 100, 50,
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, message);
float ratio = float(rect.width())/float(rect.height());
while(ratio < 1.5 || ratio > 2.0) {
rect.adjust(0, 0, 10, 5);
rect = fontMetrics.boundingRect(0, 0, rect.width(), rect.height(),
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, message);
ratio = float(rect.width())/float(rect.height());
}
return rect;
}
To copy to clipboard, switch view to plain text mode
// File: BalloonTip.h
#ifndef BALLOON_TIP_H
#define BALLOON_TIP_H
class BalloonTip
: public QWidget {private:
static const QBrush backgroundBrush;
static const QPen outlinePen;
static const int textPadding = 6;
static const int arrowHeight = 20; // That triangle bit at the bottom
QWidget* owner;
// TODO: think of a better name. public:
BalloonTip();
~BalloonTip() {}
void setOwner
(QWidget* widget
) { owner
= widget;
} void showMessage(const String& message, int timeout/*ms*/);
void showMessage
(QWidget* widget,
const String
& message,
int timeout
/*ms*/) { setOwner(widget); showMessage(message, timeout);
}
protected:
};
#endif // BALLOON_TIP_H
/**************************************************************/
// File: BalloonTip.cpp
#include "BalloonTip.h"
const QBrush BalloonTip
::backgroundBrush(QColor(255,
255,
225));
const QPen BalloonTip
::outlinePen(Qt
::black,
1);
BalloonTip::BalloonTip() :
QWidget(NULL, Qt
::ToolTip | Qt
::FramelessWindowHint),
expireTimer(), owner(NULL) {
setAttribute(Qt::WA_TranslucentBackground);
expireTimer.setSingleShot(true);
connect(&expireTimer, SIGNAL(timeout()), this, SLOT(hide()));
}
/* TODO: Get this working. What it should do is start at a minimum size,
100,50 and increase the bounding box until all the text fits in AND
the aspect ration is between 1.5 and 2.0
QRect findBestSize(const QFontMetrics& fontMetrics, const String& message) {
QRect rect = fontMetrics.boundingRect(0, 0, 100, 50,
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, message);
float ratio = float(rect.width())/float(rect.height());
while(ratio < 1.5 || ratio > 2.0) {
rect.adjust(0, 0, 10, 5);
rect = fontMetrics.boundingRect(0, 0, rect.width(), rect.height(),
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, message);
ratio = float(rect.width())/float(rect.height());
}
return rect;
}*/
void BalloonTip::showMessage(const String& message, int timeout/*ms*/) {
if (!owner) return;
int width = (textPadding*2)+200; // Hard-code size for now
int height = (textPadding*2)+60+arrowHeight;
int x = ownerPos.x() - (width-15-(owner->width()/2));
int y = ownerPos.y() - height;
setWindowTitle(message);
move(x, y); resize(width, height);
expireTimer.start(timeout);
show();
update(); // Force redraw if it is already showing
}
/*------------------------------------------------------------------+
| Do custom painting. The entire rect is filled with the background |
| colour and the clip region is used to make an outline path. |
+------------------------------------------------------------------*/
const int roundness = 12;
const int rectBase = height()-arrowHeight;
painter.
setRenderHint(QPainter::Antialiasing);
QPoint p1
(width
()-35, rectBase
-2);
QPoint p2
(width
()-15, height
());
QPoint p3
(width
()-15, rectBase
-2);
triangle << p1 << p2 << p3;
// TODO: This doesn't look quite right when drawing the bottom
// triangle bit. I need to erase the border of the rectangle
// in the triangle area, but anti-aliasing means that the triangle's
// border then slighly overlaps.
painter.setBrush(backgroundBrush);
painter.setPen(outlinePen);
painter.drawRoundedRect(1, 1, width()-2, rectBase-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, rectBase-textPadding,
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap,
windowTitle());
}
// File: BalloonTip.h
#ifndef BALLOON_TIP_H
#define BALLOON_TIP_H
class BalloonTip : public QWidget {
private:
static const QBrush backgroundBrush;
static const QPen outlinePen;
static const int textPadding = 6;
static const int arrowHeight = 20; // That triangle bit at the bottom
QTimer expireTimer;
QWidget* owner; // TODO: think of a better name.
public:
BalloonTip();
~BalloonTip() {}
void setOwner(QWidget* widget) { owner = widget; }
void showMessage(const String& message, int timeout/*ms*/);
void showMessage(QWidget* widget, const String& message, int timeout/*ms*/) {
setOwner(widget); showMessage(message, timeout);
}
protected:
void paintEvent(QPaintEvent*);
};
#endif // BALLOON_TIP_H
/**************************************************************/
// File: BalloonTip.cpp
#include "BalloonTip.h"
const QBrush BalloonTip::backgroundBrush(QColor(255, 255, 225));
const QPen BalloonTip::outlinePen(Qt::black, 1);
BalloonTip::BalloonTip() :
QWidget(NULL, Qt::ToolTip | Qt::FramelessWindowHint),
expireTimer(), owner(NULL) {
setAttribute(Qt::WA_TranslucentBackground);
expireTimer.setSingleShot(true);
connect(&expireTimer, SIGNAL(timeout()), this, SLOT(hide()));
}
/* TODO: Get this working. What it should do is start at a minimum size,
100,50 and increase the bounding box until all the text fits in AND
the aspect ration is between 1.5 and 2.0
QRect findBestSize(const QFontMetrics& fontMetrics, const String& message) {
QRect rect = fontMetrics.boundingRect(0, 0, 100, 50,
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, message);
float ratio = float(rect.width())/float(rect.height());
while(ratio < 1.5 || ratio > 2.0) {
rect.adjust(0, 0, 10, 5);
rect = fontMetrics.boundingRect(0, 0, rect.width(), rect.height(),
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, message);
ratio = float(rect.width())/float(rect.height());
}
return rect;
}*/
void BalloonTip::showMessage(const String& message, int timeout/*ms*/) {
if (!owner) return;
QPoint ownerPos = owner->mapToGlobal(QPoint(0,0));
int width = (textPadding*2)+200; // Hard-code size for now
int height = (textPadding*2)+60+arrowHeight;
int x = ownerPos.x() - (width-15-(owner->width()/2));
int y = ownerPos.y() - height;
setWindowTitle(message);
move(x, y); resize(width, height);
expireTimer.start(timeout);
show();
update(); // Force redraw if it is already showing
}
/*------------------------------------------------------------------+
| Do custom painting. The entire rect is filled with the background |
| colour and the clip region is used to make an outline path. |
+------------------------------------------------------------------*/
void BalloonTip::paintEvent(QPaintEvent*) {
QPainter painter(this);
const int roundness = 12;
const int rectBase = height()-arrowHeight;
painter.setRenderHint(QPainter::Antialiasing);
QPoint p1(width()-35, rectBase-2);
QPoint p2(width()-15, height());
QPoint p3(width()-15, rectBase-2);
QPolygon triangle;
triangle << p1 << p2 << p3;
// TODO: This doesn't look quite right when drawing the bottom
// triangle bit. I need to erase the border of the rectangle
// in the triangle area, but anti-aliasing means that the triangle's
// border then slighly overlaps.
painter.setBrush(backgroundBrush);
painter.setPen(outlinePen);
painter.drawRoundedRect(1, 1, width()-2, rectBase-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, rectBase-textPadding,
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap,
windowTitle());
}
To copy to clipboard, switch view to plain text mode
Bookmarks