feat: FluRectangle支持border绘制
This commit is contained in:
parent
af573b71a4
commit
49e96b094b
|
@ -58,6 +58,22 @@ FluScrollablePage{
|
||||||
color:"#b4009e"
|
color:"#b4009e"
|
||||||
radius:[0,0,0,15]
|
radius:[0,0,0,15]
|
||||||
}
|
}
|
||||||
|
FluRectangle{
|
||||||
|
width: 50
|
||||||
|
height: 50
|
||||||
|
color:"#a8d5ba"
|
||||||
|
radius:[15,15,15,15]
|
||||||
|
borderWidth: 3
|
||||||
|
borderColor: "#5b8a72"
|
||||||
|
}
|
||||||
|
FluRectangle{
|
||||||
|
width: 50
|
||||||
|
height: 50
|
||||||
|
color:"#dbe2ef"
|
||||||
|
radius:[15,0,0,0]
|
||||||
|
borderWidth: 2
|
||||||
|
borderColor: "#3f72af"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +82,8 @@ FluScrollablePage{
|
||||||
Layout.topMargin: -6
|
Layout.topMargin: -6
|
||||||
code:'FluRectangle{
|
code:'FluRectangle{
|
||||||
radius: [25,25,25,25]
|
radius: [25,25,25,25]
|
||||||
|
borderWidth: 2
|
||||||
|
borderColor: "#000000"
|
||||||
width: 50
|
width: 50
|
||||||
height: 50
|
height: 50
|
||||||
}'
|
}'
|
||||||
|
|
|
@ -2,33 +2,61 @@
|
||||||
#include <QPainterPath>
|
#include <QPainterPath>
|
||||||
|
|
||||||
FluRectangle::FluRectangle(QQuickItem *parent) : QQuickPaintedItem(parent) {
|
FluRectangle::FluRectangle(QQuickItem *parent) : QQuickPaintedItem(parent) {
|
||||||
color(QColor(255, 255, 255, 255));
|
color(Qt::white);
|
||||||
radius({0, 0, 0, 0});
|
radius({0, 0, 0, 0});
|
||||||
|
borderWidth(0);
|
||||||
|
borderColor(Qt::black);
|
||||||
connect(this, &FluRectangle::colorChanged, this, [=] { update(); });
|
connect(this, &FluRectangle::colorChanged, this, [=] { update(); });
|
||||||
connect(this, &FluRectangle::radiusChanged, this, [=] { update(); });
|
connect(this, &FluRectangle::radiusChanged, this, [=] { update(); });
|
||||||
|
connect(this, &FluRectangle::borderWidthChanged, this, [=] { update(); });
|
||||||
|
connect(this, &FluRectangle::borderColorChanged, this, [=] { update(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FluRectangle::borderValid() const {
|
||||||
|
return qRound(_borderWidth) >= 1 && _color.isValid() && _color.alpha() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
void FluRectangle::paint(QPainter *painter) {
|
void FluRectangle::paint(QPainter *painter) {
|
||||||
painter->save();
|
painter->save();
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
QPainterPath path;
|
|
||||||
QRectF rect = boundingRect();
|
QRectF rect = boundingRect();
|
||||||
path.moveTo(rect.bottomRight() - QPointF(0, _radius[2]));
|
bool valid = borderValid();
|
||||||
path.lineTo(rect.topRight() + QPointF(0, _radius[1]));
|
if (valid) {
|
||||||
path.arcTo(QRectF(QPointF(rect.topRight() - QPointF(_radius[1] * 2, 0)),
|
// 绘制边框时画笔的宽度从路径向两侧扩充
|
||||||
QSize(_radius[1] * 2, _radius[1] * 2)),
|
// 因此实际绘制的矩形应向内侧收缩边框宽度的一半,避免边框裁剪导致不完整
|
||||||
0, 90);
|
qreal halfBorderWidth = _borderWidth / 2.0;
|
||||||
path.lineTo(rect.topLeft() + QPointF(_radius[0], 0));
|
rect.adjust(halfBorderWidth, halfBorderWidth, -halfBorderWidth, -halfBorderWidth);
|
||||||
path.arcTo(QRectF(QPointF(rect.topLeft()), QSize(_radius[0] * 2, _radius[0] * 2)), 90, 90);
|
}
|
||||||
path.lineTo(rect.bottomLeft() - QPointF(0, _radius[3]));
|
|
||||||
path.arcTo(QRectF(QPointF(rect.bottomLeft() - QPointF(0, _radius[3] * 2)),
|
QPainterPath path;
|
||||||
QSize(_radius[3] * 2, _radius[3] * 2)),
|
QList<int> r = _radius;
|
||||||
180, 90);
|
|
||||||
path.lineTo(rect.bottomRight() - QPointF(_radius[2], 0));
|
while (r.size() < 4) {
|
||||||
path.arcTo(QRectF(QPointF(rect.bottomRight() - QPointF(_radius[2] * 2, _radius[2] * 2)),
|
r.append(0);
|
||||||
QSize(_radius[2] * 2, _radius[2] * 2)),
|
}
|
||||||
270, 90);
|
|
||||||
|
// 从右下角开始逆时针绘制圆角矩形路径
|
||||||
|
path.moveTo(rect.bottomRight() - QPointF(0, r[2]));
|
||||||
|
path.lineTo(rect.topRight() + QPointF(0, r[1]));
|
||||||
|
path.arcTo(QRectF(QPointF(rect.topRight() - QPointF(r[1] * 2, 0)), QSize(r[1] * 2, r[1] * 2)), 0, 90);
|
||||||
|
|
||||||
|
path.lineTo(rect.topLeft() + QPointF(r[0], 0));
|
||||||
|
path.arcTo(QRectF(QPointF(rect.topLeft()), QSize(r[0] * 2, r[0] * 2)), 90, 90);
|
||||||
|
|
||||||
|
path.lineTo(rect.bottomLeft() - QPointF(0, r[3]));
|
||||||
|
path.arcTo(QRectF(QPointF(rect.bottomLeft() - QPointF(0, r[3] * 2)), QSize(r[3] * 2, r[3] * 2)), 180, 90);
|
||||||
|
|
||||||
|
path.lineTo(rect.bottomRight() - QPointF(r[2], 0));
|
||||||
|
path.arcTo(QRectF(QPointF(rect.bottomRight() - QPointF(r[2] * 2, r[2] * 2)), QSize(r[2] * 2, r[2] * 2)), 270, 90);
|
||||||
|
|
||||||
|
// 填充背景
|
||||||
painter->fillPath(path, _color);
|
painter->fillPath(path, _color);
|
||||||
|
|
||||||
|
// 绘制边框
|
||||||
|
if (valid) {
|
||||||
|
painter->strokePath(path, QPen(_borderColor, _borderWidth));
|
||||||
|
}
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,13 @@ class FluRectangle : public QQuickPaintedItem {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY_AUTO(QColor, color)
|
Q_PROPERTY_AUTO(QColor, color)
|
||||||
Q_PROPERTY_AUTO(QList<int>, radius)
|
Q_PROPERTY_AUTO(QList<int>, radius)
|
||||||
|
Q_PROPERTY_AUTO(qreal, borderWidth)
|
||||||
|
Q_PROPERTY_AUTO(QColor, borderColor)
|
||||||
QML_NAMED_ELEMENT(FluRectangle)
|
QML_NAMED_ELEMENT(FluRectangle)
|
||||||
public:
|
public:
|
||||||
explicit FluRectangle(QQuickItem *parent = nullptr);
|
explicit FluRectangle(QQuickItem *parent = nullptr);
|
||||||
|
|
||||||
|
bool borderValid() const;
|
||||||
|
|
||||||
void paint(QPainter *painter) override;
|
void paint(QPainter *painter) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -231,6 +231,8 @@ Module {
|
||||||
exportMetaObjectRevisions: [0]
|
exportMetaObjectRevisions: [0]
|
||||||
Property { name: "color"; type: "QColor" }
|
Property { name: "color"; type: "QColor" }
|
||||||
Property { name: "radius"; type: "QList<int>" }
|
Property { name: "radius"; type: "QList<int>" }
|
||||||
|
Property { name: "borderWidth"; type: "double" }
|
||||||
|
Property { name: "borderColor"; type: "QColor" }
|
||||||
}
|
}
|
||||||
Component {
|
Component {
|
||||||
name: "FluSheetType"
|
name: "FluSheetType"
|
||||||
|
@ -2776,7 +2778,7 @@ Module {
|
||||||
}
|
}
|
||||||
Property {
|
Property {
|
||||||
name: "layoutMacosButtons"
|
name: "layoutMacosButtons"
|
||||||
type: "FluLoader_QMLTYPE_14"
|
type: "FluLoader_QMLTYPE_11"
|
||||||
isReadonly: true
|
isReadonly: true
|
||||||
isPointer: true
|
isPointer: true
|
||||||
}
|
}
|
||||||
|
@ -2797,12 +2799,16 @@ Module {
|
||||||
Property { name: "items"; type: "QVariant" }
|
Property { name: "items"; type: "QVariant" }
|
||||||
Property { name: "emptyText"; type: "string" }
|
Property { name: "emptyText"; type: "string" }
|
||||||
Property { name: "autoSuggestBoxReplacement"; type: "int" }
|
Property { name: "autoSuggestBoxReplacement"; type: "int" }
|
||||||
|
Property { name: "itemHeight"; type: "int" }
|
||||||
|
Property { name: "itemRows"; type: "int" }
|
||||||
|
Property { name: "showSuggestWhenPressed"; type: "bool" }
|
||||||
Property { name: "textRole"; type: "string" }
|
Property { name: "textRole"; type: "string" }
|
||||||
Property { name: "filter"; type: "QVariant" }
|
Property { name: "filter"; type: "QVariant" }
|
||||||
Signal {
|
Signal {
|
||||||
name: "itemClicked"
|
name: "itemClicked"
|
||||||
Parameter { name: "data"; type: "QVariant" }
|
Parameter { name: "data"; type: "QVariant" }
|
||||||
}
|
}
|
||||||
|
Method { name: "showSuggest"; type: "QVariant" }
|
||||||
Method {
|
Method {
|
||||||
name: "updateText"
|
name: "updateText"
|
||||||
type: "QVariant"
|
type: "QVariant"
|
||||||
|
@ -2830,8 +2836,9 @@ Module {
|
||||||
defaultProperty: "data"
|
defaultProperty: "data"
|
||||||
Property { name: "isDot"; type: "bool" }
|
Property { name: "isDot"; type: "bool" }
|
||||||
Property { name: "showZero"; type: "bool" }
|
Property { name: "showZero"; type: "bool" }
|
||||||
Property { name: "count"; type: "int" }
|
Property { name: "count"; type: "QVariant" }
|
||||||
Property { name: "topRight"; type: "bool" }
|
Property { name: "max"; type: "int" }
|
||||||
|
Property { name: "position"; type: "string" }
|
||||||
}
|
}
|
||||||
Component {
|
Component {
|
||||||
prototype: "QQuickItem"
|
prototype: "QQuickItem"
|
||||||
|
@ -3479,8 +3486,8 @@ Module {
|
||||||
Property { name: "actionItem"; type: "QQmlComponent"; isPointer: true }
|
Property { name: "actionItem"; type: "QQmlComponent"; isPointer: true }
|
||||||
Property { name: "topPadding"; type: "int" }
|
Property { name: "topPadding"; type: "int" }
|
||||||
Property { name: "pageMode"; type: "int" }
|
Property { name: "pageMode"; type: "int" }
|
||||||
Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_47"; isPointer: true }
|
Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_37"; isPointer: true }
|
||||||
Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_47"; isPointer: true }
|
Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_37"; isPointer: true }
|
||||||
Property { name: "navCompactWidth"; type: "int" }
|
Property { name: "navCompactWidth"; type: "int" }
|
||||||
Property { name: "navTopMargin"; type: "int" }
|
Property { name: "navTopMargin"; type: "int" }
|
||||||
Property { name: "cellHeight"; type: "int" }
|
Property { name: "cellHeight"; type: "int" }
|
||||||
|
|
Loading…
Reference in New Issue