function dump(o){ for(i in o){ print(i + " ===> " + o[i] ) } } Timer.prototype.addProp = function(prop, value){ this[prop] = value; } Image.prototype.addProp = function(prop, value){ this[prop] = value; } XMLHttpRequest.prototype.addProp = function(prop, value){ this[prop] = value; } Window.prototype.addProp = function(prop, value){ this[prop] = value; } HotKey.prototype.addProp = function(prop, value){ this[prop] = value; } ScrollBar.prototype.addProp = function(prop, value){ this[prop] = value; } utils = new Object(); function DockItem(){ this.clearDock = function(){ this.doc = XMLDOM.createDocument(); this.root = this.doc.createElement("dock-item"); this.doc.appendChild(this.root); } this.addObject = function(aObj,aType){ var XMLElem = this._DOMify(aObj,aType); this.root.appendChild(XMLElem); } this._DOMify = function(aObj,aType) { var element = this.doc.createElement(aType); for(i in aObj){ if(i != "addProp" && aObj[i] != null && aObj[i] != "" ) { element.setAttribute(i,aObj[i]); } } return element; } this.updateDock = function() { if(widget.setDockItem) widget.setDockItem( this.doc ); }; this.clearDock(); } function EntityResolver(){ this.resolve = function(aTextString){ var newString = aTextString; aTextString = aTextString.replace(/&/g, "&") aTextString = aTextString.replace(/'/g, "'") aTextString = aTextString.replace(/"/g, '"') aTextString = aTextString.replace(/>/g, '>') aTextString = aTextString.replace(/</g, '<') return aTextString } } //static animation utils function AnimatorUtils(){ this._timer = new Timer(); this._timer.addProp("owner", this); this._listeners = new Object(); this._name = "Animator"; this._listenersCount = 0; this._timer.name = "frameStepper"; this._timer.interval = 0.01; this._timer.ticking = false; this.isRunning = function(){ return this._timer.ticking; } this.easeInOut = function(minValue,maxValue,totalSteps,actualStep,powr) { //Generic Animation Step Value Generator By www.hesido.com var delta = maxValue - minValue; var stepp = minValue+(Math.pow(((1 / totalSteps) * actualStep), powr) * delta); return Math.ceil(stepp) } //public run this.run = function(){ this._timer.ticking = true; } //public this.sleep = function(){ this._timer.ticking = false; } this.removeListener = function(aListener){ for(iListener in this._listeners){ if(this._listeners[iListener] == aListener){ delete this._listeners[iListener]; this._listenersCount--; break; } } //once we have no more listeners, but the timer to spleep if(this.isRunning && this._listenersCount == 0){ this.sleep(); } } this.addEventListener = function(aObject,aMethod){ for(var iListener in this._listeners){ //if we already have it, then just return if((iListener) && iListener.target == aObject){ return; } } var listener = {target: aObject, callBackMethod: aMethod}; this._listenersCount++; //eval("this._listeners.object_"+this._listenersCount+" = listener"); this._listeners["object_"+this._listenersCount] = listener; //once we add an element, we can set it to run... if(!this.isRunning()){ this.run(); } return listener; } this.frameStepper = function(){ if(this.owner){ this.owner._dispatchEvent(); }else{ //(version 3 compatibility) utils.Animator._dispatchEvent.apply(utils.Animator); } } this._dispatchEvent = function(){ for(iListnerId in this._listeners){ var listener = this._listeners[iListnerId]; listener.callBackMethod.apply(listener.target); } } //creates descrete animation units this._newUnit = function(target,propIdentifier,from,to,duration){ var unit = new Object(); unit.target = target; unit.FINISHED = 1; unit.propIdentifier = propIdentifier; unit.initiallyFrom = from; unit.from = from; unit.to = to; unit.duration = duration; unit.changing = false; unit.totalSteps = (duration * 100); unit.stepValue = Math.abs(from - to)/unit.totalSteps; unit.nextStepValue = 0.0; unit.stepCounter = 0; unit.finished = false; unit._listeners = new Object(); unit._listenersCount=0; unit.change = function(){ this.stepCounter++; var currentValue = this.target[this.propIdentifier]; if(!this.changing && this.from != this.currentValue){ this.target[this.propIdentifier] = this.from; currentValue = this.from } this.changing = true; if(currentValue > this.to){ this.nextStepValue = utils.Animator.easeInOut(this.from,this.to,this.totalSteps,this.stepCounter,0.5);; var nextValue = Math.round(this.nextStepValue); if(nextValue < this.to) nextValue = to; this.target[this.propIdentifier] = nextValue; }else if(currentValue < this.to){ this.nextStepValue = utils.Animator.easeInOut(this.from,this.to,this.totalSteps,this.stepCounter,1.5); var nextValue = Math.round(this.nextStepValue); if(nextValue > this.to) nextValue = to; this.target[this.propIdentifier] = nextValue; } if (this.target[this.propIdentifier] == this.to){ this.finished = true; this._dispatchEvent(this.FINISHED); } } unit.hasFinished= function(){ return this.finished; } unit.removeListener = function(){ for(iListener in this._listeners){ if(listerner.target == aObject){ delete this._listeners[iListener]; this._listenersCount--; break; } } } unit.addEventListener = function(aObject,aMethod){ for(var iListener in this._listeners){ //if we already have it, then just return if((iListener) && iListener.target == aObject){ return; } } var listener = {target: aObject, callBackMethod: aMethod}; this._listenersCount++; this._listeners["object_"+this._listenersCount] = listener; return listener; } unit._dispatchEvent = function(aType){ var event = { source: this, type: aType, getSource: function(){return this.source}, getType: function(){return this.type} } for(iListnerId in this._listeners){ var listener = this._listeners[iListnerId]; listener.callBackMethod.apply(listener.target, [event]); } } return unit; } this.newAnim = function(target,propsToAnimate,duration,easing){ var anim = new Object(); anim.STEP_DEFAULT = 1; anim.name = "animationObject"; anim.animator = this; anim._target = target; anim._propsToAnimate = propsToAnimate; anim._elapsedTime = 0.0; anim.animating = false; anim.units = new Object(); anim.unitCounter = 0; anim.stop = function(){ this.animator.removeListener(this.listener); } anim.unitFinished = function(e){ var type = e.getType(); var src = e.getSource(); for(iProp in this.units){ if (this.units[iProp] == src){ this.units[iProp] = null; delete this.units[iProp]; } } } //decompose the units that we need to animate and create an animation unit for(iProp in anim._propsToAnimate){ var from, to, by; var animParameters = anim._propsToAnimate[iProp]; var propIdentifier = iProp; var initialValue = anim._target[iProp]; (animParameters.to) ? to = animParameters.to : to = null; if(to == null) throw "Exception: 'To' parameter is Required when animating " + iProp + " of object " + target; (animParameters.from) ? from = animParameters.from : from = initialValue; var unit = this._newUnit(anim._target,propIdentifier,from,to,duration); unit.addEventListener(anim, anim.unitFinished); anim.units["unit_" + anim.unitCounter++ + iProp] = unit; } anim.onStepFrame = function(e){ var unitCount = 0; for(i in this.units){ var unit = this.units[i]; unit.change(); if(!unit.hasFinished()){ unitCount++; } } if(unitCount == 0){ this.onComplete.dispatchEvent(); this.animator.removeListener(this.listener); } } anim.animate = function(){ anim.onStart.dispatchEvent(); this.listener = this.animator.addEventListener(this, this.onStepFrame); }; anim.onComplete = new EventDispatcher(anim,"onComplete"); anim.onStart = new EventDispatcher(anim,"onStart"); anim.onStop = new EventDispatcher(anim,"onStop"); return anim; } this._timer.onTimerFired = this.frameStepper; } utils.Animator = new AnimatorUtils(); utils.EntityResolver = new EntityResolver(); function trace(aObject){ print(aObject); } function AlertStore(){ this.name = "AlertStore"; this.ALERT_ADDED = 1; this.ALERT_REMOVED = 2; this.ALERTSTORE_UPDATED = 3; this.ALERT_ACTIVATED = 4; this._size = 0; this.expiredAlerts = new Object(); this.alerts = new Object(); this.activeAlert; //clones a new alert from a network sent alert base and adds functions this.newAlert = function(aAlert){ var alert = new Object(); alert.EXPIRED = 1; alert.ACTIVATED = 2; alert._expired = false; alert.alertStore = this; //clone the current properties of the object for(prop in aAlert){ alert[prop] = aAlert[prop]; } alert.getPosition = function(){ return this.alertStore.getPositionInStore(this); } alert.expire = function(){ this._expired = true; this.onExpire.dispatchEvent(this); this.expireTimer.ticking = false; delete this.expireTimer; } alert.hasExpired = function(){ return this._expired; } alert.scrollX = 0; //visual scrolling position; alert.scrollY = 0; alert.onScrollX = function(e){ this.scrollX = e.getData(); } alert.setScrollValue = function(aScrollBar){ aScrollBar.value = this.scrollX; } var expires = ((alert.expires.getTime()) - ((new Date()).getTime()) ); alert.onExpire = new EventDispatcher(alert, alert.EXPIRED); alert.expireTimer = new Timer(); alert.expireTimer.addProp("owner", alert); //alert.expireTimer.name = "alertTimer_" + alert.id; alert.expireTimer.onTimerFired = function(){this.owner.expire()}; if (expires < 1){ alert.expire(); }else{ alert.expireTimer.interval = expires / 1000; alert.expireTimer.ticking = true; } return alert; } function AlertStoreEvent(aEventType,aAlert,aSource){ var event = new Object(); event._source = aSource; event._alert = aAlert; event._eventType = aEventType; event.getAlert = function(){ return this._alert; }; event.getSource = function(){ return this._source; }; event.getEventType = function(){ return this._eventType; }; return event; } this.getPositionInStore = function(aAlert){ var count = 1; for(iAlert in this.alerts){ if(aAlert == this.alerts[iAlert]){ return count; } count++; } throw "The Alert is not in the Alert Store"; } this.getAlertById = function(aID){ if(this.alerts[aID]) return this.alerts[aID]; if(this.expiredAlerts[aID]) return this.expiredAlerts[aID]; return ; } this._retireAlert = function(aAlert){ this.remove(aAlert); this._addToExpiredAlerts(aAlert) this.update(); } this.retireCurrent = function(e){ var currentPos = this.activeAlert.getPosition(); var alertToRetire = this.activeAlert; if(currentPos == this.size()){ this.previous(); }else{ this.next(); } this._retireAlert(alertToRetire); } this._addToExpiredAlerts = function(aAlert){ this.expiredAlerts[aAlert.id] = aAlert; } this.add = function(aAlert){ if(aAlert.hasExpired() && !(this.getAlertById(aAlert.id))){ this._addToExpiredAlerts(aAlert); return; } this.alerts[aAlert.id] = aAlert; this._size++; //if(!this.activeAlert){ this._setActiveAlert(aAlert); //} aAlert.onExpire.subscribe(this, this.update); this.onAlertAdded.dispatchEvent(aAlert); } this._setActiveAlert = function(aAlert){ this.activeAlert = aAlert; this.onAlertActivated.dispatchEvent(aAlert); } this.remove = function(aAlert){ var alert = this.alerts[aAlert.id]; delete this.alerts[aAlert.id]; this._size--; this.onAlertRemoved.dispatchEvent(alert); } this.contains = function(aAlert){ if(this.alerts[aAlert.id]){return true;} return false; } this.size = function(){ return this._size; } this.next = function(){ var useNext = false; var index = 1; var nextAlert; for(iAlert in this.alerts){ nextAlert = iAlert; if(!useNext && index < this._size){ if(this.activeAlert == this.alerts[iAlert]){ useNext = true; } }else{ this._setActiveAlert(this.alerts[iAlert]); break; } index++; } } this.previous = function(){ var prev; var prevIndex; var index = 1; for(iAlert in this.alerts){ if(this.activeAlert == this.alerts[iAlert] && index > 1){ trace("found it") prev = this.alerts[prevIndex]; } prevIndex = iAlert; index++; } if(prev != null){ this._setActiveAlert(prev) } } this.deactivateCurrent = function(){ } this.update = function(){ this.onStoreUpdate.dispatchEvent(); } this.onAlertAdded = new EventDispatcher(this, this.ALERT_ADDED); this.onAlertRemoved = new EventDispatcher(this,this.ALERT_REMOVED); this.onStoreUpdate = new EventDispatcher(this, this.ALERTSTORE_UPDATED); this.onAlertActivated = new EventDispatcher(this, this.ALERT_ACTIVATED ); } function EventDispatcher(aOwner,aId){ this._listeners = new Object(); this._owner = aOwner; this._typeIdentifier = aId; this._listenersCount = 0; this.subscribe = function(aObject,aMethod){ for(var iListener in this._listeners){ if (this._listeners[iListener].target == aObject && this._listeners[iListener].callBackMethod == aMethod){ trace("already got it"); return; } } this._listenersCount++ var listener = {target: aObject, callBackMethod: aMethod}; this._listeners["object_"+this._listenersCount] = listener; return listener; } this.unsubscribe = function(aListener){ for(iListener in this._listeners){ if(this._listeners[iListener] == aListener){ delete this._listeners[iListener]; this._listenersCount--; break; } } } this.dispatchEvent = function(aData){ var event = { data: aData, source: this._owner, type: this._typeIdentifier, getSource: function(){return this.source}, getType: function(){return this._typeIdentifier}, getData: function(){return this.data}, } for(iListnerId in this._listeners){ var listener = this._listeners[iListnerId]; listener.callBackMethod.apply(listener.target, [event]); } } } function XHRCookieManager(aXHRObj){ this.cookieJar = new Object(); this.storeCookie = function(aXHRObject){ var cookies = aXHRObject.getResponseHeader("Set-Cookie"); if(cookies){ for(i in cookies){ this.cookieJar[i] = cookies[i]; } } } this.storeCookie(aXHRObj); this.updateCookie = function(aXHRObject){ var aCookieSet = aXHRObject.getResponseHeader("Set-Cookie"); if (!aCookieSet ) return; for(iCookie in aCookieSet){ if(! this.cookieJar[iCookie] || aCookieSet[iCookie] != this.cookieJar[iCookie] ){ this.cookieJar[iCookie] = aCookieSet[iCookie]; trace("updated cookie"); }else{ trace("matched cookies!") } } } this.replaceCookie = function(aXHRObject){ if(aXHRObject.getResponseHeader( "Set-Cookie" )){ this.cookieJar = new Array(); this.storeCookie(aXHRObject); return true; } return false; } this.setCookie = function(aXHRObject){ var cookies = this._serializeCookies(); aXHRObject.setRequestHeader("Cookie", cookies); } this._serializeCookies = function(){ var cookie = ""; for(iCookie in this.cookieJar){ var cookie = cookie + this.cookieJar[iCookie] + ";"; } return cookie; } } ({ baseURL: "http://alerts.ci.qut.edu.au", init: function(aWindowContext, aConnectionManager,aXHRObj){ this.connManager = aConnectionManager; this.name ="magic"; this.alertStore = new AlertStore(); this.currentAnimation; this.focused = false; this.closed = false; //take over the bootstrap so we can target events at ourselves (v3.1 compatability!) //store a reference to the original bootstrap in case we lose the connection this.connectionManager = bootStrap; bootStrap = this; //NETWORK cookie Management, so we don't create a new session on request this.cookieManager = new XHRCookieManager(aXHRObj); //OPACITY constants this.MIN_OPACITY = 127; this.MAX_OPACITY = 255; this.UI_TRANSITION_SPEED = 0.5; this.UI_MOVEMENT_SPEED = 0.5; this.UI_CLOSE_SPEED = 0.5; //Serverity colors this.SEVERITY_NORMAL = "Please note"; this.SEVERITY_SIGNIFICANT = "Attention"; this.SEVERITY_CRITICAL = "Very Impotant"; this.SEVERITY_COLOR_NORMAL = "r:120;g:140;b:20"; this.SEVERITY_COLOR_SIGNIFICANT = "r:0;g:110;b:255"; this.SEVERITY_COLOR_CRITICAL = "r:255;g:0;b:0"; //Window states this.WINDOW_CLOSED = 1; this.CONNECTION_INTERVALS = 60; //how often this should check the server for new messages (seconds) //set up dock for version 4; this.dock = new DockItem(); var img = new Image(); img.src = "Resources/images/dock.png"; img.colorize = this.SEVERITY_COLOR_SIGNIFICANT; //displayText = new Text(); //displayText.vOffset = 20; //displayText.hOffset = 20; //displayText.size = 20; //displayText.data = "falls"; //displayText.color = "#000000"; //this.dock.addObject(displayText, "text"); this.dockImage = img; this.dock.addObject(img, "image"); this.dock.updateDock(); this.updateDisplay= function(e){ trace("Update display: " + this.focused) var alert = e.getData(); if(!this.focused){ if(this.currentAnimation) this.currentAnimation.stop(); if(alert.severity == this.SEVERITY_CRITICAL){ var vOffset = Math.round((screen.availHeight * 0.25) - (this.window.height * 0.5)); var hOffset = Math.round((screen.availWidth /2) - (this.window.width * 0.5)); }else if(alert.severity == this.SEVERITY_SIGNIFICANT ){ var vOffset = screen.availHeight - this.window.height + 20; var hOffset = screen.availWidth - this.window.width; }else{ var vOffset = this.window.vOffset; var hOffset = this.window.hOffset; } var animParams = {opacity:{from: 1, to: this.MAX_OPACITY}, hOffset:{from:hOffset,to:hOffset}, vOffset:{from:vOffset,to:vOffset}}; this.currentAnimation = utils.Animator.newAnim(this.window,animParams,this.UI_TRANSITION_SPEED); this.currentAnimation.onStart.subscribe(this.window, function(){this.visible = true;}) if(alert.severity == this.SEVERITY_CRITICAL){ this.currentAnimation.onComplete.subscribe(this, function(){beep();}) } this.currentAnimation.animate(); } this.textBoxController.update(alert); } this.updateDock = function(e){ var alert = e.getData(); this.dockImage = new Image(); this.dockImage.src = "Resources/images/dock.png"; trace("color:" + this.getSeverityColor(alert.severity)); this.dockImage.colorize = this.getSeverityColor(alert.severity); this.dock.clearDock(); this.dock.addObject(this.dockImage, "image"); this.dock.updateDock(); } this.alertStore.onAlertActivated.subscribe(this, this.updateDisplay); this.alertStore.onAlertActivated.subscribe(this, this.updateDock); //create user interface this.window = aWindowContext; this.window.opacity = 0; this.window.visible = false; this.window.addProp("owner", this); this.setUpWindowFocusEvents(this.window); this.setUpPreferences(); this.setUpRefreshTimer(resender); //we use the global resender, which sucks!!! this.setUpBackground(this.window); this.setUpUIButtons(this.window); this.setUpUITextBoxes(this.window); this.hide(); this.updateDisplayColor = function(aColor){ this.bg.colorize = aColor; this.closeButton.colorize = aColor; } this.getSeverityColor = function(aSeverity){ switch(aSeverity){ case(this.SEVERITY_NORMAL):{ return this.SEVERITY_COLOR_NORMAL; break; } case(this.SEVERITY_SIGNIFICANT ):{ return this.SEVERITY_COLOR_SIGNIFICANT; break; } case(this.SEVERITY_CRITICAL):{ return this.SEVERITY_COLOR_CRITICAL; break; } default: { return ""; } } } this.upadateSeverityColor = function(aColor){ } this.window.onMultiClick = function(){ if ( system.event.clickCount == 3 ){ //reloadWidget(); } if ( system.event.clickCount == 2 ){ preferences.konfabulatorWindowLevel.value = "topmost"; } } this.resendRequest = function(){ this.sendRequest(this.processResponse) } this.sendRequest = function(aCallBackMethod){ var req = new XMLHttpRequest(); this.cookieManager.setCookie(req); req.setRequestHeader("HTTP_USER_AGENT", "AlerterWidget"); req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); req.setRequestHeader("Accept", "X-JSON"); req.setRequestHeader("User-Agent", "Alerter"); req.onreadystatechange = this.requestReceiver; req.owner = this; req.callBackMethod = aCallBackMethod; req.open("POST", this.baseURL+"/json.cfm", true); req.send("event=getAlertsList"); } this.processResponse = function(aXHR){ this.cookieManager.updateCookie(aXHR); try{ var jSon = eval(aXHR.getResponseHeader('X-JSON')); var modified = false; if(jSon.alerts){ for (var i = 0; i < jSon.alerts.length; i++){ var alertBase = jSon.alerts[i]; if(!this.alertStore.getAlertById(alertBase.id)){ var alert = this.alertStore.newAlert(alertBase); this.alertStore.add(alert); modified = true; } } } if(modified) this.alertStore.update() }catch(e){ print(e); } } this.requestReceiver = function(){ if ( this.status == 200 ){ try{ this.callBackMethod.apply(this.owner, [this]); }catch(e){ print(e) } } } }, onFocus: function(){ this.focused = true; this.closed = false; if(this.currentAnimation) this.currentAnimation.stop(); this.fadeIn(); }, onBlur: function(){ this.focused = false; if(!this.closed){ if(this.currentAnimation) this.currentAnimation.stop(); this.fadeOut(); } }, fadeIn: function(){ if( !this.closed ){ this.currentAnimation = utils.Animator.newAnim(this.window,{opacity:{to: this.MAX_OPACITY}},this.UI_TRANSITION_SPEED); this.currentAnimation.onStart.subscribe(this.window, function(){this.visible = true; this.closed = false;}); this.currentAnimation.animate(); } }, fadeOut: function(){ this.currentAnimation = utils.Animator.newAnim(this.window,{opacity:{to: this.MIN_OPACITY}},this.UI_TRANSITION_SPEED); this.currentAnimation.animate(); }, removeAnimation: function(e){ var anim = e.getSource(); if (this.currentAnimation == anim){ this.currentAnimation = null; } }, simulateClose: function(){ trace("pretending to close"); this.closed = true; if(this.currentAnimation) this.currentAnimation.stop(); this.currentAnimation = utils.Animator.newAnim(this.window,{opacity:{to: 10}},this.UI_CLOSE_SPEED); this.currentAnimation.onComplete.subscribe(this, this.hide); this.currentAnimation.onComplete.subscribe(this, this.hide); this.currentAnimation.animate(); this.focused = false; }, hide: function(){ trace("hide it") this.window.visible = false; }, show: function(){ this.window.visible = true; }, setUpWindowFocusEvents: function(aWindowContext){ aWindowContext.onGainFocus = function(){this.onFocus.dispatchEvent()};; aWindowContext.onLoseFocus = function(){this.onBlur.dispatchEvent()}; aWindowContext.onFocus = new EventDispatcher(aWindowContext, "focus"); aWindowContext.onBlur = new EventDispatcher(aWindowContext, "blur"); aWindowContext.onFocus.subscribe(this, this.onFocus); //subscribe the widget aWindowContext.onBlur.subscribe(this, this.onBlur); //subscribe the widget }, setUpUIButtons: function(aWindowContext){ //set up close button which hides the widget this.closeButton = new Image(aWindowContext); this.closeButton.addProp("owner", this); this.closeButton.addProp("mouseInside", false); this.closeButton.tooltip = "Close"; this.closeButton.src = this.baseURL + "/widgets/images/buttons/close_idle.png"; this.closeButton.hOffset = 197; this.closeButton.vOffset = 6; this.closeButton.onMouseEnter = function(){ this.hslAdjustment = "0,0,+20"; this.mouseInside = true; } this.closeButton.onMouseDown = function(){ this.hslAdjustment = "0,0,-20"; } this.closeButton.onMouseExit = function(){ this.hslAdjustment = "0,0,0"; this.mouseInside = false; } this.closeButton.onMouseUp = function(){ this.hslAdjustment = "0,0,0"; if(this.mouseInside){ this.owner.simulateClose.apply(this.owner); } } }, setUpUITextBoxes: function(aWindowContext){ this.textBoxController = new Object(); this.currentAlertListener = null; this.textBoxController.owner = this; this.textBoxController.mainTitle = new Text(aWindowContext); this.textBoxController.mainTitle.data = "QUT Network Alert"; this.textBoxController.mainTitle.color = "#000000"; this.textBoxController.mainTitle.vOffset = 22; this.textBoxController.mainTitle.hOffset = 55; this.textBoxController.mainTitle.height = 90; this.textBoxController.mainTitle.width = 189; this.textBoxController.mainTitle.size = 14; this.textBoxController.mainTitle.style = "bold"; this.textBoxController.textFrame = new Frame(aWindowContext); this.textBoxController.textFrame.vOffset = 30; this.textBoxController.textFrame.height = 100; this.textBoxController.signiText = new Text(); this.textBoxController.signiText.data = "...waiting for alerts..."; this.textBoxController.signiText.color = "#DDDDDD"; this.textBoxController.signiText.hOffset = this.window.width/2 -10; this.textBoxController.signiText.vOffset = 20; this.textBoxController.signiText.height = 93; this.textBoxController.signiText.width = this.window.width; this.textBoxController.signiText.size = 18; this.textBoxController.signiText.style = "bold"; this.textBoxController.signiText.alignment = "center" this.textBoxController.alertTime = new Text(aWindowContext); this.textBoxController.alertTime.data = (new Date()).toLocaleString(); this.textBoxController.alertTime.hOffset = 30; this.textBoxController.alertTime.vOffset = 37; this.textBoxController.alertTime.color = "#FFFFFF"; this.textBoxController.alertTime.size = 10; this.textBoxController.textFrame.onMouseWheel = function(){ this.onmousewheel.dispatchEvent(system.event.scrollDelta); }; this.textBoxController.textFrame.onmousewheel = new EventDispatcher(this.textBoxController.textFrame,"onmousewheel"); this.textBoxController.mainTextArea = new TextArea(); this.textBoxController.mainTextArea.data = ""; this.textBoxController.mainTextArea.color = "#FFFFFF"; this.textBoxController.mainTextArea.hOffset = 15; this.textBoxController.mainTextArea.vOffset = 45; this.textBoxController.mainTextArea.scrollbar = false this.textBoxController.mainTextArea.width = 185; this.textBoxController.mainTextArea.size = 12; this.textBoxController.mainTextArea.editable = false; this.textBoxController.textFrame.addSubview(this.textBoxController.signiText); this.textBoxController.textFrame.addSubview(this.textBoxController.alertTime); this.textBoxController.textFrame.addSubview(this.textBoxController.mainTextArea); this.textBoxController.textFrame.vScrollBar = new ScrollBar(aWindowContext); this.textBoxController.textFrame.vScrollBar.hOffset = 205; this.textBoxController.textFrame.vScrollBar.vOffset = 30; this.textBoxController.textFrame.vScrollBar.height = 100; this.textBoxController.textFrame.vScrollBar.addProp("onScroll", new EventDispatcher(this.textBoxController.textFrame.vScrollBar,"onScroll")); this.textBoxController.textFrame.vScrollBar.addProp("onValueChanged", function(){ this.onScroll.dispatchEvent(this.value); }); this.textBoxController.textFrame.vScrollBar.scrollTo = function(e){ this.value = this.value + (e.getData() * -2); } this.textBoxController.textFrame.onmousewheel.subscribe(this.textBoxController.textFrame.vScrollBar, this.textBoxController.textFrame.vScrollBar.scrollTo) this.alertStoreNavigator = new AlertStoreNavigator(aWindowContext, this.baseURL, this.alertStore, this); this.textBoxController.updateMainText = function(aString){ this.mainTextArea.data = aString; } this.textBoxController.update = function(aAlert){ if(this.currentAlertListener){ this.textFrame.vScrollBar.onScroll.unsubscribe(this.currentAlertListener); } this.currentAlertListener = this.textFrame.vScrollBar.onScroll.subscribe(aAlert, aAlert.onScrollX); this.signiText.data = aAlert.severity; this.updateMainText(utils.EntityResolver.resolve(aAlert.description)) this.owner.updateDisplayColor(this.owner.getSeverityColor(aAlert.severity)); aAlert.setScrollValue(this.textFrame.vScrollBar); this.alertTime.data = aAlert.created.toLocaleString(); } }, setUpPreferences: function(){ //set the widget if(preferences.konfabulatorWindowLevel.value != "topmost" ){ preferences.konfabulatorWindowLevel.value = "topmost"; reloadWidget(); } }, setUpBackground: function(aWindowContext){ this.bg = new Image(aWindowContext); this.bg.remoteAsync = true; this.bg.src = this.baseURL + "/widgets/images/background_clean.png"; this.bg.loadingSrc = this.baseURL + "/widgets/images/background_clean.png"; }, setUpRefreshTimer: function(aResender){ this.connectionTimer = new Timer(); this.connectionTimer.name = "heartBeat"; this.connectionTimer.onTimerFired = aResender; this.connectionTimer.interval = this.CONNECTION_INTERVALS; this.connectionTimer.ticking = true; } }) function AlertStoreNavigator(aWindowContext, aBaseURL, aAlertStore, aWidget){ var asn = new Object(); asn.frame = new Frame(aWindowContext); asn.currentAnim; asn.alertStore = aAlertStore; asn.frame.vOffset= 140; asn.frame.hOffset= 12; asn.bg = new Image(); asn.bg.src = aBaseURL + "/widgets/images/buttons/alertStoreNavigator_bg.png"; asn.bg.opacity = 30; asn.prevButton = new AlertStoreNavButton(aBaseURL + "/widgets/images/buttons/", "prev", aAlertStore); asn.nextButton = new AlertStoreNavButton(aBaseURL + "/widgets/images/buttons/", "next", aAlertStore); asn.deleteButton= new AlertStoreNavButton(aBaseURL + "/widgets/images/buttons/", "delete", aAlertStore); asn.frame.visible = false; asn.nextButton.moveTo({x: 45, y: 4}) asn.prevButton.moveTo({x: 5, y: 4}) asn.deleteButton.moveTo({x: 64, y: 2}) asn.prevButton.adjustImage("opacity", 70); asn.nextButton.adjustImage("opacity", 70); asn.nextButton.adjustImage("tooltip", "Next"); asn.prevButton.adjustImage("tooltip", "Previous"); asn.deleteButton.adjustImage("tooltip", "Delete"); var asWatcher = new AlertStoreChangeWatcher(aAlertStore, aWidget, aAlertStore); asn.frame.addSubview(asn.bg); asWatcher.frame(asn.frame); asn.nextButton.frame(asn.frame); asn.prevButton.frame(asn.frame); asn.deleteButton.frame(asn.frame); asn.onBlur = function(e){ this.hideUI(e); } asn.onFocus = function(e){ if(this.alertStore.size() > 1){ this.showUI(e); } } asn.hideUI = function(e){ if(this.currentAnim){ this.currentAnim.stop(); } this.currentAnim = utils.Animator.newAnim(this.frame,{opacity:{to: 11}},0.1); this.currentAnim.onComplete.subscribe(this, function(){this.frame.visible = false}); this.currentAnim.animate(); } asn.showUI = function(e){ if(this.currentAnim){ this.currentAnim.stop(); } this.currentAnim = utils.Animator.newAnim(this.frame,{opacity:{from: 1, to: 255}},0.1); this.currentAnim.onStart.subscribe(this, function(){this.frame.visible = true;}); this.currentAnim.animate(); } asn.updateStoreSize = function(e){ var storeSize = e.getSource().size() if(storeSize > 1){ //show the naviagtor; this.showUI(); }else{ this.hideUI(); } } aWindowContext.onFocus.subscribe(asn, asn.onFocus); aWindowContext.onBlur.subscribe(asn, asn.onBlur); asn.updateStoreSizeListener = aAlertStore.onStoreUpdate.subscribe(asn, asn.updateStoreSize); //set up handlers for prev and next buttons; asn.nextButton.onMouseUp.subscribe(asn.alertStore, asn.alertStore.next); asn.prevButton.onMouseUp.subscribe(asn.alertStore, asn.alertStore.previous); asn.deleteButton.onMouseUp.subscribe(asn.alertStore, asn.alertStore.retireCurrent); return asn; } function AlertStoreChangeWatcher(aAlertStore, aWidget, aAlertStore){ this.store = aAlertStore; this.name = "AlertStoreChangeWatcher"; this.storeSize = aAlertStore.size(); this.activeAlert; this.text = new Text(); this.text.color = "#FFFFFF"; this.text.height = 14; this.text.width = 26; this.text.size = 10; this.text.hOffset = 25; this.text.vOffset = 14; this.frame = function(aFrame){ aFrame.addSubview(this.text); } this.updateTextData = function(){ this.text.data = this.activeAlert.getPosition() + "/" + this.store.size(); } this.updateStoreSize = function(e){ if(e.getSource().size() > 0 && this.activeAlert){ this.updateTextData(); } } this.setActiveAlert = function(e){ this.activeAlert = e.getData(); this.updateTextData(); } //set up event dependencies with aAlertStore this.updateStoreSizeListener = aAlertStore.onStoreUpdate.subscribe(this, this.updateStoreSize); this.store.onAlertActivated.subscribe(this,this.setActiveAlert) } function AlertStoreNavButton(aBaseURL, aName, aAlertStore){ this._image = new Image(); this._image.addProp("owner", this); this._image_ovr_src = aBaseURL + aName+"_ovr.png"; this._image_idle_src = aBaseURL + aName+"_idle.png"; this._image.src = this._image_idle_src; this.name = aName; this.onMouseEnter = new EventDispatcher(this,"onMouseExit"); this.onMouseExit = new EventDispatcher(this,"onMouseExit"); this.onMouseDown = new EventDispatcher(this,"onMouseDown"); this.onMouseUp = new EventDispatcher(this,"onMouseUp"); this._image.onMouseEnter = function(e){this.owner.onMouseEnter.dispatchEvent(this);}; this._image.onMouseExit = function(e){this.owner.onMouseExit.dispatchEvent(this);}; this._image.onMouseDown = function(e){this.owner.onMouseEnter.dispatchEvent(this);}; this._image.onMouseUp = function(e){this.owner.onMouseUp.dispatchEvent(this);}; this.click = function(e){ trace("button " + this.name + " was clicked!"); } this.showOverState = function(e){ e.getData().src = this._image_ovr_src; } this.showIdleState = function(e){ e.getData().src = this._image_idle_src; } this.frame = function(aFrame){ aFrame.addSubview(this._image); } this.moveTo= function(aPoint){ this._image.hOffset = aPoint.x; this._image.vOffset = aPoint.y; } this.adjustImage = function(aProp, aValue){ this._image[aProp] = aValue; } this.onMouseEnter.subscribe(this, this.showOverState); this.onMouseExit.subscribe(this, this.showIdleState); this.onMouseUp.subscribe(this, this.click); this.updateStoreSize = function(e){ } //set up alert store dependancy this.updateStoreSizeListener = aAlertStore.onStoreUpdate.subscribe(this, this.updateStoreSize); }