Changeset View
Changeset View
Standalone View
Standalone View
kstyle/widgets/checkbox.cpp
- This file was added.
1 | #include "breezestyle.h" | ||||
---|---|---|---|---|---|
2 | | ||||
3 | namespace Breeze | ||||
4 | { | ||||
5 | //______________________________________________________________________________ | ||||
6 | QColor Helper::checkBoxIndicatorColor(const QPalette &palette, bool mouseOver, bool active, qreal opacity, AnimationMode mode) const | ||||
7 | { | ||||
8 | QColor color(KColorUtils::mix(palette.color(QPalette::Window), palette.color(QPalette::WindowText), 0.6)); | ||||
9 | if (mode == AnimationHover) { | ||||
10 | const QColor focus(focusColor(palette)); | ||||
11 | const QColor hover(hoverColor(palette)); | ||||
12 | if (active) | ||||
13 | color = KColorUtils::mix(focus, hover, opacity); | ||||
14 | else | ||||
15 | color = KColorUtils::mix(color, hover, opacity); | ||||
16 | | ||||
17 | } else if (mouseOver) { | ||||
18 | color = hoverColor(palette); | ||||
19 | | ||||
20 | } else if (active) { | ||||
21 | color = focusColor(palette); | ||||
22 | } | ||||
23 | | ||||
24 | return color; | ||||
25 | } | ||||
26 | | ||||
27 | //______________________________________________________________________________ | ||||
28 | void Helper::renderCheckBoxBackground(QPainter *painter, const QRect &rect, const QColor &color, bool sunken) const | ||||
29 | { | ||||
30 | // setup painter | ||||
31 | painter->setRenderHint(QPainter::Antialiasing, true); | ||||
32 | | ||||
33 | // copy rect and radius | ||||
34 | QRectF frameRect(rect); | ||||
35 | frameRect.adjust(3, 3, -3, -3); | ||||
36 | | ||||
37 | if (sunken) | ||||
38 | frameRect.translate(1, 1); | ||||
39 | | ||||
40 | painter->setPen(Qt::NoPen); | ||||
41 | painter->setBrush(color); | ||||
42 | painter->drawRect(frameRect); | ||||
43 | } | ||||
44 | | ||||
45 | //______________________________________________________________________________ | ||||
46 | void Helper::renderCheckBox(QPainter *painter, const QRect &rect, const QColor &color, const QColor &shadow, bool sunken, CheckBoxState state, qreal animation) const | ||||
47 | { | ||||
48 | // setup painter | ||||
49 | painter->setRenderHint(QPainter::Antialiasing, true); | ||||
50 | | ||||
51 | // copy rect and radius | ||||
52 | QRectF frameRect(rect); | ||||
53 | frameRect.adjust(2, 2, -2, -2); | ||||
54 | qreal radius(frameRadius()); | ||||
55 | | ||||
56 | // shadow | ||||
57 | if (sunken) { | ||||
58 | frameRect.translate(1, 1); | ||||
59 | | ||||
60 | } else { | ||||
61 | painter->setPen(QPen(shadow, 1)); | ||||
62 | painter->setBrush(Qt::NoBrush); | ||||
63 | | ||||
64 | const qreal shadowRadius(radius + 0.5); | ||||
65 | painter->drawRoundedRect(shadowRect(frameRect).adjusted(-0.5, -0.5, 0.5, 0.5), shadowRadius, shadowRadius); | ||||
66 | } | ||||
67 | | ||||
68 | // content | ||||
69 | { | ||||
70 | painter->setPen(QPen(color, 1)); | ||||
71 | painter->setBrush(Qt::NoBrush); | ||||
72 | | ||||
73 | radius = qMax(radius - 1, qreal(0.0)); | ||||
74 | const QRectF contentRect(frameRect.adjusted(0.5, 0.5, -0.5, -0.5)); | ||||
75 | painter->drawRoundedRect(contentRect, radius, radius); | ||||
76 | } | ||||
77 | | ||||
78 | // mark | ||||
79 | if (state == CheckOn) { | ||||
80 | painter->setBrush(color); | ||||
81 | painter->setPen(Qt::NoPen); | ||||
82 | | ||||
83 | const QRectF markerRect(frameRect.adjusted(3, 3, -3, -3)); | ||||
84 | painter->drawRect(markerRect); | ||||
85 | | ||||
86 | } else if (state == CheckPartial) { | ||||
87 | QPen pen(color, 2); | ||||
88 | pen.setJoinStyle(Qt::MiterJoin); | ||||
89 | painter->setPen(pen); | ||||
90 | | ||||
91 | const QRectF markerRect(frameRect.adjusted(4, 4, -4, -4)); | ||||
92 | painter->drawRect(markerRect); | ||||
93 | | ||||
94 | painter->setPen(Qt::NoPen); | ||||
95 | painter->setBrush(color); | ||||
96 | painter->setRenderHint(QPainter::Antialiasing, false); | ||||
97 | | ||||
98 | QPainterPath path; | ||||
99 | path.moveTo(markerRect.topLeft()); | ||||
100 | path.lineTo(markerRect.right() - 1, markerRect.top()); | ||||
101 | path.lineTo(markerRect.left(), markerRect.bottom() - 1); | ||||
102 | painter->drawPath(path); | ||||
103 | | ||||
104 | } else if (state == CheckAnimated) { | ||||
105 | const QRectF markerRect(frameRect.adjusted(3, 3, -3, -3)); | ||||
106 | QPainterPath path; | ||||
107 | path.moveTo(markerRect.topRight()); | ||||
108 | path.lineTo(markerRect.center() + animation * (markerRect.topLeft() - markerRect.center())); | ||||
109 | path.lineTo(markerRect.bottomLeft()); | ||||
110 | path.lineTo(markerRect.center() + animation * (markerRect.bottomRight() - markerRect.center())); | ||||
111 | path.closeSubpath(); | ||||
112 | | ||||
113 | painter->setBrush(color); | ||||
114 | painter->setPen(Qt::NoPen); | ||||
115 | painter->drawPath(path); | ||||
116 | } | ||||
117 | } | ||||
118 | | ||||
119 | //___________________________________________________________________________________________________________________ | ||||
120 | QRect Style::checkBoxContentsRect(const QStyleOption *option, const QWidget *) const | ||||
121 | { | ||||
122 | return visualRect(option, option->rect.adjusted(Metrics::CheckBox_Size + Metrics::CheckBox_ItemSpacing, 0, 0, 0)); | ||||
123 | } | ||||
124 | | ||||
125 | //______________________________________________________________ | ||||
126 | QSize Style::checkBoxSizeFromContents(const QStyleOption *, const QSize &contentsSize, const QWidget *) const | ||||
127 | { | ||||
128 | // get contents size | ||||
129 | QSize size(contentsSize); | ||||
130 | | ||||
131 | // add focus height | ||||
132 | size = expandSize(size, 0, Metrics::CheckBox_FocusMarginWidth); | ||||
133 | | ||||
134 | // make sure there is enough height for indicator | ||||
135 | size.setHeight(qMax(size.height(), int(Metrics::CheckBox_Size))); | ||||
136 | | ||||
137 | // Add space for the indicator and the icon | ||||
138 | size.rwidth() += Metrics::CheckBox_Size + Metrics::CheckBox_ItemSpacing; | ||||
139 | | ||||
140 | // also add extra space, to leave room to the right of the label | ||||
141 | size.rwidth() += Metrics::CheckBox_ItemSpacing; | ||||
142 | | ||||
143 | return size; | ||||
144 | } | ||||
145 | | ||||
146 | //___________________________________________________________________________________ | ||||
147 | bool Style::drawIndicatorCheckBoxPrimitive(const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
148 | { | ||||
149 | // copy rect and palette | ||||
150 | const auto &rect(option->rect); | ||||
151 | const auto &palette(option->palette); | ||||
152 | | ||||
153 | // store flags | ||||
154 | const State &state(option->state); | ||||
155 | const bool enabled(state & State_Enabled); | ||||
156 | const bool mouseOver(enabled && (state & State_MouseOver)); | ||||
157 | const bool sunken(enabled && (state & State_Sunken)); | ||||
158 | const bool active((state & (State_On | State_NoChange))); | ||||
159 | | ||||
160 | // checkbox state | ||||
161 | CheckBoxState checkBoxState(CheckOff); | ||||
162 | if (state & State_NoChange) | ||||
163 | checkBoxState = CheckPartial; | ||||
164 | else if (state & State_On) | ||||
165 | checkBoxState = CheckOn; | ||||
166 | | ||||
167 | // detect checkboxes in lists | ||||
168 | const bool isSelectedItem(this->isSelectedItem(widget, rect.center())); | ||||
169 | | ||||
170 | // animation state | ||||
171 | _animations->widgetStateEngine().updateState(widget, AnimationHover, mouseOver); | ||||
172 | _animations->widgetStateEngine().updateState(widget, AnimationPressed, checkBoxState != CheckOff); | ||||
173 | if (_animations->widgetStateEngine().isAnimated(widget, AnimationPressed)) | ||||
174 | checkBoxState = CheckAnimated; | ||||
175 | const qreal animation(_animations->widgetStateEngine().opacity(widget, AnimationPressed)); | ||||
176 | | ||||
177 | QColor color; | ||||
178 | if (isSelectedItem) { | ||||
179 | color = _helper->checkBoxIndicatorColor(palette, false, enabled && active); | ||||
180 | _helper->renderCheckBoxBackground(painter, rect, palette.color(QPalette::Base), sunken); | ||||
181 | | ||||
182 | } else { | ||||
183 | const AnimationMode mode(_animations->widgetStateEngine().isAnimated(widget, AnimationHover) ? AnimationHover : AnimationNone); | ||||
184 | const qreal opacity(_animations->widgetStateEngine().opacity(widget, AnimationHover)); | ||||
185 | color = _helper->checkBoxIndicatorColor(palette, mouseOver, enabled && active, opacity, mode); | ||||
186 | } | ||||
187 | | ||||
188 | // render | ||||
189 | const auto shadow(_helper->shadowColor(palette)); | ||||
190 | _helper->renderCheckBox(painter, rect, color, shadow, sunken, checkBoxState, animation); | ||||
191 | return true; | ||||
192 | } | ||||
193 | | ||||
194 | //___________________________________________________________________________________ | ||||
195 | bool Style::drawCheckBoxLabelControl(const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
196 | { | ||||
197 | // cast option and check | ||||
198 | const auto buttonOption(qstyleoption_cast<const QStyleOptionButton *>(option)); | ||||
199 | if (!buttonOption) | ||||
200 | return true; | ||||
201 | | ||||
202 | // copy palette and rect | ||||
203 | const auto &palette(option->palette); | ||||
204 | const auto &rect(option->rect); | ||||
205 | | ||||
206 | // store state | ||||
207 | const State &state(option->state); | ||||
208 | const bool enabled(state & State_Enabled); | ||||
209 | | ||||
210 | // text alignment | ||||
211 | const bool reverseLayout(option->direction == Qt::RightToLeft); | ||||
212 | const int textFlags(_mnemonics->textFlags() | Qt::AlignVCenter | (reverseLayout ? Qt::AlignRight : Qt::AlignLeft)); | ||||
213 | | ||||
214 | // text rect | ||||
215 | auto textRect(rect); | ||||
216 | | ||||
217 | // render icon | ||||
218 | if (!buttonOption->icon.isNull()) { | ||||
219 | const QIcon::Mode mode(enabled ? QIcon::Normal : QIcon::Disabled); | ||||
220 | const QPixmap pixmap(buttonOption->icon.pixmap(buttonOption->iconSize, mode)); | ||||
221 | drawItemPixmap(painter, rect, textFlags, pixmap); | ||||
222 | | ||||
223 | // adjust rect (copied from QCommonStyle) | ||||
224 | textRect.setLeft(textRect.left() + buttonOption->iconSize.width() + 4); | ||||
225 | textRect = visualRect(option, textRect); | ||||
226 | } | ||||
227 | | ||||
228 | // render text | ||||
229 | if (!buttonOption->text.isEmpty()) { | ||||
230 | textRect = option->fontMetrics.boundingRect(textRect, textFlags, buttonOption->text); | ||||
231 | drawItemText(painter, textRect, textFlags, palette, enabled, buttonOption->text, QPalette::WindowText); | ||||
232 | | ||||
233 | // check focus state | ||||
234 | const bool hasFocus(enabled && (state & State_HasFocus)); | ||||
235 | | ||||
236 | // update animation state | ||||
237 | _animations->widgetStateEngine().updateState(widget, AnimationFocus, hasFocus); | ||||
238 | const bool isFocusAnimated(_animations->widgetStateEngine().isAnimated(widget, AnimationFocus)); | ||||
239 | const qreal opacity(_animations->widgetStateEngine().opacity(widget, AnimationFocus)); | ||||
240 | | ||||
241 | // focus color | ||||
242 | QColor focusColor; | ||||
243 | if (isFocusAnimated) | ||||
244 | focusColor = _helper->alphaColor(_helper->focusColor(palette), opacity); | ||||
245 | else if (hasFocus) | ||||
246 | focusColor = _helper->focusColor(palette); | ||||
247 | | ||||
248 | // render focus | ||||
249 | _helper->renderFocusLine(painter, textRect, focusColor); | ||||
250 | } | ||||
251 | | ||||
252 | return true; | ||||
253 | } | ||||
254 | | ||||
255 | } |