File indexing completed on 2025-01-26 05:09:31
0001 /* 0002 * This file is part of the KDE wacomtablet project. For copyright 0003 * information and license terms see the AUTHORS and COPYING files 0004 * in the top-level directory of this distribution. 0005 * 0006 * This program is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU General Public License as 0008 * published by the Free Software Foundation; either version 2 of 0009 * the License, or (at your option) any later version. 0010 * 0011 * This program is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 * GNU General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU General Public License 0017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0018 */ 0019 0020 #ifndef PRESSURECURVEWIDGET_H 0021 #define PRESSURECURVEWIDGET_H 0022 0023 // Qt includes 0024 #include <QColor> 0025 #include <QPoint> 0026 #include <QSize> 0027 #include <QWidget> 0028 0029 class QMouseEvent; 0030 class QPaintEvent; 0031 0032 namespace Wacom 0033 { 0034 /** 0035 * This widget implements a visual way to adjust the press curve for wacom tablets 0036 * It shows the beziercurve and two control points to adjust the curve 0037 * Furthermore if Qt detects the tablet device the pressure is animated 0038 * as filled area below the curve to give a better feel what the changes to the press curve mean 0039 * This step is not necessary to change the press curve settings, but a nice visual help. 0040 * Qt relies on the xorg.conf to detect the tablet correctly because it use hardcoded names for it 0041 * name them "stylus", "pen", "eraser" to get it working. 0042 * 0043 * @see https://doc.qt.io/qt-5/qtabletevent.html 0044 */ 0045 class PressureCurveWidget : public QWidget 0046 { 0047 Q_OBJECT 0048 0049 public: 0050 /** 0051 * default constructor 0052 * 0053 * @param parent the parent widget that holds this one 0054 */ 0055 explicit PressureCurveWidget(QWidget *parent = nullptr); 0056 0057 /** 0058 * Sets the start values for the bezier presscurve via this control points 0059 * 0060 * @bug if this widget has no fixed size, the width()/height() return the 0061 * the values as specified in the .ui file or when the widget is created 0062 * The automatic layout changes took place before somehow and thus 0063 * leads to a wrong placement of the control points 0064 * @param p1 x value of the first point 0065 * @param p2 y value of the first point 0066 * @param p3 x value of the second point 0067 * @param p4 y value of the second point 0068 */ 0069 void setControlPoints(qreal p1, qreal p2, qreal p3, qreal p4); 0070 0071 protected: 0072 /** 0073 * Called whenever the mouse is pressed in the widget 0074 * Selects the control point if the mouse click was on it 0075 * 0076 * @param event the mouse event 0077 */ 0078 void mousePressEvent(QMouseEvent *event) override; 0079 0080 /** 0081 * Drags the control points around 0082 * based on the active selected control point specified in the mousePressEvent 0083 * the selected control point is moved around and changes the presscurve directly 0084 * 0085 * @param event the mouse event 0086 */ 0087 void mouseMoveEvent(QMouseEvent *event) override; 0088 0089 /** 0090 * Dragging the controlpoint stopped 0091 * Resets the selection of the active control point to move around 0092 * 0093 * @param event the mouse event 0094 */ 0095 void mouseReleaseEvent(QMouseEvent *event) override; 0096 0097 /** 0098 * Changes the position of the controlpoints with the same ratio than the widget resize 0099 * This way the presscurve stays the same all the time 0100 * 0101 * @param event the resize event 0102 */ 0103 void resizeEvent(QResizeEvent *event) override; 0104 0105 /** 0106 * If the tablet was detected by Qt this animates the pressure as filled area below the presscurve 0107 * Qt detects the tablet only if it was configured via the xorg.conf. Otherwise it does not know about it 0108 * Furthermore the tablet input devices must have the standard names "stylus" and "eraser" 0109 * 0110 * @param event the Tablet event 0111 */ 0112 void tabletEvent(QTabletEvent *event) override; 0113 0114 /** 0115 * Draws the background grid, controlpoints and the presscurve on the widget 0116 * Does it with antialias support 0117 * 0118 * @param event the paint event 0119 */ 0120 void paintEvent(QPaintEvent *event) override; 0121 0122 /** 0123 * Finds the nearest controlpoint the uses clicks on 0124 * Will be called for mouse and tabletevent and sets m_activePoint 0125 * with the number of the clicked point. 0126 * 0127 * @param pos the position of the mouse/pen click 0128 */ 0129 void setNearestPoint(const QPointF &pos); 0130 0131 /** 0132 * Moves both control points according to the user interaction 0133 * Both points will be changed even if only one is selected 0134 * The reason lies deep in the Linux Wacom driver that expect the beziercurve 0135 * to be this way. So point 2 is always point 1 with mirrored x/y coordinates 0136 * 0137 * @param pos the new position 0138 */ 0139 void moveControlPoint(const QPointF &pos); 0140 0141 signals: 0142 /** 0143 * This signal will be fired if the position of the control points change 0144 * Used to inform the parent widget of this change to be able to display the new values 0145 * Furthermore the changed presscurve will be set via the xsetwacom driver immediately thus 0146 * allow the user to see the changes in action right now 0147 * 0148 * @param points the presscurve points in a format expected by the xsetwacom driver (like "0 100 0 100") 0149 */ 0150 void controlPointsChanged(const QString &points); 0151 0152 private: 0153 QPointF m_cP1; /**< Control point 1 */ 0154 QPointF m_cP2; /**< Control point 2 */ 0155 int m_pointSize = 10; /**< Size of the control point */ 0156 int m_activePoint = 0; /**< The point that is dragged around */ 0157 QColor m_pointColor = Qt::red; /**< Color of the points */ 0158 QColor m_curveColor = Qt::black; /**< Color of the curve */ 0159 qreal m_pressure = 0; /**< Buffers the current stylus pressure. (0.0 - 1.0) used to animate the pressure */ 0160 QColor m_pressAreaColor = Qt::blue; /**< Color of the press indication area */ 0161 }; 0162 0163 } 0164 0165 #endif // PRESSURECURVEWIDGET_H