From 414c803ff39f82594b7890986129ff0e2e1a58b2 Mon Sep 17 00:00:00 2001 From: xtemp09 Date: Sat, 1 Apr 2023 13:34:55 +0700 Subject: [PATCH] [GUI] Radial gradient implementation This commit implements radial gradient as background and adds the option to settings. It also renames "Color gradient" as "Linear gradient", keeping Linear gradient default. Internally, it remains unchanged for compatibility. Radio gradient is more suitable for CAD, since it gives a more balanced color distribution across the screen, improving visibility of model and sketches with a halo-like effect. --- src/Gui/DlgSettingsViewColor.cpp | 2 + src/Gui/DlgSettingsViewColor.ui | 59 +++++++++++++++---- .../PreferencePackTemplates/Window_Colors.cfg | 1 + .../FreeCAD Classic Colors.cfg | 1 + src/Gui/SoFCBackgroundGradient.cpp | 50 +++++++++++++++- src/Gui/SoFCBackgroundGradient.h | 7 ++- src/Gui/SplitView3DInventor.cpp | 11 ++-- src/Gui/View3DInventorViewer.cpp | 10 ++-- src/Gui/View3DInventorViewer.h | 6 +- src/Gui/View3DSettings.cpp | 9 +-- src/Gui/View3DViewerPy.cpp | 2 +- 11 files changed, 129 insertions(+), 29 deletions(-) diff --git a/src/Gui/DlgSettingsViewColor.cpp b/src/Gui/DlgSettingsViewColor.cpp index 90a3ce9ec6..ba017d9c0b 100644 --- a/src/Gui/DlgSettingsViewColor.cpp +++ b/src/Gui/DlgSettingsViewColor.cpp @@ -64,6 +64,7 @@ void DlgSettingsViewColor::saveSettings() ui->backgroundColorMid->onSave(); ui->radioButtonSimple->onSave(); ui->radioButtonGradient->onSave(); + ui->rbRadialGradient->onSave(); ui->checkMidColor->onSave(); ui->checkBoxPreselection->onSave(); ui->checkBoxSelection->onSave(); @@ -81,6 +82,7 @@ void DlgSettingsViewColor::loadSettings() ui->backgroundColorMid->onRestore(); ui->radioButtonSimple->onRestore(); ui->radioButtonGradient->onRestore(); + ui->rbRadialGradient->onRestore(); ui->checkMidColor->onRestore(); ui->checkBoxPreselection->onRestore(); ui->checkBoxSelection->onRestore(); diff --git a/src/Gui/DlgSettingsViewColor.ui b/src/Gui/DlgSettingsViewColor.ui index 75b851b83b..398205dcbe 100644 --- a/src/Gui/DlgSettingsViewColor.ui +++ b/src/Gui/DlgSettingsViewColor.ui @@ -267,7 +267,7 @@ Background will have selected color gradient - Color gradient + Linear gradient true @@ -314,17 +314,23 @@ - - - Qt::Horizontal + + + Background will have selected color gradient - - - 40 - 20 - + + Radial gradient - + + false + + + RadialGradient + + + View + + @@ -586,6 +592,7 @@ SelectionColor_Background radioButtonGradient backgroundColorFrom + rbRadialGradient backgroundColorTo checkMidColor backgroundColorMid @@ -688,6 +695,38 @@ + + rbRadialGradient + toggled(bool) + backgroundColorFrom + setEnabled(bool) + + + 110 + 309 + + + 310 + 311 + + + + + rbRadialGradient + toggled(bool) + backgroundColorTo + setEnabled(bool) + + + 77 + 309 + + + 310 + 338 + + + radioButtonSimple toggled(bool) diff --git a/src/Gui/PreferencePackTemplates/Window_Colors.cfg b/src/Gui/PreferencePackTemplates/Window_Colors.cfg index ddb0281427..9314b8c492 100644 --- a/src/Gui/PreferencePackTemplates/Window_Colors.cfg +++ b/src/Gui/PreferencePackTemplates/Window_Colors.cfg @@ -16,6 +16,7 @@ + diff --git a/src/Gui/PreferencePacks/FreeCAD Classic Colors/FreeCAD Classic Colors.cfg b/src/Gui/PreferencePacks/FreeCAD Classic Colors/FreeCAD Classic Colors.cfg index 4f63a13e16..969289ae8e 100644 --- a/src/Gui/PreferencePacks/FreeCAD Classic Colors/FreeCAD Classic Colors.cfg +++ b/src/Gui/PreferencePacks/FreeCAD Classic Colors/FreeCAD Classic Colors.cfg @@ -119,6 +119,7 @@ + diff --git a/src/Gui/SoFCBackgroundGradient.cpp b/src/Gui/SoFCBackgroundGradient.cpp index 4f40eb7140..3009d662f9 100644 --- a/src/Gui/SoFCBackgroundGradient.cpp +++ b/src/Gui/SoFCBackgroundGradient.cpp @@ -23,6 +23,11 @@ #include "PreCompiled.h" #ifndef _PreComp_ +#include +#ifdef FC_OS_WIN32 + #define _USE_MATH_DEFINES +#endif +#include #ifdef FC_OS_MACOSX #include #else @@ -32,6 +37,16 @@ #include "SoFCBackgroundGradient.h" +static const std::array big_circle = []{ + std::array result; int c = 0; + for (GLfloat i = 0; i < 2*M_PI; i += 2*M_PI / 32, c++){ + result[c][0] = M_SQRT2*cosf(i); result[c][1] = M_SQRT2*sinf(i); } + return result; }(); +static const std::array small_oval = []{ + std::array result; int c = 0; + for (GLfloat i = 0; i < 2*M_PI; i += 2*M_PI / 32, c++){ + result[c][0] = 0.3*M_SQRT2*cosf(i); result[c][1] = M_SQRT1_2*sinf(i); } + return result; }(); using namespace Gui; @@ -51,6 +66,7 @@ SoFCBackgroundGradient::SoFCBackgroundGradient() fCol.setValue(0.5f, 0.5f, 0.8f); tCol.setValue(0.7f, 0.7f, 0.9f); mCol.setValue(1.0f, 1.0f, 1.0f); + radial = false; } /*! @@ -80,6 +96,7 @@ void SoFCBackgroundGradient::GLRender (SoGLRenderAction * /*action*/) glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); + if(!radial){ // linear gradient glBegin(GL_TRIANGLE_STRIP); if (mCol[0] < 0) { glColor3f(fCol[0],fCol[1],fCol[2]); glVertex2f(-1, 1); @@ -99,6 +116,31 @@ void SoFCBackgroundGradient::GLRender (SoGLRenderAction * /*action*/) glColor3f(mCol[0],mCol[1],mCol[2]); glVertex2f( 1, 0); glColor3f(tCol[0],tCol[1],tCol[2]); glVertex2f( 1,-1); } + } else { // radial gradient + glBegin(GL_TRIANGLE_FAN); + glColor3f(fCol[0], fCol[1], fCol[2]); glVertex2f(0.0f, 0.0f); + + if (mCol[0] < 0) { // simple radial gradient + glColor3f(tCol[0], tCol[1], tCol[2]); + for (const GLfloat *vertex : big_circle) + glVertex2fv( vertex ); + glVertex2fv( big_circle.front() ); + } else { + glColor3f(mCol[0], mCol[1], mCol[2]); + for (const GLfloat *vertex : small_oval) + glVertex2fv( vertex ); + glVertex2fv( small_oval.front() ); + glEnd(); + + glBegin(GL_TRIANGLE_STRIP); + for (std::size_t i = 0; i < small_oval.size(); i++){ + glColor3f(mCol[0], mCol[1], mCol[2]); glVertex2fv( small_oval[i] ); + glColor3f(tCol[0], tCol[1], tCol[2]); glVertex2fv( big_circle[i] ); } + + glColor3f(mCol[0], mCol[1], mCol[2]); glVertex2fv( small_oval.front() ); + glColor3f(tCol[0], tCol[1], tCol[2]); glVertex2fv( big_circle.front() ); + } + } // end of radial gradient glEnd(); glPopAttrib(); @@ -109,18 +151,22 @@ void SoFCBackgroundGradient::GLRender (SoGLRenderAction * /*action*/) } void SoFCBackgroundGradient::setColorGradient(const SbColor& fromColor, - const SbColor& toColor) + const SbColor& toColor, + bool isRadial) { fCol = fromColor; tCol = toColor; mCol[0] = -1.0f; + radial = isRadial; } void SoFCBackgroundGradient::setColorGradient(const SbColor& fromColor, const SbColor& toColor, - const SbColor& midColor) + const SbColor& midColor, + bool isRadial) { fCol = fromColor; tCol = toColor; mCol = midColor; + radial = isRadial; } diff --git a/src/Gui/SoFCBackgroundGradient.h b/src/Gui/SoFCBackgroundGradient.h index 2ebd7de091..febc83516f 100644 --- a/src/Gui/SoFCBackgroundGradient.h +++ b/src/Gui/SoFCBackgroundGradient.h @@ -44,8 +44,11 @@ public: SoFCBackgroundGradient(); void GLRender (SoGLRenderAction *action); - void setColorGradient(const SbColor& fromColor, const SbColor& toColor); - void setColorGradient(const SbColor& fromColor, const SbColor& toColor, const SbColor& midColor); + void setColorGradient(const SbColor& fromColor, const SbColor& toColor, bool isRadial); + void setColorGradient(const SbColor& fromColor, const SbColor& toColor, const SbColor& midColor, bool isRadial); + +private: + bool radial; protected: virtual ~SoFCBackgroundGradient(); diff --git a/src/Gui/SplitView3DInventor.cpp b/src/Gui/SplitView3DInventor.cpp index 76a33b4f7b..ff52ed8b13 100644 --- a/src/Gui/SplitView3DInventor.cpp +++ b/src/Gui/SplitView3DInventor.cpp @@ -109,6 +109,7 @@ void AbstractSplitView::setupSettings() OnChange(*hGrp,"CornerCoordSystemSize"); OnChange(*hGrp,"UseAutoRotation"); OnChange(*hGrp,"Gradient"); + OnChange(*hGrp,"RadialGradient"); OnChange(*hGrp,"BackgroundColor"); OnChange(*hGrp,"BackgroundColor2"); OnChange(*hGrp,"BackgroundColor3"); @@ -263,9 +264,9 @@ void AbstractSplitView::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp for (std::vector::iterator it = _viewer.begin(); it != _viewer.end(); ++it) (*it)->setAnimationEnabled(rGrp.GetBool("UseAutoRotation",false)); } - else if (strcmp(Reason,"Gradient") == 0) { + else if ( strcmp(Reason,"Gradient") == 0 || strcmp(Reason, "RadialGradient") == 0 ) { for (std::vector::iterator it = _viewer.begin(); it != _viewer.end(); ++it) - (*it)->setGradientBackground((rGrp.GetBool("Gradient",true))); + (*it)->setGradientBackground(rGrp.GetBool("Gradient", true) || rGrp.GetBool("RadialGradient", true)); } else if (strcmp(Reason,"ShowFPS") == 0) { for (std::vector::iterator it = _viewer.begin(); it != _viewer.end(); ++it) @@ -305,9 +306,11 @@ void AbstractSplitView::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp for (std::vector::iterator it = _viewer.begin(); it != _viewer.end(); ++it) { (*it)->setBackgroundColor(QColor::fromRgbF(r1, g1, b1)); if (!rGrp.GetBool("UseBackgroundColorMid",false)) - (*it)->setGradientBackgroundColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3)); + (*it)->setGradientBackgroundColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3), + rGrp.GetBool("RadialGradient", false) ); else - (*it)->setGradientBackgroundColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3), SbColor(r4, g4, b4)); + (*it)->setGradientBackgroundColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3), SbColor(r4, g4, b4), + rGrp.GetBool("RadialGradient", false) ); } } } diff --git a/src/Gui/View3DInventorViewer.cpp b/src/Gui/View3DInventorViewer.cpp index 80fe8cbb3f..6bbf447709 100644 --- a/src/Gui/View3DInventorViewer.cpp +++ b/src/Gui/View3DInventorViewer.cpp @@ -1084,16 +1084,18 @@ bool View3DInventorViewer::hasGradientBackground() const } void View3DInventorViewer::setGradientBackgroundColor(const SbColor& fromColor, - const SbColor& toColor) + const SbColor& toColor, + bool isRadial) { - pcBackGround->setColorGradient(fromColor, toColor); + pcBackGround->setColorGradient(fromColor, toColor, isRadial); } void View3DInventorViewer::setGradientBackgroundColor(const SbColor& fromColor, const SbColor& toColor, - const SbColor& midColor) + const SbColor& midColor, + bool isRadial) { - pcBackGround->setColorGradient(fromColor, toColor, midColor); + pcBackGround->setColorGradient(fromColor, toColor, midColor, isRadial); } void View3DInventorViewer::setEnabledFPSCounter(bool on) diff --git a/src/Gui/View3DInventorViewer.h b/src/Gui/View3DInventorViewer.h index 27a30ca380..1d1e03a75c 100644 --- a/src/Gui/View3DInventorViewer.h +++ b/src/Gui/View3DInventorViewer.h @@ -373,10 +373,12 @@ public: void setGradientBackground(bool b); bool hasGradientBackground() const; void setGradientBackgroundColor(const SbColor& fromColor, - const SbColor& toColor); + const SbColor& toColor, + bool isRadial); void setGradientBackgroundColor(const SbColor& fromColor, const SbColor& toColor, - const SbColor& midColor); + const SbColor& midColor, + bool isRadial); void setNavigationType(Base::Type); void setAxisCross(bool b); diff --git a/src/Gui/View3DSettings.cpp b/src/Gui/View3DSettings.cpp index ed18471c95..f42f86f56c 100644 --- a/src/Gui/View3DSettings.cpp +++ b/src/Gui/View3DSettings.cpp @@ -68,6 +68,7 @@ void View3DSettings::applySettings() OnChange(*hGrp,"ShowAxisCross"); OnChange(*hGrp,"UseAutoRotation"); OnChange(*hGrp,"Gradient"); + OnChange(*hGrp,"RadialGradient"); OnChange(*hGrp,"BackgroundColor"); OnChange(*hGrp,"BackgroundColor2"); OnChange(*hGrp,"BackgroundColor3"); @@ -233,8 +234,8 @@ void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M else if (strcmp(Reason,"UseAutoRotation") == 0) { _viewer->setAnimationEnabled(rGrp.GetBool("UseAutoRotation", false)); } - else if (strcmp(Reason,"Gradient") == 0) { - _viewer->setGradientBackground((rGrp.GetBool("Gradient", true))); + else if (strcmp(Reason,"Gradient") == 0 || strcmp(Reason,"RadialGradient") == 0) { + _viewer->setGradientBackground(rGrp.GetBool("Gradient", true) || rGrp.GetBool("RadialGradient", true)); } else if (strcmp(Reason,"ShowFPS") == 0) { _viewer->setEnabledFPSCounter(rGrp.GetBool("ShowFPS", false)); @@ -299,9 +300,9 @@ void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M r4 = ((col4 >> 24) & 0xff) / 255.0; g4 = ((col4 >> 16) & 0xff) / 255.0; b4 = ((col4 >> 8) & 0xff) / 255.0; _viewer->setBackgroundColor(QColor::fromRgbF(r1, g1, b1)); if (!rGrp.GetBool("UseBackgroundColorMid",false)) - _viewer->setGradientBackgroundColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3)); + _viewer->setGradientBackgroundColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3), rGrp.GetBool("RadialGradient", false)); else - _viewer->setGradientBackgroundColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3), SbColor(r4, g4, b4)); + _viewer->setGradientBackgroundColor(SbColor(r2, g2, b2), SbColor(r3, g3, b3), SbColor(r4, g4, b4), rGrp.GetBool("RadialGradient", false)); } } diff --git a/src/Gui/View3DViewerPy.cpp b/src/Gui/View3DViewerPy.cpp index b958f22b03..7fe65d5463 100644 --- a/src/Gui/View3DViewerPy.cpp +++ b/src/Gui/View3DViewerPy.cpp @@ -437,7 +437,7 @@ Py::Object View3DInventorViewerPy::setBackgroundColor(const Py::Tuple& args) } try { SbColor col(r,g,b); - _viewer->setGradientBackgroundColor(col,col); + _viewer->setGradientBackgroundColor(col, col, false); return Py::None(); } catch (const Base::Exception& e) {