mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-26 23:28:14 +03:00
Make ActivityItemDelegate background- and selection-aware (Dark-/Light-Mode switching)
Also implement cached member icons in ActivityListModel and return their enums to ActivityItemDelegate instead of always recreating them for each call to paint(). Signed-off-by: Michael Schuster <michael@schuster.ms>
This commit is contained in:
parent
bf0bf2c1b6
commit
ecd17f2ea2
4 changed files with 122 additions and 18 deletions
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "activityitemdelegate.h"
|
||||
#include "activitylistmodel.h"
|
||||
#include "folderstatusmodel.h"
|
||||
#include "folderman.h"
|
||||
#include "accountstate.h"
|
||||
|
@ -40,6 +41,12 @@ int ActivityItemDelegate::_buttonHeight = 0;
|
|||
const QString ActivityItemDelegate::_remote_share("remote_share");
|
||||
const QString ActivityItemDelegate::_call("call");
|
||||
|
||||
ActivityItemDelegate::ActivityItemDelegate()
|
||||
: QStyledItemDelegate()
|
||||
{
|
||||
customizeStyle();
|
||||
}
|
||||
|
||||
int ActivityItemDelegate::iconHeight()
|
||||
{
|
||||
if (_iconHeight == 0) {
|
||||
|
@ -89,10 +96,21 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
|||
int iconSize = 16;
|
||||
int iconOffset = qRound(fm.height() / 4.0 * 7.0);
|
||||
int offset = 4;
|
||||
const bool isSelected = (option.state & QStyle::State_Selected);
|
||||
|
||||
// get the data
|
||||
Activity::Type activityType = qvariant_cast<Activity::Type>(index.data(ActionRole));
|
||||
QIcon actionIcon = qvariant_cast<QIcon>(index.data(ActionIconRole));
|
||||
QIcon actionIcon;
|
||||
const ActivityListModel::ActionIcon icn = qvariant_cast<ActivityListModel::ActionIcon>(index.data(ActionIconRole));
|
||||
switch(icn.iconType) {
|
||||
case ActivityListModel::ActivityIconType::iconUseCached: actionIcon = icn.cachedIcon; break;
|
||||
case ActivityListModel::ActivityIconType::iconActivity: actionIcon = (isSelected ? _iconActivity_sel : _iconActivity); break;
|
||||
case ActivityListModel::ActivityIconType::iconBell: actionIcon = (isSelected ? _iconBell_sel : _iconBell); break;
|
||||
case ActivityListModel::ActivityIconType::iconStateError: actionIcon = _iconStateError; break;
|
||||
case ActivityListModel::ActivityIconType::iconStateWarning: actionIcon = _iconStateWarning; break;
|
||||
case ActivityListModel::ActivityIconType::iconStateInfo: actionIcon = _iconStateInfo; break;
|
||||
case ActivityListModel::ActivityIconType::iconStateSync: actionIcon = _iconStateSync; break;
|
||||
}
|
||||
QString objectType = qvariant_cast<QString>(index.data(ObjectTypeRole));
|
||||
QString actionText = qvariant_cast<QString>(index.data(ActionTextRole));
|
||||
QString messageText = qvariant_cast<QString>(index.data(MessageRole));
|
||||
|
@ -184,9 +202,9 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
|||
if(activityType == Activity::Type::NotificationType){
|
||||
|
||||
// Secondary will be 'Dismiss' or '...' multiple options button
|
||||
secondaryButton.icon = QIcon(QLatin1String(":/client/resources/close.svg"));
|
||||
secondaryButton.icon = (isSelected ? _iconClose_sel : _iconClose);
|
||||
if(customList.size() > 1)
|
||||
secondaryButton.icon = QIcon(QLatin1String(":/client/resources/more.svg"));
|
||||
secondaryButton.icon = (isSelected ? _iconMore_sel : _iconMore);
|
||||
secondaryButton.iconSize = QSize(iconSize, iconSize);
|
||||
|
||||
// Primary button will be 'More Information' or 'Accept'
|
||||
|
@ -209,7 +227,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
|||
} else if(activityType == Activity::SyncResultType){
|
||||
|
||||
// Secondary will be 'open file manager' with the folder icon
|
||||
secondaryButton.icon = QIcon(QLatin1String(":/client/resources/folder.svg"));
|
||||
secondaryButton.icon = _iconFolder;
|
||||
secondaryButton.iconSize = QSize(iconSize, iconSize);
|
||||
|
||||
// Primary button will be 'open browser'
|
||||
|
@ -230,7 +248,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
|||
} else if(activityType == Activity::SyncFileItemType){
|
||||
|
||||
// Secondary will be 'open file manager' with the folder icon
|
||||
secondaryButton.icon = QIcon(QLatin1String(":/client/resources/folder.svg"));
|
||||
secondaryButton.icon = _iconFolder;
|
||||
secondaryButton.iconSize = QSize(iconSize, iconSize);
|
||||
|
||||
// No primary button on this case
|
||||
|
@ -255,7 +273,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
|||
p.setCurrentColorGroup(QPalette::Disabled);
|
||||
|
||||
// change pen color if the line is selected
|
||||
if (option.state & QStyle::State_Selected)
|
||||
if (isSelected)
|
||||
painter->setPen(p.color(QPalette::HighlightedText));
|
||||
else
|
||||
painter->setPen(p.color(QPalette::Text));
|
||||
|
@ -269,8 +287,15 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
|||
painter->drawText(actionTextBox, elidedAction);
|
||||
|
||||
// draw the buttons
|
||||
if(activityType == Activity::Type::NotificationType || activityType == Activity::Type::SyncResultType)
|
||||
if(activityType == Activity::Type::NotificationType || activityType == Activity::Type::SyncResultType) {
|
||||
primaryButton.palette = p;
|
||||
if (isSelected)
|
||||
primaryButton.palette.setColor(QPalette::ButtonText, p.color(QPalette::HighlightedText));
|
||||
else
|
||||
primaryButton.palette.setColor(QPalette::ButtonText, p.color(QPalette::Text));
|
||||
|
||||
QApplication::style()->drawControl(QStyle::CE_PushButton, &primaryButton, painter);
|
||||
}
|
||||
|
||||
// Since they are errors on local syncing, there is nothing to do in the server
|
||||
if(activityType != Activity::Type::ActivityType)
|
||||
|
@ -284,7 +309,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
|||
}
|
||||
|
||||
// change pen color for the time
|
||||
if (option.state & QStyle::State_Selected)
|
||||
if (isSelected)
|
||||
painter->setPen(p.color(QPalette::Disabled, QPalette::HighlightedText));
|
||||
else
|
||||
painter->setPen(p.color(QPalette::Disabled, QPalette::Text));
|
||||
|
@ -333,4 +358,32 @@ bool ActivityItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
|||
return QStyledItemDelegate::editorEvent(event, model, option, index);
|
||||
}
|
||||
|
||||
void ActivityItemDelegate::slotStyleChanged()
|
||||
{
|
||||
customizeStyle();
|
||||
}
|
||||
|
||||
void ActivityItemDelegate::customizeStyle()
|
||||
{
|
||||
QPalette pal;
|
||||
pal.setColor(QPalette::Base, QColor(0,0,0)); // use dark background colour to invert icons
|
||||
|
||||
_iconClose = Theme::createColorAwareIcon(QLatin1String(":/client/resources/close.svg"));
|
||||
_iconClose_sel = Theme::createColorAwareIcon(QLatin1String(":/client/resources/close.svg"), pal);
|
||||
_iconMore = Theme::createColorAwareIcon(QLatin1String(":/client/resources/more.svg"));
|
||||
_iconMore_sel = Theme::createColorAwareIcon(QLatin1String(":/client/resources/more.svg"), pal);
|
||||
|
||||
_iconFolder = QIcon(QLatin1String(":/client/resources/folder.svg"));
|
||||
|
||||
_iconActivity = Theme::createColorAwareIcon(QLatin1String(":/client/resources/activity.png"));
|
||||
_iconActivity_sel = Theme::createColorAwareIcon(QLatin1String(":/client/resources/activity.png"), pal);
|
||||
_iconBell = Theme::createColorAwareIcon(QLatin1String(":/client/resources/bell.svg"));
|
||||
_iconBell_sel = Theme::createColorAwareIcon(QLatin1String(":/client/resources/bell.svg"), pal);
|
||||
|
||||
_iconStateError = QIcon(QLatin1String(":/client/resources/state-error.svg"));
|
||||
_iconStateWarning = QIcon(QLatin1String(":/client/resources/state-warning.svg"));
|
||||
_iconStateInfo = QIcon(QLatin1String(":/client/resources/state-info.svg"));
|
||||
_iconStateSync = QIcon(QLatin1String(":/client/resources/state-sync.svg"));
|
||||
}
|
||||
|
||||
} // namespace OCC
|
||||
|
|
|
@ -43,6 +43,8 @@ public:
|
|||
AccountConnectedRole,
|
||||
SyncFileStatusRole };
|
||||
|
||||
ActivityItemDelegate();
|
||||
|
||||
void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const override;
|
||||
QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const override;
|
||||
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
|
||||
|
@ -51,11 +53,16 @@ public:
|
|||
static int rowHeight();
|
||||
static int iconHeight();
|
||||
|
||||
public slots:
|
||||
void slotStyleChanged();
|
||||
|
||||
signals:
|
||||
void primaryButtonClickedOnItemView(const QModelIndex &index);
|
||||
void secondaryButtonClickedOnItemView(const QModelIndex &index);
|
||||
|
||||
private:
|
||||
void customizeStyle();
|
||||
|
||||
static int _margin;
|
||||
static int _iconHeight;
|
||||
static int _primaryButtonWidth;
|
||||
|
@ -65,6 +72,23 @@ private:
|
|||
static int _buttonHeight;
|
||||
static const QString _remote_share;
|
||||
static const QString _call;
|
||||
|
||||
QIcon _iconClose;
|
||||
QIcon _iconClose_sel;
|
||||
QIcon _iconMore;
|
||||
QIcon _iconMore_sel;
|
||||
|
||||
QIcon _iconFolder;
|
||||
|
||||
QIcon _iconActivity;
|
||||
QIcon _iconActivity_sel;
|
||||
QIcon _iconBell;
|
||||
QIcon _iconBell_sel;
|
||||
|
||||
QIcon _iconStateError;
|
||||
QIcon _iconStateWarning;
|
||||
QIcon _iconStateInfo;
|
||||
QIcon _iconStateSync;
|
||||
};
|
||||
|
||||
} // namespace OCC
|
||||
|
|
|
@ -79,31 +79,41 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
|||
}
|
||||
return customList;
|
||||
}
|
||||
case ActivityItemDelegate::ActionIconRole:
|
||||
case ActivityItemDelegate::ActionIconRole:{
|
||||
ActionIcon actionIcon;
|
||||
if(a._type == Activity::NotificationType){
|
||||
QIcon cachedIcon = ServerNotificationHandler::iconCache.value(a._id);
|
||||
if(!cachedIcon.isNull())
|
||||
return cachedIcon;
|
||||
else return QIcon(QLatin1String(":/client/resources/bell.svg"));
|
||||
if(!cachedIcon.isNull()) {
|
||||
actionIcon.iconType = ActivityIconType::iconUseCached;
|
||||
actionIcon.cachedIcon = cachedIcon;
|
||||
} else {
|
||||
actionIcon.iconType = ActivityIconType::iconBell;
|
||||
}
|
||||
} else if(a._type == Activity::SyncResultType){
|
||||
return QIcon(QLatin1String(":/client/resources/state-error.svg"));
|
||||
actionIcon.iconType = ActivityIconType::iconStateError;
|
||||
} else if(a._type == Activity::SyncFileItemType){
|
||||
if(a._status == SyncFileItem::NormalError
|
||||
|| a._status == SyncFileItem::FatalError
|
||||
|| a._status == SyncFileItem::DetailError
|
||||
|| a._status == SyncFileItem::BlacklistedError) {
|
||||
return QIcon(QLatin1String(":/client/resources/state-error.svg"));
|
||||
actionIcon.iconType = ActivityIconType::iconStateError;
|
||||
} else if(a._status == SyncFileItem::SoftError
|
||||
|| a._status == SyncFileItem::Conflict
|
||||
|| a._status == SyncFileItem::Restoration
|
||||
|| a._status == SyncFileItem::FileLocked){
|
||||
return QIcon(QLatin1String(":/client/resources/state-warning.svg"));
|
||||
actionIcon.iconType = ActivityIconType::iconStateWarning;
|
||||
} else if(a._status == SyncFileItem::FileIgnored){
|
||||
return QIcon(QLatin1String(":/client/resources/state-info.svg"));
|
||||
actionIcon.iconType = ActivityIconType::iconStateInfo;
|
||||
} else {
|
||||
actionIcon.iconType = ActivityIconType::iconStateSync;
|
||||
}
|
||||
return QIcon(QLatin1String(":/client/resources/state-sync.svg"));
|
||||
} else {
|
||||
actionIcon.iconType = ActivityIconType::iconActivity;
|
||||
}
|
||||
QVariant icn;
|
||||
icn.setValue(actionIcon);
|
||||
return icn;
|
||||
}
|
||||
return QIcon(QLatin1String(":/client/resources/activity.png"));
|
||||
break;
|
||||
case ActivityItemDelegate::ObjectTypeRole:
|
||||
return a._objectType;
|
||||
|
|
|
@ -38,6 +38,20 @@ class ActivityListModel : public QAbstractListModel
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ActivityIconType {
|
||||
iconUseCached = 0,
|
||||
iconActivity,
|
||||
iconBell,
|
||||
iconStateError,
|
||||
iconStateWarning,
|
||||
iconStateInfo,
|
||||
iconStateSync
|
||||
};
|
||||
struct ActionIcon {
|
||||
ActivityIconType iconType;
|
||||
QIcon cachedIcon;
|
||||
};
|
||||
|
||||
explicit ActivityListModel(AccountState *accountState, QWidget *parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
@ -84,4 +98,7 @@ private:
|
|||
int _currentItem = 0;
|
||||
};
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(OCC::ActivityListModel::ActionIcon);
|
||||
|
||||
#endif // ACTIVITYLISTMODEL_H
|
||||
|
|
Loading…
Reference in a new issue