File indexing completed on 2024-06-16 05:05:45

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2012 Filip Wieladek <wattos@gmail.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #pragma once
0011 
0012 #include "effect/effect.h"
0013 #include "effect/effectframe.h"
0014 #include "opengl/glutils.h"
0015 #include <KLocalizedString>
0016 #include <QFont>
0017 #include <QHash>
0018 #include <deque>
0019 
0020 namespace KWin
0021 {
0022 
0023 #define BUTTON_COUNT 3
0024 
0025 class EffectFrame;
0026 
0027 class MouseEvent
0028 {
0029 public:
0030     MouseEvent(int button, QPoint point, int time, std::unique_ptr<EffectFrame> &&frame, bool press)
0031         : m_button(button)
0032         , m_pos(point)
0033         , m_time(time)
0034         , m_frame(std::move(frame))
0035         , m_press(press){};
0036 
0037     int m_button;
0038     QPoint m_pos;
0039     int m_time;
0040     std::unique_ptr<EffectFrame> m_frame;
0041     bool m_press;
0042 };
0043 
0044 class TabletToolEvent
0045 {
0046 public:
0047     QPointF m_globalPosition;
0048     bool m_pressed = false;
0049     qreal m_pressure = 0;
0050     QColor m_color;
0051 };
0052 
0053 class MouseButton
0054 {
0055 public:
0056     MouseButton(QString label, Qt::MouseButtons button)
0057         : m_labelUp(label)
0058         , m_labelDown(label)
0059         , m_button(button)
0060         , m_isPressed(false)
0061         , m_time(0)
0062     {
0063         m_labelDown.append(i18n("↓"));
0064         m_labelUp.append(i18n("↑"));
0065     };
0066 
0067     inline void setPressed(bool pressed)
0068     {
0069         if (m_isPressed != pressed) {
0070             m_isPressed = pressed;
0071             if (pressed) {
0072                 m_time = 0;
0073             }
0074         }
0075     }
0076 
0077     QString m_labelUp;
0078     QString m_labelDown;
0079     Qt::MouseButtons m_button;
0080     bool m_isPressed;
0081     int m_time;
0082 };
0083 
0084 class MouseClickEffect
0085     : public Effect
0086 {
0087     Q_OBJECT
0088     Q_PROPERTY(QColor color1 READ color1)
0089     Q_PROPERTY(QColor color2 READ color2)
0090     Q_PROPERTY(QColor color3 READ color3)
0091     Q_PROPERTY(qreal lineWidth READ lineWidth)
0092     Q_PROPERTY(int ringLife READ ringLife)
0093     Q_PROPERTY(int ringSize READ ringSize)
0094     Q_PROPERTY(int ringCount READ ringCount)
0095     Q_PROPERTY(bool showText READ isShowText)
0096     Q_PROPERTY(QFont font READ font)
0097     Q_PROPERTY(bool enabled READ isEnabled)
0098 public:
0099     MouseClickEffect();
0100     ~MouseClickEffect() override;
0101     void reconfigure(ReconfigureFlags) override;
0102     void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
0103     void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen) override;
0104     void postPaintScreen() override;
0105     bool isActive() const override;
0106 
0107     // for properties
0108     QColor color1() const;
0109     QColor color2() const;
0110     QColor color3() const;
0111     qreal lineWidth() const;
0112     int ringLife() const;
0113     int ringSize() const;
0114     int ringCount() const;
0115     bool isShowText() const;
0116     QFont font() const;
0117     bool isEnabled() const;
0118 
0119     bool tabletToolEvent(QTabletEvent *event) override;
0120 
0121 private Q_SLOTS:
0122     void toggleEnabled();
0123     void slotMouseChanged(const QPointF &pos, const QPointF &old,
0124                           Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons,
0125                           Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers);
0126 
0127 private:
0128     std::unique_ptr<EffectFrame> createEffectFrame(const QPoint &pos, const QString &text);
0129     inline void drawCircle(const RenderViewport &viewport, const QColor &color, float cx, float cy, float r);
0130 
0131     inline bool isReleased(Qt::MouseButtons button, Qt::MouseButtons buttons, Qt::MouseButtons oldButtons);
0132     inline bool isPressed(Qt::MouseButtons button, Qt::MouseButtons buttons, Qt::MouseButtons oldButtons);
0133 
0134     inline float computeRadius(const MouseEvent *click, int ring);
0135     inline float computeAlpha(const MouseEvent *click, int ring);
0136 
0137     void repaint();
0138 
0139     void drawCircleGl(const RenderViewport &viewport, const QColor &color, float cx, float cy, float r);
0140     void drawCircleQPainter(const QColor &color, float cx, float cy, float r);
0141     void paintScreenSetupGl(const RenderTarget &renderTarget, const QMatrix4x4 &projectionMatrix);
0142     void paintScreenFinishGl();
0143 
0144     QColor m_colors[BUTTON_COUNT];
0145     int m_ringCount;
0146     float m_lineWidth;
0147     float m_ringLife;
0148     float m_ringMaxSize;
0149     bool m_showText;
0150     QFont m_font;
0151     std::chrono::milliseconds m_lastPresentTime = std::chrono::milliseconds::zero();
0152 
0153     std::deque<std::unique_ptr<MouseEvent>> m_clicks;
0154     std::unique_ptr<MouseButton> m_buttons[BUTTON_COUNT];
0155     QHash<quint64, TabletToolEvent> m_tabletTools;
0156 
0157     bool m_enabled;
0158 };
0159 
0160 } // namespace