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 }