23 #include <QApplication>
24 #include <QtGui/QPainter>
26 #include <KGlobalSettings>
28 #include <Plasma/PaintUtils>
34 #define WIDGET_PADDING 8
36 #define max(A, B) ((A) >= (B)) ? (A) : (B)
41 class BasicWidget::Private {
59 Private(
BasicWidget * parent,
const Plasma::Svg & icon, QString title, QString description)
70 parent->setAcceptsHoverEvents(
true);
72 parent->setGroupByName(
"BasicWidget");
75 int shortcutPosition(QString & text)
80 while ((index = text.indexOf(
'&', index)) != -1) {
81 if (index == text.size() - 1) {
85 if (text.at(index + 1) !=
'&') {
90 text.remove(index, 1);
95 void rotatePainterForIcon(QPainter * painter, qreal angle, QRect & iconRect)
98 if (angle != 90 && angle != -90)
return;
100 painter->rotate(angle);
102 iconRect.moveLeft(iconRect.width() / 2);
121 setParentItem(parent);
125 QGraphicsItem * parent)
127 d(
new Private(
this, title, description))
129 setParentItem(parent);
133 QString description, QGraphicsItem * parent)
135 d(new Private(this, icon, title, description))
137 setParentItem(parent);
141 QString description, QGraphicsItem * parent)
143 d(new Private(this, icon, title, description))
145 setParentItem(parent);
154 const QStyleOptionGraphicsItem * option, QWidget * widget)
166 #define setLeft(itemRect, parentRect, alignment) \
167 if ((parentRect).width() > (itemRect).width()) { \
168 if ((alignment) & Qt::AlignHCenter) \
169 (itemRect).moveLeft(WIDGET_PADDING + ((parentRect).width() - (itemRect).width()) / 2); \
170 else if ((alignment) & Qt::AlignRight) \
171 (itemRect).moveLeft(WIDGET_PADDING + (parentRect).width() - (itemRect).width()); \
173 (itemRect).setWidth((parentRect).width()); \
174 (itemRect).moveLeft(WIDGET_PADDING); \
179 bool rtl = QApplication::isRightToLeft();
181 QPainter * _painter = painter;
183 QPixmap foreground(size().toSize().width(), size().toSize().height());
184 foreground.fill(Qt::transparent);
187 QPainter fpainter(&foreground);
198 painter->setPen(QPen(fgColor));
200 QFont titleFont = painter->font();
201 QFont descriptionFont = KGlobalSettings::smallestReadableFont();
206 if (!d->icon.isNull() || d->iconInSvg.isValid()) {
207 iconRect = QRectF(QPointF(), d->iconSize);
208 if (iconRect.width() > geometry().width()) {
209 iconRect.setWidth(geometry().width());
211 if (iconRect.height() > geometry().height()) {
212 iconRect.setHeight(geometry().height());
217 QRectF titleRect = painter->boundingRect(widgetRect,
218 Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine, d->title);
220 painter->setFont(descriptionFont);
221 QRectF descriptionRect = painter->boundingRect(widgetRect,
222 Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine, d->description);
224 if (d->innerOrientation == Qt::Vertical || (d->title.isEmpty() && d->description.isEmpty())) {
229 if (d->alignment & Qt::AlignHCenter) {
230 iconRect.moveLeft(
WIDGET_PADDING + (widgetRect.width() - iconRect.width()) / 2);
231 }
else if (d->alignment & Qt::AlignRight) {
232 iconRect.moveLeft(
WIDGET_PADDING + widgetRect.width() - iconRect.width());
235 setLeft(titleRect, widgetRect, d->alignment);
236 setLeft(descriptionRect, widgetRect, d->alignment);
239 iconRect.height() + titleRect.height() + descriptionRect.height();
241 if ((!d->icon.isNull() || d->iconInSvg.isValid()) && !(d->title.isEmpty() && d->description.isEmpty()))
244 if (d->alignment & Qt::AlignVCenter)
246 if (d->alignment & Qt::AlignBottom)
249 if (!d->icon.isNull() || d->iconInSvg.isValid()) {
251 iconRect.moveTop(top);
252 QRect rect(QPoint(lround(iconRect.left()), lround(iconRect.top())), d->iconSize);
254 d->rotatePainterForIcon(_painter, -rotation(), rect);
256 if (!d->icon.isNull()) {
257 d->icon.paint(_painter, rect);
259 d->iconInSvg.resize(rect.size());
260 d->iconInSvg.paint(_painter, rect.left(), rect.top(),
isHovered()?
"active":
"inactive");
264 d->rotatePainterForIcon(_painter, rotation(), rect);
267 if (!d->title.isEmpty()) {
268 titleRect.moveTop(top);
269 painter->setFont(titleFont);
273 Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine | Qt::ElideRight, d->title,
true);
274 top += titleRect.height();
277 if (!d->description.isEmpty()) {
278 descriptionRect.moveTop(top);
280 painter->setFont(descriptionFont);
284 Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine | Qt::ElideRight, d->description,
false);
289 iconRect.width() + fmaxf(titleRect.width(), descriptionRect.width()) +
292 if (d->alignment & Qt::AlignTop) {
295 descriptionRect.moveTop(titleRect.bottom());
296 }
else if (d->alignment & (Qt::AlignVCenter | Qt::AlignBottom)) {
298 ((d->alignment & Qt::AlignVCenter) ? 0.5 : 1) * (widgetRect.height() - iconRect.height()));
300 ((d->alignment & Qt::AlignVCenter) ? 0.5 : 1) * (widgetRect.height() -
301 ((d->description.isEmpty())?0:descriptionRect.height()) - titleRect.height()));
302 descriptionRect.moveTop(titleRect.bottom());
305 if ((widgetRect.width() < width) || (d->alignment & Qt::AlignLeft)) {
308 titleRect.setWidth(widgetRect.width() - ((!d->icon.isNull() || d->iconInSvg.isValid()) ? iconRect.width() +
WIDGET_PADDING : 0));
309 descriptionRect.setWidth(titleRect.width());
312 titleRect.setWidth(widgetRect.width() - ((!d->icon.isNull() || d->iconInSvg.isValid()) ? iconRect.width() +
WIDGET_PADDING : 0));
313 descriptionRect.setWidth(titleRect.width());
315 }
else if (d->alignment & Qt::AlignHCenter) {
317 iconRect.moveRight(
WIDGET_PADDING + (widgetRect.width() + width) / 2);
319 iconRect.moveLeft(
WIDGET_PADDING + (widgetRect.width() - width) / 2);
323 iconRect.moveRight(widgetRect.width() -
WIDGET_PADDING - (widgetRect.width() - width));
337 if (!d->icon.isNull() || d->iconInSvg.isValid()) {
338 QRect rect(QPoint(lround(iconRect.left()), lround(iconRect.top())), d->iconSize);
340 d->rotatePainterForIcon(_painter, -rotation(), rect);
342 if (!d->icon.isNull()) {
345 mode = QIcon::Disabled;
347 mode = QIcon::Active;
349 mode = QIcon::Normal;
352 d->icon.paint(_painter, rect, Qt::AlignCenter, mode, QIcon::Off);
354 d->iconInSvg.resize(d->iconSize);
355 d->iconInSvg.paint(_painter, rect.left(), rect.top(),
isHovered()?
"active":
"inactive");
358 d->rotatePainterForIcon(_painter, rotation(), rect);
362 if (!d->title.isEmpty()) {
363 painter->setFont(titleFont);
367 Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine, d->title,
true);
370 if (!d->description.isEmpty()) {
372 QPen pen = painter->pen();
373 QColor clr = painter->pen().color();
375 painter->setPen(QPen(clr));
377 painter->setFont(descriptionFont);
381 Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine, d->description,
false);
385 QLinearGradient gradient;
386 if (QApplication::isRightToLeft()) {
387 gradient = QLinearGradient(
391 gradient.setColorAt(0, Qt::transparent);
392 gradient.setColorAt(1, Qt::black);
394 gradient = QLinearGradient(
398 gradient.setColorAt(1, Qt::transparent);
399 gradient.setColorAt(0, Qt::black);
401 painter->setCompositionMode(QPainter::CompositionMode_DestinationIn);
403 0, 0, (
int)ceil(size().width()), (
int)ceil(size().height()),
407 painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
408 _painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
410 _painter->drawPixmap(0, 0, foreground);
439 d->iconInSvg.setImagePath(icon.imagePath());
453 QString
title(value);
454 int pos = d->shortcutPosition(title);
482 return d->description;
486 d->innerOrientation = position;
493 return d->innerOrientation;
509 QSizeF result = QSizeF();
512 case Qt::MinimumSize:
513 result = d->iconSize;
515 case Qt::MaximumSize:
521 result = d->iconSize;
522 QFontMetrics titleMetrics = QFontMetrics(font());
523 QFontMetrics desctiprionMetrics =
524 QFontMetrics(KGlobalSettings::smallestReadableFont());
525 QSizeF textSize = QSizeF(
527 titleMetrics.width(d->title),
528 desctiprionMetrics.width(d->description)
530 (titleMetrics.height()) +
531 (d->description.isEmpty()?0:desctiprionMetrics.height())
534 if (d->innerOrientation == Qt::Horizontal) {
535 result.rwidth() += textSize.width();
537 if (result.height() < textSize.height()) {
538 result.setHeight(textSize.height());
541 result.rheight() += textSize.height();
543 if (result.width() < textSize.width()) {
544 result.setWidth(textSize.width());
551 if (constraint.isValid()) {
552 result = result.boundedTo(constraint);
558 void BasicWidget::drawText(QPainter * painter,
const QRectF & rectangle,
int flags,
const QString & txt,
bool shortcutEnabled)
567 int shortcutPosition = d->shortcutPosition(text);
568 if (shortcutPosition > -1 && shortcutEnabled) {
569 text = text.remove(shortcutPosition - 1, 1);
571 shortcutEnabled =
false;
574 static const int radius = 2;
575 if (
group()->hasProperty(
"BlurTextShadow")) {
576 QColor textColor = painter->pen().color();
578 if (textColor.valueF() * textColor.alphaF() > 0.4) {
579 shadowColor = Qt::black;
581 shadowColor = Qt::white;
584 QPixmap result = Plasma::PaintUtils::shadowText(
585 text, textColor, shadowColor,
586 QPoint(0, 0), radius);
588 if (
group()->hasProperty(
"TextColorBackground")) {
597 painter->setRenderHint(QPainter::Antialiasing);
598 QRectF frect = QRectF(rectangle.topLeft(), result.size());
600 Plasma::PaintUtils::roundedRectangle(
601 frect, 2 * radius), QBrush(bgColor)
605 painter->drawPixmap(rectangle.topLeft(), result);
607 if (shortcutEnabled) {
608 int width = painter->boundingRect(
610 Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine,
611 text.left(shortcutPosition - 1)).width();
612 QPixmap result = Plasma::PaintUtils::shadowText(
613 "_", textColor, shadowColor,
614 QPoint(0, 0), radius);
615 painter->drawPixmap(rectangle.topLeft() + QPoint(width, 0), result);
627 painter->setRenderHint(QPainter::Antialiasing);
628 QRectF frect = painter->boundingRect(rectangle,
629 Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine, text);
630 frect.adjust(- radius, - radius, radius, radius);
632 Plasma::PaintUtils::roundedRectangle(
633 frect, 2*radius), QBrush(bgColor)
636 painter->drawText(rectangle,
637 Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine, text);
639 if (shortcutEnabled) {
640 int width = painter->boundingRect(
642 Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine,
643 text.left(shortcutPosition - 1)).width();
645 QRectF(rectangle.topLeft() + QPoint(width, 0), rectangle.size()),
653 #include "BasicWidget.moc"
const ColorScheme * backgroundColor() const
Background color is one of the common properties, so a direct function that accesses it is provided...
bool hasProperty(const QString &property) const
const ColorScheme * foregroundColor() const
Foreground color is one of the common properties, so a direct function that accesses it is provided...