Add memorization of tool-shared dynamics options (fix #4007)

This commit is contained in:
Gaspar Capello 2023-08-30 13:11:34 -03:00 committed by David Capello
parent d8814fa2f9
commit 5968440f90
7 changed files with 111 additions and 46 deletions

View File

@ -321,7 +321,7 @@
<option id="discard_brush" type="bool" default="false" />
</section>
<section id="shared">
<option id="share_dynamics" type="bool" default="false" />
<option id="share_dynamics" type="bool" default="true" />
<option id="share_ink" type="bool" default="false" />
<option id="ink" type="app::tools::InkType" default="app::tools::InkType::DEFAULT" />
</section>
@ -473,7 +473,7 @@
<option id="min_size" type="int" default="1" />
<option id="min_angle" type="int" default="1" />
<option id="color_from_to" type="app::tools::ColorFromTo" default="app::tools::ColorFromTo::BgToFg" />
<option id="matrix_index" type="int" default="0" />
<option id="matrix_name" type="std::string" />
<option id="min_pressure_threshold" type="double" default="0.1" />
<option id="max_pressure_threshold" type="double" default="0.9" />
<option id="min_velocity_threshold" type="double" default="0.1" />

View File

@ -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)

View File

@ -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:

View File

@ -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()

View File

@ -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;
};

View File

@ -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

View File

@ -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;