From 8eee3de8310c84c1d8b8513e6822fa26f587806f Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Sun, 31 Mar 2024 17:23:16 +0800 Subject: [PATCH] - Change: Change background color for highlighted buttons in the default theme. - enhancement: Make matched contents more obvious in the code suggestion popup. - enhancement: Make matched contents more obvious in the header suggestion popup. --- NEWS.md | 4 +- RedPandaIDE/debugger/gdbmidebugger.cpp | 6 +- RedPandaIDE/resources/themes/default.json | 4 +- RedPandaIDE/widgets/codecompletionpopup.cpp | 33 ++++--- RedPandaIDE/widgets/codecompletionpopup.h | 2 - RedPandaIDE/widgets/headercompletionpopup.cpp | 86 +++++++++++++++++-- RedPandaIDE/widgets/headercompletionpopup.h | 26 +++++- 7 files changed, 132 insertions(+), 29 deletions(-) diff --git a/NEWS.md b/NEWS.md index 03f5559f..13cfa0c2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -107,7 +107,9 @@ Red Panda C++ Version 2.27 - fix: If there are only 1 line in the editor, shift+down can't select it. - enhancement: By default, use monospaced font to display register values in the CPU Info dialog. - fix: Negative values in register like AH/AL are wrongs displayed as 32/64-bit number. - - Change: Background color for highlighted buttons in the default theme. + - Change: Change background color for highlighted buttons in the default theme. + - enhancement: Make matched contents more obvious in the code suggestion popup. + - enhancement: Make matched contents more obvious in the header suggestion popup. Red Panda C++ Version 2.26 - enhancement: Code suggestion for embedded std::vectors. diff --git a/RedPandaIDE/debugger/gdbmidebugger.cpp b/RedPandaIDE/debugger/gdbmidebugger.cpp index 1e055438..83861734 100644 --- a/RedPandaIDE/debugger/gdbmidebugger.cpp +++ b/RedPandaIDE/debugger/gdbmidebugger.cpp @@ -480,14 +480,12 @@ void GDBMIDebuggerClient::handleRegisterValue(const QListstatement(index)) ) { + QFont normalFont{font()}; + QFont matchedFont{font()}; + normalFont.setBold(false); + normalFont.setUnderline(false); + matchedFont.setBold(true); + matchedFont.setUnderline(true); painter->save(); - painter->setFont(font()); + painter->setFont(normalFont); QColor normalColor = mNormalColor; + QColor matchedColor = mMatchedColor; if (option.state & QStyle::State_Selected) { painter->fillRect(option.rect, option.palette.highlight()); normalColor = option.palette.color(QPalette::HighlightedText); + float h = mMatchedColor.hslHueF(); + float s = mMatchedColor.hslSaturationF(); + float l = normalColor.lightnessF(); + if (l>0.85) { + l = 0.85; + } else if (l<0.15) { + l = 0.15; + } + matchedColor = QColor::fromHslF(h,s,l); } QPixmap icon = mModel->statementIcon(index); int x=option.rect.left(); @@ -1349,11 +1365,13 @@ void CodeCompletionListItemDelegate::paint(QPainter *painter, const QStyleOption if (posstart) { QString t = text.mid(pos,matchPosition->start-pos); painter->setPen(normalColor); + painter->setFont(normalFont); painter->drawText(x,y,t); x+=painter->fontMetrics().horizontalAdvance(t); } QString t = text.mid(matchPosition->start, matchPosition->end-matchPosition->start); - painter->setPen(mMatchedColor); + painter->setPen(matchedColor); + painter->setFont(matchedFont); painter->drawText(x,y,t); x+=painter->fontMetrics().horizontalAdvance(t); pos=matchPosition->end; @@ -1361,6 +1379,7 @@ void CodeCompletionListItemDelegate::paint(QPainter *painter, const QStyleOption if (possetPen(normalColor); + painter->setFont(normalFont); painter->drawText(x,y,t); x+=painter->fontMetrics().horizontalAdvance(t); } @@ -1370,16 +1389,6 @@ void CodeCompletionListItemDelegate::paint(QPainter *painter, const QStyleOption } } -CodeCompletionListModel *CodeCompletionListItemDelegate::model() const -{ - return mModel; -} - -void CodeCompletionListItemDelegate::setModel(CodeCompletionListModel *newModel) -{ - mModel = newModel; -} - const QColor &CodeCompletionListItemDelegate::normalColor() const { return mNormalColor; diff --git a/RedPandaIDE/widgets/codecompletionpopup.h b/RedPandaIDE/widgets/codecompletionpopup.h index 5abaa514..fe35950b 100644 --- a/RedPandaIDE/widgets/codecompletionpopup.h +++ b/RedPandaIDE/widgets/codecompletionpopup.h @@ -56,8 +56,6 @@ public: // QAbstractItemDelegate interface public: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - CodeCompletionListModel *model() const; - void setModel(CodeCompletionListModel *newModel); const QColor &normalColor() const; void setNormalColor(const QColor &newNormalColor); diff --git a/RedPandaIDE/widgets/headercompletionpopup.cpp b/RedPandaIDE/widgets/headercompletionpopup.cpp index cf1fc13c..1739d1fb 100644 --- a/RedPandaIDE/widgets/headercompletionpopup.cpp +++ b/RedPandaIDE/widgets/headercompletionpopup.cpp @@ -15,11 +15,12 @@ * along with this program. If not, see . */ #include "headercompletionpopup.h" - +#include "codecompletionpopup.h" #include #include #include #include +#include "qpainter.h" #include "systemconsts.h" #include "../utils.h" @@ -27,10 +28,12 @@ HeaderCompletionPopup::HeaderCompletionPopup(QWidget* parent):QWidget(parent) { setWindowFlags(Qt::Popup); mListView = new CodeCompletionListView(this); - mModel=new HeaderCompletionListModel(&mCompletionList); + mModel=new HeaderCompletionListModel(&mCompletionList, 0); QItemSelectionModel *m=mListView->selectionModel(); mListView->setModel(mModel); delete m; + mDelegate = new HeaderCompletionListItemDelegate(mModel,this); + mListView->setItemDelegate(mDelegate); setLayout(new QVBoxLayout()); layout()->addWidget(mListView); layout()->setMargin(0); @@ -158,6 +161,7 @@ void HeaderCompletionPopup::filterList(const QString &member) { Qt::CaseSensitivity caseSensitivity=mIgnoreCase?Qt::CaseInsensitive:Qt::CaseSensitive; mCompletionList.clear(); + mModel->setMatched(0); if (member.isEmpty()) { foreach (const PHeaderCompletionListItem& item,mFullCompletionList.values()) { mCompletionList.append(item); @@ -170,6 +174,7 @@ void HeaderCompletionPopup::filterList(const QString &member) } } std::sort(mCompletionList.begin(),mCompletionList.end(), sortByUsage); + mModel->setMatched(member.length()); } @@ -286,6 +291,7 @@ void HeaderCompletionPopup::setParser(const PCppParser &newParser) void HeaderCompletionPopup::hideEvent(QHideEvent *) { mCompletionList.clear(); + mModel->setMatched(0); mFullCompletionList.clear(); mParser = nullptr; } @@ -296,6 +302,7 @@ bool HeaderCompletionPopup::event(QEvent *event) switch (event->type()) { case QEvent::FontChange: mListView->setFont(font()); + mDelegate->setFont(font()); break; default: break; @@ -303,9 +310,10 @@ bool HeaderCompletionPopup::event(QEvent *event) return result; } -HeaderCompletionListModel::HeaderCompletionListModel(const QList *files, QObject *parent): - QAbstractListModel(parent), - mFiles(files) +HeaderCompletionListModel::HeaderCompletionListModel(const QList *files, int matched, QObject *parent): + QAbstractListModel{parent}, + mFiles{files}, + mMatched{matched} { } @@ -350,6 +358,11 @@ void HeaderCompletionListModel::notifyUpdated() endResetModel(); } +void HeaderCompletionListModel::setLocalColor(const QColor &newColor) +{ + mLocalColor = newColor; +} + void HeaderCompletionListModel::setSystemColor(const QColor &newColor) { mSystemColor = newColor; @@ -365,7 +378,66 @@ void HeaderCompletionListModel::setFolderColor(const QColor &newFolderColor) mFolderColor = newFolderColor; } -void HeaderCompletionListModel::setLocalColor(const QColor &newColor) +int HeaderCompletionListModel::matched() const { - mLocalColor = newColor; + return mMatched; +} + +void HeaderCompletionListModel::setMatched(int newMatched) +{ + mMatched = newMatched; +} + +HeaderCompletionListItemDelegate::HeaderCompletionListItemDelegate(HeaderCompletionListModel *model, QWidget *parent): + QStyledItemDelegate{parent}, + mModel{model} +{ + +} + +void HeaderCompletionListItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if (!mModel) { + QStyledItemDelegate::paint(painter, option, index); + return; + } + QString text = mModel->data(index, Qt::DisplayRole).toString(); + if (text.isEmpty()) { + QStyledItemDelegate::paint(painter, option, index); + return; + } + painter->save(); + QFont normalFont{font()}; + QFont matchedFont{font()}; + normalFont.setBold(false); + normalFont.setUnderline(false); + matchedFont.setBold(true); + matchedFont.setUnderline(true); + painter->setFont(normalFont); + QColor normalColor = mModel->data(index, Qt::ForegroundRole).value(); + if (option.state & QStyle::State_Selected) { + painter->fillRect(option.rect, option.palette.highlight()); + normalColor = option.palette.color(QPalette::HighlightedText); + } + painter->setPen(normalColor); + int y=option.rect.bottom()-painter->fontMetrics().descent(); + int x=0; + QString t = text.left(mModel->matched()); + painter->setFont(matchedFont); + painter->drawText(x,y,t); + x+=painter->fontMetrics().horizontalAdvance(t); + t = text.mid(mModel->matched()); + painter->setFont(normalFont); + painter->drawText(x,y,t); + painter->restore(); +} + +const QFont &HeaderCompletionListItemDelegate::font() const +{ + return mFont; +} + +void HeaderCompletionListItemDelegate::setFont(const QFont &newFont) +{ + mFont=newFont; } diff --git a/RedPandaIDE/widgets/headercompletionpopup.h b/RedPandaIDE/widgets/headercompletionpopup.h index 12adf4b0..abf88ce9 100644 --- a/RedPandaIDE/widgets/headercompletionpopup.h +++ b/RedPandaIDE/widgets/headercompletionpopup.h @@ -43,7 +43,7 @@ using PHeaderCompletionListItem=std::shared_ptr; class HeaderCompletionListModel: public QAbstractListModel { Q_OBJECT public: - explicit HeaderCompletionListModel(const QList* files,QObject *parent = nullptr); + explicit HeaderCompletionListModel(const QList* files, int matched, QObject *parent = nullptr); int rowCount(const QModelIndex &parent) const override; QVariant data(const QModelIndex &index, int role) const override; void notifyUpdated(); @@ -53,12 +53,34 @@ public: void setFolderColor(const QColor &newFolderColor); + int matched() const; + + void setMatched(int newMatched); + private: const QList *mFiles; QColor mLocalColor; QColor mSystemColor; QColor mProjectColor; QColor mFolderColor; + int mMatched; +}; + +class HeaderCompletionListItemDelegate: public QStyledItemDelegate { + Q_OBJECT +public: + HeaderCompletionListItemDelegate(HeaderCompletionListModel *model=nullptr, QWidget *parent = nullptr); + + // QAbstractItemDelegate interface +public: + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + + const QFont &font() const; + void setFont(const QFont &newFont); + +private: + HeaderCompletionListModel *mModel; + QFont mFont; }; class HeaderCompletionPopup : public QWidget @@ -98,6 +120,8 @@ private: bool mSearchLocal; QString mCurrentFile; + HeaderCompletionListItemDelegate* mDelegate; + // QWidget interface protected: void hideEvent(QHideEvent *event) override;