forked from openkylin/qt5-ukui-platformtheme
269 lines
6.3 KiB
C++
269 lines
6.3 KiB
C++
/*
|
|
* Copyright (C) 2018 Vlad Zagorodniy <vlad.zahorodnii@kde.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
// own
|
|
// Qt
|
|
#include <QEvent>
|
|
/*
|
|
#include <QMainWindow>
|
|
|
|
#include <QWidget>
|
|
|
|
|
|
|
|
|
|
#include <QMenu>
|
|
#include <QPushButton>
|
|
#include <QIcon>
|
|
#include <QListWidget>
|
|
#include <QTabWidget>
|
|
#include <QToolTip>
|
|
#include <QAction>
|
|
#include <QTreeView>
|
|
#include <QLabel>
|
|
#include <QPalette>
|
|
#include <QColor>
|
|
#include <QDebug>
|
|
#include <QPainter>
|
|
#include <QPixmap>
|
|
#include <QStyle>
|
|
#include <QLineEdit>
|
|
|
|
#include <QToolBar>
|
|
#include <QToolButton>
|
|
#include <QCheckBox>
|
|
#include <QLabel>
|
|
#include <QThread>
|
|
#include <QScrollBar>
|
|
#include <QVBoxLayout>
|
|
|
|
#include <QContextMenuEvent>
|
|
#include <QMenu>
|
|
*/
|
|
//#include <KWindowEffects>
|
|
#include <xcb/xproto.h>
|
|
#include <qdebug.h>
|
|
|
|
#include <QVector4D>
|
|
|
|
//#include <QTimer>
|
|
|
|
|
|
#include <xcb/xcb.h>
|
|
|
|
//#include <QApplication>
|
|
#include <QWidget>
|
|
#include <QPainter>
|
|
|
|
#include <QColor>
|
|
#include <QImage>
|
|
#include <QPoint>
|
|
#include <QSize>
|
|
#include <QScopedPointer>
|
|
#include <QWeakPointer>
|
|
|
|
template <typename T> using ScopedPointer = QScopedPointer<T, QScopedPointerPodDeleter>;
|
|
|
|
class BoxShadowRenderer
|
|
{
|
|
public:
|
|
// Compiler generated constructors & destructor are fine.
|
|
|
|
/**
|
|
* Set the size of the box.
|
|
* @param size The size of the box.
|
|
**/
|
|
void setBoxSize(const QSize &size);
|
|
|
|
/**
|
|
* Set the radius of box' corners.
|
|
* @param radius The border radius, in pixels.
|
|
**/
|
|
void setBorderRadius(qreal radius);
|
|
|
|
/**
|
|
* Set the device pixel ratio of the resulting shadow texture.
|
|
* @param dpr The device pixel ratio.
|
|
**/
|
|
void setDevicePixelRatio(qreal dpr);
|
|
|
|
/**
|
|
* Add a shadow.
|
|
* @param offset The offset of the shadow.
|
|
* @param radius The blur radius.
|
|
* @param color The color of the shadow.
|
|
**/
|
|
void addShadow(const QPoint &offset, int radius, const QColor &color);
|
|
|
|
/**
|
|
* Render the shadow.
|
|
**/
|
|
QImage render() const;
|
|
|
|
/**
|
|
* Calculate the minimum size of the box.
|
|
*
|
|
* This helper computes the minimum size of the box so the shadow behind it has
|
|
* full its strength.
|
|
*
|
|
* @param radius The blur radius of the shadow.
|
|
**/
|
|
static QSize calculateMinimumBoxSize(int radius);
|
|
|
|
/**
|
|
* Calculate the minimum size of the shadow texture.
|
|
*
|
|
* This helper computes the minimum size of the resulting texture so the shadow
|
|
* is not clipped.
|
|
*
|
|
* @param boxSize The size of the box.
|
|
* @param radius The blur radius.
|
|
* @param offset The offset of the shadow.
|
|
**/
|
|
static QSize calculateMinimumShadowTextureSize(const QSize &boxSize, int radius, const QPoint &offset);
|
|
|
|
private:
|
|
QSize m_boxSize;
|
|
qreal m_borderRadius = 0.0;
|
|
qreal m_dpr = 1.0;
|
|
|
|
struct Shadow {
|
|
QPoint offset;
|
|
int radius;
|
|
QColor color;
|
|
};
|
|
|
|
QVector<Shadow> m_shadows;
|
|
};
|
|
|
|
class TileSet
|
|
{
|
|
public:
|
|
/**
|
|
Create a TileSet from a pixmap. The size of the bottom/right chunks is
|
|
whatever is left over from the other chunks, whose size is specified
|
|
in the required parameters.
|
|
|
|
@param w1 width of the left chunks
|
|
@param h1 height of the top chunks
|
|
@param w2 width of the not-left-or-right chunks
|
|
@param h2 height of the not-top-or-bottom chunks
|
|
*/
|
|
TileSet(const QPixmap&, int w1, int h1, int w2, int h2 );
|
|
|
|
//* empty constructor
|
|
TileSet();
|
|
|
|
//* destructor
|
|
virtual ~TileSet()
|
|
{}
|
|
|
|
/**
|
|
Flags specifying what sides to draw in ::render. Corners are drawn when
|
|
the sides forming that corner are drawn, e.g. Top|Left draws the
|
|
top-center, center-left, and top-left chunks. The center-center chunk is
|
|
only drawn when Center is requested.
|
|
*/
|
|
enum Tile {
|
|
Top = 0x1,
|
|
Left = 0x2,
|
|
Bottom = 0x4,
|
|
Right = 0x8,
|
|
Center = 0x10,
|
|
TopLeft = Top|Left,
|
|
TopRight = Top|Right,
|
|
BottomLeft = Bottom|Left,
|
|
BottomRight = Bottom|Right,
|
|
Ring = Top|Left|Bottom|Right,
|
|
Horizontal = Left|Right|Center,
|
|
Vertical = Top|Bottom|Center,
|
|
Full = Ring|Center
|
|
};
|
|
Q_DECLARE_FLAGS(Tiles, Tile)
|
|
|
|
/**
|
|
Fills the specified rect with tiled chunks. Corners are never tiled,
|
|
edges are tiled in one direction, and the center chunk is tiled in both
|
|
directions. Partial tiles are used as needed so that the entire rect is
|
|
perfectly filled. Filling is performed as if all chunks are being drawn.
|
|
*/
|
|
void render(const QRect&, QPainter*, Tiles = Ring) const;
|
|
|
|
//* return size associated to this tileset
|
|
QSize size() const
|
|
{ return QSize( _w1 + _w3, _h1 + _h3 ); }
|
|
|
|
//* is valid
|
|
bool isValid() const
|
|
{ return _pixmaps.size() == 9; }
|
|
|
|
//* returns pixmap for given index
|
|
QPixmap pixmap( int index ) const
|
|
{ return _pixmaps[index]; }
|
|
|
|
protected:
|
|
|
|
//* shortcut to pixmap list
|
|
using PixmapList = QVector<QPixmap>;
|
|
|
|
//* initialize pixmap
|
|
void initPixmap( PixmapList&, const QPixmap&, int w, int h, const QRect& );
|
|
|
|
private:
|
|
|
|
//* pixmap arry
|
|
PixmapList _pixmaps;
|
|
|
|
// dimensions
|
|
int _w1;
|
|
int _h1;
|
|
int _w3;
|
|
int _h3;
|
|
|
|
};
|
|
|
|
|
|
class BreezeShadowHelper: public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
//* constructor
|
|
BreezeShadowHelper( QObject*/*, Helper& */);
|
|
|
|
//* destructor
|
|
~BreezeShadowHelper() override;
|
|
|
|
//* event filter
|
|
bool eventFilter( QObject*, QEvent* ) override;
|
|
|
|
const QVector<quint32>& createPixmapHandles();
|
|
quint32 createPixmap( const QPixmap& source );
|
|
|
|
bool installShadows( const QWidget * );
|
|
|
|
private:
|
|
QVector<quint32> _pixmaps;
|
|
TileSet _shadowTiles;
|
|
xcb_atom_t _atom = 0;
|
|
|
|
|
|
};
|