summaryrefslogtreecommitdiff
path: root/src/plugins/texteditor/textmark.cpp
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@qt.io>2017-06-20 08:28:10 +0200
committerDavid Schulz <david.schulz@qt.io>2017-06-30 08:27:16 +0000
commit6591a01452918ce40ca101bb6cfe9770a44d16be (patch)
tree66d0c53e2dbd89126f063897453dc3aef65c216b /src/plugins/texteditor/textmark.cpp
parent4506acbffc08cab4ad2a4f0425fd62c0e0a03f1b (diff)
downloadqt-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.cpp90
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"