1 /* 2 * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net> 3 * Copyright (c) 2011 Lukáš Tvrdý <lukast.dev@gmail.com> 4 * 5 * This library is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License as published by 7 * the Free Software Foundation; version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 */ 19 20 #ifndef _KIS_DYNAMIC_SENSOR_H_ 21 #define _KIS_DYNAMIC_SENSOR_H_ 22 23 #include <kritapaintop_export.h> 24 25 #include <QObject> 26 27 #include <KoID.h> 28 29 #include <klocalizedstring.h> 30 31 #include "kis_serializable_configuration.h" 32 #include "kis_curve_label.h" 33 #include <kis_cubic_curve.h> 34 #include <kis_shared_ptr.h> 35 #include <kis_shared.h> 36 37 38 class QWidget; 39 class KisPaintInformation; 40 41 const KoID FuzzyPerDabId("fuzzy", ki18nc("Context: dynamic sensors", "Fuzzy Dab")); ///< generate a random number 42 const KoID FuzzyPerStrokeId("fuzzystroke", ki18nc("Context: dynamic sensors", "Fuzzy Stroke")); ///< generate a random number 43 const KoID SpeedId("speed", ki18nc("Context: dynamic sensors", "Speed")); ///< generate a number depending on the speed of the cursor 44 const KoID FadeId("fade", ki18nc("Context: dynamic sensors", "Fade")); ///< generate a number that increase every time you call it (e.g. per dab) 45 const KoID DistanceId("distance", ki18nc("Context: dynamic sensors", "Distance")); ///< generate a number that increase with distance 46 const KoID TimeId("time", ki18nc("Context: dynamic sensors", "Time")); ///< generate a number that increase with time 47 const KoID DrawingAngleId("drawingangle", ki18nc("Context: dynamic sensors", "Drawing angle")); ///< number depending on the angle 48 const KoID RotationId("rotation", ki18nc("Context: dynamic sensors", "Rotation")); ///< rotation coming from the device 49 const KoID PressureId("pressure", ki18nc("Context: dynamic sensors", "Pressure")); ///< number depending on the pressure 50 const KoID PressureInId("pressurein", ki18nc("Context: dynamic sensors", "PressureIn")); ///< number depending on the pressure 51 const KoID XTiltId("xtilt", ki18nc("Context: dynamic sensors", "X-Tilt")); ///< number depending on X-tilt 52 const KoID YTiltId("ytilt", ki18nc("Context: dynamic sensors", "Y-Tilt")); ///< number depending on Y-tilt 53 54 /** 55 * "TiltDirection" and "TiltElevation" parameters are written to 56 * preset files as "ascension" and "declination" to keep backward 57 * compatibility with older presets from the days when they were called 58 * differently. 59 */ 60 const KoID TiltDirectionId("ascension", ki18nc("Context: dynamic sensors", "Tilt direction")); /// < number depending on the X and Y tilt, tilt direction is 0 when stylus nib points to you and changes clockwise from -180 to +180. 61 const KoID TiltElevationId("declination", ki18nc("Context: dynamic sensors", "Tilt elevation")); /// < tilt elevation is 90 when stylus is perpendicular to tablet and 0 when it's parallel to tablet 62 63 const KoID PerspectiveId("perspective", ki18nc("Context: dynamic sensors", "Perspective")); ///< number depending on the distance on the perspective grid 64 const KoID TangentialPressureId("tangentialpressure", ki18nc("Context: dynamic sensors", "Tangential pressure")); ///< the wheel on an airbrush device 65 const KoID SensorsListId("sensorslist", "SHOULD NOT APPEAR IN THE UI !"); ///< this a non user-visible sensor that can store a list of other sensors, and multiply their output 66 67 class KisDynamicSensor; 68 typedef KisSharedPtr<KisDynamicSensor> KisDynamicSensorSP; 69 70 enum DynamicSensorType { 71 FUZZY_PER_DAB, 72 FUZZY_PER_STROKE, 73 SPEED, 74 FADE, 75 DISTANCE, 76 TIME, 77 ANGLE, 78 ROTATION, 79 PRESSURE, 80 XTILT, 81 YTILT, 82 TILT_DIRECTION, 83 TILT_ELEVATATION, 84 PERSPECTIVE, 85 TANGENTIAL_PRESSURE, 86 SENSORS_LIST, 87 PRESSURE_IN, 88 UNKNOWN = 255 89 }; 90 91 /** 92 * Sensors are used to extract from KisPaintInformation a single 93 * double value which can be used to control the parameters of 94 * a brush. 95 */ 96 class PAINTOP_EXPORT KisDynamicSensor : public KisSerializableConfiguration 97 { 98 99 public: 100 enum ParameterSign { 101 NegativeParameter = -1, 102 UnSignedParameter = 0, 103 PositiveParameter = 1 104 }; 105 106 protected: 107 KisDynamicSensor(DynamicSensorType type); 108 109 public: 110 111 ~KisDynamicSensor() override; 112 113 /** 114 * @return the value of this sensor for the given KisPaintInformation 115 */ 116 qreal parameter(const KisPaintInformation& info); 117 /** 118 * @return the value of this sensor for the given KisPaintInformation 119 * curve -- a custom, temporary curve that should be used instead of the one for the sensor 120 * customCurve -- if it's a new curve or not; should always be true if the function is called from outside 121 * (aka not in parameter(info) function) 122 */ 123 qreal parameter(const KisPaintInformation& info, const KisCubicCurve curve, const bool customCurve); 124 125 /** 126 * This function is call before beginning a stroke to reset the sensor. 127 * Default implementation does nothing. 128 */ 129 virtual void reset(); 130 131 /** 132 * @param parent the parent QWidget 133 * @param selector is a \ref QWidget that contains a signal called "parametersChanged()" 134 */ 135 virtual QWidget* createConfigurationWidget(QWidget* parent, QWidget* selector); 136 137 /** 138 * Creates a sensor from its identifier. 139 */ 140 static KisDynamicSensorSP id2Sensor(const KoID& id, const QString &parentOptionName); id2Sensor(const QString & s,const QString & parentOptionName)141 static KisDynamicSensorSP id2Sensor(const QString& s, const QString &parentOptionName) { 142 return id2Sensor(KoID(s), parentOptionName); 143 } 144 145 static DynamicSensorType id2Type(const KoID& id); id2Type(const QString & s)146 static DynamicSensorType id2Type(const QString& s) { 147 return id2Type(KoID(s)); 148 } 149 150 /** 151 * type2Sensor creates a new sensor for the give type 152 */ 153 static KisDynamicSensorSP type2Sensor(DynamicSensorType sensorType, const QString &parentOptionName); 154 155 static QString minimumLabel(DynamicSensorType sensorType); 156 static QString maximumLabel(DynamicSensorType sensorType, int max = -1); 157 static int minimumValue(DynamicSensorType sensorType); 158 static int maximumValue(DynamicSensorType sensorType, int max = -1); 159 static QString valueSuffix(DynamicSensorType sensorType); 160 161 static KisDynamicSensorSP createFromXML(const QString&, const QString &parentOptionName); 162 static KisDynamicSensorSP createFromXML(const QDomElement&, const QString &parentOptionName); 163 164 /** 165 * @return the list of sensors 166 */ 167 static QList<KoID> sensorsIds(); 168 static QList<DynamicSensorType> sensorsTypes(); 169 170 /** 171 * @return the identifier of this sensor 172 */ 173 static QString id(DynamicSensorType sensorType); 174 175 using KisSerializableConfiguration::fromXML; 176 using KisSerializableConfiguration::toXML; 177 178 void toXML(QDomDocument&, QDomElement&) const override; 179 void fromXML(const QDomElement&) override; 180 181 void setCurve(const KisCubicCurve& curve); 182 const KisCubicCurve& curve() const; 183 void removeCurve(); 184 bool hasCustomCurve() const; 185 186 void setActive(bool active); 187 bool isActive() const; 188 189 virtual bool dependsOnCanvasRotation() const; 190 191 virtual bool isAdditive() const; 192 virtual bool isAbsoluteRotation() const; 193 sensorType()194 inline DynamicSensorType sensorType() const { return m_type; } 195 196 197 /** 198 * @return the currently set length or -1 if not relevant 199 */ length()200 int length() { return m_length; } 201 202 203 public: scalingToAdditive(qreal x)204 static inline qreal scalingToAdditive(qreal x) { 205 return -1.0 + 2.0 * x; 206 } 207 additiveToScaling(qreal x)208 static inline qreal additiveToScaling(qreal x) { 209 return 0.5 * (1.0 + x); 210 } 211 212 protected: 213 214 virtual qreal value(const KisPaintInformation& info) = 0; 215 216 int m_length; 217 218 private: 219 220 Q_DISABLE_COPY(KisDynamicSensor) 221 222 DynamicSensorType m_type; 223 bool m_customCurve; 224 KisCubicCurve m_curve; 225 bool m_active; 226 227 }; 228 229 #endif 230