From 8c1849700abeb51607840f149c9a4cb6ab02555d Mon Sep 17 00:00:00 2001 From: nds Date: Mon, 27 Apr 2015 16:44:41 +0300 Subject: [PATCH] Multi-color --- src/ModelAPI/ModelAPI_Result.h | 4 +- src/ModelAPI/ModelAPI_Tools.cpp | 36 +++++++++ src/ModelAPI/ModelAPI_Tools.h | 8 ++ src/XGUI/CMakeLists.txt | 2 + src/XGUI/XGUI_ColorDialog.cpp | 78 ++++++++++++++++++++ src/XGUI/XGUI_ColorDialog.h | 51 +++++++++++++ src/XGUI/XGUI_Workshop.cpp | 127 ++++++++++++++++++-------------- 7 files changed, 249 insertions(+), 57 deletions(-) create mode 100644 src/XGUI/XGUI_ColorDialog.cpp create mode 100644 src/XGUI/XGUI_ColorDialog.h diff --git a/src/ModelAPI/ModelAPI_Result.h b/src/ModelAPI/ModelAPI_Result.h index 472fe0056..635649f5c 100644 --- a/src/ModelAPI/ModelAPI_Result.h +++ b/src/ModelAPI/ModelAPI_Result.h @@ -23,7 +23,9 @@ class ModelAPI_Result : public ModelAPI_Object bool myIsConcealed; ///< the result is concealed from the data tree (referenced by other objects) public: - /// Reference to the color of the result + /// Reference to the color of the result. + /// The integer array is used. It contains tree values for red green and blue values. The values are in + /// [0, 255] range inline static const std::string& COLOR_ID() { static const std::string MY_COLOR_ID("Color"); diff --git a/src/ModelAPI/ModelAPI_Tools.cpp b/src/ModelAPI/ModelAPI_Tools.cpp index 1d8e0bf10..3564dce7c 100644 --- a/src/ModelAPI/ModelAPI_Tools.cpp +++ b/src/ModelAPI/ModelAPI_Tools.cpp @@ -12,6 +12,7 @@ #include #include +#include namespace ModelAPI_Tools { @@ -57,4 +58,39 @@ bool findVariable(const std::string& theName, double& outValue) return false; } +static std::map > myColorMap; + +std::vector vectorOfValues(const int theRed, const int theGreen, const int theBlue) +{ + std::vector aValues; + aValues.push_back(theRed); + aValues.push_back(theGreen); + aValues.push_back(theBlue); + + return aValues; +} + +void fillColorMap() +{ + if (!myColorMap.empty()) + return; + myColorMap[0] = vectorOfValues(127, 51, 0); + myColorMap[1] = vectorOfValues(0, 38, 225); + myColorMap[2] = vectorOfValues(255, 0, 0); +} + +void findRandomColor(std::vector& theValues) +{ + theValues.clear(); + if (myColorMap.empty()) { + fillColorMap(); + } + + int aSize = myColorMap.size(); + int anIndex = rand() % aSize; + if (myColorMap.find(anIndex) != myColorMap.end()) { + theValues = myColorMap.at(anIndex); + } +} + } // namespace ModelAPI_Tools diff --git a/src/ModelAPI/ModelAPI_Tools.h b/src/ModelAPI/ModelAPI_Tools.h index 9d63757ea..e89a713ce 100644 --- a/src/ModelAPI/ModelAPI_Tools.h +++ b/src/ModelAPI/ModelAPI_Tools.h @@ -11,6 +11,8 @@ #include #include +#include + namespace ModelAPI_Tools { /// Returns shape from the given Result object MODELAPI_EXPORT std::shared_ptr shape(const ResultPtr& theResult); @@ -22,6 +24,12 @@ MODELAPI_EXPORT std::shared_ptr shape(const ResultPtr& theResult) */ MODELAPI_EXPORT bool findVariable(const std::string& theName, double& outValue); +/*! + * Returns the values of the next random color. The values are in range [0, 255] + * \param theValues a container of component of RGB value: red, green, blue + */ +MODELAPI_EXPORT void findRandomColor(std::vector& theValues); + } #endif diff --git a/src/XGUI/CMakeLists.txt b/src/XGUI/CMakeLists.txt index bd843caa9..060d58af8 100644 --- a/src/XGUI/CMakeLists.txt +++ b/src/XGUI/CMakeLists.txt @@ -6,6 +6,7 @@ SET(CMAKE_AUTOMOC ON) SET(PROJECT_HEADERS XGUI.h XGUI_ActionsMgr.h + XGUI_ColorDialog.h XGUI_ContextMenuMgr.h XGUI_CustomPrs.h XGUI_DataTreeModel.h @@ -33,6 +34,7 @@ SET(PROJECT_AUTOMOC SET(PROJECT_SOURCES XGUI_ActionsMgr.cpp + XGUI_ColorDialog.cpp XGUI_ContextMenuMgr.cpp XGUI_CustomPrs.cpp XGUI_Displayer.cpp diff --git a/src/XGUI/XGUI_ColorDialog.cpp b/src/XGUI/XGUI_ColorDialog.cpp new file mode 100644 index 000000000..e91d3cceb --- /dev/null +++ b/src/XGUI/XGUI_ColorDialog.cpp @@ -0,0 +1,78 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: XGUI_ColorDialog.cpp +// Created: 27 Apr 2015 +// Author: Natalia ERMOLAEVA + +#include + +#include + +#include + +#include +#include +#include +#include +#include + +XGUI_ColorDialog::XGUI_ColorDialog(QWidget* theParent) + : QDialog(theParent) +{ + setWindowTitle("Color"); + QGridLayout* aLay = new QGridLayout(this); + + QRadioButton* aRandomChoiceBtn = new QRadioButton(this); + QRadioButton* aColorChoiceBtn = new QRadioButton(this); + aColorChoiceBtn->setChecked(true); + myButtonGroup = new QButtonGroup(this); + myButtonGroup->setExclusive(true); + myButtonGroup->addButton(aColorChoiceBtn, 0); + myButtonGroup->addButton(aRandomChoiceBtn, 1); + + aLay->addWidget(aColorChoiceBtn, 0, 0); + aLay->addWidget(aRandomChoiceBtn, 1, 0); + + myColorButton = new QtxColorButton(this); + myColorButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + aLay->addWidget(myColorButton, 0, 1); + + QLabel* aRandomLabel = new QLabel("Random", this); + aLay->addWidget(aRandomLabel, 1, 1); + + QDialogButtonBox* aButtons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, + Qt::Horizontal, this); + connect(aButtons, SIGNAL(accepted()), this, SLOT(accept())); + connect(aButtons, SIGNAL(rejected()), this, SLOT(reject())); + aLay->addWidget(aButtons, 2, 0, 1, 2); +} + +bool XGUI_ColorDialog::isRandomColor() const +{ + int anId = myButtonGroup->checkedId(); + + return myButtonGroup->checkedId() == 1; +} + +void XGUI_ColorDialog::setColor(const std::vector& theValue) +{ + if (theValue.size() != 3) + return; + + myColorButton->setColor(QColor(theValue[0], theValue[1], theValue[2])); +} + +std::vector XGUI_ColorDialog::getColor() const +{ + std::vector aValues; + if (isRandomColor()) { + ModelAPI_Tools::findRandomColor(aValues); + } + else { + QColor aColorResult = myColorButton->color(); + aValues.push_back(aColorResult.red()); + aValues.push_back(aColorResult.green()); + aValues.push_back(aColorResult.blue()); + } + return aValues; +} diff --git a/src/XGUI/XGUI_ColorDialog.h b/src/XGUI/XGUI_ColorDialog.h new file mode 100644 index 000000000..e5bc381d5 --- /dev/null +++ b/src/XGUI/XGUI_ColorDialog.h @@ -0,0 +1,51 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: XGUI_ColorDialog.hxx +// Created: 27 Apr 2015 +// Author: Natalia ERMOLAEVA + +#ifndef XGUI_ColorDialog_H +#define XGUI_ColorDialog_H + +#include "XGUI.h" + +#include + +class QButtonGroup; +class QtxColorButton; + +/** +* \ingroup GUI +* A class of dialog to chose a color. The color can be set in two ways: use a random value or +* a certain color. There is a radio button to provide this choice. The color button is visualized to +* select a certain color. +*/ +class XGUI_ColorDialog : public QDialog +{ + Q_OBJECT +public: + /// Constructor + /// \param theParent a parent widget for the dialog + XGUI_EXPORT XGUI_ColorDialog(QWidget* theParent); + + XGUI_EXPORT virtual ~XGUI_ColorDialog() {}; + + /// Returns whether the random state of color is chosen + /// \return a boolean value + bool isRandomColor() const; + + /// Initializes the dialog with the given value. Set choice on certain value and fill it by. + /// \param theValue an RGB components value + void setColor(const std::vector& theValue); + + /// Returns a container with the current color value. These are tree int values for RGB definition. + /// These value is depend on the random choice and eighter a next random color or a certain color. + /// \return a vector of values + std::vector getColor() const; + +private: + QButtonGroup* myButtonGroup; /// a group, contained random and certain color radio button choice + QtxColorButton* myColorButton; /// a control to select a color +}; + +#endif diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 8280cb14d..b32a80bbc 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -11,6 +11,7 @@ #include "XGUI_SalomeConnector.h" #include "XGUI_ActionsMgr.h" #include "XGUI_ErrorDialog.h" +#include "XGUI_ColorDialog.h" #include "XGUI_ViewerProxy.h" #include "XGUI_PropertyPanel.h" #include "XGUI_ContextMenuMgr.h" @@ -78,10 +79,6 @@ #include #include #include -#include -#include -#include -#include #ifdef _DEBUG #include @@ -1525,21 +1522,64 @@ bool XGUI_Workshop::canChangeColor() const aTypes.insert(ModelAPI_ResultGroup::group()); aTypes.insert(ModelAPI_ResultConstruction::group()); aTypes.insert(ModelAPI_ResultBody::group()); + aTypes.insert(ModelAPI_ResultPart::group()); + return hasResults(aObjects, aTypes); } +void setColor(ResultPtr theResult, std::vector& theColor) +{ + if (!theResult.get()) + return; + + AttributeIntArrayPtr aColorAttr = theResult->data()->intArray(ModelAPI_Result::COLOR_ID()); + if (aColorAttr.get() != NULL) { + if (!aColorAttr->size()) { + aColorAttr->setSize(3); + } + aColorAttr->setValue(0, theColor[0]); + aColorAttr->setValue(1, theColor[1]); + aColorAttr->setValue(2, theColor[2]); + } +} + //************************************************************** -#include -#include -#include void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) { + AttributeIntArrayPtr aColorAttr; + // 1. find the current color of the object. This is a color of AIS presentation + // The objects are iterated until a first valid color is found std::vector aColor; foreach(ObjectPtr anObject, theObjects) { - - AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject); - aColor.resize(3); - anAISObj->getColor(aColor[0], aColor[1], aColor[2]); + if (anObject->groupName() == ModelAPI_ResultPart::group()) { + ResultPartPtr aPart = std::dynamic_pointer_cast(anObject); + DocumentPtr aPartDoc = aPart->partDoc(); + // the document should be checked on null, because in opened document if the part + // has not been activated yet, the part document is empty + if (!aPartDoc.get()) { + emit errorOccurred(QString::fromLatin1("Color can not be changed on a part with an empty document")); + } + else { + if (aPartDoc->size(ModelAPI_ResultBody::group()) > 0) { + ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultBody::group(), 0); + ResultBodyPtr aBody = std::dynamic_pointer_cast(aObject); + if (aBody.get()) { + std::string aSection, aName, aDefault; + aBody->colorConfigInfo(aSection, aName, aDefault); + if (!aSection.empty() && !aName.empty()) { + aColor = Config_PropManager::color(aSection, aName, aDefault); + } + } + } + } + } + else { + AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject); + if (anAISObj.get()) { + aColor.resize(3); + anAISObj->getColor(aColor[0], aColor[1], aColor[2]); + } + } if (!aColor.empty()) break; } @@ -1547,69 +1587,44 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) return; // 2. show the dialog to change the value - QDialog* aDlg = new QDialog(); - aDlg->setWindowTitle("Color"); - QGridLayout* aLay = new QGridLayout(aDlg); - - QRadioButton* aRandomChoiceBtn = new QRadioButton(aDlg); - QRadioButton* aColorChoiceBtn = new QRadioButton(aDlg); - aColorChoiceBtn->setChecked(true); - QButtonGroup* aGroup = new QButtonGroup(aDlg); - aGroup->setExclusive(true); - aGroup->addButton(aColorChoiceBtn); - aGroup->addButton(aRandomChoiceBtn); - - aLay->addWidget(aColorChoiceBtn, 0, 0); - aLay->addWidget(aRandomChoiceBtn, 1, 0); - - QtxColorButton* aColorBtn = new QtxColorButton(aDlg); - aColorBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - aLay->addWidget(aColorBtn, 0, 1); - aColorBtn->setColor(QColor(aColor[0], aColor[1], aColor[2])); - - QLabel* aRandomLabel = new QLabel("Random", aDlg); - aLay->addWidget(aRandomLabel, 1, 1); - - QDialogButtonBox* aButtons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, - Qt::Horizontal, aDlg); - connect(aButtons, SIGNAL(accepted()), aDlg, SLOT(accept())); - connect(aButtons, SIGNAL(rejected()), aDlg, SLOT(reject())); - aLay->addWidget(aButtons, 2, 0, 1, 2); - + XGUI_ColorDialog* aDlg = new XGUI_ColorDialog(mainWindow()); + aDlg->setColor(aColor); aDlg->move(QCursor::pos()); bool isDone = aDlg->exec() == QDialog::Accepted; if (!isDone) return; - QColor aColorResult = aColorBtn->color(); - int aRedResult = aColorResult.red(), - aGreenResult = aColorResult.green(), - aBlueResult = aColorResult.blue(); - - if (aRedResult == aColor[0] && aGreenResult == aColor[1] && aBlueResult == aColor[2]) - return; + bool isRandomColor = aDlg->isRandomColor(); // 3. abort the previous operation and start a new one SessionPtr aMgr = ModelAPI_Session::get(); bool aWasOperation = aMgr->isOperation(); // keep this value if (!aWasOperation) { - QString aDescription = contextMenuMgr()->action("DELETE_CMD")->text(); + QString aDescription = contextMenuMgr()->action("COLOR_CMD")->text(); aMgr->startOperation(aDescription.toStdString()); } // 4. set the value to all results - AttributeIntArrayPtr aColorAttr; foreach(ObjectPtr anObj, theObjects) { ResultPtr aResult = std::dynamic_pointer_cast(anObj); if (aResult.get() != NULL) { - aColorAttr = aResult->data()->intArray(ModelAPI_Result::COLOR_ID()); - if (aColorAttr.get() != NULL) { - if (!aColorAttr->size()) { - aColorAttr->setSize(3); + if (aResult->groupName() == ModelAPI_ResultPart::group()) { + ResultPartPtr aPart = std::dynamic_pointer_cast(aResult); + DocumentPtr aPartDoc = aPart->partDoc(); + // the document should be checked on null, because in opened document if the part + // has not been activated yet, the part document is empty + if (aPartDoc.get()) { + for (int i = 0; i < aPartDoc->size(ModelAPI_ResultBody::group()); i++) { + ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultBody::group(), i); + ResultBodyPtr aBody = std::dynamic_pointer_cast(aObject); + std::vector aColorResult = aDlg->getColor(); + setColor(aBody, aColorResult); + } } - aColorAttr->setValue(0, aRedResult); - aColorAttr->setValue(1, aGreenResult); - aColorAttr->setValue(2, aBlueResult); + } + else { + std::vector aColorResult = aDlg->getColor(); + setColor(aResult, aColorResult); } } } -- 2.39.2