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. | ||||
163 | } | 165 | } | ||
164 | 166 | | |||
165 | void KisToolPaint::deactivate() | 167 | void KisToolPaint::deactivate() | ||
Context not available. | |||||
244 | KisTool::setMode(mode); | 246 | KisTool::setMode(mode); | ||
245 | } | 247 | } | ||
246 | 248 | | |||
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) | 249 | void KisToolPaint::activateAlternateAction(AlternateAction action) | ||
283 | { | 250 | { | ||
284 | switch (action) { | 251 | switch (action) { | ||
252 | case Secondary: | ||||
253 | // Falls through | ||||
285 | case PickFgNode: | 254 | case PickFgNode: | ||
286 | /* Falls through */ | 255 | // Falls through | ||
287 | case PickBgNode: | 256 | case PickBgNode: | ||
288 | /* Falls through */ | 257 | // Falls through | ||
289 | case PickFgImage: | 258 | case PickFgImage: | ||
290 | /* Falls through */ | 259 | // Falls through | ||
291 | case PickBgImage: | 260 | case PickBgImage: | ||
292 | delayedAction = action; | 261 | delayedAction = action; | ||
293 | m_colorPickerDelayTimer.start(100); | 262 | m_colorPickerDelayTimer.start(100); | ||
294 | /* Falls through */ | 263 | // Falls through | ||
295 | default: | 264 | default: | ||
296 | pickColorWasOverridden(); | 265 | pickColorWasOverridden(); | ||
297 | KisTool::activateAlternateAction(action); | 266 | KisTool::activateAlternateAction(action); | ||
298 | }; | 267 | }; | ||
299 | } | 268 | } | ||
300 | 269 | | |||
270 | void KisToolPaint::deactivateAlternateAction(AlternateAction action) | ||||
271 | { | ||||
272 | if (!isPickingAction(action)) { | ||||
273 | KisTool::deactivateAlternateAction(action); | ||||
274 | return; | ||||
275 | } | ||||
276 | | ||||
277 | delayedAction = KisTool::NONE; | ||||
278 | m_colorPickerDelayTimer.stop(); | ||||
279 | | ||||
280 | resetCursorStyle(); | ||||
281 | deactivatePickColor(action); | ||||
282 | } | ||||
283 | | ||||
301 | void KisToolPaint::activatePickColorDelayed() | 284 | void KisToolPaint::activatePickColorDelayed() | ||
302 | { | 285 | { | ||
303 | switch (delayedAction) { | 286 | switch (delayedAction) { | ||
287 | case Secondary: | ||||
288 | //Falls through, for now. | ||||
304 | case PickFgNode: | 289 | case PickFgNode: | ||
305 | useCursor(KisCursor::pickerLayerForegroundCursor()); | 290 | useCursor(KisCursor::pickerLayerForegroundCursor()); | ||
306 | activatePickColor(delayedAction); | 291 | activatePickColor(delayedAction); | ||
Context not available. | |||||
324 | repaintDecorations(); | 309 | repaintDecorations(); | ||
325 | } | 310 | } | ||
326 | 311 | | |||
327 | bool KisToolPaint::isPickingAction(AlternateAction action) { | 312 | void KisToolPaint::activatePickColor(AlternateAction action) | ||
328 | return action == PickFgNode || | 313 | { | ||
329 | action == PickBgNode || | 314 | m_showColorPreview = true; | ||
330 | action == PickFgImage || | 315 | | ||
331 | action == PickBgImage; | 316 | requestUpdateOutline(m_outlineDocPoint, 0); | ||
317 | | ||||
318 | int resource = colorPreviewResourceId(action); | ||||
319 | KoColor color = canvas()->resourceManager()->koColorResource(resource); | ||||
320 | | ||||
321 | KisCanvas2 *kisCanvas = dynamic_cast<KisCanvas2*>(canvas()); | ||||
322 | KIS_ASSERT_RECOVER_RETURN(kisCanvas); | ||||
323 | | ||||
324 | m_colorPreviewCurrentColor = kisCanvas->displayColorConverter()->toQColor(color); | ||||
325 | | ||||
326 | if (!m_colorPreviewBaseColor.isValid()) { | ||||
327 | m_colorPreviewBaseColor = m_colorPreviewCurrentColor; | ||||
328 | } | ||||
332 | } | 329 | } | ||
333 | 330 | | |||
334 | void KisToolPaint::deactivateAlternateAction(AlternateAction action) | 331 | void KisToolPaint::deactivatePickColor(AlternateAction action) | ||
335 | { | 332 | { | ||
336 | if (!isPickingAction(action)) { | 333 | Q_UNUSED(action); | ||
337 | KisTool::deactivateAlternateAction(action); | | |||
338 | return; | | |||
339 | } | | |||
340 | 334 | | |||
341 | delayedAction = KisTool::NONE; | 335 | m_showColorPreview = false; | ||
342 | m_colorPickerDelayTimer.stop(); | 336 | m_oldColorPreviewRect = QRect(); | ||
337 | m_oldColorPreviewUpdateRect = QRect(); | ||||
338 | m_colorPreviewCurrentColor = QColor(); | ||||
339 | } | ||||
343 | 340 | | |||
344 | resetCursorStyle(); | 341 | void KisToolPaint::pickColorWasOverridden() | ||
345 | deactivatePickColor(action); | 342 | { | ||
343 | m_colorPreviewShowComparePlate = false; | ||||
344 | m_colorPreviewBaseColor = QColor(); | ||||
345 | } | ||||
346 | | ||||
347 | bool KisToolPaint::isPickingAction(AlternateAction action) { | ||||
348 | return action == PickFgNode | ||||
349 | || action == PickBgNode | ||||
350 | || action == PickFgImage | ||||
351 | || action == PickBgImage | ||||
352 | || action == Secondary; | ||||
346 | } | 353 | } | ||
347 | 354 | | |||
348 | void KisToolPaint::addPickerJob(const PickingJob &pickingJob) | 355 | void KisToolPaint::addPickerJob(const PickingJob &pickingJob) | ||
Context not available. | |||||
357 | 364 | | |||
358 | const QPoint imagePoint = image()->documentToImagePixelFloored(pickingJob.documentPixel); | 365 | const QPoint imagePoint = image()->documentToImagePixelFloored(pickingJob.documentPixel); | ||
359 | const bool fromCurrentNode = pickingJob.action == PickFgNode || pickingJob.action == PickBgNode; | 366 | const bool fromCurrentNode = pickingJob.action == PickFgNode || pickingJob.action == PickBgNode; | ||
367 | | ||||
360 | m_pickingResource = colorPreviewResourceId(pickingJob.action); | 368 | m_pickingResource = colorPreviewResourceId(pickingJob.action); | ||
361 | 369 | | |||
362 | if (!fromCurrentNode) { | 370 | if (!fromCurrentNode) { | ||
Context not available. | |||||
375 | KisPaintDeviceSP device = fromCurrentNode ? | 383 | KisPaintDeviceSP device = fromCurrentNode ? | ||
376 | currentNode()->colorPickSourceDevice() : image()->projection(); | 384 | currentNode()->colorPickSourceDevice() : image()->projection(); | ||
377 | 385 | | |||
378 | // Used for color picker blending. | 386 | // Used for color picker mixing. | ||
379 | KoColor currentColor = canvas()->resourceManager()->foregroundColor(); | 387 | KoColor currentColor = canvas()->resourceManager()->foregroundColor(); | ||
380 | if( pickingJob.action == PickBgNode || pickingJob.action == PickBgImage ){ | 388 | if( pickingJob.action == PickBgNode || pickingJob.action == PickBgImage ){ | ||
381 | currentColor = canvas()->resourceManager()->backgroundColor(); | 389 | currentColor = canvas()->resourceManager()->backgroundColor(); | ||
382 | } | 390 | } | ||
383 | 391 | | |||
392 | bool pure = pickingJob.action == Secondary ? true : false; | ||||
393 | | ||||
394 | auto *canv = dynamic_cast<KisCanvas2*>(canvas()); | ||||
395 | KIS_SAFE_ASSERT_RECOVER_RETURN(canv); | ||||
396 | | ||||
384 | image()->addJob(m_pickerStrokeId, | 397 | image()->addJob(m_pickerStrokeId, | ||
385 | new KisColorPickerStrokeStrategy::Data(device, imagePoint, currentColor)); | 398 | new KisColorPickerStrokeStrategy::Data(device, canv, imagePoint, currentColor, | ||
399 | m_pickerSettings.radius, m_pickerSettings.mix, pure)); | ||||
386 | } | 400 | } | ||
387 | 401 | | |||
388 | void KisToolPaint::beginAlternateAction(KoPointerEvent *event, AlternateAction action) | 402 | void KisToolPaint::beginAlternateAction(KoPointerEvent *event, AlternateAction action) | ||
Context not available. | |||||
429 | 443 | | |||
430 | int KisToolPaint::colorPreviewResourceId(AlternateAction action) | 444 | int KisToolPaint::colorPreviewResourceId(AlternateAction action) | ||
431 | { | 445 | { | ||
432 | bool toForegroundColor = action == PickFgNode || action == PickFgImage; | 446 | bool toBackgroundColor = action == PickBgNode || action == PickBgImage; | ||
433 | int resource = toForegroundColor ? | 447 | return toBackgroundColor ? KoCanvasResourceProvider::BackgroundColor : KoCanvasResourceProvider::ForegroundColor; | ||
434 | KoCanvasResourceProvider::ForegroundColor : KoCanvasResourceProvider::BackgroundColor; | | |||
435 | | ||||
436 | return resource; | | |||
437 | } | 448 | } | ||
438 | 449 | | |||
439 | void KisToolPaint::slotColorPickingFinished(const KoColor &color) | 450 | void KisToolPaint::slotColorPickingFinished(const KoColor &color) | ||
Context not available. | |||||
442 | 453 | | |||
443 | if (!m_showColorPreview) return; | 454 | if (!m_showColorPreview) return; | ||
444 | 455 | | |||
445 | KisCanvas2 * kisCanvas = dynamic_cast<KisCanvas2*>(canvas()); | 456 | KisCanvas2 *kisCanvas = dynamic_cast<KisCanvas2*>(canvas()); | ||
446 | KIS_ASSERT_RECOVER_RETURN(kisCanvas); | 457 | KIS_ASSERT_RECOVER_RETURN(kisCanvas); | ||
447 | QColor previewColor = kisCanvas->displayColorConverter()->toQColor(color); | 458 | QColor previewColor = kisCanvas->displayColorConverter()->toQColor(color); | ||
448 | 459 | | |||
Context not available. | |||||
561 | m_optionsWidgetLayout->addLayout(layout, rowCount, 0, 1, 2); | 572 | m_optionsWidgetLayout->addLayout(layout, rowCount, 0, 1, 2); | ||
562 | } | 573 | } | ||
563 | 574 | | |||
564 | | ||||
565 | void KisToolPaint::addOptionWidgetOption(QWidget *control, QWidget *label) | 575 | void KisToolPaint::addOptionWidgetOption(QWidget *control, QWidget *label) | ||
566 | { | 576 | { | ||
567 | Q_ASSERT(m_optionsWidgetLayout != 0); | 577 | Q_ASSERT(m_optionsWidgetLayout != 0); | ||
Context not available. | |||||
574 | } | 584 | } | ||
575 | } | 585 | } | ||
576 | 586 | | |||
577 | | ||||
578 | void KisToolPaint::setOpacity(qreal opacity) | 587 | void KisToolPaint::setOpacity(qreal opacity) | ||
579 | { | 588 | { | ||
580 | m_opacity = quint8(opacity * OPACITY_OPAQUE_U8); | 589 | m_opacity = quint8(opacity * OPACITY_OPAQUE_U8); | ||
Context not available. | |||||
738 | 747 | | |||
739 | // DIRTY HACK ALERT: we should fetch the assistant's dirty rect when requesting | 748 | // DIRTY HACK ALERT: we should fetch the assistant's dirty rect when requesting | ||
740 | // the update, instead of just dumbly update the entire canvas! | 749 | // the update, instead of just dumbly update the entire canvas! | ||
741 | 750 | KisCanvas2 *kiscanvas = dynamic_cast<KisCanvas2*>(canvas()); | |||
742 | KisCanvas2 * kiscanvas = dynamic_cast<KisCanvas2*>(canvas()); | | |||
743 | KisPaintingAssistantsDecorationSP decoration = kiscanvas->paintingAssistantsDecoration(); | 751 | KisPaintingAssistantsDecorationSP decoration = kiscanvas->paintingAssistantsDecoration(); | ||
744 | if (decoration && decoration->visible()) { | 752 | if (decoration && decoration->visible()) { | ||
745 | kiscanvas->updateCanvas(); | 753 | kiscanvas->updateCanvas(); | ||
Context not available. | |||||
779 | 787 | | |||
780 | return path; | 788 | return path; | ||
781 | } | 789 | } | ||
782 | | ||||
Context not available. |