diff --git a/data/pref.xml b/data/pref.xml
index f452127f2..7f70beb2a 100644
--- a/data/pref.xml
+++ b/data/pref.xml
@@ -321,7 +321,7 @@
@@ -473,7 +473,7 @@
-
+
diff --git a/src/app/pref/preferences.cpp b/src/app/pref/preferences.cpp
index 92f3c1b83..53d9c9a46 100644
--- a/src/app/pref/preferences.cpp
+++ b/src/app/pref/preferences.cpp
@@ -147,23 +147,29 @@ bool Preferences::isSet(OptionBase& opt) const
ToolPreferences& Preferences::tool(tools::Tool* tool)
{
- ASSERT(tool != NULL);
+ std::string id;
- auto it = m_tools.find(tool->getId());
+ // If tool == nullptr it means that the tool's options are shared with all tools.
+ if (tool)
+ id = tool->getId();
+ else
+ id = "shared";
+
+ auto it = m_tools.find(id);
if (it != m_tools.end()) {
return *it->second;
}
else {
- std::string section = std::string("tool.") + tool->getId();
+ std::string section = std::string("tool.") + id;
ToolPreferences* toolPref = new ToolPreferences(section);
// Default size for eraser, blur, etc.
- if (tool->getInk(0)->isEraser() ||
- tool->getInk(0)->isEffect()) {
+ if (tool && (tool->getInk(0)->isEraser() ||
+ tool->getInk(0)->isEffect())) {
toolPref->brush.size.setDefaultValue(8);
}
- m_tools[tool->getId()] = toolPref;
+ m_tools[id] = toolPref;
toolPref->load();
return *toolPref;
}
@@ -223,6 +229,9 @@ void Preferences::resetToolPreferences(tools::Tool* tool)
del_config_section((section + ".brush").c_str());
del_config_section((section + ".spray").c_str());
del_config_section((section + ".floodfill").c_str());
+ del_config_section((section + ".dynamics").c_str());
+ std::string shared = "tool.shared";
+ del_config_section(shared.c_str());
}
void Preferences::removeDocument(Doc* doc)
diff --git a/src/app/ui/context_bar.cpp b/src/app/ui/context_bar.cpp
index ae4697c6c..1b22d4d0f 100644
--- a/src/app/ui/context_bar.cpp
+++ b/src/app/ui/context_bar.cpp
@@ -1164,22 +1164,13 @@ public:
if (!m_popup.get())
m_popup.reset(new DynamicsPopup(this));
- auto activeTool = App::instance()->activeTool();
- m_popup->loadDynamicsPref();
- m_dynamics = m_popup->getDynamics();
m_sameInAllTools = m_popup->sharedSettings();
+ m_popup->loadDynamicsPref(m_sameInAllTools);
+ m_dynamics = m_popup->getDynamics();
m_popup->Close.connect(
[this](CloseEvent&) {
deselectItems();
- auto activeTool = App::instance()->activeTool();
- m_dynamics = m_popup->getDynamics();
- m_sameInAllTools = m_popup->sharedSettings();
- if (m_sameInAllTools) {
- for (Tool* tool : *App::instance()->toolBox())
- saveDynamicsPref(tool);
- }
- else
- saveDynamicsPref(activeTool);
+ saveDynamicsPref();
});
m_popup->refreshVisibility();
@@ -1206,8 +1197,15 @@ public:
m_popup->setOptionsGridVisibility(state);
}
- void saveDynamicsPref(Tool* tool) {
+ void saveDynamicsPref() {
+ m_sameInAllTools = m_popup->sharedSettings();
+ Preferences::instance().shared.shareDynamics(m_sameInAllTools);
+ tools::Tool* tool = nullptr;
+ if (!m_sameInAllTools)
+ tool = App::instance()->activeTool();
+
auto& dynaPref = Preferences::instance().tool(tool).dynamics;
+ m_dynamics = m_popup->getDynamics();
dynaPref.stabilizer(m_dynamics.stabilizer);
dynaPref.stabilizerFactor(m_dynamics.stabilizerFactor);
dynaPref.size(m_dynamics.size);
@@ -1220,13 +1218,16 @@ public:
dynaPref.maxPressureThreshold(m_dynamics.maxPressureThreshold);
dynaPref.maxVelocityThreshold(m_dynamics.maxVelocityThreshold);
dynaPref.colorFromTo(m_dynamics.colorFromTo);
- dynaPref.matrixIndex(m_popup->ditheringIndex());
- Preferences::instance().shared.shareDynamics(m_sameInAllTools);
+ dynaPref.matrixName(m_popup->ditheringMatrixName());
}
void loadDynamicsPref() {
- auto& dynaPref = Preferences::instance()
- .tool(App::instance()->activeTool()).dynamics;
+ m_sameInAllTools = Preferences::instance().shared.shareDynamics();
+ tools::Tool* tool = nullptr;
+ if (!m_sameInAllTools)
+ tool = App::instance()->activeTool();
+
+ auto& dynaPref = Preferences::instance().tool(tool).dynamics;
m_dynamics.stabilizer = dynaPref.stabilizer();
m_dynamics.stabilizerFactor = dynaPref.stabilizerFactor();
m_dynamics.size = dynaPref.size();
@@ -1241,11 +1242,10 @@ public:
m_dynamics.colorFromTo = dynaPref.colorFromTo();
DitheringSelector matrixSel(DitheringSelector::SelectMatrix);
- matrixSel.setSelectedItemIndex(dynaPref.matrixIndex());
+ matrixSel.setSelectedItemIndex(matrixSel.findItemIndex(
+ dynaPref.matrixName()));
render::DitheringMatrix matrix(matrixSel.ditheringMatrix());
m_dynamics.ditheringMatrix = matrix;
-
- m_sameInAllTools = Preferences::instance().shared.shareDynamics();
}
private:
diff --git a/src/app/ui/dithering_selector.cpp b/src/app/ui/dithering_selector.cpp
index 60933745b..ef655a775 100644
--- a/src/app/ui/dithering_selector.cpp
+++ b/src/app/ui/dithering_selector.cpp
@@ -198,7 +198,14 @@ void DitheringSelector::onInitTheme(ui::InitThemeEvent& ev)
setSizeHint(getItem(0)->sizeHint());
}
-void DitheringSelector::regenerate()
+void DitheringSelector::setSelectedItemByName(const std::string& name)
+{
+ int index = findItemIndex(name);
+ setSelectedItemIndex(index);
+ regenerate(index);
+}
+
+void DitheringSelector::regenerate(int selectedItemIndex)
{
deleteAllItems();
@@ -255,9 +262,9 @@ void DitheringSelector::regenerate()
}
break;
}
-
- setSelectedItemIndex(0);
- setSizeHint(getItem(0)->sizeHint());
+ selectedItemIndex = std::clamp(selectedItemIndex, 0, std::max(0, getItemCount()-1));
+ setSelectedItemIndex(selectedItemIndex);
+ setSizeHint(getItem(selectedItemIndex)->sizeHint());
}
render::DitheringAlgorithm DitheringSelector::ditheringAlgorithm()
diff --git a/src/app/ui/dithering_selector.h b/src/app/ui/dithering_selector.h
index ffbd64936..bf2774ce1 100644
--- a/src/app/ui/dithering_selector.h
+++ b/src/app/ui/dithering_selector.h
@@ -27,13 +27,13 @@ namespace app {
render::DitheringAlgorithm ditheringAlgorithm();
render::DitheringMatrix ditheringMatrix();
+ void setSelectedItemByName(const std::string& name);
protected:
void onInitTheme(ui::InitThemeEvent& ev) override;
private:
- void regenerate();
-
+ void regenerate(int selectedItemIndex = 0);
Type m_type;
obs::scoped_connection m_extChanges;
};
diff --git a/src/app/ui/dynamics_popup.cpp b/src/app/ui/dynamics_popup.cpp
index 3cca3d694..2b7439854 100644
--- a/src/app/ui/dynamics_popup.cpp
+++ b/src/app/ui/dynamics_popup.cpp
@@ -11,11 +11,13 @@
#include "app/ui/dynamics_popup.h"
#include "app/app.h"
+#include "app/i18n/strings.h"
#include "app/tools/tool_box.h"
#include "app/ui/dithering_selector.h"
#include "app/ui/skin/skin_theme.h"
#include "os/font.h"
#include "os/surface.h"
+#include "ui/fit_bounds.h"
#include "ui/message.h"
#include "ui/paint_event.h"
#include "ui/scale.h"
@@ -275,7 +277,22 @@ DynamicsPopup::DynamicsPopup(Delegate* delegate)
setHotRegion(m_hotRegion);
}
});
-
+ m_dynamics->sameInAllTools()->setSelected(
+ Preferences::instance().shared.shareDynamics());
+ m_dynamics->sameInAllTools()->Click.connect(
+ [this]{
+ // if sameInAllTools is true here, this means:
+ // "Transition false to true of 'Same in all tools' and the
+ // current parameters in the DynamicsPopup windows are the
+ // old one, i.e non-shared parameters."
+ bool sameInAllTools = m_dynamics->sameInAllTools()->isSelected();
+ // Save the old dynamics options:
+ saveDynamicsPref(!sameInAllTools);
+ Preferences::instance().shared.shareDynamics(sameInAllTools);
+ // Load the new dynamics options:
+ loadDynamicsPref(sameInAllTools);
+ refreshVisibility();
+ });
m_dynamics->gradientPlaceholder()->addChild(m_ditheringSel);
m_dynamics->pressurePlaceholder()->addChild(m_pressureThreshold = new ThresholdSlider);
m_dynamics->velocityPlaceholder()->addChild(m_velocityThreshold = new ThresholdSlider);
@@ -289,15 +306,22 @@ void DynamicsPopup::setOptionsGridVisibility(bool state)
expandWindow(sizeHint());
}
-int DynamicsPopup::ditheringIndex() const {
+std::string DynamicsPopup::ditheringMatrixName() const
+{
if (m_ditheringSel)
- return m_ditheringSel->getSelectedItemIndex();
- return 0;
+ return m_ditheringSel->getItemText(
+ m_ditheringSel->getSelectedItemIndex());
+ return std::string();
}
-void DynamicsPopup::loadDynamicsPref() {
- auto& dynaPref = Preferences::instance().tool(
- App::instance()->activeTool()).dynamics;
+void DynamicsPopup::loadDynamicsPref(bool sameInAllTools)
+{
+ m_dynamics->sameInAllTools()->setSelected(sameInAllTools);
+ tools::Tool* tool = nullptr;
+ if (!sameInAllTools)
+ tool = App::instance()->activeTool();
+
+ auto& dynaPref = Preferences::instance().tool(tool).dynamics;
m_dynamics->stabilizer()->setSelected(dynaPref.stabilizer());
m_stabilizerFactorBackup = dynaPref.stabilizerFactor();
m_dynamics->stabilizerFactor()->setValue(
@@ -324,10 +348,34 @@ void DynamicsPopup::loadDynamicsPref() {
dynaPref.gradient() == tools::DynamicSensor::Velocity);
if (m_ditheringSel)
- m_ditheringSel->setSelectedItemIndex(dynaPref.matrixIndex());
+ m_ditheringSel->setSelectedItemByName(dynaPref.matrixName());
+}
- m_dynamics->sameInAllTools()->setSelected(
- Preferences::instance().shared.shareDynamics());
+void DynamicsPopup::saveDynamicsPref(bool sameInAllTools)
+{
+ tools::DynamicsOptions dyna = getDynamics();
+ tools::Tool* tool = nullptr;
+ if (!sameInAllTools)
+ tool = App::instance()->activeTool();
+
+ auto dynaPref = &Preferences::instance().tool(tool).dynamics;
+ dynaPref->stabilizer(dyna.stabilizer);
+ dynaPref->stabilizerFactor(m_stabilizerFactorBackup);
+ dynaPref->minSize(dyna.minSize);
+ dynaPref->minAngle(dyna.minAngle);
+ dynaPref->minPressureThreshold(dyna.minPressureThreshold);
+ dynaPref->maxPressureThreshold(dyna.maxPressureThreshold);
+ dynaPref->minVelocityThreshold(dyna.minVelocityThreshold);
+ dynaPref->maxVelocityThreshold(dyna.maxVelocityThreshold);
+ dynaPref->colorFromTo(m_fromTo);
+
+ dynaPref->size(dyna.size);
+ dynaPref->angle(dyna.angle);
+ dynaPref->gradient(dyna.gradient);
+
+ if (m_ditheringSel)
+ dynaPref->matrixName(m_ditheringSel->getItemText(
+ m_ditheringSel->getSelectedItemIndex()));
}
tools::DynamicsOptions DynamicsPopup::getDynamics() const
diff --git a/src/app/ui/dynamics_popup.h b/src/app/ui/dynamics_popup.h
index 04dd2b51d..e8b194a74 100644
--- a/src/app/ui/dynamics_popup.h
+++ b/src/app/ui/dynamics_popup.h
@@ -37,8 +37,9 @@ namespace app {
tools::DynamicsOptions getDynamics() const;
void setOptionsGridVisibility(bool state);
- void loadDynamicsPref();
- int ditheringIndex() const;
+ void loadDynamicsPref(bool sameInAllTools);
+ void saveDynamicsPref(bool sameInAllTools);
+ std::string ditheringMatrixName() const;
void refreshVisibility();
bool sharedSettings() const;