Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion panels/notification/bubble/bubblemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,36 @@
for (const auto &item : m_bubbles) {
if (item->id() == id) {
m_delayBubbles.removeAll(id);
remove(m_bubbles.indexOf(item));
// Emit signal before removing to trigger QML animation
Q_EMIT bubbleAboutToRemove(id);
// Delay the actual removal to allow animation to complete
QTimer::singleShot(m_removeAnimationDuration, this, [this, id]() {
for (const auto &item : m_bubbles) {

Check warning on line 144 in panels/notification/bubble/bubblemodel.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Variable 'item' can be declared as pointer to const
if (item->id() == id) {

Check warning on line 145 in panels/notification/bubble/bubblemodel.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Consider using std::find_if algorithm instead of a raw loop.
remove(m_bubbles.indexOf(item));
break;
}
}
});
return item;
}
}

return nullptr;
}

int BubbleModel::removeAnimationDuration() const

Check warning on line 158 in panels/notification/bubble/bubblemodel.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'removeAnimationDuration' is never used.
{
return m_removeAnimationDuration;
}

void BubbleModel::setRemoveAnimationDuration(int duration)

Check warning on line 163 in panels/notification/bubble/bubblemodel.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'setRemoveAnimationDuration' is never used.
{
m_removeAnimationDuration = duration + 100;
Q_EMIT removeAnimationDurationChanged();
}

BubbleItem *BubbleModel::bubbleItem(int bubbleIndex) const

Check warning on line 169 in panels/notification/bubble/bubblemodel.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'bubbleItem' is never used.
{
if (bubbleIndex < 0 || bubbleIndex >= items().count())
return nullptr;
Expand Down
7 changes: 7 additions & 0 deletions panels/notification/bubble/bubblemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
{
Q_OBJECT
Q_PROPERTY(qint64 delayRemovedBubble READ delayRemovedBubble WRITE setDelayRemovedBubble NOTIFY delayRemovedBubbleChanged FINAL)
Q_PROPERTY(int removeAnimationDuration READ removeAnimationDuration WRITE setRemoveAnimationDuration NOTIFY removeAnimationDurationChanged FINAL)
public:
enum {
AppName = Qt::UserRole + 1,
Expand Down Expand Up @@ -64,10 +65,15 @@
qint64 delayRemovedBubble() const;
void setDelayRemovedBubble(qint64 newDelayRemovedBubble);

int removeAnimationDuration() const;
void setRemoveAnimationDuration(int duration);

void clearInvalidBubbles();

signals:
void delayRemovedBubbleChanged();
void bubbleAboutToRemove(qint64 id);

Check warning on line 75 in panels/notification/bubble/bubblemodel.h

View workflow job for this annotation

GitHub Actions / cppcheck

Local variable 'bubbleAboutToRemove' shadows outer function
void removeAnimationDurationChanged();

private:
void updateBubbleCount(int count);
Expand All @@ -85,6 +91,7 @@
QList<qint64> m_delayBubbles;
qint64 m_delayRemovedBubble{NotifyEntity::InvalidId};
const int DelayRemovBubbleTime{1000};
int m_removeAnimationDuration{700};
};

}
34 changes: 34 additions & 0 deletions panels/notification/bubble/package/Bubble.qml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,47 @@ Control {
id: control
height: loader.height
property var bubble
property bool isRemoving: false

Connections {
target: Applet.bubbles
function onBubbleAboutToRemove(id) {
if (id === bubble.id) {
control.isRemoving = true
}
}
}

onHoveredChanged: function () {
if (control.hovered) {
Applet.bubbles.delayRemovedBubble = bubble.id
} else {
Applet.bubbles.delayRemovedBubble = NotifyEntity.InvalidId
}
}

states: [
State {
name: "removing"
when: control.isRemoving
PropertyChanges {
target: control
x: control.width
opacity: 0
}
}
]

transitions: [
Transition {
to: "removing"
NumberAnimation {
properties: "x,opacity"
duration: Applet.bubbles.removeAnimationDuration
easing.type: Easing.InExpo
}
}
]

Loader {
id: loader
Expand Down
32 changes: 32 additions & 0 deletions panels/notification/bubble/package/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import org.deepin.dtk 1.0

Window {
id: root

readonly property int removeAnimationDuration: 600

Component.onCompleted: {
Applet.bubbles.removeAnimationDuration = removeAnimationDuration
}

function windowMargin(position) {
let dockApplet = DS.applet("org.deepin.ds.dock")
Expand Down Expand Up @@ -105,6 +111,7 @@ Window {
model: Applet.bubbles
interactive: false
verticalLayoutDirection: ListView.BottomToTop
cacheBuffer: 0
add: Transition {
id: addTrans
// Before starting the new animation, forcibly complete the previous notification bubble's animation
Expand All @@ -128,6 +135,31 @@ Window {
easing.type: Easing.OutExpo
}
}
remove: Transition {
NumberAnimation {
target: removeTrans.ViewTransition.item
property: "x"
from: 0
to: removeTrans.ViewTransition.item.width
duration: root.removeAnimationDuration
easing.type: Easing.InExpo
}
NumberAnimation {
target: removeTrans.ViewTransition.item
property: "opacity"
from: 1.0
to: 0.0
duration: root.removeAnimationDuration
easing.type: Easing.InExpo
}
}
removeDisplaced: Transition {
NumberAnimation {
properties: "y"
duration: 400
easing.type: Easing.OutCubic
}
}
delegate: Bubble {
width: 360
bubble: model
Expand Down