diff --git a/krita/krita.action b/krita/krita.action
--- a/krita/krita.action
+++ b/krita/krita.action
@@ -353,6 +353,19 @@
true
+
+
+ Toggle erase op
+
+ Toggle eraser op
+ Toggle eraser op
+ 10000
+ 0
+ Shift+E
+ Shift+E
+
+
+
view-refresh
Reload Original Preset
diff --git a/krita/ui/kis_canvas_resource_provider.h b/krita/ui/kis_canvas_resource_provider.h
--- a/krita/ui/kis_canvas_resource_provider.h
+++ b/krita/ui/kis_canvas_resource_provider.h
@@ -59,6 +59,7 @@
CurrentImage,
CurrentKritaNode,
CurrentPaintOpPreset,
+ CurrentEraserMode,
CurrentGeneratorConfiguration,
CurrentCompositeOp,
MirrorHorizontal,
@@ -107,6 +108,9 @@
KisPaintOpPresetSP previousPreset() const;
void setPreviousPaintOpPreset(const KisPaintOpPresetSP preset);
+ bool currentEraserMode() const;
+ void setEraserMode(const bool mode);
+
KisFilterConfiguration* currentGeneratorConfiguration() const;
void setCurrentCompositeOp(const QString& compositeOp);
diff --git a/krita/ui/kis_canvas_resource_provider.cpp b/krita/ui/kis_canvas_resource_provider.cpp
--- a/krita/ui/kis_canvas_resource_provider.cpp
+++ b/krita/ui/kis_canvas_resource_provider.cpp
@@ -179,6 +179,20 @@
m_resourceManager->setResource(CurrentPaintOpPreset, v);
}
+
+
+bool KisCanvasResourceProvider::currentEraserMode() const
+{
+ return m_resourceManager->resource(CurrentEraserMode).value();
+}
+
+void KisCanvasResourceProvider::setEraserMode(const bool eraserMode)
+{
+ dbgUI << "setEraserMode" << eraserMode;
+ m_resourceManager->setResource(CurrentEraserMode, qVariantFromValue(eraserMode));
+}
+
+
KisPaintOpPresetSP KisCanvasResourceProvider::previousPreset() const
{
KisPaintOpPresetSP preset = m_resourceManager->resource(PreviousPaintOpPreset).value();
diff --git a/krita/ui/kis_paintop_box.h b/krita/ui/kis_paintop_box.h
--- a/krita/ui/kis_paintop_box.h
+++ b/krita/ui/kis_paintop_box.h
@@ -141,7 +141,8 @@
void slotUpdatePreset();
void slotSetupDefaultPreset();
void slotNodeChanged(const KisNodeSP node);
- void slotToggleEraseMode(bool checked);
+ void slotToggleEraserMode(bool checked);
+ void slotToggleEraseOp();
void slotSetCompositeMode(int index);
void slotSetPaintop(const QString& paintOpId);
void slotHorizontalMirrorChanged(bool value);
@@ -164,7 +165,7 @@
void slotSaveLockedOptionToPreset(KisPropertiesConfiguration* p);
void slotDropLockedOption(KisPropertiesConfiguration* p);
void slotDirtyPresetToggled(bool);
- void slotEraserBrushSizeToggled(bool);
+ void slotEraserBrushSizeToggled(bool);
void slotUpdateSelectionIcon();
private:
@@ -190,6 +191,7 @@
KisFavoriteResourceManager* m_favoriteResourceManager;
QToolButton* m_reloadButton;
KisAction* m_eraseAction;
+ KisAction* m_eraseOpAction;
KisAction* m_reloadAction;
QString m_prevCompositeOpID;
@@ -202,6 +204,7 @@
KisAction* m_hMirrorAction;
KisAction* m_vMirrorAction;
+ // Tracking tools seems to duplicate functionality in KoToolManager?
struct TabletToolID {
TabletToolID(const KoInputDevice& dev) {
uniqueID = dev.uniqueTabletId();
@@ -241,7 +244,7 @@
bool m_blockUpdate;
bool m_dirtyPresetsEnabled;
bool m_eraserBrushSizeEnabled;
-
+ bool m_currentEraserMode;
};
diff --git a/krita/ui/kis_paintop_box.cc b/krita/ui/kis_paintop_box.cc
--- a/krita/ui/kis_paintop_box.cc
+++ b/krita/ui/kis_paintop_box.cc
@@ -135,10 +135,15 @@
m_eraseModeButton = new QToolButton(this);
m_eraseModeButton->setFixedSize(iconsize, iconsize);
m_eraseModeButton->setCheckable(true);
+ m_eraseModeButton->setChecked(m_resourceProvider->currentEraserMode());
m_eraseAction = m_viewManager->actionManager()->createAction("erase_action");
+ m_eraseAction->setChecked(m_resourceProvider->currentEraserMode());
m_eraseModeButton->setDefaultAction(m_eraseAction);
+ m_eraseOpAction = m_viewManager->actionManager()->createAction("erase_op");
+
+
eraserBrushSize = 0; // brush size changed when using erase mode
m_reloadButton = new QToolButton(this);
@@ -370,22 +375,23 @@
}
m_presetsPopup->setPaintOpList(factoryList);
- connect(m_presetsPopup , SIGNAL(paintopActivated(QString)) , SLOT(slotSetPaintop(QString)));
- connect(m_presetsPopup , SIGNAL(savePresetClicked()) , SLOT(slotSaveActivePreset()));
- connect(m_presetsPopup , SIGNAL(defaultPresetClicked()) , SLOT(slotSetupDefaultPreset()));
- connect(m_presetsPopup , SIGNAL(signalResourceSelected(KoResource*)), SLOT(resourceSelected(KoResource*)));
- connect(m_presetsPopup , SIGNAL(reloadPresetClicked()) , SLOT(slotReloadPreset()));
- connect(m_presetsPopup , SIGNAL(dirtyPresetToggled(bool)) , SLOT(slotDirtyPresetToggled(bool)));
- connect(m_presetsPopup , SIGNAL(eraserBrushSizeToggled(bool)) , SLOT(slotEraserBrushSizeToggled(bool)));
+ connect(m_presetsPopup , SIGNAL(paintopActivated(QString)) , SLOT(slotSetPaintop(QString)));
+ connect(m_presetsPopup , SIGNAL(savePresetClicked()) , SLOT(slotSaveActivePreset()));
+ connect(m_presetsPopup , SIGNAL(defaultPresetClicked()) , SLOT(slotSetupDefaultPreset()));
+ connect(m_presetsPopup , SIGNAL(signalResourceSelected(KoResource*)), SLOT(resourceSelected(KoResource*)));
+ connect(m_presetsPopup , SIGNAL(reloadPresetClicked()) , SLOT(slotReloadPreset()));
+ connect(m_presetsPopup , SIGNAL(dirtyPresetToggled(bool)) , SLOT(slotDirtyPresetToggled(bool)));
+ connect(m_presetsPopup , SIGNAL(eraserBrushSizeToggled(bool)) , SLOT(slotEraserBrushSizeToggled(bool)));
- connect(m_presetsChooserPopup, SIGNAL(resourceSelected(KoResource*)) , SLOT(resourceSelected(KoResource*)));
- connect(m_resourceProvider , SIGNAL(sigNodeChanged(const KisNodeSP)) , SLOT(slotNodeChanged(const KisNodeSP)));
- connect(m_cmbCompositeOp , SIGNAL(currentIndexChanged(int)) , SLOT(slotSetCompositeMode(int)));
- connect(m_eraseAction , SIGNAL(triggered(bool)) , SLOT(slotToggleEraseMode(bool)));
- connect(alphaLockAction , SIGNAL(triggered(bool)) , SLOT(slotToggleAlphaLockMode(bool)));
- connect(m_hMirrorAction , SIGNAL(triggered(bool)) , SLOT(slotHorizontalMirrorChanged(bool)));
- connect(m_vMirrorAction , SIGNAL(triggered(bool)) , SLOT(slotVerticalMirrorChanged(bool)));
- connect(m_reloadAction , SIGNAL(triggered()) , SLOT(slotReloadPreset()));
+ connect(m_presetsChooserPopup , SIGNAL(resourceSelected(KoResource*)) , SLOT(resourceSelected(KoResource*)));
+ connect(m_resourceProvider , SIGNAL(sigNodeChanged(const KisNodeSP)) , SLOT(slotNodeChanged(const KisNodeSP)));
+ connect(m_cmbCompositeOp , SIGNAL(currentIndexChanged(int)) , SLOT(slotSetCompositeMode(int)));
+ connect(m_eraseAction , SIGNAL(triggered(bool)) , SLOT(slotToggleEraserMode(bool)));
+ connect(m_eraseOpAction , SIGNAL(triggered()) , SLOT(slotToggleEraseOp()));
+ connect(alphaLockAction , SIGNAL(triggered(bool)) , SLOT(slotToggleAlphaLockMode(bool)));
+ connect(m_hMirrorAction , SIGNAL(triggered(bool)) , SLOT(slotHorizontalMirrorChanged(bool)));
+ connect(m_vMirrorAction , SIGNAL(triggered(bool)) , SLOT(slotVerticalMirrorChanged(bool)));
+ connect(m_reloadAction , SIGNAL(triggered()) , SLOT(slotReloadPreset()));
connect(m_sliderChooser[0]->getWidget("opacity"), SIGNAL(valueChanged(qreal)), SLOT(slotSlider1Changed()));
connect(m_sliderChooser[0]->getWidget("flow") , SIGNAL(valueChanged(qreal)), SLOT(slotSlider1Changed()));
@@ -604,13 +610,6 @@
m_cmbCompositeOp->selectCompositeOp(KoID(compositeOpID));
m_cmbCompositeOp->blockSignals(false);
- m_eraseModeButton->defaultAction()->blockSignals(true);
- m_eraseModeButton->blockSignals(true);
- m_eraseModeButton->setChecked(compositeOpID == COMPOSITE_ERASE);
- m_eraseModeButton->defaultAction()->setChecked(compositeOpID == COMPOSITE_ERASE);
- m_eraseModeButton->blockSignals(false);
- m_eraseModeButton->defaultAction()->blockSignals(false);
-
if (compositeOpID != m_currCompositeOpID) {
m_resourceProvider->currentPreset()->settings()->setPaintOpCompositeOp(compositeOpID);
m_optionWidget->setConfiguration(m_resourceProvider->currentPreset()->settings().data());
@@ -666,6 +665,15 @@
void KisPaintopBox::slotInputDeviceChanged(const KoInputDevice& inputDevice)
{
+ // We will intercept cursor type and force it to be an eraser if eraserMode = true.
+ // This seems to duplicate functionality in KoToolManager.
+ KoInputDevice modInputDevice;
+ if (m_resourceProvider->currentEraserMode()) {
+ modInputDevice = KoInputDevice(inputDevice.device(), QTabletEvent::Eraser, inputDevice.uniqueTabletId());
+ }
+ else {
+ modInputDevice = inputDevice;
+ }
TabletToolMap::iterator toolData = m_tabletToolMap.find(inputDevice);
if (toolData == m_tabletToolMap.end()) {
@@ -710,14 +718,17 @@
m_cmbCompositeOp->blockSignals(true);
m_cmbCompositeOp->selectCompositeOp(KoID(compositeOp));
m_cmbCompositeOp->blockSignals(false);
+ }
+ if (m_eraseModeButton->isChecked() != m_resourceProvider->currentEraserMode()) {
m_eraseModeButton->defaultAction()->blockSignals(true);
m_eraseModeButton->blockSignals(true);
- m_eraseModeButton->setChecked(compositeOp == COMPOSITE_ERASE);
- m_eraseModeButton->defaultAction()->setChecked(compositeOp == COMPOSITE_ERASE);
+ m_eraseModeButton->setChecked(m_resourceProvider->currentEraserMode());
+ m_eraseModeButton->defaultAction()->setChecked(m_resourceProvider->currentEraserMode());
m_eraseModeButton->blockSignals(false);
m_eraseModeButton->defaultAction()->blockSignals(false);
}
+
sender()->blockSignals(false);
}
}
@@ -825,10 +836,20 @@
m_cmbCompositeOp->validate(colorSpace);
}
-void KisPaintopBox::slotToggleEraseMode(bool checked)
+void KisPaintopBox::slotToggleEraserMode(bool checked)
{
- if (checked)
+ // Update. These two calls should always be made together!
+ KoToolManager::instance()->setEraserMode(checked);
+ m_resourceProvider->setEraserMode(checked);
+ // toggleHighlightedButton(m_eraseModeButton);
+}
+
+void KisPaintopBox::slotToggleEraseOp()
+{
+ bool switchingToErase = false;
+ if (m_currCompositeOpID != COMPOSITE_ERASE) // Note - can't handle both ops being erasers. Whatever!
{
+ switchingToErase = true;
updateCompositeOp(COMPOSITE_ERASE);
//add an option to enable eraser brush size
if (m_eraserBrushSizeEnabled==true)
@@ -862,7 +883,7 @@
//update value in UI (this is the main place the value is 'stored' in memory)
- qreal updateSize = checked ? eraserBrushSize : normalBrushSize;
+ qreal updateSize = switchingToErase ? eraserBrushSize : normalBrushSize;
m_sliderChooser[0]->getWidget("size")->setValue(updateSize);
m_sliderChooser[1]->getWidget("size")->setValue(updateSize);
m_sliderChooser[2]->getWidget("size")->setValue(updateSize);
@@ -1072,6 +1093,7 @@
m_tool->setPalette(p);
}
}
+
void KisPaintopBox::slotReloadPreset()
{
KisSignalsBlocker blocker(m_optionWidget);
diff --git a/krita/ui/widgets/kis_workspace_chooser.h b/krita/ui/widgets/kis_workspace_chooser.h
--- a/krita/ui/widgets/kis_workspace_chooser.h
+++ b/krita/ui/widgets/kis_workspace_chooser.h
@@ -43,6 +43,7 @@
KoResourceItemChooser * m_itemChooser;
KisViewManager* m_view;
QLineEdit* m_nameEdit;
+ bool eraseMode;
};
#endif // KIS_WORKSPACE_CHOOSER_H
diff --git a/libs/flake/KoInputDevice.h b/libs/flake/KoInputDevice.h
--- a/libs/flake/KoInputDevice.h
+++ b/libs/flake/KoInputDevice.h
@@ -49,7 +49,7 @@
explicit KoInputDevice(QTabletEvent::TabletDevice device, QTabletEvent::PointerType pointer, qint64 uniqueTabletId = -1);
/**
- * Constructor for the mouse as input device.
+ * Constructor for the default input device.
*/
KoInputDevice();
@@ -87,7 +87,6 @@
static KoInputDevice stylus(); ///< Wacom style/pen
static KoInputDevice eraser(); ///< Wacom eraser
-
private:
class Private;
Private * const d;
diff --git a/libs/flake/KoInputDevice.cpp b/libs/flake/KoInputDevice.cpp
--- a/libs/flake/KoInputDevice.cpp
+++ b/libs/flake/KoInputDevice.cpp
@@ -39,6 +39,7 @@
{
}
+// Should this return Stylus by default??
KoInputDevice::KoInputDevice()
: d(new Private(QTabletEvent::NoDevice, QTabletEvent::UnknownPointer, -1, true))
{
@@ -85,6 +86,13 @@
d->uniqueTabletId == other.d->uniqueTabletId && d->mouse == other.d->mouse;
}
+// bool KoInputDevice::sameDevice(const KoInputDevice &other) const
+// {
+// return d->device == other.d->device &&
+// d->uniqueTabletId == other.d->uniqueTabletId &&
+// d->mouse == other.d->mouse;
+// }
+
bool KoInputDevice::operator!=(const KoInputDevice &other) const
{
return !(operator==(other));
diff --git a/libs/flake/KoToolManager.h b/libs/flake/KoToolManager.h
--- a/libs/flake/KoToolManager.h
+++ b/libs/flake/KoToolManager.h
@@ -256,6 +256,17 @@
void switchInputDeviceRequested(const KoInputDevice &id);
/**
+ * Request using an eraser as the default tool.
+ */
+ void setEraserMode(bool mode);
+
+ /**
+ * Request changing to default input device.
+ * @param id the id of the input device
+ */
+ void resetInputDeviceRequested();
+
+ /**
* a new tool has become known to mankind
*/
void addDeferredToolFactory(KoToolFactoryBase *toolFactory);
@@ -322,6 +333,7 @@
*/
void addedTool(KoToolAction *toolAction, KoCanvasController *canvas);
+
private:
KoToolManager(const KoToolManager&);
KoToolManager operator=(const KoToolManager&);
diff --git a/libs/flake/KoToolManager.cpp b/libs/flake/KoToolManager.cpp
--- a/libs/flake/KoToolManager.cpp
+++ b/libs/flake/KoToolManager.cpp
@@ -71,11 +71,11 @@
{
public:
CanvasData(KoCanvasController *cc, const KoInputDevice &id)
- : activeTool(0),
- canvas(cc),
- inputDevice(id),
- dummyToolWidget(0),
- dummyToolLabel(0)
+ : activeTool(0)
+ , canvas(cc)
+ , inputDevice(id)
+ , dummyToolWidget(0)
+ , dummyToolLabel(0)
{
}
@@ -173,18 +173,20 @@
disabledCanvasShortcuts.clear();
}
- KoToolBase *activeTool; // active Tool
- QString activeToolId; // the id of the active Tool
+ KoToolBase *activeTool; // active Tool
+ QString activeToolId; // the id of the active Tool
QString activationShapeId; // the shape-type (KoShape::shapeId()) the activeTool 'belongs' to.
QHash allTools; // all the tools that are created for this canvas.
QStack stack; // stack of temporary tools
KoCanvasController *const canvas;
const KoInputDevice inputDevice;
+ KoInputDevice eraserStashedDevice;
QWidget *dummyToolWidget; // the widget shown in the toolDocker.
QLabel *dummyToolLabel;
QList > disabledActions; ///< disabled conflicting actions
QList > disabledDisabledActions; ///< disabled conflicting actions that were already disabled
QMap, QString> disabledCanvasShortcuts; ///< Shortcuts that were temporarily removed from canvas actions because the tool overrides
+
};
@@ -321,6 +323,18 @@
d->switchInputDevice(id);
}
+void KoToolManager::setEraserMode(bool mode)
+{
+ d->setEraserMode(mode);
+}
+
+void KoToolManager::resetInputDeviceRequested()
+{
+ if (!d->canvasData) return;
+ d->resetInputDevice();
+}
+
+
void KoToolManager::switchToolTemporaryRequested(const QString &id)
{
d->switchTool(id, true);
@@ -592,6 +606,17 @@
}
+void KoToolManager::Private::setEraserMode(bool mode)
+{
+ eraserMode = mode;
+
+ if (mode) {
+ stashedEraserDevice = inputDevice;
+ switchInputDevice(inputDevice);
+ } else {
+ switchInputDevice(stashedEraserDevice);
+ }
+}
void KoToolManager::Private::disconnectActiveTool()
{
@@ -1006,17 +1031,37 @@
proxy->setActiveTool(canUseTool ? canvasData->activeTool : 0);
}
-void KoToolManager::Private::switchInputDevice(const KoInputDevice &device)
+
+void KoToolManager::Private::resetInputDevice()
+{
+ KoInputDevice id;
+ switchInputDevice(id);
+}
+
+void KoToolManager::Private::switchInputDevice(const KoInputDevice &hardwareDevice)
{
Q_ASSERT(canvasData);
if (!canvasData) return;
+
+ // Override with eraser if we are in eraser mode
+ KoInputDevice device;
+ if (eraserMode) {
+ device = KoInputDevice(hardwareDevice.device(),
+ QTabletEvent::Eraser,
+ hardwareDevice.uniqueTabletId());
+ } else {
+ device = hardwareDevice;
+ }
+
+
+
if (inputDevice == device) return;
if (inputDevice.isMouse() && device.isMouse()) return;
if (device.isMouse() && !inputDevice.isMouse()) {
// we never switch back to mouse from a tablet input device, so the user can use the
// mouse to edit the settings for a tool activated by a tablet. See bugs
// https://bugs.kde.org/show_bug.cgi?id=283130 and https://bugs.kde.org/show_bug.cgi?id=285501.
- // We do continue to switch between tablet devices, thought.
+ // We do continue to switch between tablet devices, though.
return;
}
diff --git a/libs/flake/KoToolManager_p.h b/libs/flake/KoToolManager_p.h
--- a/libs/flake/KoToolManager_p.h
+++ b/libs/flake/KoToolManager_p.h
@@ -53,6 +53,7 @@
void connectActiveTool();
void disconnectActiveTool();
+ void setEraserMode(bool mode);
void switchTool(KoToolBase *tool, bool temporary);
void switchTool(const QString &id, bool temporary);
void postSwitchTool(bool temporary);
@@ -76,7 +77,13 @@
* Request a switch from to the param input device.
* This will cause the tool for that device to be selected.
*/
- void switchInputDevice(const KoInputDevice &device);
+ void switchInputDevice(const KoInputDevice &hardwareDevice);
+
+
+ /**
+ * Request a switch to the default input device.
+ */
+ void resetInputDevice();
/**
* Whenever a new tool proxy class is instantiated, it will use this method to register itself
@@ -103,6 +110,11 @@
KoInputDevice inputDevice;
bool layerExplicitlyDisabled;
+
+ /// Save the true device that was used when eraser mode was activated.
+ /// Pressing "eraser mode" twice in a row returns to the original tool.
+ KoInputDevice stashedEraserDevice;
+ bool eraserMode;
};
class ShortcutToolAction;
diff --git a/libs/flake/KoToolProxy.cpp b/libs/flake/KoToolProxy.cpp
--- a/libs/flake/KoToolProxy.cpp
+++ b/libs/flake/KoToolProxy.cpp
@@ -182,8 +182,7 @@
KoPointerEvent ev(event, point, touchPoints);
- KoInputDevice id;
- KoToolManager::instance()->priv()->switchInputDevice(id);
+ KoToolManager::instance()->priv()->resetInputDevice();
switch (event->type()) {
case QEvent::TouchBegin:
@@ -269,8 +268,7 @@
void KoToolProxy::mousePressEvent(KoPointerEvent *ev)
{
d->mouseLeaveWorkaround = false;
- KoInputDevice id;
- KoToolManager::instance()->priv()->switchInputDevice(id);
+ KoToolManager::instance()->priv()->resetInputDevice();
d->mouseDownPoint = ev->pos();
if (d->tabletPressed) // refuse to send a press unless there was a release first.
@@ -339,8 +337,7 @@
d->mouseLeaveWorkaround = false;
return;
}
- KoInputDevice id;
- KoToolManager::instance()->priv()->switchInputDevice(id);
+ KoToolManager::instance()->priv()->resetInputDevice();
if (d->activeTool == 0) {
event->ignore();
return;
@@ -358,8 +355,8 @@
d->mouseLeaveWorkaround = false;
return;
}
- KoInputDevice id;
- KoToolManager::instance()->priv()->switchInputDevice(id);
+
+ KoToolManager::instance()->priv()->resetInputDevice();
if (d->activeTool == 0) {
event->ignore();
return;
@@ -373,8 +370,7 @@
void KoToolProxy::mouseReleaseEvent(QMouseEvent *event, const QPointF &point)
{
d->mouseLeaveWorkaround = false;
- KoInputDevice id;
- KoToolManager::instance()->priv()->switchInputDevice(id);
+ KoToolManager::instance()->priv()->resetInputDevice();
d->scrollTimer.stop();
KoPointerEvent ev(event, point);
@@ -409,8 +405,7 @@
void KoToolProxy::mouseReleaseEvent(KoPointerEvent* event)
{
d->mouseLeaveWorkaround = false;
- KoInputDevice id;
- KoToolManager::instance()->priv()->switchInputDevice(id);
+ KoToolManager::instance()->priv()->resetInputDevice();
d->scrollTimer.stop();
if (d->activeTool) {
diff --git a/libs/widgetutils/kis_action_registry.h b/libs/widgetutils/kis_action_registry.h
--- a/libs/widgetutils/kis_action_registry.h
+++ b/libs/widgetutils/kis_action_registry.h
@@ -131,4 +131,3 @@
class Private;
Private * const d;
};
-