File indexing completed on 2024-12-22 04:31:07

0001 /*
0002  * Copyright (C) 2021 CutefishOS Team.
0003  *
0004  * Author:     revenmartin <revenmartin@gmail.com>
0005  *
0006  * This program is free software: you can redistribute it and/or modify
0007  * it under the terms of the GNU General Public License as published by
0008  * the Free Software Foundation, either version 3 of the License, or
0009  * 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 #pragma once
0021 
0022 #include "tileset.h"
0023 
0024 #include <KWindowShadow>
0025 #include <KWindowShadowTile>
0026 #include <KWindowSystem>
0027 
0028 #include <QApplication>
0029 #include <QMap>
0030 #include <QObject>
0031 #include <QPainter>
0032 #include <QPixmap>
0033 #include <QQmlEngine>
0034 #include <QQmlParserStatus>
0035 #include <QRect>
0036 #include <QWindow>
0037 #include <QVector>
0038 
0039 struct ShadowParams
0040 {
0041     ShadowParams() = default;
0042 
0043     ShadowParams(const QPoint &offset, int radius, qreal opacity):
0044         offset(offset),
0045         radius(radius),
0046         opacity(opacity)
0047     {}
0048 
0049     QPoint offset;
0050     int radius = 0;
0051     qreal opacity = 0;
0052 };
0053 
0054 struct CompositeShadowParams
0055 {
0056     CompositeShadowParams() = default;
0057 
0058     CompositeShadowParams(
0059             const QPoint &offset,
0060             const ShadowParams &shadow1,
0061             const ShadowParams &shadow2)
0062         : offset(offset)
0063         , shadow1(shadow1)
0064         , shadow2(shadow2) {}
0065 
0066     bool isNone() const
0067     { return qMax(shadow1.radius, shadow2.radius) == 0; }
0068 
0069     QPoint offset;
0070     ShadowParams shadow1;
0071     ShadowParams shadow2;
0072 };
0073 
0074 class WindowShadow : public QObject, public QQmlParserStatus
0075 {
0076     Q_OBJECT
0077     QML_ELEMENT
0078     Q_INTERFACES(QQmlParserStatus)
0079     Q_PROPERTY(QWindow *view READ view WRITE setView NOTIFY viewChanged)
0080     Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry NOTIFY geometryChanged)
0081     Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
0082     Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged)
0083 
0084 public:
0085     WindowShadow(QObject *parent = nullptr) noexcept;
0086     ~WindowShadow() override;
0087 
0088     static CompositeShadowParams lookupShadowParams(int shadowSizeEnum);
0089 
0090     void classBegin() override;
0091     void componentComplete() override;
0092 
0093     void setView(QWindow *view);
0094     QWindow *view() const;
0095 
0096     void setGeometry(const QRect &rect);
0097     QRect geometry() const;
0098 
0099     void setRadius(qreal value);
0100     qreal radius() { return m_radius; }
0101 
0102     qreal strength() const;
0103     void setStrength(qreal strength);
0104 
0105 private Q_SLOTS:
0106     void onViewVisibleChanged(bool);
0107 
0108 private:
0109     void configureTiles();
0110     KWindowShadowTile::Ptr createTile(const QPixmap &);
0111     TileSet shadowTiles();
0112 
0113     QMargins shadowMargins(TileSet) const;
0114 
0115 Q_SIGNALS:
0116     void geometryChanged();
0117     void enabledChanged();
0118     void viewChanged();
0119     void edgesChanged();
0120     void radiusChanged();
0121     void strengthChanged();
0122 
0123 private:
0124     QWindow *m_view;
0125     QRect m_rect;
0126     KWindowShadow *m_shadow;
0127     QVector<KWindowShadowTile::Ptr> m_tile;
0128     TileSet m_shadowTiles;
0129     qreal m_radius = 10;
0130     qreal m_strength = 1.2;
0131 };
0132