File indexing completed on 2024-04-28 16:44:53

0001 /*
0002     SPDX-License-Identifier: GPL-2.0-only
0003     SPDX-FileCopyrightText: 1999-2002 Lubos Lunak <l.lunak@kde.org>
0004  */
0005 
0006 #ifndef _GESTURES_H_
0007 #define _GESTURES_H_
0008 
0009 #include <QAbstractNativeEventFilter>
0010 #include <QMap>
0011 #include <QPointer>
0012 #include <QTimer>
0013 #include <qwindowdefs.h>
0014 
0015 #include "windows_handler.h"
0016 
0017 namespace KHotKeys
0018 {
0019 class Gesture;
0020 class ActionData;
0021 
0022 Q_DECL_EXPORT extern QPointer<Gesture> gesture_handler;
0023 
0024 /**
0025  * A PointQuintet represents a point in the gesture,
0026  * saving not only coordinates but also the relation to the successor.
0027  * The coordinates x and y are mainly used for drawing the stroke,
0028  * the rest is used by the gesture matching algoritm.
0029  */
0030 
0031 class PointQuintet
0032 {
0033 public:
0034     // at which percentage of the stroke length does the point occur?
0035     // 100%=1
0036     qreal s;
0037     // relative distance to the successor (s+delta_s is s of the next point)
0038     qreal delta_s;
0039     // angle to successor in units of pi
0040     qreal angle;
0041     // coordinates scaled to a square box. each goes from 0 to 1
0042     qreal x, y;
0043 };
0044 
0045 typedef QVector<PointQuintet> StrokePoints;
0046 
0047 /**
0048  * The Stroke saves the raw data of the mouse movement. It gets sent the coordinates and
0049  * records them while preparing for processing them. The method processData()
0050  * returns the processed version of this raw data.
0051  */
0052 
0053 class Q_DECL_EXPORT Stroke
0054 {
0055 public:
0056     // largest number of points allowed to be sampled
0057     enum {
0058         MAX_POINTS = 5000,
0059     };
0060 
0061     Stroke();
0062     ~Stroke();
0063     bool record(int x, int y);
0064 
0065     StrokePoints processData();
0066     void reset();
0067 
0068 protected:
0069     // metrics for input stroke
0070     int min_x, min_y;
0071     int max_x, max_y;
0072     int point_count;
0073 
0074     struct point {
0075         int x;
0076         int y;
0077     };
0078 
0079     point *points;
0080 };
0081 
0082 /**
0083  * The Gesture class manages the mouse grabbing and sends its data to a Stroke.
0084  * Then it emits the Stroke's processed data so that instances of GestureTrigger
0085  * can handle it.
0086  */
0087 
0088 class Q_DECL_EXPORT Gesture : public QObject, public QAbstractNativeEventFilter
0089 {
0090     Q_OBJECT
0091 public:
0092     Gesture(bool enabled_P, QObject *parent_P);
0093     ~Gesture() override;
0094     void enable(bool enable_P);
0095     void set_mouse_button(unsigned int button_P);
0096     void set_timeout(int time_P);
0097     void set_exclude(Windowdef_list *windows_P);
0098     void register_handler(QObject *receiver_P, const char *slot_P);
0099     void unregister_handler(QObject *receiver_P, const char *slot_P);
0100 
0101 protected:
0102     bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override;
0103 
0104 private Q_SLOTS:
0105     void stroke_timeout();
0106     void active_window_changed(WId window_P);
0107     void handleScore(ActionData *const data, const qreal score);
0108 Q_SIGNALS:
0109     void handle_gesture(const StrokePoints &gesture);
0110 
0111 private:
0112     void update_grab();
0113     void grab_mouse(bool grab_P);
0114     void mouse_replay(bool release_P);
0115     bool _enabled;
0116     Stroke stroke;
0117     int start_x, start_y;
0118     QTimer nostroke_timer;
0119     bool recording;
0120     unsigned int button;
0121     int timeout;
0122 
0123     // two variables to help determine which action belongs to
0124     // the best-fitting gesture.
0125     qreal maxScore;
0126     ActionData *bestFit;
0127 
0128     Windowdef_list *exclude;
0129     QMap<QObject *, bool> handlers; // bool is just a dummy
0130 };
0131 
0132 } // namespace KHotKeys
0133 
0134 #endif