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_