Changeset View
Changeset View
Standalone View
Standalone View
kstyle/widgets/itemview.cpp
- This file was added.
1 | #include "breezestyle.h" | ||||
---|---|---|---|---|---|
2 | | ||||
3 | namespace Breeze | ||||
4 | { | ||||
5 | //______________________________________________________________________________ | ||||
6 | void Helper::renderSelection(QPainter *painter, const QRect &rect, const QColor &color) const | ||||
7 | { | ||||
8 | painter->setRenderHint(QPainter::Antialiasing); | ||||
9 | painter->setPen(Qt::NoPen); | ||||
10 | painter->setBrush(color); | ||||
11 | painter->drawRect(rect); | ||||
12 | } | ||||
13 | | ||||
14 | //______________________________________________________________________________ | ||||
15 | void Helper::renderSidePanelFrame(QPainter *painter, const QRect &rect, const QColor &outline, Side side) const | ||||
16 | { | ||||
17 | // check color | ||||
18 | if (!outline.isValid()) | ||||
19 | return; | ||||
20 | | ||||
21 | // adjust rect | ||||
22 | QRectF frameRect(rect); | ||||
23 | frameRect.adjust(0.5, 0.5, -0.5, -0.5); | ||||
24 | | ||||
25 | // setup painter | ||||
26 | painter->setRenderHint(QPainter::Antialiasing); | ||||
27 | painter->setPen(outline); | ||||
28 | | ||||
29 | // render | ||||
30 | switch (side) { | ||||
31 | default: | ||||
32 | case SideLeft: | ||||
33 | painter->drawLine(frameRect.topRight(), frameRect.bottomRight()); | ||||
34 | break; | ||||
35 | | ||||
36 | case SideTop: | ||||
37 | painter->drawLine(frameRect.topLeft(), frameRect.topRight()); | ||||
38 | break; | ||||
39 | | ||||
40 | case SideRight: | ||||
41 | painter->drawLine(frameRect.topLeft(), frameRect.bottomLeft()); | ||||
42 | break; | ||||
43 | | ||||
44 | case SideBottom: | ||||
45 | painter->drawLine(frameRect.bottomLeft(), frameRect.bottomRight()); | ||||
46 | break; | ||||
47 | | ||||
48 | case AllSides: { | ||||
49 | const qreal radius(frameRadius(-1.0)); | ||||
50 | painter->drawRoundedRect(frameRect, radius, radius); | ||||
51 | break; | ||||
52 | } | ||||
53 | } | ||||
54 | } | ||||
55 | | ||||
56 | //______________________________________________________________ | ||||
57 | QSize Style::itemViewItemSizeFromContents(const QStyleOption *option, const QSize &contentsSize, const QWidget *widget) const | ||||
58 | { | ||||
59 | // call base class | ||||
60 | const QSize size(ParentStyleClass::sizeFromContents(CT_ItemViewItem, option, contentsSize, widget)); | ||||
61 | return expandSize(size, Metrics::ItemView_ItemMarginWidth); | ||||
62 | } | ||||
63 | | ||||
64 | //___________________________________________________________________________________ | ||||
65 | bool Style::drawPanelItemViewItemPrimitive(const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
66 | { | ||||
67 | // cast option and check | ||||
68 | #if BREEZE_USE_KDE4 | ||||
69 | const auto viewItemOption = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option); | ||||
70 | #else | ||||
71 | const auto viewItemOption = qstyleoption_cast<const QStyleOptionViewItem *>(option); | ||||
72 | #endif | ||||
73 | if (!viewItemOption) | ||||
74 | return false; | ||||
75 | | ||||
76 | // try cast widget | ||||
77 | const auto abstractItemView = qobject_cast<const QAbstractItemView *>(widget); | ||||
78 | | ||||
79 | // store palette and rect | ||||
80 | const auto &palette(option->palette); | ||||
81 | auto rect(option->rect); | ||||
82 | | ||||
83 | // store flags | ||||
84 | const State &state(option->state); | ||||
85 | const bool mouseOver((state & State_MouseOver) && (!abstractItemView || abstractItemView->selectionMode() != QAbstractItemView::NoSelection)); | ||||
86 | const bool selected(state & State_Selected); | ||||
87 | const bool enabled(state & State_Enabled); | ||||
88 | const bool active(state & State_Active); | ||||
89 | | ||||
90 | const bool hasCustomBackground = viewItemOption->backgroundBrush.style() != Qt::NoBrush && !(state & State_Selected); | ||||
91 | const bool hasSolidBackground = !hasCustomBackground || viewItemOption->backgroundBrush.style() == Qt::SolidPattern; | ||||
92 | #if BREEZE_USE_KDE4 | ||||
93 | const bool hasAlternateBackground(viewItemOption->features & QStyleOptionViewItemV2::Alternate); | ||||
94 | #else | ||||
95 | const bool hasAlternateBackground(viewItemOption->features & QStyleOptionViewItem::Alternate); | ||||
96 | #endif | ||||
97 | | ||||
98 | // do nothing if no background is to be rendered | ||||
99 | if (!(mouseOver || selected || hasCustomBackground || hasAlternateBackground)) { | ||||
100 | return true; | ||||
101 | } | ||||
102 | | ||||
103 | // define color group | ||||
104 | QPalette::ColorGroup colorGroup; | ||||
105 | if (enabled) | ||||
106 | colorGroup = active ? QPalette::Active : QPalette::Inactive; | ||||
107 | else | ||||
108 | colorGroup = QPalette::Disabled; | ||||
109 | | ||||
110 | // render alternate background | ||||
111 | if (hasAlternateBackground) { | ||||
112 | painter->setPen(Qt::NoPen); | ||||
113 | painter->setBrush(palette.brush(colorGroup, QPalette::AlternateBase)); | ||||
114 | painter->drawRect(rect); | ||||
115 | } | ||||
116 | | ||||
117 | // stop here if no highlight is needed | ||||
118 | if (!(mouseOver || selected || hasCustomBackground)) { | ||||
119 | return true; | ||||
120 | } | ||||
121 | | ||||
122 | // render custom background | ||||
123 | if (hasCustomBackground && !hasSolidBackground) { | ||||
124 | painter->setBrushOrigin(viewItemOption->rect.topLeft()); | ||||
125 | painter->setBrush(viewItemOption->backgroundBrush); | ||||
126 | painter->setPen(Qt::NoPen); | ||||
127 | painter->drawRect(viewItemOption->rect); | ||||
128 | return true; | ||||
129 | } | ||||
130 | | ||||
131 | // render selection | ||||
132 | // define color | ||||
133 | QColor color; | ||||
134 | if (hasCustomBackground && hasSolidBackground) | ||||
135 | color = viewItemOption->backgroundBrush.color(); | ||||
136 | else | ||||
137 | color = palette.color(colorGroup, QPalette::Highlight); | ||||
138 | | ||||
139 | // change color to implement mouse over | ||||
140 | if (mouseOver && !hasCustomBackground) { | ||||
141 | if (!selected) | ||||
142 | color.setAlphaF(0.2); | ||||
143 | else | ||||
144 | color = color.lighter(110); | ||||
145 | } | ||||
146 | | ||||
147 | // render | ||||
148 | _helper->renderSelection(painter, rect, color); | ||||
149 | | ||||
150 | return true; | ||||
151 | } | ||||
152 | | ||||
153 | //______________________________________________________________________________ | ||||
154 | const QAbstractItemView *Style::itemViewParent(const QWidget *widget) const | ||||
155 | { | ||||
156 | const QAbstractItemView *itemView(nullptr); | ||||
157 | | ||||
158 | // check widget directly | ||||
159 | if ((itemView = qobject_cast<const QAbstractItemView *>(widget))) | ||||
160 | return itemView; | ||||
161 | | ||||
162 | // check widget grand-parent | ||||
163 | else if (widget && widget->parentWidget() && (itemView = qobject_cast<const QAbstractItemView *>(widget->parentWidget()->parentWidget())) && itemView->viewport() == widget->parentWidget()) { | ||||
164 | return itemView; | ||||
165 | } | ||||
166 | | ||||
167 | // return null otherwise | ||||
168 | else | ||||
169 | return nullptr; | ||||
170 | } | ||||
171 | | ||||
172 | //____________________________________________________________________ | ||||
173 | bool Style::isSelectedItem(const QWidget *widget, const QPoint &localPosition) const | ||||
174 | { | ||||
175 | // get relevant itemview parent and check | ||||
176 | const QAbstractItemView *itemView(itemViewParent(widget)); | ||||
177 | if (!(itemView && itemView->hasFocus() && itemView->selectionModel())) | ||||
178 | return false; | ||||
179 | | ||||
180 | #if QT_VERSION >= 0x050000 | ||||
181 | QPoint position = widget->mapTo(itemView, localPosition); | ||||
182 | #else | ||||
183 | // qt4 misses a const for mapTo argument, although nothing is actually changed to the passed widget | ||||
184 | QPoint position = widget->mapTo(const_cast<QAbstractItemView *>(itemView), localPosition); | ||||
185 | #endif | ||||
186 | | ||||
187 | // get matching QModelIndex and check | ||||
188 | const QModelIndex index(itemView->indexAt(position)); | ||||
189 | if (!index.isValid()) | ||||
190 | return false; | ||||
191 | | ||||
192 | // check whether index is selected | ||||
193 | return itemView->selectionModel()->isSelected(index); | ||||
194 | } | ||||
195 | | ||||
196 | //___________________________________________________________________________________ | ||||
197 | bool Style::drawIndicatorBranchPrimitive(const QStyleOption *option, QPainter *painter, const QWidget *) const | ||||
198 | { | ||||
199 | // copy rect and palette | ||||
200 | const auto &rect(option->rect); | ||||
201 | const auto &palette(option->palette); | ||||
202 | | ||||
203 | // state | ||||
204 | const State &state(option->state); | ||||
205 | const bool reverseLayout(option->direction == Qt::RightToLeft); | ||||
206 | | ||||
207 | // draw expander | ||||
208 | int expanderAdjust = 0; | ||||
209 | if (state & State_Children) { | ||||
210 | // state | ||||
211 | const bool expanderOpen(state & State_Open); | ||||
212 | const bool enabled(state & State_Enabled); | ||||
213 | const bool mouseOver(enabled && (state & State_MouseOver)); | ||||
214 | | ||||
215 | // expander rect | ||||
216 | int expanderSize = qMin(rect.width(), rect.height()); | ||||
217 | expanderSize = qMin(expanderSize, int(Metrics::ItemView_ArrowSize)); | ||||
218 | expanderAdjust = expanderSize / 2 + 1; | ||||
219 | const auto arrowRect = centerRect(rect, expanderSize, expanderSize); | ||||
220 | | ||||
221 | // get orientation from option | ||||
222 | ArrowOrientation orientation; | ||||
223 | if (expanderOpen) | ||||
224 | orientation = ArrowDown; | ||||
225 | else if (reverseLayout) | ||||
226 | orientation = ArrowLeft; | ||||
227 | else | ||||
228 | orientation = ArrowRight; | ||||
229 | | ||||
230 | // color | ||||
231 | const auto arrowColor(mouseOver ? _helper->hoverColor(palette) : _helper->arrowColor(palette, QPalette::Text)); | ||||
232 | | ||||
233 | // render | ||||
234 | _helper->renderArrow(painter, arrowRect, arrowColor, orientation); | ||||
235 | } | ||||
236 | | ||||
237 | // tree branches | ||||
238 | if (!StyleConfigData::viewDrawTreeBranchLines()) | ||||
239 | return true; | ||||
240 | | ||||
241 | const auto center(rect.center()); | ||||
242 | const auto lineColor(KColorUtils::mix(palette.color(QPalette::Base), palette.color(QPalette::Text), 0.25)); | ||||
243 | painter->setRenderHint(QPainter::Antialiasing, true); | ||||
244 | painter->translate(0.5, 0.5); | ||||
245 | painter->setPen(QPen(lineColor, 1)); | ||||
246 | if (state & (State_Item | State_Children | State_Sibling)) { | ||||
247 | const QLineF line(QPointF(center.x(), rect.top()), QPointF(center.x(), center.y() - expanderAdjust - 1)); | ||||
248 | painter->drawLine(line); | ||||
249 | } | ||||
250 | | ||||
251 | // The right/left (depending on direction) line gets drawn if we have an item | ||||
252 | if (state & State_Item) { | ||||
253 | const QLineF line = reverseLayout ? QLineF(QPointF(rect.left(), center.y()), QPointF(center.x() - expanderAdjust, center.y())) : QLineF(QPointF(center.x() + expanderAdjust, center.y()), QPointF(rect.right(), center.y())); | ||||
254 | painter->drawLine(line); | ||||
255 | } | ||||
256 | | ||||
257 | // The bottom if we have a sibling | ||||
258 | if (state & State_Sibling) { | ||||
259 | const QLineF line(QPointF(center.x(), center.y() + expanderAdjust), QPointF(center.x(), rect.bottom())); | ||||
260 | painter->drawLine(line); | ||||
261 | } | ||||
262 | | ||||
263 | return true; | ||||
264 | } | ||||
265 | | ||||
266 | } |