From f71f962f5458df1e43ab473d809d837c738ba1cf Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 1 Jul 2015 11:05:26 +0200 Subject: [PATCH] + Add QSint sources --- src/Gui/QSint/actionpanel/actionbox.cpp | 218 ++++++++++++++ src/Gui/QSint/actionpanel/actionbox.h | 251 ++++++++++++++++ src/Gui/QSint/actionpanel/actiongroup.cpp | 250 ++++++++++++++++ src/Gui/QSint/actionpanel/actiongroup.h | 167 +++++++++++ src/Gui/QSint/actionpanel/actionlabel.cpp | 116 ++++++++ src/Gui/QSint/actionpanel/actionlabel.h | 86 ++++++ src/Gui/QSint/actionpanel/actionpanel.cpp | 93 ++++++ src/Gui/QSint/actionpanel/actionpanel.h | 86 ++++++ .../QSint/actionpanel/actionpanelscheme.cpp | 113 ++++++++ src/Gui/QSint/actionpanel/actionpanelscheme.h | 76 +++++ src/Gui/QSint/actionpanel/android/Fold.png | Bin 0 -> 1705 bytes .../QSint/actionpanel/android/FoldOver.png | Bin 0 -> 1725 bytes src/Gui/QSint/actionpanel/android/Unfold.png | Bin 0 -> 1701 bytes .../QSint/actionpanel/android/UnfoldOver.png | Bin 0 -> 1721 bytes .../QSint/actionpanel/androidpanelscheme.cpp | 75 +++++ .../QSint/actionpanel/androidpanelscheme.h | 34 +++ src/Gui/QSint/actionpanel/default/Fold.png | Bin 0 -> 140 bytes .../QSint/actionpanel/default/FoldOver.png | Bin 0 -> 771 bytes src/Gui/QSint/actionpanel/default/Unfold.png | Bin 0 -> 140 bytes .../QSint/actionpanel/default/UnfoldOver.png | Bin 0 -> 747 bytes src/Gui/QSint/actionpanel/mac/FoldOver.png | Bin 0 -> 511 bytes src/Gui/QSint/actionpanel/mac/UnfoldOver.png | Bin 0 -> 685 bytes src/Gui/QSint/actionpanel/macpanelscheme.cpp | 66 +++++ src/Gui/QSint/actionpanel/macpanelscheme.h | 32 ++ src/Gui/QSint/actionpanel/schemes.qrc | 26 ++ src/Gui/QSint/actionpanel/taskgroup_p.cpp | 146 ++++++++++ src/Gui/QSint/actionpanel/taskgroup_p.h | 48 +++ src/Gui/QSint/actionpanel/taskheader_p.cpp | 274 ++++++++++++++++++ src/Gui/QSint/actionpanel/taskheader_p.h | 64 ++++ src/Gui/QSint/actionpanel/vista/Fold.png | Bin 0 -> 140 bytes src/Gui/QSint/actionpanel/vista/FoldOver.png | Bin 0 -> 771 bytes src/Gui/QSint/actionpanel/vista/Unfold.png | Bin 0 -> 140 bytes .../QSint/actionpanel/vista/UnfoldOver.png | Bin 0 -> 747 bytes .../QSint/actionpanel/winvistapanelscheme.cpp | 86 ++++++ .../QSint/actionpanel/winvistapanelscheme.h | 34 +++ .../QSint/actionpanel/winxppanelscheme.cpp | 170 +++++++++++ src/Gui/QSint/actionpanel/winxppanelscheme.h | 51 ++++ .../QSint/actionpanel/xp/FoldOver_Blue1.png | Bin 0 -> 823 bytes .../QSint/actionpanel/xp/FoldOver_Blue2.png | Bin 0 -> 777 bytes src/Gui/QSint/actionpanel/xp/Fold_Blue1.png | Bin 0 -> 808 bytes src/Gui/QSint/actionpanel/xp/Fold_Blue2.png | Bin 0 -> 782 bytes .../QSint/actionpanel/xp/UnfoldOver_Blue1.png | Bin 0 -> 804 bytes .../QSint/actionpanel/xp/UnfoldOver_Blue2.png | Bin 0 -> 797 bytes src/Gui/QSint/actionpanel/xp/Unfold_Blue1.png | Bin 0 -> 792 bytes src/Gui/QSint/actionpanel/xp/Unfold_Blue2.png | Bin 0 -> 802 bytes src/Gui/QSint/include/QSint | 9 + 46 files changed, 2571 insertions(+) create mode 100644 src/Gui/QSint/actionpanel/actionbox.cpp create mode 100644 src/Gui/QSint/actionpanel/actionbox.h create mode 100644 src/Gui/QSint/actionpanel/actiongroup.cpp create mode 100644 src/Gui/QSint/actionpanel/actiongroup.h create mode 100644 src/Gui/QSint/actionpanel/actionlabel.cpp create mode 100644 src/Gui/QSint/actionpanel/actionlabel.h create mode 100644 src/Gui/QSint/actionpanel/actionpanel.cpp create mode 100644 src/Gui/QSint/actionpanel/actionpanel.h create mode 100644 src/Gui/QSint/actionpanel/actionpanelscheme.cpp create mode 100644 src/Gui/QSint/actionpanel/actionpanelscheme.h create mode 100644 src/Gui/QSint/actionpanel/android/Fold.png create mode 100644 src/Gui/QSint/actionpanel/android/FoldOver.png create mode 100644 src/Gui/QSint/actionpanel/android/Unfold.png create mode 100644 src/Gui/QSint/actionpanel/android/UnfoldOver.png create mode 100644 src/Gui/QSint/actionpanel/androidpanelscheme.cpp create mode 100644 src/Gui/QSint/actionpanel/androidpanelscheme.h create mode 100644 src/Gui/QSint/actionpanel/default/Fold.png create mode 100644 src/Gui/QSint/actionpanel/default/FoldOver.png create mode 100644 src/Gui/QSint/actionpanel/default/Unfold.png create mode 100644 src/Gui/QSint/actionpanel/default/UnfoldOver.png create mode 100644 src/Gui/QSint/actionpanel/mac/FoldOver.png create mode 100644 src/Gui/QSint/actionpanel/mac/UnfoldOver.png create mode 100644 src/Gui/QSint/actionpanel/macpanelscheme.cpp create mode 100644 src/Gui/QSint/actionpanel/macpanelscheme.h create mode 100644 src/Gui/QSint/actionpanel/schemes.qrc create mode 100644 src/Gui/QSint/actionpanel/taskgroup_p.cpp create mode 100644 src/Gui/QSint/actionpanel/taskgroup_p.h create mode 100644 src/Gui/QSint/actionpanel/taskheader_p.cpp create mode 100644 src/Gui/QSint/actionpanel/taskheader_p.h create mode 100644 src/Gui/QSint/actionpanel/vista/Fold.png create mode 100644 src/Gui/QSint/actionpanel/vista/FoldOver.png create mode 100644 src/Gui/QSint/actionpanel/vista/Unfold.png create mode 100644 src/Gui/QSint/actionpanel/vista/UnfoldOver.png create mode 100644 src/Gui/QSint/actionpanel/winvistapanelscheme.cpp create mode 100644 src/Gui/QSint/actionpanel/winvistapanelscheme.h create mode 100644 src/Gui/QSint/actionpanel/winxppanelscheme.cpp create mode 100644 src/Gui/QSint/actionpanel/winxppanelscheme.h create mode 100644 src/Gui/QSint/actionpanel/xp/FoldOver_Blue1.png create mode 100644 src/Gui/QSint/actionpanel/xp/FoldOver_Blue2.png create mode 100644 src/Gui/QSint/actionpanel/xp/Fold_Blue1.png create mode 100644 src/Gui/QSint/actionpanel/xp/Fold_Blue2.png create mode 100644 src/Gui/QSint/actionpanel/xp/UnfoldOver_Blue1.png create mode 100644 src/Gui/QSint/actionpanel/xp/UnfoldOver_Blue2.png create mode 100644 src/Gui/QSint/actionpanel/xp/Unfold_Blue1.png create mode 100644 src/Gui/QSint/actionpanel/xp/Unfold_Blue2.png create mode 100644 src/Gui/QSint/include/QSint diff --git a/src/Gui/QSint/actionpanel/actionbox.cpp b/src/Gui/QSint/actionpanel/actionbox.cpp new file mode 100644 index 000000000..28ea29564 --- /dev/null +++ b/src/Gui/QSint/actionpanel/actionbox.cpp @@ -0,0 +1,218 @@ +#include "actionbox.h" + +#include + + +namespace QSint +{ + + +const char* ActionBoxStyle = + "QSint--ActionBox {" + "background-color: white;" + "border: 1px solid white;" + "border-radius: 3px;" + "text-align: left;" + "}" + + "QSint--ActionBox:hover {" + "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #F9FDFF, stop: 1 #EAF7FF);" + "border: 1px solid #DAF2FC;" + "}" + + + "QSint--ActionBox QSint--ActionLabel[class='header'] {" + "text-align: left;" + "font: 14px;" + "color: #006600;" + "background-color: transparent;" + "border: none;" + "}" + + "QSint--ActionBox QSint--ActionLabel[class='header']:hover {" + "color: #00cc00;" + "text-decoration: underline;" + "}" + + + "QSint--ActionBox QSint--ActionLabel[class='action'] {" + "background-color: transparent;" + "border: none;" + "color: #0033ff;" + "text-align: left;" + "font: 11px;" + "}" + + "QSint--ActionBox QSint--ActionLabel[class='action']:!enabled {" + "color: #999999;" + "}" + + "QSint--ActionBox QSint--ActionLabel[class='action']:hover {" + "color: #0099ff;" + "text-decoration: underline;" + "}" + + "QSint--ActionBox QSint--ActionLabel[class='action']:on {" + "background-color: #ddeeff;" + "color: #006600;" + "}" + +; + + +ActionBox::ActionBox(QWidget *parent) : + QFrame(parent) +{ + init(); +} + +ActionBox::ActionBox(const QString & headerText, QWidget *parent) : + QFrame(parent) +{ + init(); + headerLabel->setText(headerText); +} + +ActionBox::ActionBox(const QPixmap & icon, const QString & headerText, QWidget *parent) : + QFrame(parent) +{ + init(); + headerLabel->setText(headerText); + setIcon(icon); +} + +void ActionBox::init() +{ + setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Maximum); + + setStyleSheet(QString(ActionBoxStyle)); + + QHBoxLayout *mainLayout = new QHBoxLayout(this); + + QVBoxLayout *iconLayout = new QVBoxLayout(); + mainLayout->addLayout(iconLayout); + + iconLabel = new QLabel(this); + iconLayout->addWidget(iconLabel); + iconLayout->addStretch(); + + dataLayout = new QVBoxLayout(); + mainLayout->addLayout(dataLayout); + + headerLabel = createItem(""); + headerLabel->setProperty("class", "header"); +} + +void ActionBox::setIcon(const QPixmap & icon) +{ + iconLabel->setPixmap(icon); + iconLabel->setFixedSize(icon.size()); +} + +ActionLabel* ActionBox::createItem(QAction * action, QLayout * l) +{ + if (!action) + return 0; + + ActionLabel *act = createItem("", l); + act->setDefaultAction(action); + return act; +} + +QList ActionBox::createItems(QList actions) +{ + QList list; + + if (actions.isEmpty()) + return list; + + QLayout *l = createHBoxLayout(); + + foreach (QAction *action, actions) { + ActionLabel *act = createItem(action, l); + if (act) + list.append(act); + } + + return list; +} + +ActionLabel* ActionBox::createItem(const QString & text, QLayout * l) +{ + ActionLabel *act = new ActionLabel(this); + act->setText(text); + act->setProperty("class", "action"); + act->setStyleSheet(""); + + if (l) + l->addWidget(act); + else { + QHBoxLayout *hbl = new QHBoxLayout(); + hbl->addWidget(act); + createSpacer(hbl); + dataLayout->addLayout(hbl); + } + + return act; +} + +ActionLabel* ActionBox::createItem(const QPixmap & icon, const QString & text, QLayout * l) +{ + ActionLabel *act = createItem(text, l); + act->setIcon(QIcon(icon)); + return act; +} + +QSpacerItem* ActionBox::createSpacer(QLayout * l) +{ + QSpacerItem * spacer; + + if (l) // add horizontal spacer + l->addItem(spacer = new QSpacerItem(1,0,QSizePolicy::MinimumExpanding,QSizePolicy::Ignored)); + else // add vertical spacer + dataLayout->addItem(spacer = new QSpacerItem(0,1,QSizePolicy::Ignored,QSizePolicy::MinimumExpanding)); + + return spacer; +} + +QLayout* ActionBox::createHBoxLayout() +{ + QHBoxLayout *hbl = new QHBoxLayout(); + dataLayout->addLayout(hbl); + QHBoxLayout *hbl1 = new QHBoxLayout(); + hbl->addLayout(hbl1); + createSpacer(hbl); + return hbl1; +} + +void ActionBox::addLayout(QLayout * l) +{ + if (l) { + dataLayout->addLayout(l); + l->setParent(this); + } +} + +void ActionBox::addWidget(QWidget * w, QLayout * l) +{ + if (!w) return; + + w->setParent(this); + + if (l) + l->addWidget(w); + else { + QHBoxLayout *hbl = new QHBoxLayout(); + hbl->addWidget(w); + createSpacer(hbl); + dataLayout->addLayout(hbl); + } +} + +QSize ActionBox::minimumSizeHint() const +{ + return QSize(150,100); +} + + +} // namespace diff --git a/src/Gui/QSint/actionpanel/actionbox.h b/src/Gui/QSint/actionpanel/actionbox.h new file mode 100644 index 000000000..819593414 --- /dev/null +++ b/src/Gui/QSint/actionpanel/actionbox.h @@ -0,0 +1,251 @@ +#ifndef ACTIONBOX_H +#define ACTIONBOX_H + +#include "actionlabel.h" + +#include +#include + + +namespace QSint +{ + + +/** + \brief Class representing a panel of actions similar to Windows Vista/7 control panel items. + \since 0.2 + + \image html ActionBox.png An example of ActionBox + + ActionBox normally consists of an icon, clickable header and a list of actions. + Every action can have own icon as well, provide tooltips and status tips, + be clickable and checkable etc. i.e. behave like a normal ActionLabel. + + ActionBox objects are easily customizable via CSS technology - you can get + different look just by writing corresponding style sheet. + + Usage of ActionBox in the application + + 1. Create ActionBox using constructor (or in Designer as Promoted Objects). + Icon and header text can be passed to the constructor as well. For example: + + \code + ActionBox *box1 = new ActionBox(":/icons/box1icon.png", "Header Text", this); + \endcode + + 2. ActionBox header itself is a clickable item (based on ActionLabel), so you + can retrieve it and use, for example, to connect with a slot: + + \code + connect(box1->header(), SIGNAL(clicked()), this, SLOT(header1clicked())); + \endcode + + 3. To create an action, use one of createItem() functions. For example: + + \code + ActionLabel *action1 = box1->createItem(":/icons/action1icon.png", "Action1 Text"); + connect(action1, SIGNAL(clicked()), this, SLOT(action1clicked())); + + ActionLabel *action2 = box1->createItem(":/icons/action2icon.png", "Action2 Text"); + connect(action2, SIGNAL(clicked()), this, SLOT(action2clicked())); + \endcode + + createItem() also allows to create an ActionLabel from already existing QAction: + + \code + QAction myAction3(":/icons/action3icon.png", "Action3 Text"); + connect(myAction3, SIGNAL(clicked()), this, SLOT(action3clicked())); + + ActionLabel *action3 = box1->createItem(myAction3); + \endcode + + 4. By default, actions are arranged vertically, one per row. In order + to have more than one actions in a row, first add horizontal layout item + using createHBoxLayout() function, and then pass it to the createItem() to + create actions. + + \code + // create horizontal layout + QLayout *hbl1 = box1->createHBoxLayout(); + // create actions using this layout + ActionLabel *action3 = box1->createItem(":/icons/action3icon.png", "1st action in row", hbl1); + ActionLabel *action4 = box1->createItem("2nd action in row", hbl1); + \endcode + + 5. Sometimes you would like to have a spacer between the items. Use createSpacer() + function to insert an empty space into default or specified layout. + + \code + // create a spacer after two actions added before + box1->createSpacer(hbl1); + // create another action which will be preceded by the empty space (i.e. right-aligned) + ActionLabel *action5 = box1->createItem("3nd action in row", hbl1); + \endcode + + 6. You can insert arbitrary layout items and widgets into ActionBox using + addLayout() and addWidgets() functions. Please note that ownership of these items + transferred to ActionBox, so you must not delete them manually. + + Customization of ActionBox via CSS + + ActionBox items can be easily customized using CSS mechanism. Just create a new + style and apply it to the ActionBox with setStyleSheet(). + + See the following example of the complete ActionBox customization. Note that + \a QSint--ActionBox is used as a main class name. Headers are ActionLabels with + property \a class='header'. Actions are ActionLabels with + property \a class='action'. + + \code + // define a string representing CSS style + const char* ActionBoxNewStyle = + + // customization of ActionBox + "QSint--ActionBox {" + "background-color: white;" + "border: 1px solid white;" + "border-radius: 3px;" + "text-align: left;" + "}" + + "QSint--ActionBox:hover {" + "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #F9FDFF, stop: 1 #EAF7FF);" + "border: 1px solid #DAF2FC;" + "}" + + // customization of ActionBox's header + "QSint--ActionBox QSint--ActionLabel[class='header'] {" + "text-align: left;" + "font: 14px;" + "color: #006600;" + "background-color: transparent;" + "border: none;" + "}" + + "QSint--ActionBox QSint--ActionLabel[class='header']:hover {" + "color: #00cc00;" + "text-decoration: underline;" + "}" + + // customization of ActionBox's actions + "QSint--ActionBox QSint--ActionLabel[class='action'] {" + "background-color: transparent;" + "border: none;" + "color: #0033ff;" + "text-align: left;" + "font: 11px;" + "}" + + "QSint--ActionBox QSint--ActionLabel[class='action']:hover {" + "color: #0099ff;" + "text-decoration: underline;" + "}" + + "QSint--ActionBox QSint--ActionLabel[class='action']:on {" + "background-color: #ddeeff;" + "color: #006600;" + "}" + ; + + // apply the style + box1->setStyleSheet(ActionBoxNewStyle); + \endcode + +*/ +class ActionBox : public QFrame +{ + Q_OBJECT + + Q_PROPERTY(QPixmap icon READ icon WRITE setIcon) + Q_PROPERTY(ActionLabel header READ header) + +public: + /** Constructor. + */ + explicit ActionBox(QWidget *parent = 0); + /** Constructor. + */ + explicit ActionBox(const QString & headerText, QWidget *parent = 0); + /** Constructor. + */ + explicit ActionBox(const QPixmap & icon, const QString & headerText, QWidget *parent = 0); + + /** Sets icon of the ActionBox to \a icon. + */ + void setIcon(const QPixmap & icon); + /** Returns icon of the ActionBox. + */ + inline const QPixmap* icon() const { return iconLabel->pixmap(); } + + /** Returns header item of the ActionBox. + */ + inline ActionLabel* header() const { return headerLabel; } + + /** Creates action item from the \a action and returns it. + + By default, action is added to the default vertical layout, i.e. subsequent + calls of this function will create several actions arranged vertically, + one below another. + + You can add action to the specified layout passing it as \a l parameter. + This allows to do custom actions arrangements, i.e. horizontal etc. + + \since 0.2 + */ + ActionLabel* createItem(QAction * action, QLayout * l = 0); + + /** Creates action items from the \a actions list and returns the list of action items. + \since 0.2 + */ + QList createItems(QList actions); + + /** Adds an action with \a text to the ActionBox and returns action item. + */ + ActionLabel* createItem(const QString & text = QString(), QLayout * l = 0); + /** Adds an action with \a icon and \a text to the ActionBox and returns action item. + + This function acts just like previous one. See the description above. + */ + ActionLabel* createItem(const QPixmap & icon, const QString & text, QLayout * l = 0); + + /** Adds a spacer and returns spacer item. + + By default, a spacer is added to the default vertical layout. + You can add a spacer to the specified layout passing it as \a l parameter. + */ + QSpacerItem* createSpacer(QLayout * l = 0); + + /** Creates empty horizontal layout. + + Use this function to arrange action items into a row. + */ + QLayout* createHBoxLayout(); + + /** Returns default layout used for actions (typically it's QVBoxLayout). + */ + inline QLayout* itemLayout() const { return dataLayout; } + + /** Adds layout \a l to the default layout. + */ + void addLayout(QLayout * l); + /** Adds widget \a w to the layout. + + By default, widget is added to the default vertical layout. + You can add widget to the specified layout passing it as \a l parameter. + */ + void addWidget(QWidget * w, QLayout * l = 0); + + virtual QSize minimumSizeHint() const; + +protected: + void init(); + + QVBoxLayout *dataLayout; + QLabel *iconLabel; + ActionLabel *headerLabel; +}; + + +} // namespace + +#endif // ACTIONBOX_H diff --git a/src/Gui/QSint/actionpanel/actiongroup.cpp b/src/Gui/QSint/actionpanel/actiongroup.cpp new file mode 100644 index 000000000..a2ab56ddb --- /dev/null +++ b/src/Gui/QSint/actionpanel/actiongroup.cpp @@ -0,0 +1,250 @@ +#include "actiongroup.h" +#include "taskheader_p.h" +#include "taskgroup_p.h" +#include "actionlabel.h" +#include "actionpanelscheme.h" + +#include + + +namespace QSint +{ + + +ActionGroup::ActionGroup(QWidget *parent) + : QWidget(parent) +{ + myHeader = new TaskHeader(QPixmap(), "", false, this); + myHeader->setVisible(false); + init(false); +} + +ActionGroup::ActionGroup(const QString &title, bool expandable, QWidget *parent) + : QWidget(parent) +{ + myHeader = new TaskHeader(QPixmap(), title, expandable, this); + init(true); +} + +ActionGroup::ActionGroup(const QPixmap &icon, const QString &title, bool expandable, QWidget *parent) + : QWidget(parent) +{ + myHeader = new TaskHeader(icon, title, expandable, this); + init(true); +} + +void ActionGroup::init(bool header) +{ + m_foldStep = 0; + + myScheme = ActionPanelScheme::defaultScheme(); + + QVBoxLayout *vbl = new QVBoxLayout(); + vbl->setMargin(0); + vbl->setSpacing(0); + setLayout(vbl); + + vbl->addWidget(myHeader); + + myGroup = new TaskGroup(this, header); + vbl->addWidget(myGroup); + + myDummy = new QWidget(this); + vbl->addWidget(myDummy); + myDummy->hide(); + + connect(myHeader, SIGNAL(activated()), this, SLOT(showHide())); +} + +void ActionGroup::setScheme(ActionPanelScheme *pointer) +{ + myScheme = pointer; + myHeader->setScheme(pointer); + myGroup->setScheme(pointer); + update(); +} + +QBoxLayout* ActionGroup::groupLayout() +{ + return myGroup->groupLayout(); +} + +ActionLabel* ActionGroup::addAction(QAction *action, bool addToLayout, bool addStretch) +{ + if (!action) + return 0; + + ActionLabel* label = new ActionLabel(action, this); + myGroup->addActionLabel(label, addToLayout, addStretch); + + return label; +} + +ActionLabel* ActionGroup::addActionLabel(ActionLabel *label, bool addToLayout, bool addStretch) +{ + if (!label) + return 0; + + myGroup->addActionLabel(label, addToLayout, addStretch); + + return label; +} + +bool ActionGroup::addWidget(QWidget *widget, bool addToLayout, bool addStretch) +{ + return myGroup->addWidget(widget, addToLayout, addStretch); +} + +void ActionGroup::showHide() +{ + if (m_foldStep) + return; + + if (!myHeader->expandable()) + return; + + if (myGroup->isVisible()) + { + m_foldPixmap = myGroup->transparentRender(); +// m_foldPixmap = QPixmap::grabWidget(myGroup, myGroup->rect()); + + m_tempHeight = m_fullHeight = myGroup->height(); + m_foldDelta = m_fullHeight / myScheme->groupFoldSteps; + m_foldStep = myScheme->groupFoldSteps; + m_foldDirection = -1; + + myGroup->hide(); + myDummy->setFixedSize(myGroup->size()); + myDummy->show(); + + QTimer::singleShot(myScheme->groupFoldDelay, this, SLOT(processHide())); + } + else + { + m_foldStep = myScheme->groupFoldSteps; + m_foldDirection = 1; + m_tempHeight = 0; + + QTimer::singleShot(myScheme->groupFoldDelay, this, SLOT(processShow())); + } + + myDummy->show(); +} + +void ActionGroup::processHide() +{ + if (!--m_foldStep) { + myDummy->setFixedHeight(0); + myDummy->hide(); + setFixedHeight(myHeader->height()); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + return; + } + + setUpdatesEnabled(false); + + m_tempHeight -= m_foldDelta; + myDummy->setFixedHeight(m_tempHeight); + setFixedHeight(myDummy->height()+myHeader->height()); + + QTimer::singleShot(myScheme->groupFoldDelay, this, SLOT(processHide())); + + setUpdatesEnabled(true); +} + +void ActionGroup::processShow() +{ + if (!--m_foldStep) { + myDummy->hide(); + m_foldPixmap = QPixmap(); + myGroup->show(); + setFixedHeight(m_fullHeight+myHeader->height()); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + setMaximumHeight(9999); + setMinimumHeight(0); + return; + } + + setUpdatesEnabled(false); + + m_tempHeight += m_foldDelta; + myDummy->setFixedHeight(m_tempHeight); + setFixedHeight(myDummy->height()+myHeader->height()); + + QTimer::singleShot(myScheme->groupFoldDelay, this, SLOT(processShow())); + + setUpdatesEnabled(true); +} + +void ActionGroup::paintEvent ( QPaintEvent * event ) +{ + QPainter p(this); + + if (myDummy->isVisible()) { + if (myScheme->groupFoldThaw) { + if (m_foldDirection < 0) + p.setOpacity((double)m_foldStep / myScheme->groupFoldSteps); + else + p.setOpacity((double)(myScheme->groupFoldSteps-m_foldStep) / myScheme->groupFoldSteps); + } + + switch (myScheme->groupFoldEffect) + { + case ActionPanelScheme::ShrunkFolding: + p.drawPixmap(myDummy->pos(), m_foldPixmap.scaled(myDummy->size()) ); + break; + + case ActionPanelScheme::SlideFolding: + p.drawPixmap(myDummy->pos(), m_foldPixmap, + QRect(0, m_foldPixmap.height()-myDummy->height(), + m_foldPixmap.width(), myDummy->width() + ) ); + break; + + default: + p.drawPixmap(myDummy->pos(), m_foldPixmap); + } + + return; + } +} + + +bool ActionGroup::isExpandable() const +{ + return myHeader->expandable(); +} + +void ActionGroup::setExpandable(bool expandable) +{ + myHeader->setExpandable(expandable); +} + +bool ActionGroup::hasHeader() const +{ + return myHeader->isVisible(); +} + +void ActionGroup::setHeader(bool enable) +{ + myHeader->setVisible(enable); +} + +QString ActionGroup::headerText() const +{ + return myHeader->myTitle->text(); +} + +void ActionGroup::setHeaderText(const QString & headerText) +{ + myHeader->myTitle->setText(headerText); +} + + +QSize ActionGroup::minimumSizeHint() const +{ + return QSize(200,100); +} + + +} diff --git a/src/Gui/QSint/actionpanel/actiongroup.h b/src/Gui/QSint/actionpanel/actiongroup.h new file mode 100644 index 000000000..71178a554 --- /dev/null +++ b/src/Gui/QSint/actionpanel/actiongroup.h @@ -0,0 +1,167 @@ +#ifndef ACTIONGROUP_H +#define ACTIONGROUP_H + +#include +#include +#include + + +namespace QSint +{ + + +class ActionLabel; +class ActionPanelScheme; + + +/** + \brief Class representing a single group of actions similar to Windows XP task panels. + \since 0.2 + + \image html ActionGroup.png An example of ActionGroup + + ActionGroup consists from optional header and set of actions represented by ActionLabel. + It can contain arbitrary widgets as well. +*/ + +class ActionGroup : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(bool expandable READ isExpandable WRITE setExpandable) + Q_PROPERTY(bool header READ hasHeader WRITE setHeader) + Q_PROPERTY(QString headerText READ headerText WRITE setHeaderText) + +public: + /** Constructor. Creates ActionGroup without header. + */ + explicit ActionGroup(QWidget *parent = 0); + + /** Constructor. Creates ActionGroup with header's + text set to \a title, but with no icon. + + If \a expandable set to \a true (default), the group can be expanded/collapsed by the user. + */ + explicit ActionGroup(const QString& title, + bool expandable = true, + QWidget *parent = 0); + + /** Constructor. Creates ActionGroup with header's + text set to \a title and icon set to \a icon. + + If \a expandable set to \a true (default), the group can be expanded/collapsed by the user. + */ + explicit ActionGroup(const QPixmap& icon, + const QString& title, + bool expandable = true, + QWidget *parent = 0); + + /** Creates action item from the \a action and returns it. + + If \a addToLayout is set to \a true (default), + the action is added to the default vertical layout, i.e. subsequent + calls of this function will create several ActionLabels arranged vertically, + one below another. + + Set \a addToLayout to \a false if you want to add the action to the specified layout manually. + This allows to do custom actions arrangements, i.e. horizontal etc. + + If \a addStretch is set to \a true (default), + ActionLabel will be automatically aligned to the left side of the ActionGroup. + Set \a addStretch to \a false if you want ActionLabel to occupy all the horizontal space. + */ + ActionLabel* addAction(QAction *action, bool addToLayout = true, bool addStretch = true); + + /** Adds \a label to the group. + + \sa addAction() for the description. + */ + ActionLabel* addActionLabel(ActionLabel *label, bool addToLayout = true, bool addStretch = true); + + /** Adds \a widget to the group. Returns \a true if it has been added successfully. + + \sa addAction() for the description. + */ + bool addWidget(QWidget *widget, bool addToLayout = true, bool addStretch = true); + + /** Returns group's layout (QVBoxLayout by default). + */ + QBoxLayout* groupLayout(); + + /** Sets the scheme of the panel and all the child groups to \a scheme. + + By default, ActionPanelScheme::defaultScheme() is used. + */ + void setScheme(ActionPanelScheme *pointer); + + /** Returns \a true if the group is expandable. + + \sa setExpandable(). + */ + bool isExpandable() const; + + /** Returns \a true if the group has header. + + \sa setHeader(). + */ + bool hasHeader() const; + + /** Returns text of the header. + Only valid if the group has header (see hasHeader()). + + \sa setHeaderText(). + */ + QString headerText() const; + + QSize minimumSizeHint() const; + +public Q_SLOTS: + /** Expands/collapses the group. + Only valid if the group has header (see hasHeader()). + */ + void showHide(); + + /** Makes the group expandable if \a expandable is set to \a true. + + \sa isExpandable(). + */ + void setExpandable(bool expandable = true); + + /** Enables/disables group's header according to \a enable. + + \sa hasHeader(). + */ + void setHeader(bool enable = true); + + /** Sets text of the header to \a title. + Only valid if the group has header (see hasHeader()). + + \sa headerText(). + */ + void setHeaderText(const QString & title); + +protected Q_SLOTS: + void processHide(); + void processShow(); + +protected: + void init(bool header); + + virtual void paintEvent ( QPaintEvent * event ); + + double m_foldStep, m_foldDelta, m_fullHeight, m_tempHeight; + int m_foldDirection; + + QPixmap m_foldPixmap; + + class TaskHeader *myHeader; + class TaskGroup *myGroup; + QWidget *myDummy; + + ActionPanelScheme *myScheme; +}; + + +} // namespace + +#endif // ACTIONGROUP_H diff --git a/src/Gui/QSint/actionpanel/actionlabel.cpp b/src/Gui/QSint/actionpanel/actionlabel.cpp new file mode 100644 index 000000000..263bdff8b --- /dev/null +++ b/src/Gui/QSint/actionpanel/actionlabel.cpp @@ -0,0 +1,116 @@ +#include "actionlabel.h" + +#include +#include + + +namespace QSint +{ + + +const char* ActionLabelStyle = + "QSint--ActionLabel[class='action'] {" + "background-color: transparent;" + "border: 1px solid transparent;" + "color: #0033ff;" + "text-align: left;" + "font: 11px;" + "}" + + "QSint--ActionLabel[class='action']:!enabled {" + "color: #999999;" + "}" + + "QSint--ActionLabel[class='action']:hover {" + "color: #0099ff;" + "text-decoration: underline;" + "}" + + "QSint--ActionLabel[class='action']:focus {" + "border: 1px dotted black;" + "}" + + "QSint--ActionLabel[class='action']:on {" + "background-color: #ddeeff;" + "color: #006600;" + "}" +; + + +ActionLabel::ActionLabel(QWidget *parent) : + QToolButton(parent) +{ + init(); +} + +ActionLabel::ActionLabel(QAction *action, QWidget *parent) : + QToolButton(parent) +{ + init(); + + setDefaultAction(action); +} + +void ActionLabel::init() +{ + setProperty("class", "action"); + + setCursor(Qt::PointingHandCursor); + + setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + + setStyleSheet(QString(ActionLabelStyle)); + + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + setFocusPolicy(Qt::StrongFocus); +} + +QSize ActionLabel::sizeHint() const +{ + ensurePolished(); + + int w = 0, h = 0; + + QStyleOptionToolButton opt; + initStyleOption(&opt); + + QString s(text()); + bool empty = s.isEmpty(); + if (empty) + s = QString::fromLatin1("XXXX"); + QFontMetrics fm = fontMetrics(); + QSize sz = fm.size(Qt::TextShowMnemonic, s); + if(!empty || !w) + w += sz.width(); + if(!empty || !h) + h = qMax(h, sz.height()); + opt.rect.setSize(QSize(w, h)); // PM_MenuButtonIndicator depends on the height + + if (!icon().isNull()) { + int ih = opt.iconSize.height(); + int iw = opt.iconSize.width() + 4; + w += iw; + h = qMax(h, ih); + } + + if (menu()) + w += style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, this); + + h += 4; + w += 8; + + QSize sizeHint = (style()->sizeFromContents(QStyle::CT_PushButton, &opt, QSize(w, h), this). + expandedTo(QApplication::globalStrut())); + + return sizeHint; +} + +QSize ActionLabel::minimumSizeHint() const +{ + return sizeHint(); +} + + +} // namespace + diff --git a/src/Gui/QSint/actionpanel/actionlabel.h b/src/Gui/QSint/actionpanel/actionlabel.h new file mode 100644 index 000000000..6ad8421b3 --- /dev/null +++ b/src/Gui/QSint/actionpanel/actionlabel.h @@ -0,0 +1,86 @@ +#ifndef ACTIONLABEL_H +#define ACTIONLABEL_H + +#include + + +namespace QSint +{ + + +/** + \brief Class representing an action similar to Windows Vista/7 control panel item. + + \image html ActionLabel.png An example of ActionLabel + + ActionLabel normally consists of an icon and text. + It also can have tooltip and status tip, + be clickable and checkable etc. i.e. behave like a normal QToolButton. + + Customization of ActionLabel via CSS + + ActionLabel objects are easily customizable via CSS technology - you can get + different look just by writing corresponding style sheet and applying it with setStyleSheet(). + + See the following example of the complete ActionLabel customization. Note that + \a QSint--ActionLabel is used as a main class name. + + \code + // define a string representing CSS style + const char* ActionLabelNewStyle = + + "QSint--ActionLabel[class='action'] {" + "background-color: transparent;" + "border: 1px solid transparent;" + "color: #0033ff;" + "text-align: left;" + "font: 11px;" + "}" + + "QSint--ActionLabel[class='action']:hover {" + "color: #0099ff;" + "text-decoration: underline;" + "}" + + "QSint--ActionLabel[class='action']:focus {" + "border: 1px dotted black;" + "}" + + "QSint--ActionLabel[class='action']:on {" + "background-color: #ddeeff;" + "color: #006600;" + "}" + ; + + // apply the style + label1->setStyleSheet(ActionLabelNewStyle); + + \endcode +*/ +class ActionLabel : public QToolButton +{ + Q_OBJECT + +public: + /** Constructor. + */ + explicit ActionLabel(QWidget *parent = 0); + + /** Constructor. Creates ActionLabel from the \a action. + \since 0.2 + */ + explicit ActionLabel(QAction *action, QWidget *parent = 0); + + virtual ~ActionLabel() {} + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + +protected: + void init(); +}; + + +} // namespace + +#endif // ACTIONLABEL_H diff --git a/src/Gui/QSint/actionpanel/actionpanel.cpp b/src/Gui/QSint/actionpanel/actionpanel.cpp new file mode 100644 index 000000000..3e68b5652 --- /dev/null +++ b/src/Gui/QSint/actionpanel/actionpanel.cpp @@ -0,0 +1,93 @@ +#include "actionpanel.h" +#include "actionpanelscheme.h" +#include "actiongroup.h" + +#include + + +namespace QSint +{ + + +ActionPanel::ActionPanel(QWidget *parent) : + BaseClass(parent) +{ + setProperty("class", "panel"); + + setScheme(ActionPanelScheme::defaultScheme()); + + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + + QVBoxLayout *vbl = new QVBoxLayout(); + vbl->setMargin(8); + vbl->setSpacing(8); + setLayout(vbl); +} + +void ActionPanel::setScheme(ActionPanelScheme *scheme) +{ + if (scheme) { + myScheme = scheme; + setStyleSheet(myScheme->actionStyle); + + // set scheme for children + QObjectList list(children()); + foreach(QObject *obj, list) { + if (dynamic_cast(obj)) { + ((ActionGroup*)obj)->setScheme(scheme); + continue; + } + } + + update(); + } +} + +//void ActionPanel::paintEvent ( QPaintEvent * event ) +//{ +// //QPainter p(this); + +// //p.setOpacity(0.5); +// //p.fillRect(rect(), myScheme->panelBackground); +//} + +void ActionPanel::addWidget(QWidget *w) +{ + if (w) + layout()->addWidget(w); +} + +void ActionPanel::addStretch(int s) +{ + ((QVBoxLayout*)layout())->addStretch(s); +} + +ActionGroup * ActionPanel::createGroup() +{ + ActionGroup * group = new ActionGroup(this); + addWidget(group); + return group; +} + +ActionGroup * ActionPanel::createGroup(const QString &title, bool expandable) +{ + ActionGroup * box = new ActionGroup(title, expandable, this); + addWidget(box); + return box; +} + +ActionGroup * ActionPanel::createGroup(const QPixmap &icon, const QString &title, bool expandable) +{ + ActionGroup * box = new ActionGroup(icon, title, expandable, this); + addWidget(box); + return box; +} + + +QSize ActionPanel::minimumSizeHint() const +{ + return QSize(200,150); +} + + +} // namespace diff --git a/src/Gui/QSint/actionpanel/actionpanel.h b/src/Gui/QSint/actionpanel/actionpanel.h new file mode 100644 index 000000000..ae8dc6b98 --- /dev/null +++ b/src/Gui/QSint/actionpanel/actionpanel.h @@ -0,0 +1,86 @@ +#ifndef ACTIONPANEL_H +#define ACTIONPANEL_H + +#include + + +namespace QSint +{ + + +class ActionPanelScheme; +class ActionGroup; + + +/** + \brief Class representing panels of actions similar to Windows XP task panels. + \since 0.2 + + \image html ActionPanel1.png An example of ActionPanel + + ActionPanel acts like a container for ActionGroup which in turn are containers for + the actions represented by ActionLabel. + + The look and fill is complete styleable via setScheme(). + Currently the following schemes available: ActionPanelScheme (the default), + WinXPPanelScheme and WinXPPanelScheme2 (blue Windows XP schemes), + WinVistaPanelScheme (Windows Vista variation), MacPanelScheme (MacOS variation), + AndroidPanelScheme (Android variation). +*/ +class ActionPanel : public QFrame +{ + typedef QFrame BaseClass; + + Q_OBJECT + +public: + /** Constructor. + */ + explicit ActionPanel(QWidget *parent = 0); + + /** Adds a widget \a w to the ActionPanel's vertical layout. + */ + void addWidget(QWidget *w); + + /** Adds a spacer with width \a s to the ActionPanel's vertical layout. + Normally you should do this after all the ActionGroups were added, in order to + maintain some space below. + */ + void addStretch(int s = 0); + + /** Creates and adds to the ActionPanel's vertical layout an empty ActionGroup without header. + */ + ActionGroup* createGroup(); + + /** Creates and adds to the ActionPanel's vertical layout an empty ActionGroup with header's + text set to \a title, but with no icon. + + If \a expandable set to \a true (default), the group can be expanded/collapsed by the user. + */ + ActionGroup* createGroup(const QString &title, bool expandable = true); + + /** Creates and adds to the ActionPanel's vertical layout an empty ActionGroup with header's + text set to \a title and icon set to \a icon. + + If \a expandable set to \a true (default), the group can be expanded/collapsed by the user. + */ + ActionGroup* createGroup(const QPixmap &icon, const QString &title, bool expandable = true); + + /** Sets the scheme of the panel and all the child groups to \a scheme. + + By default, ActionPanelScheme::defaultScheme() is used. + */ + void setScheme(ActionPanelScheme *scheme); + + virtual QSize minimumSizeHint() const; + +protected: + //virtual void paintEvent ( QPaintEvent * event ); + + ActionPanelScheme *myScheme; +}; + + +} // namespace + +#endif // ACTIONPANEL_H diff --git a/src/Gui/QSint/actionpanel/actionpanelscheme.cpp b/src/Gui/QSint/actionpanel/actionpanelscheme.cpp new file mode 100644 index 000000000..f6681e9ad --- /dev/null +++ b/src/Gui/QSint/actionpanel/actionpanelscheme.cpp @@ -0,0 +1,113 @@ +#include "actionpanelscheme.h" + + +class StaticLibInitializer +{ +public: + StaticLibInitializer() + { + Q_INIT_RESOURCE(schemes); + } +}; + +StaticLibInitializer staticLibInitializer; + + +namespace QSint +{ + + +const char* ActionPanelDefaultStyle = + + "QFrame[class='panel'] {" + "background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #99cccc, stop: 1 #EAF7FF);" + "}" + + "QSint--ActionGroup QFrame[class='header'] {" + "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #F9FDFF, stop: 1 #EAF7FF);" + "border: 1px solid #00aa99;" + "border-bottom: 1px solid #99cccc;" + "border-top-left-radius: 3px;" + "border-top-right-radius: 3px;" + "}" + + "QSint--ActionGroup QFrame[class='header']:hover {" + "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EAF7FF, stop: 1 #F9FDFF);" + "}" + + "QSint--ActionGroup QToolButton[class='header'] {" + "text-align: left;" + "font: 14px;" + "color: #006600;" + "background-color: transparent;" + "border: 1px solid transparent;" + "}" + + "QSint--ActionGroup QToolButton[class='header']:hover {" + "color: #00cc00;" + "text-decoration: underline;" + "}" + + "QSint--ActionGroup QFrame[class='content'] {" + "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #F9FDFF, stop: 1 #EAF7FF);" + "border: 1px solid #00aa99;" + "}" + + "QSint--ActionGroup QFrame[class='content'][header='true'] {" + "border-top: none;" + "}" + + "QSint--ActionGroup QToolButton[class='action'] {" + "background-color: transparent;" + "border: 1px solid transparent;" + "color: #0033ff;" + "text-align: left;" + "font: 11px;" + "}" + + "QSint--ActionGroup QToolButton[class='action']:!enabled {" + "color: #999999;" + "}" + + "QSint--ActionGroup QToolButton[class='action']:hover {" + "color: #0099ff;" + "text-decoration: underline;" + "}" + + "QSint--ActionGroup QToolButton[class='action']:focus {" + "border: 1px dotted black;" + "}" + + "QSint--ActionGroup QToolButton[class='action']:on {" + "background-color: #ddeeff;" + "color: #006600;" + "}" +; + + +ActionPanelScheme::ActionPanelScheme() +{ + headerSize = 28; + headerAnimation = true; + + headerButtonFold = QPixmap(":/default/Fold.png"); + headerButtonFoldOver = QPixmap(":/default/FoldOver.png"); + headerButtonUnfold = QPixmap(":/default/Unfold.png"); + headerButtonUnfoldOver = QPixmap(":/default/UnfoldOver.png"); + headerButtonSize = QSize(18,18); + + groupFoldSteps = 20; groupFoldDelay = 15; + groupFoldEffect = NoFolding; + groupFoldThaw = true; + + actionStyle = QString(ActionPanelDefaultStyle); +} + +ActionPanelScheme* ActionPanelScheme::defaultScheme() +{ + static ActionPanelScheme scheme; + return &scheme; +} + + +} diff --git a/src/Gui/QSint/actionpanel/actionpanelscheme.h b/src/Gui/QSint/actionpanel/actionpanelscheme.h new file mode 100644 index 000000000..c7a34bcfc --- /dev/null +++ b/src/Gui/QSint/actionpanel/actionpanelscheme.h @@ -0,0 +1,76 @@ +#ifndef TASKPANELSCHEME_H +#define TASKPANELSCHEME_H + +#include +#include + +#include + + +namespace QSint +{ + + +/** + \brief Class representing color scheme for ActionPanel and ActionGroup. + \since 0.2 + + \image html ActionPanel1.png Default ActionPanel scheme +*/ +class ActionPanelScheme +{ +public: + /** \enum TaskPanelFoldEffect + \brief Animation effect during expanding/collapsing of the ActionGroup's contents. + */ + enum TaskPanelFoldEffect + { + /// No folding effect + NoFolding, + /// Folding by scaling group's contents + ShrunkFolding, + /// Folding by sliding group's contents + SlideFolding + }; + + + ActionPanelScheme(); + + /** Returns a pointer to the default scheme object. + Must be reimplemented in the own schemes. + */ + static ActionPanelScheme* defaultScheme(); + + /// Height of the header in pixels. + int headerSize; + /// If set to \a true, moving mouse over the header results in changing its opacity slowly. + bool headerAnimation; + + /// Image of folding button when the group is expanded. + QPixmap headerButtonFold; + /// Image of folding button when the group is expanded and mouse cursor is over the button. + QPixmap headerButtonFoldOver; + /// Image of folding button when the group is collapsed. + QPixmap headerButtonUnfold; + /// Image of folding button when the group is collapsed and mouse cursor is over the button. + QPixmap headerButtonUnfoldOver; + + QSize headerButtonSize; + + /// Number of steps made for expanding/collapsing animation (default 20). + int groupFoldSteps; + /// Delay in ms between steps made for expanding/collapsing animation (default 15). + int groupFoldDelay; + /// Sets folding effect during expanding/collapsing. + TaskPanelFoldEffect groupFoldEffect; + /// If set to \a true, changes group's opacity slowly during expanding/collapsing. + bool groupFoldThaw; + + /// The CSS for the ActionPanel/ActionGroup elements. + QString actionStyle; +}; + + +} + +#endif // TASKPANELSCHEME_H diff --git a/src/Gui/QSint/actionpanel/android/Fold.png b/src/Gui/QSint/actionpanel/android/Fold.png new file mode 100644 index 0000000000000000000000000000000000000000..a1139c48a760b5d718886ccb91ed8012700e02ae GIT binary patch literal 1705 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 TvgE$700000NkvXXu0mjfedIEB literal 0 HcmV?d00001 diff --git a/src/Gui/QSint/actionpanel/android/Unfold.png b/src/Gui/QSint/actionpanel/android/Unfold.png new file mode 100644 index 0000000000000000000000000000000000000000..9e6342bf56542986b9143e39959e9f207d6a12ac GIT binary patch literal 1701 zcmV;W23q-vP)@Q~)r%WeVmW4LcmFNP_Iiri~m_)$A)L{d3gV5=;^uVyXQOKJ@-Hf1OnC)mc?QrpYHDN_++!$6h$p%FSP)M&1RdLnlhP8 z2pt_A?dIkd^HvP(nhp)@8jS`P4-XG6m%A|7ycn-uy)v84Ny$m+JJL68+QjGcZ7kdL z^z=*yEXrgyH8wWZ+^)HE=MF4zcmoWC20&U`+L59o!NI|klat5;IXUm7D3FFE^m@Il zOr}&SJv}{nJl^6Mh>rASGTG|b)nLhLwJu6G7(?jJ&d$QZ!m-h@xe3j}FdB^^At4to zTv)bjnVlB0I2;Z(6W%8#CXgS~0d&DwR8-W_(c$Ig6Sd9taM$X`4_W+_H7ch7B7=M@PrU#|aF+W@Tl8XK+3X11FNp_DKa7w5eST0t2L+eUWpmjJ6x?dDP8uh7f4CbOnJ`X}+8qDUOYC^C@J|hF)0z`({F&fRZZ?aR#{n@Fjxq6qDk0=wD3Z=M$19Q?dtZUM~~X? zHtTf{6iG$2uF&|(73Hb#rIJ0hb+up_WpMf6xLoK)I-L$3EIT`!7@Hq9qsQR%6gn#y zKl#N;@*C=m^kd^<=k~z`R(o4}dU|?HOboGn``x!?vNHPBS-Em0u0qS-EnJR+_uAUp zr%#`X#G)kv^!N3nuE1a#H*VgDPDnrg=!s|^=gywnyJs)cqxx30R;LAHivsAhx{iN4 z3O_9*BF3uvqpF~=03@;OeHXVMeNgp4#e5_29^AiwzqhwnEEd}bs<{j8xu>Ux@5PT_ z7atK3LF^D)N@_}fe?P>=B5xG5k-I;)M^RCRJ1Bu1wr5J4?!}$RYFFkiAVH2xj1G;S{_1qaKp2Da7d24a&Le^7Oe%d8K3mzM&@>ken7!H02ci(Z@Z literal 0 HcmV?d00001 diff --git a/src/Gui/QSint/actionpanel/android/UnfoldOver.png b/src/Gui/QSint/actionpanel/android/UnfoldOver.png new file mode 100644 index 0000000000000000000000000000000000000000..951813813ff8ef1cf5bf2c08d93ff4dc42ce8801 GIT binary patch literal 1721 zcmV;q21fabP)M&Pz8K!_sYSZDO%_cxd?bfM#H5G@2DF zR$RDnVe#U{Mq0>Vu~?W)cpn`dMSOGz&;?^!T3TystDT*lc?@{CySo<`7sH#reFq1J zB}p`nqH5dwo(p->2(!TAgf?5H5W zVDsk91OV|OH#h#gp=?lIl3p?b(1(6fpSVBKi|YlX)gG&{0)c66Zch9t5z$X$0CUqj zn+ggFj7QAKeos%2L%l3;`i*`1C5MoMoDgte{sB~rUpuz!szes zFD)(g^75MAqh6o;b*}V^l*yU_pdHcTX=QIU17>1Uv`>_fnBeT$Y6DXnV?d>x%G7=LK$%NtI;q&Lum;72nUj<6lj%nlf$K!WVagmj^p@h&KVuUe* zT>?)pPhydk$ucuDAxjFbvTHJEkz`DvP#pREh_&tXiA9LL|MrUFMc5Etp(1IK)X~`y zo27@6E>2HMN+L<^?CcDFHyCtLh~>dQ50Is)bXhX9PiB`@meJ>Tc69C)?sau_rPE#d zb1BE2Lk~p|Awc;dCj;B{ecKmlr#Nn$+x54JU;jWqufmotiGy&TP}QcQcwW5PKWd5f@#Du=f4N$zs5A&^RD-G| ziW4zrAJQMB;MvaBAhXC1B7w1C!v^v-GAa@aQcg}z_wU`G=Blq>B9YYItVMO{>h4PZ zB-uniCIfndznhyI@){l*j?0GU%_Cm}g91Um;SOkSY9{9%BQGycUM`0^Q6!8)ntPyH zqvRlBzCZuap+m;A&3IJNt3!(R=kG1xtY$_mC$o;XRqALU%>(;HT ztSnDYPh&&%`apT^=;%n#NcY?1=i%W&>=0W>Xh>IA7sSROcNDad5TB5fonx{J`WmHD zSyff#?CeaJ09HYgQN4YAeffMo3LkwI2q^fjfb4h*13Lm^7Yi>!;3hB#sG*?&H!gZ2 zV?Zd8s6|MxpPwJFP5iI@b`2~+^rYfV_Y9CTs`ureE(Zn#nq>y<0d8N$t6mgJG3#?z zc{eIL3TMm6k|~Cf0j!eqWlqY0lm#k^K2TQ*Ng)d9Tg2El$iyt z4vn7r>Qs@m2#5T2ftc@i(QDzEk(QB~lDc&1(m7U#SR{p#+;4JGOJ-|%XYHwxSOf&> zLV`oW!@|)PIoLb!c!qlS@ZrOO!GXqmjpY^PwRN@FI3!1Ixi`Qd!=MGN7EeRxM*4Qj zaDjq%0L=R@rXDE=R%QmfL{UN3l%L0eCNX%r`njxgN@xNA78E9s literal 0 HcmV?d00001 diff --git a/src/Gui/QSint/actionpanel/default/FoldOver.png b/src/Gui/QSint/actionpanel/default/FoldOver.png new file mode 100644 index 0000000000000000000000000000000000000000..70cd655af60a80cc7f480b4fd576ad93867e9dd8 GIT binary patch literal 771 zcmV+e1N{7nP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXMy z6bc%Z8x;-!00M(aL_t(I%dL~kOO#<0#((pT-#5+7cTustpq5}!78bS8aM7l={S9qG z%gU%Ah(IHP!Y!Bj%#d!(0Y(rF2t`tAH8kIj4nghIMP~6 z``&GQ7*FtSY=OkjJif1PJm~4Tx}nNkB3s)%Fx=Za^hrjik|LruaC9muy+fa*dtkWt zPi+`L8jtr?I$N$BZEv7?dj$mnR~5OcprF7hkK$Mn7E`&ZgU3$n9(nWZEr2%pJzZ~_ z#>Li_YMd&YL?IyU`lNlu(jQE@0Tneihg$3QDLA*@f%f>-mmVcTU9CkBD1tx;6exim zW+#G1K!`vIDi9j#Y^=D!`Y4(Rm$o-l;CX_tgkX)$Rwn>W=1G(ilq#P43U)SCVMX;m z04-2LO|^xH6bZCcp8o5RciElD+QLK>jr9({@?LR-uohza+Y;%#OKQdCKy`OX_;TuY zDQ>AeMQYh4wd^u6lf;VZ#R5S8+?#Y{LP_xAOaEGtJEh!wrg-P;bSmTe!C>hl zow+|O4b5AruCa(j!j$P@bX`LWX&|6N3eQ#ep5n)RhS`}E16^&Q^$yTA?QUZ3CxvAf zGaA8;=~!_C$1*5)4D470JFb(<7MPn&ql*ld)(CL#%;AgqoOf$xGC_7}1>1~J9ychD z={PYR$27I^D{G<35$0qIDg1c h%V7{qxWb?X)PG^FsGvt*)eWFY44$rjF6*2UngA<)CYS&K literal 0 HcmV?d00001 diff --git a/src/Gui/QSint/actionpanel/default/UnfoldOver.png b/src/Gui/QSint/actionpanel/default/UnfoldOver.png new file mode 100644 index 0000000000000000000000000000000000000000..869c2b9c434b9d33d3ffc2224750f5042b3ed574 GIT binary patch literal 747 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXMy z6buu(oeC@f00L`CL_t(I%e9luOH@%9#((#YcLsIl&ZyxR7D^VF(8nSaTLco+pU@&` z6X+yKH3lIqYEheJKqVW?ZM6%67P)8>VOeerN}c>dY)XguQb%Xz&b{Zf&?X0`We+?Y z&N=USc+UIqDilHA;|YI>P4y*H1|Fv!(-Hyy)%Lz(waVVjt>CA?cGkQJaOqq#?XA^J ze2ehx?K}V;r+wu9mDAp0Li7%Oc+fL2E~n1K5;p~jJ&YL^6}37S z&K@S2GP?gbQ2R$Gg8=n)E-XvXQt72x_wFd~qRH7sv)+xcBnRvDe4_zWA!PUQ)>?8o zi790MQKPe~U3luWG+?-K!-jt6)8Aq9sT-1&3W zRjRSDoFJYyh;13fQU>pT3>73avHFO3I!7$Eb3eTp{VQNvBCrx(XLTdXuZ;}h%?v-2 z8D7pl1mM+NfN(NHIFTj1zEd+Z8v(eRkMZ`?&!LJ2&(WG%7Y>Jw63vFDsi=wy5`-ei z83HpWSPQSS6pEwovh*iesITi1|1iB znWsR;XMUJC1i)pr`EVI``S9+Y*BJDiTvfP${I7QoZ@I)^=x(be$|J%b>i)R2=-?v(ZF_fhUWQM% zu6|b2mc}0y@UWBR`gCg5_IqGI3GjdT0G1WxV!6F@>DiAEzbab$n2AG-d-zsJfSm!B zAXvD7>4V|xhc925xx{!`e}4Y>@fQO-FF!vUNcEq;e_5EpvVS2enIXnOlmP(%W&r~- zYrKIS0000MbVXQnQ*UN;cVTj606}tecV%IAWpW@fE-

