Prettier global search tooltip

This commit is contained in:
David Sansome 2011-09-18 16:00:04 +01:00
parent 4ac16f0dd4
commit 2a97a63719
5 changed files with 108 additions and 31 deletions

View File

@ -19,19 +19,28 @@
#include "tooltipresultwidget.h"
#include "core/logging.h"
#include <QCoreApplication>
#include <QApplication>
#include <QDesktopWidget>
#include <QKeyEvent>
#include <QLayoutItem>
#include <QPainter>
#include <QVBoxLayout>
const qreal GlobalSearchTooltip::kBorderRadius = 8.0;
const qreal GlobalSearchTooltip::kBorderWidth = 4.0;
const qreal GlobalSearchTooltip::kArrowWidth = 10.0;
const qreal GlobalSearchTooltip::kArrowHeight = 10.0;
GlobalSearchTooltip::GlobalSearchTooltip(QObject* event_target)
: QWidget(NULL),
desktop_(qApp->desktop()),
event_target_(event_target)
{
setWindowFlags(Qt::Popup);
setFocusPolicy(Qt::NoFocus);
setAttribute(Qt::WA_OpaquePaintEvent);
setAttribute(Qt::WA_TranslucentBackground);
}
void GlobalSearchTooltip::SetResults(const SearchProvider::ResultList& results) {
@ -42,7 +51,7 @@ void GlobalSearchTooltip::SetResults(const SearchProvider::ResultList& results)
// Using a QVBoxLayout here made some weird flickering that I couldn't figure
// out how to fix, so do layout manually.
int y = 0;
int y = 9;
int w = 0;
foreach (const SearchProvider::Result& result, results) {
@ -56,11 +65,30 @@ void GlobalSearchTooltip::SetResults(const SearchProvider::ResultList& results)
w = qMax(w, size_hint.width());
}
foreach (QWidget* widget, widgets_) {
widget->resize(w, widget->sizeHint().height());
}
y += 9;
resize(w, y);
inner_rect_ = rect().adjusted(
kArrowWidth + kBorderWidth, kBorderWidth, -kBorderWidth, -kBorderWidth);
foreach (QWidget* widget, widgets_) {
widget->setMask(inner_rect_);
}
}
void GlobalSearchTooltip::ShowAt(const QPoint& pointing_to) {
move(pointing_to);
const qreal min_arrow_offset = kBorderRadius + kArrowHeight;
const QRect screen = desktop_->screenGeometry(this);
arrow_offset_ = min_arrow_offset +
qMax(0, pointing_to.y() + height() - screen.bottom());
move(pointing_to.x(), pointing_to.y() - arrow_offset_);
if (!isVisible())
show();
@ -68,10 +96,10 @@ void GlobalSearchTooltip::ShowAt(const QPoint& pointing_to) {
void GlobalSearchTooltip::keyPressEvent(QKeyEvent* e) {
// Copy the event to send to the target
QKeyEvent e2(e->type(), e->key(), e->modifiers(), e->text(),
e->isAutoRepeat(), e->count());
QKeyEvent copy(e->type(), e->key(), e->modifiers(), e->text(),
e->isAutoRepeat(), e->count());
qApp->sendEvent(event_target_, &e2);
qApp->sendEvent(event_target_, &copy);
e->accept();
}
@ -79,5 +107,27 @@ void GlobalSearchTooltip::keyPressEvent(QKeyEvent* e) {
void GlobalSearchTooltip::paintEvent(QPaintEvent*) {
QPainter p(this);
p.fillRect(rect(), palette().base());
QColor color = Qt::black;
// Transparent background
p.fillRect(rect(), Qt::transparent);
QRect area(inner_rect_.adjusted(
-kBorderWidth/2, -kBorderWidth/2, kBorderWidth/2, kBorderWidth/2));
// Draw the border
p.setRenderHint(QPainter::Antialiasing);
p.setPen(QPen(color, kBorderWidth));
p.setBrush(palette().color(QPalette::Base));
p.drawRoundedRect(area, kBorderRadius, kBorderRadius);
// Draw the arrow
QPolygonF arrow;
arrow << QPointF(kArrowWidth, arrow_offset_ - kArrowHeight)
<< QPointF(0, arrow_offset_)
<< QPointF(kArrowWidth, arrow_offset_ + kArrowHeight);
p.setBrush(color);
p.setPen(color);
p.drawPolygon(arrow);
}

View File

@ -22,7 +22,7 @@
#include <QWidget>
class QVBoxLayout;
class QDesktopWidget;
class GlobalSearchTooltip : public QWidget {
Q_OBJECT
@ -30,15 +30,26 @@ class GlobalSearchTooltip : public QWidget {
public:
GlobalSearchTooltip(QObject* event_target);
static const qreal kBorderRadius;
static const qreal kBorderWidth;
static const qreal kArrowWidth;
static const qreal kArrowHeight;
void SetResults(const SearchProvider::ResultList& results);
void ShowAt(const QPoint& pointing_to);
qreal ArrowOffset() const;
protected:
void keyPressEvent(QKeyEvent* e);
void paintEvent(QPaintEvent*);
private:
QDesktopWidget* desktop_;
SearchProvider::ResultList results_;
qreal arrow_offset_;
QRect inner_rect_;
QObject* event_target_;

View File

@ -530,6 +530,11 @@ void GlobalSearchWidget::UpdateTooltip() {
tooltip_->setPalette(view_->palette());
}
const QRect item_rect = view_->visualRect(current);
const QPoint popup_pos = item_rect.topRight() +
QPoint(-GlobalSearchTooltip::kArrowWidth,
item_rect.height() / 2);
tooltip_->SetResults(results);
tooltip_->ShowAt(view_->mapToGlobal(view_->visualRect(current).topRight()));
tooltip_->ShowAt(view_->mapToGlobal(popup_pos));
}

View File

@ -20,9 +20,9 @@
#include <QPainter>
const int TooltipResultWidget::kBorder = 6;
const int TooltipResultWidget::kBorder = 15;
const int TooltipResultWidget::kSpacing = 3;
const int TooltipResultWidget::kTrackNoSpacing = 6;
const int TooltipResultWidget::kTrackNumSpacing = 6;
const int TooltipResultWidget::kLineHeight = 1;
const int TooltipResultWidget::kIconSize = 16;
@ -50,8 +50,9 @@ QSize TooltipResultWidget::CalculateSizeHint() const {
int h = 0;
// Title text
h += kBorder + kIconSize + kBorder + kLineHeight;
w = qMax(w, kBorder + kIconSize + kBorder + bold_metrics_.width(TitleText()) + kBorder);
h += kSpacing + kIconSize + kSpacing + kLineHeight;
w = qMax(w, kBorder + kTrackNoWidth + kTrackNumSpacing +
bold_metrics_.width(TitleText()) + kBorder);
switch (result_.type_) {
case SearchProvider::Result::Type_Track:
@ -62,15 +63,15 @@ QSize TooltipResultWidget::CalculateSizeHint() const {
break;
// Song list
h += kBorder + kSpacing * (result_.album_songs_.count() - 1) +
h += kSpacing + kSpacing * (result_.album_songs_.count() - 1) +
kTextHeight * result_.album_songs_.count();
foreach (const Song& song, result_.album_songs_) {
w = qMax(w, kTrackNoWidth + kTrackNoSpacing +
w = qMax(w, kBorder + kTrackNoWidth + kTrackNumSpacing +
fontMetrics().width(song.TitleWithCompilationArtist()) +
kBorder);
}
h += kBorder + kLineHeight;
h += kSpacing + kLineHeight;
break;
}
@ -84,22 +85,30 @@ QString TooltipResultWidget::TitleText() const {
void TooltipResultWidget::paintEvent(QPaintEvent*) {
QPainter p(this);
p.setPen(palette().color(QPalette::Text));
int y = kBorder;
const qreal line_opacity = 0.4;
const qreal track_opacity = 0.6;
const qreal text_opacity = 0.9;
// Title icon
QRect icon_rect(kBorder, y, kIconSize, kIconSize);
p.drawPixmap(icon_rect, result_.provider_->icon().pixmap(kIconSize));
int y = kSpacing;
// Title text
QRect text_rect(icon_rect.right() + kBorder, y,
width() - kBorder*2 - icon_rect.right(), kIconSize);
QRect text_rect(kBorder + kTrackNoWidth + kTrackNumSpacing, y,
width() - kBorder*2 - kTrackNoWidth - kTrackNumSpacing, kIconSize);
p.setFont(bold_font_);
p.setOpacity(text_opacity);
p.drawText(text_rect, Qt::AlignVCenter, TitleText());
// Title icon
QRect icon_rect(text_rect.left() - kTrackNumSpacing - kIconSize, y,
kIconSize, kIconSize);
p.drawPixmap(icon_rect, result_.provider_->icon().pixmap(kIconSize));
// Line
y += kIconSize + kBorder;
y += kIconSize + kSpacing;
p.setOpacity(line_opacity);
p.drawLine(0, y, width(), y);
y += kLineHeight;
@ -112,34 +121,36 @@ void TooltipResultWidget::paintEvent(QPaintEvent*) {
break;
// Song list
y += kBorder;
y += kSpacing;
p.setFont(font());
foreach (const Song& song, result_.album_songs_) {
QRect number_rect(0, y, kTrackNoWidth, kTextHeight);
QRect number_rect(kBorder, y, kTrackNoWidth, kTextHeight);
if (song.track() > 0) {
// Track number
p.setOpacity(track_opacity);
p.drawText(number_rect, Qt::AlignRight | Qt::AlignHCenter,
QString::number(song.track()));
}
// Song title
QRect title_rect(number_rect.right() + kTrackNoSpacing, y,
width() - number_rect.right() - kTrackNoSpacing - kBorder,
QRect title_rect(number_rect.right() + kTrackNumSpacing, y,
width() - number_rect.right() - kTrackNumSpacing - kBorder,
kTextHeight);
p.setOpacity(text_opacity);
p.drawText(title_rect, song.TitleWithCompilationArtist());
y += kTextHeight + kSpacing;
}
y -= kSpacing;
y += kBorder;
// Line
p.setOpacity(line_opacity);
p.drawLine(0, y, width(), y);
y += kLineHeight;
break;
}
y += kSpacing;
}

View File

@ -30,7 +30,7 @@ public:
static const int kBorder;
static const int kSpacing;
static const int kTrackNoSpacing;
static const int kTrackNumSpacing;
static const int kLineHeight;
static const int kIconSize;