From bb4935ae020406988071e9e88e007025251ed3bf Mon Sep 17 00:00:00 2001 From: Damien Churchill Date: Mon, 23 Mar 2009 01:10:57 +0000 Subject: [PATCH] add a notify method to Deluge.Ui --- deluge/ui/web/css/Roar.css | 55 +++++++++++ deluge/ui/web/index.html | 2 + deluge/ui/web/js/Roar.js | 166 ++++++++++++++++++++++++++++++++++ deluge/ui/web/js/deluge-ui.js | 8 ++ 4 files changed, 231 insertions(+) create mode 100644 deluge/ui/web/css/Roar.css create mode 100644 deluge/ui/web/js/Roar.js diff --git a/deluge/ui/web/css/Roar.css b/deluge/ui/web/css/Roar.css new file mode 100644 index 000000000..efa6f539d --- /dev/null +++ b/deluge/ui/web/css/Roar.css @@ -0,0 +1,55 @@ +.roar-body +{ + position: absolute; + font: 12px/14px "Lucida Grande", Arial, Helvetica, Verdana, sans-serif; + color: #fff; + text-align: left; + z-index: 999; +} + +.roar +{ + position: absolute; + width: 300px; + cursor: pointer; +} +.roar-bg +{ + position: absolute; + z-index: 1000; + width: 100%; + height: 100%; + left: 0; + top: 0; + background-color: #000; + -moz-border-radius: 10px; + -webkit-border-radius: 5px; + -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); +} +.roar-body-ugly .roar +{ + background-color: #333; +} +.roar-body-ugly .roar-bg +{ + display: none; +} +.roar h3 +{ + position: relative; + padding: 15px 10px 0; + margin: 0; + border: 0; + font-size: 13px; + color: #fff; + z-index: 1002; +} +.roar p +{ + position: relative; + padding: 10px 10px 15px; + margin: 0; + font-size: 12px; + color: #fff; + z-index: 1002; +} \ No newline at end of file diff --git a/deluge/ui/web/index.html b/deluge/ui/web/index.html index 41be50341..45228c3ab 100644 --- a/deluge/ui/web/index.html +++ b/deluge/ui/web/index.html @@ -10,6 +10,7 @@ + @@ -19,6 +20,7 @@ + diff --git a/deluge/ui/web/js/Roar.js b/deluge/ui/web/js/Roar.js new file mode 100644 index 000000000..78580f8c0 --- /dev/null +++ b/deluge/ui/web/js/Roar.js @@ -0,0 +1,166 @@ +/** + * Roar - Notifications + * + * Inspired by Growl + * + * @version 1.0.1 + * + * @license MIT-style license + * @author Harald Kirschner + * @copyright Author + */ + +var Roar = new Class({ + + Implements: [Options, Events, Chain], + + options: { + duration: 3000, + position: 'upperLeft', + container: null, + bodyFx: null, + itemFx: null, + margin: {x: 10, y: 10}, + offset: 10, + className: 'roar', + onShow: $empty, + onHide: $empty, + onRender: $empty + }, + + initialize: function(options) { + this.setOptions(options); + this.items = []; + this.container = $(this.options.container) || document; + }, + + alert: function(title, message, options) { + var params = Array.link(arguments, {title: String.type, message: String.type, options: Object.type}); + var items = [new Element('h3', {'html': $pick(params.title, '')})]; + if (params.message) items.push(new Element('p', {'html': params.message})); + return this.inject(items, params.options); + }, + + inject: function(elements, options) { + if (!this.body) this.render(); + options = options || {}; + + var offset = [-this.options.offset, 0]; + var last = this.items.getLast(); + if (last) { + offset[0] = last.retrieve('roar:offset'); + offset[1] = offset[0] + last.offsetHeight + this.options.offset; + } + var to = {'opacity': 1}; + to[this.align.y] = offset; + + var item = new Element('div', { + 'class': this.options.className, + 'opacity': 0 + }).adopt( + new Element('div', { + 'class': 'roar-bg', + 'opacity': 0.7 + }), + elements + ); + + item.setStyle(this.align.x, 0).store('roar:offset', offset[1]).set('morph', $merge({ + unit: 'px', + link: 'cancel', + onStart: Chain.prototype.clearChain, + transition: Fx.Transitions.Back.easeOut + }, this.options.itemFx)); + + var remove = this.remove.create({ + bind: this, + arguments: [item], + delay: 10 + }); + this.items.push(item.addEvent('click', remove)); + + if (this.options.duration) { + var over = false; + var trigger = (function() { + trigger = null; + if (!over) remove(); + }).delay(this.options.duration); + item.addEvents({ + mouseover: function() { + over = true; + }, + mouseout: function() { + over = false; + if (!trigger) remove(); + } + }); + } + item.inject(this.body).morph(to); + return this.fireEvent('onShow', [item, this.items.length]); + }, + + remove: function(item) { + var index = this.items.indexOf(item); + if (index == -1) return this; + this.items.splice(index, 1); + item.removeEvents(); + var to = {opacity: 0}; + to[this.align.y] = item.getStyle(this.align.y).toInt() - item.offsetHeight - this.options.offset; + item.morph(to).get('morph').chain(item.destroy.bind(item)); + return this.fireEvent('onHide', [item, this.items.length]).callChain(item); + }, + + empty: function() { + while (this.items.length) this.remove(this.items[0]); + return this; + }, + + render: function() { + this.position = this.options.position; + if ($type(this.position) == 'string') { + var position = {x: 'center', y: 'center'}; + this.align = {x: 'left', y: 'top'}; + if ((/left|west/i).test(this.position)) position.x = 'left'; + else if ((/right|east/i).test(this.position)) this.align.x = position.x = 'right'; + if ((/upper|top|north/i).test(this.position)) position.y = 'top'; + else if ((/bottom|lower|south/i).test(this.position)) this.align.y = position.y = 'bottom'; + this.position = position; + } + this.body = new Element('div', {'class': 'roar-body'}).inject(document.body); + if (Browser.Engine.trident4) this.body.addClass('roar-body-ugly'); + this.moveTo = this.body.setStyles.bind(this.body); + this.reposition(); + if (this.options.bodyFx) { + var morph = new Fx.Morph(this.body, $merge({ + unit: 'px', + chain: 'cancel', + transition: Fx.Transitions.Circ.easeOut + }, this.options.bodyFx)); + this.moveTo = morph.start.bind(morph); + } + var repos = this.reposition.bind(this); + window.addEvents({ + scroll: repos, + resize: repos + }); + this.fireEvent('onRender', this.body); + }, + + reposition: function() { + var max = document.getCoordinates(), scroll = document.getScroll(), margin = this.options.margin; + max.left += scroll.x; + max.right += scroll.x; + max.top += scroll.y; + max.bottom += scroll.y; + var rel = ($type(this.container) == 'element') ? this.container.getCoordinates() : max; + this.moveTo({ + left: (this.position.x == 'right') + ? (Math.min(rel.right, max.right) - margin.x) + : (Math.max(rel.left, max.left) + margin.x), + top: (this.position.y == 'bottom') + ? (Math.min(rel.bottom, max.bottom) - margin.y) + : (Math.max(rel.top, max.top) + margin.y) + }); + } + +}); \ No newline at end of file diff --git a/deluge/ui/web/js/deluge-ui.js b/deluge/ui/web/js/deluge-ui.js index 0a3d17ef0..3dc763b15 100644 --- a/deluge/ui/web/js/deluge-ui.js +++ b/deluge/ui/web/js/deluge-ui.js @@ -25,6 +25,9 @@ Copyright: Deluge.Ui = { initialize: function() { this.errorCount = 0; + this.roar = new Roar({ + position: 'lowerRight' + }); Ext.state.Manager.setProvider(new Ext.state.CookieProvider()); this.MainPanel = new Ext.Panel({ id: 'mainPanel', @@ -52,6 +55,10 @@ Deluge.Ui = { Deluge.Client = new JSON.RPC('/json'); }, + notify: function(title, message) { + this.roar.alert(title, message); + }, + update: function() { var filters = Deluge.SideBar.getFilters(); Deluge.Client.web.update_ui(Deluge.Keys.Grid, filters, { @@ -128,6 +135,7 @@ Deluge.Ui = { onDisconnect: function() { this.stop(); + this.notify('Disconnected', 'Deluge has disconnected from the daemon'); }, /*