zOVoQ002ovPDHLkV1f>q B<`w_| literal 0 HcmV?d00001 diff --git a/src/Gui/QSint/actionpanel/mac/UnfoldOver.png b/src/Gui/QSint/actionpanel/mac/UnfoldOver.png new file mode 100644 index 0000000000000000000000000000000000000000..3ef9d683a2ad4007c9afaeb5de0fa1954dbc7d23 GIT binary patch literal 685 zcmV;e0#f~nP)u-w;Y2RE^F>%#d~YVo?8r>_8ywN z6qtK>)5??2Rh*+el^7V_Uq1F+PKD>*?w!{d^qgE(xX3s6)Q;slu6$Cm_AwP_U|{Cp zX8!T@J=k1+-gh5AgOo@chnq`+7*EdvU4ZbGGy~Y9l2$>+vJfedN}j8G4qjnUW4wFw z==RN5-hmW@RRHO)Aamad=tPI=zuUWX`#nA#7d!3GAe}rQ_(bYr~v@U4)*k8^9boO};+hyd8VhHjpUY@hD| zb$(Q|^ilr|)X8Y->!8H?m*w{Zpi};7+j}d$1v2<8?Rl>q{3a}S=iWbC7v3v-o~igc zFoM$qGq(T__ovHC*IarhYaFii9Ui`4?;PH8=_4?dv_1nF42JHuYTQr{ffT5JJG1)4 zU0Er`$6tl)W$qum$}1!D@Cl=1s6OMVt(%@m8*B41Fg(Ao^7s=W17}z9=a}YNGF@DH z__2Vty}LT^$D4FtH}d*1O0GRir+OFiDX>om~QN|td3!i?v3E#GqK6Eqf; zY%{Hd-o3t!X|Aa(m)PqQllMM?C{%HduoL?7^)Cba+e?cMK4MU`h&B{|c7Egj`wSqL zDRDC1eeqF^gqJ1;*!8^a&4MgVQgB-OD|0KfnM02XvbSaefwW^{L9a%BKPa&&iPVRmJ5ATcg5 TvgE$700000NkvXXu0mjf=W;=f literal 0 HcmV?d00001 diff --git a/src/Gui/QSint/actionpanel/macpanelscheme.cpp b/src/Gui/QSint/actionpanel/macpanelscheme.cpp new file mode 100644 index 000000000..da0cd9694 --- /dev/null +++ b/src/Gui/QSint/actionpanel/macpanelscheme.cpp @@ -0,0 +1,66 @@ +#include "macpanelscheme.h" + + +namespace QSint +{ + + +const char* MacPanelStyle = + + "QFrame[class='panel'] {" + "background-color: #D9DEE5;" + "border: 1px solid #BBBBBB;" + "}" + + "QSint--ActionGroup QFrame[class='header'] {" + "border: none;" + "}" + + "QSint--ActionGroup QToolButton[class='header'] {" + "text-align: left;" + "color: #828CA8;" + "background-color: transparent;" + "font-weight: bold;" + "}" + + "QSint--ActionGroup QFrame[class='content'] {" + "background-color: #D9DEE5;" + "margin-left: 12px;" + "}" + + "QSint--ActionGroup QToolButton[class='action'] {" + "color: #000000;" + "text-align: left;" + "background-color: transparent;" + "border: 1px solid transparent;" + "}" + + "QSint--ActionGroup QToolButton[class='action']:!enabled {" + "color: #ffffff;" + "}" + + "QSint--ActionGroup QToolButton[class='action']:focus {" + "border: 1px solid #1E6CBB;" + "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6FA6DE, stop: 1 #1E6CBB);" + "color: #ffffff;" + "}" + + "QSint--ActionGroup QToolButton[class='action']:on {" + "background-color: #ddeeff;" + "color: #006600;" + "}" +; + +MacPanelScheme::MacPanelScheme() : ActionPanelScheme() +{ + actionStyle = QString(MacPanelStyle); + + headerButtonFold = QPixmap(); + headerButtonFoldOver = QPixmap(":/mac/FoldOver.png"); + headerButtonUnfold = QPixmap(); + headerButtonUnfoldOver = QPixmap(":/mac/UnfoldOver.png"); + headerButtonSize = QSize(30,16); +} + + +} diff --git a/src/Gui/QSint/actionpanel/macpanelscheme.h b/src/Gui/QSint/actionpanel/macpanelscheme.h new file mode 100644 index 000000000..599a7696a --- /dev/null +++ b/src/Gui/QSint/actionpanel/macpanelscheme.h @@ -0,0 +1,32 @@ +#ifndef MACPANELSCHEME_H +#define MACPANELSCHEME_H + +#include "actionpanelscheme.h" + + +namespace QSint +{ + + +/** + \brief MacOS-like color scheme for ActionPanel and ActionGroup. + \since 0.2 + + \image html ActionPanel6.png Example of the scheme +*/ +class MacPanelScheme : public ActionPanelScheme +{ +public: + explicit MacPanelScheme(); + + static ActionPanelScheme* defaultScheme() + { + static MacPanelScheme scheme; + return &scheme; + } +}; + + +} + +#endif // MACPANELSCHEME_H diff --git a/src/Gui/QSint/actionpanel/schemes.qrc b/src/Gui/QSint/actionpanel/schemes.qrc new file mode 100644 index 000000000..b90d9bfc5 --- /dev/null +++ b/src/Gui/QSint/actionpanel/schemes.qrc @@ -0,0 +1,26 @@ + + + default/Fold.png + default/FoldOver.png + default/Unfold.png + default/UnfoldOver.png + xp/Fold_Blue1.png + xp/Fold_Blue2.png + xp/FoldOver_Blue1.png + xp/FoldOver_Blue2.png + xp/Unfold_Blue1.png + xp/Unfold_Blue2.png + xp/UnfoldOver_Blue1.png + xp/UnfoldOver_Blue2.png + vista/Fold.png + vista/FoldOver.png + vista/Unfold.png + vista/UnfoldOver.png + mac/FoldOver.png + mac/UnfoldOver.png + android/Fold.png + android/Unfold.png + android/FoldOver.png + android/UnfoldOver.png + + diff --git a/src/Gui/QSint/actionpanel/taskgroup_p.cpp b/src/Gui/QSint/actionpanel/taskgroup_p.cpp new file mode 100644 index 000000000..f3e92eb7b --- /dev/null +++ b/src/Gui/QSint/actionpanel/taskgroup_p.cpp @@ -0,0 +1,146 @@ +#include "taskgroup_p.h" + +#include +#include +#include + + +namespace QSint +{ + + +TaskGroup::TaskGroup(QWidget *parent, bool hasHeader) + : BaseClass(parent), + myHasHeader(hasHeader) +{ + setProperty("class", "content"); + setProperty("header", hasHeader ? "true" : "false"); + + setScheme(ActionPanelScheme::defaultScheme()); + + QVBoxLayout *vbl = new QVBoxLayout(); + vbl->setMargin(4); + vbl->setSpacing(0); + setLayout(vbl); + + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); +} + +void TaskGroup::setScheme(ActionPanelScheme *scheme) +{ + if (scheme) { + myScheme = scheme; + + setStyleSheet(myScheme->actionStyle); + + update(); + } +} + +bool TaskGroup::addActionLabel(ActionLabel *label, bool addToLayout, bool addStretch) +{ + if (!label) + return false; + + label->setStyleSheet(""); + + return addWidget(label, addToLayout, addStretch); +} + +bool TaskGroup::addWidget(QWidget *widget, bool addToLayout, bool addStretch) +{ + if (!widget) + return false; + + if (!addToLayout) + return true; + + if (addStretch) { + QHBoxLayout *hbl = new QHBoxLayout(); + hbl->setMargin(0); + hbl->setSpacing(0); + hbl->addWidget(widget); + hbl->addStretch(); + + groupLayout()->addLayout(hbl); + } + else { + groupLayout()->addWidget(widget); + } + + return true; +} + +QPixmap TaskGroup::transparentRender() +{ + QPixmap pm(size()); + pm.fill(Qt::transparent); + + render(&pm, QPoint(0,0), rect(), DrawChildren | IgnoreMask); + + return pm; +} + +void TaskGroup::paintEvent ( QPaintEvent * event ) +{ +// QPainter p(this); + +// p.setBrush(myScheme->groupBackground); + +// p.setPen(myScheme->groupBorder); +// p.drawRect(rect().adjusted(0,-(int)myHasHeader,-1,-1)); + + BaseClass::paintEvent(event); +} + +void TaskGroup::keyPressEvent ( QKeyEvent * event ) +{ + switch (event->key()) + { + case Qt::Key_Down: + { + QKeyEvent ke(QEvent::KeyPress, Qt::Key_Tab, 0); + QApplication::sendEvent(this, &ke); + return; + } + + case Qt::Key_Up: + { + QKeyEvent ke(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier); + QApplication::sendEvent(this, &ke); + return; + } + + default:; + } + + BaseClass::keyPressEvent(event); +} + + +void TaskGroup::keyReleaseEvent ( QKeyEvent * event ) +{ + switch (event->key()) + { + case Qt::Key_Down: + { + QKeyEvent ke(QEvent::KeyRelease, Qt::Key_Tab, 0); + QApplication::sendEvent(this, &ke); + return; + } + + case Qt::Key_Up: + { + QKeyEvent ke(QEvent::KeyRelease, Qt::Key_Tab, Qt::ShiftModifier); + QApplication::sendEvent(this, &ke); + return; + } + + default:; + } + + BaseClass::keyReleaseEvent(event); +} + + +} diff --git a/src/Gui/QSint/actionpanel/taskgroup_p.h b/src/Gui/QSint/actionpanel/taskgroup_p.h new file mode 100644 index 000000000..5ab2ab939 --- /dev/null +++ b/src/Gui/QSint/actionpanel/taskgroup_p.h @@ -0,0 +1,48 @@ +#ifndef TASKGROUP_P_H +#define TASKGROUP_P_H + +#include "actionpanelscheme.h" +#include "actionlabel.h" + +#include +#include + + +namespace QSint +{ + + +class TaskGroup : public QFrame +{ + typedef QFrame BaseClass; + +public: + TaskGroup(QWidget *parent, bool hasHeader = false); + + void setScheme(ActionPanelScheme *scheme); + + inline QBoxLayout* groupLayout() + { + return (QBoxLayout*)layout(); + } + + bool addActionLabel(ActionLabel *label, bool addToLayout, bool addStretch); + + bool addWidget(QWidget *widget, bool addToLayout, bool addStretch); + + QPixmap transparentRender(); + +protected: + virtual void paintEvent ( QPaintEvent * event ); + virtual void keyPressEvent ( QKeyEvent * event ); + virtual void keyReleaseEvent ( QKeyEvent * event ); + + ActionPanelScheme *myScheme; + + bool myHasHeader; +}; + + +} + +#endif // TASKGROUP_P_H diff --git a/src/Gui/QSint/actionpanel/taskheader_p.cpp b/src/Gui/QSint/actionpanel/taskheader_p.cpp new file mode 100644 index 000000000..02032afbf --- /dev/null +++ b/src/Gui/QSint/actionpanel/taskheader_p.cpp @@ -0,0 +1,274 @@ +#include "taskheader_p.h" +#include "actionpanelscheme.h" +#include "actionlabel.h" + +#include +#include +#include + +#include +#include +#include +#include + + +namespace QSint +{ + + +TaskHeader::TaskHeader(const QIcon &icon, const QString &title, bool expandable, QWidget *parent) + : BaseClass(parent), + myExpandable(expandable), + m_over(false), + m_buttonOver(false), + m_fold(true), + m_opacity(0.1), + myButton(0) +{ + setProperty("class", "header"); + + myTitle = new ActionLabel(this); + myTitle->setProperty("class", "header"); + myTitle->setText(title); + myTitle->setIcon(icon); + myTitle->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); + + connect(myTitle, SIGNAL(clicked()), this, SLOT(fold())); + + QHBoxLayout *hbl = new QHBoxLayout(); + hbl->setMargin(2); + setLayout(hbl); + + hbl->addWidget(myTitle); + + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); + + setScheme(ActionPanelScheme::defaultScheme()); + //myTitle->setSchemePointer(&myLabelScheme); + + setExpandable(myExpandable); +} + +void TaskHeader::setExpandable(bool expandable) +{ + if (expandable) { + myExpandable = true; + + if (myButton) + return; + + myButton = new QLabel(this); + myButton->installEventFilter(this); + myButton->setFixedSize(myScheme->headerButtonSize); + layout()->addWidget(myButton); + changeIcons(); + + } else { + myExpandable = false; + + if (!myButton) + return; + + myButton->removeEventFilter(this); + myButton->setParent(0); + delete myButton; + myButton = 0; + changeIcons(); + } +} + +bool TaskHeader::eventFilter(QObject *obj, QEvent *event) +{ + switch (event->type()) { + case QEvent::MouseButtonPress: + if (myExpandable) + fold(); + return true; + + case QEvent::Enter: + m_buttonOver = true; + changeIcons(); + return true; + + case QEvent::Leave: + m_buttonOver = false; + changeIcons(); + return true; + + default:; + } + + return BaseClass::eventFilter(obj, event); +} + +void TaskHeader::setScheme(ActionPanelScheme *scheme) +{ + if (scheme) { + myScheme = scheme; + //myLabelScheme = &(scheme->headerLabelScheme); + setStyleSheet(myScheme->actionStyle); + + if (myExpandable) { + //setCursor(myLabelScheme->cursorOver ? Qt::PointingHandCursor : cursor()); + changeIcons(); + } + + setFixedHeight(scheme->headerSize); + + update(); + } +} + +void TaskHeader::paintEvent ( QPaintEvent * event ) +{ + QPainter p(this); + + if (myScheme->headerAnimation) + p.setOpacity(m_opacity+0.7); + +// p.setPen(m_over ? myScheme->headerBorderOver : myScheme->headerBorder); +// p.setBrush(m_over ? myScheme->headerBackgroundOver : myScheme->headerBackground); + +// myScheme->headerCorners.draw(&p, rect()); + + BaseClass::paintEvent(event); +} + +void TaskHeader::animate() +{ + if (!myScheme->headerAnimation) + return; + + if (!isEnabled()) { + m_opacity = 0.1; + update(); + return; + } + + if (m_over) { + if (m_opacity >= 0.3) { + m_opacity = 0.3; + return; + } + m_opacity += 0.05; + } else { + if (m_opacity <= 0.1) { + m_opacity = 0.1; + return; + } + m_opacity = qMax(0.1, m_opacity-0.05); + } + + QTimer::singleShot(100, this, SLOT(animate())); + update(); +} + +void TaskHeader::enterEvent ( QEvent * /*event*/ ) +{ + m_over = true; + + if (isEnabled()) + QTimer::singleShot(100, this, SLOT(animate())); + + update(); +} + +void TaskHeader::leaveEvent ( QEvent * /*event*/ ) +{ + m_over = false; + + if (isEnabled()) + QTimer::singleShot(100, this, SLOT(animate())); + + update(); +} + +void TaskHeader::fold() +{ + if (myExpandable) { + emit activated(); + + m_fold = !m_fold; + changeIcons(); + } +} + +void TaskHeader::changeIcons() +{ + if (!myButton) + return; + + if (m_buttonOver) + { + if (m_fold) + myButton->setPixmap(myScheme->headerButtonFoldOver); + else + myButton->setPixmap(myScheme->headerButtonUnfoldOver); + } else + { + if (m_fold) + myButton->setPixmap(myScheme->headerButtonFold); + else + myButton->setPixmap(myScheme->headerButtonUnfold); + } + + myButton->setFixedSize(myScheme->headerButtonSize); +} + +void TaskHeader::mouseReleaseEvent ( QMouseEvent * event ) +{ + if (event->button() == Qt::LeftButton) { + emit activated(); + } +} + +void TaskHeader::keyPressEvent ( QKeyEvent * event ) +{ + switch (event->key()) + { + case Qt::Key_Down: + { + QKeyEvent ke(QEvent::KeyPress, Qt::Key_Tab, 0); + QApplication::sendEvent(this, &ke); + return; + } + + case Qt::Key_Up: + { + QKeyEvent ke(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier); + QApplication::sendEvent(this, &ke); + return; + } + + default:; + } + + BaseClass::keyPressEvent(event); +} + +void TaskHeader::keyReleaseEvent ( QKeyEvent * event ) +{ + switch (event->key()) + { + case Qt::Key_Down: + { + QKeyEvent ke(QEvent::KeyRelease, Qt::Key_Tab, 0); + QApplication::sendEvent(this, &ke); + return; + } + + case Qt::Key_Up: + { + QKeyEvent ke(QEvent::KeyRelease, Qt::Key_Tab, Qt::ShiftModifier); + QApplication::sendEvent(this, &ke); + return; + } + + default:; + } + + BaseClass::keyReleaseEvent(event); +} + + +} diff --git a/src/Gui/QSint/actionpanel/taskheader_p.h b/src/Gui/QSint/actionpanel/taskheader_p.h new file mode 100644 index 000000000..0cee4b50c --- /dev/null +++ b/src/Gui/QSint/actionpanel/taskheader_p.h @@ -0,0 +1,64 @@ +#ifndef TASKHEADER_P_H +#define TASKHEADER_P_H + +#include "actionpanelscheme.h" +#include "actionlabel.h" + +#include + + +namespace QSint +{ + + +class TaskHeader : public QFrame +{ + Q_OBJECT + + typedef QFrame BaseClass; + + friend class ActionGroup; + +public: + TaskHeader(const QIcon &icon, const QString &title, bool expandable, QWidget *parent = 0); + + inline bool expandable() const { return myExpandable; } + void setExpandable(bool expandable); + + void setScheme(ActionPanelScheme *scheme); + +Q_SIGNALS: + void activated(); + +public slots: + void fold(); + +protected Q_SLOTS: + void animate(); + +protected: + virtual void paintEvent ( QPaintEvent * event ); + virtual void enterEvent ( QEvent * event ); + virtual void leaveEvent ( QEvent * event ); + virtual void mouseReleaseEvent ( QMouseEvent * event ); + virtual void keyPressEvent ( QKeyEvent * event ); + virtual void keyReleaseEvent ( QKeyEvent * event ); + + bool eventFilter(QObject *obj, QEvent *event); + + void changeIcons(); + + ActionPanelScheme *myScheme; + + bool myExpandable; + bool m_over, m_buttonOver, m_fold; + double m_opacity; + + ActionLabel *myTitle; + QLabel *myButton; +}; + + +} + +#endif // TASKHEADER_P_H diff --git a/src/Gui/QSint/actionpanel/vista/Fold.png b/src/Gui/QSint/actionpanel/vista/Fold.png new file mode 100644 index 0000000000000000000000000000000000000000..279ddda66f024795b7bcd2fe1d60a2a9c664afa8 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP|(iP z#WAGfR&vS$0fRm%hXV|cXa1Kwx6F7_I)jHX&jZ7ji3`%0+6*3D<+rXDE=R%QmfL{UN3l%L0eCNX%r`njxgN@xNA78E9s literal 0 HcmV?d00001 diff --git a/src/Gui/QSint/actionpanel/vista/FoldOver.png b/src/Gui/QSint/actionpanel/vista/FoldOver.png new file mode 100644 index 0000000000000000000000000000000000000000..70cd655af60a80cc7f480b4fd576ad93867e9dd8 GIT binary patch literal 771 zcmV+e1N{7nP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXMy z6bc%Z8x;-!00M(aL_t(I%dL~kOO#<0#((pT-#5+7cTustpq5}!78bS8aM7l={S9qG z%gU%Ah(IHP!Y!Bj%#d!(0Y(rF2t`tAH8kIj4nghIMP~6 z``&GQ7*FtSY=OkjJif1PJm~4Tx}nNkB3s)%Fx=Za^hrjik|LruaC9muy+fa*dtkWt zPi+`L8jtr?I$N$BZEv7?dj$mnR~5OcprF7hkK$Mn7E`&ZgU3$n9(nWZEr2%pJzZ~_ z#>Li_YMd&YL?IyU`lNlu(jQE@0Tneihg$3QDLA*@f%f>-mmVcTU9CkBD1tx;6exim zW+#G1K!`vIDi9j#Y^=D!`Y4(Rm$o-l;CX_tgkX)$Rwn>W=1G(ilq#P43U)SCVMX;m z04-2LO|^xH6bZCcp8o5RciElD+QLK>jr9({@?LR-uohza+Y;%#OKQdCKy`OX_;TuY zDQ>AeMQYh4wd^u6lf;VZ#R5S8+?#Y{LP_xAOaEGtJEh!wrg-P;bSmTe!C>hl zow+|O4b5AruCa(j!j$P@bX`LWX&|6N3eQ#ep5n)RhS`}E16^&Q^$yTA?QUZ3CxvAf zGaA8;=~!_C$1*5)4D470JFb(<7MPn&ql*ld)(CL#%;AgqoOf$xGC_7}1>1~J9ychD z={PYR$27I^D{G<35$0qIDg1c h%V7{qxWb?X)PG^FsGvt*)eWFY44$rjF6*2UngA<)CYS&K literal 0 HcmV?d00001 diff --git a/src/Gui/QSint/actionpanel/vista/UnfoldOver.png b/src/Gui/QSint/actionpanel/vista/UnfoldOver.png new file mode 100644 index 0000000000000000000000000000000000000000..869c2b9c434b9d33d3ffc2224750f5042b3ed574 GIT binary patch literal 747 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXMy z6buu(oeC@f00L`CL_t(I%e9luOH@%9#((#YcLsIl&ZyxR7D^VF(8nSaTLco+pU@&` z6X+yKH3lIqYEheJKqVW?ZM6%67P)8>VOeerN}c>dY)XguQb%Xz&b{Zf&?X0`We+?Y z&N=USc+UIqDilHA;|YI>P4y*H1|Fv!(-Hyy)%Lz(waVVjt>CA?cGkQJaOqq#?XA^J ze2ehx?K}V;r+wu9mDAp0Li7%Oc+fL2E~n1K5;p~jJ&YL^6}37S z&K@S2GP?gbQ2R$Gg8=n)E-XvXQt72x_wFd~qRH7sv)+xcBnRvDe4_zWA!PUQ)>?8o zi790MQKPe~U3luWG+?-K!-jt6)8Aq9sT-1&3W zRjRSDoFJYyh;13fQU>pT3>73avHFO3I!7$Eb3eTp{VQNvBCrx(XLTdXuZ;}h%?v-2 z8D7pl1mM+NfN(NHIFTj1zEd+Z8v(eRkMZ`?&!LJ2&(WG%7Y>Jw63vFDsi=wy5`-ei z83HpWSPQSS6pEwovhPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_0008YNklf!U>1ptAds+qrCs7AN3WJ#M#ZtghVR;==I9 z+bafx9F)da3W7kh(GFQ(tuq`X3@@ ze3W8ksm|I;oqjK--x*_aN1R%c%;Fq~2wE$Yf+&d?3=NMSE%0>bBYyg|hi=prEB9uI zBSW_{CN`E~l=D8yiDJt)UwuxTTE>YbNgYY*xa_4I99_~1eU=vkbl9j6HWa;XOp;ng zalt6DnB4K**Utd>{>3iV3AuIT)?uB{?IxU_kGZ!vgAS?+R|wH4BQci5IP${r!;4)2 zeti8i0Iy!|A_7wO5BprKzv7WwAuGyuP6KWzC`BL$zNgVjq0?0GeMPnA zQxtCE`8x3btN?@!9{_z7Wf&tYErr)_Hvs=Ft{@1Wr&wH^B}ocY`^(>CV?AW&lUwW` zbU1l8nj}=H=_*iOK}1+xZnC{K$H8H*oY=pQ$K06@*m=AF0w?dTkSX2Q3Pl8^;Qswt zwl?SKT*jQ9j?oG*nPYFi%S9*V>61HbZO#$SR1iMw&4=Jtv&!bi9FMmb==D<$kNPC3 zLp^-HCnAE_f*??AwVSLxXkuMCfF>&ds8&51bsv=GpOY*8{A)-QS(L8em(B&WN0vGE z4+k6{k7%|k1c5j4q7)cYFdSyQA7zLIrG1oA{0shwnmmh+BCh}d002ovPDHLkV1krJ BYqbCX literal 0 HcmV?d00001 diff --git a/src/Gui/QSint/actionpanel/xp/FoldOver_Blue2.png b/src/Gui/QSint/actionpanel/xp/FoldOver_Blue2.png new file mode 100644 index 0000000000000000000000000000000000000000..0be4eb493de39833912fab7e8b178a2ee01ffa85 GIT binary patch literal 777 zcmV+k1NQuhP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00076bJDC%$@tlP1-a~OKa;JMGzu>2bcLA-E`-&P*)0Fy6YyNqf0-4pn^n;MFcID z#@6JTBA@Iv7Q^P+Y7NzDfGAXOj*(7E{5Vh1>y7&| zh<56YMklO9kWx+&V+@l1;JMDT-TQZ&xOHO*mB`2CAY$~+#yC7W!!WfkmR44t#c>S9 zOqh(*EnVch5ALnt-km0-6qpxM3T&(|q8bNy^ZsOaIOrcM<#(hmO`N9b-p2X@?%rO$ z0z7$n6{{~sc=T``9^76!9>vlav+W6P-q@%^d2%jr8Da*S%Q3ER)SG3VZ%b=!yIS$E zRFCEYub$3_h#0G@H2|(Hnb8UZAA#@v6}SvB7{ovrDkx936f-v%e4)xLX_olv>BT)} zfSDl#Acbg12qZ;mVI5s*;Jlv907ndC3B;U8rBpYaXpBb1fAxeh1spLZ6AkCME0yvO zj0L`ZAA)FF>0dpuZhC@JTb!Mzu!IBg`a>EIeh!YyY}9<*+QjCy#S6pr=WAHUFpgj> z;q-Kf&tHD_os4cuDMeOYSlA&EpnKTE@yQUz5wsiG|x=O>u00000NkvXX Hu0mjfsU=i| literal 0 HcmV?d00001 diff --git a/src/Gui/QSint/actionpanel/xp/Fold_Blue1.png b/src/Gui/QSint/actionpanel/xp/Fold_Blue1.png new file mode 100644 index 0000000000000000000000000000000000000000..539a40eb7c5738ffcc7e707fbc0aa35355529a1e GIT binary patch literal 808 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 bNeq7hi3pg0!BKzq00000NkvXXu0mjfEYX7k literal 0 HcmV?d00001 diff --git a/src/Gui/QSint/actionpanel/xp/Unfold_Blue1.png b/src/Gui/QSint/actionpanel/xp/Unfold_Blue1.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9819b4e7aaea8e075d729f189434fad3b0f5c1 GIT binary patch literal 792 zcmV+z1LypSP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00083NklbVI)E6jk(kp~oDV0JCQg2#8M2HiU z*mb8y*Tb(mlO|IduvdG@;kpb%9J3v*SLmTJt-1VlB1dIbda5GR)I zNk+GqGnsh601yI*K%*YAb-T&tS`ATUJj%&OIYr^{3Sl*1u3cke{cBE6a{m15oWWoM zVhBYbiVSzRn%v%~GaRH02Ps)*nOMa-#jBzoj=M3fc8#@-Hc!5r=hwY6`U6Xd2VDGD8yQoc6|K zxg$<2`nIHzQ}qp%+9JgQeLt^<4#3Q01-JC6|+yebo0f_Z=S?;`OA03{vk73Z~N5>^5x zPAP0z&i$89Z!oxir&Bp$U@#(>EK|ZzsMbQP{eLMpBu#y3HbMZ*d0dd^%JOpa;_U{5 z>t|I(QG!6|bY@9Yi%C<*-ycS-uFg(@uGV!=6ukscRaQDp=I0^~kK(dpKOBs?wGi>} z!6GOeemdu3Dj)s$>XMaHR5_TWmVrP4v=1c`; zIyckgcB{(v-FY6|TjZ>t@%CMxH1o)vXM3uusIx?ou(Q=-^P3jVmkpQ~7JzCspivJ& z3?C2A`RDzRIChAs5P~2mn1G`2ym>p|;9x|nT_K8s%Swnqo?C{)f`3N^>Of40i0~hK WR+5HO0NR%T0000Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_0008DNklsyMxX=T`z=7{K=leLLetA;@AOa$uVp^m{IXm>V+xH^7 zkyc#@nUm0uB6HDfwNBHOm6_HWlmb94Ag;D#+1)`|Oi#LNjo#Mg3hj16vtjT)kWVYF zZgK{L$xtWFqfWPb)@U`+TF)WYTC(Bo_jNHl{_;tW&mOPSYQ}tAB7wp6gx7Db8RhQ9 z`o_k0X_{g}5T=v-pe~E!XHPeH`b7_|6%Uoxik+G)a1zrH^n-3~8}iO+Oh*)-4d zlb!8Vo_zl3KLN|tS!?q3SKCDRlYBBxwYByzQla;Fr-O;~JgB{M)ZY0A!sT8F(0i2f z$xf$N6~&=;&h58b5$m1iy&(Mf?Y(gMUi26FY;LXqeqV>cZX=0F;^>2yKL#xW0s#ro zXc$bScXbG%8wd}2UkH~03p*hMlme|(SEId0q5rvRJG&!CdUaEI*!e0+HMao z-`(=|&pW&bUIga_|MEEi{^fI=7iue1)>Av->T1H@!|70)iYat4DDMWtStR_iP_2KDoA1tLOSTV`c-Fuog~xVr4Eq%rNZK^)Jw z*jgc<))a*sN@R|rxN(*=5|TKX|6&ord!crYvb1ScmWS5beeY#A1iC;5^nnW