diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 614a8d9fc8..1ab2566955 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -319,6 +319,7 @@ SET(Gui_UIC_SRCS PreferencePages/DlgSettingsEditor.ui PreferencePages/DlgSettingsGeneral.ui DlgSettingsImage.ui + PreferencePages/DlgSettingsLightSources.ui PreferencePages/DlgSettingsMacro.ui PreferencePages/DlgSettingsNavigation.ui PreferencePages/DlgSettingsNotificationArea.ui @@ -565,6 +566,7 @@ SET(Dialog_Settings_CPP_SRCS PreferencePages/DlgSettingsEditor.cpp PreferencePages/DlgSettingsGeneral.cpp DlgSettingsImageImp.cpp + PreferencePages/DlgSettingsLightSources.cpp PreferencePages/DlgSettingsMacroImp.cpp PreferencePages/DlgSettingsNavigation.cpp PreferencePages/DlgSettingsNotificationArea.cpp @@ -586,6 +588,7 @@ SET(Dialog_Settings_HPP_SRCS PreferencePages/DlgSettingsEditor.h PreferencePages/DlgSettingsGeneral.h DlgSettingsImageImp.h + PreferencePages/DlgSettingsLightSources.h PreferencePages/DlgSettingsMacroImp.h PreferencePages/DlgSettingsNavigation.h PreferencePages/DlgSettingsNotificationArea.h @@ -609,6 +612,7 @@ SET(Dialog_Settings_SRCS PreferencePages/DlgSettingsEditor.ui PreferencePages/DlgSettingsGeneral.ui DlgSettingsImage.ui + PreferencePages/DlgSettingsLightSources.ui PreferencePages/DlgSettingsMacro.ui PreferencePages/DlgSettingsNavigation.ui PreferencePages/DlgSettingsNotificationArea.ui diff --git a/src/Gui/PreferencePages/DlgSettingsLightSources.cpp b/src/Gui/PreferencePages/DlgSettingsLightSources.cpp new file mode 100644 index 0000000000..9ca7fc8df0 --- /dev/null +++ b/src/Gui/PreferencePages/DlgSettingsLightSources.cpp @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/*************************************************************************** + * Copyright (c) 2023 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" + +#ifndef _PreComp_ +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include "DlgSettingsLightSources.h" +#include "ui_DlgSettingsLightSources.h" +#include + + +using namespace Gui::Dialog; + +/* TRANSLATOR Gui::Dialog::DlgSettingsLightSources */ + +DlgSettingsLightSources::DlgSettingsLightSources(QWidget* parent) + : PreferencePage(parent) + , ui(new Ui_DlgSettingsLightSources) +{ + ui->setupUi(this); + setupConnection(); +} + +DlgSettingsLightSources::~DlgSettingsLightSources() +{ + delete view; +} + +void DlgSettingsLightSources::setupConnection() +{ + connect(ui->checkBoxLight1, &QCheckBox::toggled, + this, &DlgSettingsLightSources::toggleLight); + connect(ui->sliderIntensity1, &QSlider::valueChanged, + this, &DlgSettingsLightSources::lightIntensity); + connect(ui->light1Color, &Gui::ColorButton::changed, + this, &DlgSettingsLightSources::lightColor); +} + +void DlgSettingsLightSources::showEvent(QShowEvent* event) +{ + Q_UNUSED(event) + if (!view) { + QGroupBox* box = ui->groupBoxLight; + QWidget* widget = createViewer(box); + auto grid = new QGridLayout(box); + grid->addWidget(widget); + box->setLayout(grid); + + loadDirection(); + } +} + +void DlgSettingsLightSources::dragMotionCallback(void *data, SoDragger *drag) +{ + auto lightdrag = static_cast(drag); + auto self = static_cast(data); + SbRotation rotation = lightdrag->rotation.getValue(); + SbVec3f dir(0, 0, -1); + rotation.multVec(dir, dir); + self->view->getHeadlight()->direction = dir; +} + +QWidget* DlgSettingsLightSources::createViewer(QWidget* parent) +{ + // NOLINTBEGIN + view = new Gui::View3DInventorViewer(parent); + view->setRedirectToSceneGraph(true); + view->setViewing(true); + view->setPopupMenuEnabled(false); + + view->setBackgroundColor(QColor(255, 255, 255)); + view->setGradientBackground(Gui::View3DInventorViewer::NoGradient); + view->setEnabledNaviCube(false); + + auto root = static_cast(view->getSceneGraph()); + root->addChild(createDragger()); + + view->setCameraType(SoOrthographicCamera::getClassTypeId()); + view->setViewDirection(SbVec3f(1, 1, -5)); + view->viewAll(); + // NOLINTEND + + const int size = 250; + view->resize(size, size); + + return view; +} + +SoDirectionalLightDragger* DlgSettingsLightSources::createDragger() +{ + lightDragger = new SoDirectionalLightDragger(); + SoDragger * therotator = static_cast(lightDragger->getPart("translator", false)); + therotator->setPartAsDefault("xTranslator.translatorActive", nullptr); + therotator->setPartAsDefault("yTranslator.translatorActive", nullptr); + therotator->setPartAsDefault("zTranslator.translatorActive", nullptr); + therotator->setPartAsDefault("xTranslator.translator", nullptr); + therotator->setPartAsDefault("yTranslator.translator", nullptr); + therotator->setPartAsDefault("zTranslator.translator", nullptr); + SoNode* node = therotator->getPart("yzTranslator.translator", false); + if (node && node->isOfType(SoGroup::getClassTypeId())) { + auto ps = new SoPickStyle(); + ps->style = SoPickStyle::UNPICKABLE; + static_cast(node)->insertChild(ps, 0); + } + + lightDragger->addMotionCallback(dragMotionCallback, this); + return lightDragger; +} + +void DlgSettingsLightSources::saveSettings() +{ + ui->checkBoxLight1->onSave(); + ui->light1Color->onSave(); + ui->sliderIntensity1->onSave(); + saveDirection(); +} + +void DlgSettingsLightSources::loadSettings() +{ + ui->checkBoxLight1->onRestore(); + ui->light1Color->onRestore(); + ui->sliderIntensity1->onRestore(); +} + +void DlgSettingsLightSources::saveDirection() +{ + if (lightDragger) { + ParameterGrp::handle grp = ui->sliderIntensity1->getWindowParameter(); + SbRotation rotation = lightDragger->rotation.getValue(); + grp->SetFloat("HeadlightRotationX", rotation[0]); + grp->SetFloat("HeadlightRotationY", rotation[1]); + grp->SetFloat("HeadlightRotationZ", rotation[2]); + grp->SetFloat("HeadlightRotationW", rotation[3]); + + SbVec3f dir(0, 0, -1); + rotation.multVec(dir, dir); + + QString headlightDir = QString::fromLatin1("(%1,%2,%3)").arg(dir[0]).arg(dir[1]).arg(dir[2]); + grp->SetASCII("HeadlightDirection", headlightDir.toLatin1()); + } +} + +void DlgSettingsLightSources::loadDirection() +{ + ParameterGrp::handle grp = ui->sliderIntensity1->getWindowParameter(); + SbRotation rotation = lightDragger->rotation.getValue(); + // NOLINTBEGIN + float q1 = float(grp->GetFloat("HeadlightRotationX", rotation[0])); + float q2 = float(grp->GetFloat("HeadlightRotationY", rotation[1])); + float q3 = float(grp->GetFloat("HeadlightRotationZ", rotation[2])); + float q4 = float(grp->GetFloat("HeadlightRotationW", rotation[3])); + // NOLINTEND + rotation.setValue(q1, q2, q3, q4); + lightDragger->rotation.setValue(rotation); + + SbVec3f direction(0, 0, -1); + rotation.multVec(direction, direction); + view->getHeadlight()->direction = direction; +} + +void DlgSettingsLightSources::toggleLight(bool on) +{ + view->getHeadlight()->on = on; +} + +void DlgSettingsLightSources::lightIntensity(int value) +{ + float intensity = float(value) / 100.0F; + view->getHeadlight()->intensity = intensity; +} + +void DlgSettingsLightSources::lightColor() +{ + QColor color = ui->light1Color->color(); + double red = color.redF(); + double green = color.greenF(); + double blue = color.blueF(); + view->getHeadlight()->color = SbColor(float(red), float(green), float(blue)); +} + +void DlgSettingsLightSources::changeEvent(QEvent* event) +{ + if (event->type() == QEvent::LanguageChange) { + ui->retranslateUi(this); + } + PreferencePage::changeEvent(event); +} + + +#include "moc_DlgSettingsLightSources.cpp" diff --git a/src/Gui/PreferencePages/DlgSettingsLightSources.h b/src/Gui/PreferencePages/DlgSettingsLightSources.h new file mode 100644 index 0000000000..6b7dfc15c1 --- /dev/null +++ b/src/Gui/PreferencePages/DlgSettingsLightSources.h @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/*************************************************************************** + * Copyright (c) 2023 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_DIALOG_DLGSETTINGSLIGHTSOURCES_H +#define GUI_DIALOG_DLGSETTINGSLIGHTSOURCES_H + +#include +#include + +class SoDragger; +class SoDirectionalLightDragger; + +namespace Gui { +class View3DInventorViewer; +namespace Dialog { +class Ui_DlgSettingsLightSources; + +/** + * The DlgSettingsLightSources class implements a preference page to change settings + * for the light sources of a 3D view. + * @author Werner Mayer + */ +class DlgSettingsLightSources : public PreferencePage +{ + Q_OBJECT + +public: + explicit DlgSettingsLightSources(QWidget* parent = nullptr); + ~DlgSettingsLightSources() override; + + void saveSettings() override; + void loadSettings() override; + +protected: + void changeEvent(QEvent* event) override; + void showEvent(QShowEvent* event) override; + +private: + void setupConnection(); + void toggleLight(bool on); + void lightIntensity(int value); + void lightColor(); + void saveDirection(); + void loadDirection(); + QWidget* createViewer(QWidget* parent); + SoDirectionalLightDragger* createDragger(); + static void dragMotionCallback(void *data, SoDragger *drag); + +private: + std::unique_ptr ui; + View3DInventorViewer* view = nullptr; + SoDirectionalLightDragger* lightDragger = nullptr; +}; + +} // namespace Dialog +} // namespace Gui + +#endif // GUI_DIALOG_DLGSETTINGSLIGHTSOURCES_H diff --git a/src/Gui/PreferencePages/DlgSettingsLightSources.ui b/src/Gui/PreferencePages/DlgSettingsLightSources.ui new file mode 100644 index 0000000000..adbe2c86c9 --- /dev/null +++ b/src/Gui/PreferencePages/DlgSettingsLightSources.ui @@ -0,0 +1,199 @@ + + + Gui::Dialog::DlgSettingsLightSources + + + + 0 + 0 + 484 + 515 + + + + Light Sources + + + + + + Light sources + + + + + + Light source + + + true + + + EnableHeadlight + + + View + + + + + + + + 255 + 255 + 255 + + + + HeadlightColor + + + View + + + + + + + Qt::Horizontal + + + + 115 + 13 + + + + + + + + Intensity + + + + + + + 100 + + + 100 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 10 + + + HeadlightIntensity + + + View + + + + + + + + + + Lights + + + + + + + Qt::Vertical + + + + 428 + 376 + + + + + + + + + Gui::ColorButton + QPushButton +
Gui/Widgets.h
+
+ + Gui::PrefColorButton + Gui::ColorButton +
Gui/PrefWidgets.h
+
+ + Gui::PrefSlider + QSlider +
Gui/PrefWidgets.h
+
+ + Gui::PrefCheckBox + QCheckBox +
Gui/PrefWidgets.h
+
+
+ + + + checkBoxLight1 + toggled(bool) + light1Color + setEnabled(bool) + + + 73 + 53 + + + 150 + 53 + + + + + checkBoxLight1 + toggled(bool) + light1Label + setEnabled(bool) + + + 73 + 53 + + + 284 + 53 + + + + + checkBoxLight1 + toggled(bool) + sliderIntensity1 + setEnabled(bool) + + + 73 + 53 + + + 357 + 53 + + + + +
diff --git a/src/Gui/View3DSettings.cpp b/src/Gui/View3DSettings.cpp index f16e5e5acb..e248e6fa06 100644 --- a/src/Gui/View3DSettings.cpp +++ b/src/Gui/View3DSettings.cpp @@ -87,6 +87,7 @@ void View3DSettings::applySettings() OnChange(*hGrp,"UseVBO"); OnChange(*hGrp,"RenderCache"); OnChange(*hGrp,"Orthographic"); + OnChange(*hGrp,"EnableHeadlight"); OnChange(*hGrp,"HeadlightColor"); OnChange(*hGrp,"HeadlightDirection"); OnChange(*hGrp,"HeadlightIntensity"); @@ -108,7 +109,13 @@ void View3DSettings::applySettings() void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::MessageType Reason) { const ParameterGrp& rGrp = static_cast(rCaller); - if (strcmp(Reason,"HeadlightColor") == 0) { + if (strcmp(Reason,"EnableHeadlight") == 0) { + bool enable = rGrp.GetBool("EnableHeadlight", true); + for (auto _viewer : _viewers) { + _viewer->getHeadlight()->on.setValue(enable); + } + } + else if (strcmp(Reason,"HeadlightColor") == 0) { unsigned long headlight = rGrp.GetUnsigned("HeadlightColor",ULONG_MAX); // default color (white) float transparency; SbColor headlightColor; diff --git a/src/Gui/resource.cpp b/src/Gui/resource.cpp index 3ec05feb00..a5746990a6 100644 --- a/src/Gui/resource.cpp +++ b/src/Gui/resource.cpp @@ -36,6 +36,7 @@ #include "PreferencePages/DlgSettingsEditor.h" #include "PreferencePages/DlgSettingsGeneral.h" #include "PreferencePages/DlgSettingsMacroImp.h" +#include "PreferencePages/DlgSettingsLightSources.h" #include "PreferencePages/DlgSettingsNavigation.h" #include "PreferencePages/DlgSettingsNotificationArea.h" #include "PreferencePages/DlgSettingsPythonConsole.h" @@ -58,6 +59,7 @@ using namespace Gui; using namespace Gui::Dialog; +// clang-format off /** * Registers all preference pages or widgets to create them dynamically at any later time. */ @@ -74,6 +76,7 @@ WidgetFactorySupplier::WidgetFactorySupplier() new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","General") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","General") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","Display") ); + new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","Display") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","Display") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","Display") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","Display") ); @@ -122,3 +125,4 @@ WidgetFactorySupplier::WidgetFactorySupplier() new WidgetProducer; new WidgetProducer; } +// clang-format on