Add focusOut and focusIn event support for KFileItemListView and update selected widget on focus change

This commit is contained in:
Méven Car 2023-09-02 11:30:25 +02:00
parent 012f8a224a
commit fae5fec964
10 changed files with 82 additions and 9 deletions

View file

@ -326,6 +326,31 @@ void KFileItemListView::resizeEvent(QGraphicsSceneResizeEvent *event)
triggerVisibleIndexRangeUpdate(); triggerVisibleIndexRangeUpdate();
} }
void KFileItemListView::focusInEvent(QFocusEvent *event)
{
Q_UNUSED(event)
updateSelectedWidgets();
}
void KFileItemListView::focusOutEvent(QFocusEvent *event)
{
Q_UNUSED(event)
updateSelectedWidgets();
}
void KFileItemListView::updateSelectedWidgets()
{
const auto visibleWidgets = visibleItemListWidgets();
for (KItemListWidget *widget : visibleWidgets) {
if (widget->isSelected()) {
auto w = qobject_cast<KFileItemListWidget *>(widget);
if (w) {
w->forceUpdate();
}
}
}
}
void KFileItemListView::slotItemsRemoved(const KItemRangeList &itemRanges) void KFileItemListView::slotItemsRemoved(const KItemRangeList &itemRanges)
{ {
KStandardItemListView::slotItemsRemoved(itemRanges); KStandardItemListView::slotItemsRemoved(itemRanges);

View file

@ -98,6 +98,8 @@ protected:
void onTransactionBegin() override; void onTransactionBegin() override;
void onTransactionEnd() override; void onTransactionEnd() override;
void resizeEvent(QGraphicsSceneResizeEvent *event) override; void resizeEvent(QGraphicsSceneResizeEvent *event) override;
void focusInEvent(QFocusEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;
protected Q_SLOTS: protected Q_SLOTS:
void slotItemsRemoved(const KItemRangeList &itemRanges) override; void slotItemsRemoved(const KItemRangeList &itemRanges) override;
@ -127,6 +129,8 @@ private:
QSize availableIconSize() const; QSize availableIconSize() const;
private: private:
void updateSelectedWidgets();
KFileItemModelRolesUpdater *m_modelRolesUpdater; KFileItemModelRolesUpdater *m_modelRolesUpdater;
QTimer *m_updateVisibleIndexRangeTimer; QTimer *m_updateVisibleIndexRangeTimer;
QTimer *m_updateIconSizeTimer; QTimer *m_updateIconSizeTimer;

View file

@ -203,6 +203,17 @@ void KFileItemListWidget::hoverSequenceStarted()
view->setHoverSequenceState(itemUrl, 0); view->setHoverSequenceState(itemUrl, 0);
} }
void KFileItemListWidget::forceUpdate()
{
updateAdditionalInfoTextColor();
// icon layout does not include the icons in the item selection rectangle
// so its icon does not need updating
if (listView()->itemLayout() != KStandardItemListView::ItemLayout::IconsLayout) {
invalidateIconCache();
}
update();
}
void KFileItemListWidget::hoverSequenceIndexChanged(int sequenceIndex) void KFileItemListWidget::hoverSequenceIndexChanged(int sequenceIndex)
{ {
KFileItemListView *view = listView(); KFileItemListView *view = listView();

View file

@ -35,6 +35,9 @@ public:
static KItemListWidgetInformant *createInformant(); static KItemListWidgetInformant *createInformant();
/// Force-update the displayed icon
void forceUpdate();
protected: protected:
virtual void hoverSequenceStarted() override; virtual void hoverSequenceStarted() override;
virtual void hoverSequenceIndexChanged(int sequenceIndex) override; virtual void hoverSequenceIndexChanged(int sequenceIndex) override;

View file

@ -175,6 +175,22 @@ void KItemListContainer::wheelEvent(QWheelEvent *event)
smoothScroller->handleWheelEvent(event); smoothScroller->handleWheelEvent(event);
} }
void KItemListContainer::focusInEvent(QFocusEvent *event)
{
KItemListView *view = m_controller->view();
if (view) {
QApplication::sendEvent(view, event);
}
}
void KItemListContainer::focusOutEvent(QFocusEvent *event)
{
KItemListView *view = m_controller->view();
if (view) {
QApplication::sendEvent(view, event);
}
}
void KItemListContainer::slotScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous) void KItemListContainer::slotScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous)
{ {
Q_UNUSED(previous) Q_UNUSED(previous)

View file

@ -50,6 +50,8 @@ protected:
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;
void scrollContentsBy(int dx, int dy) override; void scrollContentsBy(int dx, int dy) override;
void wheelEvent(QWheelEvent *event) override; void wheelEvent(QWheelEvent *event) override;
void focusInEvent(QFocusEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;
private Q_SLOTS: private Q_SLOTS:
void slotScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous); void slotScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous);

View file

@ -961,6 +961,18 @@ bool KItemListView::event(QEvent *event)
updateFont(); updateFont();
break; break;
case QEvent::FocusIn:
focusInEvent(static_cast<QFocusEvent *>(event));
event->accept();
return true;
break;
case QEvent::FocusOut:
focusOutEvent(static_cast<QFocusEvent *>(event));
event->accept();
return true;
break;
default: default:
// Forward all other events to the controller and handle them there // Forward all other events to the controller and handle them there
if (!m_editingRole && m_controller && m_controller->processEvent(event, transform())) { if (!m_editingRole && m_controller && m_controller->processEvent(event, transform())) {

View file

@ -115,12 +115,12 @@ void KItemListWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
drawItemStyleOption(painter, widget, activeState | QStyle::State_Enabled | QStyle::State_Selected | QStyle::State_Item); drawItemStyleOption(painter, widget, activeState | QStyle::State_Enabled | QStyle::State_Selected | QStyle::State_Item);
} }
if (m_current && m_editedRole.isEmpty() && widget->hasFocus()) { if (m_current && m_editedRole.isEmpty()) {
QStyleOptionFocusRect focusRectOption; QStyleOptionFocusRect focusRectOption;
initStyleOption(&focusRectOption); initStyleOption(&focusRectOption);
focusRectOption.rect = textFocusRect().toRect(); focusRectOption.rect = textFocusRect().toRect();
focusRectOption.state = QStyle::State_Enabled | QStyle::State_Item | QStyle::State_KeyboardFocusChange; focusRectOption.state = QStyle::State_Enabled | QStyle::State_Item | QStyle::State_KeyboardFocusChange;
if (m_selected) { if (m_selected && widget->hasFocus()) {
focusRectOption.state |= QStyle::State_Selected; focusRectOption.state |= QStyle::State_Selected;
} }

View file

@ -386,7 +386,7 @@ void KStandardItemListWidget::paint(QPainter *painter, const QStyleOptionGraphic
} }
painter->setFont(m_customizedFont); painter->setFont(m_customizedFont);
painter->setPen(textColor(widget)); painter->setPen(textColor(*widget));
const TextInfo *textInfo = m_textInfo.value("text"); const TextInfo *textInfo = m_textInfo.value("text");
if (!textInfo) { if (!textInfo) {
@ -645,7 +645,7 @@ void KStandardItemListWidget::setTextColor(const QColor &color)
} }
} }
QColor KStandardItemListWidget::textColor(QWidget *widget) const QColor KStandardItemListWidget::textColor(const QWidget &widget) const
{ {
if (!isSelected()) { if (!isSelected()) {
if (m_isHidden) { if (m_isHidden) {
@ -655,7 +655,7 @@ QColor KStandardItemListWidget::textColor(QWidget *widget) const
} }
} }
const QPalette::ColorGroup group = isActiveWindow() && widget->hasFocus() ? QPalette::Active : QPalette::Inactive; const QPalette::ColorGroup group = isActiveWindow() && widget.hasFocus() ? QPalette::Active : QPalette::Inactive;
const QPalette::ColorRole role = isSelected() ? QPalette::HighlightedText : normalTextColorRole(); const QPalette::ColorRole role = isSelected() ? QPalette::HighlightedText : normalTextColorRole();
return styleOption().palette.color(group, role); return styleOption().palette.color(group, role);
} }
@ -1436,9 +1436,10 @@ void KStandardItemListWidget::updateDetailsLayoutTextCache()
void KStandardItemListWidget::updateAdditionalInfoTextColor() void KStandardItemListWidget::updateAdditionalInfoTextColor()
{ {
QColor c1; QColor c1;
const bool hasFocus = scene()->views()[0]->parentWidget()->hasFocus();
if (m_customTextColor.isValid()) { if (m_customTextColor.isValid()) {
c1 = m_customTextColor; c1 = m_customTextColor;
} else if (isSelected() && (m_layout != DetailsLayout || m_highlightEntireRow)) { } else if (isSelected() && hasFocus && (m_layout != DetailsLayout || m_highlightEntireRow)) {
// The detail text colour needs to match the main text (HighlightedText) for the same level // The detail text colour needs to match the main text (HighlightedText) for the same level
// of readability. We short circuit early here to avoid interpolating with another colour. // of readability. We short circuit early here to avoid interpolating with another colour.
m_additionalInfoTextColor = styleOption().palette.color(QPalette::HighlightedText); m_additionalInfoTextColor = styleOption().palette.color(QPalette::HighlightedText);

View file

@ -139,7 +139,7 @@ protected:
virtual QPalette::ColorRole normalTextColorRole() const; virtual QPalette::ColorRole normalTextColorRole() const;
void setTextColor(const QColor &color); void setTextColor(const QColor &color);
QColor textColor(QWidget *widget) const; QColor textColor(const QWidget &widget) const;
void setOverlay(const QPixmap &overlay); void setOverlay(const QPixmap &overlay);
QPixmap overlay() const; QPixmap overlay() const;
@ -181,6 +181,7 @@ protected:
QPointF pos; QPointF pos;
QStaticText staticText; QStaticText staticText;
}; };
void updateAdditionalInfoTextColor();
public Q_SLOTS: public Q_SLOTS:
void finishRoleEditing(); void finishRoleEditing();
@ -200,8 +201,6 @@ private:
void updateCompactLayoutTextCache(); void updateCompactLayoutTextCache();
void updateDetailsLayoutTextCache(); void updateDetailsLayoutTextCache();
void updateAdditionalInfoTextColor();
void drawPixmap(QPainter *painter, const QPixmap &pixmap); void drawPixmap(QPainter *painter, const QPixmap &pixmap);
void drawSiblingsInformation(QPainter *painter); void drawSiblingsInformation(QPainter *painter);