Author: sergeyhalipov
Date: 2007-11-12 13:19:34 -0500 (Mon, 12 Nov 2007)
New Revision: 3934
Added:
trunk/sandbox/samples/orderingListDemo/src/main/webapp/scripts/
trunk/sandbox/samples/orderingListDemo/src/main/webapp/scripts/effects.js
Modified:
trunk/sandbox/samples/orderingListDemo/src/main/java/org/richfaces/OrderingListDemoBean.java
trunk/sandbox/samples/orderingListDemo/src/main/webapp/pages/index.jsp
Log:
Ordering list demo. Event handlers with effects.
Modified:
trunk/sandbox/samples/orderingListDemo/src/main/java/org/richfaces/OrderingListDemoBean.java
===================================================================
---
trunk/sandbox/samples/orderingListDemo/src/main/java/org/richfaces/OrderingListDemoBean.java 2007-11-12
17:51:01 UTC (rev 3933)
+++
trunk/sandbox/samples/orderingListDemo/src/main/java/org/richfaces/OrderingListDemoBean.java 2007-11-12
18:19:34 UTC (rev 3934)
@@ -15,8 +15,8 @@
private String controlsVerticalAlign = "center";
private String headerLabel = "headerLabel";
- private String ontopclick;
- private String onbottomclick;
+ private String ontopclick = "new Effect.Highlight('form:ontopclickDiv',
{startcolor:'#FF0000', endcolor:'#FF0000'});";
+ private String onbottomclick = "new
Effect.Highlight('form:onbottomclickDiv', {startcolor:'#FF0000',
endcolor:'#FF0000'});";
private boolean orderControlsVisible = true;
private boolean fastOrderControlsVisible = true;
Modified: trunk/sandbox/samples/orderingListDemo/src/main/webapp/pages/index.jsp
===================================================================
--- trunk/sandbox/samples/orderingListDemo/src/main/webapp/pages/index.jsp 2007-11-12
17:51:01 UTC (rev 3933)
+++ trunk/sandbox/samples/orderingListDemo/src/main/webapp/pages/index.jsp 2007-11-12
18:19:34 UTC (rev 3934)
@@ -10,14 +10,22 @@
<style type="text/css">
.columnClass {
vertical-align: top;
+ }
+ .eventDiv {
+ background-color: green;
+ color: white;
+ width: 200px;
+ height: 50px;
+ font-weight: bold;
}
</style>
- <title></title>
+ <script type="text/javascript" src="scripts/effects.js" />
+ <title>Ordering List Demo.</title>
</head>
<body>
<f:view>
- <h:form>
+ <h:form id="form" >
<h:selectOneRadio binding="#{skinBean.component}" />
<h:commandLink action="#{skinBean.change}" value="set skin"
/>
<br />
@@ -34,8 +42,13 @@
controlsVerticalAlign="#{demoBean.controlsVerticalAlign}"
orderControlsVisible="#{demoBean.orderControlsVisible}"
fastOrderControlsVisible="#{demoBean.fastOrderControlsVisible}"
-
- >
+
+ ontopclick="#{demoBean.ontopclick}"
+ onbottomclick="#{demoBean.onbottomclick}"
+ onorderchanged="new Effect.Highlight('form:onorderchangedDiv',
{startcolor:'#FF0000', endcolor:'#FF0000'});"
+ ondownclick="new Effect.Highlight('form:ondownclickDiv',
{startcolor:'#FF0000', endcolor:'#FF0000'});"
+ onheaderclick="new Effect.Highlight('form:onheaderclickDiv',
{startcolor:'#FF0000', endcolor:'#FF0000'});"
+ onupclick="new Effect.Highlight('form:onupclickDiv',
{startcolor:'#FF0000', endcolor:'#FF0000'});" >
<h:column>
<f:facet name="header">
@@ -68,6 +81,27 @@
</ol:orderingList>
<h:panelGrid columns="2">
+ <h:panelGroup layout="block" styleClass="eventDiv"
id="ontopclickDiv" >
+ <h:outputText value="ontopclick" />
+ </h:panelGroup>
+ <h:panelGroup layout="block" styleClass="eventDiv"
id="onbottomclickDiv" >
+ <h:outputText value="onbottomclick" />
+ </h:panelGroup>
+ <h:panelGroup layout="block" styleClass="eventDiv"
id="onorderchangedDiv" >
+ <h:outputText value="onorderchanged" />
+ </h:panelGroup>
+ <h:panelGroup layout="block" styleClass="eventDiv"
id="ondownclickDiv" >
+ <h:outputText value="ondownclick" />
+ </h:panelGroup>
+ <h:panelGroup layout="block" styleClass="eventDiv"
id="onupclickDiv">
+ <h:outputText value="onupclick" />
+ </h:panelGroup>
+ <h:panelGroup layout="block" styleClass="eventDiv"
id="onheaderclickDiv" >
+ <h:outputText value="onheaderclick" />
+ </h:panelGroup>
+ </h:panelGrid>
+
+ <h:panelGrid columns="2">
<h:outputText value="Item Clicked: " />
<h:outputText value="#{demoBean.actionResult}"
id="actionResult" />
Added: trunk/sandbox/samples/orderingListDemo/src/main/webapp/scripts/effects.js
===================================================================
--- trunk/sandbox/samples/orderingListDemo/src/main/webapp/scripts/effects.js
(rev 0)
+++ trunk/sandbox/samples/orderingListDemo/src/main/webapp/scripts/effects.js 2007-11-12
18:19:34 UTC (rev 3934)
@@ -0,0 +1,263 @@
+var Effect = {
+ tagifyText: function(element) {
+ var tagifyStyle = 'position:relative';
+ if (/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1';
+ element = $(element);
+ $A(element.childNodes).each(function(child) {
+ if (child.nodeType == 3) {
+ child.nodeValue.toArray().each(function(character) {
+ element.insertBefore(
+ Builder.node('span', {style: tagifyStyle},
+ character == ' ' ? String.fromCharCode(160) :
character),
+ child);
+ });
+ Element.remove(child);
+ }
+ });
+ },
+ multiple: function(element, effect) {
+ var elements;
+ if (((typeof element == 'object') ||
+ (typeof element == 'function')) &&
+ (element.length))
+ elements = element;
+ else
+ elements = $(element).childNodes;
+
+ var options = Object.extend({
+ speed: 0.1,
+ delay: 0.0
+ }, arguments[2] || {});
+ var masterDelay = options.delay;
+
+ $A(elements).each(function(element, index) {
+ new effect(element, Object.extend(options, { delay: index * options.speed +
masterDelay }));
+ });
+ },
+ PAIRS: {
+ 'slide': ['SlideDown','SlideUp'],
+ 'blind': ['BlindDown','BlindUp'],
+ 'appear': ['Appear','Fade']
+ },
+ toggle: function(element, effect) {
+ element = $(element);
+ effect = (effect || 'appear').toLowerCase();
+ var options = Object.extend({
+ queue: { position:'end', scope:(element.id || 'global') }
+ }, arguments[2] || {});
+ Effect[Element.visible(element) ?
+ Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
+ }
+};
+
+Effect.Transitions = {}
+
+Effect.Transitions.linear = function(pos) {
+ return pos;
+}
+Effect.Transitions.sinoidal = function(pos) {
+ return (-Math.cos(pos * Math.PI) / 2) + 0.5;
+}
+Effect.Transitions.reverse = function(pos) {
+ return 1 - pos;
+}
+Effect.Transitions.flicker = function(pos) {
+ return ((-Math.cos(pos * Math.PI) / 4) + 0.75) + Math.random() / 4;
+}
+Effect.Transitions.wobble = function(pos) {
+ return (-Math.cos(pos * Math.PI * (9 * pos)) / 2) + 0.5;
+}
+Effect.Transitions.pulse = function(pos) {
+ return (Math.floor(pos * 10) % 2 == 0 ?
+ (pos * 10 - Math.floor(pos * 10)) : 1 - (pos * 10 - Math.floor(pos * 10)));
+}
+Effect.Transitions.none = function(pos) {
+ return 0;
+}
+Effect.Transitions.full = function(pos) {
+ return 1;
+}
+
+/* ------------- core effects ------------- */
+
+Effect.ScopedQueue = Class.create();
+Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
+ initialize: function() {
+ this.effects = [];
+ this.interval = null;
+ },
+ _each: function(iterator) {
+ this.effects._each(iterator);
+ },
+ add: function(effect) {
+ var timestamp = new Date().getTime();
+
+ var position = (typeof effect.options.queue == 'string') ?
+ effect.options.queue : effect.options.queue.position;
+
+ switch (position) {
+ case 'front':
+ // move unstarted effects after this effect
+ this.effects.findAll(function(e) {
+ return e.state == 'idle'
+ }).each(function(e) {
+ e.startOn += effect.finishOn;
+ e.finishOn += effect.finishOn;
+ });
+ break;
+ case 'end':
+ // start effect after last queued effect has finished
+ timestamp = this.effects.pluck('finishOn').max() || timestamp;
+ break;
+ }
+
+ effect.startOn += timestamp;
+ effect.finishOn += timestamp;
+ this.effects.push(effect);
+ if (!this.interval)
+ this.interval = setInterval(this.loop.bind(this), 40);
+ },
+ remove: function(effect) {
+ this.effects = this.effects.reject(function(e) {
+ return e == effect
+ });
+ if (this.effects.length == 0) {
+ clearInterval(this.interval);
+ this.interval = null;
+ }
+ },
+ loop: function() {
+ var timePos = new Date().getTime();
+ this.effects.invoke('loop', timePos);
+ }
+});
+
+Effect.Queues = {
+ instances: $H(),
+ get: function(queueName) {
+ if (typeof queueName != 'string') return queueName;
+
+ if (!this.instances[queueName])
+ this.instances[queueName] = new Effect.ScopedQueue();
+
+ return this.instances[queueName];
+ }
+}
+Effect.Queue = Effect.Queues.get('global');
+
+Effect.DefaultOptions = {
+ transition: Effect.Transitions.sinoidal,
+ duration: 1.0, // seconds
+ fps: 25.0, // max. 25fps due to Effect.Queue implementation
+ sync: false, // true for combining
+ from: 0.0,
+ to: 1.0,
+ delay: 0.0,
+ queue: 'parallel'
+}
+
+Effect.Base = function() {
+};
+Effect.Base.prototype = {
+ position: null,
+ start: function(options) {
+ this.options = Object.extend(Object.extend({}, Effect.DefaultOptions), options ||
{});
+ this.currentFrame = 0;
+ this.state = 'idle';
+ this.startOn = this.options.delay * 1000;
+ this.finishOn = this.startOn + (this.options.duration * 1000);
+ this.event('beforeStart');
+ if (!this.options.sync)
+ Effect.Queues.get(typeof this.options.queue == 'string' ?
+ 'global' : this.options.queue.scope).add(this);
+ },
+ loop: function(timePos) {
+ if (timePos >= this.startOn) {
+ if (timePos >= this.finishOn) {
+ this.render(1.0);
+ this.cancel();
+ this.event('beforeFinish');
+ if (this.finish) this.finish();
+ this.event('afterFinish');
+ return;
+ }
+ var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
+ var frame = Math.round(pos * this.options.fps * this.options.duration);
+ if (frame > this.currentFrame) {
+ this.render(pos);
+ this.currentFrame = frame;
+ }
+ }
+ },
+ render: function(pos) {
+ if (this.state == 'idle') {
+ this.state = 'running';
+ this.event('beforeSetup');
+ if (this.setup) this.setup();
+ this.event('afterSetup');
+ }
+ if (this.state == 'running') {
+ if (this.options.transition) pos = this.options.transition(pos);
+ pos *= (this.options.to - this.options.from);
+ pos += this.options.from;
+ this.position = pos;
+ this.event('beforeUpdate');
+ if (this.update) this.update(pos);
+ this.event('afterUpdate');
+ }
+ },
+ cancel: function() {
+ if (!this.options.sync)
+ Effect.Queues.get(typeof this.options.queue == 'string' ?
+ 'global' : this.options.queue.scope).remove(this);
+ this.state = 'finished';
+ },
+ event: function(eventName) {
+ if (this.options[eventName + 'Internal']) this.options[eventName +
'Internal'](this);
+ if (this.options[eventName]) this.options[eventName](this);
+ },
+ inspect: function() {
+ return '#<Effect:' + $H(this).inspect() + ',options:' +
$H(this.options).inspect() + '>';
+ }
+}
+
+Effect.Highlight = Class.create();
+Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
+ initialize: function(element) {
+ this.element = $(element);
+ var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] ||
{});
+ this.start(options);
+ },
+ setup: function() {
+ // Prevent executing on elements not in the layout flow
+ if (Element.getStyle(this.element, 'display') == 'none') {
+ this.cancel();
+ return;
+ }
+ // Disable background image during the effect
+ this.oldStyle = {
+ backgroundImage: Element.getStyle(this.element, 'background-image')
};
+ Element.setStyle(this.element, {backgroundImage: 'none'});
+ if (!this.options.endcolor)
+ this.options.endcolor = Element.getStyle(this.element,
'background-color').parseColor('#ffffff');
+ if (!this.options.restorecolor)
+ this.options.restorecolor = Element.getStyle(this.element,
'background-color');
+ // init color calculations
+ this._base = $R(0, 2).map(function(i) {
+ return parseInt(this.options.startcolor.slice(i * 2 + 1, i * 2 + 3), 16)
+ }.bind(this));
+ this._delta = $R(0, 2).map(function(i) {
+ return parseInt(this.options.endcolor.slice(i * 2 + 1, i * 2 + 3), 16) -
this._base[i]
+ }.bind(this));
+ },
+ update: function(position) {
+ Element.setStyle(this.element, {backgroundColor: $R(0, 2).inject('#',
function(m, v, i) {
+ return m + (Math.round(this._base[i] + (this._delta[i] *
position)).toColorPart());
+ }.bind(this)) });
+ },
+ finish: function() {
+ Element.setStyle(this.element, Object.extend(this.oldStyle, {
+ backgroundColor: this.options.restorecolor
+ }));
+ }
+});
\ No newline at end of file