[gnome-shell/wip/fmuellner/notification-redux: 64/88] calendar: Do some cute animations
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/fmuellner/notification-redux: 64/88] calendar: Do some cute animations
- Date: Sun, 15 Feb 2015 17:36:10 +0000 (UTC)
commit fcb7a78bddcea0d75ace3688375d2e7bbdb05aa2
Author: Florian Müllner <fmuellner gnome org>
Date: Fri Feb 13 20:06:24 2015 +0100
calendar: Do some cute animations
js/ui/calendar.js | 100 +++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 90 insertions(+), 10 deletions(-)
---
diff --git a/js/ui/calendar.js b/js/ui/calendar.js
index 0d63f7e..c280d89 100644
--- a/js/ui/calendar.js
+++ b/js/ui/calendar.js
@@ -3,6 +3,7 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
+const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const St = imports.gi.St;
const Signals = imports.signals;
@@ -916,12 +917,15 @@ const MessageListEntry = new Lang.Class({
this._closeButton.connect('clicked', Lang.bind(this,
function() {
this.emit('close');
- this.actor.destroy();
}));
this.actor.connect('notify::hover', Lang.bind(this, this._sync));
this._sync();
},
+ canClear: function() {
+ return true;
+ },
+
_sync: function() {
let hovered = this.actor.hover;
this._closeButton.visible = hovered;
@@ -935,6 +939,7 @@ const MessageListSection = new Lang.Class({
_init: function(title) {
this.actor = new St.BoxLayout({ style_class: 'message-list-section',
+ clip_to_allocation: true,
x_expand: true, vertical: true });
let titleBox = new St.BoxLayout({ style_class: 'message-list-section-title-box' });
this.actor.add_actor(titleBox);
@@ -976,8 +981,71 @@ const MessageListSection = new Lang.Class({
}
},
+ addMessage: function(message, animate) {
+ let bin = new St.Widget({ layout_manager: new ScaleLayout(),
+ pivot_point: new Clutter.Point({ x: 0.5, y: 0.5 }) });
+ bin._delegate = message;
+ message.actor.connect('destroy', function() { bin.destroy(); });
+ message.connect('close', Lang.bind(this, this.removeMessage, true));
+
+ bin.add_actor(message.actor);
+ this._list.add_actor(bin);
+
+ if (animate) {
+ bin.scale_y = bin.scale_x = 0;
+ Tweener.addTween(bin, { scale_x: 1,
+ scale_y: 1,
+ time: MessageTray.ANIMATION_TIME,
+ transition: 'easeOutQuad' });
+ }
+
+ return bin;
+ },
+
+ removeMessage: function(message, animate) {
+ let bin = message.actor.get_parent();
+
+ if (animate)
+ Tweener.addTween(bin, { scale_x: 0,
+ scale_y: 0,
+ time: MessageTray.ANIMATION_TIME,
+ transition: 'easeOutQuad',
+ onComplete: function() { bin.destroy(); } });
+ else
+ bin.destroy();
+ },
+
+ get _messages() {
+ return this._list.get_children().map(function(a) { return a._delegate; });
+ },
+
+ _tweenMessages: function(messages, params, onComplete) {
+ if (Array.isArray(messages)) {
+ for (let i = 0; i < messages.length; i++) {
+ if (i == messages.length - 1)
+ params.onComplete = onComplete;
+ params.delay = i * 0.1;
+ Tweener.addTween(messages[i].actor.get_parent(), params);
+ }
+ } else {
+ params.onComplete = onComplete;
+ Tweener.addTween(messages.actor.get_parent(), params);
+ }
+ },
+
clear: function() {
- this._list.destroy_all_children();
+ let messages = this._messages.filter(function(m) { return m.canClear(); });
+ this._tweenMessages(messages,
+ { anchor_x: this._list.width,
+ time: MessageTray.ANIMATION_TIME,
+ transition: 'easeOutQuad' },
+ function() {
+ messages.forEach(function(m) { m.actor.get_parent().destroy(); });
+ });
+ },
+
+ _canClear: function() {
+ return this._messages.some(function(m) { return m.canClear(); });
},
isEmpty: function() {
@@ -991,6 +1059,7 @@ const MessageListSection = new Lang.Class({
_sync: function() {
this.actor.visible = !this.isEmpty() && this._isToday();
+ this._closeButton.visible = this._canClear();
}
});
@@ -1215,8 +1284,14 @@ const NotificationSection = new Lang.Class({
: GLib.markup_escape_text(notification.bannerBodyText, -1);
}
let listEntry = new MessageListEntry(notification.title, body, { gicon: gicon, time: new Date() });
+ listEntry.actor.connect('clicked', function() { notification._onClicked(); });
+ notification.connect('destroy', Lang.bind(this, function() {
+ this.removeMessage(listEntry, this.actor.mapped);
+ }));
+ listEntry.connect('close', function() { notification.destroy(); });
+ let listChild = this.addMessage(listEntry, this.actor.mapped);
// TODO: Keep URGENT notifications on top
- this._list.insert_child_below(listEntry.actor, null);
+ this._list.set_child_below_sibling(listChild, null);
},
_onSourceDestroy: function(source, obj) {
@@ -1365,7 +1440,7 @@ const EventsSection = new Lang.Class({
this._reloading = true;
- this.clear();
+ this._list.destroy_all_children();
let periodBegin = _getBeginningOfDay(this._date);
let periodEnd = _getEndOfDay(this._date);
@@ -1492,19 +1567,24 @@ const MessageList = new Lang.Class({
Name: 'MessageList',
_init: function() {
- this.actor = new St.Widget({ style_class: 'events-table',
+ this.actor = new St.Widget({ style_class: 'message-list',
layout_manager: new Clutter.BinLayout(),
x_expand: true, y_expand: true });
this._placeholder = new Placeholder();
this.actor.add_actor(this._placeholder.actor);
- this._scrollView = new St.ScrollView({ x_expand: true, y_expand: true,
- y_align: Clutter.ActorAlign.START });
+ this._scrollView = new St.ScrollView({ style_class: 'vfade',
+ overlay_scrollbars: true,
+ x_expand: true, y_expand: true,
+ x_fill: true, y_fill: true });
+ this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
this.actor.add_actor(this._scrollView);
this._sectionList = new St.BoxLayout({ style_class: 'message-list-sections',
- vertical: true });
+ vertical: true,
+ y_expand: true,
+ y_align: Clutter.ActorAlign.START });
this._scrollView.add_actor(this._sectionList);
this._sections = [];
@@ -1525,8 +1605,8 @@ const MessageList = new Lang.Class({
},
_sync: function() {
- let visible = this._sections.every(function(s) { return s.isEmpty() || !s.actor.visible });
- this._placeholder.actor.visible = visible;
+ let showPlaceholder = this._sections.every(function(s) { return s.isEmpty() || !s.actor.visible });
+ this._placeholder.actor.visible = showPlaceholder;
},
setEventSource: function(eventSource) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]