Editor: paint location marker over everything else

The location marker is updated very regularly and especially while
stepping moves one line at a time. Resizing this marker when it enters a
line that already contains a marker is visually distracting. To prevent
this paint the marker over all other markers in that line.

Change-Id: I63ad72384e77eeae4dc6d2e2c2ac77c88da92c56
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
David Schulz
2022-09-06 13:01:51 +02:00
parent 2f093aec66
commit d8fcaf0a73
6 changed files with 46 additions and 10 deletions

View File

@@ -156,6 +156,7 @@ LocationMark::LocationMark(DebuggerEngine *engine, const FilePath &file, int lin
: TextMark(file, line, Constants::TEXT_MARK_CATEGORY_LOCATION), m_engine(engine) : TextMark(file, line, Constants::TEXT_MARK_CATEGORY_LOCATION), m_engine(engine)
{ {
setPriority(TextMark::HighPriority); setPriority(TextMark::HighPriority);
setIsLocationMarker(true);
updateIcon(); updateIcon();
} }

View File

@@ -983,6 +983,10 @@ bool TextDocument::addMark(TextMark *mark)
// Update document layout // Update document layout
bool fullUpdate = !documentLayout->hasMarks; bool fullUpdate = !documentLayout->hasMarks;
documentLayout->hasMarks = true; documentLayout->hasMarks = true;
if (!documentLayout->hasLocationMarker && mark->isLocationMarker()) {
documentLayout->hasLocationMarker = true;
fullUpdate = true;
}
if (fullUpdate) if (fullUpdate)
documentLayout->scheduleUpdate(); documentLayout->scheduleUpdate();
else else
@@ -1018,6 +1022,11 @@ void TextDocument::removeMarkFromMarksCache(TextMark *mark)
Qt::QueuedConnection); Qt::QueuedConnection);
}; };
if (mark->isLocationMarker()) {
documentLayout->hasLocationMarker = false;
scheduleLayoutUpdate();
}
if (d->m_marksCache.isEmpty()) { if (d->m_marksCache.isEmpty()) {
documentLayout->hasMarks = false; documentLayout->hasMarks = false;
scheduleLayoutUpdate(); scheduleLayoutUpdate();

View File

@@ -203,6 +203,7 @@ public:
int lastSaveRevision = 0; int lastSaveRevision = 0;
bool hasMarks = false; bool hasMarks = false;
bool hasLocationMarker = false;
int m_requiredWidth = 0; int m_requiredWidth = 0;
void setRequiredWidth(int width); void setRequiredWidth(int width);

View File

@@ -4930,35 +4930,46 @@ void TextEditorWidgetPrivate::paintTextMarks(QPainter &painter, const ExtraAreaP
QList<QIcon> icons; QList<QIcon> icons;
auto end = marks.crend(); auto end = marks.crend();
int marksWithIconCount = 0; int marksWithIconCount = 0;
QIcon overrideIcon;
for (auto it = marks.crbegin(); it != end; ++it) { for (auto it = marks.crbegin(); it != end; ++it) {
if ((*it)->isVisible()) { if ((*it)->isVisible()) {
const QIcon icon = (*it)->icon(); const QIcon icon = (*it)->icon();
if (!icon.isNull()) { if (!icon.isNull()) {
if (icons.size() < 3 if ((*it)->isLocationMarker()) {
&& !Utils::contains(icons, Utils::equal(&QIcon::cacheKey, icon.cacheKey()))) { overrideIcon = icon;
icons << icon; } else {
if (icons.size() < 3
&& !Utils::contains(icons, Utils::equal(&QIcon::cacheKey, icon.cacheKey()))) {
icons << icon;
}
++marksWithIconCount;
} }
++marksWithIconCount;
} }
} }
} }
if (icons.isEmpty())
return;
painter.save();
Utils::ExecuteOnDestruction painterRestore([&]() { painter.restore(); });
int size = data.lineSpacing - 1; int size = data.lineSpacing - 1;
int xoffset = 0; int xoffset = 0;
int yoffset = blockBoundingRect.top(); int yoffset = blockBoundingRect.top();
painter.save();
Utils::ExecuteOnDestruction eod([&painter, size, yoffset, xoffset, overrideIcon]() {
if (!overrideIcon.isNull()) {
const QRect r(xoffset, yoffset, size, size);
overrideIcon.paint(&painter, r, Qt::AlignCenter);
}
painter.restore();
});
if (icons.isEmpty())
return;
if (icons.size() == 1) { if (icons.size() == 1) {
const QRect r(xoffset, yoffset, size, size); const QRect r(xoffset, yoffset, size, size);
icons.first().paint(&painter, r, Qt::AlignCenter); icons.first().paint(&painter, r, Qt::AlignCenter);
return; return;
} }
size = size / 2; size = size / 2;
for (const QIcon &icon : qAsConst(icons)) { for (const QIcon &icon : qAsConst(icons)) {
const QRect r(xoffset, yoffset, size, size); const QRect r(xoffset, yoffset, size, size);

View File

@@ -409,6 +409,16 @@ void TextMark::setSettingsPage(Id settingsPage)
m_settingsPage = settingsPage; m_settingsPage = settingsPage;
} }
bool TextMark::isLocationMarker() const
{
return m_isLocationMarker;
}
void TextMark::setIsLocationMarker(bool newIsLocationMarker)
{
m_isLocationMarker = newIsLocationMarker;
}
TextMarkRegistry::TextMarkRegistry(QObject *parent) TextMarkRegistry::TextMarkRegistry(QObject *parent)
: QObject(parent) : QObject(parent)
{ {

View File

@@ -111,6 +111,9 @@ public:
void setActions(const QVector<QAction *> &actions); // Takes ownership void setActions(const QVector<QAction *> &actions); // Takes ownership
void setActionsProvider(const std::function<QList<QAction *>()> &actionsProvider); // Takes ownership void setActionsProvider(const std::function<QList<QAction *>()> &actionsProvider); // Takes ownership
bool isLocationMarker() const;;
void setIsLocationMarker(bool newIsLocationMarker);
protected: protected:
void setSettingsPage(Utils::Id settingsPage); void setSettingsPage(Utils::Id settingsPage);
@@ -121,6 +124,7 @@ private:
Utils::FilePath m_fileName; Utils::FilePath m_fileName;
int m_lineNumber = 0; int m_lineNumber = 0;
Priority m_priority = LowPriority; Priority m_priority = LowPriority;
bool m_isLocationMarker = false;
QIcon m_icon; QIcon m_icon;
std::function<QIcon()> m_iconProvider; std::function<QIcon()> m_iconProvider;
std::optional<Utils::Theme::Color> m_color; std::optional<Utils::Theme::Color> m_color;