qskinny/examples/iot-dashboard/kirigami/shadowedrectangle.h
Peter Hartmann c199a3bb59
Add IOT dashboard example (#116)
* Add IOT dashboard example

* Add images

* more content

* add pie chart

* Add skin factories etc.

* more work on the pie chart

* Try to use quick shapes

* Revert "Try to use quick shapes"

This reverts commit df6b5b22a339173d2a70ed85744b598811c26b30.

Doesn't work that easily unfortunately.

* implement design

* Add fonts; for now as a resource

We should use fontconfig of course later

* improve menu bar

* implement top bar

* use QNanoPainter for circular graphs

* Revert "use QNanoPainter for circular graphs"

This reverts commit ba0263cb1c19462cc41063ec7087c95e176c8293.

Try with QQuickPaintedItem instead for now.

* use painted items for circular bar graphs (for now)

* use different colors

* use some gradients

all of this is very hackish still

* add to top bar

* fix fonts and time display

* implement usage

* implement indoor temperature

* implement Humidity

* implement My Devices

* fix opacity issue with devices

* make icons quadratic

with some quick fixes as usual

* Add diagram

* try to smooth out curves

* Add diagram caption

* use tiny font

* make caption smaller

* add wekdays

* add grid lines

* fix my devices

* add light intensity

* add box around each section

* rename Card to Box

* Put indoor temperature inside a box

* put Humidity in a box

* put the rest in a box

* some small stuff

* add kirigami code

* something works somehow

* maybe we don't need our own class

still some work to do, but the main thing works

* add shadow from outside

... because the class is not a QskControl

* fine-tune the layout

* cross compilation: Make sure examples find libraries at link time

* fix compilation for embedded target

* add night time skin

* add new button class to better style it

* more hints for the night time skin

* change hints for dimmer

* change hints for progress bars

* Use animator for light dimmer

* use animator for progress bars

* Add Kirigami code

It was on oversight that this was forgotten earlier. We could of course
strip this down a lot to the part that we are actually using (i.e. the
shadowed rectangle).

* fix build with new QSkinny version

* fix paddings, something in the API changed

* fix stretch factors

* fix build with new version

* clang tidy fixes

* fix unused parameter warnings

should clean this up properly

* beautify example

* use astyle

* style menu bar properly

* fix warning

* more size hints

* refactor skins

* more skin hints

* graphic label skin hints

* menu item states instead of own API

* main grid box styling

* top bar styling

* fix build

* style round progress bars

* style time

* style indoor temperature and humidity

* simplify temperature and humidity

* style some more

* style My Devices section

* style My Devices some more

* fix styles when switching between them

* style diagram

* style more elements inside diagram

* more diagram style

* fix skin changes

* style light intensity

* Fix Humidity

* fix light intensity layout and other stuff

* style light intensity

* style button value label

* style round button

* style button boxes some more

* style menu bar top label

* style menu bar icons

* remove ShadowBox, it is not used

* style shadow boxes

* remove QskShadowedRectangle

We are not using it

* style usage spacer

* fine tune

* Refactor diagram before replacing it

* Add Diagram drawn with OpenGL

* use new Diagram class

* Support more than one data point in a diagram

* change data points and colors a bit

* position caption box

* adapt the spline to show nice curves

* remove boost::math dependency

We just hardcode the values here so we can get rid of the dependency.

* Remove kirigami code that we don't need

We only need the shadow

* move kirigami code

* rename header guards

* add license headers

* rename some classes
2021-04-26 06:22:35 +02:00

257 lines
6.6 KiB
C++

/*
* SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
#pragma once
#include <memory>
#include <QQuickItem>
class PaintedRectangleItem;
/**
* Grouped property for rectangle border.
*/
class BorderGroup : public QObject
{
Q_OBJECT
/**
* The width of the border in pixels.
*
* Default is 0.
*/
Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY changed)
/**
* The color of the border.
*
* Full RGBA colors are supported. The default is fully opaque black.
*/
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY changed)
public:
explicit BorderGroup(QObject *parent = nullptr);
qreal width() const;
void setWidth(qreal newWidth);
QColor color() const;
void setColor(const QColor &newColor);
Q_SIGNAL void changed();
inline bool isEnabled() const
{
return !qFuzzyIsNull(m_width);
}
private:
qreal m_width = 0.0;
QColor m_color = Qt::black;
};
/**
* Grouped property for rectangle shadow.
*/
class ShadowGroup : public QObject
{
Q_OBJECT
/**
* The size of the shadow.
*
* This is the approximate size of the shadow in pixels. However, due to falloff
* the actual shadow size can differ. The default is 0, which means no shadow will
* be rendered.
*/
Q_PROPERTY(qreal size READ size WRITE setSize NOTIFY changed)
/**
* Offset of the shadow on the X axis.
*
* In pixels. The default is 0.
*/
Q_PROPERTY(qreal xOffset READ xOffset WRITE setXOffset NOTIFY changed)
/**
* Offset of the shadow on the Y axis.
*
* In pixels. The default is 0.
*/
Q_PROPERTY(qreal yOffset READ yOffset WRITE setYOffset NOTIFY changed)
/**
* The color of the shadow.
*
* Full RGBA colors are supported. The default is fully opaque black.
*/
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY changed)
public:
explicit ShadowGroup(QObject *parent = nullptr);
qreal size() const;
void setSize(qreal newSize);
qreal xOffset() const;
void setXOffset(qreal newXOffset);
qreal yOffset() const;
void setYOffset(qreal newYOffset);
QColor color() const;
void setColor(const QColor &newShadowColor);
Q_SIGNAL void changed();
private:
qreal m_size = 0.0;
qreal m_xOffset = 0.0;
qreal m_yOffset = 0.0;
QColor m_color = Qt::black;
};
/**
* Grouped property for corner radius.
*/
class CornersGroup : public QObject
{
Q_OBJECT
/**
* The radius of the top-left corner.
*
* In pixels. Defaults to -1, which indicates this value should not be used.
*/
Q_PROPERTY(qreal topLeftRadius READ topLeft WRITE setTopLeft NOTIFY changed)
/**
* The radius of the top-right corner.
*
* In pixels. Defaults to -1, which indicates this value should not be used.
*/
Q_PROPERTY(qreal topRightRadius READ topRight WRITE setTopRight NOTIFY changed)
/**
* The radius of the bottom-left corner.
*
* In pixels. Defaults to -1, which indicates this value should not be used.
*/
Q_PROPERTY(qreal bottomLeftRadius READ bottomLeft WRITE setBottomLeft NOTIFY changed)
/**
* The radius of the bottom-right corner.
*
* In pixels. Defaults to -1, which indicates this value should not be used.
*/
Q_PROPERTY(qreal bottomRightRadius READ bottomRight WRITE setBottomRight NOTIFY changed)
public:
explicit CornersGroup(QObject *parent = nullptr);
qreal topLeft() const;
void setTopLeft(qreal newTopLeft);
qreal topRight() const;
void setTopRight(qreal newTopRight);
qreal bottomLeft() const;
void setBottomLeft(qreal newBottomLeft);
qreal bottomRight() const;
void setBottomRight(qreal newBottomRight);
Q_SIGNAL void changed();
QVector4D toVector4D(float all) const;
private:
float m_topLeft = -1.0;
float m_topRight = -1.0;
float m_bottomLeft = -1.0;
float m_bottomRight = -1.0;
};
/**
* A rectangle with a shadow.
*
* This item will render a rectangle, with a shadow below it. The rendering is done
* using distance fields, which provide greatly improved performance. The shadow is
* rendered outside of the item's bounds, so the item's width and height are the
* rectangle's width and height.
*
* @since 5.69 / 2.12
*/
class ShadowedRectangle : public QQuickItem
{
Q_OBJECT
/**
* Corner radius of the rectangle.
*
* This is the amount of rounding to apply to all of the rectangle's
* corners, in pixels. Individual corners can have a different radius, see
* \property corners.
*
* The default is 0.
*/
Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
/**
* The color of the rectangle.
*
* Full RGBA colors are supported. The default is fully opaque white.
*/
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
/**
* Border properties.
*
* \sa BorderGroup
*/
Q_PROPERTY(BorderGroup *border READ border CONSTANT)
/**
* Shadow properties.
*
* \sa ShadowGroup
*/
Q_PROPERTY(ShadowGroup *shadow READ shadow CONSTANT)
/**
* Corner radius.
*
* Note that the values from this group override \property radius for the
* corner they affect.
*
* \sa CornerGroup
*/
Q_PROPERTY(CornersGroup *corners READ corners CONSTANT)
Q_PROPERTY(bool softwareRendering READ isSoftwareRendering NOTIFY softwareRenderingChanged)
public:
ShadowedRectangle(QQuickItem *parent = nullptr);
~ShadowedRectangle() override;
BorderGroup *border() const;
ShadowGroup *shadow() const;
CornersGroup *corners() const;
qreal radius() const;
void setRadius(qreal newRadius);
Q_SIGNAL void radiusChanged();
QColor color() const;
void setColor(const QColor &newColor);
Q_SIGNAL void colorChanged();
void componentComplete() override;
bool isSoftwareRendering() const;
Q_SIGNALS:
void softwareRenderingChanged();
protected:
PaintedRectangleItem *softwareItem() const;
void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override;
QSGNode *updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *data) override;
private:
void checkSoftwareItem();
const std::unique_ptr<BorderGroup> m_border;
const std::unique_ptr<ShadowGroup> m_shadow;
const std::unique_ptr<CornersGroup> m_corners;
qreal m_radius = 0.0;
QColor m_color = Qt::white;
PaintedRectangleItem *m_softwareItem = nullptr;
};