Changeset View
Changeset View
Standalone View
Standalone View
libs/ui/tool/kis_tool_paint.cc
Context not available. | |||||
83 | m_colorPickerDelayTimer(), | 83 | m_colorPickerDelayTimer(), | ||
---|---|---|---|---|---|
84 | m_isOutlineEnabled(true) | 84 | m_isOutlineEnabled(true) | ||
85 | { | 85 | { | ||
86 | m_opacity = OPACITY_OPAQUE_U8; | ||||
86 | m_specialHoverModifier = false; | 87 | m_specialHoverModifier = false; | ||
87 | m_optionsWidgetLayout = 0; | 88 | m_optionsWidgetLayout = 0; | ||
88 | | ||||
89 | m_opacity = OPACITY_OPAQUE_U8; | | |||
90 | | ||||
91 | m_supportOutline = false; | 89 | m_supportOutline = false; | ||
92 | 90 | | |||
93 | { | 91 | { | ||
Context not available. | |||||
110 | m_colorPickerDelayTimer.setSingleShot(true); | 108 | m_colorPickerDelayTimer.setSingleShot(true); | ||
111 | connect(&m_colorPickerDelayTimer, SIGNAL(timeout()), this, SLOT(activatePickColorDelayed())); | 109 | connect(&m_colorPickerDelayTimer, SIGNAL(timeout()), this, SLOT(activatePickColorDelayed())); | ||
112 | 110 | | |||
111 | m_pickerSettings.load(); | ||||
112 | | ||||
113 | using namespace std::placeholders; // For _1 placeholder | 113 | using namespace std::placeholders; // For _1 placeholder | ||
114 | std::function<void(PickingJob)> callback = | 114 | std::function<void(PickingJob)> callback = | ||
115 | std::bind(&KisToolPaint::addPickerJob, this, _1); | 115 | std::bind(&KisToolPaint::addPickerJob, this, _1); | ||
116 | m_colorPickingCompressor.reset( | 116 | m_colorPickingCompressor.reset( | ||
117 | new PickingCompressor(100, callback, KisSignalCompressor::FIRST_ACTIVE)); | 117 | // "m_pickerSettings.resampleRateMS / 1.5" is a bit of magic number. | ||
118 | // It's a small hacky way to keep ctrl-picker speed roughly the same as dedicated kis_tool_colorpicker. | ||||
119 | new PickingCompressor(m_pickerSettings.resampleRateMS / 1.5, callback, KisSignalCompressor::FIRST_ACTIVE)); | ||||
118 | } | 120 | } | ||
119 | 121 | | |||
120 | | ||||
121 | KisToolPaint::~KisToolPaint() | 122 | KisToolPaint::~KisToolPaint() | ||
122 | { | 123 | { | ||
123 | } | 124 | } | ||
Context not available. | |||||
140 | } | 141 | } | ||
141 | 142 | | |||
142 | connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(resetCursorStyle()), Qt::UniqueConnection); | 143 | connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(resetCursorStyle()), Qt::UniqueConnection); | ||
143 | | ||||
144 | } | 144 | } | ||
145 | 145 | | |||
146 | 146 | | |||
Context not available. | |||||
160 | KisCanvasResourceProvider *provider = qobject_cast<KisCanvas2*>(canvas())->viewManager()->resourceProvider(); | 160 | KisCanvasResourceProvider *provider = qobject_cast<KisCanvas2*>(canvas())->viewManager()->resourceProvider(); | ||
161 | m_oldOpacity = provider->opacity(); | 161 | m_oldOpacity = provider->opacity(); | ||
162 | provider->setOpacity(m_localOpacity); | 162 | provider->setOpacity(m_localOpacity); | ||
163 | | ||||
164 | m_pickerSettings.load(); //Reload picker settings. | ||||
165 | m_useDedicatePickerConfig = KSharedConfig::openConfig()->group("").readEntry("CtrlPickerUsesDedicatedPickerConfig", false); | ||||
163 | } | 166 | } | ||
164 | 167 | | |||
165 | void KisToolPaint::deactivate() | 168 | void KisToolPaint::deactivate() | ||
Context not available. | |||||
244 | KisTool::setMode(mode); | 247 | KisTool::setMode(mode); | ||
245 | } | 248 | } | ||
246 | 249 | | |||
247 | void KisToolPaint::activatePickColor(AlternateAction action) | | |||
248 | { | | |||
249 | m_showColorPreview = true; | | |||
250 | | ||||
251 | requestUpdateOutline(m_outlineDocPoint, 0); | | |||
252 | | ||||
253 | int resource = colorPreviewResourceId(action); | | |||
254 | KoColor color = canvas()->resourceManager()->koColorResource(resource); | | |||
255 | | ||||
256 | KisCanvas2 * kisCanvas = dynamic_cast<KisCanvas2*>(canvas()); | | |||
257 | KIS_ASSERT_RECOVER_RETURN(kisCanvas); | | |||
258 | | ||||
259 | m_colorPreviewCurrentColor = kisCanvas->displayColorConverter()->toQColor(color); | | |||
260 | | ||||
261 | if (!m_colorPreviewBaseColor.isValid()) { | | |||
262 | m_colorPreviewBaseColor = m_colorPreviewCurrentColor; | | |||
263 | } | | |||
264 | } | | |||
265 | | ||||
266 | void KisToolPaint::deactivatePickColor(AlternateAction action) | | |||
267 | { | | |||
268 | Q_UNUSED(action); | | |||
269 | | ||||
270 | m_showColorPreview = false; | | |||
271 | m_oldColorPreviewRect = QRect(); | | |||
272 | m_oldColorPreviewUpdateRect = QRect(); | | |||
273 | m_colorPreviewCurrentColor = QColor(); | | |||
274 | } | | |||
275 | | ||||
276 | void KisToolPaint::pickColorWasOverridden() | | |||
277 | { | | |||
278 | m_colorPreviewShowComparePlate = false; | | |||
279 | m_colorPreviewBaseColor = QColor(); | | |||
280 | } | | |||
281 | | ||||
282 | void KisToolPaint::activateAlternateAction(AlternateAction action) | 250 | void KisToolPaint::activateAlternateAction(AlternateAction action) | ||
283 | { | 251 | { | ||
284 | switch (action) { | 252 | switch (action) { | ||
253 | case Secondary: | ||||
254 | // Falls through | ||||
285 | case PickFgNode: | 255 | case PickFgNode: | ||
286 | /* Falls through */ | 256 | // Falls through | ||
287 | case PickBgNode: | 257 | case PickBgNode: | ||
288 | /* Falls through */ | 258 | // Falls through | ||
289 | case PickFgImage: | 259 | case PickFgImage: | ||
290 | /* Falls through */ | 260 | // Falls through | ||
291 | case PickBgImage: | 261 | case PickBgImage: | ||
292 | delayedAction = action; | 262 | delayedAction = action; | ||
293 | m_colorPickerDelayTimer.start(100); | 263 | m_colorPickerDelayTimer.start(100); | ||
294 | /* Falls through */ | 264 | // Falls through | ||
295 | default: | 265 | default: | ||
296 | pickColorWasOverridden(); | 266 | pickColorWasOverridden(); | ||
297 | KisTool::activateAlternateAction(action); | 267 | KisTool::activateAlternateAction(action); | ||
298 | }; | 268 | }; | ||
299 | } | 269 | } | ||
300 | 270 | | |||
271 | void KisToolPaint::deactivateAlternateAction(AlternateAction action) | ||||
272 | { | ||||
273 | if (!isPickingAction(action)) { | ||||
274 | KisTool::deactivateAlternateAction(action); | ||||
275 | return; | ||||
276 | } | ||||
277 | | ||||
278 | delayedAction = KisTool::NONE; | ||||
279 | m_colorPickerDelayTimer.stop(); | ||||
280 | | ||||
281 | resetCursorStyle(); | ||||
282 | deactivatePickColor(action); | ||||
283 | } | ||||
284 | | ||||
301 | void KisToolPaint::activatePickColorDelayed() | 285 | void KisToolPaint::activatePickColorDelayed() | ||
302 | { | 286 | { | ||
303 | switch (delayedAction) { | 287 | switch (delayedAction) { | ||
288 | case Secondary: | ||||
289 | //Falls through, for now. | ||||
304 | case PickFgNode: | 290 | case PickFgNode: | ||
305 | useCursor(KisCursor::pickerLayerForegroundCursor()); | 291 | useCursor(KisCursor::pickerLayerForegroundCursor()); | ||
306 | activatePickColor(delayedAction); | 292 | activatePickColor(delayedAction); | ||
Context not available. | |||||
324 | repaintDecorations(); | 310 | repaintDecorations(); | ||
325 | } | 311 | } | ||
326 | 312 | | |||
327 | bool KisToolPaint::isPickingAction(AlternateAction action) { | 313 | void KisToolPaint::activatePickColor(AlternateAction action) | ||
328 | return action == PickFgNode || | 314 | { | ||
329 | action == PickBgNode || | 315 | m_showColorPreview = true; | ||
330 | action == PickFgImage || | 316 | | ||
331 | action == PickBgImage; | 317 | requestUpdateOutline(m_outlineDocPoint, 0); | ||
318 | | ||||
319 | int resource = colorPreviewResourceId(action); | ||||
320 | KoColor color = canvas()->resourceManager()->koColorResource(resource); | ||||
321 | | ||||
322 | KisCanvas2 *kisCanvas = dynamic_cast<KisCanvas2*>(canvas()); | ||||
323 | KIS_ASSERT_RECOVER_RETURN(kisCanvas); | ||||
324 | | ||||
325 | m_colorPreviewCurrentColor = kisCanvas->displayColorConverter()->toQColor(color); | ||||
326 | | ||||
327 | if (!m_colorPreviewBaseColor.isValid()) { | ||||
328 | m_colorPreviewBaseColor = m_colorPreviewCurrentColor; | ||||
329 | } | ||||
332 | } | 330 | } | ||
333 | 331 | | |||
334 | void KisToolPaint::deactivateAlternateAction(AlternateAction action) | 332 | void KisToolPaint::deactivatePickColor(AlternateAction action) | ||
335 | { | 333 | { | ||
336 | if (!isPickingAction(action)) { | 334 | Q_UNUSED(action); | ||
337 | KisTool::deactivateAlternateAction(action); | | |||
338 | return; | | |||
339 | } | | |||
340 | 335 | | |||
341 | delayedAction = KisTool::NONE; | 336 | m_showColorPreview = false; | ||
342 | m_colorPickerDelayTimer.stop(); | 337 | m_oldColorPreviewRect = QRect(); | ||
338 | m_oldColorPreviewUpdateRect = QRect(); | ||||
339 | m_colorPreviewCurrentColor = QColor(); | ||||
340 | } | ||||
343 | 341 | | |||
344 | resetCursorStyle(); | 342 | void KisToolPaint::pickColorWasOverridden() | ||
345 | deactivatePickColor(action); | 343 | { | ||
344 | m_colorPreviewShowComparePlate = false; | ||||
345 | m_colorPreviewBaseColor = QColor(); | ||||
346 | } | ||||
347 | | ||||
348 | bool KisToolPaint::isPickingAction(AlternateAction action) { | ||||
349 | return action == PickFgNode | ||||
350 | || action == PickBgNode | ||||
351 | || action == PickFgImage | ||||
352 | || action == PickBgImage | ||||
353 | || action == Secondary; | ||||
346 | } | 354 | } | ||
347 | 355 | | |||
348 | void KisToolPaint::addPickerJob(const PickingJob &pickingJob) | 356 | void KisToolPaint::addPickerJob(const PickingJob &pickingJob) | ||
Context not available. | |||||
357 | 365 | | |||
358 | const QPoint imagePoint = image()->documentToImagePixelFloored(pickingJob.documentPixel); | 366 | const QPoint imagePoint = image()->documentToImagePixelFloored(pickingJob.documentPixel); | ||
359 | const bool fromCurrentNode = pickingJob.action == PickFgNode || pickingJob.action == PickBgNode; | 367 | const bool fromCurrentNode = pickingJob.action == PickFgNode || pickingJob.action == PickBgNode; | ||
368 | | ||||
360 | m_pickingResource = colorPreviewResourceId(pickingJob.action); | 369 | m_pickingResource = colorPreviewResourceId(pickingJob.action); | ||
361 | 370 | | |||
362 | if (!fromCurrentNode) { | 371 | if (!fromCurrentNode) { | ||
Context not available. | |||||
375 | KisPaintDeviceSP device = fromCurrentNode ? | 384 | KisPaintDeviceSP device = fromCurrentNode ? | ||
376 | currentNode()->colorPickSourceDevice() : image()->projection(); | 385 | currentNode()->colorPickSourceDevice() : image()->projection(); | ||
377 | 386 | | |||
378 | // Used for color picker blending. | 387 | bool pure = !m_useDedicatePickerConfig; | ||
388 | | ||||
389 | // Used for color picker mixing. | ||||
379 | KoColor currentColor = canvas()->resourceManager()->foregroundColor(); | 390 | KoColor currentColor = canvas()->resourceManager()->foregroundColor(); | ||
380 | if( pickingJob.action == PickBgNode || pickingJob.action == PickBgImage ){ | 391 | if( pickingJob.action == PickBgNode || pickingJob.action == PickBgImage ){ | ||
381 | currentColor = canvas()->resourceManager()->backgroundColor(); | 392 | currentColor = canvas()->resourceManager()->backgroundColor(); | ||
382 | } | 393 | } | ||
383 | 394 | | |||
395 | auto *canv = dynamic_cast<KisCanvas2*>(canvas()); | ||||
396 | KIS_SAFE_ASSERT_RECOVER_RETURN(canv); | ||||
397 | | ||||
384 | image()->addJob(m_pickerStrokeId, | 398 | image()->addJob(m_pickerStrokeId, | ||
385 | new KisColorPickerStrokeStrategy::Data(device, imagePoint, currentColor)); | 399 | new KisColorPickerStrokeStrategy::Data(device, canv, imagePoint, currentColor, | ||
400 | m_pickerSettings.radius, m_pickerSettings.mix, pure)); | ||||
386 | } | 401 | } | ||
387 | 402 | | |||
388 | void KisToolPaint::beginAlternateAction(KoPointerEvent *event, AlternateAction action) | 403 | void KisToolPaint::beginAlternateAction(KoPointerEvent *event, AlternateAction action) | ||
Context not available. | |||||
429 | 444 | | |||
430 | int KisToolPaint::colorPreviewResourceId(AlternateAction action) | 445 | int KisToolPaint::colorPreviewResourceId(AlternateAction action) | ||
431 | { | 446 | { | ||
432 | bool toForegroundColor = action == PickFgNode || action == PickFgImage; | 447 | bool toBackgroundColor = action == PickBgNode || action == PickBgImage; | ||
433 | int resource = toForegroundColor ? | 448 | return toBackgroundColor ? KoCanvasResourceProvider::BackgroundColor : KoCanvasResourceProvider::ForegroundColor; | ||
434 | KoCanvasResourceProvider::ForegroundColor : KoCanvasResourceProvider::BackgroundColor; | | |||
435 | | ||||
436 | return resource; | | |||
437 | } | 449 | } | ||
438 | 450 | | |||
439 | void KisToolPaint::slotColorPickingFinished(const KoColor &color) | 451 | void KisToolPaint::slotColorPickingFinished(const KoColor &color) | ||
Context not available. | |||||
442 | 454 | | |||
443 | if (!m_showColorPreview) return; | 455 | if (!m_showColorPreview) return; | ||
444 | 456 | | |||
445 | KisCanvas2 * kisCanvas = dynamic_cast<KisCanvas2*>(canvas()); | 457 | KisCanvas2 *kisCanvas = dynamic_cast<KisCanvas2*>(canvas()); | ||
446 | KIS_ASSERT_RECOVER_RETURN(kisCanvas); | 458 | KIS_ASSERT_RECOVER_RETURN(kisCanvas); | ||
447 | QColor previewColor = kisCanvas->displayColorConverter()->toQColor(color); | 459 | QColor previewColor = kisCanvas->displayColorConverter()->toQColor(color); | ||
448 | 460 | | |||
Context not available. | |||||
561 | m_optionsWidgetLayout->addLayout(layout, rowCount, 0, 1, 2); | 573 | m_optionsWidgetLayout->addLayout(layout, rowCount, 0, 1, 2); | ||
562 | } | 574 | } | ||
563 | 575 | | |||
564 | | ||||
565 | void KisToolPaint::addOptionWidgetOption(QWidget *control, QWidget *label) | 576 | void KisToolPaint::addOptionWidgetOption(QWidget *control, QWidget *label) | ||
566 | { | 577 | { | ||
567 | Q_ASSERT(m_optionsWidgetLayout != 0); | 578 | Q_ASSERT(m_optionsWidgetLayout != 0); | ||
Context not available. | |||||
574 | } | 585 | } | ||
575 | } | 586 | } | ||
576 | 587 | | |||
577 | | ||||
578 | void KisToolPaint::setOpacity(qreal opacity) | 588 | void KisToolPaint::setOpacity(qreal opacity) | ||
579 | { | 589 | { | ||
580 | m_opacity = quint8(opacity * OPACITY_OPAQUE_U8); | 590 | m_opacity = quint8(opacity * OPACITY_OPAQUE_U8); | ||
Context not available. | |||||
738 | 748 | | |||
739 | // DIRTY HACK ALERT: we should fetch the assistant's dirty rect when requesting | 749 | // DIRTY HACK ALERT: we should fetch the assistant's dirty rect when requesting | ||
740 | // the update, instead of just dumbly update the entire canvas! | 750 | // the update, instead of just dumbly update the entire canvas! | ||
741 | 751 | KisCanvas2 *kiscanvas = dynamic_cast<KisCanvas2*>(canvas()); | |||
742 | KisCanvas2 * kiscanvas = dynamic_cast<KisCanvas2*>(canvas()); | | |||
743 | KisPaintingAssistantsDecorationSP decoration = kiscanvas->paintingAssistantsDecoration(); | 752 | KisPaintingAssistantsDecorationSP decoration = kiscanvas->paintingAssistantsDecoration(); | ||
744 | if (decoration && decoration->visible()) { | 753 | if (decoration && decoration->visible()) { | ||
745 | kiscanvas->updateCanvas(); | 754 | kiscanvas->updateCanvas(); | ||
Context not available. | |||||
779 | 788 | | |||
780 | return path; | 789 | return path; | ||
781 | } | 790 | } | ||
782 | | ||||
Context not available. |