2014-09-28 16:46:56 -04:00
|
|
|
/****************************************************************************
|
|
|
|
**
|
|
|
|
** 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);
|
|
|
|
|
2014-10-12 16:07:12 -04:00
|
|
|
/// \brief updated
|
|
|
|
///Signales when the image (getImage) is updated.
|
|
|
|
void imageUpdated();
|
|
|
|
|
2014-09-28 16:46:56 -04:00
|
|
|
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
|