From d64bf15f8a8fba24b3c94d5c9045a8f7595ae894 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 30 Jun 2024 22:32:44 +0200 Subject: [PATCH] Core: Update color bar when changing preferences This solves one part of issue #10717 --- src/Gui/CMakeLists.txt | 2 + src/Gui/SoFCColorBar.cpp | 22 ++++++ src/Gui/SoFCColorBar.h | 18 +++++ src/Gui/SoFCColorBarNotifier.cpp | 74 +++++++++++++++++++ src/Gui/SoFCColorBarNotifier.h | 56 ++++++++++++++ src/Gui/SoFCColorGradient.cpp | 28 +++++-- src/Gui/SoFCColorGradient.h | 1 + src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp | 3 + .../Inspection/Gui/ViewProviderInspection.cpp | 3 + src/Mod/Mesh/Gui/ViewProviderCurvature.cpp | 3 + 10 files changed, 202 insertions(+), 8 deletions(-) create mode 100644 src/Gui/SoFCColorBarNotifier.cpp create mode 100644 src/Gui/SoFCColorBarNotifier.h diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index e02bd98546..f68985438e 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -1012,6 +1012,7 @@ SET(Inventor_CPP_SRCS SoFCBackgroundGradient.cpp SoFCBoundingBox.cpp SoFCColorBar.cpp + SoFCColorBarNotifier.cpp SoFCColorGradient.cpp SoFCColorLegend.cpp SoFCDB.cpp @@ -1042,6 +1043,7 @@ SET(Inventor_SRCS SoFCBackgroundGradient.h SoFCBoundingBox.h SoFCColorBar.h + SoFCColorBarNotifier.h SoFCColorGradient.h SoFCColorLegend.h SoFCDB.h diff --git a/src/Gui/SoFCColorBar.cpp b/src/Gui/SoFCColorBar.cpp index ff36dabf2d..7ab1f6ebd3 100644 --- a/src/Gui/SoFCColorBar.cpp +++ b/src/Gui/SoFCColorBar.cpp @@ -83,6 +83,22 @@ void SoFCColorBarBase::setModified() _boxWidth = -1.0f; } +void SoFCColorBarBase::setFormat(const SoLabelTextFormat& fmt) +{ + format = fmt; + applyFormat(fmt); +} + +SoLabelTextFormat SoFCColorBarBase::getFormat() const +{ + return format; +} + +void SoFCColorBarBase::applyFormat(const SoLabelTextFormat& fmt) +{ + boost::ignore_unused(fmt); +} + float SoFCColorBarBase::getBoundingWidth(const SbVec2s& size) { float fRatio = static_cast(size[0]) / static_cast(size[1]); @@ -222,6 +238,12 @@ SoFCColorBarBase* SoFCColorBar::getActiveBar() const return _colorBars[child]; } +void SoFCColorBar::setFormat(const SoLabelTextFormat& fmt) +{ + for (auto it : _colorBars) + it->setFormat(fmt); +} + void SoFCColorBar::setViewportSize( const SbVec2s& size ) { boost::ignore_unused(size); diff --git a/src/Gui/SoFCColorBar.h b/src/Gui/SoFCColorBar.h index 5ad7acadfc..c6b1fc5235 100644 --- a/src/Gui/SoFCColorBar.h +++ b/src/Gui/SoFCColorBar.h @@ -41,6 +41,14 @@ class SoGLRenderAction; namespace Gui { class SoFCColorGradient; +struct SoLabelTextFormat +{ + // NOLINTBEGIN + int textSize = 13; + uint32_t textColor = 0xffffffff; + // NOLINTEND +}; + /** * The abstract color bar base class to get most important information on how to convert a scalar to an RGB color. * @author Werner Mayer @@ -110,8 +118,16 @@ public: * This method must be implemented in subclasses. */ virtual const char* getColorBarName() const = 0; + /** Sets the format for the label text. + */ + virtual void setFormat(const SoLabelTextFormat& fmt); + /** Returns the format for the label text. + */ + SoLabelTextFormat getFormat() const; protected: + /** Applies the format to the label text */ + virtual void applyFormat(const SoLabelTextFormat& fmt); /** Computes the dimensions of the color bar and labels in coordinates with * respect to the defined height of the camera. * Returns the width of the bounding box @@ -140,6 +156,7 @@ protected: private: float _boxWidth{-1.0F}; SbVec2s _windowSize; + SoLabelTextFormat format; }; // -------------------------------------------------------------------------- @@ -202,6 +219,7 @@ public: /** Returns the name of the color bar. */ const char* getColorBarName() const override { return "Color Bar"; } + void setFormat(const SoLabelTextFormat& fmt) override; protected: /** diff --git a/src/Gui/SoFCColorBarNotifier.cpp b/src/Gui/SoFCColorBarNotifier.cpp new file mode 100644 index 0000000000..92d955ce36 --- /dev/null +++ b/src/Gui/SoFCColorBarNotifier.cpp @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/*************************************************************************** + * Copyright (c) 2024 Werner Mayer * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + **************************************************************************/ + +#include "PreCompiled.h" + +#include "SoFCColorBarNotifier.h" +#include "SoFCColorBar.h" +#include "Window.h" + +using namespace Gui; + +SoFCColorBarNotifier& SoFCColorBarNotifier::instance() +{ + static SoFCColorBarNotifier instance; + return instance; +} + +SoFCColorBarNotifier::SoFCColorBarNotifier() +{ + group = Gui::WindowParameter::getDefaultParameter()->GetGroup("View"); + group->Attach(this); +} + +void SoFCColorBarNotifier::attach(SoFCColorBarBase* bar) +{ + if (bars.insert(bar).second) { + bar->ref(); + group->Notify("CbLabelTextSize"); + } +} + +void SoFCColorBarNotifier::detach(SoFCColorBarBase* bar) +{ + auto pos = bars.find(bar); + if (pos != bars.end()) { + bars.erase(pos); + bar->unref(); + } +} + +void SoFCColorBarNotifier::OnChange(ParameterGrp::SubjectType& caller, + ParameterGrp::MessageType reason) +{ + const ParameterGrp& grp = dynamic_cast(caller); + if (strcmp(reason, "CbLabelTextSize") == 0 || strcmp(reason, "CbLabelColor") == 0) { + SoLabelTextFormat format; + format.textSize = static_cast(grp.GetInt("CbLabelTextSize", format.textSize)); + format.textColor = static_cast(grp.GetUnsigned("CbLabelColor", format.textColor)); + + for (auto bar : bars) { + bar->setFormat(format); + } + } +} diff --git a/src/Gui/SoFCColorBarNotifier.h b/src/Gui/SoFCColorBarNotifier.h new file mode 100644 index 0000000000..6725b1ac5f --- /dev/null +++ b/src/Gui/SoFCColorBarNotifier.h @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/*************************************************************************** + * Copyright (c) 2024 Werner Mayer * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + **************************************************************************/ + +#ifndef GUI_SOFCCOLORBARNOTIFIER_H +#define GUI_SOFCCOLORBARNOTIFIER_H + +#include +#include + +namespace Gui { + +class SoFCColorBarBase; + +class GuiExport SoFCColorBarNotifier: public ParameterGrp::ObserverType // NOLINT +{ +public: + static SoFCColorBarNotifier& instance(); + void attach(SoFCColorBarBase* bar); + void detach(SoFCColorBarBase* bar); + void OnChange(ParameterGrp::SubjectType& caller, ParameterGrp::MessageType reason) override; + +private: + SoFCColorBarNotifier(); + ~SoFCColorBarNotifier() override = default; + + FC_DISABLE_COPY_MOVE(SoFCColorBarNotifier) + +private: + std::set bars; + ParameterGrp::handle group; +}; + +} // namespace Gui + + +#endif // GUI_SOFCCOLORBARNOTIFIER_H diff --git a/src/Gui/SoFCColorGradient.cpp b/src/Gui/SoFCColorGradient.cpp index 92f551b6a7..e0f4ee8321 100644 --- a/src/Gui/SoFCColorGradient.cpp +++ b/src/Gui/SoFCColorGradient.cpp @@ -53,8 +53,6 @@ constexpr const float yMin = -4.0F; constexpr const float yMax = 4.0F; constexpr const float spaceX = 0.1F; constexpr const float spaceY = 0.05F; -constexpr const int defaultNumLabels = 13; -constexpr const unsigned long defaultColor = 0xffffffff; constexpr const float defaultMin = -0.5F; constexpr const float defaultMax = 0.5F; constexpr const float upperLimit = 10000.0F; @@ -105,6 +103,22 @@ const char* SoFCColorGradient::getColorBarName() const return QT_TRANSLATE_NOOP("QObject", "Color Gradient"); } +void SoFCColorGradient::applyFormat(const SoLabelTextFormat& fmt) +{ + auto textColor = App::Color(fmt.textColor); + + for (int j = 0; j < labels->getNumChildren(); j++) { + if (labels->getChild(j)->getTypeId() == SoBaseColor::getClassTypeId()) { + auto baseColor = static_cast(labels->getChild(j)); // NOLINT + baseColor->rgb.setValue(textColor.r, textColor.g, textColor.b); + } + else if (labels->getChild(j)->getTypeId() == SoFont::getClassTypeId()) { + auto font = static_cast(labels->getChild(j)); // NOLINT + font->size.setValue(static_cast(fmt.textSize)); + } + } +} + void SoFCColorGradient::setMarkerLabel(const SoMFString& label) { coinRemoveAllChildren(labels); @@ -116,16 +130,14 @@ void SoFCColorGradient::setMarkerLabel(const SoMFString& label) float fStep = (maxPt[1] - minPt[1]) / ((float)num - 1); auto trans = new SoTransform; - ParameterGrp::handle hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("View"); - auto LabelTextSize = hGrp->GetInt("CbLabelTextSize", defaultNumLabels); - auto LabelTextColor = - App::Color((uint32_t)hGrp->GetUnsigned("CbLabelColor", defaultColor)); + SoLabelTextFormat fmt = getFormat(); + auto textColor = App::Color(fmt.textColor); auto textFont = new SoFont; auto color = new SoBaseColor; textFont->name.setValue("Helvetica,Arial,Times New Roman"); - textFont->size.setValue(static_cast(LabelTextSize)); + textFont->size.setValue(static_cast(fmt.textSize)); trans->translation.setValue(maxPt[0] + spaceX, maxPt[1] - spaceY + fStep, 0.0F); - color->rgb.setValue(LabelTextColor.r, LabelTextColor.g, LabelTextColor.b); + color->rgb.setValue(textColor.r, textColor.g, textColor.b); labels->addChild(trans); labels->addChild(color); labels->addChild(textFont); diff --git a/src/Gui/SoFCColorGradient.h b/src/Gui/SoFCColorGradient.h index d55daf11e2..4d5ffd3240 100644 --- a/src/Gui/SoFCColorGradient.h +++ b/src/Gui/SoFCColorGradient.h @@ -78,6 +78,7 @@ public: const char* getColorBarName() const override; protected: + void applyFormat(const SoLabelTextFormat& fmt) override; /** * Sets the current viewer size this color gradient is embedded into, to recalculate its new position. */ diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp index 5cb8638f62..55aded5af5 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -232,6 +233,7 @@ ViewProviderFemPostObject::ViewProviderFemPostObject() m_colorRoot->addChild(m_colorStyle); m_colorBar = new Gui::SoFCColorBar; m_colorBar->Attach(this); + Gui::SoFCColorBarNotifier::instance().attach(m_colorBar); m_colorBar->ref(); // create the vtk algorithms we use for visualisation @@ -274,6 +276,7 @@ ViewProviderFemPostObject::~ViewProviderFemPostObject() m_material->unref(); m_matPlainEdges->unref(); m_switchMatEdges->unref(); + Gui::SoFCColorBarNotifier::instance().detach(m_colorBar); m_colorBar->Detach(this); m_colorBar->unref(); m_colorStyle->unref(); diff --git a/src/Mod/Inspection/Gui/ViewProviderInspection.cpp b/src/Mod/Inspection/Gui/ViewProviderInspection.cpp index bb02d337dc..17ab772a10 100644 --- a/src/Mod/Inspection/Gui/ViewProviderInspection.cpp +++ b/src/Mod/Inspection/Gui/ViewProviderInspection.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,7 @@ ViewProviderInspection::ViewProviderInspection() // simple color bar pcColorBar = new Gui::SoFCColorBar; pcColorBar->Attach(this); + Gui::SoFCColorBarNotifier::instance().attach(pcColorBar); pcColorBar->ref(); pcColorBar->setRange(-0.1f, 0.1f, 3); pcLinkRoot = new SoGroup; @@ -113,6 +115,7 @@ ViewProviderInspection::~ViewProviderInspection() pcCoords->unref(); pcMatBinding->unref(); pcColorMat->unref(); + Gui::SoFCColorBarNotifier::instance().detach(pcColorBar); pcColorBar->Detach(this); pcColorBar->unref(); pcLinkRoot->unref(); diff --git a/src/Mod/Mesh/Gui/ViewProviderCurvature.cpp b/src/Mod/Mesh/Gui/ViewProviderCurvature.cpp index eb568e88e1..989a39f7db 100644 --- a/src/Mod/Mesh/Gui/ViewProviderCurvature.cpp +++ b/src/Mod/Mesh/Gui/ViewProviderCurvature.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,7 @@ ViewProviderMeshCurvature::ViewProviderMeshCurvature() // simple color bar pcColorBar = new Gui::SoFCColorBar; pcColorBar->Attach(this); + Gui::SoFCColorBarNotifier::instance().attach(pcColorBar); pcColorBar->ref(); pcColorBar->setRange(-0.5f, 0.5f, 3); pcLinkRoot = new SoGroup; @@ -124,6 +126,7 @@ ViewProviderMeshCurvature::~ViewProviderMeshCurvature() { pcColorRoot->unref(); pcColorMat->unref(); + Gui::SoFCColorBarNotifier::instance().detach(pcColorBar); pcColorBar->Detach(this); pcColorBar->unref(); pcLinkRoot->unref();