diff --git a/src/plugins/binarytools/mainframe/binarytoolsconfigview.cpp b/src/plugins/binarytools/mainframe/binarytoolsconfigview.cpp index 838889e57..33b75bc33 100644 --- a/src/plugins/binarytools/mainframe/binarytoolsconfigview.cpp +++ b/src/plugins/binarytools/mainframe/binarytoolsconfigview.cpp @@ -6,12 +6,12 @@ #include "environmentview.h" #include "advancedsettingsdialog.h" #include "models/binarytoolsmodel.h" +#include "models/toolitemdelegate.h" #include "configure/binarytoolsmanager.h" #include "widgets/combinationcomboxbox.h" #include "widgets/iconcombobox.h" #include "constants.h" -#include "base/baseitemdelegate.h" #include "common/widget/variablechooser.h" #include @@ -143,20 +143,25 @@ QWidget *BinaryToolsConfigViewPrivate::createLeftWidget() DFrame *widget = new DFrame(q); widget->setFixedWidth(200); QVBoxLayout *mainLayout = new QVBoxLayout(widget); - mainLayout->setContentsMargins(10, 10, 10, 6); + mainLayout->setContentsMargins(0, 6, 0, 0); mainLayout->setSpacing(0); + QVBoxLayout *viewLayout = new QVBoxLayout; + viewLayout->setContentsMargins(8, 0, 8, 0); toolTree = new DTreeView(q); + toolTree->setIndentation(0); toolTree->setFrameShape(QFrame::NoFrame); toolTree->setDragEnabled(false); toolTree->header()->setVisible(false); toolTree->setModel(&treeModel); - toolTree->setItemDelegate(new BaseItemDelegate(toolTree)); + toolTree->setItemDelegate(new ToolItemDelegate(toolTree)); toolTree->setIconSize({ 16, 16 }); toolTree->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); + viewLayout->addWidget(toolTree); addBtn = new DToolButton(q); - addBtn->setIconSize({ 16, 16 }); + addBtn->setIconSize({ 12, 12 }); + addBtn->setFixedHeight(24); addBtn->setIcon(DStyle::standardIcon(q->style(), DStyle::SP_IncreaseElement)); addBtn->setPopupMode(QToolButton::InstantPopup); QMenu *addMenu = new QMenu(q); @@ -168,16 +173,18 @@ QWidget *BinaryToolsConfigViewPrivate::createLeftWidget() addBtn->setMenu(addMenu); delBtn = new DToolButton(q); - delBtn->setIconSize({ 16, 16 }); + delBtn->setIconSize({ 12, 12 }); + delBtn->setFixedSize(24, 24); delBtn->setIcon(DStyle::standardIcon(q->style(), DStyle::SP_DecreaseElement)); QHBoxLayout *btnLayout = new QHBoxLayout(); - btnLayout->setContentsMargins(0, 0, 0, 0); + btnLayout->setContentsMargins(8, 6, 8, 6); btnLayout->addWidget(addBtn); btnLayout->addWidget(delBtn); btnLayout->addStretch(1); - mainLayout->addWidget(toolTree); + mainLayout->addLayout(viewLayout); + mainLayout->addWidget(new DHorizontalLine(q)); mainLayout->addLayout(btnLayout); return widget; } @@ -244,6 +251,7 @@ QWidget *BinaryToolsConfigViewPrivate::createRightWidget() DLabel *cmdIconLabel = new DLabel(BinaryToolsConfigView::tr("Tool icon:"), q); iconCB = new IconComboBox(q); iconCB->setFixedWidth(240); + iconCB->setFocusPolicy(Qt::NoFocus); mainLayout->addWidget(cmdIconLabel, IconRow, 0); mainLayout->addWidget(iconCB, IconRow, 1); @@ -434,7 +442,7 @@ void BinaryToolsConfigViewPrivate::handleShowAdvanceSettings() const auto tool = treeModel.toolForIndex(currentIndex); if (!tool) return; - + dialog.setAdvancedSettings(tool->advSettings); int code = dialog.exec(); if (code == 1) { diff --git a/src/plugins/binarytools/mainframe/binarytoolsdialog.cpp b/src/plugins/binarytools/mainframe/binarytoolsdialog.cpp index 615dc93a9..8d788b5a5 100644 --- a/src/plugins/binarytools/mainframe/binarytoolsdialog.cpp +++ b/src/plugins/binarytools/mainframe/binarytoolsdialog.cpp @@ -30,10 +30,12 @@ BinaryToolsDialog::BinaryToolsDialog(QDialog *parent) DWidget *mainFrame = new DWidget(this); addContent(mainFrame); QVBoxLayout *vLayout = new QVBoxLayout(mainFrame); + vLayout->setSpacing(0); d->configView = new BinaryToolsConfigView(mainFrame); DLabel *configLabel = new DLabel(tr("Running Configuration:"), this); vLayout->addWidget(configLabel); + vLayout->addSpacing(15); vLayout->addWidget(d->configView); QHBoxLayout *buttonLayout = new QHBoxLayout(mainFrame); @@ -52,6 +54,7 @@ BinaryToolsDialog::BinaryToolsDialog(QDialog *parent) buttonLayout->setAlignment(Qt::AlignHCenter | Qt::AlignTop); buttonLayout->setContentsMargins(0, 0, 0, 0); + vLayout->addSpacing(20); vLayout->addLayout(buttonLayout); connect(okButton, &DPushButton::clicked, this, &BinaryToolsDialog::saveClicked); diff --git a/src/plugins/binarytools/models/toolitemdelegate.cpp b/src/plugins/binarytools/models/toolitemdelegate.cpp new file mode 100644 index 000000000..27751b071 --- /dev/null +++ b/src/plugins/binarytools/models/toolitemdelegate.cpp @@ -0,0 +1,209 @@ +// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "toolitemdelegate.h" + +#include +#include +#include +#ifdef DTKWIDGET_CLASS_DPaletteHelper +# include +#endif + +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +ToolItemDelegate::ToolItemDelegate(QAbstractItemView *parent) + : DStyledItemDelegate(parent) +{ +} + +void ToolItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if (!index.isValid()) + return DStyledItemDelegate::paint(painter, option, index); + + QStyleOptionViewItem opt = option; + DStyledItemDelegate::initStyleOption(&opt, index); + + painter->setRenderHint(QPainter::Antialiasing); + drawBackground(painter, opt); + drawToolItem(painter, opt, index); +} + +QSize ToolItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return { view()->width(), 24 }; +} + +QWidget *ToolItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const +{ + auto edit = new DLineEdit(parent); + edit->setAutoFillBackground(true); + edit->setBackgroundRole(QPalette::Base); + return edit; +} + +void ToolItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + auto edit = qobject_cast(editor); + edit->setText(index.data(Qt::DisplayRole).toString()); +} + +void ToolItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + auto edit = qobject_cast(editor); + const auto &text = edit->text(); + if (!text.isEmpty()) + model->setData(index, text); +} + +void ToolItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if (view()) { + QRect rect = view()->visualRect(index); + editor->setGeometry(rect); + } else { + DStyledItemDelegate::updateEditorGeometry(editor, option, index); + } +} + +bool ToolItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, + const QModelIndex &index) +{ + if (event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick) { + QMouseEvent *mouseEvent = static_cast(event); + const QRect arRect = arrowRect(option.rect); + if (arRect.contains(mouseEvent->pos())) { + if (view()->isExpanded(index)) { + view()->collapse(index); + } else { + view()->expand(index); + } + return true; + } + } + + return false; +} + +QTreeView *ToolItemDelegate::view() const +{ + return qobject_cast(parent()); +} + +void ToolItemDelegate::drawBackground(QPainter *painter, const QStyleOptionViewItem &option) const +{ + painter->save(); + if (option.state.testFlag(QStyle::State_Selected)) { + QColor bgColor = option.palette.color(QPalette::Normal, QPalette::Highlight); + painter->setBrush(bgColor); + painter->setPen(Qt::NoPen); + painter->drawRoundedRect(option.rect, 6, 6); + } else if (option.state.testFlag(QStyle::State_MouseOver)) { +#ifdef DTKWIDGET_CLASS_DPaletteHelper + DPalette palette = DPaletteHelper::instance()->palette(option.widget); +#else + DPalette palette = DGuiApplicationHelper::instance()->applicationPalette(); +#endif + painter->setBrush(palette.brush(DPalette::ItemBackground)); + painter->setPen(Qt::NoPen); + painter->drawRoundedRect(option.rect, 6, 6); + } + painter->restore(); +} + +void ToolItemDelegate::drawToolItem(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QRect extraRect; + if (!index.parent().isValid()) + extraRect = drawExpandArrow(painter, option, index); + else + extraRect = drawItemIcon(painter, option, index); + + QRect itemRect = option.rect; + itemRect.setLeft(extraRect.right() + 6); + + QString toolName = index.data(Qt::DisplayRole).toString(); + if (option.state & QStyle::State_Selected) { + painter->setPen(option.palette.color(QPalette::Normal, QPalette::HighlightedText)); + } else { + painter->setPen(option.palette.color(QPalette::Normal, QPalette::Text)); + } + + QString displayText = option.fontMetrics.elidedText(toolName, Qt::ElideRight, itemRect.width()); + painter->drawText(itemRect, displayText); +} + +QRect ToolItemDelegate::drawItemIcon(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QRect iconRect = option.rect; + iconRect.setSize(view()->iconSize()); + iconRect.moveLeft(iconRect.left() + 24); + iconRect.moveTop(option.rect.top() + (option.rect.bottom() - iconRect.bottom()) / 2); + + QIcon::Mode iconMode = QIcon::Normal; + if (!(option.state.testFlag(QStyle::State_Enabled))) + iconMode = QIcon::Disabled; + if (option.state.testFlag(QStyle::State_Selected)) + iconMode = QIcon::Selected; + + auto px = option.icon.pixmap(view()->iconSize(), iconMode); + px.setDevicePixelRatio(qApp->devicePixelRatio()); + + qreal x = iconRect.x(); + qreal y = iconRect.y(); + qreal w = px.width() / px.devicePixelRatio(); + qreal h = px.height() / px.devicePixelRatio(); + y += (iconRect.size().height() - h) / 2.0; + x += (iconRect.size().width() - w) / 2.0; + + painter->drawPixmap(qRound(x), qRound(y), px); + return iconRect; +} + +QRect ToolItemDelegate::drawExpandArrow(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QStyleOptionViewItem opt = option; + opt.rect = arrowRect(opt.rect).marginsRemoved(QMargins(5, 5, 5, 5)); + + painter->save(); + bool isSelected = (option.state & QStyle::State_Selected) && option.showDecorationSelected; + if (isSelected) { + painter->setPen(option.palette.color(QPalette::Active, QPalette::HighlightedText)); + } else { + painter->setPen(option.palette.color(QPalette::Active, QPalette::Text)); + } + + auto style = option.widget->style(); + if (view()->isExpanded(index)) { + style->drawPrimitive(QStyle::PE_IndicatorArrowDown, &opt, painter, nullptr); + } else { + style->drawPrimitive(QStyle::PE_IndicatorArrowRight, &opt, painter, nullptr); + } + + painter->restore(); + return opt.rect; +} + +QRect ToolItemDelegate::arrowRect(const QRect &itemRect) const +{ + QRect arrowRect = itemRect; + + arrowRect.setSize(QSize(20, 20)); + arrowRect.moveLeft(arrowRect.left() + 4); + arrowRect.moveTop(itemRect.top() + (itemRect.bottom() - arrowRect.bottom()) / 2); + + return arrowRect; +} diff --git a/src/plugins/binarytools/models/toolitemdelegate.h b/src/plugins/binarytools/models/toolitemdelegate.h new file mode 100644 index 000000000..ffa1db11c --- /dev/null +++ b/src/plugins/binarytools/models/toolitemdelegate.h @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TOOLITEMDELEGATE_H +#define TOOLITEMDELEGATE_H + +#include + +class QTreeView; +class ToolItemDelegate : public DTK_WIDGET_NAMESPACE::DStyledItemDelegate +{ + Q_OBJECT +public: + explicit ToolItemDelegate(QAbstractItemView *parent = nullptr); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void setEditorData(QWidget *editor, const QModelIndex &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + +protected: + bool editorEvent(QEvent *event, + QAbstractItemModel *model, + const QStyleOptionViewItem &option, + const QModelIndex &index) override; + +private: + QTreeView *view() const; + void drawBackground(QPainter *painter, const QStyleOptionViewItem &option) const; + void drawToolItem(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + QRect drawItemIcon(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + QRect drawExpandArrow(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + QRect arrowRect(const QRect &itemRect) const; +}; + +#endif // TOOLITEMDELEGATE_H diff --git a/src/plugins/binarytools/widgets/iconcombobox.cpp b/src/plugins/binarytools/widgets/iconcombobox.cpp index 0f4c512e8..49d68a986 100644 --- a/src/plugins/binarytools/widgets/iconcombobox.cpp +++ b/src/plugins/binarytools/widgets/iconcombobox.cpp @@ -14,6 +14,7 @@ #include #include #include +#include DGUI_USE_NAMESPACE #ifdef DTKWIDGET_CLASS_DPaletteHelper @@ -88,17 +89,20 @@ void IconItemDelegate::paintItemBackgroundAndGeomerty(QPainter *painter, painter->save(); bool isSelected = (option.state & QStyle::State_Selected); - + #ifdef DTKWIDGET_CLASS_DPaletteHelper - const DPalette &pl = DPaletteHelper::instance()->palette(option.widget); + const DPalette &pl = DPaletteHelper::instance()->palette(option.widget); #else - const DPalette &pl = DGuiApplicationHelper::instance()->applicationPalette(); + const DPalette &pl = DGuiApplicationHelper::instance()->applicationPalette(); #endif - - QColor backgroundColor = pl.color(DPalette::ColorGroup::Active, DPalette::ColorType::ItemBackground); + + QColor backgroundColor = pl.color(QPalette::Active, QPalette::Shadow); bool isHover = option.state & QStyle::StateFlag::State_MouseOver; - if (isSelected || isHover) + if (isSelected) { backgroundColor = pl.color(DPalette::ColorGroup::Active, DPalette::ColorType::LightLively); + } else if (isHover) { + backgroundColor = pl.color(DPalette::ColorGroup::Active, DPalette::ColorType::ObviousBackground); + } QRectF backgroundRect = option.rect; QSizeF iconSize = view->iconSize(); @@ -113,18 +117,6 @@ void IconItemDelegate::paintItemBackgroundAndGeomerty(QPainter *painter, painter->setRenderHint(QPainter::Antialiasing, true); painter->fillPath(path, backgroundColor); - if (isHover) { - QRectF outLineRect = backgroundRect; - outLineRect.setSize(outLineRect.size() - QSizeF(1.5, 1.5)); - outLineRect.moveCenter(backgroundRect.center()); - QPainterPath outLinePath; - outLinePath.addRoundedRect(outLineRect, 8, 8); - backgroundColor.setAlpha(40); - painter->setPen(backgroundColor); - painter->drawPath(outLinePath); - } - - painter->setRenderHint(QPainter::Antialiasing, false); painter->restore(); } @@ -134,12 +126,16 @@ void IconItemDelegate::paintItemIcon(QPainter *painter, { // init icon geomerty QRectF iconRect = itemIconRect(option.rect); - bool isEnabled = option.state & QStyle::State_Enabled; // draw icon + QIcon::Mode iconMode = QIcon::Normal; + if (!(option.state.testFlag(QStyle::State_Enabled))) + iconMode = QIcon::Disabled; + if (option.state.testFlag(QStyle::State_Selected)) + iconMode = QIcon::Selected; const qreal pixelRatio = painter->device()->devicePixelRatioF(); const QPixmap &px = getIconPixmap(option.icon, iconRect.size().toSize(), pixelRatio, - isEnabled ? QIcon::Normal : QIcon::Disabled); + iconMode); qreal x = iconRect.x(); qreal y = iconRect.y(); qreal w = px.width() / px.devicePixelRatio(); @@ -161,10 +157,13 @@ IconComboBox::IconComboBox(QWidget *parent) void IconComboBox::initUI() { iconFrame = new QFrame(this, Qt::Popup); + iconFrame->setAttribute(Qt::WA_TranslucentBackground); + iconFrame->installEventFilter(this); QHBoxLayout *layout = new QHBoxLayout(iconFrame); layout->setContentsMargins(0, 0, 0, 0); iconView = new QListView(this); + iconView->setFrameShape(QFrame::NoFrame); iconView->setViewMode(QListView::IconMode); iconView->setFlow(QListView::LeftToRight); iconView->setDragDropMode(QListView::NoDragDrop); @@ -263,3 +262,37 @@ void IconComboBox::paintEvent(QPaintEvent *event) // draw the icon and text painter.drawControl(QStyle::CE_ComboBoxLabel, opt); } + +bool IconComboBox::eventFilter(QObject *obj, QEvent *e) +{ + if (iconFrame) { + switch (e->type()) { + case QEvent::Paint: { + QPainter painter(iconFrame); + painter.setRenderHint(QPainter::Antialiasing); + + auto p = iconFrame->palette(); + painter.setPen(Qt::NoPen); + painter.setBrush(p.brush(QPalette::Normal, QPalette::Base)); + + QPainterPath path; + path.addRoundedRect(iconFrame->rect(), 18, 18); + painter.drawPath(path); + } break; + case QEvent::Resize: { + QPixmap pixmap(iconFrame->size()); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + painter.setRenderHint(QPainter::Antialiasing); + painter.setBrush(Qt::black); + painter.setPen(Qt::NoPen); + painter.drawRoundedRect(iconFrame->rect(), 18, 18); + iconFrame->setMask(pixmap.mask()); + } break; + default: + break; + } + } + + return QComboBox::eventFilter(obj, e); +} diff --git a/src/plugins/binarytools/widgets/iconcombobox.h b/src/plugins/binarytools/widgets/iconcombobox.h index 67c80df05..c9f886531 100644 --- a/src/plugins/binarytools/widgets/iconcombobox.h +++ b/src/plugins/binarytools/widgets/iconcombobox.h @@ -21,6 +21,7 @@ class IconComboBox : public QComboBox protected: virtual void paintEvent(QPaintEvent *event) override; + bool eventFilter(QObject *obj, QEvent *e) override; private: void initUI(); diff --git a/src/plugins/builder/mainframe/settingdialog.cpp b/src/plugins/builder/mainframe/settingdialog.cpp index 7b2b7f465..a44d72f9a 100644 --- a/src/plugins/builder/mainframe/settingdialog.cpp +++ b/src/plugins/builder/mainframe/settingdialog.cpp @@ -12,6 +12,7 @@ #include #include +#include DWIDGET_USE_NAMESPACE diff --git a/src/plugins/smartut/common/projectitemdelegate.cpp b/src/plugins/smartut/common/projectitemdelegate.cpp index 34312c838..410f72bf6 100644 --- a/src/plugins/smartut/common/projectitemdelegate.cpp +++ b/src/plugins/smartut/common/projectitemdelegate.cpp @@ -268,11 +268,6 @@ void ProjectItemDelegate::drawFileNameItem(QPainter *painter, if (view->viewType() == ProjectTreeView::UnitTest) stateRect = drawItemState(painter, opt, index); -#ifdef DTKWIDGET_CLASS_DPaletteHelper - DPalette palette = DPaletteHelper::instance()->palette(option.widget); -#else - DPalette palette = DGuiApplicationHelper::instance()->applicationPalette(); -#endif QRect nameRect = opt.rect; nameRect.setLeft(iconRect.right() + kPadding); if (stateRect.isValid()) diff --git a/src/plugins/smartut/gui/widget/promptsettingwidget.cpp b/src/plugins/smartut/gui/widget/promptsettingwidget.cpp index 20e6aef65..6b3b48dec 100644 --- a/src/plugins/smartut/gui/widget/promptsettingwidget.cpp +++ b/src/plugins/smartut/gui/widget/promptsettingwidget.cpp @@ -11,6 +11,7 @@ #include #include +#include DWIDGET_USE_NAMESPACE diff --git a/src/plugins/smartut/gui/widget/resourcesettingwidget.cpp b/src/plugins/smartut/gui/widget/resourcesettingwidget.cpp index 5b1b9803a..1c4c7bce0 100644 --- a/src/plugins/smartut/gui/widget/resourcesettingwidget.cpp +++ b/src/plugins/smartut/gui/widget/resourcesettingwidget.cpp @@ -13,6 +13,7 @@ #include #include #include +#include DWIDGET_USE_NAMESPACE