1 /***************************************************************************
2 * Copyright (c) 2008 Jeff Mitchell <mitchell@kde.org> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
19
20 #include "PopupDropperItem.h"
21 #include "PopupDropperItem_p.h"
22 #include "PopupDropper.h"
23
24 #include <QtDebug>
25 #include <QSvgRenderer>
26 #include <QAction>
27 #include <QFont>
28
29 ///////////////////////////////////////////////////////////
30
PopupDropperItemPrivate(PopupDropperItem * parent)31 PopupDropperItemPrivate::PopupDropperItemPrivate( PopupDropperItem *parent )
32 : action( 0 )
33 , text( QString() )
34 , hoverTimer( 500, parent )
35 , elementId( QString() )
36 , textItem( 0 )
37 , borderRectItem( 0 )
38 , svgItem( 0 )
39 , hoverIndicatorRectItem( 0 )
40 , hoverIndicatorRectFillItem( 0 )
41 , borderWidth( 2 )
42 , hoverIndicatorRectWidth( 15 )
43 , font()
44 , submenuTrigger( false )
45 , baseTextColor()
46 , hoveredTextColor()
47 , hoveredBorderPen()
48 , hoveredFillBrush()
49 , hoverIndicatorRectFillBrush()
50 , hoveredOver( false )
51 , customBaseTextColor( false )
52 , customHoveredTextColor( false )
53 , customHoveredBorderPen( false )
54 , customHoveredFillBrush( false )
55 , subitemOpacity( 0.0 )
56 , file( QString() )
57 , svgElementRect( 0, 0, 50, 50 )
58 , sharedRenderer( 0 )
59 , horizontalOffset( 30 )
60 , textOffset( 30 )
61 , separator( false )
62 , hasLineSeparatorPen( false )
63 , lineSeparatorPen()
64 , hoverIndicatorShowStyle( PopupDropperItem::Never )
65 , orientation( PopupDropperItem::Left )
66 , textProtection( PopupDropperItem::ScaleFont )
67 , separatorStyle( PopupDropperItem::TextSeparator )
68 , pd( 0 )
69 , q( parent )
70 {
71 hoverTimer.setFrameRange( 0, 30 );
72 hoverTimer.setUpdateInterval( 20 ); // 50 fps
73 q->setAcceptDrops( true );
74 hoverIndicatorRectFillBrush.setColor( Qt::white );
75 hoveredBorderPen.setWidth( borderWidth );
76 hoveredBorderPen.setColor( Qt::white );
77 hoveredBorderPen.setStyle( Qt::SolidLine );
78 hoveredFillBrush.setColor( Qt::white );
79 hoveredFillBrush.setStyle( Qt::SolidPattern );
80 }
81
~PopupDropperItemPrivate()82 PopupDropperItemPrivate::~PopupDropperItemPrivate()
83 {
84 }
85
86 ///////////////////////////////////////////////////////////
87
PopupDropperItem(QGraphicsItem * parent)88 PopupDropperItem::PopupDropperItem( QGraphicsItem *parent )
89 : QObject()
90 , QAbstractGraphicsShapeItem( parent )
91 , d( new PopupDropperItemPrivate( this ) )
92 {
93 connect( &d->hoverTimer, &QTimeLine::finished, this, &PopupDropperItem::hoverFinished );
94 connect( &d->hoverTimer, &QTimeLine::frameChanged, this, &PopupDropperItem::hoverFrameChanged );
95 }
96
PopupDropperItem(const QString & file,QGraphicsItem * parent)97 PopupDropperItem::PopupDropperItem( const QString &file, QGraphicsItem *parent )
98 : QObject()
99 , QAbstractGraphicsShapeItem( parent )
100 , d( new PopupDropperItemPrivate( this ) )
101 {
102 d->file = file;
103 connect( &d->hoverTimer, &QTimeLine::finished, this, &PopupDropperItem::hoverFinished );
104 connect( &d->hoverTimer, &QTimeLine::frameChanged, this, &PopupDropperItem::hoverFrameChanged );
105 }
106
~PopupDropperItem()107 PopupDropperItem::~PopupDropperItem()
108 {
109 delete d;
110 }
111
show()112 void PopupDropperItem::show()
113 {
114 }
115
action() const116 QAction* PopupDropperItem::action() const
117 {
118 return d->action;
119 }
120
setAction(QAction * action)121 void PopupDropperItem::setAction( QAction *action )
122 {
123 if( !action )
124 return;
125 //note that this also sets the text
126 d->action = action;
127 d->text = action->text();
128 if( action )
129 {
130 if( !d->svgItem )
131 {
132 if( !d->file.isEmpty() )
133 d->svgItem = new QGraphicsSvgItem( d->file, this );
134 else
135 d->svgItem = new QGraphicsSvgItem( this );
136 }
137
138 if( d->sharedRenderer )
139 d->svgItem->setSharedRenderer( d->sharedRenderer );
140
141 if( d->elementId.isEmpty() )
142 d->elementId = action->property( "popupdropper_svg_id" ).toString();
143 if( !d->elementId.isEmpty() )
144 {
145 if( d->svgItem->renderer() && d->svgItem->renderer()->elementExists( d->elementId ) )
146 d->svgItem->setElementId( d->elementId );
147 }
148
149 if( !d->svgItem->elementId().isEmpty() && d->svgItem->renderer()->elementExists( d->svgItem->elementId() ) )
150 d->svgItem->show();
151 else
152 d->svgItem->hide();
153
154 if( action->isSeparator() )
155 d->separator = true;
156
157 scaleAndReposSvgItem();
158
159 d->hoverIndicatorRectItem = new QGraphicsRectItem( this );
160
161 QPen pen = d->hoveredBorderPen;
162 QColor color( pen.color() );
163 color.setAlpha( 255 );
164 pen.setColor( color );
165 d->hoverIndicatorRectItem->setPen( pen );
166 QBrush brush = d->hoverIndicatorRectItem->brush();
167 brush.setStyle( Qt::NoBrush );
168 d->hoverIndicatorRectItem->setBrush( brush );
169
170 d->hoverIndicatorRectFillItem = new QGraphicsRectItem( this );
171 pen = d->hoverIndicatorRectFillItem->pen();
172 pen.setStyle( Qt::NoPen );
173 d->hoverIndicatorRectFillItem->setPen( pen );
174 d->hoverIndicatorRectFillBrush.setStyle( Qt::SolidPattern );
175
176 if( d->hoverIndicatorShowStyle == PopupDropperItem::AlwaysShow )
177 d->hoverIndicatorRectItem->show();
178 else
179 d->hoverIndicatorRectItem->hide();
180
181 d->hoverIndicatorRectFillItem->hide();
182
183 reposHoverFillRects();
184 }
185
186 if( d->pd )
187 d->pd->updateAllOverlays();
188 }
189
hoverIndicatorShowStyle() const190 PopupDropperItem::HoverIndicatorShowStyle PopupDropperItem::hoverIndicatorShowStyle() const
191 {
192 return d->hoverIndicatorShowStyle;
193 }
194
setHoverIndicatorShowStyle(HoverIndicatorShowStyle hover)195 void PopupDropperItem::setHoverIndicatorShowStyle( HoverIndicatorShowStyle hover )
196 {
197 d->hoverIndicatorShowStyle = hover;
198 if( !d->hoveredOver )
199 {
200 if( d->hoverIndicatorShowStyle == PopupDropperItem::AlwaysShow )
201 d->hoverIndicatorRectItem->show();
202 else
203 d->hoverIndicatorRectItem->hide();
204 }
205 }
206
orientation() const207 PopupDropperItem::Orientation PopupDropperItem::orientation() const
208 {
209 return d->orientation;
210 }
211
setOrientation(const Orientation orientation)212 void PopupDropperItem::setOrientation( const Orientation orientation )
213 {
214 d->orientation = orientation;
215 fullUpdate();
216 }
217
textProtection() const218 PopupDropperItem::TextProtection PopupDropperItem::textProtection() const
219 {
220 return d->textProtection;
221 }
222
setTextProtection(const TextProtection textProtection)223 void PopupDropperItem::setTextProtection( const TextProtection textProtection )
224 {
225 d->textProtection = textProtection;
226 fullUpdate();
227 }
228
text() const229 QString PopupDropperItem::text() const
230 {
231 return d->text;
232 }
233
setText(const QString & text)234 void PopupDropperItem::setText( const QString &text )
235 {
236 d->text = text;
237 if( d->textItem )
238 d->textItem->setHtml( text );
239 reposTextItem();
240 }
241
font() const242 QFont PopupDropperItem::font() const
243 {
244 return d->font;
245 }
246
setFont(const QFont & font)247 void PopupDropperItem::setFont( const QFont &font )
248 {
249 d->font = font;
250 if( d->textItem )
251 d->textItem->setFont( font );
252 reposTextItem();
253 }
254
baseTextColor() const255 QColor PopupDropperItem::baseTextColor() const
256 {
257 return d->baseTextColor;
258 }
259
setBaseTextColor(const QColor & color)260 void PopupDropperItem::setBaseTextColor( const QColor &color )
261 {
262 if( !d->hoveredOver && d->textItem )
263 d->textItem->setDefaultTextColor( color );
264 d->baseTextColor = color;
265 d->customBaseTextColor = true;
266 }
267
hoveredTextColor() const268 QColor PopupDropperItem::hoveredTextColor() const
269 {
270 return d->hoveredTextColor;
271 }
272
setHoveredTextColor(const QColor & color)273 void PopupDropperItem::setHoveredTextColor( const QColor &color )
274 {
275 if( d->textItem && d->hoveredOver && d->hoverTimer.state() != QTimeLine::Running )
276 d->textItem->setDefaultTextColor( color );
277 d->hoveredTextColor = color;
278 d->customHoveredTextColor = true;
279 }
280
hoveredBorderPen() const281 QPen PopupDropperItem::hoveredBorderPen() const
282 {
283 return d->hoveredBorderPen;
284 }
285
setHoveredBorderPen(const QPen & pen)286 void PopupDropperItem::setHoveredBorderPen( const QPen &pen )
287 {
288 d->hoveredBorderPen = pen;
289 d->customHoveredBorderPen = true;
290 if( d->borderRectItem && ( !d->hoveredOver || ( d->hoveredOver && d->hoverTimer.state() != QTimeLine::Running ) ) )
291 {
292 QPen borderPen = pen;
293 if( !d->hoveredOver )
294 {
295 QColor pencolor = borderPen.color();
296 pencolor.setAlpha( 0 );
297 borderPen.setColor( pencolor );
298 }
299 d->borderRectItem->setPen( borderPen );
300 }
301 if( d->hoverIndicatorRectItem && ( !d->hoveredOver || ( d->hoveredOver && d->hoverTimer.state() != QTimeLine::Running ) ) )
302 {
303 QPen borderPen = d->hoveredBorderPen;
304 QColor color = borderPen.color();
305 color.setAlpha( 255 );
306 borderPen.setColor( color );
307 d->hoverIndicatorRectItem->setPen( borderPen );
308 }
309 }
310
hoveredFillBrush() const311 QBrush PopupDropperItem::hoveredFillBrush() const
312 {
313 return d->hoveredFillBrush;
314 }
315
setHoveredFillBrush(const QBrush & brush)316 void PopupDropperItem::setHoveredFillBrush( const QBrush &brush )
317 {
318 d->hoveredFillBrush = brush;
319 d->customHoveredFillBrush = true;
320 if( d->borderRectItem && ( !d->hoveredOver || ( d->hoveredOver && d->hoverTimer.state() != QTimeLine::Running ) ) )
321 {
322 QBrush borderBrush = brush;
323 if( !d->hoveredOver )
324 {
325 QColor brushColor = borderBrush.color();
326 brushColor.setAlpha( 0 );
327 borderBrush.setColor( brushColor );
328 }
329 d->borderRectItem->setBrush( borderBrush );
330 }
331 }
332
hoverIndicatorFillBrush() const333 QBrush PopupDropperItem::hoverIndicatorFillBrush() const
334 {
335 return d->hoverIndicatorRectFillBrush;
336 }
337
setHoverIndicatorFillBrush(const QBrush & brush)338 void PopupDropperItem::setHoverIndicatorFillBrush( const QBrush &brush )
339 {
340 d->hoverIndicatorRectFillBrush = brush;
341 if( d->hoverIndicatorRectFillItem && ( d->hoveredOver && d->hoverTimer.state() != QTimeLine::Running ) )
342 d->hoverIndicatorRectFillItem->setBrush( d->hoverIndicatorRectFillBrush );
343 }
344
customBaseTextColor() const345 bool PopupDropperItem::customBaseTextColor() const
346 {
347 return d->customBaseTextColor;
348 }
349
customHoveredTextColor() const350 bool PopupDropperItem::customHoveredTextColor() const
351 {
352 return d->customHoveredTextColor;
353 }
354
customHoveredBorderPen() const355 bool PopupDropperItem::customHoveredBorderPen() const
356 {
357 return d->customHoveredBorderPen;
358 }
359
customHoveredFillBrush() const360 bool PopupDropperItem::customHoveredFillBrush() const
361 {
362 return d->customHoveredFillBrush;
363 }
364
subitemOpacity() const365 qreal PopupDropperItem::subitemOpacity() const
366 {
367 return d->subitemOpacity;
368 }
369
setSubitemOpacity(qreal opacity)370 void PopupDropperItem::setSubitemOpacity( qreal opacity )
371 {
372 if( d->svgItem )
373 d->svgItem->setOpacity( opacity );
374 if( d->textItem )
375 d->textItem->setOpacity( opacity );
376 if( d->borderRectItem )
377 d->borderRectItem->setOpacity( opacity );
378 if( d->hoverIndicatorRectItem )
379 d->hoverIndicatorRectItem->setOpacity( opacity );
380 if( d->hoverIndicatorRectFillItem )
381 d->hoverIndicatorRectFillItem->setOpacity( opacity );
382 }
383
textItem() const384 QGraphicsTextItem* PopupDropperItem::textItem() const
385 {
386 return d->textItem;
387 }
388
setTextItem(QGraphicsTextItem * textItem)389 void PopupDropperItem::setTextItem( QGraphicsTextItem *textItem )
390 {
391 d->textItem = textItem;
392 if( d->textItem )
393 d->textItem->setHtml( d->text );
394 }
395
borderRectItem() const396 QGraphicsRectItem* PopupDropperItem::borderRectItem() const
397 {
398 return d->borderRectItem;
399 }
400
setBorderRectItem(QGraphicsRectItem * borderRectItem)401 void PopupDropperItem::setBorderRectItem( QGraphicsRectItem *borderRectItem )
402 {
403 if( !borderRectItem )
404 return;
405
406 d->borderRectItem = borderRectItem;
407 if( !d->hoveredOver )
408 {
409 QPen pen = d->hoveredBorderPen;
410 QColor color = pen.color();
411 color.setAlpha( 0 );
412 pen.setColor( color );
413 d->borderRectItem->setPen( pen );
414 QBrush brush = d->hoveredFillBrush;
415 color = brush.color();
416 color.setAlpha( 0 );
417 brush.setColor( color );
418 d->borderRectItem->setBrush( brush );
419 }
420 }
421
svgItem() const422 QGraphicsSvgItem* PopupDropperItem::svgItem() const
423 {
424 return d->svgItem;
425 }
426
scaleAndReposSvgItem()427 void PopupDropperItem::scaleAndReposSvgItem()
428 {
429 if( !d->svgItem || !d->borderRectItem )
430 return;
431
432 if( d->separator )
433 {
434 d->svgItem->setScale( 1.0 );
435 d->svgItem->setPos( 0, 0 );
436 return;
437 }
438
439 //Need to scale if it is too tall or wide
440 qreal maxheight = d->svgElementRect.height() - ( 2 * d->borderRectItem->pen().width() );
441 qreal maxwidth = d->svgElementRect.width() - ( 2 * d->borderRectItem->pen().width() );
442 qreal vertScaleValue = maxheight / d->svgItem->sceneBoundingRect().height();
443 qreal horizScaleValue = maxwidth / d->svgItem->sceneBoundingRect().width();
444 qreal scaleValue = vertScaleValue < horizScaleValue ? vertScaleValue : horizScaleValue;
445
446 d->svgItem->setScale( scaleValue );
447
448 qreal item_center = ( d->borderRectItem->sceneBoundingRect().height() / 2 ) + d->borderRectItem->pos().y();
449
450 if( d->orientation == PopupDropperItem::Left )
451 {
452 d->svgItem->setPos( d->horizontalOffset, item_center - ( d->svgElementRect.height() / 2 ) );
453 }
454 else
455 {
456 int rightside;
457 if( !d->pd || d->pd->viewSize().width() == 0 )
458 rightside = sceneBoundingRect().width();
459 else
460 rightside = d->pd->viewSize().width();
461
462 d->svgItem->setPos(
463 rightside
464 - d->svgItem->sceneBoundingRect().width()
465 - d->horizontalOffset
466 , item_center - ( d->svgElementRect.height() / 2 ) );
467 }
468 }
469
reposTextItem()470 void PopupDropperItem::reposTextItem()
471 {
472 if( !d->textItem || !d->borderRectItem )
473 return;
474 d->textItem->setFont( d->font );
475
476 qreal item_vert_center = ( d->borderRectItem->sceneBoundingRect().height() / 2 ) + d->borderRectItem->pos().y();
477
478 if( d->separator )
479 {
480 if( d->text.isEmpty() )
481 return;
482 qreal width = d->textItem->textWidth();
483 if( width > d->borderRectItem->sceneBoundingRect().width() )
484 d->textItem->setTextWidth( d->borderRectItem->sceneBoundingRect().width() );
485 qreal offset = ( d->borderRectItem->sceneBoundingRect().width() - width ) / 2;
486 d->textItem->setPos( offset, item_vert_center - ( d->textItem->sceneBoundingRect().height() / 2 ) );
487 return;
488 }
489
490 int offsetPos = d->horizontalOffset + d->textOffset + d->svgElementRect.width();
491 d->textItem->setPos(
492 ( d->orientation == PopupDropperItem::Left
493 ? offsetPos
494 : 0
495 )
496 , item_vert_center - ( d->textItem->sceneBoundingRect().height() / 2 ) );
497
498 if( d->textProtection == PopupDropperItem::ScaleFont )
499 {
500 QFontMetrics fm( d->textItem->font() );
501 qreal desiredWidth = d->borderRectItem->sceneBoundingRect().width() - offsetPos;
502 while( d->textItem->font().pointSize() > 1 &&
503 ( fm.width( d->textItem->toPlainText() ) > desiredWidth ||
504 fm.height() > d->textItem->boundingRect().height() ) )
505 {
506 QFont font = d->textItem->font();
507 font.setPointSize( font.pointSize() - 1 );
508 d->textItem->setFont( font );
509 fm = QFontMetrics( font );
510 }
511 }
512 else if( d->textProtection == PopupDropperItem::MultiLine &&
513 ( d->textItem->textWidth() == -1 ||
514 d->textItem->textWidth() > ( d->borderRectItem->sceneBoundingRect().width() - offsetPos )
515 )
516 )
517 {
518 d->textItem->setTextWidth( d->borderRectItem->sceneBoundingRect().width() - offsetPos );
519 reposTextItem();
520 }
521 }
522
reposHoverFillRects()523 void PopupDropperItem::reposHoverFillRects()
524 {
525 if( !d->hoverIndicatorRectItem || !d->hoverIndicatorRectFillItem || !d->textItem || !d->borderRectItem )
526 return;
527
528 if( d->separator )
529 {
530 d->hoverIndicatorRectItem->setRect( 0, 0, 0, 0 );
531 d->hoverIndicatorRectFillItem->setRect( 0, 0, 0, 0 );
532 return;
533 }
534
535 //qDebug() << "\n\nPUDItem boundingRect().width() = " << boundingRect().width();
536 qreal startx, starty, endx, endy, item_center;
537 //int rightside = d->borderRectItem ? d->borderRectItem->boundingRect().width() : boundingRect().width();
538 if( d->orientation == PopupDropperItem::Left )
539 {
540 startx = d->horizontalOffset
541 - d->hoverIndicatorRectWidth
542 - ( 2 * d->hoverIndicatorRectItem->pen().width() );
543 }
544 else
545 {
546 int rightside = (!d->pd || d->pd->viewSize().width() == 0 )
547 ? sceneBoundingRect().width()
548 : d->pd->viewSize().width();
549 //qDebug() << "right side = " << rightside;
550 startx = rightside - d->horizontalOffset
551 + d->hoverIndicatorRectWidth
552 - ( 2 * d->hoverIndicatorRectItem->pen().width() );
553 }
554
555 item_center = ( d->borderRectItem->sceneBoundingRect().height() / 2 ) + d->borderRectItem->pos().y();
556
557 starty = item_center - ( d->svgElementRect.height() / 2 );
558
559 endx = d->hoverIndicatorRectWidth - ( 2 * d->hoverIndicatorRectItem->pen().width() );
560
561 endy = d->svgElementRect.height();
562
563 QRectF indicatorRect( startx, starty, endx, endy );
564 d->hoverIndicatorRectItem->setRect( indicatorRect );
565
566 QRectF indicatorFillRect(
567 indicatorRect.left() + d->hoverIndicatorRectItem->pen().width()
568 , indicatorRect.bottom() - d->hoverIndicatorRectItem->pen().width()
569 , indicatorRect.width() - ( 2 * d->hoverIndicatorRectItem->pen().width() )
570 , 0 );
571 d->hoverIndicatorRectFillItem->setRect( indicatorFillRect );
572 }
573
sharedRenderer() const574 QSvgRenderer* PopupDropperItem::sharedRenderer() const
575 {
576 return d->sharedRenderer;
577 }
578
setSharedRenderer(QSvgRenderer * renderer)579 void PopupDropperItem::setSharedRenderer( QSvgRenderer *renderer )
580 {
581 d->sharedRenderer = renderer;
582 if( renderer && d->svgItem )
583 {
584 d->svgItem->setSharedRenderer( renderer );
585 d->svgItem->setElementId( d->elementId );
586 if( !d->svgItem->elementId().isEmpty() && d->svgItem->renderer()->elementExists( d->svgItem->elementId() ) )
587 {
588 d->svgItem->show();
589 fullUpdate();
590 }
591 }
592 }
593
elementId() const594 QString PopupDropperItem::elementId() const
595 {
596 return d->elementId;
597 }
598
setElementId(const QString & id)599 void PopupDropperItem::setElementId( const QString &id )
600 {
601 //qDebug() << "Element ID being set: " << id;
602 d->elementId = id;
603 if( id.isEmpty() )
604 {
605 d->svgItem->hide();
606 fullUpdate();
607 }
608 else if( d->svgItem && d->svgItem->renderer() && d->svgItem->renderer()->elementExists( id ))
609 {
610 d->svgItem->setElementId( id );
611 d->svgItem->show();
612 fullUpdate();
613 }
614 }
615
svgElementRect() const616 QRect PopupDropperItem::svgElementRect() const
617 {
618 return d->svgElementRect;
619 }
620
setSvgElementRect(const QRect & rect)621 void PopupDropperItem::setSvgElementRect( const QRect &rect )
622 {
623 d->svgElementRect = rect;
624 }
625
horizontalOffset() const626 int PopupDropperItem::horizontalOffset() const
627 {
628 return d->horizontalOffset;
629 }
630
setHorizontalOffset(int offset)631 void PopupDropperItem::setHorizontalOffset( int offset )
632 {
633 d->horizontalOffset = offset;
634 }
635
textOffset() const636 int PopupDropperItem::textOffset() const
637 {
638 return d->textOffset;
639 }
640
setTextOffset(int offset)641 void PopupDropperItem::setTextOffset( int offset )
642 {
643 d->textOffset = offset;
644 }
645
isSeparator() const646 bool PopupDropperItem::isSeparator() const
647 {
648 return d->separator;
649 }
650
setSeparator(bool separator)651 void PopupDropperItem::setSeparator( bool separator )
652 {
653 d->separator = separator;
654 }
655
separatorStyle() const656 PopupDropperItem::SeparatorStyle PopupDropperItem::separatorStyle() const
657 {
658 return d->separatorStyle;
659 }
660
setSeparatorStyle(SeparatorStyle style)661 void PopupDropperItem::setSeparatorStyle( SeparatorStyle style )
662 {
663 d->separatorStyle = style;
664 }
665
hasLineSeparatorPen() const666 bool PopupDropperItem::hasLineSeparatorPen() const
667 {
668 return d->hasLineSeparatorPen;
669 }
670
lineSeparatorPen() const671 QPen PopupDropperItem::lineSeparatorPen() const
672 {
673 return d->lineSeparatorPen;
674 }
675
setLineSeparatorPen(const QPen & pen)676 void PopupDropperItem::setLineSeparatorPen( const QPen &pen )
677 {
678 d->lineSeparatorPen = pen;
679 }
680
clearLineSeparatorPen()681 void PopupDropperItem::clearLineSeparatorPen()
682 {
683 d->lineSeparatorPen = QPen();
684 d->hasLineSeparatorPen = false;
685 }
686
hoverMsecs() const687 int PopupDropperItem::hoverMsecs() const
688 {
689 return d->hoverTimer.duration();
690 }
691
setHoverMsecs(const int msecs)692 void PopupDropperItem::setHoverMsecs( const int msecs )
693 {
694 d->hoverTimer.setDuration( msecs );
695 }
696
hoverEntered()697 void PopupDropperItem::hoverEntered()
698 {
699 if( d->hoverIndicatorRectItem && d->hoverIndicatorRectFillItem && d->hoverIndicatorShowStyle != PopupDropperItem::Never )
700 {
701 d->hoverIndicatorRectFillItem->show();
702 }
703 d->hoverTimer.stop();
704 d->hoverTimer.setDirection( QTimeLine::Forward );
705 d->hoveredOver = true;
706 d->hoverTimer.start();
707 }
708
hoverLeft()709 void PopupDropperItem::hoverLeft()
710 {
711 d->hoverTimer.stop();
712 d->hoverTimer.setDirection( QTimeLine::Backward );
713 d->hoveredOver = false;
714 if( d->hoverTimer.currentFrame() != 0 )
715 d->hoverTimer.start();
716 }
717
borderWidth() const718 int PopupDropperItem::borderWidth() const
719 {
720 return d->borderWidth;
721 }
722
setBorderWidth(int borderWidth)723 void PopupDropperItem::setBorderWidth( int borderWidth )
724 {
725 d->borderWidth = borderWidth;
726 d->hoveredBorderPen.setWidth( borderWidth );
727 if( d->borderRectItem )
728 {
729 d->borderRectItem->setPen( d->hoveredBorderPen );
730 }
731 }
732
hoverIndicatorRectWidth() const733 int PopupDropperItem::hoverIndicatorRectWidth() const
734 {
735 return d->hoverIndicatorRectWidth;
736 }
737
setHoverIndicatorRectWidth(int hoverIndicatorRectWidth)738 void PopupDropperItem::setHoverIndicatorRectWidth( int hoverIndicatorRectWidth )
739 {
740 d->hoverIndicatorRectWidth = hoverIndicatorRectWidth;
741 if( d->hoverIndicatorRectItem )
742 {
743 QPen pen = d->hoverIndicatorRectItem->pen();
744 pen.setWidth( d->hoverIndicatorRectWidth );
745 d->hoverIndicatorRectItem->setPen( pen );
746 }
747 }
748
isSubmenuTrigger() const749 bool PopupDropperItem::isSubmenuTrigger() const
750 {
751 return d->submenuTrigger;
752 }
753
setSubmenuTrigger(bool trigger)754 void PopupDropperItem::setSubmenuTrigger( bool trigger )
755 {
756 d->submenuTrigger = trigger;
757 }
758
setPopupDropper(PopupDropper * pd)759 void PopupDropperItem::setPopupDropper( PopupDropper* pd )
760 {
761 d->pd = pd;
762 }
763
764 //bool PopupDropperItem::operator<( const PopupDropperItem &other ) const
765 //{
766 // return d->text < other.text();
767 //}
768
dropped(QDropEvent * event)769 void PopupDropperItem::dropped( QDropEvent *event ) //virtual SLOT
770 {
771 Q_UNUSED( event );
772 d->hoverTimer.stop();
773 //qDebug() << "PopupDropperItem drop detected";
774 if( d->action )
775 {
776 //qDebug() << "Triggering action";
777 d->action->activate( QAction::Trigger );
778 }
779 }
780
hoverFinished()781 void PopupDropperItem::hoverFinished() //SLOT
782 {
783 if( d->separator )
784 return;
785
786 //qDebug() << "direction = forwards ? " << ( d->hoverTimer.direction() == QTimeLine::Forward ? "yes" : "no" );
787
788 if( d->action && d->hoverTimer.direction() == QTimeLine::Forward )
789 d->action->activate( QAction::Hover );
790
791 if( d->hoverTimer.direction() == QTimeLine::Forward )
792 d->textItem->setDefaultTextColor( d->hoveredTextColor );
793 else
794 d->textItem->setDefaultTextColor( d->baseTextColor );
795
796 //Something is messed up in QTimeLine...I get hoverFinished immediately after doing a hoverLeft, but only sometimes...hence the check
797 //to see if the timeline isn't running
798 if( d->hoverIndicatorRectFillItem && d->hoverTimer.state() == QTimeLine::NotRunning && d->hoverTimer.direction() == QTimeLine::Backward )
799 {
800 d->hoverIndicatorRectFillItem->hide();
801 if( d->hoverIndicatorRectItem && d->hoverIndicatorShowStyle != PopupDropperItem::AlwaysShow )
802 d->hoverIndicatorRectItem->hide();
803 }
804
805 if( d->pd )
806 d->pd->updateAllOverlays();
807 }
808
hoverFrameChanged(int frame)809 void PopupDropperItem::hoverFrameChanged( int frame ) //SLOT
810 {
811 if( d->separator )
812 return;
813 //qDebug() << "hoverFrameChanged for " << static_cast<QObject*>(this) << ", frame = " << frame;
814 int range = d->hoverTimer.endFrame() - d->hoverTimer.startFrame();
815 qreal multiplier = ( 1.0 * frame ) / range;
816 int r = (int)( ( d->hoveredTextColor.red() - d->baseTextColor.red() ) * multiplier ) + d->baseTextColor.red();
817 int g = (int)( ( d->hoveredTextColor.green() - d->baseTextColor.green() ) * multiplier ) + d->baseTextColor.green();
818 int b = (int)( ( d->hoveredTextColor.blue() - d->baseTextColor.blue() ) * multiplier ) + d->baseTextColor.blue();
819 int a = (int)( ( d->hoveredTextColor.alpha() - d->baseTextColor.alpha() ) * multiplier ) + d->baseTextColor.alpha();
820
821 d->textItem->setDefaultTextColor( QColor( r, g, b, a ) );
822
823 QColor borderColor = d->hoveredBorderPen.color();
824 borderColor.setAlpha( (int)( borderColor.alpha() * multiplier ) );
825 QPen pen = d->borderRectItem->pen();
826 pen.setColor( borderColor );
827 d->borderRectItem->setPen( pen );
828 if( d->hoverIndicatorRectItem && d->hoverIndicatorShowStyle == PopupDropperItem::OnHover )
829 {
830 d->hoverIndicatorRectItem->setPen( pen );
831 d->hoverIndicatorRectItem->show();
832 }
833 QColor fillColor = d->hoveredFillBrush.color();
834 QBrush brush = d->borderRectItem->brush();
835 fillColor.setAlpha( (int)( fillColor.alpha() * multiplier ) );
836 brush.setColor( fillColor );
837 d->borderRectItem->setBrush( brush );
838
839 if( d->hoverIndicatorRectItem && d->hoverIndicatorRectFillItem && d->hoverIndicatorShowStyle != PopupDropperItem::Never )
840 {
841 int hoverIndicatorPenWidth = d->hoverIndicatorRectItem->pen().width();
842 QRectF rect = d->hoverIndicatorRectFillItem->rect();
843 QRectF outerRect = d->hoverIndicatorRectItem->rect();
844 rect.setTop( ( multiplier * -1 * ( outerRect.bottom() - outerRect.top() - ( 2 * hoverIndicatorPenWidth ) ) )
845 + outerRect.bottom()
846 - hoverIndicatorPenWidth );
847 d->hoverIndicatorRectFillItem->setRect( rect );
848 d->hoverIndicatorRectFillItem->setBrush( d->hoverIndicatorRectFillBrush );
849 d->hoverIndicatorRectFillItem->show();
850 //qDebug() << "hoverIndicatorRectFillItem = " << d->hoverIndicatorRectFillItem;
851 }
852
853 if( d->pd )
854 d->pd->updateAllOverlays();
855 }
856
fullUpdate()857 void PopupDropperItem::fullUpdate()
858 {
859 scaleAndReposSvgItem();
860 reposTextItem();
861 reposHoverFillRects();
862 if( d->pd )
863 d->pd->updateAllOverlays();
864 }
865
boundingRect() const866 QRectF PopupDropperItem::boundingRect() const
867 {
868 if( d->borderRectItem )
869 return d->borderRectItem->boundingRect();
870 else if( d->pd && d->pd->viewSize().width() != 0 )
871 return QRectF( 0, 0, d->pd->viewSize().width(), d->svgElementRect.height() );
872 else
873 return QRectF( 0, 0, d->svgElementRect.width(), d->svgElementRect.height() );
874 }
875
paint(QPainter * painter,const QStyleOptionGraphicsItem * option,QWidget * widget)876 void PopupDropperItem::paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget )
877 {
878 Q_UNUSED( painter )
879 Q_UNUSED( option )
880 Q_UNUSED( widget )
881 return;
882 }
883
884
885