File indexing completed on 2024-05-19 04:29:04
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 Shop 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 slotToggleEraserPreset(bool usingEraser); 0113 void slotSelectEraserPreset(); 0114 void slotSelectBrushPreset(); 0115 void slotCanvasResourceChangeAttempted(int key, const QVariant &value); 0116 void slotCanvasResourceChanged(int key, const QVariant& v); 0117 void resourceSelected(KoResourceSP resource); 0118 0119 /// This should take care of creating a new brush preset from scratch 0120 /// It will either load the default brush preset for the engine, 0121 /// or create a new empty preset if a default preset does not exist 0122 void slotCreatePresetFromScratch(QString paintop); 0123 0124 private: 0125 0126 void setCurrentPaintop(const KoID& paintop); 0127 void setCurrentPaintop(KisPaintOpPresetSP preset); 0128 0129 KisPaintOpPresetSP defaultPreset(const KoID& paintOp); 0130 KisPaintOpPresetSP activePreset(const KoID& paintOp); 0131 void updateCompositeOp(QString compositeOpID); 0132 void setWidgetState(int flags); 0133 void setSliderValue(const QString& sliderID, qreal value); 0134 void setMultiplierSliderValue(const QString& sliderID, qreal value); 0135 void setAngleSliderValue(const QString& sliderID, qreal value); 0136 void sliderChanged(int n); 0137 void findDefaultPresets(); 0138 0139 private Q_SLOTS: 0140 0141 void slotSetupDefaultPreset(); 0142 void slotNodeChanged(const KisNodeSP node); 0143 void slotToggleEraseMode(bool checked); 0144 void slotSetCompositeMode(int index); 0145 void slotSetPaintop(const QString& paintOpId); 0146 void slotHorizontalMirrorChanged(bool value); 0147 void slotVerticalMirrorChanged(bool value); 0148 void slotSlider1Changed(); 0149 void slotSlider2Changed(); 0150 void slotSlider3Changed(); 0151 void slotSlider4Changed(); 0152 void slotSlider5Changed(); 0153 void slotToolChanged(KoCanvasController* canvas); 0154 void slotPreviousFavoritePreset(); 0155 void slotNextFavoritePreset(); 0156 void slotSwitchToPreviousPreset(); 0157 void slotUnsetEraseMode(); 0158 void slotToggleAlphaLockMode(bool); 0159 void slotDisablePressureMode(bool); 0160 0161 void slotReloadPreset(); 0162 void slotGuiChangedCurrentPreset(); 0163 void slotSaveLockedOptionToPreset(KisPropertiesConfigurationSP p); 0164 void slotDropLockedOption(KisPropertiesConfigurationSP p); 0165 void slotDirtyPresetToggled(bool); 0166 void slotEraserBrushSizeToggled(bool); 0167 void slotEraserBrushOpacityToggled(bool); 0168 void slotUpdateSelectionIcon(); 0169 0170 void slotLockXMirrorToggle(bool); 0171 void slotLockYMirrorToggle(bool); 0172 void slotMoveToCenterMirrorX(); 0173 void slotMoveToCenterMirrorY(); 0174 void slotHideDecorationMirrorX(bool); 0175 void slotHideDecorationMirrorY(bool); 0176 0177 void slotUpdateOptionsWidgetPopup(); 0178 0179 void togglePresetEditor(); 0180 void updatePresetConfig(); 0181 0182 private: 0183 KisCanvasResourceProvider* m_resourceProvider {0}; 0184 QHBoxLayout* m_layout {0}; 0185 QWidget* m_paintopWidget {0}; 0186 KisPaintOpConfigWidget* m_optionWidget {0}; 0187 KisPopupButton* m_toolOptionsPopupButton {0}; 0188 0189 KisPresetSaveWidget* m_savePresetWidget {0}; 0190 KisIconWidget* m_brushEditorPopupButton {0}; 0191 KisIconWidget* m_presetSelectorPopupButton {0}; 0192 KisCompositeOpComboBox* m_cmbCompositeOp {0}; 0193 QToolButton* m_eraseModeButton {0}; 0194 QToolButton* m_alphaLockButton {0}; 0195 QToolButton* m_hMirrorButton {0}; 0196 QToolButton* m_vMirrorButton {0}; 0197 QToolButton* m_wrapAroundButton {0}; 0198 KisToolOptionsPopup* m_toolOptionsPopup {0}; 0199 KisPaintOpPresetsEditor* m_presetsEditor {0}; 0200 KisPaintOpPresetsChooserPopup* m_presetsChooserPopup {0}; 0201 KisViewManager* m_viewManager {0}; 0202 KisPopupButton* m_workspaceWidget {0}; 0203 KisWidgetChooser* m_sliderChooser[5]; 0204 QMap<KoID, KisPaintOpConfigWidget*> m_paintopOptionWidgets; 0205 KisFavoriteResourceManager* m_favoriteResourceManager {0}; 0206 QToolButton* m_reloadButton {0}; 0207 KisAction* m_eraseAction {0}; 0208 KisAction* m_eraserTogglePresetAction {0}; 0209 KisAction* m_eraserSelectPresetAction {0}; 0210 KisAction* m_brushSelectPresetAction {0}; 0211 KisAction* m_reloadAction {0}; 0212 KisAction* m_disablePressureAction {0}; 0213 0214 QString m_currCompositeOpID; 0215 KisNodeWSP m_currentNode; 0216 0217 QMenu* toolbarMenuXMirror{nullptr}; 0218 QMenu* toolbarMenuYMirror{nullptr}; 0219 0220 KisAction* m_hMirrorAction {0}; 0221 KisAction* m_vMirrorAction {0}; 0222 0223 KisAction* hideCanvasDecorationsX {0}; 0224 KisAction* lockActionX {0}; 0225 KisAction* moveToCenterActionX {0}; 0226 KisAction* hideCanvasDecorationsY {0}; 0227 KisAction* lockActionY {0}; 0228 KisAction* moveToCenterActionY {0}; 0229 0230 0231 struct TabletToolID { 0232 TabletToolID(const KoInputDevice& dev) { 0233 // Only the eraser is special, and we don't look at Cursor 0234 pointer = QTabletEvent::Pen; 0235 if (dev.pointer() == QTabletEvent::Eraser) { 0236 pointer = QTabletEvent::Eraser; 0237 } 0238 uniqueTabletId = dev.uniqueTabletId(); 0239 } 0240 0241 bool operator == (const TabletToolID& id) const { 0242 return pointer == id.pointer; 0243 } 0244 0245 bool operator < (const TabletToolID& id) const { 0246 return pointer < id.pointer; 0247 } 0248 0249 QTabletEvent::PointerType pointer; 0250 qint64 uniqueTabletId; 0251 }; 0252 0253 struct TabletToolData { 0254 KoID paintOpID; 0255 KisPaintOpPresetSP preset; 0256 }; 0257 0258 typedef QMap<TabletToolID, TabletToolData> TabletToolMap; 0259 typedef QMap<KoID, KisPaintOpPresetSP> PaintOpPresetMap; 0260 0261 TabletToolMap m_tabletToolMap; 0262 PaintOpPresetMap m_paintOpPresetMap; 0263 TabletToolID m_currTabletToolID {KoInputDevice::invalid()}; 0264 bool m_presetsEnabled {true}; 0265 bool m_blockUpdate {false}; 0266 bool m_dirtyPresetsEnabled {false}; 0267 bool m_eraserBrushSizeEnabled {false}; 0268 bool m_eraserBrushOpacityEnabled {false}; 0269 0270 KisSignalAutoConnectionsStore m_presetConnections; 0271 QScopedPointer<KisAcyclicSignalConnector> m_optionsWidgetConnections; 0272 KisSignalCompressor m_optionWidgetUpdateCompressor; 0273 0274 QString m_eraserName; 0275 QString m_defaultPresetName; 0276 }; 0277 0278 #endif //KIS_PAINTOP_BOX_H_