Make the tooltip actions work properly by click and shortcut key, add a pretty mouseover animation to the tooltip actions, pass mouse events through to the proper widget when the tooltip is open.
This commit is contained in:
parent
7ec059dc13
commit
b45c5a866e
@ -34,7 +34,7 @@ const qreal GlobalSearchTooltip::kArrowWidth = 10.0;
|
|||||||
const qreal GlobalSearchTooltip::kArrowHeight = 10.0;
|
const qreal GlobalSearchTooltip::kArrowHeight = 10.0;
|
||||||
|
|
||||||
|
|
||||||
GlobalSearchTooltip::GlobalSearchTooltip(QObject* event_target)
|
GlobalSearchTooltip::GlobalSearchTooltip(QWidget* event_target)
|
||||||
: QWidget(NULL),
|
: QWidget(NULL),
|
||||||
desktop_(qApp->desktop()),
|
desktop_(qApp->desktop()),
|
||||||
event_target_(event_target)
|
event_target_(event_target)
|
||||||
@ -43,16 +43,6 @@ GlobalSearchTooltip::GlobalSearchTooltip(QObject* event_target)
|
|||||||
setFocusPolicy(Qt::NoFocus);
|
setFocusPolicy(Qt::NoFocus);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
setAttribute(Qt::WA_TranslucentBackground);
|
setAttribute(Qt::WA_TranslucentBackground);
|
||||||
|
|
||||||
add_ = new QAction(tr("Add to playlist"), this);
|
|
||||||
add_and_play_ = new QAction(tr("Add and play now"), this);
|
|
||||||
add_and_queue_ = new QAction(tr("Queue track"), this);
|
|
||||||
replace_ = new QAction(tr("Replace current playlist"), this);
|
|
||||||
|
|
||||||
add_->setShortcut(QKeySequence(Qt::Key_Return));
|
|
||||||
add_and_play_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Return));
|
|
||||||
add_and_queue_->setShortcut(QKeySequence(Qt::SHIFT | Qt::Key_Return));
|
|
||||||
replace_->setShortcut(QKeySequence(Qt::ALT | Qt::Key_Return));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalSearchTooltip::SetResults(const SearchProvider::ResultList& results) {
|
void GlobalSearchTooltip::SetResults(const SearchProvider::ResultList& results) {
|
||||||
@ -73,7 +63,7 @@ void GlobalSearchTooltip::SetResults(const SearchProvider::ResultList& results)
|
|||||||
|
|
||||||
// Add the action widget
|
// Add the action widget
|
||||||
QList<QAction*> actions;
|
QList<QAction*> actions;
|
||||||
actions << add_ << add_and_play_ << add_and_queue_ << replace_;
|
actions.append(common_actions_);
|
||||||
|
|
||||||
action_widget_ = new TooltipActionWidget(this);
|
action_widget_ = new TooltipActionWidget(this);
|
||||||
action_widget_->SetActions(actions);
|
action_widget_->SetActions(actions);
|
||||||
@ -119,14 +109,42 @@ void GlobalSearchTooltip::ShowAt(const QPoint& pointing_to) {
|
|||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalSearchTooltip::keyPressEvent(QKeyEvent* e) {
|
bool GlobalSearchTooltip::event(QEvent* e) {
|
||||||
// Copy the event to send to the target
|
switch (e->type()) {
|
||||||
QKeyEvent copy(e->type(), e->key(), e->modifiers(), e->text(),
|
case QEvent::KeyPress:
|
||||||
e->isAutoRepeat(), e->count());
|
case QEvent::KeyRelease:
|
||||||
|
case QEvent::InputMethod:
|
||||||
|
case QEvent::Shortcut:
|
||||||
|
case QEvent::ShortcutOverride:
|
||||||
|
if (QApplication::sendEvent(event_target_, e)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
qApp->sendEvent(event_target_, ©);
|
case QEvent::MouseButtonPress:
|
||||||
|
case QEvent::MouseButtonRelease:
|
||||||
|
case QEvent::MouseButtonDblClick:
|
||||||
|
if (!underMouse()) {
|
||||||
|
QMouseEvent* me = static_cast<QMouseEvent*>(e);
|
||||||
|
QMouseEvent c(me->type(), event_target_->mapFromGlobal(me->globalPos()),
|
||||||
|
me->globalPos(), me->button(),
|
||||||
|
me->buttons(), me->modifiers());
|
||||||
|
|
||||||
e->accept();
|
QWidget* child = event_target_->childAt(c.pos());
|
||||||
|
|
||||||
|
if (child)
|
||||||
|
child->setAttribute(Qt::WA_UnderMouse, true);
|
||||||
|
|
||||||
|
QApplication::sendEvent(child ? child : event_target_, &c);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QWidget::event(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalSearchTooltip::paintEvent(QPaintEvent*) {
|
void GlobalSearchTooltip::paintEvent(QPaintEvent*) {
|
||||||
|
@ -30,20 +30,22 @@ class GlobalSearchTooltip : public QWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GlobalSearchTooltip(QObject* event_target);
|
GlobalSearchTooltip(QWidget* event_target);
|
||||||
|
|
||||||
static const qreal kBorderRadius;
|
static const qreal kBorderRadius;
|
||||||
static const qreal kBorderWidth;
|
static const qreal kBorderWidth;
|
||||||
static const qreal kArrowWidth;
|
static const qreal kArrowWidth;
|
||||||
static const qreal kArrowHeight;
|
static const qreal kArrowHeight;
|
||||||
|
|
||||||
|
void SetActions(const QList<QAction*>& actions) { common_actions_ = actions; }
|
||||||
void SetResults(const SearchProvider::ResultList& results);
|
void SetResults(const SearchProvider::ResultList& results);
|
||||||
void ShowAt(const QPoint& pointing_to);
|
void ShowAt(const QPoint& pointing_to);
|
||||||
|
|
||||||
qreal ArrowOffset() const;
|
qreal ArrowOffset() const;
|
||||||
|
|
||||||
|
bool event(QEvent* e);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void keyPressEvent(QKeyEvent* e);
|
|
||||||
void paintEvent(QPaintEvent*);
|
void paintEvent(QPaintEvent*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -51,18 +53,14 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QDesktopWidget* desktop_;
|
QDesktopWidget* desktop_;
|
||||||
|
|
||||||
QAction* add_;
|
|
||||||
QAction* add_and_play_;
|
|
||||||
QAction* add_and_queue_;
|
|
||||||
QAction* replace_;
|
|
||||||
TooltipActionWidget* action_widget_;
|
TooltipActionWidget* action_widget_;
|
||||||
|
QList<QAction*> common_actions_;
|
||||||
|
|
||||||
SearchProvider::ResultList results_;
|
SearchProvider::ResultList results_;
|
||||||
qreal arrow_offset_;
|
qreal arrow_offset_;
|
||||||
QRect inner_rect_;
|
QRect inner_rect_;
|
||||||
|
|
||||||
QObject* event_target_;
|
QWidget* event_target_;
|
||||||
|
|
||||||
QWidgetList widgets_;
|
QWidgetList widgets_;
|
||||||
};
|
};
|
||||||
|
@ -82,6 +82,24 @@ GlobalSearchWidget::GlobalSearchWidget(QWidget* parent)
|
|||||||
|
|
||||||
ui_->search->installEventFilter(this);
|
ui_->search->installEventFilter(this);
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
add_ = new QAction(tr("Add to playlist"), this);
|
||||||
|
add_and_play_ = new QAction(tr("Add and play now"), this);
|
||||||
|
add_and_queue_ = new QAction(tr("Queue track"), this);
|
||||||
|
replace_ = new QAction(tr("Replace current playlist"), this);
|
||||||
|
|
||||||
|
add_->setShortcut(QKeySequence(Qt::Key_Return));
|
||||||
|
add_and_play_->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Return));
|
||||||
|
add_and_queue_->setShortcut(QKeySequence(Qt::SHIFT | Qt::Key_Return));
|
||||||
|
replace_->setShortcut(QKeySequence(Qt::ALT | Qt::Key_Return));
|
||||||
|
|
||||||
|
connect(add_, SIGNAL(triggered()), SLOT(AddCurrent()));
|
||||||
|
connect(add_and_play_, SIGNAL(triggered()), SLOT(AddAndPlayCurrent()));
|
||||||
|
connect(add_and_queue_, SIGNAL(triggered()), SLOT(AddAndQueueCurrent()));
|
||||||
|
connect(replace_, SIGNAL(triggered()), SLOT(ReplaceCurrent()));
|
||||||
|
|
||||||
|
actions_ << add_ << add_and_play_ << add_and_queue_ << replace_;
|
||||||
|
|
||||||
// Load style sheets
|
// Load style sheets
|
||||||
StyleSheetLoader* style_loader = new StyleSheetLoader(this);
|
StyleSheetLoader* style_loader = new StyleSheetLoader(this);
|
||||||
style_loader->SetStyleSheet(this, ":globalsearch.css");
|
style_loader->SetStyleSheet(this, ":globalsearch.css");
|
||||||
@ -89,10 +107,13 @@ GlobalSearchWidget::GlobalSearchWidget(QWidget* parent)
|
|||||||
connect(ui_->search, SIGNAL(textEdited(QString)), SLOT(TextEdited(QString)));
|
connect(ui_->search, SIGNAL(textEdited(QString)), SLOT(TextEdited(QString)));
|
||||||
connect(engine_, SIGNAL(ResultsAvailable(int,SearchProvider::ResultList)),
|
connect(engine_, SIGNAL(ResultsAvailable(int,SearchProvider::ResultList)),
|
||||||
SLOT(AddResults(int,SearchProvider::ResultList)));
|
SLOT(AddResults(int,SearchProvider::ResultList)));
|
||||||
connect(engine_, SIGNAL(SearchFinished(int)), SLOT(SearchFinished(int)));
|
connect(engine_, SIGNAL(SearchFinished(int)), SLOT(SearchFinished(int)),
|
||||||
connect(engine_, SIGNAL(ArtLoaded(int,QPixmap)), SLOT(ArtLoaded(int,QPixmap)));
|
Qt::QueuedConnection);
|
||||||
connect(engine_, SIGNAL(TracksLoaded(int,MimeData*)), SLOT(TracksLoaded(int,MimeData*)));
|
connect(engine_, SIGNAL(ArtLoaded(int,QPixmap)), SLOT(ArtLoaded(int,QPixmap)),
|
||||||
connect(view_, SIGNAL(doubleClicked(QModelIndex)), SLOT(AddCurrent()));
|
Qt::QueuedConnection);
|
||||||
|
connect(engine_, SIGNAL(TracksLoaded(int,MimeData*)), SLOT(TracksLoaded(int,MimeData*)),
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(view_, SIGNAL(doubleClicked(QModelIndex)), SLOT(ResultDoubleClicked()));
|
||||||
connect(view_->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
connect(view_->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
||||||
SLOT(UpdateTooltip()));
|
SLOT(UpdateTooltip()));
|
||||||
}
|
}
|
||||||
@ -358,9 +379,15 @@ bool GlobalSearchWidget::EventFilterPopup(QObject*, QEvent* e) {
|
|||||||
switch (key) {
|
switch (key) {
|
||||||
case Qt::Key_Return:
|
case Qt::Key_Return:
|
||||||
case Qt::Key_Enter:
|
case Qt::Key_Enter:
|
||||||
case Qt::Key_Tab:
|
// Handle the QActions here - they don't activate when the tooltip is showing
|
||||||
HidePopup();
|
if (ke->modifiers() & Qt::AltModifier)
|
||||||
AddCurrent();
|
replace_->trigger();
|
||||||
|
else if (ke->modifiers() & Qt::ControlModifier)
|
||||||
|
add_and_play_->trigger();
|
||||||
|
else if (ke->modifiers() & Qt::ShiftModifier)
|
||||||
|
add_and_queue_->trigger();
|
||||||
|
else
|
||||||
|
add_->trigger();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_F4:
|
case Qt::Key_F4:
|
||||||
@ -427,7 +454,27 @@ void GlobalSearchWidget::ArtLoaded(int id, const QPixmap& pixmap) {
|
|||||||
model_->itemFromIndex(index)->setData(pixmap, Qt::DecorationRole);
|
model_->itemFromIndex(index)->setData(pixmap, Qt::DecorationRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GlobalSearchWidget::ResultDoubleClicked() {
|
||||||
|
LoadTracks(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void GlobalSearchWidget::AddCurrent() {
|
void GlobalSearchWidget::AddCurrent() {
|
||||||
|
LoadTracks(add_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalSearchWidget::AddAndPlayCurrent() {
|
||||||
|
LoadTracks(add_and_play_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalSearchWidget::AddAndQueueCurrent() {
|
||||||
|
LoadTracks(add_and_queue_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalSearchWidget::ReplaceCurrent() {
|
||||||
|
LoadTracks(replace_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalSearchWidget::LoadTracks(QAction* trigger) {
|
||||||
QModelIndex index = view_->currentIndex();
|
QModelIndex index = view_->currentIndex();
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
index = proxy_->index(0, 0);
|
index = proxy_->index(0, 0);
|
||||||
@ -435,16 +482,31 @@ void GlobalSearchWidget::AddCurrent() {
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
engine_->LoadTracksAsync(index.data(Role_PrimaryResult).value<SearchProvider::Result>());
|
int id = engine_->LoadTracksAsync(
|
||||||
|
index.data(Role_PrimaryResult).value<SearchProvider::Result>());
|
||||||
|
track_requests_[id] = trigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalSearchWidget::TracksLoaded(int id, MimeData* mime_data) {
|
void GlobalSearchWidget::TracksLoaded(int id, MimeData* mime_data) {
|
||||||
Q_UNUSED(id);
|
if (!track_requests_.contains(id))
|
||||||
|
return;
|
||||||
|
|
||||||
|
QAction* trigger = track_requests_.take(id);
|
||||||
|
|
||||||
if (!mime_data)
|
if (!mime_data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mime_data->from_doubleclick_ = true;
|
if (trigger == NULL) {
|
||||||
|
mime_data->from_doubleclick_ = true;
|
||||||
|
} else if (trigger == add_) {
|
||||||
|
} else if (trigger == add_and_play_) {
|
||||||
|
mime_data->play_now_ = true;
|
||||||
|
} else if (trigger == add_and_queue_) {
|
||||||
|
mime_data->enqueue_now_ = true;
|
||||||
|
} else if (trigger == replace_) {
|
||||||
|
mime_data->clear_first_= true;
|
||||||
|
}
|
||||||
|
|
||||||
emit AddToPlaylist(mime_data);
|
emit AddToPlaylist(mime_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,6 +590,7 @@ void GlobalSearchWidget::UpdateTooltip() {
|
|||||||
tooltip_.reset(new GlobalSearchTooltip(view_));
|
tooltip_.reset(new GlobalSearchTooltip(view_));
|
||||||
tooltip_->setFont(view_->font());
|
tooltip_->setFont(view_->font());
|
||||||
tooltip_->setPalette(view_->palette());
|
tooltip_->setPalette(view_->palette());
|
||||||
|
tooltip_->SetActions(actions_);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QRect item_rect = view_->visualRect(current);
|
const QRect item_rect = view_->visualRect(current);
|
||||||
|
@ -81,7 +81,11 @@ private slots:
|
|||||||
|
|
||||||
void TracksLoaded(int id, MimeData* mime_data);
|
void TracksLoaded(int id, MimeData* mime_data);
|
||||||
|
|
||||||
|
void ResultDoubleClicked();
|
||||||
void AddCurrent();
|
void AddCurrent();
|
||||||
|
void AddAndPlayCurrent();
|
||||||
|
void AddAndQueueCurrent();
|
||||||
|
void ReplaceCurrent();
|
||||||
|
|
||||||
void HidePopup();
|
void HidePopup();
|
||||||
void UpdateTooltip();
|
void UpdateTooltip();
|
||||||
@ -102,6 +106,8 @@ private:
|
|||||||
bool EventFilterSearchWidget(QObject* o, QEvent* e);
|
bool EventFilterSearchWidget(QObject* o, QEvent* e);
|
||||||
bool EventFilterPopup(QObject* o, QEvent* e);
|
bool EventFilterPopup(QObject* o, QEvent* e);
|
||||||
|
|
||||||
|
void LoadTracks(QAction* trigger);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui_GlobalSearchWidget* ui_;
|
Ui_GlobalSearchWidget* ui_;
|
||||||
|
|
||||||
@ -110,6 +116,7 @@ private:
|
|||||||
bool clear_model_on_next_result_;
|
bool clear_model_on_next_result_;
|
||||||
|
|
||||||
QMap<int, QModelIndex> art_requests_;
|
QMap<int, QModelIndex> art_requests_;
|
||||||
|
QMap<int, QAction*> track_requests_;
|
||||||
|
|
||||||
QStandardItemModel* model_;
|
QStandardItemModel* model_;
|
||||||
QSortFilterProxyModel* proxy_;
|
QSortFilterProxyModel* proxy_;
|
||||||
@ -125,6 +132,12 @@ private:
|
|||||||
QStringList provider_order_;
|
QStringList provider_order_;
|
||||||
|
|
||||||
QScopedPointer<GlobalSearchTooltip> tooltip_;
|
QScopedPointer<GlobalSearchTooltip> tooltip_;
|
||||||
|
|
||||||
|
QAction* add_;
|
||||||
|
QAction* add_and_play_;
|
||||||
|
QAction* add_and_queue_;
|
||||||
|
QAction* replace_;
|
||||||
|
QList<QAction*> actions_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GLOBALSEARCHWIDGET_H
|
#endif // GLOBALSEARCHWIDGET_H
|
||||||
|
@ -19,10 +19,13 @@
|
|||||||
#include "core/logging.h"
|
#include "core/logging.h"
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
#include <QMouseEvent>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
const int TooltipActionWidget::kBorder = 16;
|
const int TooltipActionWidget::kBorder = 16;
|
||||||
const int TooltipActionWidget::kSpacing = 6;
|
const int TooltipActionWidget::kSpacing = 6;
|
||||||
|
const int TooltipActionWidget::kTopPadding = 3;
|
||||||
|
const int TooltipActionWidget::kFadeDurationMsec = 200;
|
||||||
|
|
||||||
TooltipActionWidget::TooltipActionWidget(QWidget* parent)
|
TooltipActionWidget::TooltipActionWidget(QWidget* parent)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
@ -30,12 +33,14 @@ TooltipActionWidget::TooltipActionWidget(QWidget* parent)
|
|||||||
shortcut_width_(0),
|
shortcut_width_(0),
|
||||||
description_width_(0)
|
description_width_(0)
|
||||||
{
|
{
|
||||||
|
setMouseTracking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TooltipActionWidget::SetActions(QList<QAction*> actions) {
|
void TooltipActionWidget::SetActions(QList<QAction*> actions) {
|
||||||
actions_ = actions;
|
actions_ = actions;
|
||||||
|
action_opacities_.clear();
|
||||||
|
|
||||||
int h = 3 + kTextHeight * actions.count();
|
int h = kTopPadding + kTextHeight * actions.count();
|
||||||
shortcut_width_ = 0;
|
shortcut_width_ = 0;
|
||||||
description_width_ = 0;
|
description_width_ = 0;
|
||||||
|
|
||||||
@ -45,6 +50,10 @@ void TooltipActionWidget::SetActions(QList<QAction*> actions) {
|
|||||||
fontMetrics().width(action->shortcut().toString(QKeySequence::NativeText)));
|
fontMetrics().width(action->shortcut().toString(QKeySequence::NativeText)));
|
||||||
description_width_ =
|
description_width_ =
|
||||||
qMax(description_width_, fontMetrics().width(action->text()));
|
qMax(description_width_, fontMetrics().width(action->text()));
|
||||||
|
|
||||||
|
QTimeLine* timeline = new QTimeLine(kFadeDurationMsec, this);
|
||||||
|
connect(timeline, SIGNAL(valueChanged(qreal)), SLOT(update()));
|
||||||
|
action_opacities_ << timeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_hint_ = QSize(
|
size_hint_ = QSize(
|
||||||
@ -55,19 +64,22 @@ void TooltipActionWidget::SetActions(QList<QAction*> actions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TooltipActionWidget::paintEvent(QPaintEvent*) {
|
void TooltipActionWidget::paintEvent(QPaintEvent*) {
|
||||||
int y = 3;
|
int y = kTopPadding;
|
||||||
|
|
||||||
const qreal shortcut_opacity = 0.4;
|
|
||||||
const qreal description_opacity = 0.7;
|
|
||||||
|
|
||||||
QPainter p(this);
|
QPainter p(this);
|
||||||
p.setPen(palette().color(QPalette::Text));
|
p.setPen(palette().color(QPalette::Text));
|
||||||
|
|
||||||
foreach (const QAction* action, actions_) {
|
for (int i=0 ; i<actions_.count() ; ++i) {
|
||||||
|
const QAction* action = actions_[i];
|
||||||
|
const QTimeLine* timeline = action_opacities_[i];
|
||||||
|
|
||||||
const QRect shortcut_rect(kBorder, y, shortcut_width_, kTextHeight);
|
const QRect shortcut_rect(kBorder, y, shortcut_width_, kTextHeight);
|
||||||
const QRect description_rect(shortcut_rect.right() + kSpacing, y,
|
const QRect description_rect(shortcut_rect.right() + kSpacing, y,
|
||||||
description_width_, kTextHeight);
|
description_width_, kTextHeight);
|
||||||
|
|
||||||
|
const qreal shortcut_opacity = 0.4 + 0.3 * timeline->currentValue();
|
||||||
|
const qreal description_opacity = 0.7 + 0.3 * timeline->currentValue();
|
||||||
|
|
||||||
p.setOpacity(shortcut_opacity);
|
p.setOpacity(shortcut_opacity);
|
||||||
p.drawText(shortcut_rect, Qt::AlignRight | Qt::AlignVCenter,
|
p.drawText(shortcut_rect, Qt::AlignRight | Qt::AlignVCenter,
|
||||||
action->shortcut().toString(QKeySequence::NativeText));
|
action->shortcut().toString(QKeySequence::NativeText));
|
||||||
@ -79,6 +91,40 @@ void TooltipActionWidget::paintEvent(QPaintEvent*) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TooltipActionWidget::mousePressEvent(QMouseEvent* e) {
|
int TooltipActionWidget::ActionAt(const QPoint& pos) const {
|
||||||
|
return (pos.y() - kTopPadding) / kTextHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TooltipActionWidget::mouseMoveEvent(QMouseEvent* e) {
|
||||||
|
const int action = ActionAt(e->pos());
|
||||||
|
|
||||||
|
for (int i=0 ; i<actions_.count() ; ++i) {
|
||||||
|
if (i == action) {
|
||||||
|
StartAnimation(i, QTimeLine::Forward);
|
||||||
|
} else {
|
||||||
|
StartAnimation(i, QTimeLine::Backward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TooltipActionWidget::leaveEvent(QEvent* e) {
|
||||||
|
for (int i=0 ; i<actions_.count() ; ++i) {
|
||||||
|
StartAnimation(i, QTimeLine::Backward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TooltipActionWidget::StartAnimation(int i, QTimeLine::Direction direction) {
|
||||||
|
QTimeLine* timeline = action_opacities_[i];
|
||||||
|
if (timeline->direction() != direction) {
|
||||||
|
timeline->setDirection(direction);
|
||||||
|
if (timeline->state() != QTimeLine::Running)
|
||||||
|
timeline->resume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TooltipActionWidget::mousePressEvent(QMouseEvent* e) {
|
||||||
|
const int action = ActionAt(e->pos());
|
||||||
|
if (action >= 0 && action < actions_.count()) {
|
||||||
|
actions_[action]->trigger();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,10 @@
|
|||||||
#ifndef TOOLTIPACTIONWIDGET_H
|
#ifndef TOOLTIPACTIONWIDGET_H
|
||||||
#define TOOLTIPACTIONWIDGET_H
|
#define TOOLTIPACTIONWIDGET_H
|
||||||
|
|
||||||
|
#include <QTimeLine>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
|
||||||
class TooltipActionWidget : public QWidget {
|
class TooltipActionWidget : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -28,6 +30,8 @@ public:
|
|||||||
|
|
||||||
static const int kBorder;
|
static const int kBorder;
|
||||||
static const int kSpacing;
|
static const int kSpacing;
|
||||||
|
static const int kTopPadding;
|
||||||
|
static const int kFadeDurationMsec;
|
||||||
|
|
||||||
void SetActions(QList<QAction*> actions);
|
void SetActions(QList<QAction*> actions);
|
||||||
|
|
||||||
@ -35,12 +39,20 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent*);
|
void paintEvent(QPaintEvent*);
|
||||||
|
void mouseMoveEvent(QMouseEvent* e);
|
||||||
|
void leaveEvent(QEvent* e);
|
||||||
void mousePressEvent(QMouseEvent* e);
|
void mousePressEvent(QMouseEvent* e);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int ActionAt(const QPoint& pos) const;
|
||||||
|
void StartAnimation(int i, QTimeLine::Direction direction);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int kTextHeight;
|
const int kTextHeight;
|
||||||
|
|
||||||
QList<QAction*> actions_;
|
QList<QAction*> actions_;
|
||||||
|
QList<QTimeLine*> action_opacities_;
|
||||||
|
|
||||||
QSize size_hint_;
|
QSize size_hint_;
|
||||||
int shortcut_width_;
|
int shortcut_width_;
|
||||||
int description_width_;
|
int description_width_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user