1
/***************************************************************************
2
* Copyright (C) 2011-2014 by Savoir-Faire Linux *
3
* Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>*
5
* This program is free software; you can redistribute it and/or modify *
6
* it under the terms of the GNU General Public License as published by *
7
* the Free Software Foundation; either version 3 of the License, or *
8
* (at your option) any later version. *
10
* This program is distributed in the hope that it will be useful, *
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13
* GNU General Public License for more details. *
15
* You should have received a copy of the GNU General Public License *
16
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17
**************************************************************************/
18
#include "delegatedropoverlay.h"
20
#include <QtGui/QPainter>
23
#include <QtCore/QTimer>
24
#include <QDragEnterEvent>
25
#include <QDragMoveEvent>
26
#include <QDragLeaveEvent>
28
#include <QtGui/QApplication>
30
#include <lib/abstractcontactbackend.h>
33
DelegateDropOverlay::DelegateDropOverlay(QObject* parent):QObject(parent),
34
m_pTimer(0),m_Init(false),m_Reverse(1),m_lpButtons(nullptr)
36
const QColor color = QApplication::palette().base().color();
37
const bool dark = (color.red() > 128 && color.green() > 128 && color.blue() > 128);
39
m_Pen.setColor("#f3f3f3");
41
m_Pen.setColor(Qt::white);
45
DelegateDropOverlay::~DelegateDropOverlay()
47
if (m_pTimer) delete m_pTimer;
51
void DelegateDropOverlay::paintEvent(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)
55
static bool initSignals = false;
57
connect(index.model(),SIGNAL(layoutChanged()),this,SLOT(slotLayoutChanged()));
60
int step = index.data(AbstractContactBackend::Role::DropState).toInt();
61
if ((step == 1 || step == -1) && m_lActiveIndexes.indexOf(index) == -1) {
62
m_lActiveIndexes << index;
65
m_pTimer = new QTimer(this);
66
connect(m_pTimer, SIGNAL(timeout()), this, SLOT(changeVisibility()));
69
//Start it if it's nor already
70
if (!m_pTimer->isActive()) {
75
QMapIterator<QString, OverlayButton*> it(*m_lpButtons);
76
const int dropPosition = index.data(Call::Role::DropPosition).toInt();
77
while (it.hasNext()) {
80
const bool highlight = dropPosition == it.value()->role;
81
const int tmpStep = (step>0)?step:15+step;
83
painter->setOpacity(1);
84
painter->setRenderHint(QPainter::Antialiasing, true);
85
QPen pen = highlight?QApplication::palette().color(QPalette::Highlight): QColor(235,235,235,235);
88
QLinearGradient linearGrad(QPointF(0, 0), QPointF(0, 100));
89
linearGrad.setColorAt(0, QColor(130,130,130,(0.7*tmpStep*tmpStep)));
90
linearGrad.setColorAt(1, QColor(0,0,0,(0.75*tmpStep*tmpStep)));
91
painter->setBrush(linearGrad);
92
const QRect buttonRect = QRect(
93
option.rect.x()+(option.rect.width()/m_lpButtons->size())*i+4,
95
option.rect.width()/m_lpButtons->size() - 10,
96
option.rect.height()-4);
97
painter->drawRoundedRect(buttonRect, 10, 10);
98
painter->setPen(highlight?QColor(Qt::white):m_Pen);
100
if (it.value()->m_pImage) {
101
painter->drawImage(QRect(
102
buttonRect.x()+buttonRect.width()-(buttonRect.height()-10)-10/*padding*/,
104
(buttonRect.height()-10),
105
(buttonRect.height()-10)),*it.value()->m_pImage);
108
QFont font = painter->font();
110
painter->setFont(font);
111
painter->drawText (buttonRect, Qt::AlignVCenter|Qt::AlignHCenter, QString(it.key()).remove('&') );
116
QColor col = pen.color();
117
for(int i=1;i<=4;i++) {
118
painter->setBrush(Qt::NoBrush);
120
col.setAlpha(205*(0.5/((float)i)));
122
painter->setPen(pen);
123
painter->drawRoundedRect(buttonRect, 10, 10);
130
///Step by step animation
131
void DelegateDropOverlay::changeVisibility()
133
foreach(const QModelIndex& idx, m_lActiveIndexes) {
134
//There is a race condition when removing a conference participant
135
if (idx.isValid() && !idx.model()->rowCount(idx)) {
136
int step = idx.data(AbstractContactBackend::Role::DropState).toInt();
137
//Remove items from the loop if there is no animation
138
if (step >= 15 || step <= -15) {
139
m_lActiveIndexes.removeAll(idx);
140
if (step <= -15) //Hide the overlay
141
((QAbstractItemModel*)idx.model())->setData(idx,QVariant((int)0),AbstractContactBackend::Role::DropState);
146
((QAbstractItemModel*)idx.model())->setData(idx,QVariant((int)step),AbstractContactBackend::Role::DropState);
150
//Stop loop if no animations are running
151
if (!m_lActiveIndexes.size()) {
156
///Prevent a race condition between the timer and model changes
157
void DelegateDropOverlay::slotLayoutChanged()
159
m_lActiveIndexes.clear();