mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-21 23:40:26 -04:00
Big progress for People dialog. Phenom work.
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7573 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
28277c53df
commit
9efc43f41c
15 changed files with 3630 additions and 133 deletions
755
retroshare-gui/src/gui/common/FlowLayout.cpp
Normal file
755
retroshare-gui/src/gui/common/FlowLayout.cpp
Normal file
|
@ -0,0 +1,755 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "gui/common/FlowLayout.h"
|
||||
#include <QApplication>
|
||||
#include <QtGui>
|
||||
#include <QDebug>
|
||||
|
||||
//*** FlowLayoutItem **********************************************************
|
||||
|
||||
void FlowLayoutItem::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
m_startPos = event->pos();
|
||||
}//if (event->button() == Qt::LeftButton)
|
||||
QWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void FlowLayoutItem::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->buttons() & Qt::LeftButton) {
|
||||
int distance = (event->pos() - m_startPos).manhattanLength();
|
||||
if (distance >= QApplication::startDragDistance())
|
||||
performDrag();
|
||||
}//if (event->buttons() & Qt::LeftButton)
|
||||
QWidget::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void FlowLayoutItem::performDrag()
|
||||
{
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setText(m_myName);
|
||||
|
||||
QDrag *drag = new QDrag(this);
|
||||
drag->setMimeData(mimeData);
|
||||
QPixmap pixmap=getDragImage();
|
||||
|
||||
drag->setPixmap(pixmap.scaled(50,50,Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
/// Warning On Windows, Drag Pixmap size cannot exceed 50*50. ///
|
||||
drag->setHotSpot(QPoint(0, 0));
|
||||
Qt::DropAction dropAction = drag->exec(Qt::CopyAction);
|
||||
qDebug()<<dropAction;
|
||||
}
|
||||
|
||||
void FlowLayoutItem::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void FlowLayoutItem::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
FlowLayoutItem *source =
|
||||
qobject_cast<FlowLayoutItem *>(event->source());
|
||||
if (source && source != this) {
|
||||
event->setDropAction(Qt::CopyAction);
|
||||
event->acceptProposedAction();
|
||||
return;
|
||||
}//if (source && source != this)
|
||||
QWidget *wid =
|
||||
qobject_cast<QWidget *>(event->source());//QT5 return QObject
|
||||
FlowLayout *layout = 0;
|
||||
if (wid) layout =
|
||||
qobject_cast<FlowLayout *>(wid->layout());
|
||||
if (layout) {
|
||||
event->setDropAction(Qt::CopyAction);
|
||||
event->acceptProposedAction();
|
||||
return;
|
||||
}//if (layout)
|
||||
}
|
||||
|
||||
void FlowLayoutItem::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
FlowLayoutItem *source =
|
||||
qobject_cast<FlowLayoutItem *>(event->source());
|
||||
if (source && source != this) {
|
||||
event->setDropAction(Qt::CopyAction);
|
||||
event->acceptProposedAction();
|
||||
return;
|
||||
}//if (source && source != this)
|
||||
QWidget *wid =
|
||||
qobject_cast<QWidget *>(event->source());//QT5 return QObject
|
||||
FlowLayout *layout = 0;
|
||||
if (wid) layout =
|
||||
qobject_cast<FlowLayout *>(wid->layout());
|
||||
if (layout) {
|
||||
event->setDropAction(Qt::CopyAction);
|
||||
event->acceptProposedAction();
|
||||
return;
|
||||
}//if (layout)
|
||||
}
|
||||
|
||||
void FlowLayoutItem::dropEvent(QDropEvent *event)
|
||||
{
|
||||
QList <FlowLayoutItem*> list;
|
||||
FlowLayoutItem *source =
|
||||
qobject_cast<FlowLayoutItem *>(event->source());
|
||||
if (source && source != this) {
|
||||
event->setDropAction(Qt::CopyAction);
|
||||
list << source;
|
||||
} else {//if (source && source != this)
|
||||
QWidget *wid =
|
||||
qobject_cast<QWidget *>(event->source());//QT5 return QObject
|
||||
FlowLayout *layout;
|
||||
if (wid) layout =
|
||||
qobject_cast<FlowLayout *>(wid->layout());
|
||||
if (layout) {
|
||||
QList<QLayoutItem *> listSel = layout->selectionList();
|
||||
int count = listSel.count();
|
||||
for (int curs = 0; curs < count; ++curs){
|
||||
QLayoutItem *layoutItem = listSel.at(curs);
|
||||
FlowLayoutItem *flItem = 0;
|
||||
if (layoutItem) flItem = qobject_cast<FlowLayoutItem*>(layoutItem->widget());
|
||||
if (flItem) list << flItem;
|
||||
}//for (int curs = 0; curs < count; ++curs)
|
||||
}//if (layout)
|
||||
}//else (source && source != this)
|
||||
if (!list.isEmpty()) {
|
||||
event->setDropAction(Qt::CopyAction);
|
||||
bool bAccept=true;
|
||||
emit flowLayoutItemDropped(list, bAccept);
|
||||
if (bAccept) event->acceptProposedAction();
|
||||
}//if (!list.empty())
|
||||
}
|
||||
|
||||
//*** FlowLayoutWidget **********************************************************
|
||||
FlowLayoutWidget::FlowLayoutWidget(QWidget *parent, int margin/*=-1*/, int hSpacing/*=-1*/, int vSpacing/*=-1*/)
|
||||
: QWidget(parent)
|
||||
{
|
||||
FlowLayoutWidget(margin, hSpacing, vSpacing);
|
||||
}
|
||||
|
||||
FlowLayoutWidget::FlowLayoutWidget(int margin/*=-1*/, int hSpacing/*=-1*/, int vSpacing/*=-1*/)
|
||||
{
|
||||
FlowLayout *fl = new FlowLayout(this, margin, hSpacing, vSpacing);
|
||||
Q_UNUSED(fl)
|
||||
this->installEventFilter(this);
|
||||
this->setMouseTracking(true);
|
||||
this->setAcceptDrops(true);
|
||||
m_saParent = 0;
|
||||
m_sbVertical = 0;
|
||||
}
|
||||
|
||||
FlowLayoutWidget::~FlowLayoutWidget()
|
||||
{
|
||||
}
|
||||
|
||||
bool FlowLayoutWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
qDebug() << "FlowLayoutWidget:: obj type:" << obj->metaObject()->className() << " event type:" << event->type();
|
||||
updateParent();
|
||||
if (event->type() == QEvent::DragEnter) {
|
||||
QDragEnterEvent *dragEnterEvent = static_cast<QDragEnterEvent *>(event);
|
||||
if (dragEnterEvent){
|
||||
dragEnterEvent->setDropAction(Qt::IgnoreAction);
|
||||
dragEnterEvent->accept();
|
||||
}//if (dragEnterEvent)
|
||||
}//if (event->type() == QEvent::DragEnter)
|
||||
|
||||
if (event->type() == QEvent::DragMove) {
|
||||
QDragMoveEvent *dragMoveEvent = static_cast<QDragMoveEvent *>(event);
|
||||
const int border = 20;
|
||||
if (obj==this && dragMoveEvent){
|
||||
if (m_sbVertical){
|
||||
int maxY = m_sbVertical->maximum();
|
||||
int currentY = m_sbVertical->value();
|
||||
int height = m_saParent->height();
|
||||
int topBorder = currentY + border;
|
||||
int bottomBorder = currentY + height - border;
|
||||
int dragY = dragMoveEvent->pos().y();
|
||||
qDebug() <<"Drag event:" << dragY ;
|
||||
int dY = (dragY<topBorder)?dragY - topBorder:((dragY>bottomBorder)?dragY - bottomBorder:0);
|
||||
qDebug() << "dY:" << dY << " m_lastYPos:" << m_lastYPos << "(dragY-m_lastYPos)*dY:" << (dragY-m_lastYPos)*dY;
|
||||
int newValue=currentY+dY;
|
||||
if ((abs(dY)<border) && ((dragY-m_lastYPos)*dY >= 0)){
|
||||
if (newValue>maxY) newValue=maxY;
|
||||
if (newValue<0) newValue=0;
|
||||
m_sbVertical->setValue(newValue);
|
||||
} else {
|
||||
newValue=currentY;
|
||||
}//if ((abs(dY)<border) && ((dragY-m_lastYPos)*dY >= 0))
|
||||
m_lastYPos = dragY+(newValue-currentY);
|
||||
}//if (sbVertical)
|
||||
}//if (obj==this && dragMoveEvent)
|
||||
if (obj==m_sbVertical && dragMoveEvent){
|
||||
if (m_sbVertical->isVisible()){
|
||||
int maxY = m_sbVertical->maximum();
|
||||
double height = m_sbVertical->height()*1.0;
|
||||
double scale = (maxY/height);
|
||||
int dragY = dragMoveEvent->pos().y();
|
||||
qDebug() << "Drag maxY:" << maxY << "height:" << height << "scale:" << scale << "dragY:" << dragY;
|
||||
m_sbVertical->setValue(dragY*scale);
|
||||
}//if (sbVertical->isVisible())
|
||||
}//if (obj==this && dragMoveEvent)
|
||||
}//if (event->type() == QEvent::DragMove)
|
||||
|
||||
// standard event processing
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void FlowLayoutWidget::updateParent()
|
||||
{
|
||||
if (parent()){
|
||||
if (!m_saParent){
|
||||
if (parent()->objectName() == "qt_scrollarea_viewport"){
|
||||
m_saParent = qobject_cast<QScrollArea*>(parent()->parent());
|
||||
} else {
|
||||
m_saParent = qobject_cast<QScrollArea*>(parent());
|
||||
}//if (parent()->objectName() == "qt_scrollarea_viewport")
|
||||
if (m_saParent){
|
||||
m_saParent->installEventFilter(this);
|
||||
m_saParent->setAcceptDrops(true);
|
||||
m_saParent->setMouseTracking(true);
|
||||
}//if (saParent)
|
||||
}//if (!saParent)
|
||||
if (m_saParent && !m_sbVertical){
|
||||
m_sbVertical= m_saParent->verticalScrollBar();
|
||||
if (m_sbVertical){
|
||||
m_sbVertical->installEventFilter(this);
|
||||
m_sbVertical->setAcceptDrops(true);
|
||||
m_sbVertical->setMouseTracking(true);
|
||||
}//if (sbVertical)
|
||||
}//if (saParent && !sbVertical)
|
||||
}//if (parent())
|
||||
}
|
||||
|
||||
//*** FlowLayout **********************************************************
|
||||
|
||||
FlowLayout::FlowLayout(QWidget *parent, int margin/*=-1*/, int hSpacing/*=-1*/, int vSpacing/*=-1*/)
|
||||
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
|
||||
{
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
this->installEventFilter(this);
|
||||
}
|
||||
|
||||
FlowLayout::FlowLayout(int margin/*=-1*/, int hSpacing/*=-1*/, int vSpacing/*=-1*/)
|
||||
: m_hSpace(hSpacing), m_vSpace(vSpacing)
|
||||
{
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
this->installEventFilter(this);
|
||||
}
|
||||
|
||||
FlowLayout::~FlowLayout()
|
||||
{
|
||||
QLayoutItem *item;
|
||||
while ((item = takeAt(0)))
|
||||
delete item;
|
||||
}
|
||||
|
||||
bool FlowLayout::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
qDebug() << "FlowLayout::obj type:" << obj->metaObject()->className() << " event type:" << event->type();
|
||||
|
||||
if (event->type() == QEvent::MouseButtonPress) {
|
||||
m_startPos = QCursor::pos();
|
||||
}//if (event->type() == QEvent::MouseButtonPress)
|
||||
|
||||
if (event->type() == QEvent::MouseButtonRelease) {
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
int distance = (QCursor::pos() - m_startPos).manhattanLength();
|
||||
if (distance < QApplication::startDragDistance()){
|
||||
unsetCurrent();
|
||||
m_currentIndex=indexAtGlobal(QCursor::pos());
|
||||
setCurrent();
|
||||
bool invert = (mouseEvent->modifiers() &= Qt::ControlModifier);
|
||||
if (mouseEvent->modifiers() &= Qt::ShiftModifier){
|
||||
m_selStartIndex=(m_selStartIndex<m_currentIndex)?m_selStartIndex:m_currentIndex;
|
||||
m_selStopIndex=(m_selStopIndex>m_currentIndex)?m_selStopIndex:m_currentIndex;
|
||||
} else {
|
||||
m_selStartIndex=m_selStopIndex=m_currentIndex;
|
||||
if (mouseEvent->modifiers() != Qt::ControlModifier){
|
||||
foreach (QLayoutItem *item, m_selectionList) {
|
||||
FlowLayoutItem *fli = qobject_cast<FlowLayoutItem *>(item->widget());
|
||||
if (fli) fli->setIsSelected(false);
|
||||
m_selectionList.removeOne(item);
|
||||
}
|
||||
}//if (mouseEvent->modifiers() != Qt::ControlModifier)
|
||||
}//if (mouseEvent->modifiers()
|
||||
addSelection(invert);
|
||||
setCurrent();
|
||||
}//if (distance < QApplication::startDragDistance())
|
||||
doLayout(geometry(),false);
|
||||
}//if (event->type() == QEvent::MouseButtonRelease)
|
||||
|
||||
if (event->type() == QEvent::MouseMove) {
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
if (mouseEvent->buttons() & Qt::LeftButton) {
|
||||
int distance = (QCursor::pos() - m_startPos).manhattanLength();
|
||||
if (distance >= QApplication::startDragDistance()){
|
||||
if (!m_selectionList.isEmpty()) {
|
||||
QLayoutItem *item=itemAtGlobal(m_startPos);
|
||||
if (item) {
|
||||
if (m_selectionList.contains(item)){
|
||||
performDrag();
|
||||
return true; // eat event
|
||||
}//if (m_selectionList.contains(item))
|
||||
}//if (item)
|
||||
}//if (!m_selectionList.isEmpty())
|
||||
}//if (distance >= QApplication::startDragDistance())
|
||||
}//if (mouseEvent->buttons() & Qt::LeftButton)
|
||||
}//if (event->type() == QEvent::MouseMove)
|
||||
|
||||
if (event->type() == QEvent::KeyRelease) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
|
||||
if ((keyEvent->key()==Qt::Key_A) && (keyEvent->modifiers() &= Qt::ControlModifier)){
|
||||
int count = m_itemList.count();
|
||||
int selected = m_selectionList.count();
|
||||
if (count != selected){
|
||||
for (int curs=0; curs<count; ++curs){
|
||||
QLayoutItem *item=itemAt(curs);
|
||||
if (item) {
|
||||
if (!m_selectionList.contains(item)){
|
||||
FlowLayoutItem *fli = qobject_cast<FlowLayoutItem *>(item->widget());
|
||||
if (fli) fli->setIsSelected(true);
|
||||
m_selectionList.append(item);
|
||||
}//if (!m_selectionList.contains(item))
|
||||
}//if (item)
|
||||
}//for (int curs=0; curs<count; ++curs)
|
||||
} else {
|
||||
foreach (QLayoutItem *item, m_selectionList) {
|
||||
FlowLayoutItem *fli = qobject_cast<FlowLayoutItem *>(item->widget());
|
||||
if (fli) fli->setIsSelected(false);
|
||||
m_selectionList.removeOne(item);
|
||||
}
|
||||
}//if (count != selected)
|
||||
|
||||
doLayout(geometry(),false);
|
||||
event->accept();
|
||||
}//if ((keyEvent->key()==Qt::Key_A) && (keyEvent->modifiers() &= Qt::ControlModifier))
|
||||
|
||||
if ((keyEvent->key()==Qt::Key_Space)){
|
||||
if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier)){
|
||||
addSelection((keyEvent->modifiers() &= Qt::ControlModifier));
|
||||
}//if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier))
|
||||
doLayout(geometry(),false);
|
||||
m_selStartIndex = m_selStopIndex = m_currentIndex;
|
||||
event->accept();
|
||||
}//if ((keyEvent->key()==Qt::Key_Space))
|
||||
|
||||
if ((keyEvent->key()==Qt::Key_Left)){
|
||||
unsetCurrent();
|
||||
if (m_currentIndex>0) m_currentIndex-=1;
|
||||
if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier)){
|
||||
m_selStartIndex=m_currentIndex;
|
||||
addSelection((keyEvent->modifiers() &= Qt::ControlModifier));
|
||||
}//if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier))
|
||||
doLayout(geometry(),false);
|
||||
m_selStartIndex = m_selStopIndex = m_currentIndex;
|
||||
event->accept();
|
||||
setCurrent();
|
||||
}//if ((keyEvent->key()==Qt::Key_Left))
|
||||
|
||||
if ((keyEvent->key()==Qt::Key_Right)){
|
||||
unsetCurrent();
|
||||
if (m_currentIndex<(m_itemList.count()-1)) m_currentIndex+=1;
|
||||
if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier)){
|
||||
m_selStopIndex=m_currentIndex;
|
||||
addSelection((keyEvent->modifiers() &= Qt::ControlModifier));
|
||||
}//if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier))
|
||||
doLayout(geometry(),false);
|
||||
m_selStartIndex = m_selStopIndex = m_currentIndex;
|
||||
event->accept();
|
||||
setCurrent();
|
||||
}//if ((keyEvent->key()==Qt::Key_Right))
|
||||
|
||||
if ((keyEvent->key()==Qt::Key_Up)){
|
||||
unsetCurrent();
|
||||
QLayoutItem* item = currentItem();
|
||||
if (item) {
|
||||
QRect loc = item->geometry();
|
||||
int vSpace = verticalSpacing();
|
||||
QPoint pos = QPoint(loc.left()+loc.width()/2, loc.top()-vSpace-2);
|
||||
int index = -1;
|
||||
while ((pos.y()>0) && (index < 0)){
|
||||
index = indexAtParent(pos);
|
||||
pos.setY(pos.y()-2);
|
||||
}//while ((pos.y()>0) && (index < 0))
|
||||
m_currentIndex = (index>0)?index:0;
|
||||
m_currentIndex = (index<=m_itemList.count())?index:m_itemList.count();
|
||||
if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier)){
|
||||
m_selStopIndex = m_currentIndex;
|
||||
addSelection((keyEvent->modifiers() &= Qt::ControlModifier));
|
||||
}//if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier))
|
||||
doLayout(geometry(),false);
|
||||
m_selStartIndex = m_selStopIndex = m_currentIndex;
|
||||
event->accept();
|
||||
}//if (wid)
|
||||
setCurrent();
|
||||
}//if ((keyEvent->key()==Qt::Key_Right))
|
||||
|
||||
if ((keyEvent->key()==Qt::Key_Down)){
|
||||
unsetCurrent();
|
||||
QLayoutItem* item = currentItem();
|
||||
if (item){
|
||||
QRect loc = item->geometry();
|
||||
int vSpace = verticalSpacing();
|
||||
QPoint pos = QPoint(loc.left()+loc.width()/2, loc.bottom()+vSpace+2);
|
||||
int index = -1;
|
||||
while ((pos.y()<geometry().bottom()) && (index < 0)){
|
||||
index = indexAtParent(pos);
|
||||
pos.setY(pos.y()+2);
|
||||
}//while ((pos.y()<geometry().bottom()) && (index < 0))
|
||||
m_currentIndex = (index>0)?index:0;
|
||||
m_currentIndex = (index<=m_itemList.count())?index:m_itemList.count();
|
||||
if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier)){
|
||||
m_selStopIndex = m_currentIndex;
|
||||
addSelection((keyEvent->modifiers() &= Qt::ControlModifier));
|
||||
}//if ((keyEvent->modifiers() &= Qt::ShiftModifier) || (keyEvent->modifiers() &= Qt::ControlModifier))
|
||||
doLayout(geometry(),false);
|
||||
m_selStartIndex = m_selStopIndex = m_currentIndex;
|
||||
event->accept();
|
||||
}//if (wid)
|
||||
setCurrent();
|
||||
}//if ((keyEvent->key()==Qt::Key_Right))
|
||||
|
||||
}//if (event->type() == QEvent::KeyRelease)
|
||||
|
||||
// standard event processing
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void FlowLayout::unsetCurrent()
|
||||
{
|
||||
QLayoutItem *oldItem = currentItem();
|
||||
if (oldItem) {
|
||||
FlowLayoutItem *fli = qobject_cast<FlowLayoutItem *>(oldItem->widget());
|
||||
if (fli) fli->setIsCurrent(false);
|
||||
}//if (oldItem)
|
||||
}
|
||||
|
||||
void FlowLayout::setCurrent()
|
||||
{
|
||||
QLayoutItem *newItem = currentItem();
|
||||
if (newItem) {
|
||||
FlowLayoutItem *fli = qobject_cast<FlowLayoutItem *>(newItem->widget());
|
||||
if (fli) fli->setIsCurrent(true);
|
||||
}//if (newItem)
|
||||
}
|
||||
|
||||
void FlowLayout::addItem(QLayoutItem *item)
|
||||
{
|
||||
m_itemList.append(item);
|
||||
item->widget()->installEventFilter(this);
|
||||
}
|
||||
|
||||
void FlowLayout::addItem(FlowLayoutItem *item)
|
||||
{
|
||||
QWidget *widget = qobject_cast<QWidget *>(item);
|
||||
addWidget(widget);
|
||||
}
|
||||
|
||||
int FlowLayout::horizontalSpacing() const
|
||||
{
|
||||
if (m_hSpace >= 0) {
|
||||
return m_hSpace;
|
||||
} else {
|
||||
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
|
||||
}//if (m_hSpace >= 0)
|
||||
}
|
||||
void FlowLayout::setHorizontalSpacing(int &h)
|
||||
{
|
||||
if (h>=0) {
|
||||
m_hSpace = h;
|
||||
} else {
|
||||
m_hSpace = -1;
|
||||
}//if (h>=0)
|
||||
doLayout(geometry(), false);
|
||||
}
|
||||
|
||||
int FlowLayout::verticalSpacing() const
|
||||
{
|
||||
if (m_vSpace >= 0) {
|
||||
return m_vSpace;
|
||||
} else {
|
||||
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
|
||||
}//if (m_vSpace >= 0)
|
||||
}
|
||||
void FlowLayout::setVerticalSpacing(int &v)
|
||||
{
|
||||
if (v>=0) {
|
||||
m_vSpace = v;
|
||||
} else {
|
||||
m_vSpace = -1;
|
||||
}//if (v>=0)
|
||||
doLayout(geometry(), false);
|
||||
}
|
||||
|
||||
int FlowLayout::count() const
|
||||
{
|
||||
return m_itemList.size();
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::itemAt(int index) const
|
||||
{
|
||||
return m_itemList.value(index);
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::itemAtGlobal(const QPoint &p) const
|
||||
{
|
||||
return m_itemList.value(indexAtGlobal(p));
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::itemAtParent(const QPoint &p) const
|
||||
{
|
||||
return m_itemList.value(indexAtParent(p));
|
||||
}
|
||||
|
||||
int FlowLayout::indexAtGlobal(const QPoint &p) const
|
||||
{
|
||||
int count = m_itemList.size();
|
||||
for(int curs=0; curs<count; ++curs){
|
||||
QWidget *widget = m_itemList.value(curs)->widget();
|
||||
if(widget) {
|
||||
QPoint pos = widget->mapFromGlobal(p);
|
||||
if((pos.x()>0) && (pos.x()<widget->width()))
|
||||
if((pos.y()>0) && (pos.y()<widget->height()))
|
||||
return curs;
|
||||
}//if(widget)
|
||||
}//for(int curs=0; curs<count; ++curs)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int FlowLayout::indexAtParent(const QPoint &p) const
|
||||
{
|
||||
int count = m_itemList.size();
|
||||
for(int curs=0; curs<count; ++curs){
|
||||
QWidget *widget = m_itemList.value(curs)->widget();
|
||||
if(widget) {
|
||||
QPoint pos = widget->mapFromParent(p);
|
||||
if((pos.x()>=0) && (pos.x()<=widget->width()))
|
||||
if((pos.y()>=0) && (pos.y()<=widget->height()))
|
||||
return curs;
|
||||
|
||||
if (pos.y()<0) break;//In line below so don't check other item.
|
||||
}//if(widget)
|
||||
}//for(int curs=0; curs<count; ++curs)
|
||||
return -1;
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::takeAt(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_itemList.size())
|
||||
return m_itemList.takeAt(index);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
Qt::Orientations FlowLayout::expandingDirections() const
|
||||
{
|
||||
return Qt::Horizontal;
|
||||
}
|
||||
|
||||
bool FlowLayout::hasHeightForWidth() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int FlowLayout::heightForWidth(int width) const
|
||||
{
|
||||
int height = doLayout(QRect(0, 0, width, 0), true);
|
||||
return height;
|
||||
}
|
||||
|
||||
void FlowLayout::setGeometry(const QRect &rect)
|
||||
{
|
||||
QLayout::setGeometry(rect);
|
||||
doLayout(rect, false);
|
||||
}
|
||||
|
||||
QSize FlowLayout::sizeHint() const
|
||||
{
|
||||
return minimumSize();
|
||||
}
|
||||
|
||||
QSize FlowLayout::minimumSize() const
|
||||
{
|
||||
QSize size;
|
||||
QLayoutItem *item;
|
||||
foreach (item, m_itemList)
|
||||
size = size.expandedTo(item->minimumSize());
|
||||
|
||||
size += QSize(2*margin(), 2*margin());
|
||||
return size;
|
||||
}
|
||||
|
||||
void FlowLayout::addSelection(bool invert){
|
||||
for (int curs=m_selStartIndex; curs<=m_selStopIndex; ++curs){
|
||||
QLayoutItem *item=itemAt(curs);
|
||||
if (item) {
|
||||
FlowLayoutItem *fli = qobject_cast<FlowLayoutItem *>(item->widget());
|
||||
if (invert && m_selectionList.contains(item)){
|
||||
if (fli) fli->setIsSelected(false);
|
||||
m_selectionList.removeOne(item);
|
||||
} else {
|
||||
if (fli) fli->setIsSelected(true);
|
||||
m_selectionList.append(item);
|
||||
}//if (m_selectionList.contains(item))
|
||||
}//if (item)
|
||||
}//for (int curs=m_selStartIndex; curs<=m_selStopIndex; ++curs)
|
||||
}
|
||||
|
||||
void FlowLayout::performDrag()
|
||||
{
|
||||
QPixmap dragPixmap;
|
||||
bool atLeastOnePixmap = false;
|
||||
int count = m_selectionList.count();
|
||||
for (int curs=0; curs<count; ++curs){
|
||||
QLayoutItem *layoutItem = m_selectionList.at(curs);
|
||||
if (layoutItem){
|
||||
QWidget *widget = layoutItem->widget();
|
||||
if (widget) {
|
||||
QPixmap itemPixmap;
|
||||
FlowLayoutItem *item = qobject_cast<FlowLayoutItem *>(widget);
|
||||
if (item){
|
||||
itemPixmap = item->getDragImage();
|
||||
} else {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
|
||||
itemPixmap = widget->grab();//QT5
|
||||
#else
|
||||
itemPixmap = QPixmap::grabWidget(widget);
|
||||
#endif
|
||||
}//if (item)
|
||||
|
||||
itemPixmap = itemPixmap.scaled(50,50,Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
/// Warning On Windows, Drag Pixmap size cannot exceed 50*50. ///
|
||||
if (curs==0) dragPixmap = itemPixmap;
|
||||
QPixmap oldPixmap = dragPixmap;
|
||||
if (curs!=0) dragPixmap = QPixmap(oldPixmap.width() + 20 , oldPixmap.height());
|
||||
dragPixmap.fill(widget->palette().background().color());
|
||||
QPainter painter(&dragPixmap);
|
||||
painter.drawPixmap(0, 0, oldPixmap);
|
||||
if (curs!=0) painter.drawPixmap((20 * curs), 0, itemPixmap);
|
||||
|
||||
atLeastOnePixmap = true;
|
||||
}//if (widget)
|
||||
}//if (layoutItem)
|
||||
}//for (int curs=0; curs<count; ++curs)
|
||||
if (atLeastOnePixmap) {
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setText("");
|
||||
QDrag *drag = new QDrag(this->parentWidget());
|
||||
drag->setMimeData(mimeData);
|
||||
|
||||
drag->setPixmap(dragPixmap);
|
||||
drag->setHotSpot(QPoint(0, 0));
|
||||
drag->exec(Qt::CopyAction);
|
||||
}//if (atLeastOnePixmap)
|
||||
}
|
||||
|
||||
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
|
||||
{
|
||||
int left, top, right, bottom;
|
||||
getContentsMargins(&left, &top, &right, &bottom);
|
||||
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
|
||||
int x = effectiveRect.x();
|
||||
int y = effectiveRect.y();
|
||||
int lineHeight = 0;
|
||||
|
||||
int count = m_itemList.size();
|
||||
for (int curs=0; curs<count; ++curs) {
|
||||
QLayoutItem *item=m_itemList.value(curs);
|
||||
QWidget *wid = item->widget();
|
||||
int spaceX = horizontalSpacing();
|
||||
if (spaceX == -1)
|
||||
spaceX = wid->style()->layoutSpacing(
|
||||
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
|
||||
int spaceY = verticalSpacing();
|
||||
if (spaceY == -1)
|
||||
spaceY = wid->style()->layoutSpacing(
|
||||
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
|
||||
|
||||
int nextX = x + item->sizeHint().width() + spaceX;
|
||||
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
|
||||
x = effectiveRect.x();
|
||||
y = y + lineHeight + spaceY;
|
||||
nextX = x + item->sizeHint().width() + spaceX;
|
||||
lineHeight = 0;
|
||||
}//if (nextX - spaceX > effectiveRect.right() && lineHeight > 0)
|
||||
|
||||
if (!testOnly){
|
||||
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
|
||||
bool selected = m_selectionList.contains(item);
|
||||
bool isCurrent = (curs==currentIndex());
|
||||
QString solid = isCurrent?"dot-dash":"inset";
|
||||
QString color = selected?"blue":isCurrent?"gray":"";
|
||||
QString border = (selected||isCurrent)?QString("border: 1px %1 %2").arg(solid).arg(color):"";
|
||||
QString widName = wid->objectName();
|
||||
QString style;
|
||||
if (widName.isEmpty()){
|
||||
style=border;
|
||||
} else {
|
||||
//For Custom QWidget, change paintEvent as FlowLayoutItem. cf:http://qt-project.org/doc/qt-4.8/stylesheet-reference.html
|
||||
style = QString("QWidget#%1\n{\n%2\n}\n").arg(wid->objectName(),border);
|
||||
}//if (widName.isEmpty())
|
||||
///Warning: Test if != to not ask a new redraw all time ///
|
||||
if (wid->styleSheet()!=style) wid->setStyleSheet(style);
|
||||
}//if (!testOnly)
|
||||
|
||||
x = nextX;
|
||||
lineHeight = qMax(lineHeight, item->sizeHint().height());
|
||||
}//for (curs=0; curs<count; ++curs)
|
||||
|
||||
return y + lineHeight - rect.y() + bottom;
|
||||
}
|
||||
|
||||
int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
|
||||
{
|
||||
QObject *parent = this->parent();
|
||||
if (!parent) {
|
||||
return -1;
|
||||
} else if (parent->isWidgetType()) {
|
||||
QWidget *pw = static_cast<QWidget *>(parent);
|
||||
return pw->style()->pixelMetric(pm, 0, pw);
|
||||
} else {
|
||||
return static_cast<QLayout *>(parent)->spacing();
|
||||
}//if (!parent)
|
||||
}
|
344
retroshare-gui/src/gui/common/FlowLayout.h
Normal file
344
retroshare-gui/src/gui/common/FlowLayout.h
Normal file
|
@ -0,0 +1,344 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
/** WARNING: QT Designer don't accept Custom Layout, maybe on QT5
|
||||
*You can get widget's children like this:
|
||||
* FlowLayout *flowLayout = new FlowLayout;
|
||||
* //First Get Item in Qt Designer
|
||||
* int count = ui->id->children().count();
|
||||
* for (int curs = 0; curs < count; ++curs){
|
||||
* QObject *obj = ui->id->children().at(curs);
|
||||
* QWidget *wid = qobject_cast<QWidget *>(obj);
|
||||
* if (wid) flowLayout->addWidget(wid);
|
||||
* }//for (int curs = 0; curs < count; ++curs)
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef FLOWLAYOUT_H
|
||||
#define FLOWLAYOUT_H
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QLayout>
|
||||
#include <QPainter>
|
||||
#include <QRect>
|
||||
#include <QScrollArea>
|
||||
#include <QStyle>
|
||||
#include <QStyleOption>
|
||||
#include <QWidget>
|
||||
#include <QWidgetItem>
|
||||
|
||||
/// \class FlowLayoutItem
|
||||
/// \brief The FlowLayoutItem class
|
||||
///FlowLayoutItem represents FlowLayout item.
|
||||
///Derivatives from it to make a custom widget
|
||||
///and to get Drag and Drop better.
|
||||
class FlowLayoutItem : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FlowLayoutItem(QString name=QString(), QWidget *parent=0) : QWidget(parent), m_myName(name){
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
~FlowLayoutItem(){}
|
||||
|
||||
/// \brief getImage
|
||||
/// \return Image to represent your widget (not necessary all the widget).
|
||||
virtual const QPixmap getImage() =0;
|
||||
/// \brief getDragImage
|
||||
/// \return Image to represent your widget when dragged (not necessary all the widget).
|
||||
virtual const QPixmap getDragImage() =0;
|
||||
/// \brief setName
|
||||
/// \param value
|
||||
virtual void setName(QString value) {m_myName=value;}
|
||||
/// \brief getName
|
||||
/// \return the name of your widget;
|
||||
virtual const QString getName() const {return m_myName;}
|
||||
/// \brief setIsSelected
|
||||
/// \param value
|
||||
virtual void setIsSelected(bool value) {m_isSelected=value;}
|
||||
/// \brief getSelected
|
||||
/// \return if item is selected
|
||||
virtual bool isSelected() const {return m_isSelected;}
|
||||
/// \brief setCurrent
|
||||
/// \param value
|
||||
virtual void setIsCurrent(bool value) {m_isCurrent=value;}
|
||||
/// \brief isCurrent
|
||||
/// \return if item is the current one
|
||||
virtual bool isCurrent() const {return m_isCurrent;}
|
||||
|
||||
/// \brief paintEvent
|
||||
///To get Style working on widget and not on all children.
|
||||
void paintEvent(QPaintEvent *)
|
||||
{
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
||||
|
||||
signals:
|
||||
/// \brief flowLayoutItemDropped
|
||||
/// \param listItem: QList with all item dropped.
|
||||
/// \param bAccept: set it to true to accept drop event.
|
||||
///Signales when the widget is dropped.
|
||||
void flowLayoutItemDropped(QList <FlowLayoutItem*> listItem, bool &bAccept);
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event){event->ignore();}
|
||||
void keyReleaseEvent(QKeyEvent *event){event->ignore();}
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
void dragMoveEvent(QDragMoveEvent *event);
|
||||
void dropEvent(QDropEvent *event);
|
||||
|
||||
QString m_myName;
|
||||
bool m_isSelected;
|
||||
bool m_isCurrent;
|
||||
|
||||
private:
|
||||
void performDrag();
|
||||
|
||||
private:
|
||||
QPoint m_startPos;
|
||||
};
|
||||
|
||||
/// \class FlowLayout
|
||||
/// \brief The FlowLayout class
|
||||
///Class FlowLayout arranges child widgets from left to right
|
||||
///and top to bottom in a top-level widget.
|
||||
///The items are first laid out horizontally and
|
||||
///then vertically when each line in the layout runs out of space.
|
||||
class FlowLayout : public QLayout
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int horizontalSpacing READ horizontalSpacing WRITE setHorizontalSpacing)
|
||||
Q_PROPERTY(int verticalSpacing READ verticalSpacing WRITE setVerticalSpacing)
|
||||
Q_PROPERTY(Qt::Orientations expandingDirections READ expandingDirections)
|
||||
Q_PROPERTY(int count READ count)
|
||||
Q_PROPERTY(QSize minimumSize READ minimumSize)
|
||||
Q_PROPERTY(QLayoutItem *currentItem READ currentItem)
|
||||
Q_PROPERTY(int currentIndex READ currentIndex)
|
||||
|
||||
public:
|
||||
FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
~FlowLayout();
|
||||
|
||||
///
|
||||
/// \brief addItem QLayoutItem
|
||||
/// \param item
|
||||
///to add a new item. (normally called by addWidget)
|
||||
void addItem(QLayoutItem *item);
|
||||
///
|
||||
/// \brief addItem FlowLayoutItem
|
||||
/// \param item
|
||||
///To add a new FlowLayoutItem item.
|
||||
void addItem(FlowLayoutItem *item);
|
||||
///
|
||||
/// \brief horizontalSpacing
|
||||
/// \return int
|
||||
///Returns the horizontal spacing of items in the layout.
|
||||
int horizontalSpacing() const;
|
||||
///
|
||||
/// \brief setHorizontalSpacing
|
||||
/// \param h
|
||||
///To set the horizontal spacing of items in the layout.
|
||||
void setHorizontalSpacing(int &h);
|
||||
///
|
||||
/// \brief verticalSpacing
|
||||
/// \return int
|
||||
///Returns the vertical spacing of items in the layout.
|
||||
int verticalSpacing() const;
|
||||
///
|
||||
/// \brief setVerticalSpacing
|
||||
/// \param v
|
||||
///To set the horizontal spacing of items in the layout.
|
||||
void setVerticalSpacing(int &v);
|
||||
///
|
||||
/// \brief expandingDirections
|
||||
/// \return Qt::Orientations
|
||||
///Returns the Qt::Orientations in which the layout can make
|
||||
/// use of more space than its sizeHint().
|
||||
Qt::Orientations expandingDirections() const;
|
||||
///
|
||||
/// \brief hasHeightForWidth
|
||||
/// \return bool
|
||||
///Indicates if heightForWidth() is implemented.
|
||||
bool hasHeightForWidth() const;
|
||||
///
|
||||
/// \brief heightForWidth
|
||||
/// \return int
|
||||
///To adjust to widgets of which height is dependent on width.
|
||||
int heightForWidth(int) const;
|
||||
///
|
||||
/// \brief count
|
||||
/// \return int
|
||||
///Returns items count.
|
||||
int count() const;
|
||||
///
|
||||
/// \brief itemAt
|
||||
/// \param index
|
||||
/// \return QLayoutItem*
|
||||
///Returns item at index position.
|
||||
QLayoutItem *itemAt(int index) const;
|
||||
///
|
||||
/// \brief itemAtGlobal
|
||||
/// \param p
|
||||
/// \return QLayoutItem*
|
||||
///Returns item at position indicate with p. This position is on global screen coordinates.
|
||||
QLayoutItem *itemAtGlobal(const QPoint &p) const;
|
||||
///
|
||||
/// \brief itemAtParent
|
||||
/// \param p
|
||||
/// \return QLayoutItem*
|
||||
///Returns item at position indicate with p. This position is on parent screen coordinates.
|
||||
QLayoutItem *itemAtParent(const QPoint &p) const;
|
||||
///
|
||||
/// \brief indexAtGlobal
|
||||
/// \param p
|
||||
/// \return int
|
||||
///Returns index of item at position indicate with p. This position is on global screen coordinates.
|
||||
int indexAtGlobal(const QPoint &p) const;
|
||||
///
|
||||
/// \brief indexAtParent
|
||||
/// \param p
|
||||
/// \return int
|
||||
///Returns index of item at position indicate with p. This position is on parent screen coordinates.
|
||||
int indexAtParent(const QPoint &p) const;
|
||||
///
|
||||
/// \brief minimumSize
|
||||
/// \return QSize
|
||||
///Returns the minimum size of all child items.
|
||||
QSize minimumSize() const;
|
||||
///
|
||||
/// \brief setGeometry
|
||||
/// \param rect
|
||||
///Set the geometry of the layout relative to its parent and excluding the window frame.
|
||||
///It's for redraw item list when it was resized.
|
||||
void setGeometry(const QRect &rect);
|
||||
///
|
||||
/// \brief sizeHint
|
||||
/// \return QSize
|
||||
///Returns recommended (minimum) size.
|
||||
QSize sizeHint() const;
|
||||
///
|
||||
/// \brief takeAt
|
||||
/// \param index
|
||||
/// \return QLayoutItem*
|
||||
///Take an item in list (erase it).
|
||||
QLayoutItem *takeAt(int index);
|
||||
///
|
||||
/// \brief selectionList
|
||||
/// \return QList<QLayoutItem *>
|
||||
///Returns the list of selected items.
|
||||
QList<QLayoutItem *> selectionList() const { return m_selectionList;}
|
||||
///
|
||||
/// \brief currentItem
|
||||
/// \return QLayoutItem *
|
||||
///Returns the current (only one) item.
|
||||
QLayoutItem *currentItem() const { return m_itemList.value(m_currentIndex);}
|
||||
///
|
||||
/// \brief currentIndex
|
||||
/// \return int
|
||||
///Returns index of current item.
|
||||
int currentIndex() const { return m_currentIndex;}
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
void unsetCurrent();
|
||||
void setCurrent();
|
||||
|
||||
private:
|
||||
// Redraw all the layout
|
||||
int doLayout(const QRect &rect, bool testOnly) const;
|
||||
//To get the default spacing for either the top-level layouts or the sublayouts.
|
||||
//The default spacing for top-level layouts, when the parent is a QWidget,
|
||||
//will be determined by querying the style.
|
||||
//The default spacing for sublayouts, when the parent is a QLayout,
|
||||
//will be determined by querying the spacing of the parent layout.
|
||||
int smartSpacing(QStyle::PixelMetric pm) const;
|
||||
//Execute drag action.
|
||||
void performDrag();
|
||||
//Update selection with m_selStartIndex and m_selStopIndex.
|
||||
//If invert, item selection is toggled.
|
||||
void addSelection(bool invert);
|
||||
|
||||
QList<QLayoutItem *> m_itemList;
|
||||
QList<QLayoutItem *> m_selectionList;
|
||||
int m_selStartIndex;
|
||||
int m_selStopIndex;
|
||||
int m_currentIndex;
|
||||
|
||||
QPoint m_startPos;
|
||||
|
||||
int m_hSpace;
|
||||
int m_vSpace;
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief The FlowLayoutWidget class
|
||||
///Class FlowLayoutWidget provide a simple widget with FlowLayout as layout.
|
||||
///This could be integrate on QtDesigner
|
||||
class FlowLayoutWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FlowLayoutWidget(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
FlowLayoutWidget(int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
~FlowLayoutWidget();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
private:
|
||||
void updateParent();
|
||||
|
||||
QScrollArea *m_saParent;
|
||||
QScrollBar *m_sbVertical;
|
||||
int m_lastYPos;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
1264
retroshare-gui/src/gui/common/PictureFlow.cpp
Normal file
1264
retroshare-gui/src/gui/common/PictureFlow.cpp
Normal file
File diff suppressed because it is too large
Load diff
263
retroshare-gui/src/gui/common/PictureFlow.h
Normal file
263
retroshare-gui/src/gui/common/PictureFlow.h
Normal file
|
@ -0,0 +1,263 @@
|
|||
/*From version of May 16 2010
|
||||
ORIGINAL COPYRIGHT HEADER
|
||||
PictureFlow - animated image show widget
|
||||
http://pictureflow.googlecode.com
|
||||
|
||||
Copyright (C) 2008 Ariya Hidayat (ariya@kde.org)
|
||||
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PICTUREFLOW_H
|
||||
#define PICTUREFLOW_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class PictureFlowPrivate;
|
||||
|
||||
/// \class PictureFlow
|
||||
/// \brief The PictureFlow class
|
||||
///Class PictureFlow implements an image show widget with animation effect
|
||||
///like Apple's CoverFlow (in iTunes and iPod). Images are arranged in form
|
||||
///of slides, one main slide is shown at the center with few slides on
|
||||
///the left and right sides of the center slide. When the next or previous
|
||||
///slide is brought to the front, the whole slides flow to the right or
|
||||
///the right with smooth animation effect; until the new slide is finally
|
||||
///placed at the center.
|
||||
class PictureFlow : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
|
||||
Q_PROPERTY(QSize slideSize READ slideSize)
|
||||
Q_PROPERTY(float slideSizeRatio READ slideSizeRatio WRITE setSlideSizeRatio)
|
||||
Q_PROPERTY(int slideCount READ slideCount)
|
||||
Q_PROPERTY(int centerIndex READ centerIndex WRITE setCenterIndex)
|
||||
|
||||
public:
|
||||
|
||||
enum ReflectionEffect
|
||||
{
|
||||
NoReflection,
|
||||
PlainReflection,
|
||||
BlurredReflection
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief PictureFlow
|
||||
/// \param parent
|
||||
///Creates a new PictureFlow widget.
|
||||
PictureFlow(QWidget* parent = 0);
|
||||
|
||||
///
|
||||
/// \brief ~PictureFlow
|
||||
///Destroys the widget.
|
||||
~PictureFlow();
|
||||
|
||||
///
|
||||
/// \brief backgroundColor
|
||||
/// \return QColor
|
||||
///Returns the background color.
|
||||
QColor backgroundColor() const;
|
||||
|
||||
///
|
||||
/// \brief setBackgroundColor
|
||||
/// \param c
|
||||
///Sets the background color. By default it is black.
|
||||
void setBackgroundColor(const QColor& c);
|
||||
|
||||
/*!
|
||||
Returns the dimension of each slide (in pixels).
|
||||
*/
|
||||
///
|
||||
/// \brief slideSize
|
||||
/// \return QSize
|
||||
///Returns the dimension of each slide (in pixels).
|
||||
QSize slideSize() const;
|
||||
|
||||
///
|
||||
/// \brief slideSizeRatio
|
||||
/// \return float
|
||||
///Returns the ratio dimension of each slide (Height/Width).
|
||||
float slideSizeRatio() const;
|
||||
|
||||
///
|
||||
/// \brief setSlideSizeRatio
|
||||
/// \param ratio
|
||||
///Sets the ratio of dimension of each slide (in pixels).
|
||||
void setSlideSizeRatio(float ratio);
|
||||
|
||||
///
|
||||
/// \brief slideCount
|
||||
/// \return int
|
||||
///Returns the total number of slides.
|
||||
int slideCount() const;
|
||||
|
||||
///
|
||||
/// \brief slide
|
||||
/// \param index
|
||||
/// \return QImage
|
||||
///Returns QImage of specified slide.
|
||||
QImage slide(int index) const;
|
||||
|
||||
///
|
||||
/// \brief slideAt
|
||||
/// \param point
|
||||
/// \return int
|
||||
///Returns QImage of specified slide.
|
||||
int slideAt(QPoint point) const;
|
||||
|
||||
///
|
||||
/// \brief centerIndex
|
||||
/// \return int
|
||||
///Returns the index of slide currently shown in the middle of the viewport.
|
||||
int centerIndex() const;
|
||||
|
||||
///
|
||||
/// \brief reflectionEffect
|
||||
/// \return ReflectionEffect
|
||||
///Returns the effect applied to the reflection.
|
||||
ReflectionEffect reflectionEffect() const;
|
||||
|
||||
///
|
||||
/// \brief setReflectionEffect
|
||||
/// \param effect
|
||||
///Sets the effect applied to the reflection. The default is PlainReflection.
|
||||
void setReflectionEffect(ReflectionEffect effect);
|
||||
|
||||
public slots:
|
||||
|
||||
///
|
||||
/// \brief addSlide
|
||||
/// \param image QImage of slide
|
||||
///Adds a new slide.
|
||||
void addSlide(const QImage& image);
|
||||
|
||||
///
|
||||
/// \brief addSlide
|
||||
/// \param pixmap QPixmap of slide
|
||||
///Adds a new slide.
|
||||
void addSlide(const QPixmap& pixmap);
|
||||
|
||||
///
|
||||
/// \brief setSlide
|
||||
/// \param index index of slide
|
||||
/// \param image QImage of slide
|
||||
///Sets an image for specified slide. If the slide already exists,
|
||||
///it will be replaced.
|
||||
|
||||
void setSlide(int index, const QImage& image);
|
||||
|
||||
///
|
||||
/// \brief setSlide
|
||||
/// \param index index of slide
|
||||
/// \param pixmap QPixmap of slide
|
||||
///Sets a pixmap for specified slide. If the slide already exists,
|
||||
///it will be replaced.
|
||||
void setSlide(int index, const QPixmap& pixmap);
|
||||
|
||||
///
|
||||
/// \brief setCenterIndex
|
||||
/// \param index Index of slide to center
|
||||
///Sets slide to be shown in the middle of the viewport. No animation
|
||||
///effect will be produced, unlike using showSlide.
|
||||
void setCenterIndex(int index);
|
||||
|
||||
///
|
||||
/// \brief clear
|
||||
///Clears all slides.
|
||||
void clear();
|
||||
|
||||
///
|
||||
/// \brief showPrevious
|
||||
///Shows previous slide using animation effect.
|
||||
void showPrevious();
|
||||
|
||||
///
|
||||
/// \brief showNext
|
||||
///Shows next slide using animation effect.
|
||||
void showNext();
|
||||
|
||||
///
|
||||
/// \brief showSlide
|
||||
/// \param index
|
||||
///Go to specified slide using animation effect.
|
||||
void showSlide(int index);
|
||||
|
||||
///
|
||||
/// \brief render
|
||||
///Rerender the widget. Normally this function will be automatically invoked
|
||||
///whenever necessary, e.g. during the transition animation.
|
||||
void render();
|
||||
|
||||
///
|
||||
/// \brief triggerRender
|
||||
///Schedules a rendering update. Unlike render(), this function does not cause
|
||||
///immediate rendering.
|
||||
void triggerRender();
|
||||
|
||||
signals:
|
||||
///
|
||||
/// \brief centerIndexChanged
|
||||
/// \param index
|
||||
///Signals when index was changed.
|
||||
void centerIndexChanged(int index);
|
||||
///
|
||||
/// \brief mouseMoveOverSlideEvent
|
||||
/// \param event
|
||||
/// \param slideIndex
|
||||
///Signals when mouse move over a slide.
|
||||
void mouseMoveOverSlideEvent(QMouseEvent* event, int slideIndex);
|
||||
///
|
||||
/// \brief dragEnterEventOccurs
|
||||
/// \param event
|
||||
///Signals when a drag enters on a slide.
|
||||
void dragEnterEventOccurs(QDragEnterEvent *event);
|
||||
///
|
||||
/// \brief dragMoveEventOccurs
|
||||
/// \param event
|
||||
///Signals when a drag move over a slide.
|
||||
void dragMoveEventOccurs(QDragMoveEvent *event);
|
||||
///
|
||||
/// \brief dropEventOccurs
|
||||
/// \param event
|
||||
///Signals when something is dropped on slide.
|
||||
void dropEventOccurs(QDropEvent *event);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event);
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
void dragMoveEvent(QDragMoveEvent *event);
|
||||
void dropEvent(QDropEvent *event);
|
||||
|
||||
private slots:
|
||||
void updateAnimation();
|
||||
|
||||
private:
|
||||
PictureFlowPrivate* d;
|
||||
QPoint dragMoveLastPos;
|
||||
};
|
||||
|
||||
#endif // PICTUREFLOW_H
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue