File indexing completed on 2024-12-22 04:16:37

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2016 Michael Abrahams <miabraha@gmail.com>
0003  *
0004  * SPDX-License-Identifier: LGPL-3.0-or-later
0005  */
0006 
0007 /**
0008  * This is a basic template to create selection tools from basic path based drawing tools.
0009  * The template overrides the ability to execute alternate actions correctly.
0010  * Modifier keys are overridden with the following behavior:
0011  *
0012  * Shift: add to selection
0013  * Alt: subtract from selection
0014  * Shift+Alt: intersect current selection
0015  * Ctrl: replace selection
0016  *
0017  * Certain tools also use modifier keys to alter their behavior, e.g. forcing square proportions with the rectangle tool.
0018  * The template enables the following rules for forwarding keys:
0019  * 1) Any modifier keys held *when the tool is first activated* will determine the new selection method.
0020  * 2) If the underlying tool *does not take modifier keys*, pressing modifier keys in the middle of a stroke will change the selection method.  This applies to the lasso tool and polygon tool.
0021  * 3) If the underlying tool *takes modifier keys,* they will always be forwarded to the underlying tool, and it is not possible to change the selection method in the middle of a stroke.
0022  */
0023 
0024 #include "kis_selection.h"
0025 #include "kis_selection_modifier_mapper.h"
0026 #include "kis_config_notifier.h"
0027 #include "kis_config.h"
0028 
0029 Q_GLOBAL_STATIC(KisSelectionModifierMapper, s_instance)
0030 
0031 
0032 // This numerically serializes modifier flags... let's keep it around for later.
0033 #if 0
0034 #include <bitset>
0035 QString QMOD_BINARY(Qt::KeyboardModifiers m)
0036 {
0037     return QString(std::bitset<sizeof(int) * 8>(m).to_string().c_str());
0038 };
0039 #endif
0040 
0041 struct Q_DECL_HIDDEN KisSelectionModifierMapper::Private
0042 {
0043     SelectionAction map(Qt::KeyboardModifiers m);
0044     void slotConfigChanged();
0045     Qt::KeyboardModifiers replaceModifiers;
0046     Qt::KeyboardModifiers intersectModifiers;
0047     Qt::KeyboardModifiers addModifiers;
0048     Qt::KeyboardModifiers subtractModifiers;
0049     Qt::KeyboardModifiers symmetricdifferenceModifiers;
0050 };
0051 
0052 
0053 KisSelectionModifierMapper::KisSelectionModifierMapper()
0054     : m_d(new Private)
0055 {
0056     connect(KisConfigNotifier::instance(),
0057             SIGNAL(configChanged()),
0058             SLOT(slotConfigChanged()));
0059     slotConfigChanged();
0060 }
0061 
0062 
0063 KisSelectionModifierMapper::~KisSelectionModifierMapper()
0064 {
0065 }
0066 
0067 KisSelectionModifierMapper *KisSelectionModifierMapper::instance()
0068 {
0069     return s_instance;
0070 }
0071 
0072 void KisSelectionModifierMapper::slotConfigChanged()
0073 {
0074     m_d->slotConfigChanged();
0075 }
0076 
0077 
0078 void KisSelectionModifierMapper::Private::slotConfigChanged()
0079 {
0080     KisConfig cfg(true);
0081     if (!cfg.switchSelectionCtrlAlt()) {
0082         replaceModifiers   = Qt::ControlModifier;
0083         intersectModifiers = (Qt::KeyboardModifiers)(Qt::AltModifier | Qt::ShiftModifier);
0084         subtractModifiers  = Qt::AltModifier;
0085         symmetricdifferenceModifiers = (Qt::KeyboardModifiers)(Qt::ControlModifier | Qt::AltModifier);
0086     } else {
0087         replaceModifiers   = Qt::AltModifier;
0088         intersectModifiers = (Qt::KeyboardModifiers)(Qt::ControlModifier | Qt::ShiftModifier);
0089         subtractModifiers  = Qt::ControlModifier;
0090         symmetricdifferenceModifiers = (Qt::KeyboardModifiers)(Qt::AltModifier | Qt::ControlModifier);
0091     }
0092 
0093     addModifiers = Qt::ShiftModifier;
0094 }
0095 
0096 SelectionAction KisSelectionModifierMapper::map(Qt::KeyboardModifiers m)
0097 {
0098     return s_instance->m_d->map(m);
0099 }
0100 
0101 SelectionAction KisSelectionModifierMapper::Private::map(Qt::KeyboardModifiers m)
0102 {
0103     SelectionAction newAction = SELECTION_DEFAULT;
0104     if (m == replaceModifiers) {
0105         newAction = SELECTION_REPLACE;
0106     } else if (m == intersectModifiers) {
0107         newAction = SELECTION_INTERSECT;
0108     } else if (m == addModifiers) {
0109         newAction = SELECTION_ADD;
0110     } else if (m == subtractModifiers) {
0111         newAction = SELECTION_SUBTRACT;
0112     } else if (m == symmetricdifferenceModifiers) {
0113         newAction = SELECTION_SYMMETRICDIFFERENCE;
0114     }
0115         
0116     return newAction;
0117 }