From 3ca85dccb6993c137c255abd0955caa589269d10 Mon Sep 17 00:00:00 2001 From: vsv Date: Thu, 1 Nov 2018 13:49:01 +0300 Subject: [PATCH] Provide editing of toolbars --- src/SHAPERGUI/SHAPERGUI.cpp | 71 ++++++- src/SHAPERGUI/SHAPERGUI.h | 7 + src/SHAPERGUI/SHAPERGUI_ToolbarsMgr.cpp | 245 ++++++++++++++++++++---- src/SHAPERGUI/SHAPERGUI_ToolbarsMgr.h | 64 ++++++- src/XGUI/XGUI_pictures.qrc | 5 + src/XGUI/pictures/arrow-down.png | Bin 0 -> 3650 bytes src/XGUI/pictures/arrow-left.png | Bin 0 -> 3640 bytes src/XGUI/pictures/arrow-right.png | Bin 0 -> 3653 bytes src/XGUI/pictures/arrow-up.png | Bin 0 -> 3676 bytes 9 files changed, 340 insertions(+), 52 deletions(-) create mode 100644 src/XGUI/pictures/arrow-down.png create mode 100644 src/XGUI/pictures/arrow-left.png create mode 100644 src/XGUI/pictures/arrow-right.png create mode 100644 src/XGUI/pictures/arrow-up.png diff --git a/src/SHAPERGUI/SHAPERGUI.cpp b/src/SHAPERGUI/SHAPERGUI.cpp index 0959e9cac..53c7fcbbf 100644 --- a/src/SHAPERGUI/SHAPERGUI.cpp +++ b/src/SHAPERGUI/SHAPERGUI.cpp @@ -67,6 +67,7 @@ #include #include #include +#include #define SALOME_PATCH_FOR_CTRL_WHEEL @@ -571,7 +572,6 @@ QAction* SHAPERGUI::addFeature(const QString& theWBName, const QString& theTBNam createTool(separator(), aWBTool); registerCommandToolbar(theTBName, -1); } - return aAction; } @@ -641,6 +641,7 @@ void SHAPERGUI::addDesktopMenuSeparator(const char* theMenuSourceText, const int createMenu(separator(), aMenu, -1, theMenuPosition); } +//****************************************************** bool SHAPERGUI::addActionInToolbar( QAction* theAction, const QString& theToolBarTitle ) { if( !theAction ) @@ -812,8 +813,10 @@ void SHAPERGUI::updateModuleVisibilityState() void SHAPERGUI::onEditToolbars() { - SHAPERGUI_ToolbarsDlg aDlg(this, myActionsList, myToolbars); - aDlg.exec(); + SHAPERGUI_ToolbarsDlg aDlg(this); + if (aDlg.exec() == QDialog::Accepted) { + updateToolbars(aDlg.result()); + } } void SHAPERGUI::registerCommandToolbar(const QString& theToolName, int theCommandId) @@ -828,7 +831,67 @@ int SHAPERGUI::getNextCommandId() const QtxActionMenuMgr* aMenuMgr = menuMgr(); QIntList aIds = aMenuMgr->idList(); int aId = aIds.count(); - while (aIds.contains(aId)) + while (action(aId) || myActionsList.contains(aId)) aId++; return aId; } + +void SHAPERGUI::updateToolbars(const QMap& theNewToolbars) +{ + QtxActionToolMgr* aMgr = toolMgr(); + QStringList aToolbars = theNewToolbars.keys(); + QIntList aCommands, aOldCmd; + int aToolbarId; + QAction* aAction; + int aActionId; + foreach(QString aName, aToolbars) { + aCommands = theNewToolbars[aName]; + // Find or create toolbar + if (aMgr->hasToolBar(aName)) { + aToolbarId = aMgr->find(aMgr->toolBar(aName)); + aOldCmd = myToolbars[aName]; + } + else { + aToolbarId = aMgr->createToolBar(aName); + } + int aPos = 0; + foreach (int aCmd, aCommands) { + // Find action + if (aCmd == -1) + aAction = separator(); + else + aAction = action(aCmd); + aActionId = aMgr->actionId(aAction); + if (aActionId == -1) { + // Add new action + aMgr->insert(aAction, aToolbarId, aPos); + } + else { + // Change position of action + if (aMgr->index(aActionId, aToolbarId) != aPos) { + if (aMgr->containsAction(aActionId, aToolbarId)) + aMgr->remove(aActionId, aToolbarId); + aMgr->insert(aActionId, aToolbarId, aPos); + } + } + aOldCmd.removeAll(aCmd); + aPos++; + } + // remove extra actions + foreach(int aCmd, aOldCmd) { + aAction = action(aCmd); + aActionId = aMgr->actionId(aAction); + aMgr->remove(aActionId, aToolbarId); + } + myToolbars.remove(aName); + } + // Remove extra toolbars + aToolbars = myToolbars.keys(); + QToolBar* aToolbar = 0; + QList aActionList; + foreach(QString aName, aToolbars) { + aMgr->removeToolBar(aName); + } + // Set new toolbars structure + myToolbars = theNewToolbars; +} diff --git a/src/SHAPERGUI/SHAPERGUI.h b/src/SHAPERGUI/SHAPERGUI.h index 8c06ccf46..afcc55bf6 100644 --- a/src/SHAPERGUI/SHAPERGUI.h +++ b/src/SHAPERGUI/SHAPERGUI.h @@ -156,6 +156,11 @@ Q_OBJECT virtual void updateModuleVisibilityState(); + + QIntList shaperActions() const { return myActionsList; } + QMap shaperToolbars() const { return myToolbars; } + + public slots: /// \brief The method is redefined to connect to the study viewer before the data /// model is filled by opened file. This file open will flush redisplay signals for, @@ -218,6 +223,8 @@ private slots: int getNextCommandId() const; + // Update current toolbars + void updateToolbars(const QMap& theNewToolbars); /// List of registered nested actions QStringList myNestedActionsList; diff --git a/src/SHAPERGUI/SHAPERGUI_ToolbarsMgr.cpp b/src/SHAPERGUI/SHAPERGUI_ToolbarsMgr.cpp index 337871cdb..673bab04e 100644 --- a/src/SHAPERGUI/SHAPERGUI_ToolbarsMgr.cpp +++ b/src/SHAPERGUI/SHAPERGUI_ToolbarsMgr.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -31,8 +32,12 @@ #include #include #include +#include +#define SEPARATOR "------" +#define LIST_WIDTH 180 + class SHAPERGUI_CommandIdItem : public QListWidgetItem { public: @@ -41,17 +46,28 @@ public: virtual QVariant data(int theRole) const { - if (theRole == Qt::DisplayRole) { - if (myId == -1) - return "------"; - QAction* aAction = myModule->action(myId); + QAction* aAction = 0; + if (myId != -1) + aAction = myModule->action(myId); + + switch (theRole) { + case Qt::DisplayRole: if (aAction) return aAction->text(); + else + return SEPARATOR; + case Qt::DecorationRole: + if (aAction) + return aAction->icon(); + else + return QIcon(); } return QListWidgetItem::data(theRole); } + int id() const { return myId; } + private: SHAPERGUI* myModule; int myId; @@ -61,14 +77,13 @@ private: //************************************************************************************ //************************************************************************************ //************************************************************************************ -SHAPERGUI_ToolbarsDlg::SHAPERGUI_ToolbarsDlg(SHAPERGUI* theModule, - const QIntList& theActionsList, - const QMap& theToolbars) +SHAPERGUI_ToolbarsDlg::SHAPERGUI_ToolbarsDlg(SHAPERGUI* theModule) : QDialog(theModule->application()->desktop()), myModule(theModule), - myActionsList(theActionsList), - myToolbars(theToolbars) + myResult(theModule->shaperToolbars()) { + myFreeCommands = getModuleFreeCommands(); + setWindowTitle(tr("Toolbars")); QVBoxLayout* aMailLayout = new QVBoxLayout(this); @@ -87,9 +102,19 @@ SHAPERGUI_ToolbarsDlg::SHAPERGUI_ToolbarsDlg(SHAPERGUI* theModule, aListLayout->addWidget(new QLabel(tr("Toolbars:"), aListWgt)); myToolbarsList = new QListWidget(aListWgt); - myToolbarsList->addItems(theToolbars.keys()); + connect(myToolbarsList, SIGNAL(doubleClicked(const QModelIndex&)), + SLOT(onDoubleClick(const QModelIndex&))); aListLayout->addWidget(myToolbarsList); + QWidget* aFreeItemsWgt = new QWidget(aListWgt); + QHBoxLayout* aFreeLayout = new QHBoxLayout(aFreeItemsWgt); + aFreeLayout->setContentsMargins(0, 0, 0, 0); + aListLayout->addWidget(aFreeItemsWgt); + + aFreeLayout->addWidget(new QLabel(tr("Number of commands out of toolbars:"), aFreeItemsWgt)); + myFreeNbLbl = new QLabel(aFreeItemsWgt); + aFreeLayout->addWidget(myFreeNbLbl); + // Left controls QWidget* aButtonsWgt = new QWidget(aControlsWgt); QVBoxLayout* aBtnLayout = new QVBoxLayout(aButtonsWgt); @@ -115,6 +140,9 @@ SHAPERGUI_ToolbarsDlg::SHAPERGUI_ToolbarsDlg(SHAPERGUI* theModule, aMailLayout->addWidget(aButtons); connect(aButtons, SIGNAL(accepted()), SLOT(accept())); connect(aButtons, SIGNAL(rejected()), SLOT(reject())); + + updateToolbarsList(); + updateNumber(); } void SHAPERGUI_ToolbarsDlg::onAdd() @@ -122,8 +150,8 @@ void SHAPERGUI_ToolbarsDlg::onAdd() QString aNewToolbar = QInputDialog::getText(this, tr("Create toolbar"), tr("Name of a new toolbar")); if (!(aNewToolbar.isNull() || aNewToolbar.isEmpty())) { - if (!myToolbars.contains(aNewToolbar)) { - myToolbars[aNewToolbar] = QIntList(); + if (!myResult.contains(aNewToolbar)) { + myResult[aNewToolbar] = QIntList(); updateToolbarsList(); } else { @@ -138,10 +166,17 @@ void SHAPERGUI_ToolbarsDlg::onEdit() QList aSelected = myToolbarsList->selectedItems(); if (aSelected.size() == 1) { QString aToolbarName = aSelected.first()->text(); - QIntList aFreeItems = getFreeCommands(); + int aPos = aToolbarName.lastIndexOf(" ("); + aToolbarName = aToolbarName.left(aPos); + SHAPERGUI_ToolbarItemsDlg aDlg(this, myModule, - aToolbarName, aFreeItems, myToolbars[aToolbarName]); - aDlg.exec(); + aToolbarName, myFreeCommands, myResult[aToolbarName]); + if (aDlg.exec() == QDialog::Accepted) { + myFreeCommands = aDlg.freeItems(); + myResult[aToolbarName] = aDlg.toolbarItems(); + updateNumber(); + updateToolbarsList(); + } } } @@ -150,10 +185,17 @@ void SHAPERGUI_ToolbarsDlg::onDelete() QList aSelected = myToolbarsList->selectedItems(); if (aSelected.size() == 1) { QString aToolbarName = aSelected.first()->text(); + int aPos = aToolbarName.lastIndexOf(" ("); + aToolbarName = aToolbarName.left(aPos); + QString aMsg = tr("Toolbar %1 will be deleted. Continue?").arg(aToolbarName); if (QMessageBox::question(this, tr("Delete toolbar"), aMsg) == QMessageBox::Yes) { - myToolbars.remove(aToolbarName); + myFreeCommands.append(myResult[aToolbarName]); + // remove separators from free items + myFreeCommands.removeAll(-1); + myResult.remove(aToolbarName); updateToolbarsList(); + updateNumber(); } } } @@ -161,28 +203,43 @@ void SHAPERGUI_ToolbarsDlg::onDelete() void SHAPERGUI_ToolbarsDlg::updateToolbarsList() { myToolbarsList->clear(); - myToolbarsList->addItems(myToolbars.keys()); + QStringList aItems; + QMap::const_iterator aIt; + for (aIt = myResult.cbegin(); aIt != myResult.cend(); aIt++) { + aItems.append(aIt.key() + tr(" (%1 items)").arg(aIt.value().size() - aIt.value().count(-1))); + } + myToolbarsList->addItems(aItems); } -QIntList SHAPERGUI_ToolbarsDlg::getFreeCommands() const +QIntList SHAPERGUI_ToolbarsDlg::getModuleFreeCommands() const { QIntList aFreeCommands; + QtxActionToolMgr* aMgr = myModule->toolMgr(); + QAction* anAction; + int aId; QMap::const_iterator aIt; - foreach(int aCmd, myActionsList) { - bool aIsFree = true; - for (aIt = myToolbars.cbegin(); aIt != myToolbars.cend(); aIt++) { - if (aIt.value().contains(aCmd)) { - aIsFree = false; - break; - } - } - if (aIsFree) + QIntList aShaperActions = myModule->shaperActions(); + foreach(int aCmd, aShaperActions) { + anAction = myModule->action(aCmd); + aId = aMgr->actionId(anAction); + if (!aMgr->containsAction(aId)) aFreeCommands.append(aCmd); } return aFreeCommands; } +void SHAPERGUI_ToolbarsDlg::onDoubleClick(const QModelIndex& theIdx) +{ + if (theIdx.isValid()) + onEdit(); +} + +void SHAPERGUI_ToolbarsDlg::updateNumber() +{ + myFreeNbLbl->setText(QString::number(myFreeCommands.size())); +} + //************************************************************************************ //************************************************************************************ //************************************************************************************ @@ -192,9 +249,7 @@ SHAPERGUI_ToolbarItemsDlg::SHAPERGUI_ToolbarItemsDlg(QWidget* theParent, const QIntList& theFreeItems, const QIntList& theItemsList) : QDialog(theParent), - myModule(theModule), - myFreeItems(theFreeItems), - myToolItems(theItemsList) + myModule(theModule) { setWindowTitle(tr("Edit toolbar items")); @@ -228,10 +283,13 @@ SHAPERGUI_ToolbarItemsDlg::SHAPERGUI_ToolbarItemsDlg(QWidget* theParent, aCommandsLay->addWidget(new QLabel(tr("Out of toolbars:"), aCommandsWgt)); myCommandsList = new QListWidget(aCommandsWgt); - foreach(int aId, myFreeItems) { + myCommandsList->setSortingEnabled(false); + + myCommandsList->addItem(new SHAPERGUI_CommandIdItem(myCommandsList, -1, myModule)); + foreach(int aId, theFreeItems) { myCommandsList->addItem(new SHAPERGUI_CommandIdItem(myCommandsList, aId, myModule)); } - myCommandsList->setMaximumWidth(150); + myCommandsList->setMaximumWidth(LIST_WIDTH); aCommandsLay->addWidget(myCommandsList); // Middle buttons @@ -241,13 +299,13 @@ SHAPERGUI_ToolbarItemsDlg::SHAPERGUI_ToolbarItemsDlg(QWidget* theParent, aCtrlLayout->addWidget(aButtonsWgt); aBtnLayout->addStretch(1); - QPushButton* aAddButton = new QPushButton("--->", aButtonsWgt); + QPushButton* aAddButton = new QPushButton(QIcon(":pictures/arrow-right.png"), "", aButtonsWgt); connect(aAddButton, SIGNAL(clicked(bool)), SLOT(onAddItem())); aBtnLayout->addWidget(aAddButton); aBtnLayout->addSpacing(20); - QPushButton* aDelButton = new QPushButton("<---", aButtonsWgt); + QPushButton* aDelButton = new QPushButton(QIcon(":pictures/arrow-left.png"), "", aButtonsWgt); connect(aDelButton, SIGNAL(clicked(bool)), SLOT(onDelItem())); aBtnLayout->addWidget(aDelButton); aBtnLayout->addStretch(1); @@ -260,12 +318,32 @@ SHAPERGUI_ToolbarItemsDlg::SHAPERGUI_ToolbarItemsDlg(QWidget* theParent, aItemsLay->addWidget(new QLabel(tr("In the toolbar:"), aItemsWgt)); myItemsList = new QListWidget(aItemsWgt); - foreach(int aId, myToolItems) { + myItemsList->setSortingEnabled(false); + foreach(int aId, theItemsList) { myItemsList->addItem(new SHAPERGUI_CommandIdItem(myItemsList, aId, myModule)); } - myItemsList->setMaximumWidth(150); + myItemsList->setMaximumWidth(LIST_WIDTH); + myItemsList->viewport()->installEventFilter(this); aItemsLay->addWidget(myItemsList); + // Buttons of right list + QWidget* aBtnWgt = new QWidget(aControlsWgt); + QVBoxLayout* aBtnLay = new QVBoxLayout(aBtnWgt); + aBtnLay->setContentsMargins(0, 0, 0, 0); + aCtrlLayout->addWidget(aBtnWgt); + + aBtnLay->addStretch(1); + QPushButton* aUpButton = new QPushButton(QIcon(":pictures/arrow-up.png"), "", aBtnWgt); + connect(aUpButton, SIGNAL(clicked(bool)), SLOT(onUp())); + aBtnLay->addWidget(aUpButton); + + aBtnLay->addSpacing(20); + + QPushButton* aDownButton = new QPushButton(QIcon(":pictures/arrow-down.png"), "", aBtnWgt); + connect(aDownButton, SIGNAL(clicked(bool)), SLOT(onDown())); + aBtnLay->addWidget(aDownButton); + aBtnLay->addStretch(1); + // Buttons part of the dialog QDialogButtonBox* aButtons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); @@ -276,10 +354,101 @@ SHAPERGUI_ToolbarItemsDlg::SHAPERGUI_ToolbarItemsDlg(QWidget* theParent, void SHAPERGUI_ToolbarItemsDlg::onAddItem() { - + QList aCurrentList = myCommandsList->selectedItems(); + if (aCurrentList.size() > 0) { + SHAPERGUI_CommandIdItem* aItem = dynamic_cast(aCurrentList.first()); + int aId = aItem->id(); + if (aId != -1) { + myCommandsList->removeItemWidget(aItem); + delete aItem; + } + QModelIndex aIdx = myItemsList->currentIndex(); + aItem = new SHAPERGUI_CommandIdItem(0, aId, myModule); + if (aIdx.isValid()) { + int aRow = aIdx.row(); + myItemsList->insertItem(aRow, aItem); + } + else { + myItemsList->addItem(aItem); + } + } } void SHAPERGUI_ToolbarItemsDlg::onDelItem() { + QList aCurrentList = myItemsList->selectedItems(); + if (aCurrentList.size() > 0) { + SHAPERGUI_CommandIdItem* aItem = dynamic_cast(aCurrentList.first()); + int aId = aItem->id(); + myItemsList->removeItemWidget(aItem); + delete aItem; + if (aId != -1) { + aItem = new SHAPERGUI_CommandIdItem(myCommandsList, aId, myModule); + myCommandsList->addItem(aItem); + } + } +} + + +bool SHAPERGUI_ToolbarItemsDlg::eventFilter(QObject* theObj, QEvent* theEvent) +{ + if (theEvent->type() == QEvent::MouseButtonRelease) { + QMouseEvent* aMouseEvent = (QMouseEvent*)theEvent; + QModelIndex aIdx = myItemsList->indexAt(aMouseEvent->pos()); + if (!aIdx.isValid() || aMouseEvent->button() == Qt::RightButton) { + myItemsList->setCurrentIndex(QModelIndex()); + } + } + return QDialog::eventFilter(theObj, theEvent); +} + +void SHAPERGUI_ToolbarItemsDlg::onUp() +{ + QModelIndex aCurrentIdx = myItemsList->currentIndex(); + if (aCurrentIdx.isValid()) { + int aRow = aCurrentIdx.row(); + if (aRow > 0) { + QListWidgetItem* aItem = myItemsList->takeItem(aRow); + aRow--; + myItemsList->insertItem(aRow, aItem); + myItemsList->setCurrentRow(aRow); + } + } +} + +void SHAPERGUI_ToolbarItemsDlg::onDown() +{ + QModelIndex aCurrentIdx = myItemsList->currentIndex(); + if (aCurrentIdx.isValid()) { + int aNb = myItemsList->count(); + int aRow = aCurrentIdx.row(); + if (aRow < (aNb - 1)) { + QListWidgetItem* aItem = myItemsList->takeItem(aRow); + aRow++; + myItemsList->insertItem(aRow, aItem); + myItemsList->setCurrentRow(aRow); + } + } +} -} \ No newline at end of file +QIntList SHAPERGUI_ToolbarItemsDlg::freeItems() const +{ + return getItems(myCommandsList, 1); +} + +QIntList SHAPERGUI_ToolbarItemsDlg::toolbarItems() const +{ + return getItems(myItemsList, 0); +} + +QIntList SHAPERGUI_ToolbarItemsDlg::getItems(QListWidget* theWidget, int theStart) const +{ + QIntList aList; + SHAPERGUI_CommandIdItem* aItem = 0; + int aNb = theWidget->count(); + for (int i = theStart; i < aNb; i++) { + aItem = (SHAPERGUI_CommandIdItem*)theWidget->item(i); + aList.append(aItem->id()); + } + return aList; +} diff --git a/src/SHAPERGUI/SHAPERGUI_ToolbarsMgr.h b/src/SHAPERGUI/SHAPERGUI_ToolbarsMgr.h index 1da7e8a2e..9d6e77536 100644 --- a/src/SHAPERGUI/SHAPERGUI_ToolbarsMgr.h +++ b/src/SHAPERGUI/SHAPERGUI_ToolbarsMgr.h @@ -32,26 +32,57 @@ class QListWidget; class SHAPERGUI; +class QLabel; - +/** +* \ingroup Salome +* A dialog box for editing of toolbar items +*/ class SHAPERGUI_ToolbarItemsDlg : public QDialog { Q_OBJECT public: + /// Constructor + /// \param theParent a parent for the dialog + /// \param theModule a module with toolbars + /// \param theToolbar a name of the toolbar for editing + /// \param theFreeItems a list of commands out of toolbars + /// \param theItemsList a list of command in the toolbar SHAPERGUI_ToolbarItemsDlg(QWidget* theParent, SHAPERGUI* theModule, const QString& theToolbar, const QIntList& theFreeItems, const QIntList& theItemsList); + /// Returns list of free commands + QIntList freeItems() const; + + /// Returns list of commands in the toolbar + QIntList toolbarItems() const; + +protected: + /// An redifinition of a virtual function + /// \param theObj an object + /// \param theEvent an event + virtual bool eventFilter(QObject* theObj, QEvent* theEvent); + private slots: + /// A slot for button to add an item to toolbar commands void onAddItem(); + + /// A slot for button to remove an item from toolbar commands void onDelItem(); + /// A slot to move a current item up in list of toolbar command + void onUp(); + + /// A slot to move a current item down in list of toolbar command + void onDown(); + private: + QIntList getItems(QListWidget* theWidget, int theStart) const; + SHAPERGUI* myModule; - QIntList myFreeItems; - QIntList myToolItems; QListWidget* myCommandsList; QListWidget* myItemsList; @@ -66,29 +97,42 @@ class SHAPERGUI_ToolbarsDlg : public QDialog { Q_OBJECT public: - SHAPERGUI_ToolbarsDlg(SHAPERGUI* theModule, - const QIntList& theActionsList, - const QMap& theToolbars); + /// Constructor + /// \param theModule a SHAPER module + SHAPERGUI_ToolbarsDlg(SHAPERGUI* theModule); - QMap result() const { return myToolbars; } + /// Returns result of editing + QMap result() const { return myResult; } private slots: + /// A slot to add a new toolbar void onAdd(); + /// A slot to edit a current toolbar void onEdit(); + /// A slot to delete a current toolbar void onDelete(); + /// A slot called on double click on item in list + void onDoubleClick(const QModelIndex& theIdx); + private: + /// Update content of toolbars list void updateToolbarsList(); - QIntList getFreeCommands() const; + /// Update number of free items + void updateNumber(); + + /// Returns free commands which are not in toolbars in the module + QIntList getModuleFreeCommands() const; private: SHAPERGUI* myModule; - QIntList myActionsList; - QMap myToolbars; + QMap myResult; + QIntList myFreeCommands; + QLabel* myFreeNbLbl; QListWidget* myToolbarsList; }; diff --git a/src/XGUI/XGUI_pictures.qrc b/src/XGUI/XGUI_pictures.qrc index ea9614f94..8ea63a1e0 100644 --- a/src/XGUI/XGUI_pictures.qrc +++ b/src/XGUI/XGUI_pictures.qrc @@ -77,5 +77,10 @@ pictures/autoapply_start.png pictures/autoapply_stop.png pictures/whatis.png + + pictures/arrow-left.png + pictures/arrow-right.png + pictures/arrow-up.png + pictures/arrow-down.png diff --git a/src/XGUI/pictures/arrow-down.png b/src/XGUI/pictures/arrow-down.png new file mode 100644 index 0000000000000000000000000000000000000000..b5d69badfaa4e5836ee96de692a01b42ff2b1922 GIT binary patch literal 3650 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 Uq`Vt&)Bpeg07*qoM6N<$g2R#C^#A|> literal 0 HcmV?d00001 diff --git a/src/XGUI/pictures/arrow-left.png b/src/XGUI/pictures/arrow-left.png new file mode 100644 index 0000000000000000000000000000000000000000..7895091ceb77018e02f4e2c0cb962ca18684053f GIT binary patch literal 3640 zcmV-84#)9{P)004&%004{+008|`004nN004b?008NW002DY000@xb3BE2000U( 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 KMNUMnLSTZ=_1Xyl literal 0 HcmV?d00001 diff --git a/src/XGUI/pictures/arrow-right.png b/src/XGUI/pictures/arrow-right.png new file mode 100644 index 0000000000000000000000000000000000000000..7d8f9ba0810b3d83dae622a545fc49a76b0b5b62 GIT binary patch literal 3653 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