add clipping to FAB ripple

This commit is contained in:
laserpants 2016-06-12 18:17:27 +03:00
parent 369ed5adbb
commit 09405ad0be
6 changed files with 86 additions and 20 deletions

View File

@ -6,6 +6,8 @@
FloatingActionButtonPrivate::FloatingActionButtonPrivate(FloatingActionButton *q) FloatingActionButtonPrivate::FloatingActionButtonPrivate(FloatingActionButton *q)
: RaisedButtonPrivate(q), : RaisedButtonPrivate(q),
mini(false), mini(false),
offsX(34),
offsY(36),
corner(Qt::BottomRightCorner) corner(Qt::BottomRightCorner)
{ {
} }
@ -23,6 +25,11 @@ void FloatingActionButtonPrivate::init()
q->setGeometry(fabGeometry()); q->setGeometry(fabGeometry());
assignAnimationProperties(); assignAnimationProperties();
QPainterPath path;
path.addEllipse(0, 0, 56, 56);
ripple->setClipPath(path);
ripple->setClipping(true);
} }
QRect FloatingActionButtonPrivate::fabGeometry() const QRect FloatingActionButtonPrivate::fabGeometry() const
@ -33,27 +40,26 @@ QRect FloatingActionButtonPrivate::fabGeometry() const
if (!parent) if (!parent)
return QRect(); return QRect();
const int offset = mini ? 74 : 90;
const int s = mini ? 40 : 56; const int s = mini ? 40 : 56;
switch (corner) switch (corner)
{ {
case Qt::TopLeftCorner: case Qt::TopLeftCorner:
return QRect(offset - s, return QRect(offsX,
offset - s, offsY,
s, s); s, s);
case Qt::TopRightCorner: case Qt::TopRightCorner:
return QRect(parent->width() - offset, return QRect(parent->width() - (offsX + s),
offset - s, offsY,
s, s); s, s);
case Qt::BottomLeftCorner: case Qt::BottomLeftCorner:
return QRect(offset -s, return QRect(offsX,
parent->height() - offset, parent->height() - (offsY + s),
s, s); s, s);
case Qt::BottomRightCorner: case Qt::BottomRightCorner:
default: default:
return QRect(parent->width() - offset, return QRect(parent->width() - (offsX + s),
parent->height() - offset, parent->height() - (offsY + s),
s, s); s, s);
} }
} }
@ -111,11 +117,13 @@ void FloatingActionButton::setMini(bool state)
d->mini = state; d->mini = state;
if (state) { const int s = state ? 40 : 56;
setFixedSize(40, 40);
} else { setFixedSize(s, s);
setFixedSize(56, 56); QPainterPath path;
} path.addEllipse(0, 0, s, s);
d->ripple->setClipPath(path);
d->assignAnimationProperties(); d->assignAnimationProperties();
update(); update();
} }
@ -145,6 +153,52 @@ Qt::Corner FloatingActionButton::corner() const
return d->corner; return d->corner;
} }
void FloatingActionButton::setOffset(int x, int y)
{
Q_D(FloatingActionButton);
d->offsX = x;
d->offsY = y;
update();
}
QSize FloatingActionButton::offset() const
{
Q_D(const FloatingActionButton);
return QSize(d->offsX, d->offsY);
}
void FloatingActionButton::setXOffset(int x)
{
Q_D(FloatingActionButton);
d->offsX = x;
update();
}
int FloatingActionButton::xOffset() const
{
Q_D(const FloatingActionButton);
return d->offsX;
}
void FloatingActionButton::setYOffset(int y)
{
Q_D(FloatingActionButton);
d->offsY = y;
update();
}
int FloatingActionButton::yOffset() const
{
Q_D(const FloatingActionButton);
return d->offsY;
}
bool FloatingActionButton::event(QEvent *event) bool FloatingActionButton::event(QEvent *event)
{ {
QEvent::Type type = event->type(); QEvent::Type type = event->type();

View File

@ -21,6 +21,15 @@ public:
void setCorner(Qt::Corner corner); void setCorner(Qt::Corner corner);
Qt::Corner corner() const; Qt::Corner corner() const;
void setOffset(int x, int y);
QSize offset() const;
void setXOffset(int x);
int xOffset() const;
void setYOffset(int y);
int yOffset() const;
protected: protected:
bool event(QEvent *event) Q_DECL_OVERRIDE; bool event(QEvent *event) Q_DECL_OVERRIDE;
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;

View File

@ -19,6 +19,8 @@ public:
void assignAnimationProperties(); void assignAnimationProperties();
bool mini; bool mini;
int offsX;
int offsY;
Qt::Corner corner; Qt::Corner corner;
}; };

View File

@ -46,7 +46,7 @@ void RippleOverlay::paintEvent(QPaintEvent *event)
painter.setPen(Qt::NoPen); painter.setPen(Qt::NoPen);
if (useClip) { if (useClip) {
painter.setClipRegion(clipRegion); painter.setClipPath(clipPath);
} }
QList<Ripple *>::const_iterator i; QList<Ripple *>::const_iterator i;

View File

@ -21,7 +21,7 @@ public:
inline void setClipping(bool enabled) { useClip = enabled; update(); } inline void setClipping(bool enabled) { useClip = enabled; update(); }
inline bool hasClipping() const { return useClip; } inline bool hasClipping() const { return useClip; }
inline void setClipRegion(const QRegion &region) { clipRegion = region; update(); } inline void setClipPath(const QPainterPath &path) { clipPath = path; update(); }
protected: protected:
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
@ -31,7 +31,7 @@ protected slots:
private: private:
QList<Ripple *> ripples; QList<Ripple *> ripples;
QRegion clipRegion; QPainterPath clipPath;
bool useClip; bool useClip;
}; };

View File

@ -48,15 +48,16 @@ MainWindow::MainWindow(QWidget *parent)
FloatingActionButton *button = new FloatingActionButton(QIcon("../qt-material-widgets/ic_local_dining_white_24px.svg")); FloatingActionButton *button = new FloatingActionButton(QIcon("../qt-material-widgets/ic_local_dining_white_24px.svg"));
button->setParent(this); button->setParent(this);
button->setCorner(Qt::TopLeftCorner); button->setCorner(Qt::TopRightCorner);
button->setMini(true); button->setMini(true);
button->setYOffset(56);
// //
FloatingActionButton *button2 = new FloatingActionButton(QIcon("../qt-material-widgets/ic_message_white_24px.svg")); FloatingActionButton *button2 = new FloatingActionButton(QIcon("../qt-material-widgets/ic_message_white_24px.svg"));
button2->setParent(this); button2->setParent(this);
button2->setDisabled(true); //button2->setDisabled(true);
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()