File indexing completed on 2024-12-22 04:12:39

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2012 Arjen Hiemstra <ahiemstra@heimr.nl>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_alternate_invocation_action.h"
0008 
0009 #include <QApplication>
0010 #include <klocalizedstring.h>
0011 
0012 #include <kis_tool_proxy.h>
0013 #include <kis_canvas2.h>
0014 
0015 #include "kis_input_manager.h"
0016 #include "kis_cursor.h"
0017 
0018 struct KisAlternateInvocationAction::Private
0019 {
0020     KisTool::ToolAction savedAction;
0021 };
0022 
0023 KisAlternateInvocationAction::KisAlternateInvocationAction()
0024     : KisAbstractInputAction("Alternate Invocation")
0025     , m_d(new Private)
0026 {
0027     setName(i18n("Alternate Invocation"));
0028     setDescription(i18n("The <i>Alternate Invocation</i> action performs an alternate action with the current tool. For example, using the brush tool it samples a color from the canvas."));
0029     QHash<QString, int> shortcuts;
0030     shortcuts.insert(i18n("Primary Mode"), PrimaryAlternateModeShortcut);
0031     shortcuts.insert(i18n("Secondary Mode"), SecondaryAlternateModeShortcut);
0032     shortcuts.insert(i18n("Tertiary Mode"), TertiaryAlternateModeShortcut);
0033 
0034 
0035     shortcuts.insert(i18n("Sample Foreground Color from Current Layer"), SampleColorFgLayerModeShortcut);
0036     shortcuts.insert(i18n("Sample Background Color from Current Layer"), SampleColorBgLayerModeShortcut);
0037 
0038     shortcuts.insert(i18n("Sample Foreground Color from Merged Image"), SampleColorFgImageModeShortcut);
0039     shortcuts.insert(i18n("Sample Background Color from Merged Image"), SampleColorBgImageModeShortcut);
0040 
0041     setShortcutIndexes(shortcuts);
0042 }
0043 
0044 KisAlternateInvocationAction::~KisAlternateInvocationAction()
0045 {
0046 }
0047 
0048 KisTool::ToolAction KisAlternateInvocationAction::shortcutToToolAction(int shortcut) const
0049 {
0050     KisTool::ToolAction action = KisTool::Alternate_NONE;
0051 
0052     switch ((Shortcut)shortcut) {
0053     case SampleColorFgLayerModeShortcut:
0054         action = KisTool::AlternateSampleFgNode;
0055         break;
0056     case SampleColorBgLayerModeShortcut:
0057         action = KisTool::AlternateSampleBgNode;
0058         break;
0059     case SampleColorFgImageModeShortcut:
0060         action = KisTool::AlternateSampleFgImage;
0061         break;
0062     case SampleColorBgImageModeShortcut:
0063         action = KisTool::AlternateSampleBgImage;
0064         break;
0065     case PrimaryAlternateModeShortcut:
0066         action = KisTool::AlternateSecondary;
0067         break;
0068     case SecondaryAlternateModeShortcut:
0069         action = KisTool::AlternateThird;
0070         break;
0071     case TertiaryAlternateModeShortcut:
0072         action = KisTool::AlternateFourth;
0073         break;
0074     }
0075 
0076     return action;
0077 }
0078 
0079 void KisAlternateInvocationAction::activate(int shortcut)
0080 {
0081     KisTool::ToolAction action = shortcutToToolAction(shortcut);
0082     inputManager()->toolProxy()->activateToolAction(action);
0083 }
0084 
0085 void KisAlternateInvocationAction::deactivate(int shortcut)
0086 {
0087     KisTool::ToolAction action = shortcutToToolAction(shortcut);
0088     inputManager()->toolProxy()->deactivateToolAction(action);
0089 }
0090 
0091 int KisAlternateInvocationAction::priority() const
0092 {
0093     return 9;
0094 }
0095 
0096 void KisAlternateInvocationAction::begin(int shortcut, QEvent *event)
0097 {
0098     if (!event) return;
0099 
0100     KisAbstractInputAction::begin(shortcut, event);
0101 
0102     QMouseEvent targetEvent(QEvent::MouseButtonPress, eventPosF(event), Qt::LeftButton, Qt::LeftButton, Qt::ControlModifier); // There must be a better way
0103 
0104     m_d->savedAction = shortcutToToolAction(shortcut);
0105 
0106     inputManager()->toolProxy()->forwardEvent(KisToolProxy::BEGIN, m_d->savedAction, &targetEvent, event);
0107 }
0108 
0109 void KisAlternateInvocationAction::end(QEvent *event)
0110 {
0111     if (!event) return;
0112 
0113     Qt::KeyboardModifiers modifiers;
0114 
0115     switch (m_d->savedAction) {
0116     case KisTool::AlternateSampleFgNode:
0117         modifiers = Qt::ControlModifier;
0118         break;
0119     case KisTool::AlternateThird:
0120         modifiers = Qt::ControlModifier | Qt::AltModifier;
0121         break;
0122     default:
0123         ;
0124     }
0125 
0126     QMouseEvent targetEvent = QMouseEvent(QEvent::MouseButtonRelease, eventPosF(event), Qt::LeftButton, Qt::LeftButton, modifiers);
0127     inputManager()->toolProxy()->forwardEvent(KisToolProxy::END, m_d->savedAction, &targetEvent, event);
0128 
0129     KisAbstractInputAction::end(event);
0130 }
0131 
0132 void KisAlternateInvocationAction::inputEvent(QEvent* event)
0133 {
0134     if (event
0135         && ((event->type() == QEvent::MouseMove) || (event->type() == QEvent::TabletMove)
0136             || (event->type() == QEvent::TouchUpdate))) {
0137         Qt::KeyboardModifiers modifiers;
0138         switch (m_d->savedAction) {
0139         case KisTool::AlternateSampleFgNode:
0140             modifiers =  Qt::ControlModifier;
0141             break;
0142         case KisTool::AlternateThird:
0143             modifiers = Qt::ControlModifier | Qt::AltModifier;
0144             break;
0145         default:
0146             modifiers = Qt::ShiftModifier;
0147         }
0148 
0149         QMouseEvent targetEvent(QEvent::MouseMove, eventPosF(event), Qt::LeftButton, Qt::LeftButton, modifiers);
0150         inputManager()->toolProxy()->forwardEvent(KisToolProxy::CONTINUE, m_d->savedAction, &targetEvent, event);
0151     }
0152 }
0153 
0154 bool KisAlternateInvocationAction::supportsHiResInputEvents(int shortcut) const
0155 {
0156     return inputManager()->toolProxy()->alternateActionSupportsHiResEvents(
0157         KisTool::actionToAlternateAction(shortcutToToolAction(shortcut)));
0158 }