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

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 <QGuiApplication>
0025 #include <QMap>
0026 #include <QObject>
0027 #include <QPainter>
0028 #include <QPixmap>
0029 #include <QQmlEngine>
0030 #include <QQmlParserStatus>
0031 #include <QRect>
0032 #include <QWindow>
0033 #include <QVector>
0034 
0035 struct ShadowParams
0036 {
0037     ShadowParams() = default;
0038 
0039     ShadowParams(const QPoint &offset, int radius, qreal opacity):
0040         offset(offset),
0041         radius(radius),
0042         opacity(opacity)
0043     {}
0044 
0045     QPoint offset;
0046     int radius = 0;
0047     qreal opacity = 0;
0048 };
0049 
0050 struct CompositeShadowParams
0051 {
0052     CompositeShadowParams() = default;
0053 
0054     CompositeShadowParams(
0055             const QPoint &offset,
0056             const ShadowParams &shadow1,
0057             const ShadowParams &shadow2)
0058         : offset(offset)
0059         , shadow1(shadow1)
0060         , shadow2(shadow2) {}
0061 
0062     bool isNone() const
0063     { return qMax(shadow1.radius, shadow2.radius) == 0; }
0064 
0065     QPoint offset;
0066     ShadowParams shadow1;
0067     ShadowParams shadow2;
0068 };
0069 
0070 class WindowShadow : public QObject, public QQmlParserStatus
0071 {
0072     Q_OBJECT
0073     QML_ELEMENT
0074     Q_INTERFACES(QQmlParserStatus)
0075     Q_PROPERTY(QWindow *view READ view WRITE setView NOTIFY viewChanged)
0076     Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry NOTIFY geometryChanged)
0077     Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
0078     Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged)
0079 
0080 public:
0081     WindowShadow(QObject *parent = nullptr) noexcept;
0082     ~WindowShadow() override;
0083 
0084     static CompositeShadowParams lookupShadowParams(int shadowSizeEnum);
0085 
0086     void classBegin() override;
0087     void componentComplete() override;
0088 
0089     void setView(QWindow *view);
0090     QWindow *view() const;
0091 
0092     void setGeometry(const QRect &rect);
0093     QRect geometry() const;
0094 
0095     void setRadius(qreal value);
0096     qreal radius() { return m_radius; }
0097 
0098     qreal strength() const;
0099     void setStrength(qreal strength);
0100 
0101 private slots:
0102     void onViewVisibleChanged(bool);
0103 
0104 private:
0105     void configureTiles();
0106     TileSet shadowTiles();
0107 
0108     QMargins shadowMargins(TileSet) const;
0109 
0110 signals:
0111     void geometryChanged();
0112     void enabledChanged();
0113     void viewChanged();
0114     void edgesChanged();
0115     void radiusChanged();
0116     void strengthChanged();
0117 
0118 private:
0119     QWindow *m_view;
0120     QRect m_rect;
0121     TileSet m_shadowTiles;
0122     qreal m_radius = 10;
0123     qreal m_strength = 1.2;
0124 };
0125