mirror of
https://github.com/clementine-player/Clementine
synced 2025-02-01 11:56:45 +01:00
Prettier global search tooltip
This commit is contained in:
parent
4ac16f0dd4
commit
2a97a63719
@ -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_, ©);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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_;
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user