File indexing completed on 2024-05-12 16:01:38

0001 /*
0002  *  kis_paintop_box.h - part of KImageShop/Krayon/Krita
0003  *
0004  *  SPDX-FileCopyrightText: 2004-2008 Boudewijn Rempt (boud@valdyas.org)
0005  *  SPDX-FileCopyrightText: 2011 Silvio Heinrich <plassy@web.de>
0006  *
0007  *  SPDX-License-Identifier: GPL-2.0-or-later
0008  */
0009 
0010 #ifndef KIS_PAINTOP_BOX_H_
0011 #define KIS_PAINTOP_BOX_H_
0012 
0013 #include <QMap>
0014 #include <QWidget>
0015 #include <QList>
0016 
0017 #include <KoResource.h>
0018 #include <KoID.h>
0019 #include <KoInputDevice.h>
0020 
0021 #include <kis_types.h>
0022 #include <brushengine/kis_paintop_settings.h>
0023 #include <brushengine/kis_locked_properties_proxy.h>
0024 #include <brushengine/kis_locked_properties_server.h>
0025 #include <brushengine/kis_locked_properties.h>
0026 #include "kritaui_export.h"
0027 #include "kis_signal_auto_connection.h"
0028 #include "kis_signal_compressor.h"
0029 
0030 class QMenu;
0031 class QToolButton;
0032 class QString;
0033 class QHBoxLayout;
0034 
0035 class KoColorSpace;
0036 class KoCanvasController;
0037 
0038 class KisViewManager;
0039 class KisCanvasResourceProvider;
0040 class KisPopupButton;
0041 class KisIconWidget;
0042 class KisToolOptionsPopup;
0043 class KisPaintOpPresetsEditor;
0044 class KisPaintOpPresetsChooserPopup;
0045 class KisPaintOpConfigWidget;
0046 class KisCompositeOpComboBox;
0047 class KisWidgetChooser;
0048 class KisFavoriteResourceManager;
0049 class KisAction;
0050 class KisPresetSaveWidget;
0051 class KisAcyclicSignalConnector;
0052 
0053 /**
0054  * This widget presents all paintops that a user can paint with.
0055  * Paintops represent real-world tools or the well-known Shoup
0056  * computer equivalents that do nothing but change color.
0057  *
0058  * To incorporate the dirty preset functionality and locked settings
0059  * the following slots are added
0060  *  void slotReloadPreset();
0061     void slotGuiChangedCurrentPreset();
0062     void slotSaveLockedOptionToPreset(KisPropertiesConfigurationSP p);
0063     void slotDropLockedOption(KisPropertiesConfigurationSP p);
0064     void slotDirtyPresetToggled(bool);
0065     Every time a value is changed in a preset, the preset is made dirty through the onChange() function.
0066     For Locked Settings however, a changed Locked Setting will not cause a preset to become dirty. That is
0067     because it borrows its values from the KisLockedPropertiesServer.
0068     Hence the dirty state of the Preset is kept consistent before and after a writeConfiguration operation in  most cases.
0069  * XXX: When we have a lot of paintops, replace the listbox
0070  * with a table, and for every category a combobox.
0071  *
0072  * XXX: instead of text, use pretty pictures.
0073  */
0074 class KRITAUI_EXPORT KisPaintopBox : public QWidget
0075 {
0076     Q_OBJECT
0077 
0078     enum {
0079         ENABLE_PRESETS      = 0x0001,
0080         DISABLE_PRESETS     = 0x0002,
0081         ENABLE_COMPOSITEOP  = 0x0004,
0082         DISABLE_COMPOSITEOP = 0x0008,
0083         ENABLE_OPACITY      = 0x0010,
0084         DISABLE_OPACITY     = 0x0020,
0085         ENABLE_FLOW         = 0x0040,
0086         DISABLE_FLOW        = 0x0080,
0087         ENABLE_SIZE         = 0x0100,
0088         DISABLE_SIZE        = 0x0200,
0089         ENABLE_PATTERNSIZE  = 0x0400,
0090         DISABLE_PATTERNSIZE = 0x0800,
0091         ENABLE_ALL          = 0x5555,
0092         DISABLE_ALL         = 0xAAAA
0093     };
0094 
0095 public:
0096 
0097     KisPaintopBox(KisViewManager* view, QWidget* parent, const char* name);
0098     ~KisPaintopBox() override;
0099 
0100     void restoreResource(KoResourceSP resource);
0101     /**
0102      * Update the option widgets to the argument ones, removing the currently set widgets.
0103      */
0104     void newOptionWidgets(const QList<QPointer<QWidget> > & optionWidgetList);
0105 
0106     KisFavoriteResourceManager *favoriteResourcesManager() { return m_favoriteResourceManager; }
0107 
0108 public Q_SLOTS:
0109 
0110     void slotColorSpaceChanged(const KoColorSpace* colorSpace);
0111     void slotInputDeviceChanged(const KoInputDevice & inputDevice);
0112     void slotCanvasResourceChangeAttempted(int key, const QVariant &value);
0113     void slotCanvasResourceChanged(int key, const QVariant& v);
0114     void resourceSelected(KoResourceSP resource);
0115 
0116     /// This should take care of creating a new brush preset from scratch
0117     /// It will either load the default brush preset for the engine,
0118     /// or create a new empty preset if a default preset does not exist
0119     void slotCreatePresetFromScratch(QString paintop);
0120 
0121 private:
0122 
0123     void setCurrentPaintop(const KoID& paintop);
0124     void setCurrentPaintop(KisPaintOpPresetSP preset);
0125 
0126     KisPaintOpPresetSP defaultPreset(const KoID& paintOp);
0127     KisPaintOpPresetSP activePreset(const KoID& paintOp);
0128     void updateCompositeOp(QString compositeOpID);
0129     void setWidgetState(int flags);
0130     void setSliderValue(const QString& sliderID, qreal value);
0131     void setMultiplierSliderValue(const QString& sliderID, qreal value);
0132     void sliderChanged(int n);
0133     void findDefaultPresets();
0134 
0135 private Q_SLOTS:
0136 
0137     void slotSetupDefaultPreset();
0138     void slotNodeChanged(const KisNodeSP node);
0139     void slotToggleEraseMode(bool checked);
0140     void slotSetCompositeMode(int index);
0141     void slotSetPaintop(const QString& paintOpId);
0142     void slotHorizontalMirrorChanged(bool value);
0143     void slotVerticalMirrorChanged(bool value);
0144     void slotSlider1Changed();
0145     void slotSlider2Changed();
0146     void slotSlider3Changed();
0147     void slotSlider4Changed();
0148     void slotToolChanged(KoCanvasController* canvas);
0149     void slotPreviousFavoritePreset();
0150     void slotNextFavoritePreset();
0151     void slotSwitchToPreviousPreset();
0152     void slotUnsetEraseMode();
0153     void slotToggleAlphaLockMode(bool);
0154     void slotDisablePressureMode(bool);
0155 
0156     void slotReloadPreset();
0157     void slotGuiChangedCurrentPreset();
0158     void slotSaveLockedOptionToPreset(KisPropertiesConfigurationSP p);
0159     void slotDropLockedOption(KisPropertiesConfigurationSP p);
0160     void slotDirtyPresetToggled(bool);
0161     void slotEraserBrushSizeToggled(bool);
0162     void slotEraserBrushOpacityToggled(bool);
0163     void slotUpdateSelectionIcon();
0164 
0165     void slotLockXMirrorToggle(bool);
0166     void slotLockYMirrorToggle(bool);
0167     void slotMoveToCenterMirrorX();
0168     void slotMoveToCenterMirrorY();
0169     void slotHideDecorationMirrorX(bool);
0170     void slotHideDecorationMirrorY(bool);
0171 
0172     void slotUpdateOptionsWidgetPopup();
0173 
0174     void togglePresetEditor();
0175 
0176 private:
0177     KisCanvasResourceProvider*          m_resourceProvider {0};
0178     QHBoxLayout*                        m_layout {0};
0179     QWidget*                            m_paintopWidget {0};
0180     KisPaintOpConfigWidget*             m_optionWidget {0};
0181     KisPopupButton*                     m_toolOptionsPopupButton {0};
0182 
0183     KisPresetSaveWidget*                m_savePresetWidget {0};
0184     KisIconWidget*                      m_brushEditorPopupButton {0};
0185     KisIconWidget*                      m_presetSelectorPopupButton {0};
0186     KisCompositeOpComboBox*             m_cmbCompositeOp {0};
0187     QToolButton*                        m_eraseModeButton {0};
0188     QToolButton*                        m_alphaLockButton {0};
0189     QToolButton*                        m_hMirrorButton {0};
0190     QToolButton*                        m_vMirrorButton {0};
0191     QToolButton*                        m_wrapAroundButton {0};
0192     KisToolOptionsPopup*                m_toolOptionsPopup {0};
0193     KisPaintOpPresetsEditor*            m_presetsEditor {0};
0194     KisPaintOpPresetsChooserPopup*      m_presetsChooserPopup {0};
0195     KisViewManager*                     m_viewManager {0};
0196     KisPopupButton*                     m_workspaceWidget {0};
0197     KisWidgetChooser*                   m_sliderChooser[4];
0198     QMap<KoID, KisPaintOpConfigWidget*> m_paintopOptionWidgets;
0199     KisFavoriteResourceManager*         m_favoriteResourceManager {0};
0200     QToolButton*                        m_reloadButton {0};
0201     KisAction*                          m_eraseAction {0};
0202     KisAction*                          m_reloadAction {0};
0203     KisAction*                          m_disablePressureAction {0};
0204 
0205     QString    m_currCompositeOpID;
0206     KisNodeWSP m_currentNode;
0207 
0208     QMenu*     toolbarMenuXMirror{nullptr};
0209     QMenu*     toolbarMenuYMirror{nullptr};
0210 
0211     KisAction* m_hMirrorAction {0};
0212     KisAction* m_vMirrorAction {0};
0213 
0214     KisAction* hideCanvasDecorationsX {0};
0215     KisAction* lockActionX {0};
0216     KisAction* moveToCenterActionX {0};
0217     KisAction* hideCanvasDecorationsY {0};
0218     KisAction* lockActionY {0};
0219     KisAction* moveToCenterActionY {0};
0220 
0221 
0222     struct TabletToolID {
0223         TabletToolID(const KoInputDevice& dev) {
0224             // Only the eraser is special, and we don't look at Cursor
0225             pointer = QTabletEvent::Pen;
0226             if (dev.pointer() == QTabletEvent::Eraser) {
0227                 pointer = QTabletEvent::Eraser;
0228             }
0229             uniqueTabletId = dev.uniqueTabletId();
0230         }
0231 
0232         bool operator == (const TabletToolID& id) const {
0233             return pointer == id.pointer;
0234         }
0235 
0236         bool operator < (const TabletToolID& id) const {
0237             return pointer < id.pointer;
0238         }
0239 
0240         QTabletEvent::PointerType  pointer;
0241         qint64 uniqueTabletId;
0242     };
0243 
0244     struct TabletToolData {
0245         KoID               paintOpID;
0246         KisPaintOpPresetSP preset;
0247     };
0248 
0249     typedef QMap<TabletToolID, TabletToolData> TabletToolMap;
0250     typedef QMap<KoID, KisPaintOpPresetSP>     PaintOpPresetMap;
0251 
0252     TabletToolMap    m_tabletToolMap;
0253     PaintOpPresetMap m_paintOpPresetMap;
0254     TabletToolID     m_currTabletToolID {KoInputDevice::invalid()};
0255     bool             m_presetsEnabled {true};
0256     bool             m_blockUpdate {false};
0257     bool             m_dirtyPresetsEnabled {false};
0258     bool             m_eraserBrushSizeEnabled {false};
0259     bool             m_eraserBrushOpacityEnabled {false};
0260 
0261     KisSignalAutoConnectionsStore m_presetConnections;
0262     QScopedPointer<KisAcyclicSignalConnector> m_optionsWidgetConnections;
0263     KisSignalCompressor m_optionWidgetUpdateCompressor;
0264 
0265     QString m_eraserName;
0266     QString m_defaultPresetName;
0267 };
0268 
0269 #endif //KIS_PAINTOP_BOX_H_