diff options
author | David Schulz <david.schulz@qt.io> | 2017-06-20 08:28:10 +0200 |
---|---|---|
committer | David Schulz <david.schulz@qt.io> | 2017-06-30 08:27:16 +0000 |
commit | 6591a01452918ce40ca101bb6cfe9770a44d16be (patch) | |
tree | 66d0c53e2dbd89126f063897453dc3aef65c216b /src/plugins/texteditor/textmark.cpp | |
parent | 4506acbffc08cab4ad2a4f0425fd62c0e0a03f1b (diff) | |
download | qt-creator-6591a01452918ce40ca101bb6cfe9770a44d16be.tar.gz |
TextEditor: Add line annotations
Displaying short descriptive text of a TextMark at line end.
Currently implemented for ClangTextMark and BookMark.
Change-Id: Idc6b579bda0382ad94b2e236b715696396b10460
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
Diffstat (limited to 'src/plugins/texteditor/textmark.cpp')
-rw-r--r-- | src/plugins/texteditor/textmark.cpp | 90 |
1 files changed, 87 insertions, 3 deletions
diff --git a/src/plugins/texteditor/textmark.cpp b/src/plugins/texteditor/textmark.cpp index 975cc7a41c..15939a3f44 100644 --- a/src/plugins/texteditor/textmark.cpp +++ b/src/plugins/texteditor/textmark.cpp @@ -33,6 +33,7 @@ #include <utils/qtcassert.h> #include <QGridLayout> +#include <QPainter> using namespace Core; using namespace Utils; @@ -57,6 +58,24 @@ private: QHash<Utils::FileName, QSet<TextMark *> > m_marks; }; +class AnnotationColors +{ +public: + static AnnotationColors &getAnnotationColors(const QColor &markColor, + const QColor &backgroundColor); + +public: + using SourceColors = QPair<QColor, QColor>; + QColor rectColor; + QColor textColor; + +private: + static double clipHsl(double value); + +private: + static QHash<SourceColors, AnnotationColors> m_colorCache; +}; + TextMarkRegistry *m_instance = nullptr; TextMark::TextMark(const QString &fileName, int lineNumber, Id category, double widthFactor) @@ -99,11 +118,49 @@ int TextMark::lineNumber() const return m_lineNumber; } -void TextMark::paint(QPainter *painter, const QRect &rect) const +void TextMark::paintIcon(QPainter *painter, const QRect &rect) const { m_icon.paint(painter, rect, Qt::AlignCenter); } +void TextMark::paintAnnotation(QPainter *painter, + QRectF *annotationRect, + const QFontMetrics &fm) const +{ + QString text = lineAnnotation(); + if (text.isEmpty()) + return; + + const bool drawIcon = !m_icon.isNull(); + int textWidth = fm.width(text); + constexpr qreal margin = 1; + const qreal iconHeight = annotationRect->height() - 2 * margin; + const qreal iconWidth = iconHeight * m_widthFactor + 2 * margin; + qreal annotationWidth = (drawIcon ? textWidth + iconWidth : textWidth) + margin; + if (annotationRect->left() + annotationWidth > annotationRect->right()) { + textWidth = int(annotationRect->width() - (drawIcon ? iconWidth + margin : margin)); + text = fm.elidedText(text, Qt::ElideRight, textWidth); + annotationWidth = annotationRect->width(); + } + const QColor markColor = m_hasColor ? Utils::creatorTheme()->color(m_color).toHsl() + : painter->pen().color(); + const AnnotationColors &colors = + AnnotationColors::getAnnotationColors(markColor, painter->background().color()); + + painter->save(); + annotationRect->setWidth(annotationWidth); + painter->setPen(colors.rectColor); + painter->setBrush(colors.rectColor); + painter->drawRect(*annotationRect); + painter->setPen(colors.textColor); + if (drawIcon) { + paintIcon(painter, annotationRect->adjusted( + margin, margin, -(textWidth + 2 * margin), -margin).toAlignedRect()); + } + painter->drawText(annotationRect->adjusted(iconWidth, 0, 0, 0), Qt::AlignLeft, text); + painter->restore(); +} + void TextMark::updateLineNumber(int lineNumber) { m_lineNumber = lineNumber; @@ -176,7 +233,7 @@ void TextMark::dragToLine(int lineNumber) Q_UNUSED(lineNumber); } -void TextMark::addToToolTipLayout(QGridLayout *target) +void TextMark::addToToolTipLayout(QGridLayout *target) const { auto *contentLayout = new QVBoxLayout; addToolTipContent(contentLayout); @@ -191,7 +248,7 @@ void TextMark::addToToolTipLayout(QGridLayout *target) } } -bool TextMark::addToolTipContent(QLayout *target) +bool TextMark::addToolTipContent(QLayout *target) const { QString text = m_toolTip; if (text.isEmpty()) { @@ -304,6 +361,33 @@ void TextMarkRegistry::allDocumentsRenamed(const QString &oldName, const QString mark->updateFileName(newName); } +QHash<AnnotationColors::SourceColors, AnnotationColors> AnnotationColors::m_colorCache; + +AnnotationColors &AnnotationColors::getAnnotationColors(const QColor &markColor, + const QColor &backgroundColor) +{ + AnnotationColors &colors = m_colorCache[{markColor, backgroundColor}]; + if (!colors.rectColor.isValid() || !colors.textColor.isValid()) { + const double backgroundSaturation = clipHsl(markColor.hslSaturationF() / 2); + const double backgroundLightness = clipHsl(backgroundColor.lightnessF()); + const double foregroundLightness = clipHsl(backgroundLightness > 0.5 + ? backgroundLightness - 0.5 + : backgroundLightness + 0.5); + colors.rectColor.setHslF(markColor.hslHueF(), + backgroundSaturation, + backgroundLightness); + colors.textColor.setHslF(markColor.hslHueF(), + markColor.hslSaturationF(), + foregroundLightness); + } + return colors; +} + +double AnnotationColors::clipHsl(double value) +{ + return std::max(0.15, std::min(0.85, value)); +} + } // namespace TextEditor #include "textmark.moc" |