File indexing completed on 2024-05-12 16:01:26

0001 /*
0002  *  SPDX-FileCopyrightText: 2003-2009 Boudewijn Rempt <boud@valdyas.org>
0003  *  SPDX-FileCopyrightText: 2014 Sven Langkamp <sven.langkamp@gmail.com>
0004  *
0005  *  SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #include "kis_canvas_controls_manager.h"
0009 
0010 #include <kactioncollection.h>
0011 #include <QAction>
0012 
0013 #include <KoCanvasResourceProvider.h>
0014 
0015 #include "kis_action.h"
0016 #include "kis_action_manager.h"
0017 #include "KisViewManager.h"
0018 #include "kis_canvas2.h"
0019 #include "kis_canvas_resource_provider.h"
0020 
0021 #include <brushengine/kis_locked_properties_proxy.h>
0022 #include <brushengine/kis_locked_properties_server.h>
0023 #include <brushengine/kis_locked_properties.h>
0024 
0025 #include <klocalizedstring.h>
0026 #include <kconfiggroup.h>
0027 #include <ksharedconfig.h>
0028 
0029 #include <math.h>
0030 
0031 const int STEP = 25;
0032 
0033 KisCanvasControlsManager::KisCanvasControlsManager(KisViewManager * view) : m_view(view)
0034 {
0035 
0036 }
0037 
0038 KisCanvasControlsManager::~KisCanvasControlsManager()
0039 {
0040 
0041 }
0042 
0043 void KisCanvasControlsManager::setup(KisActionManager *actionManager)
0044 {
0045     KisAction *lighterColor = actionManager->createAction("make_brush_color_lighter");
0046     connect(lighterColor, SIGNAL(triggered()), SLOT(makeColorLighter()));
0047 
0048     KisAction *darkerColor = actionManager->createAction("make_brush_color_darker");
0049     connect(darkerColor, SIGNAL(triggered()), SLOT(makeColorDarker()));
0050     KisAction *saturatedColor = actionManager->createAction("make_brush_color_saturated");
0051     connect(saturatedColor, SIGNAL(triggered()), SLOT(makeColorSaturated()));
0052 
0053     KisAction *desaturatedColor = actionManager->createAction("make_brush_color_desaturated");
0054     connect(desaturatedColor, SIGNAL(triggered()), SLOT(makeColorDesaturated()));
0055 
0056     KisAction *hueClockwise = actionManager->createAction("shift_brush_color_clockwise");
0057     connect(hueClockwise, SIGNAL(triggered()), SLOT(shiftHueClockWise()));
0058 
0059     KisAction *hueCounterClockwise = actionManager->createAction("shift_brush_color_counter_clockwise");
0060     connect(hueCounterClockwise, SIGNAL(triggered()), SLOT(shiftHueCounterClockWise()));
0061 
0062     KisAction *moreRed = actionManager->createAction("make_brush_color_redder");
0063     connect(moreRed, SIGNAL(triggered()), SLOT(makeColorRed()));
0064 
0065     KisAction *moreGreen = actionManager->createAction("make_brush_color_greener");
0066     connect(moreGreen, SIGNAL(triggered()), SLOT(makeColorGreen()));
0067 
0068     KisAction *moreBlue = actionManager->createAction("make_brush_color_bluer");
0069     connect(moreBlue, SIGNAL(triggered()), SLOT(makeColorBlue()));
0070 
0071     KisAction *moreYellow = actionManager->createAction("make_brush_color_yellower");
0072     connect(moreYellow, SIGNAL(triggered()), SLOT(makeColorYellow()));
0073 
0074     KisAction *increaseOpacity = actionManager->createAction("increase_opacity");
0075     connect(increaseOpacity, SIGNAL(triggered()), SLOT(increaseOpacity()));
0076 
0077     KisAction *decreaseOpacity = actionManager->createAction("decrease_opacity");
0078     connect(decreaseOpacity, SIGNAL(triggered()), SLOT(decreaseOpacity()));
0079 
0080     KisAction *increaseFlow = actionManager->createAction("increase_flow");
0081     connect(increaseFlow, SIGNAL(triggered()), SLOT(increaseFlow()));
0082 
0083     KisAction *decreaseFlow = actionManager->createAction("decrease_flow");
0084     connect(decreaseFlow, SIGNAL(triggered()), SLOT(decreaseFlow()));
0085 
0086     KisAction *increaseFade = actionManager->createAction("increase_fade");
0087     connect(increaseFade, SIGNAL(triggered()), SLOT(increaseFade()));
0088 
0089     KisAction *decreaseFade = actionManager->createAction("decrease_fade");
0090     connect(decreaseFade, SIGNAL(triggered()), SLOT(decreaseFade()));
0091 
0092     KisAction *increaseScatter = actionManager->createAction("increase_scatter");
0093     connect(increaseScatter, SIGNAL(triggered()), SLOT(increaseScatter()));
0094 
0095     KisAction *decreaseScatter = actionManager->createAction("decrease_scatter");
0096     connect(decreaseScatter, SIGNAL(triggered()), SLOT(decreaseScatter()));
0097 }
0098 
0099 void KisCanvasControlsManager::setView(QPointer<KisView>imageView)
0100 {
0101     Q_UNUSED(imageView);
0102 }
0103 
0104 void KisCanvasControlsManager::transformColor(int step)
0105 {
0106     if (!m_view) return;
0107     if (!m_view->canvasBase()) return;
0108     if (!m_view->canvasResourceProvider()->resourceManager()) return;
0109     KConfigGroup hotkeycfg =  KSharedConfig::openConfig()->group("colorhotkeys");
0110     int steps = hotkeycfg.readEntry("steps_lightness", 10);
0111     if (steps <= 0) {
0112         steps = 1;
0113     }
0114 
0115 
0116     KoColor color = m_view->canvasResourceProvider()->resourceManager()->resource(KoCanvasResource::ForegroundColor).value<KoColor>();
0117     if (color.colorSpace()->colorModelId().id()=="CMYKA" || color.colorSpace()->colorModelId().id()=="XYZA"){
0118         QColor rgb = color.toQColor();
0119         int h = 0, s = 0, v = 0;
0120         rgb.getHsv(&h,&s,&v);
0121         if ((v < 255) || ((s == 0) || (s == 255))) {
0122             v += step;
0123             v = qBound(0,v,255);
0124         } else {
0125             s += -step;
0126             s = qBound(0,s,255);
0127         }
0128         rgb.setHsv(h,s,v);
0129         color.fromQColor(rgb);
0130     } else if (step<0){
0131         color.colorSpace()->decreaseLuminosity(color.data(), 1.0/steps);
0132     } else {
0133         color.colorSpace()->increaseLuminosity(color.data(), 1.0/steps);
0134     }
0135     m_view->canvasResourceProvider()->resourceManager()->setResource(KoCanvasResource::ForegroundColor, color);
0136 }
0137 void KisCanvasControlsManager::transformSaturation(int step)
0138 {
0139     if (!m_view) return;
0140     if (!m_view->canvasBase()) return;
0141     if (!m_view->canvasResourceProvider()->resourceManager()) return;
0142     KConfigGroup hotkeycfg =  KSharedConfig::openConfig()->group("colorhotkeys");
0143     int steps = hotkeycfg.readEntry("steps_saturation", 10);
0144     if (steps <= 0) {
0145         steps = 1;
0146     }
0147 
0148     KoColor color = m_view->canvasResourceProvider()->resourceManager()->resource(KoCanvasResource::ForegroundColor).value<KoColor>();
0149     if (color.colorSpace()->colorModelId().id()=="CMYKA" || color.colorSpace()->colorModelId().id()=="XYZA"){
0150         QColor rgb = color.toQColor();
0151         int h = 0, s = 0, v = 0;
0152         rgb.getHsl(&h,&s,&v);
0153         s += step;
0154         s = qBound(0,s,255);
0155         rgb.setHsl(h,s,v);
0156         color.fromQColor(rgb);
0157     } else if (step<0){
0158         color.colorSpace()->decreaseSaturation(color.data(), 1.0/steps);
0159     } else {
0160         color.colorSpace()->increaseSaturation(color.data(), 1.0/steps);
0161     }
0162     m_view->canvasResourceProvider()->resourceManager()->setResource(KoCanvasResource::ForegroundColor, color);
0163 }
0164 void KisCanvasControlsManager::transformHue(int step)
0165 {
0166     if (!m_view) return;
0167     if (!m_view->canvasBase()) return;
0168     if (!m_view->canvasResourceProvider()->resourceManager()) return;
0169     KConfigGroup hotkeycfg =  KSharedConfig::openConfig()->group("colorhotkeys");
0170     int steps = hotkeycfg.readEntry("steps_hue", 36);
0171     if (steps <= 0) {
0172         steps = 1;
0173     }
0174 
0175     KoColor color = m_view->canvasResourceProvider()->resourceManager()->resource(KoCanvasResource::ForegroundColor).value<KoColor>();
0176     if (color.colorSpace()->colorModelId().id()=="CMYKA" || color.colorSpace()->colorModelId().id()=="XYZA"){
0177         QColor rgb = color.toQColor();
0178         int h = 0, s = 0, v = 0;
0179         rgb.getHsl(&h,&s,&v);
0180         h += step;
0181         if (h>360.0 || h<0.0){h=fmod(h, 360.0);}
0182         rgb.setHsl(h,s,v);
0183         color.fromQColor(rgb);
0184     } else if (step<0){
0185         color.colorSpace()->increaseHue(color.data(), 1.0/steps);
0186     } else {
0187         color.colorSpace()->decreaseHue(color.data(), 1.0/steps);
0188     }
0189     m_view->canvasResourceProvider()->resourceManager()->setResource(KoCanvasResource::ForegroundColor, color);
0190 }
0191 void KisCanvasControlsManager::transformRed(int step)
0192 {
0193     if (!m_view) return;
0194     if (!m_view->canvasBase()) return;
0195     if (!m_view->canvasResourceProvider()->resourceManager()) return;
0196     KConfigGroup hotkeycfg =  KSharedConfig::openConfig()->group("colorhotkeys");
0197     int steps = hotkeycfg.readEntry("steps_redgreen", 10);
0198     if (steps <= 0) {
0199         steps = 1;
0200     }
0201 
0202     KoColor color = m_view->canvasResourceProvider()->resourceManager()->resource(KoCanvasResource::ForegroundColor).value<KoColor>();
0203     if (step<0){
0204         color.colorSpace()->increaseGreen(color.data(), 1.0/steps);
0205     } else {
0206         color.colorSpace()->increaseRed(color.data(), 1.0/steps);
0207     }
0208     m_view->canvasResourceProvider()->resourceManager()->setResource(KoCanvasResource::ForegroundColor, color);
0209 }
0210 void KisCanvasControlsManager::transformBlue(int step)
0211 {
0212     if (!m_view) return;
0213     if (!m_view->canvasBase()) return;
0214     if (!m_view->canvasResourceProvider()->resourceManager()) return;
0215     KConfigGroup hotkeycfg =  KSharedConfig::openConfig()->group("colorhotkeys");
0216     int steps = hotkeycfg.readEntry("steps_blueyellow", 10);
0217     if (steps <= 0) {
0218         steps = 1;
0219     }
0220 
0221     KoColor color = m_view->canvasResourceProvider()->resourceManager()->resource(KoCanvasResource::ForegroundColor).value<KoColor>();
0222     if (step<0){
0223         color.colorSpace()->increaseYellow(color.data(), 1.0/steps);
0224     } else {
0225         color.colorSpace()->increaseBlue(color.data(), 1.0/steps);
0226     }
0227     m_view->canvasResourceProvider()->resourceManager()->setResource(KoCanvasResource::ForegroundColor, color);
0228 }
0229 
0230 
0231 void KisCanvasControlsManager::makeColorDarker()
0232 {
0233     transformColor(-STEP);
0234 }
0235 
0236 void KisCanvasControlsManager::makeColorLighter()
0237 {
0238     transformColor(STEP);
0239 }
0240 
0241 void KisCanvasControlsManager::makeColorDesaturated()
0242 {
0243     transformSaturation(-STEP);
0244 }
0245 
0246 void KisCanvasControlsManager::makeColorSaturated()
0247 {
0248     transformSaturation(STEP);
0249 }
0250 void KisCanvasControlsManager::shiftHueClockWise()
0251 {
0252     transformHue(STEP);
0253 }
0254 
0255 void KisCanvasControlsManager::shiftHueCounterClockWise()
0256 {
0257     transformHue(-STEP);
0258 }
0259 void KisCanvasControlsManager::makeColorRed()
0260 {
0261     transformRed(STEP);
0262 }
0263 void KisCanvasControlsManager::makeColorGreen()
0264 {
0265     transformRed(-STEP);
0266 }
0267 void KisCanvasControlsManager::makeColorBlue()
0268 {
0269     transformBlue(STEP);
0270 }
0271 void KisCanvasControlsManager::makeColorYellow()
0272 {
0273     transformBlue(-STEP);
0274 }
0275 
0276 void KisCanvasControlsManager::stepAlpha(float step)
0277 {
0278     if (!m_view) return;
0279     if (!m_view->canvasBase()) return;
0280     if (!m_view->canvasResourceProvider()->resourceManager()) return;
0281 
0282     qreal alpha = m_view->canvasResourceProvider()->resourceManager()->resource(KoCanvasResource::Opacity).toDouble();
0283     alpha += step;
0284     alpha = qBound<qreal>(0.0, alpha, 1.0);
0285     m_view->canvasBase()->resourceManager ()->setResource(KoCanvasResource::Opacity, alpha);
0286 
0287     m_view->showFloatingMessage(i18n("Brush Opacity: %1%", alpha * 100), QIcon(), 1000, KisFloatingMessage::High,
0288                                 Qt::AlignLeft | Qt::TextWordWrap | Qt::AlignVCenter);
0289 
0290     // FIXME: DK: should we uncomment it back?
0291     //KisLockedPropertiesProxySP p = KisLockedPropertiesServer::instance()->createLockedPropertiesProxy(m_view->resourceProvider()->currentPreset()->settings());
0292     //p->setProperty("OpacityValue", alpha);
0293 }
0294 
0295 void KisCanvasControlsManager::increaseOpacity()
0296 {
0297     stepAlpha(0.1f);
0298 }
0299 
0300 void KisCanvasControlsManager::decreaseOpacity()
0301 {
0302     stepAlpha(-0.1f);
0303 }
0304 
0305 void KisCanvasControlsManager::stepFlow(float step)
0306 {
0307     if (!m_view) return;
0308     if (!m_view->canvasBase()) return;
0309     if (!m_view->canvasResourceProvider()->resourceManager()) return;
0310 
0311     qreal flow = m_view->canvasResourceProvider()->resourceManager()->resource(KoCanvasResource::Flow).toDouble();
0312     flow += step;
0313     flow = qBound<qreal>(0.0, flow, 1.0);
0314     m_view->canvasBase()->resourceManager ()->setResource(KoCanvasResource::Flow, flow);
0315 
0316     // verify if the brush does actually support this change
0317     flow = m_view->canvasBase()->resourceManager ()->resource(KoCanvasResource::Flow).toReal();
0318 
0319     m_view->showFloatingMessage(i18nc("Brush Option Flow", "Flow: %1%", flow * 100), QIcon(), 1000, KisFloatingMessage::High,
0320                                 Qt::AlignLeft | Qt::TextWordWrap | Qt::AlignVCenter);
0321 }
0322 
0323 void KisCanvasControlsManager::increaseFlow()
0324 {
0325     stepFlow(0.1f);
0326 }
0327 
0328 void KisCanvasControlsManager::decreaseFlow()
0329 {
0330     stepFlow(-0.1f);
0331 }
0332 
0333 void KisCanvasControlsManager::stepFade(float step)
0334 {
0335     if (!m_view) return;
0336     if (!m_view->canvasBase()) return;
0337     if (!m_view->canvasResourceProvider()->resourceManager()) return;
0338 
0339     qreal fade = m_view->canvasResourceProvider()->resourceManager()->resource(KoCanvasResource::Fade).toDouble();
0340     fade += step;
0341     fade = qBound<qreal>(0.0, fade, 1.0);
0342     m_view->canvasBase()->resourceManager ()->setResource(KoCanvasResource::Fade, fade);
0343 
0344     // verify if the brush does actually support this change
0345     fade = m_view->canvasBase()->resourceManager ()->resource(KoCanvasResource::Fade).toReal();
0346 
0347     m_view->showFloatingMessage(i18nc("Edge softness, Brush Option Fade", "Fade: %1", fade),
0348                                 QIcon(), 1000, KisFloatingMessage::High, Qt::AlignLeft | Qt::TextWordWrap | Qt::AlignVCenter);
0349 }
0350 
0351 void KisCanvasControlsManager::increaseFade()
0352 {
0353     stepFade(0.1f);
0354 }
0355 
0356 void KisCanvasControlsManager::decreaseFade()
0357 {
0358     stepFade(-0.1f);
0359 }
0360 
0361 void KisCanvasControlsManager::stepScatter(float step)
0362 {
0363     if (!m_view) return;
0364     if (!m_view->canvasBase()) return;
0365     if (!m_view->canvasResourceProvider()->resourceManager()) return;
0366 
0367     qreal scatter = m_view->canvasResourceProvider()->resourceManager()->resource(KoCanvasResource::Scatter).toDouble();
0368     scatter += step;
0369     scatter = qBound<qreal>(0.0, scatter, 5.0);
0370     m_view->canvasBase()->resourceManager ()->setResource(KoCanvasResource::Scatter, scatter);
0371 
0372     // verify if the brush does actually support this change
0373     scatter = m_view->canvasBase()->resourceManager ()->resource(KoCanvasResource::Scatter).toReal();
0374 
0375     m_view->showFloatingMessage(i18nc("Brush Option Scatter", "Scatter: %1%", scatter * 100), QIcon(), 1000, KisFloatingMessage::High,
0376                                 Qt::AlignLeft | Qt::TextWordWrap | Qt::AlignVCenter);
0377 }
0378 
0379 void KisCanvasControlsManager::increaseScatter()
0380 {
0381     stepScatter(0.1f);
0382 }
0383 
0384 void KisCanvasControlsManager::decreaseScatter()
0385 {
0386     stepScatter(-0.1f);
0387 }