From: Peter Penz Date: Sat, 2 Feb 2008 20:53:35 +0000 (+0000) Subject: Improve the selection toggle: Instead of a delay of one second until appearing, let... X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/a50c7b6bd1a924425a1f165e3b910209f005b35a Improve the selection toggle: Instead of a delay of one second until appearing, let it appear immediately but provide a smooth fade-in effect. This makes it usable from the start but is less obtrusive for the eyes. svn path=/trunk/KDE/kdebase/apps/; revision=770115 --- diff --git a/src/selectionmanager.cpp b/src/selectionmanager.cpp index bdb4c5368..f79e1ada0 100644 --- a/src/selectionmanager.cpp +++ b/src/selectionmanager.cpp @@ -31,21 +31,21 @@ #include #include #include +#include SelectionManager::SelectionManager(QAbstractItemView* parent) : QObject(parent), m_view(parent), - m_button(0), - m_item() + m_toggle(0) { connect(parent, SIGNAL(entered(const QModelIndex&)), this, SLOT(slotEntered(const QModelIndex&))); connect(parent, SIGNAL(viewportEntered()), this, SLOT(slotViewportEntered())); - m_button = new SelectionToggle(m_view->viewport()); - m_button->setCheckable(true); - m_button->hide(); - connect(m_button, SIGNAL(clicked(bool)), + m_toggle = new SelectionToggle(m_view->viewport()); + m_toggle->setCheckable(true); + m_toggle->hide(); + connect(m_toggle, SIGNAL(clicked(bool)), this, SLOT(setItemSelected(bool))); } @@ -55,37 +55,36 @@ SelectionManager::~SelectionManager() void SelectionManager::reset() { - m_button->hide(); - m_item = KFileItem(); + m_toggle->reset(); } void SelectionManager::slotEntered(const QModelIndex& index) { - m_button->hide(); + m_toggle->hide(); if (index.isValid() && (index.column() == DolphinModel::Name)) { - m_item = itemForIndex(index); + m_toggle->setFileItem(itemForIndex(index)); connect(m_view->model(), SIGNAL(rowsRemoved(const QModelIndex&, int, int)), this, SLOT(slotRowsRemoved(const QModelIndex&, int, int))); const QRect rect = m_view->visualRect(index); const int gap = 2; - const int x = rect.right() - m_button->width() - gap; + const int x = rect.right() - m_toggle->width() - gap; int y = rect.top(); - if (rect.height() <= m_button->height() * 2) { + if (rect.height() <= m_toggle->height() * 2) { // center the button vertically - y += (rect.height() - m_button->height()) / 2; + y += (rect.height() - m_toggle->height()) / 2; } else { y += gap; } - m_button->move(QPoint(x, y)); + m_toggle->move(QPoint(x, y)); QItemSelectionModel* selModel = m_view->selectionModel(); - m_button->setChecked(selModel->isSelected(index)); - m_button->show(); + m_toggle->setChecked(selModel->isSelected(index)); + m_toggle->show(); } else { - m_item = KFileItem(); + m_toggle->setFileItem(KFileItem()); disconnect(m_view->model(), SIGNAL(rowsRemoved(const QModelIndex&, int, int)), this, SLOT(slotRowsRemoved(const QModelIndex&, int, int))); } @@ -93,15 +92,15 @@ void SelectionManager::slotEntered(const QModelIndex& index) void SelectionManager::slotViewportEntered() { - m_button->hide(); + m_toggle->hide(); } void SelectionManager::setItemSelected(bool selected) { emit selectionChanged(); - Q_ASSERT(!m_item.isNull()); + Q_ASSERT(!m_toggle->fileItem().isNull()); - const QModelIndex index = indexForItem(m_item); + const QModelIndex index = indexForItem(m_toggle->fileItem()); if (index.isValid()) { QItemSelectionModel* selModel = m_view->selectionModel(); if (selected) { @@ -117,7 +116,7 @@ void SelectionManager::slotRowsRemoved(const QModelIndex& parent, int start, int Q_UNUSED(parent); Q_UNUSED(start); Q_UNUSED(end); - m_button->hide(); + m_toggle->hide(); } KFileItem SelectionManager::itemForIndex(const QModelIndex& index) const diff --git a/src/selectionmanager.h b/src/selectionmanager.h index fcc240ff9..04e6e29c1 100644 --- a/src/selectionmanager.h +++ b/src/selectionmanager.h @@ -28,6 +28,7 @@ class DolphinSortFilterProxyModel; class QAbstractItemView; class QModelIndex; class QAbstractButton; +class SelectionToggle; /** * @brief Allows to select and deselect items for the single-click mode. @@ -66,8 +67,7 @@ private: private: QAbstractItemView* m_view; - QAbstractButton* m_button; - KFileItem m_item; + SelectionToggle* m_toggle; }; #endif diff --git a/src/selectiontoggle.cpp b/src/selectiontoggle.cpp index 244f51583..7a3f0ef56 100644 --- a/src/selectiontoggle.cpp +++ b/src/selectiontoggle.cpp @@ -27,24 +27,20 @@ #include #include #include - -#include +#include SelectionToggle::SelectionToggle(QWidget* parent) : QAbstractButton(parent), - m_showIcon(false), m_isHovered(false), + m_fadingValue(0), m_icon(), - m_timer(0) + m_fadingTimeLine(0) { parent->installEventFilter(this); resize(sizeHint()); m_icon = KIconLoader::global()->loadIcon("dialog-ok", KIconLoader::NoGroup, KIconLoader::SizeSmall); - m_timer = new QTimer(this); - connect(m_timer, SIGNAL(timeout()), - this, SLOT(showIcon())); } SelectionToggle::~SelectionToggle() @@ -56,15 +52,34 @@ QSize SelectionToggle::sizeHint() const return QSize(16, 16); } +void SelectionToggle::reset() +{ + m_item = KFileItem(); + hide(); +} + +void SelectionToggle::setFileItem(const KFileItem& item) +{ + m_item = item; + if (!item.isNull()) { + startFading(); + } +} + +KFileItem SelectionToggle::fileItem() const +{ + return m_item; +} + void SelectionToggle::setVisible(bool visible) { QAbstractButton::setVisible(visible); + + stopFading(); if (visible) { - m_timer->start(1000); - } else { - m_timer->stop(); - m_showIcon = false; + startFading(); } + } bool SelectionToggle::eventFilter(QObject* obj, QEvent* event) @@ -78,8 +93,14 @@ bool SelectionToggle::eventFilter(QObject* obj, QEvent* event) void SelectionToggle::enterEvent(QEvent* event) { QAbstractButton::enterEvent(event); + + // if the mouse cursor is above the selection toggle, display + // it immediately without fading timer m_isHovered = true; - m_showIcon = true; + if (m_fadingTimeLine != 0) { + m_fadingTimeLine->stop(); + } + m_fadingValue = 255; update(); } @@ -99,15 +120,52 @@ void SelectionToggle::paintEvent(QPaintEvent* event) KIconEffect iconEffect; QPixmap activeIcon = iconEffect.apply(m_icon, KIconLoader::Desktop, KIconLoader::ActiveState); painter.drawPixmap(0, 0, activeIcon); - } else if (m_showIcon) { - painter.drawPixmap(0, 0, m_icon); + } else { + if (m_fadingValue < 255) { + // apply an alpha mask respecting the fading value to the icon + QPixmap icon = m_icon; + QPixmap alphaMask(icon.width(), icon.height()); + const QColor color(m_fadingValue, m_fadingValue, m_fadingValue); + alphaMask.fill(color); + icon.setAlphaChannel(alphaMask); + painter.drawPixmap(0, 0, icon); + } else { + // no fading is required + painter.drawPixmap(0, 0, m_icon); + } } } -void SelectionToggle::showIcon() +void SelectionToggle::setFadingValue(int value) { - m_showIcon = true; + m_fadingValue = value; + if (m_fadingValue >= 255) { + Q_ASSERT(m_fadingTimeLine != 0); + m_fadingTimeLine->stop(); + } update(); } +void SelectionToggle::startFading() +{ + Q_ASSERT(m_fadingTimeLine == 0); + + m_fadingTimeLine = new QTimeLine(2000, this); + connect(m_fadingTimeLine, SIGNAL(frameChanged(int)), + this, SLOT(setFadingValue(int))); + m_fadingTimeLine->setFrameRange(0, 255); + m_fadingTimeLine->start(); + m_fadingValue = 0; +} + +void SelectionToggle::stopFading() +{ + if (m_fadingTimeLine != 0) { + m_fadingTimeLine->stop(); + delete m_fadingTimeLine; + m_fadingTimeLine = 0; + } + m_fadingValue = 0; +} + #include "selectiontoggle.moc" diff --git a/src/selectiontoggle.h b/src/selectiontoggle.h index 5815c5dae..653104ab5 100644 --- a/src/selectiontoggle.h +++ b/src/selectiontoggle.h @@ -20,12 +20,19 @@ #ifndef SELECTIONTOGGLE_H #define SELECTIONTOGGLE_H +#include + #include #include -#include + +class QTimeLine; /** * @brief Toggle button for changing the selection of an hovered item. + * + * The toggle button is visually invisible until it is displayed at least + * for one second. + * * @see SelectionManager */ class SelectionToggle : public QAbstractButton @@ -37,6 +44,15 @@ public: virtual ~SelectionToggle(); virtual QSize sizeHint() const; + /** + * Resets the selection toggle so that it is hidden and stays + * visually invisible for at least one second after it is shown again. + */ + void reset(); + + void setFileItem(const KFileItem& item); + KFileItem fileItem() const; + public slots: virtual void setVisible(bool visible); @@ -47,13 +63,22 @@ protected: virtual void paintEvent(QPaintEvent* event); private slots: - void showIcon(); + /** + * Sets the alpha value for the fading animation and is + * connected with m_fadingTimeLine. + */ + void setFadingValue(int value); + +private: + void startFading(); + void stopFading(); private: - bool m_showIcon; bool m_isHovered; + int m_fadingValue; QPixmap m_icon; - QTimer* m_timer; + QTimeLine* m_fadingTimeLine; + KFileItem m_item; }; #endif