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...