1/*
2 SPDX-FileCopyrightText: 2009 Rafael Fernández López <ereslibre@kde.org>
3 SPDX-FileCopyrightText: 2013 Dominik Haumann <dhaumann@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "katecategorydrawer.h"
9
10#include <QApplication>
11#include <QPainter>
12#include <QPainterPath>
13#include <QStyleOption>
14
15KateCategoryDrawer::KateCategoryDrawer()
16 : KCategoryDrawer(nullptr)
17{
18}
19
20void KateCategoryDrawer::drawCategory(const QModelIndex &index, int sortRole, const QStyleOption &option, QPainter *painter) const
21{
22 Q_UNUSED(sortRole)
23
24 painter->setRenderHint(hint: QPainter::Antialiasing);
25
26 const QRect optRect = option.rect;
27 QFont font(QApplication::font());
28 font.setBold(true);
29 const int height = categoryHeight(index, option);
30 const bool leftToRight = painter->layoutDirection() == Qt::LeftToRight;
31
32 {
33 QRect newOptRect(optRect);
34
35 if (leftToRight) {
36 newOptRect.translate(dx: 1, dy: 1);
37 } else {
38 newOptRect.translate(dx: -1, dy: 1);
39 }
40
41 // BEGIN: inner top left corner
42 {
43 painter->save();
44 painter->setPen(option.palette.base().color());
45 QRectF arc;
46 if (leftToRight) {
47 const QPointF topLeft(newOptRect.topLeft());
48 arc = QRectF(topLeft, QSizeF(4, 4));
49 arc.translate(dx: 0.5, dy: 0.5);
50 painter->drawArc(rect: arc, a: 1440, alen: 1440);
51 } else {
52 QPointF topRight(newOptRect.topRight());
53 topRight.rx() -= 4;
54 arc = QRectF(topRight, QSizeF(4, 4));
55 arc.translate(dx: -0.5, dy: 0.5);
56 painter->drawArc(rect: arc, a: 0, alen: 1440);
57 }
58 painter->restore();
59 }
60 // END: inner top left corner
61
62 // BEGIN: inner left vertical line
63 {
64 QPoint start;
65 QPoint verticalGradBottom;
66 if (leftToRight) {
67 start = newOptRect.topLeft();
68 verticalGradBottom = newOptRect.topLeft();
69 } else {
70 start = newOptRect.topRight();
71 verticalGradBottom = newOptRect.topRight();
72 }
73 start.ry() += 3;
74 verticalGradBottom.ry() += newOptRect.height() - 3;
75 QLinearGradient gradient(start, verticalGradBottom);
76 gradient.setColorAt(pos: 0, color: option.palette.base().color());
77 gradient.setColorAt(pos: 1, color: Qt::transparent);
78 painter->fillRect(QRect(start, QSize(1, newOptRect.height() - 3)), gradient);
79 }
80 // END: inner left vertical line
81
82 // BEGIN: inner horizontal line
83 {
84 QPoint start;
85 QPoint horizontalGradTop;
86 if (leftToRight) {
87 start = newOptRect.topLeft();
88 horizontalGradTop = newOptRect.topLeft();
89 start.rx() += 3;
90 horizontalGradTop.rx() += newOptRect.width() - 3;
91 } else {
92 start = newOptRect.topRight();
93 horizontalGradTop = newOptRect.topRight();
94 start.rx() -= 3;
95 horizontalGradTop.rx() -= newOptRect.width() - 3;
96 }
97 QLinearGradient gradient(start, horizontalGradTop);
98 gradient.setColorAt(pos: 0, color: option.palette.base().color());
99 gradient.setColorAt(pos: 1, color: Qt::transparent);
100 QSize rectSize;
101 if (leftToRight) {
102 rectSize = QSize(newOptRect.width() - 3, 1);
103 } else {
104 rectSize = QSize(-newOptRect.width() + 3, 1);
105 }
106 painter->fillRect(QRect(start, rectSize), gradient);
107 }
108 // END: inner horizontal line
109 }
110
111 QColor outlineColor = option.palette.text().color();
112 outlineColor.setAlphaF(0.35);
113
114 // BEGIN: top left corner
115 {
116 painter->save();
117 painter->setPen(outlineColor);
118 QRectF arc;
119 if (leftToRight) {
120 const QPointF topLeft(optRect.topLeft());
121 arc = QRectF(topLeft, QSizeF(4, 4));
122 arc.translate(dx: 0.5, dy: 0.5);
123 painter->drawArc(rect: arc, a: 1440, alen: 1440);
124 } else {
125 QPointF topRight(optRect.topRight());
126 topRight.rx() -= 4;
127 arc = QRectF(topRight, QSizeF(4, 4));
128 arc.translate(dx: -0.5, dy: 0.5);
129 painter->drawArc(rect: arc, a: 0, alen: 1440);
130 }
131 painter->restore();
132 }
133 // END: top left corner
134
135 // BEGIN: left vertical line
136 {
137 QPoint start;
138 QPoint verticalGradBottom;
139 if (leftToRight) {
140 start = optRect.topLeft();
141 verticalGradBottom = optRect.topLeft();
142 } else {
143 start = optRect.topRight();
144 verticalGradBottom = optRect.topRight();
145 }
146 start.ry() += 3;
147 verticalGradBottom.ry() += optRect.height() - 3;
148 QLinearGradient gradient(start, verticalGradBottom);
149 gradient.setColorAt(pos: 0, color: outlineColor);
150 gradient.setColorAt(pos: 1, color: option.palette.base().color());
151 painter->fillRect(QRect(start, QSize(1, optRect.height() - 3)), gradient);
152 }
153 // END: left vertical line
154
155 // BEGIN: horizontal line
156 {
157 QPoint start;
158 QPoint horizontalGradTop;
159 if (leftToRight) {
160 start = optRect.topLeft();
161 horizontalGradTop = optRect.topLeft();
162 start.rx() += 3;
163 horizontalGradTop.rx() += optRect.width() - 3;
164 } else {
165 start = optRect.topRight();
166 horizontalGradTop = optRect.topRight();
167 start.rx() -= 3;
168 horizontalGradTop.rx() -= optRect.width() - 3;
169 }
170 QLinearGradient gradient(start, horizontalGradTop);
171 gradient.setColorAt(pos: 0, color: outlineColor);
172 gradient.setColorAt(pos: 1, color: option.palette.base().color());
173 QSize rectSize;
174 if (leftToRight) {
175 rectSize = QSize(optRect.width() - 3, 1);
176 } else {
177 rectSize = QSize(-optRect.width() + 3, 1);
178 }
179 painter->fillRect(QRect(start, rectSize), gradient);
180 }
181 // END: horizontal line
182
183 // BEGIN: draw text
184 {
185 const QString category = index.model()->data(index, role: Qt::DisplayRole).toString(); // KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
186 QRect textRect = QRect(option.rect.topLeft(), QSize(option.rect.width() - 2 - 3 - 3, height));
187 textRect.setTop(textRect.top() + 2 + 3 /* corner */);
188 textRect.setLeft(textRect.left() + 2 + 3 /* corner */ + 3 /* a bit of margin */);
189 painter->save();
190 painter->setFont(font);
191 QColor penColor(option.palette.text().color());
192 penColor.setAlphaF(0.6);
193 painter->setPen(penColor);
194 painter->drawText(r: textRect, flags: Qt::AlignLeft | Qt::AlignTop, text: category);
195 painter->restore();
196 }
197 // END: draw text
198}
199
200int KateCategoryDrawer::categoryHeight(const QModelIndex &index, const QStyleOption &option) const
201{
202 Q_UNUSED(index);
203 Q_UNUSED(option);
204
205 QFont font(QApplication::font());
206 font.setBold(true);
207 const QFontMetrics fontMetrics = QFontMetrics(font);
208
209 return fontMetrics.height() + 2 + 12 /* vertical spacing */;
210}
211
212int KateCategoryDrawer::leftMargin() const
213{
214 return 7;
215}
216
217int KateCategoryDrawer::rightMargin() const
218{
219 return 7;
220}
221

source code of ktexteditor/src/syntax/katecategorydrawer.cpp