diff --git a/src/App/ColorModel.cpp b/src/App/ColorModel.cpp index 15625fbf3b..37daf807a6 100644 --- a/src/App/ColorModel.cpp +++ b/src/App/ColorModel.cpp @@ -168,20 +168,45 @@ void ColorField::interpolate (Color clCol1, std::size_t usInd1, Color clCol2, st } +ColorGradientProfile::ColorGradientProfile() + : tStyle{ColorBarStyle::FLOW} + , fMin{} + , fMax{} + , ctColors{} + , tColorModel{} + , visibility{Visibility::Default} +{ + +} + +bool ColorGradientProfile::isEqual(const ColorGradientProfile& cg) const +{ + if (tStyle != cg.tStyle) + return false; + if (fMin != cg.fMin) + return false; + if (fMax != cg.fMax) + return false; + if (visibility.testFlag(Visibility::Grayed) != + cg.visibility.testFlag(Visibility::Grayed)) + return false; + if (visibility.testFlag(Visibility::Invisible) != + cg.visibility.testFlag(Visibility::Invisible)) + return false; + if (tColorModel != cg.tColorModel) + return false; + return true; +} + + ColorGradient::ColorGradient () - : tStyle(ZERO_BASED) - , visibility(Visibility::Default) - , tColorModel(0) { createStandardPacks(); setColorModel(); - set(-1.0f, 1.0f, 13, ZERO_BASED, Visibility::Default); + set(-1.0f, 1.0f, 13, ColorBarStyle::ZERO_BASED, Visibility::Default); } -ColorGradient::ColorGradient (float fMin, float fMax, std::size_t usCtColors, TStyle tS, VisibilityFlags flags) - : tStyle(tS) - , visibility(Visibility::Default) - , tColorModel(0) +ColorGradient::ColorGradient (float fMin, float fMax, std::size_t usCtColors, ColorBarStyle tS, VisibilityFlags flags) { createStandardPacks(); setColorModel(); @@ -206,41 +231,48 @@ std::vector ColorGradient::getColorModelNames() const return names; } -void ColorGradient::set (float fMin, float fMax, std::size_t usCt, TStyle tS, VisibilityFlags flags) +void ColorGradient::setProfile(const ColorGradientProfile& pro) +{ + profile = pro; + setColorModel(); + rebuild(); +} + +void ColorGradient::set (float fMin, float fMax, std::size_t usCt, ColorBarStyle tS, VisibilityFlags flags) { auto bounds = std::minmax(fMin, fMax); if (bounds.second <= bounds.first) { throw Base::ValueError("Maximum must be higher than minimum"); } - _fMin = bounds.first; - _fMax = bounds.second; - ctColors = std::max(usCt, getMinColors()); - tStyle = tS; - visibility = flags; + profile.fMin = bounds.first; + profile.fMax = bounds.second; + profile.ctColors = std::max(usCt, getMinColors()); + profile.tStyle = tS; + profile.visibility = flags; rebuild(); } void ColorGradient::rebuild () { - switch (tStyle) + switch (profile.tStyle) { - case FLOW: + case ColorBarStyle::FLOW: { - colorField1.set(currentModelPack.totalModel, _fMin, _fMax, ctColors); + colorField1.set(currentModelPack.totalModel, profile.fMin, profile.fMax, profile.ctColors); break; } - case ZERO_BASED: + case ColorBarStyle::ZERO_BASED: { - if ((_fMin < 0.0f) && (_fMax > 0.0f)) + if ((profile.fMin < 0.0f) && (profile.fMax > 0.0f)) { - colorField1.set(currentModelPack.bottomModel, _fMin, 0.0f, ctColors / 2); - colorField2.set(currentModelPack.topModel, 0.0f, _fMax, ctColors / 2); + colorField1.set(currentModelPack.bottomModel, profile.fMin, 0.0f, profile.ctColors / 2); + colorField2.set(currentModelPack.topModel, 0.0f, profile.fMax, profile.ctColors / 2); } - else if (_fMin >= 0.0f) - colorField1.set(currentModelPack.topModel, 0.0f, _fMax, ctColors); + else if (profile.fMin >= 0.0f) + colorField1.set(currentModelPack.topModel, 0.0f, profile.fMax, profile.ctColors); else - colorField1.set(currentModelPack.bottomModel, _fMin, 0.0f, ctColors); + colorField1.set(currentModelPack.bottomModel, profile.fMin, 0.0f, profile.ctColors); break; } } @@ -248,13 +280,13 @@ void ColorGradient::rebuild () std::size_t ColorGradient::getMinColors () const { - switch (tStyle) + switch (profile.tStyle) { - case FLOW: - return colorField1.getMinColors(); - case ZERO_BASED: + case ColorBarStyle::FLOW: + return colorField1.getMinColors(); + case ColorBarStyle::ZERO_BASED: { - if ((_fMin < 0.0f) && (_fMax > 0.0f)) + if ((profile.fMin < 0.0f) && (profile.fMax > 0.0f)) return colorField1.getMinColors() + colorField2.getMinColors(); else return colorField1.getMinColors(); @@ -265,25 +297,25 @@ std::size_t ColorGradient::getMinColors () const void ColorGradient::setColorModel (std::size_t tModel) { - tColorModel = tModel; + profile.tColorModel = tModel; setColorModel(); rebuild(); } void ColorGradient::setColorModel () { - if (tColorModel < modelPacks.size()) - currentModelPack = modelPacks[tColorModel]; + if (profile.tColorModel < modelPacks.size()) + currentModelPack = modelPacks[profile.tColorModel]; - switch (tStyle) + switch (profile.tStyle) { - case FLOW: + case ColorBarStyle::FLOW: { colorField1.setColorModel(currentModelPack.totalModel); colorField2.setColorModel(currentModelPack.bottomModel); break; } - case ZERO_BASED: + case ColorBarStyle::ZERO_BASED: { colorField1.setColorModel(currentModelPack.topModel); colorField2.setColorModel(currentModelPack.bottomModel); diff --git a/src/App/ColorModel.h b/src/App/ColorModel.h index f4f151241b..4942d1d3a2 100644 --- a/src/App/ColorModel.h +++ b/src/App/ColorModel.h @@ -44,6 +44,11 @@ enum class Visibility { using VisibilityFlags = Base::Flags; +enum class ColorBarStyle { + FLOW, + ZERO_BASED +}; + } ENABLE_BITMASK_OPERATORS(App::Visibility) @@ -335,63 +340,81 @@ inline std::size_t ColorField::getColorIndex (float fVal) const return std::size_t(std::min(std::max(int(fConstant + fAscent * fVal), 0), int(ctColors - 1))); } +struct AppExport ColorGradientProfile +{ + ColorBarStyle tStyle; + float fMin; + float fMax; + std::size_t ctColors; + std::size_t tColorModel; + VisibilityFlags visibility; + + ColorGradientProfile(); + ColorGradientProfile (const ColorGradientProfile &) = default; + ColorGradientProfile& operator = (const ColorGradientProfile &) = default; + + bool isEqual(const ColorGradientProfile&) const; +}; class AppExport ColorGradient { public: - enum TStyle { FLOW, ZERO_BASED }; - ColorGradient (); - ColorGradient (float fMin, float fMax, std::size_t usCtColors, TStyle tS, VisibilityFlags fl = Visibility::Default); + ColorGradient (float fMin, float fMax, std::size_t usCtColors, ColorBarStyle tS, VisibilityFlags fl = Visibility::Default); ColorGradient (const ColorGradient &) = default; ColorGradient& operator = (const ColorGradient &) = default; + const ColorGradientProfile& getProfile() const { + return profile; + } + void setProfile(const ColorGradientProfile& pro); - void set (float fMin, float fMax, std::size_t usCt, TStyle tS, VisibilityFlags fl); + void set (float fMin, float fMax, std::size_t usCt, ColorBarStyle tS, VisibilityFlags fl); void setRange (float fMin, float fMax) { - set(fMin, fMax, ctColors, tStyle, visibility); + set(fMin, fMax, profile.ctColors, profile.tStyle, profile.visibility); } void getRange (float &rfMin, float &rfMax) const { - rfMin = _fMin; rfMax = _fMax; + rfMin = profile.fMin; + rfMax = profile.fMax; } bool isOutOfRange(float fVal) const { - return ((fVal < _fMin) || (fVal > _fMax)); + return ((fVal < profile.fMin) || (fVal > profile.fMax)); } std::size_t getCountColors () const { - return ctColors; + return profile.ctColors; } void setCountColors (std::size_t usCt) { - set(_fMin, _fMax, usCt, tStyle, visibility); + set(profile.fMin, profile.fMax, usCt, profile.tStyle, profile.visibility); } - void setStyle (TStyle tS) { - set(_fMin, _fMax, ctColors, tS, visibility); + void setStyle (ColorBarStyle tS) { + set(profile.fMin, profile.fMax, profile.ctColors, tS, profile.visibility); } std::size_t getMinColors () const; - TStyle getStyle () const { - return tStyle; + ColorBarStyle getStyle () const { + return profile.tStyle; } void setOutsideGrayed (bool value) { - visibility.setFlag(Visibility::Grayed, value); + profile.visibility.setFlag(Visibility::Grayed, value); } bool isOutsideGrayed () const { - return visibility.testFlag(Visibility::Grayed); + return profile.visibility.testFlag(Visibility::Grayed); } void setOutsideInvisible (bool value) { - visibility.setFlag(Visibility::Invisible, value); + profile.visibility.setFlag(Visibility::Invisible, value); } bool isOutsideInvisible () const { - return visibility.testFlag(Visibility::Invisible); + return profile.visibility.testFlag(Visibility::Invisible); } void setColorModel (std::size_t tModel); std::size_t getColorModelType () const { - return tColorModel; + return profile.tColorModel; } inline const ColorModel& getColorModel () const; std::vector getColorModelNames() const; float getMinValue () const { - return _fMin; + return profile.fMin; } float getMaxValue () const { - return _fMax; + return profile.fMax; } inline Color getColor (float fVal) const; @@ -404,12 +427,8 @@ protected: void createStandardPacks(); protected: + ColorGradientProfile profile; ColorField colorField1, colorField2; - TStyle tStyle; - float _fMin, _fMax; - std::size_t ctColors; - VisibilityFlags visibility; - std::size_t tColorModel; ColorModelPack currentModelPack; std::vector modelPacks; @@ -535,10 +554,10 @@ inline Color ColorGradient::_getColor (float fVal) const return Color(0.5f, 0.5f, 0.5f); } - switch (tStyle) { - case ZERO_BASED: + switch (profile.tStyle) { + case ColorBarStyle::ZERO_BASED: { - if ((_fMin < 0.0f) && (_fMax > 0.0f)) { + if ((profile.fMin < 0.0f) && (profile.fMax > 0.0f)) { if (fVal < 0.0f) return colorField1.getColor(fVal); else @@ -550,7 +569,7 @@ inline Color ColorGradient::_getColor (float fVal) const } default: - case FLOW: + case ColorBarStyle::FLOW: { return colorField1.getColor(fVal); } @@ -559,10 +578,10 @@ inline Color ColorGradient::_getColor (float fVal) const inline std::size_t ColorGradient::getColorIndex (float fVal) const { - switch (tStyle) { - case ZERO_BASED: + switch (profile.tStyle) { + case ColorBarStyle::ZERO_BASED: { - if ((_fMin < 0.0f) && (_fMax > 0.0f)) { + if ((profile.fMin < 0.0f) && (profile.fMax > 0.0f)) { if (fVal < 0.0f) return colorField1.getColorIndex(fVal); else @@ -574,7 +593,7 @@ inline std::size_t ColorGradient::getColorIndex (float fVal) const } default: - case FLOW: + case ColorBarStyle::FLOW: { return colorField1.getColorIndex(fVal); } @@ -583,10 +602,10 @@ inline std::size_t ColorGradient::getColorIndex (float fVal) const inline const ColorModel& ColorGradient::getColorModel () const { - if (tStyle == ZERO_BASED) { - if (_fMax <= 0.0f) + if (profile.tStyle == ColorBarStyle::ZERO_BASED) { + if (profile.fMax <= 0.0f) return currentModelPack.bottomModel; - else if ( _fMin >= 0.0f ) + else if ( profile.fMin >= 0.0f ) return currentModelPack.topModel; else return currentModelPack.totalModel; diff --git a/src/Gui/DlgSettingsColorGradientImp.cpp b/src/Gui/DlgSettingsColorGradientImp.cpp index 2226b2eefa..30f6bbb71e 100644 --- a/src/Gui/DlgSettingsColorGradientImp.cpp +++ b/src/Gui/DlgSettingsColorGradientImp.cpp @@ -69,6 +69,28 @@ DlgSettingsColorGradientImp::~DlgSettingsColorGradientImp() // no need to delete child widgets, Qt does it all for us } +App::ColorGradientProfile DlgSettingsColorGradientImp::getProfile() const +{ + App::ColorGradientProfile profile; + profile.tColorModel = colorModel(); + profile.tStyle = colorStyle(); + profile.visibility.setFlag(App::Visibility::Grayed, isOutGrayed()); + profile.visibility.setFlag(App::Visibility::Invisible, isOutInvisible()); + profile.ctColors = numberOfLabels(); + getRange(profile.fMin, profile.fMax); + return profile; +} + +void DlgSettingsColorGradientImp::setProfile(const App::ColorGradientProfile& pro) +{ + setColorModel(pro.tColorModel); + setColorStyle(pro.tStyle); + setOutGrayed(pro.visibility.testFlag(App::Visibility::Grayed)); + setOutInvisible(pro.visibility.testFlag(App::Visibility::Invisible)); + setNumberOfLabels(pro.ctColors); + setRange(pro.fMin, pro.fMax); +} + void DlgSettingsColorGradientImp::setColorModel(std::size_t index) { ui->comboBoxModel->setCurrentIndex(index); @@ -87,22 +109,23 @@ void DlgSettingsColorGradientImp::setColorModelNames(const std::vectorradioButtonFlow->setChecked(true); break; - case App::ColorGradient::ZERO_BASED: + case App::ColorBarStyle::ZERO_BASED: ui->radioButtonZero->setChecked(true); break; } } -App::ColorGradient::TStyle DlgSettingsColorGradientImp::colorStyle() const +App::ColorBarStyle DlgSettingsColorGradientImp::colorStyle() const { - return ui->radioButtonZero->isChecked() ? App::ColorGradient::ZERO_BASED : App::ColorGradient::FLOW; + return ui->radioButtonZero->isChecked() ? App::ColorBarStyle::ZERO_BASED + : App::ColorBarStyle::FLOW; } void DlgSettingsColorGradientImp::setOutGrayed( bool grayed ) @@ -125,7 +148,7 @@ bool DlgSettingsColorGradientImp::isOutInvisible() const return ui->checkBoxInvisible->isChecked(); } -void DlgSettingsColorGradientImp::setRange( float fMin, float fMax ) +void DlgSettingsColorGradientImp::setRange(float fMin, float fMax) { ui->floatLineEditMax->blockSignals(true); ui->floatLineEditMax->setText(QLocale().toString(fMax, 'g', numberOfDecimals())); diff --git a/src/Gui/DlgSettingsColorGradientImp.h b/src/Gui/DlgSettingsColorGradientImp.h index 0b376e525b..f4598ce4fc 100644 --- a/src/Gui/DlgSettingsColorGradientImp.h +++ b/src/Gui/DlgSettingsColorGradientImp.h @@ -44,21 +44,35 @@ class DlgSettingsColorGradientImp : public QDialog Q_OBJECT public: - DlgSettingsColorGradientImp( QWidget* parent = nullptr, Qt::WindowFlags fl = Qt::WindowFlags() ); + DlgSettingsColorGradientImp(QWidget* parent = nullptr, Qt::WindowFlags fl = Qt::WindowFlags()); ~DlgSettingsColorGradientImp(); void accept(); + /** @name Color profile */ + //@{ + App::ColorGradientProfile getProfile() const; + void setProfile(const App::ColorGradientProfile& pro); + //@} + /** @name Color model */ + //@{ + void setColorModelNames(const std::vector&); + //@} + /** @name Parameter range and scale */ + //@{ + void setNumberOfDecimals(int); + int numberOfDecimals() const; + //@} +private: /** @name Color model */ //@{ void setColorModel(std::size_t tModel); std::size_t colorModel() const; - void setColorModelNames(const std::vector&); //@} /** @name Color style */ //@{ - void setColorStyle( App::ColorGradient::TStyle tStyle ); - App::ColorGradient::TStyle colorStyle() const; + void setColorStyle( App::ColorBarStyle tStyle ); + App::ColorBarStyle colorStyle() const; //@} /** @name Display mode */ //@{ @@ -69,12 +83,10 @@ public: //@} /** @name Parameter range and scale */ //@{ - void setRange( float fMin, float fMax ); - void getRange( float& fMin, float& fMax) const; + void setRange(float fMin, float fMax); + void getRange(float& fMin, float& fMax) const; void setNumberOfLabels(int); int numberOfLabels() const; - void setNumberOfDecimals(int); - int numberOfDecimals() const; //@} private: diff --git a/src/Gui/SoFCColorGradient.cpp b/src/Gui/SoFCColorGradient.cpp index dafdf400a1..713e06f628 100644 --- a/src/Gui/SoFCColorGradient.cpp +++ b/src/Gui/SoFCColorGradient.cpp @@ -48,7 +48,7 @@ SO_NODE_SOURCE(SoFCColorGradient) /*! Constructor. */ -SoFCColorGradient::SoFCColorGradient() : _bbox(4.0f, -4.0f, 4.5f, 4.0f), _precision(3) +SoFCColorGradient::SoFCColorGradient() : _bbox(4.0f, -4.0f, 4.5f, 4.0f), _precision(5) { SO_NODE_CONSTRUCTOR(SoFCColorGradient); coords = new SoCoordinate3; @@ -56,7 +56,7 @@ SoFCColorGradient::SoFCColorGradient() : _bbox(4.0f, -4.0f, 4.5f, 4.0f), _precis labels = new SoSeparator; labels->ref(); - _cColGrad.setStyle(App::ColorGradient::FLOW); + _cColGrad.setStyle(App::ColorBarStyle::FLOW); setColorModel(0); setRange(-0.5f, 0.5f, 1); } @@ -181,7 +181,7 @@ std::vector SoFCColorGradient::getMarkerValues(float fMin, float fMax, in std::vector labels; // the middle of the bar is zero - if (fMin < 0.0f && fMax > 0.0f && _cColGrad.getStyle() == App::ColorGradient::ZERO_BASED) { + if (fMin < 0.0f && fMax > 0.0f && _cColGrad.getStyle() == App::ColorBarStyle::ZERO_BASED) { if (count % 2 == 0) count++; int half = count / 2; @@ -230,7 +230,7 @@ void SoFCColorGradient::setColorModel(std::size_t index) rebuildGradient(); } -void SoFCColorGradient::setColorStyle (App::ColorGradient::TStyle tStyle) +void SoFCColorGradient::setColorStyle (App::ColorBarStyle tStyle) { _cColGrad.setStyle( tStyle ); rebuildGradient(); @@ -298,32 +298,20 @@ void SoFCColorGradient::customize(SoFCColorBarBase* parentNode) { QWidget* parent = Gui::getMainWindow()->activeWindow(); Gui::Dialog::DlgSettingsColorGradientImp dlg(parent); - dlg.setColorModelNames(_cColGrad.getColorModelNames()); - dlg.setColorModel(_cColGrad.getColorModelType()); - dlg.setColorStyle(_cColGrad.getStyle()); - dlg.setOutGrayed(_cColGrad.isOutsideGrayed()); - dlg.setOutInvisible(_cColGrad.isOutsideInvisible()); - dlg.setNumberOfLabels(_cColGrad.getCountColors()); + App::ColorGradientProfile profile = _cColGrad.getProfile(); + dlg.setProfile(profile); dlg.setNumberOfDecimals(_precision); - float fMin, fMax; - _cColGrad.getRange(fMin, fMax); - dlg.setRange(fMin, fMax); QPoint pos(QCursor::pos()); pos += QPoint((int)(-1.1 * dlg.width()), (int)(-0.1 * dlg.height())); dlg.move( pos ); if (dlg.exec() == QDialog::Accepted) { - _cColGrad.setColorModel(dlg.colorModel()); - _cColGrad.setStyle(dlg.colorStyle()); - _cColGrad.setOutsideGrayed(dlg.isOutGrayed()); - _cColGrad.setOutsideInvisible(dlg.isOutInvisible()); - _cColGrad.setCountColors(dlg.numberOfLabels()); + App::ColorGradientProfile profileMod = dlg.getProfile(); + _cColGrad.setProfile(profileMod); _precision = dlg.numberOfDecimals(); - dlg.getRange(fMin, fMax); - int dec = dlg.numberOfDecimals(); - setRange(fMin, fMax, dec); + setRange(profileMod.fMin, profileMod.fMax, _precision); rebuildGradient(); triggerChange(parentNode); diff --git a/src/Gui/SoFCColorGradient.h b/src/Gui/SoFCColorGradient.h index 4163876858..fb1fe18584 100644 --- a/src/Gui/SoFCColorGradient.h +++ b/src/Gui/SoFCColorGradient.h @@ -88,7 +88,7 @@ protected: * Sets the color style of the underlying color gradient to \a tStyle. \a tStyle either can * be \c FLOW or \c ZERO_BASED */ - void setColorStyle (App::ColorGradient::TStyle tStyle); + void setColorStyle (App::ColorBarStyle tStyle); /** Rebuild the gradient bar. */ void rebuildGradient(); /** Returns a list of \a count labels within the ranhe [\a fMin, \a fMax]. */