File indexing completed on 2024-05-19 04:48:57

0001 /***************************************************************************
0002  *   Copyright (c) 2008  Jeff Mitchell <mitchell@kde.org>                  *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or modify  *
0005  *   it under the terms of the GNU General Public License as published by  *
0006  *   the Free Software Foundation; either version 2 of the License, or     *
0007  *   (at your option) any later version.                                   *
0008  *                                                                         *
0009  *   This program is distributed in the hope that it will be useful,       *
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0012  *   GNU General Public License for more details.                          *
0013  *                                                                         *
0014  *   You should have received a copy of the GNU General Public License     *
0015  *   along with this program; if not, write to the                         *
0016  *   Free Software Foundation, Inc.,                                       *
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
0018  ***************************************************************************/
0019 
0020 #include "PopupDropperItem.h"
0021 #include "PopupDropperItem_p.h"
0022 #include "PopupDropper.h"
0023 
0024 #include <QtDebug>
0025 #include <QSvgRenderer>
0026 #include <QAction>
0027 #include <QFont>
0028 
0029 ///////////////////////////////////////////////////////////
0030 
0031 PopupDropperItemPrivate::PopupDropperItemPrivate( PopupDropperItem *parent )
0032     : action( nullptr )
0033     , text( QString() )
0034     , hoverTimer( 500, parent )
0035     , elementId( QString() )
0036     , textItem( nullptr )
0037     , borderRectItem( nullptr )
0038     , svgItem( nullptr )
0039     , hoverIndicatorRectItem( nullptr )
0040     , hoverIndicatorRectFillItem( nullptr )
0041     , borderWidth( 2 )
0042     , hoverIndicatorRectWidth( 15 )
0043     , font()
0044     , submenuTrigger( false )
0045     , baseTextColor()
0046     , hoveredTextColor()
0047     , hoveredBorderPen()
0048     , hoveredFillBrush()
0049     , hoverIndicatorRectFillBrush()
0050     , hoveredOver( false )
0051     , customBaseTextColor( false )
0052     , customHoveredTextColor( false )
0053     , customHoveredBorderPen( false )
0054     , customHoveredFillBrush( false )
0055     , subitemOpacity( 0.0 )
0056     , file( QString() )
0057     , svgElementRect( 0, 0, 50, 50 )
0058     , sharedRenderer( nullptr )
0059     , horizontalOffset( 30 )
0060     , textOffset( 30 )
0061     , separator( false )
0062     , hasLineSeparatorPen( false )
0063     , lineSeparatorPen()
0064     , hoverIndicatorShowStyle( PopupDropperItem::Never )
0065     , orientation( PopupDropperItem::Left )
0066     , textProtection( PopupDropperItem::ScaleFont )
0067     , separatorStyle( PopupDropperItem::TextSeparator )
0068     , pd( nullptr )
0069     , q( parent )
0070     {
0071         hoverTimer.setFrameRange( 0, 30 );
0072         hoverTimer.setUpdateInterval( 20 ); // 50 fps
0073         q->setAcceptDrops( true );
0074         hoverIndicatorRectFillBrush.setColor( Qt::white );
0075         hoveredBorderPen.setWidth( borderWidth );
0076         hoveredBorderPen.setColor( Qt::white );
0077         hoveredBorderPen.setStyle( Qt::SolidLine );
0078         hoveredFillBrush.setColor( Qt::white );
0079         hoveredFillBrush.setStyle( Qt::SolidPattern );
0080     }
0081 
0082 PopupDropperItemPrivate::~PopupDropperItemPrivate()
0083 {
0084 }
0085 
0086 ///////////////////////////////////////////////////////////
0087 
0088 PopupDropperItem::PopupDropperItem( QGraphicsItem *parent )
0089     : QObject()
0090     , QAbstractGraphicsShapeItem( parent )
0091     , d( new PopupDropperItemPrivate( this ) )
0092 {
0093     connect( &d->hoverTimer, &QTimeLine::finished, this, &PopupDropperItem::hoverFinished );
0094     connect( &d->hoverTimer, &QTimeLine::frameChanged, this, &PopupDropperItem::hoverFrameChanged );
0095 }
0096 
0097 PopupDropperItem::PopupDropperItem( const QString &file, QGraphicsItem *parent )
0098     : QObject()
0099     , QAbstractGraphicsShapeItem( parent )
0100     , d( new PopupDropperItemPrivate( this ) )
0101 {
0102     d->file = file;
0103     connect( &d->hoverTimer, &QTimeLine::finished, this, &PopupDropperItem::hoverFinished );
0104     connect( &d->hoverTimer, &QTimeLine::frameChanged, this, &PopupDropperItem::hoverFrameChanged );
0105 }
0106 
0107 PopupDropperItem::~PopupDropperItem()
0108 {
0109     delete d;
0110 }
0111 
0112 void PopupDropperItem::show()
0113 {
0114 }
0115 
0116 QAction* PopupDropperItem::action() const
0117 {
0118     return d->action;
0119 }
0120 
0121 void PopupDropperItem::setAction( QAction *action )
0122 {
0123     if( !action )
0124         return;
0125     //note that this also sets the text
0126     d->action = action;
0127     d->text = action->text();
0128     if( action )
0129     {
0130         if( !d->svgItem )
0131         {
0132             if( !d->file.isEmpty() )
0133                 d->svgItem = new QGraphicsSvgItem( d->file, this );
0134             else
0135                 d->svgItem = new QGraphicsSvgItem( this );
0136         }
0137 
0138         if( d->sharedRenderer )
0139             d->svgItem->setSharedRenderer( d->sharedRenderer );
0140 
0141         if( d->elementId.isEmpty() )
0142             d->elementId = action->property( "popupdropper_svg_id" ).toString();
0143         if( !d->elementId.isEmpty() )
0144         {
0145             if( d->svgItem->renderer() && d->svgItem->renderer()->elementExists( d->elementId ) )
0146                 d->svgItem->setElementId( d->elementId );
0147         }
0148 
0149         if( !d->svgItem->elementId().isEmpty() && d->svgItem->renderer()->elementExists( d->svgItem->elementId() ) )
0150             d->svgItem->show();
0151         else
0152             d->svgItem->hide();
0153  
0154         if( action->isSeparator() )
0155             d->separator = true;
0156         
0157         scaleAndReposSvgItem();
0158 
0159         d->hoverIndicatorRectItem = new QGraphicsRectItem( this );
0160             
0161         QPen pen = d->hoveredBorderPen;
0162         QColor color( pen.color() );
0163         color.setAlpha( 255 );
0164         pen.setColor( color );
0165         d->hoverIndicatorRectItem->setPen( pen );
0166         QBrush brush = d->hoverIndicatorRectItem->brush();
0167         brush.setStyle( Qt::NoBrush );
0168         d->hoverIndicatorRectItem->setBrush( brush );
0169 
0170         d->hoverIndicatorRectFillItem = new QGraphicsRectItem( this );
0171         pen = d->hoverIndicatorRectFillItem->pen();
0172         pen.setStyle( Qt::NoPen );
0173         d->hoverIndicatorRectFillItem->setPen( pen );
0174         d->hoverIndicatorRectFillBrush.setStyle( Qt::SolidPattern );
0175 
0176         if( d->hoverIndicatorShowStyle == PopupDropperItem::AlwaysShow )
0177             d->hoverIndicatorRectItem->show();
0178         else
0179             d->hoverIndicatorRectItem->hide();
0180 
0181         d->hoverIndicatorRectFillItem->hide();
0182 
0183         reposHoverFillRects();
0184     }
0185 
0186     if( d->pd )
0187         d->pd->updateAllOverlays();
0188 }
0189 
0190 PopupDropperItem::HoverIndicatorShowStyle PopupDropperItem::hoverIndicatorShowStyle() const
0191 {
0192     return d->hoverIndicatorShowStyle;
0193 }
0194 
0195 void PopupDropperItem::setHoverIndicatorShowStyle( HoverIndicatorShowStyle hover )
0196 {
0197     d->hoverIndicatorShowStyle = hover;
0198     if( !d->hoveredOver )
0199     {
0200         if( d->hoverIndicatorShowStyle == PopupDropperItem::AlwaysShow )
0201             d->hoverIndicatorRectItem->show();
0202         else
0203             d->hoverIndicatorRectItem->hide();
0204     }
0205 }
0206 
0207 PopupDropperItem::Orientation PopupDropperItem::orientation() const
0208 {
0209     return d->orientation;
0210 }
0211 
0212 void PopupDropperItem::setOrientation( const Orientation orientation )
0213 {
0214     d->orientation = orientation;
0215     fullUpdate();
0216 }
0217 
0218 PopupDropperItem::TextProtection PopupDropperItem::textProtection() const
0219 {
0220     return d->textProtection;
0221 }
0222 
0223 void PopupDropperItem::setTextProtection( const TextProtection textProtection )
0224 {
0225     d->textProtection = textProtection;
0226     fullUpdate();
0227 }
0228 
0229 QString PopupDropperItem::text() const
0230 {
0231     return d->text;
0232 }
0233 
0234 void PopupDropperItem::setText( const QString &text )
0235 {
0236     d->text = text;
0237     if( d->textItem )
0238         d->textItem->setHtml( text );
0239     reposTextItem();
0240 }
0241 
0242 QFont PopupDropperItem::font() const
0243 {
0244     return d->font;
0245 }
0246 
0247 void PopupDropperItem::setFont( const QFont &font )
0248 {
0249     d->font = font;
0250     if( d->textItem )
0251         d->textItem->setFont( font );
0252     reposTextItem();
0253 }
0254 
0255 QColor PopupDropperItem::baseTextColor() const
0256 {
0257     return d->baseTextColor;
0258 }
0259 
0260 void PopupDropperItem::setBaseTextColor( const QColor &color )
0261 {
0262     if( !d->hoveredOver && d->textItem )
0263         d->textItem->setDefaultTextColor( color );
0264     d->baseTextColor = color;
0265     d->customBaseTextColor = true;
0266 }
0267 
0268 QColor PopupDropperItem::hoveredTextColor() const
0269 {
0270     return d->hoveredTextColor;
0271 }
0272 
0273 void PopupDropperItem::setHoveredTextColor( const QColor &color )
0274 {
0275     if( d->textItem && d->hoveredOver && d->hoverTimer.state() != QTimeLine::Running )
0276         d->textItem->setDefaultTextColor( color );
0277     d->hoveredTextColor = color;
0278     d->customHoveredTextColor = true; 
0279 }
0280 
0281 QPen PopupDropperItem::hoveredBorderPen() const
0282 {
0283     return d->hoveredBorderPen;
0284 }
0285 
0286 void PopupDropperItem::setHoveredBorderPen( const QPen &pen )
0287 {
0288     d->hoveredBorderPen = pen;
0289     d->customHoveredBorderPen = true;
0290     if( d->borderRectItem && ( !d->hoveredOver || ( d->hoveredOver && d->hoverTimer.state() != QTimeLine::Running ) ) )
0291     {
0292         QPen borderPen = pen;
0293         if( !d->hoveredOver )
0294         {
0295             QColor pencolor = borderPen.color();
0296             pencolor.setAlpha( 0 );
0297             borderPen.setColor( pencolor );
0298         }
0299         d->borderRectItem->setPen( borderPen );
0300     }
0301     if( d->hoverIndicatorRectItem && ( !d->hoveredOver || ( d->hoveredOver && d->hoverTimer.state() != QTimeLine::Running ) ) )
0302     {
0303         QPen borderPen = d->hoveredBorderPen;
0304         QColor color = borderPen.color();
0305         color.setAlpha( 255 );
0306         borderPen.setColor( color );
0307         d->hoverIndicatorRectItem->setPen( borderPen );
0308     }
0309 }
0310 
0311 QBrush PopupDropperItem::hoveredFillBrush() const
0312 {
0313     return d->hoveredFillBrush;
0314 }
0315 
0316 void PopupDropperItem::setHoveredFillBrush( const QBrush &brush )
0317 {
0318     d->hoveredFillBrush = brush;
0319     d->customHoveredFillBrush = true;
0320     if( d->borderRectItem && ( !d->hoveredOver || ( d->hoveredOver && d->hoverTimer.state() != QTimeLine::Running ) ) )
0321     {
0322         QBrush borderBrush = brush;
0323         if( !d->hoveredOver )
0324         {
0325             QColor brushColor = borderBrush.color();
0326             brushColor.setAlpha( 0 );
0327             borderBrush.setColor( brushColor );
0328         }
0329         d->borderRectItem->setBrush( borderBrush );
0330     }
0331 }
0332 
0333 QBrush PopupDropperItem::hoverIndicatorFillBrush() const
0334 {
0335     return d->hoverIndicatorRectFillBrush;
0336 }
0337 
0338 void PopupDropperItem::setHoverIndicatorFillBrush( const QBrush &brush )
0339 {
0340     d->hoverIndicatorRectFillBrush = brush;
0341     if( d->hoverIndicatorRectFillItem && ( d->hoveredOver && d->hoverTimer.state() != QTimeLine::Running ) )
0342         d->hoverIndicatorRectFillItem->setBrush( d->hoverIndicatorRectFillBrush );
0343 }
0344 
0345 bool PopupDropperItem::customBaseTextColor() const
0346 {
0347     return d->customBaseTextColor;
0348 }
0349 
0350 bool PopupDropperItem::customHoveredTextColor() const
0351 {
0352     return d->customHoveredTextColor;
0353 }
0354 
0355 bool PopupDropperItem::customHoveredBorderPen() const
0356 {
0357     return d->customHoveredBorderPen;
0358 }
0359 
0360 bool PopupDropperItem::customHoveredFillBrush() const
0361 {
0362     return d->customHoveredFillBrush;
0363 }
0364 
0365 qreal PopupDropperItem::subitemOpacity() const
0366 {
0367     return d->subitemOpacity;
0368 }
0369 
0370 void PopupDropperItem::setSubitemOpacity( qreal opacity )
0371 {
0372     if( d->svgItem )
0373         d->svgItem->setOpacity( opacity );
0374     if( d->textItem )
0375         d->textItem->setOpacity( opacity );
0376     if( d->borderRectItem )
0377         d->borderRectItem->setOpacity( opacity );
0378     if( d->hoverIndicatorRectItem )
0379         d->hoverIndicatorRectItem->setOpacity( opacity );
0380     if( d->hoverIndicatorRectFillItem )
0381         d->hoverIndicatorRectFillItem->setOpacity( opacity );
0382 }
0383 
0384 QGraphicsTextItem* PopupDropperItem::textItem() const
0385 {
0386     return d->textItem;
0387 }
0388 
0389 void PopupDropperItem::setTextItem( QGraphicsTextItem *textItem )
0390 {
0391     d->textItem = textItem;
0392     if( d->textItem )
0393         d->textItem->setHtml( d->text );   
0394 }
0395 
0396 QGraphicsRectItem* PopupDropperItem::borderRectItem() const
0397 {
0398     return d->borderRectItem;
0399 }
0400 
0401 void PopupDropperItem::setBorderRectItem( QGraphicsRectItem *borderRectItem )
0402 {
0403     if( !borderRectItem )
0404         return;
0405 
0406     d->borderRectItem = borderRectItem;
0407     if( !d->hoveredOver  )
0408     {
0409         QPen pen = d->hoveredBorderPen;
0410         QColor color = pen.color();
0411         color.setAlpha( 0 );
0412         pen.setColor( color );
0413         d->borderRectItem->setPen( pen );
0414         QBrush brush = d->hoveredFillBrush;
0415         color = brush.color();
0416         color.setAlpha( 0 );
0417         brush.setColor( color );
0418         d->borderRectItem->setBrush( brush );
0419     }
0420 }
0421 
0422 QGraphicsSvgItem* PopupDropperItem::svgItem() const
0423 {
0424     return d->svgItem;
0425 }
0426 
0427 void PopupDropperItem::scaleAndReposSvgItem()
0428 {
0429     if( !d->svgItem || !d->borderRectItem )
0430         return;
0431 
0432     if( d->separator )
0433     {
0434         d->svgItem->setScale( 1.0 );
0435         d->svgItem->setPos( 0, 0 );
0436         return;
0437     }
0438 
0439     //Need to scale if it is too tall or wide
0440     qreal maxheight = d->svgElementRect.height() - ( 2 * d->borderRectItem->pen().width() );
0441     qreal maxwidth = d->svgElementRect.width() - ( 2 * d->borderRectItem->pen().width() );
0442     qreal vertScaleValue = maxheight / d->svgItem->sceneBoundingRect().height();
0443     qreal horizScaleValue = maxwidth / d->svgItem->sceneBoundingRect().width();
0444     qreal scaleValue = vertScaleValue < horizScaleValue ? vertScaleValue : horizScaleValue;
0445     
0446     d->svgItem->setScale( scaleValue );
0447 
0448     qreal item_center = ( d->borderRectItem->sceneBoundingRect().height() / 2 ) + d->borderRectItem->pos().y();
0449 
0450     if( d->orientation == PopupDropperItem::Left )
0451     {
0452         d->svgItem->setPos( d->horizontalOffset, item_center - ( d->svgElementRect.height() / 2 ) );
0453     }
0454     else
0455     {
0456         int rightside;
0457         if( !d->pd || d->pd->viewSize().width() == 0 )
0458             rightside = sceneBoundingRect().width();
0459         else
0460             rightside = d->pd->viewSize().width();
0461 
0462         d->svgItem->setPos(
0463             rightside
0464             - d->svgItem->sceneBoundingRect().width()
0465             - d->horizontalOffset
0466             , item_center - ( d->svgElementRect.height() / 2 ) );
0467     }
0468 }
0469 
0470 void PopupDropperItem::reposTextItem()
0471 {
0472     if( !d->textItem || !d->borderRectItem )
0473         return;
0474     d->textItem->setFont( d->font );
0475 
0476     qreal item_vert_center = ( d->borderRectItem->sceneBoundingRect().height() / 2 ) + d->borderRectItem->pos().y();
0477 
0478     if( d->separator )
0479     {
0480         if( d->text.isEmpty() )
0481             return;
0482         qreal width = d->textItem->textWidth();
0483         if( width > d->borderRectItem->sceneBoundingRect().width() )
0484             d->textItem->setTextWidth( d->borderRectItem->sceneBoundingRect().width() );
0485         qreal offset = ( d->borderRectItem->sceneBoundingRect().width() - width ) / 2;
0486         d->textItem->setPos( offset, item_vert_center - ( d->textItem->sceneBoundingRect().height()  / 2 ) );
0487         return;
0488     }
0489 
0490     int offsetPos = d->horizontalOffset + d->textOffset + d->svgElementRect.width();
0491     d->textItem->setPos(
0492             ( d->orientation == PopupDropperItem::Left
0493                 ? offsetPos
0494                 : 0
0495             )
0496         , item_vert_center - ( d->textItem->sceneBoundingRect().height() / 2 ) ); 
0497 
0498     if( d->textProtection == PopupDropperItem::ScaleFont )
0499     {
0500         QFontMetrics fm( d->textItem->font() );
0501         qreal desiredWidth = d->borderRectItem->sceneBoundingRect().width() - offsetPos;
0502         while( d->textItem->font().pointSize() > 1 &&
0503                 ( fm.horizontalAdvance( d->textItem->toPlainText() ) > desiredWidth ||
0504                   fm.height() > d->textItem->boundingRect().height() ) ) 
0505         {
0506             QFont font = d->textItem->font();
0507             font.setPointSize( font.pointSize() - 1 );
0508             d->textItem->setFont( font );
0509             fm = QFontMetrics( font );
0510         }
0511     }
0512     else if( d->textProtection == PopupDropperItem::MultiLine &&
0513              ( d->textItem->textWidth() == -1 ||
0514                d->textItem->textWidth() > ( d->borderRectItem->sceneBoundingRect().width() - offsetPos )
0515              )
0516            )
0517     {
0518         d->textItem->setTextWidth( d->borderRectItem->sceneBoundingRect().width() - offsetPos );
0519         reposTextItem();
0520     }
0521 }
0522 
0523 void PopupDropperItem::reposHoverFillRects()
0524 {
0525     if( !d->hoverIndicatorRectItem || !d->hoverIndicatorRectFillItem || !d->textItem || !d->borderRectItem )
0526         return;
0527 
0528     if( d->separator )
0529     {
0530         d->hoverIndicatorRectItem->setRect( 0, 0, 0, 0 );
0531         d->hoverIndicatorRectFillItem->setRect( 0, 0, 0, 0 );
0532         return;
0533     }
0534 
0535     //qDebug() << "\n\nPUDItem boundingRect().width() = " << boundingRect().width();
0536     qreal startx, starty, endx, endy, item_center;
0537     //int rightside = d->borderRectItem ? d->borderRectItem->boundingRect().width() : boundingRect().width();
0538     if( d->orientation == PopupDropperItem::Left )
0539     {
0540         startx = d->horizontalOffset
0541                 - d->hoverIndicatorRectWidth
0542                 - ( 2  * d->hoverIndicatorRectItem->pen().width() );
0543     }
0544     else
0545     {
0546         int rightside = (!d->pd || d->pd->viewSize().width() == 0 )
0547                 ? sceneBoundingRect().width()
0548                 : d->pd->viewSize().width();
0549         //qDebug() << "right side = " << rightside;
0550         startx = rightside - d->horizontalOffset
0551                  + d->hoverIndicatorRectWidth
0552                  - ( 2 * d->hoverIndicatorRectItem->pen().width() );
0553     }
0554 
0555     item_center = ( d->borderRectItem->sceneBoundingRect().height() / 2 ) + d->borderRectItem->pos().y();
0556 
0557     starty = item_center - ( d->svgElementRect.height() / 2 );
0558 
0559     endx = d->hoverIndicatorRectWidth - ( 2 * d->hoverIndicatorRectItem->pen().width() );
0560 
0561     endy = d->svgElementRect.height();
0562 
0563     QRectF indicatorRect( startx, starty, endx, endy );
0564     d->hoverIndicatorRectItem->setRect( indicatorRect );
0565 
0566     QRectF indicatorFillRect(
0567             indicatorRect.left() + d->hoverIndicatorRectItem->pen().width()
0568             , indicatorRect.bottom() - d->hoverIndicatorRectItem->pen().width() 
0569             , indicatorRect.width() - ( 2 * d->hoverIndicatorRectItem->pen().width() )
0570             , 0 );
0571     d->hoverIndicatorRectFillItem->setRect( indicatorFillRect );
0572 }
0573 
0574 QSvgRenderer* PopupDropperItem::sharedRenderer() const
0575 {
0576     return d->sharedRenderer;
0577 }
0578 
0579 void PopupDropperItem::setSharedRenderer( QSvgRenderer *renderer )
0580 {
0581     d->sharedRenderer = renderer;
0582     if( renderer && d->svgItem )
0583     {
0584         d->svgItem->setSharedRenderer( renderer );
0585         d->svgItem->setElementId( d->elementId );
0586         if( !d->svgItem->elementId().isEmpty() && d->svgItem->renderer()->elementExists( d->svgItem->elementId() ) )
0587         {
0588             d->svgItem->show();
0589             fullUpdate();
0590         }
0591     }
0592 }
0593 
0594 QString PopupDropperItem::elementId() const
0595 {
0596     return d->elementId;
0597 }
0598 
0599 void PopupDropperItem::setElementId( const QString &id )
0600 {
0601     //qDebug() << "Element ID being set: " << id;
0602     d->elementId = id;
0603     if( id.isEmpty() )
0604     {
0605         d->svgItem->hide();
0606         fullUpdate();
0607     }
0608     else if( d->svgItem && d->svgItem->renderer() && d->svgItem->renderer()->elementExists( id ))
0609     {
0610         d->svgItem->setElementId( id );
0611         d->svgItem->show();
0612         fullUpdate();
0613     }
0614 }
0615 
0616 QRect PopupDropperItem::svgElementRect() const
0617 {
0618     return d->svgElementRect;
0619 }
0620 
0621 void PopupDropperItem::setSvgElementRect( const QRect &rect )
0622 {
0623     d->svgElementRect = rect;
0624 }
0625 
0626 int PopupDropperItem::horizontalOffset() const
0627 {
0628     return d->horizontalOffset;
0629 }
0630 
0631 void PopupDropperItem::setHorizontalOffset( int offset )
0632 {
0633     d->horizontalOffset = offset;
0634 }
0635 
0636 int PopupDropperItem::textOffset() const
0637 {
0638     return d->textOffset;
0639 }
0640 
0641 void PopupDropperItem::setTextOffset( int offset )
0642 {
0643     d->textOffset = offset;
0644 }
0645 
0646 bool PopupDropperItem::isSeparator() const
0647 {
0648     return d->separator;
0649 }
0650 
0651 void PopupDropperItem::setSeparator( bool separator )
0652 {
0653     d->separator = separator;
0654 }
0655 
0656 PopupDropperItem::SeparatorStyle PopupDropperItem::separatorStyle() const
0657 {
0658     return d->separatorStyle;
0659 }
0660 
0661 void PopupDropperItem::setSeparatorStyle( SeparatorStyle style )
0662 {
0663     d->separatorStyle = style;
0664 }
0665 
0666 bool PopupDropperItem::hasLineSeparatorPen() const
0667 {
0668     return d->hasLineSeparatorPen;
0669 }
0670 
0671 QPen PopupDropperItem::lineSeparatorPen() const
0672 {
0673     return d->lineSeparatorPen;
0674 }
0675 
0676 void PopupDropperItem::setLineSeparatorPen( const QPen &pen )
0677 {
0678     d->lineSeparatorPen = pen;
0679 }
0680 
0681 void PopupDropperItem::clearLineSeparatorPen()
0682 {
0683     d->lineSeparatorPen = QPen();
0684     d->hasLineSeparatorPen = false;
0685 }
0686 
0687 int PopupDropperItem::hoverMsecs() const
0688 {
0689     return d->hoverTimer.duration();
0690 }
0691 
0692 void PopupDropperItem::setHoverMsecs( const int msecs )
0693 {
0694     d->hoverTimer.setDuration( msecs );
0695 }
0696 
0697 void PopupDropperItem::hoverEntered()
0698 {
0699     if( d->hoverIndicatorRectItem && d->hoverIndicatorRectFillItem && d->hoverIndicatorShowStyle != PopupDropperItem::Never )
0700     {
0701         d->hoverIndicatorRectFillItem->show();
0702     }
0703     d->hoverTimer.stop();
0704     d->hoverTimer.setDirection( QTimeLine::Forward );
0705     d->hoveredOver = true;
0706     d->hoverTimer.start();
0707 }
0708 
0709 void PopupDropperItem::hoverLeft()
0710 {
0711     d->hoverTimer.stop();
0712     d->hoverTimer.setDirection( QTimeLine::Backward );
0713     d->hoveredOver = false;
0714     if( d->hoverTimer.currentFrame() != 0 )
0715         d->hoverTimer.start();
0716 }
0717 
0718 int PopupDropperItem::borderWidth() const
0719 {
0720     return d->borderWidth;
0721 }
0722 
0723 void PopupDropperItem::setBorderWidth( int borderWidth )
0724 {
0725     d->borderWidth = borderWidth;
0726     d->hoveredBorderPen.setWidth( borderWidth );
0727     if( d->borderRectItem )
0728     {
0729         d->borderRectItem->setPen( d->hoveredBorderPen );
0730     }
0731 }
0732 
0733 int PopupDropperItem::hoverIndicatorRectWidth() const
0734 {
0735     return d->hoverIndicatorRectWidth;
0736 }
0737 
0738 void PopupDropperItem::setHoverIndicatorRectWidth( int hoverIndicatorRectWidth )
0739 {
0740     d->hoverIndicatorRectWidth = hoverIndicatorRectWidth;
0741     if( d->hoverIndicatorRectItem )
0742     {
0743         QPen pen = d->hoverIndicatorRectItem->pen();
0744         pen.setWidth( d->hoverIndicatorRectWidth );
0745         d->hoverIndicatorRectItem->setPen( pen );
0746     }
0747 }
0748 
0749 bool PopupDropperItem::isSubmenuTrigger() const
0750 {
0751     return d->submenuTrigger;
0752 }
0753 
0754 void PopupDropperItem::setSubmenuTrigger( bool trigger )
0755 {
0756     d->submenuTrigger = trigger;
0757 }
0758 
0759 void PopupDropperItem::setPopupDropper( PopupDropper* pd )
0760 {
0761     d->pd = pd;
0762 }
0763 
0764 //bool PopupDropperItem::operator<( const PopupDropperItem &other ) const
0765 //{
0766 //    return d->text < other.text();
0767 //}
0768 
0769 void PopupDropperItem::dropped( QDropEvent *event ) //virtual SLOT
0770 {
0771     Q_UNUSED( event );
0772     d->hoverTimer.stop();
0773     //qDebug() << "PopupDropperItem drop detected";
0774     if( d->action )
0775     {
0776         //qDebug() << "Triggering action";
0777         d->action->activate( QAction::Trigger );
0778     }
0779 }
0780 
0781 void PopupDropperItem::hoverFinished() //SLOT
0782 {
0783     if( d->separator )
0784         return;
0785 
0786     //qDebug() << "direction = forwards ? " << ( d->hoverTimer.direction() == QTimeLine::Forward ? "yes" : "no" );
0787 
0788     if( d->action && d->hoverTimer.direction() == QTimeLine::Forward )
0789         d->action->activate( QAction::Hover );
0790     
0791     if( d->hoverTimer.direction() == QTimeLine::Forward )
0792         d->textItem->setDefaultTextColor( d->hoveredTextColor );
0793     else
0794         d->textItem->setDefaultTextColor( d->baseTextColor );
0795 
0796     //Something is messed up in QTimeLine...I get hoverFinished immediately after doing a hoverLeft, but only sometimes...hence the check
0797     //to see if the timeline isn't running
0798     if( d->hoverIndicatorRectFillItem && d->hoverTimer.state() == QTimeLine::NotRunning && d->hoverTimer.direction() == QTimeLine::Backward )
0799     {
0800         d->hoverIndicatorRectFillItem->hide();
0801         if( d->hoverIndicatorRectItem && d->hoverIndicatorShowStyle != PopupDropperItem::AlwaysShow )
0802             d->hoverIndicatorRectItem->hide();
0803     }
0804     
0805     if( d->pd )
0806         d->pd->updateAllOverlays();
0807 }
0808 
0809 void PopupDropperItem::hoverFrameChanged( int frame ) //SLOT
0810 {
0811     if( d->separator )
0812         return;
0813     //qDebug() << "hoverFrameChanged for " << static_cast<QObject*>(this) << ", frame = " << frame;
0814     int range = d->hoverTimer.endFrame() - d->hoverTimer.startFrame();
0815     qreal multiplier = ( 1.0 * frame ) / range;
0816     int r = (int)( ( d->hoveredTextColor.red() - d->baseTextColor.red() ) * multiplier ) + d->baseTextColor.red();
0817     int g = (int)( ( d->hoveredTextColor.green() - d->baseTextColor.green() ) * multiplier ) + d->baseTextColor.green();
0818     int b = (int)( ( d->hoveredTextColor.blue() - d->baseTextColor.blue() ) * multiplier ) + d->baseTextColor.blue();
0819     int a = (int)( ( d->hoveredTextColor.alpha() - d->baseTextColor.alpha() ) * multiplier ) + d->baseTextColor.alpha();
0820     
0821     d->textItem->setDefaultTextColor( QColor( r, g, b, a ) );
0822     
0823     QColor borderColor = d->hoveredBorderPen.color();
0824     borderColor.setAlpha( (int)( borderColor.alpha() * multiplier ) );
0825     QPen pen = d->borderRectItem->pen();
0826     pen.setColor( borderColor );
0827     d->borderRectItem->setPen( pen );
0828     if( d->hoverIndicatorRectItem && d->hoverIndicatorShowStyle == PopupDropperItem::OnHover )
0829     {
0830         d->hoverIndicatorRectItem->setPen( pen );
0831         d->hoverIndicatorRectItem->show();
0832     }
0833     QColor fillColor = d->hoveredFillBrush.color();
0834     QBrush brush = d->borderRectItem->brush();
0835     fillColor.setAlpha( (int)( fillColor.alpha() * multiplier ) );
0836     brush.setColor( fillColor );
0837     d->borderRectItem->setBrush( brush );
0838 
0839     if( d->hoverIndicatorRectItem && d->hoverIndicatorRectFillItem && d->hoverIndicatorShowStyle != PopupDropperItem::Never )
0840     {
0841         int hoverIndicatorPenWidth = d->hoverIndicatorRectItem->pen().width();
0842         QRectF rect = d->hoverIndicatorRectFillItem->rect();
0843         QRectF outerRect = d->hoverIndicatorRectItem->rect();
0844         rect.setTop( ( multiplier * -1 * ( outerRect.bottom() - outerRect.top() - ( 2 * hoverIndicatorPenWidth ) ) ) 
0845                 + outerRect.bottom() 
0846                 - hoverIndicatorPenWidth );
0847         d->hoverIndicatorRectFillItem->setRect( rect );
0848         d->hoverIndicatorRectFillItem->setBrush( d->hoverIndicatorRectFillBrush );
0849         d->hoverIndicatorRectFillItem->show();
0850         //qDebug() << "hoverIndicatorRectFillItem = " << d->hoverIndicatorRectFillItem;
0851     }
0852 
0853     if( d->pd )
0854         d->pd->updateAllOverlays();
0855 }
0856 
0857 void PopupDropperItem::fullUpdate()
0858 {
0859     scaleAndReposSvgItem();
0860     reposTextItem();
0861     reposHoverFillRects();
0862     if( d->pd )
0863         d->pd->updateAllOverlays();
0864 }
0865 
0866 QRectF PopupDropperItem::boundingRect() const
0867 {
0868     if( d->borderRectItem )
0869         return d->borderRectItem->boundingRect();
0870     else if( d->pd && d->pd->viewSize().width() != 0 )
0871         return QRectF( 0, 0, d->pd->viewSize().width(), d->svgElementRect.height() );
0872     else
0873         return QRectF( 0, 0, d->svgElementRect.width(), d->svgElementRect.height() );
0874 }
0875 
0876 void PopupDropperItem::paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget )
0877 {
0878     Q_UNUSED( painter )
0879     Q_UNUSED( option )
0880     Q_UNUSED( widget )
0881     return;
0882 }
0883 
0884