diff options
| author | Andreas Brachold <vdr07@deltab.de> | 2009-10-05 18:00:06 +0000 |
|---|---|---|
| committer | Andreas Brachold <vdr07@deltab.de> | 2009-10-05 18:00:06 +0000 |
| commit | 6f21b40befb77303cc04415b675256b0ba098be3 (patch) | |
| tree | 5b50a6017c6c086f2a9855076326ef1e3fabbd1e | |
| parent | 728c070809470ec928cd23470c304463cf75e2e9 (diff) | |
| download | xxv-6f21b40befb77303cc04415b675256b0ba098be3.tar.gz xxv-6f21b40befb77303cc04415b675256b0ba098be3.tar.bz2 | |
* jason: refactoring view recordings
| -rw-r--r-- | skins/jason/common.js | 65 | ||||
| -rw-r--r-- | skins/jason/files.lst | 1 | ||||
| -rw-r--r-- | skins/jason/fixes.js | 205 | ||||
| -rw-r--r-- | skins/jason/index.tmpl | 1 | ||||
| -rw-r--r-- | skins/jason/jason.css | 3 | ||||
| -rw-r--r-- | skins/jason/locale/lang-de.js | 1 | ||||
| -rw-r--r-- | skins/jason/locale/lang-en.js | 1 | ||||
| -rwxr-xr-x | skins/jason/locale/lang-it.js | 1 | ||||
| -rw-r--r-- | skins/jason/pic/slide-left.png | bin | 0 -> 548 bytes | |||
| -rw-r--r-- | skins/jason/pic/slide-right.png | bin | 0 -> 603 bytes | |||
| -rw-r--r-- | skins/jason/recordings.js | 580 | ||||
| -rw-r--r-- | skins/jason/timers.js | 13 | ||||
| -rw-r--r-- | skins/jason/ux/Carousel.css | 67 | ||||
| -rw-r--r-- | skins/jason/ux/Carousel.js | 457 |
14 files changed, 1046 insertions, 349 deletions
diff --git a/skins/jason/common.js b/skins/jason/common.js index 416f131..355c71a 100644 --- a/skins/jason/common.js +++ b/skins/jason/common.js @@ -113,5 +113,70 @@ Ext.xxv.Panel = Ext.extend(Ext.Panel, { }); +/******************************************************************************/ +Ext.xxv.TagClouds = function(config){
+ Ext.xxv.TagClouds.superclass.constructor.call(this, config);
+ Ext.apply(this, config);
+};
+
+Ext.extend(Ext.xxv.TagClouds, Ext.Component, {
+
+ initComponent : function(){
+ Ext.xxv.TagClouds.superclass.initComponent.call(this);
+
+ this.addEvents({'selectKeyword' : true});
+ },
+ + setvalue : function(keywords){ + + this.keywords = keywords; + + if(this.cloudlist) { + this.cloudlist.remove(); + delete this.cloudlist; + this.cloudlist = null; + } + }, +
+ render : function(ct, position){
+ + if(!this.cloudlist && this.keywords && this.keywords.length) { + this.cloudlist = ct.createChild({tag: "ol", cls: "x-cloud-list"}); + for(var i = 0, len = this.keywords.length; i < len; i++){
+ var child = this.cloudlist.createChild({
+ tag: "li",
+ cls: "x-cloud-item "+this.getWeight(this.keywords[i][1]),
+ html: '<a href="#">'+this.keywords[i][0]+'</a>'
+ });
+
+ child.on('click', this.onSelectKeyWord, this);
+ } + } + } + /**************************************************************************/ + ,getWeight : function(weight){
+ var nmax = 100; + var nmin = 0; + + var styles = new Array('smallest','smaller','small','medium','large','larger','largest'); + var value = weight / (nmax - nmin) * 6;
+ if(value >= 6.0)
+ return styles[6];
+ if(value <= 0.0)
+ return styles[0];
+
+ return styles[Math.round(value)];
+ } + /**************************************************************************/ + ,onSelectKeyWord : function(e, t){
+
+ var tag = t.firstChild.data;
+ this.fireEvent('selectKeyword', tag);
+
+ // Prevent the link href from being followed
+ Ext.EventObject.stopEvent(e);
+ } +}); +Ext.reg('TagClouds', Ext.xxv.TagClouds); diff --git a/skins/jason/files.lst b/skins/jason/files.lst index 73847c8..79524f9 100644 --- a/skins/jason/files.lst +++ b/skins/jason/files.lst @@ -2,6 +2,7 @@ FILES = \ extjs/adapter/ext/ext-base.js \ extjs/ext-all.js \ fixes.js \ +ux/Carousel.js \ ux/DDView.js \ ux/Multiselect.js \ ux/TabCloseMenu.js \ diff --git a/skins/jason/fixes.js b/skins/jason/fixes.js index da74e25..5fb77b8 100644 --- a/skins/jason/fixes.js +++ b/skins/jason/fixes.js @@ -71,3 +71,208 @@ Ext.override(Ext.form.TimeField, { return v; } }); + + +/* http://www.extjs.com/forum/showthread.php?t=78223 */ +Ext.override(Ext.layout.VBoxLayout, { + onLayout : function(ct, target){ + Ext.layout.VBoxLayout.superclass.onLayout.call(this, ct, target); + var cs = this.getItems(ct), cm, ch, margin, + size = this.getTargetSize(target), + w = size.width - target.getPadding('lr'), + h = size.height - target.getPadding('tb') - this.scrollOffset, + l = this.padding.left, t = this.padding.top, + isStart = this.pack == 'start', + isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1, + stretchWidth = w - (this.padding.left + this.padding.right), + extraHeight = 0, + maxWidth = 0, + totalFlex = 0, + flexHeight = 0, + usedHeight = 0; + Ext.each(cs, function(c){ + cm = c.margins; + totalFlex += c.flex || 0; + ch = c.getHeight(); + margin = cm.top + cm.bottom; + extraHeight += ch + margin; + flexHeight += margin + (c.flex ? 0 : ch); + maxWidth = Math.max(maxWidth, c.getWidth() + cm.left + cm.right); + }); + extraHeight = h - extraHeight - this.padding.top - this.padding.bottom; + var th = flexHeight + this.padding.top + this.padding.bottom; + if(h < th){ + h = th; + w -= this.scrollOffset; + stretchWidth -= this.scrollOffset; + } + var innerCtWidth = maxWidth + this.padding.left + this.padding.right; + switch(this.align){ + case 'stretch': + this.innerCt.setSize(w, h); + break; + case 'stretchmax': + case 'left': + this.innerCt.setSize(innerCtWidth, h); + break; + case 'center': + this.innerCt.setSize(w = Math.max(w, innerCtWidth), h); + break; + } + var availHeight = Math.max(0, h - this.padding.top - this.padding.bottom - flexHeight), + leftOver = availHeight, + heights = [], + restore = [], + idx = 0, + availableWidth = Math.max(0, w - this.padding.left - this.padding.right); + Ext.each(cs, function(c){ + if(isStart && c.flex){ + ch = Math.floor(availHeight * (c.flex / totalFlex)); + leftOver -= ch; + heights.push(ch); + } + }); + if(this.pack == 'center'){ + t += extraHeight ? extraHeight / 2 : 0; + }else if(this.pack == 'end'){ + t += extraHeight; + } + Ext.each(cs, function(c){ + cm = c.margins; + t += cm.top; + c.setPosition(l + cm.left, t); + if(isStart && c.flex){ + ch = Math.max(0, heights[idx++] + (leftOver-- > 0 ? 1 : 0)); + if(isRestore){ + restore.push(c.getWidth()); + } + c.setSize(availableWidth, ch); + }else{ + ch = c.getHeight(); + } + t += ch + cm.bottom; + }); + idx = 0; + Ext.each(cs, function(c){ + cm = c.margins; + if(this.align == 'stretch'){ + c.setWidth((stretchWidth - (cm.left + cm.right)).constrain( + c.minWidth || 0, c.maxWidth || 1000000)); + }else if(this.align == 'stretchmax'){ + c.setWidth((maxWidth - (cm.left + cm.right)).constrain( + c.minWidth || 0, c.maxWidth || 1000000)); + }else{ + if(this.align == 'center'){ + var diff = availableWidth - (c.getWidth() + cm.left + cm.right); + if(diff > 0){ + c.setPosition(l + cm.left + (diff/2), c.y); + } + } + if(isStart && c.flex){ + c.setWidth(restore[idx++]); + } + } + }, this); + } +}); +Ext.override(Ext.layout.HBoxLayout, { + onLayout : function(ct, target){ + Ext.layout.HBoxLayout.superclass.onLayout.call(this, ct, target); + var cs = this.getItems(ct), cm, cw, margin, + size = this.getTargetSize(target), + w = size.width - target.getPadding('lr') - this.scrollOffset, + h = size.height - target.getPadding('tb'), + l = this.padding.left, t = this.padding.top, + isStart = this.pack == 'start', + isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1, + stretchHeight = h - (this.padding.top + this.padding.bottom), + extraWidth = 0, + maxHeight = 0, + totalFlex = 0, + flexWidth = 0, + usedWidth = 0; + Ext.each(cs, function(c){ + cm = c.margins; + totalFlex += c.flex || 0; + cw = c.getWidth(); + margin = cm.left + cm.right; + extraWidth += cw + margin; + flexWidth += margin + (c.flex ? 0 : cw); + maxHeight = Math.max(maxHeight, c.getHeight() + cm.top + cm.bottom); + }); + extraWidth = w - extraWidth - this.padding.left - this.padding.right; + var tw = flexWidth + this.padding.left + this.padding.right; + if(w < tw){ + w = tw; + h -= this.scrollOffset; + stretchHeight -= this.scrollOffset; + } + var innerCtHeight = maxHeight + this.padding.top + this.padding.bottom; + switch(this.align){ + case 'stretch': + this.innerCt.setSize(w, h); + break; + case 'stretchmax': + case 'top': + this.innerCt.setSize(w, innerCtHeight); + break; + case 'middle': + this.innerCt.setSize(w, h = Math.max(h, innerCtHeight)); + break; + } + var availWidth = Math.max(0, w - this.padding.left - this.padding.right - flexWidth), + leftOver = availWidth, + widths = [], + restore = [], + idx = 0, + availableHeight = Math.max(0, h - this.padding.top - this.padding.bottom); + Ext.each(cs, function(c){ + if(isStart && c.flex){ + cw = Math.floor(availWidth * (c.flex / totalFlex)); + leftOver -= cw; + widths.push(cw); + } + }); + if(this.pack == 'center'){ + l += extraWidth ? extraWidth / 2 : 0; + }else if(this.pack == 'end'){ + l += extraWidth; + } + Ext.each(cs, function(c){ + cm = c.margins; + l += cm.left; + c.setPosition(l, t + cm.top); + if(isStart && c.flex){ + cw = Math.max(0, widths[idx++] + (leftOver-- > 0 ? 1 : 0)); + if(isRestore){ + restore.push(c.getHeight()); + } + c.setSize(cw, availableHeight); + }else{ + cw = c.getWidth(); + } + l += cw + cm.right; + }); + idx = 0; + Ext.each(cs, function(c){ + var cm = c.margins; + if(this.align == 'stretch'){ + c.setHeight((stretchHeight - (cm.top + cm.bottom)).constrain( + c.minHeight || 0, c.maxHeight || 1000000)); + }else if(this.align == 'stretchmax'){ + c.setHeight((maxHeight - (cm.top + cm.bottom)).constrain( + c.minHeight || 0, c.maxHeight || 1000000)); + }else{ + if(this.align == 'middle'){ + var diff = availableHeight - (c.getHeight() + cm.top + cm.bottom); + if(diff > 0){ + c.setPosition(c.x, t + cm.top + (diff/2)); + } + } + if(isStart && c.flex){ + c.setHeight(restore[idx++]); + } + } + }, this); + } +}); diff --git a/skins/jason/index.tmpl b/skins/jason/index.tmpl index e2fa6fe..f073515 100644 --- a/skins/jason/index.tmpl +++ b/skins/jason/index.tmpl @@ -10,6 +10,7 @@ <link rel="stylesheet" type="text/css" href="extjs/resources/css/xtheme-default.css" id="theme" /> <link rel="stylesheet" type="text/css" href="jason.css" /> <link rel="stylesheet" type="text/css" href="ux/multiselect.css" /> + <link rel="stylesheet" type="text/css" href="ux/Carousel.css" /> <script language="javascript" type="text/javascript"> var configuration = { periods : [ "<?% getModule('EPG').periods.replace(',','","') %?>" ] diff --git a/skins/jason/jason.css b/skins/jason/jason.css index 1ecbfc0..9571803 100644 --- a/skins/jason/jason.css +++ b/skins/jason/jason.css @@ -228,7 +228,8 @@ padding:5px; border-bottom:1px solid #dadadb; }
.preview .x-panel-body div.preview-body {
-padding:10px;
+padding:10px; +overflow: auto;
}
.reading-menu .x-menu-item-checked {
diff --git a/skins/jason/locale/lang-de.js b/skins/jason/locale/lang-de.js index 46e0cf4..d1e5b4f 100644 --- a/skins/jason/locale/lang-de.js +++ b/skins/jason/locale/lang-de.js @@ -182,6 +182,7 @@ Ext.xxv.timerGrid.prototype.szColDay = "Tag"; Ext.xxv.timerGrid.prototype.szColChannel = "Kanal";
Ext.xxv.timerGrid.prototype.szColStart = "Beginn";
Ext.xxv.timerGrid.prototype.szColStop = "Ende"; +Ext.xxv.timerGrid.prototype.szColDuration = "Dauer"; Ext.xxv.timerGrid.prototype.szSelChEmptyText = "Kanal wählen...";
Ext.xxv.timerGrid.prototype.szColDayFormat = "l, d.m.Y"; Ext.xxv.timerGrid.prototype.szLoadException = "Konnte keine Daten über Timer holen!\r\n{0}"; diff --git a/skins/jason/locale/lang-en.js b/skins/jason/locale/lang-en.js index f39fed8..6c63039 100644 --- a/skins/jason/locale/lang-en.js +++ b/skins/jason/locale/lang-en.js @@ -182,6 +182,7 @@ Ext.xxv.timerGrid.prototype.szColDay = "Day"; Ext.xxv.timerGrid.prototype.szColChannel = "Channel"; Ext.xxv.timerGrid.prototype.szColStart = "Start";
Ext.xxv.timerGrid.prototype.szColStop = "Stop"; +Ext.xxv.timerGrid.prototype.szColDuration = "Duration"; Ext.xxv.timerGrid.prototype.szHost = "Host"; Ext.xxv.timerGrid.prototype.szColDayFormat = "l, m/d/Y"; Ext.xxv.timerGrid.prototype.szSelChEmptyText = "Select a channel...";
diff --git a/skins/jason/locale/lang-it.js b/skins/jason/locale/lang-it.js index 5199ef5..6dc1615 100755 --- a/skins/jason/locale/lang-it.js +++ b/skins/jason/locale/lang-it.js @@ -182,6 +182,7 @@ Ext.xxv.timerGrid.prototype.szColDay = "Giorno"; Ext.xxv.timerGrid.prototype.szColChannel = "Canale"; Ext.xxv.timerGrid.prototype.szColStart = "Inizio";
Ext.xxv.timerGrid.prototype.szColStop = "Fine"; +Ext.xxv.timerGrid.prototype.szColDuration = "Durata"; Ext.xxv.timerGrid.prototype.szHost = "Nome sistema"; Ext.xxv.timerGrid.prototype.szColDayFormat = "l, m/d/Y"; Ext.xxv.timerGrid.prototype.szSelChEmptyText = "Seleziona un canale...";
diff --git a/skins/jason/pic/slide-left.png b/skins/jason/pic/slide-left.png Binary files differnew file mode 100644 index 0000000..27ab7f2 --- /dev/null +++ b/skins/jason/pic/slide-left.png diff --git a/skins/jason/pic/slide-right.png b/skins/jason/pic/slide-right.png Binary files differnew file mode 100644 index 0000000..3da357c --- /dev/null +++ b/skins/jason/pic/slide-right.png diff --git a/skins/jason/recordings.js b/skins/jason/recordings.js index cc12d72..84aea21 100644 --- a/skins/jason/recordings.js +++ b/skins/jason/recordings.js @@ -33,35 +33,101 @@ HMSToSeconds = function(s) { } /******************************************************************************/ -Ext.xxv.slide = function(config){
- Ext.xxv.slide.superclass.constructor.call(this, config);
+Ext.xxv.slider = function(config){
+ Ext.xxv.slider.superclass.constructor.call(this, config);
Ext.apply(this, config);
- - this.addEvents({
- 'selectKeyword' : true
- });
};
-Ext.extend(Ext.xxv.slide, Ext.Component, {
+Ext.extend(Ext.xxv.slider, Ext.Component, {
+ + slider: null +
+ ,initComponent : function(){
+ Ext.xxv.slider.superclass.initComponent.call(this);
+ this.addEvents({'MoveSlider' : true});
+ },
+ + setvalue : function(marks, duration){ + this.marks = marks; + this.duration = duration; + this.modified = 1; + }, +
+ render : function(ct, position){ + if(!this.modified) + return; + this.modified = 0;
+ if(this.slider) { + //this.slider.remove(); + ct.dom.innerHTML = ''; + delete this.slider; + this.slider = null; + + //this.slider.sliders.clear(); + //this.slider.maxValue = this.duration; + } //else + { + this.slider = new Ext.ux.SlideZone(ct.id, { + type: 'horizontal' + ,size: ct.getWidth() + ,sliderWidth: 16 + ,sliderHeight: 24 + ,minValue: 0 + ,maxValue: this.duration + //,sliderSnap: 1 + ,allowSliderCrossing: true + }); + this.ts = new Ext.ux.ThumbSlider({ + value: 0 + ,name: 'cutpoint_thumb' + ,cls: 'x-slide-zone-bottom' + ,allowMove: true + }); + this.ts.on('drag', + function() { + var v = parseInt(this.ts.value * 1000); + this.fireEvent('MoveSlider', this, new Date((minTime().getTime())+v), null, null); + },this); + } + + if(this.marks && this.marks.length) { + var cutpoint = this.marks.split(","); + for(var i = 0, len = cutpoint.length; i < len; i += 2){ + var first = HMSToSeconds(cutpoint[i]); + var second; + if(i+1 < cutpoint.length) { + second = HMSToSeconds(cutpoint[i+1]); + } else { + second = this.duration; + } + var rs = new Ext.ux.RangeSlider({ + value: [first,second] + ,name: 'cutpoint_'+i + ,cls: 'x-slide-zone-top' + ,allowMove: false + }); + this.slider.add(rs); + } + } + this.slider.add(this.ts); + } +});
- baseCls : 'x-slide',
+Ext.reg('MarksSlider', Ext.xxv.slider); + +/******************************************************************************/ +Ext.xxv.RecHeader = function(config){
+ Ext.xxv.RecHeader.superclass.constructor.call(this, config);
Ext.apply(this, config);
+};
- setSize : Ext.emptyFn,
- setWidth : Ext.emptyFn,
- setHeight : Ext.emptyFn,
- setPosition : Ext.emptyFn,
- setPagePosition : Ext.emptyFn,
- slider: null, +Ext.extend(Ext.xxv.RecHeader, Ext.Component, {
initComponent : function(){
- Ext.xxv.slide.superclass.initComponent.call(this);
+ Ext.xxv.RecHeader.superclass.initComponent.call(this);
- this.addEvents({'selected' : true});
- if (typeof(this.imageGap)=='undefined') { this.imageGap = 10 }
this.tpl = new Ext.Template( - '<span id="preview-recordings-frame">', - '<div class="preview-header">', + '<div class="preview-header">', '<h3 class="preview-title">{title}</h3>', '<div class="preview-channel">', '<tpl if="channel != 0">', @@ -73,38 +139,22 @@ Ext.extend(Ext.xxv.slide, Ext.Component, { '</tpl>', '</div>', '<h4 class="preview-shorttitle">{subtitle} </h4>', - '<div class="preview-date">{day:date} {start} - {stop}</div>', - '</div>',
- '<div class="{cls}-wrap">',
- '<div id="images-inner" class="{cls}-inner">',
- '<div class="{cls}-images-wrap">',
- '<div class="{cls}-images"></div>',
- '</div>',
- '</div>',
- '</div>', - '<div id="slider"><div id="slider-inner"></div></div>', - '<div class="preview-body">{content}</div>', - '</span>' + '<div class="preview-date">{day:date} {start} - {stop}</div>' + ,'</div>' ); this.tpl.compile();
- - this.tplimg = new Ext.Template('{day:date} - {start} ({period})'); - this.tplimg.compile();
- },
- setvalue : function(data, first){ + setvalue : function(data){ this.param = { - data: data - ,title: data.fulltitle + title: data.fulltitle ,subtitle: '' ,channel: data.channel ,day: data.day ,duration: data.duration ,start: data.day.dateFormat('H:i') ,stop: new Date(data.day.getTime() + (data.duration * 1000)).dateFormat('H:i') - ,content: data.description.replace(/\r\n/g, '<br />') ,cutlength: data.cutlength == data.duration ? null : SecondsToHMS(data.cutlength) ,period: SecondsToHMS(data.duration) }; @@ -117,244 +167,16 @@ Ext.extend(Ext.xxv.slide, Ext.Component, { this.param.subtitle = title.pop(); this.param.title = title.join("~"); } - - if(first === true) { - var images = []; - if(!data.preview || data.preview == '') { - /*var day = new Date(data.day.getTime()); - images.push( - { - src: (data.type == 'RADIO') ? 'pic/radio.png' : 'pic/movie.png' - ,day: day - ,start: day.dateFormat('H:i') - ,frame: 0 - ,period: SecondsToHMS(0) - } - );*/ - } else { - var frames = data.preview.split(","); - Ext.each(frames, function(frame){ - var url = "?cmd=ri&data="+data.id+"_"+frame; - var day = new Date(data.day.getTime() + (frame * 40)); - images.push( - { - src: url - ,day: day - ,start: day.dateFormat('H:i') - ,frame: frame - ,period: SecondsToHMS((frame * 40)/1000) - } - ); - },this); - } - this.images = images; - } }, -
- render : function(ct, position){
- - if(!this.param) return; - /** add preview images ************************************************/ - - var inner= Ext.get("images-inner"); - if(!inner) { - this.param.cls = this.baseCls; - if(position){
- this.el = this.tpl.insertBefore(position, this.param, true);
- }else{
- this.el = this.tpl.append(ct, this.param, true);
- }
- if(this.id){
- this.el.dom.id = this.id;
- }
-
- inner= Ext.get("images-inner"); - if(this.slider) { - delete this.slider; - this.slider = null; - } - if(this.cloudlist) { - delete this.cloudlist; - this.cloudlist = null; - } + render : function(ct, position){ + if(this.param) { + this.tpl.overwrite(ct, this.param); }
- var imagesWrap = Ext.get(inner.dom.firstChild); - this.divImages = Ext.get(imagesWrap.dom.firstChild);
- - var size = inner.getSize(); - this.width = size.width; - this.height = size.height; -
- inner.setStyle({
- height:(this.imageHeight + (2*this.wrapMarginY)) + 'px',
- width:(this.width-this.wrapMarginX)+'px'
- });
-
- var totalImageWidth=this.imageWidth+this.imageGap;
- var usableWidth=this.width-(this.wrapMarginX*2);
- var maxPicsOnce=Math.floor(usableWidth/totalImageWidth);
- var usedWidth=maxPicsOnce*totalImageWidth-this.imageGap;
- var offsetLeft=Math.floor((usableWidth-usedWidth)/2);
- this.pageSize=usedWidth+this.imageGap;
- this.maxPages=Math.round(this.images.length/maxPicsOnce+.04999);
- this.curPage=0;
-
- if (!Ext.isIE){
- offsetLeft+=this.wrapMarginX;
- }
-
- imagesWrap.setStyle({
- position: 'absolute',
- clip:'rect(0,'+(usedWidth*1)+','+(this.imageHeight)+',0)',
- 'margin-top':this.wrapMarginY+'px',
- width:this.width+'px',
- height:this.imageHeight+'px',
- 'margin-left':offsetLeft+'px'
- });
-
- /*this.divImages.setStyle({
- position: 'absolute'
- });*/
-
- Ext.each(this.images, function(image){
-
- if (typeof(image)=='string'){
- image={src:image}
- }
- var qtip = this.tplimg.applyTemplate(image);
-
- thisImage = this.divImages.createChild({tag:"img", src:image.src, - 'ext:qtip':qtip, - style:{
- 'margin-right': this.imageGap+'px',
- width: this.imageWidth+'px'
- // height: this.imageHeight+'px'
- } - });
-
- thisImage.on("click", function(e, ele){
- if (!image.onSelected || !(image.onSelected.call(this, image, e, ele )===false)){
- this.fireEvent('selected', this, new Date(minTime().getTime()+(image.frame * 40)), e, ele); - - var slider = this.slider.getSlider('cutpoint_thumb'); - slider.value = image.frame/25; - this.slider.initSliderPosition(slider); - }
- },this);
- },this);
- - /** add cutmark slider **************************************************/ - if(this.slider) { - this.slider.sliders.clear(); - } else { - - this.slider = new Ext.ux.SlideZone('slider-inner', { - type: 'horizontal', - size: usableWidth-32, - sliderWidth: 16, - sliderHeight: 24, - maxValue: this.param.data.duration, - minValue: 0, - //sliderSnap: 1, - allowSliderCrossing: true - }); - this.ts = new Ext.ux.ThumbSlider({ - value: 0 - ,name: 'cutpoint_thumb' - ,cls: 'x-slide-zone-bottom' - ,allowMove: true - }); - this.ts.on('drag', - function() { - var v = parseInt(this.ts.value * 1000); - this.fireEvent('selected', this, new Date((minTime().getTime())+v), null, null); - },this); - } - - if(this.param.data.marks && this.param.data.marks.length) { - var cutpoint = this.param.data.marks.split(","); - for(var i = 0, len = cutpoint.length; i < len; i += 2){ - var first = HMSToSeconds(cutpoint[i]); - var second; - if(i+1 < cutpoint.length) { - second = HMSToSeconds(cutpoint[i+1]); - } else { - second = this.param.data.duration; - } - var rs = new Ext.ux.RangeSlider({ - value: [first,second] - ,name: 'cutpoint_'+i - ,cls: 'x-slide-zone-top' - ,allowMove: false - }); - this.slider.add(rs); - } - } - this.slider.add(this.ts); - /** add keywords tagcloud ***********************************************/ - if(!this.cloudlist && this.param.data.keywords && this.param.data.keywords.length) { - var cont = Ext.get(ct.dom.lastChild); - this.cloudlist = cont.createChild({tag: "ol", cls: "x-cloud-list"}); - for(var i = 0, len = this.param.data.keywords.length; i < len; i++){
- var child = this.cloudlist.createChild({
- tag: "li",
- cls: "x-cloud-item "+this.getWeight(this.param.data.keywords[i][1]),
- html: '<a href="#">'+this.param.data.keywords[i][0]+'</a>'
- });
-
- child.on('click', this.onSelectKeyWord, this);
- } - } } - /**************************************************************************/ - ,onSelectKeyWord : function(e, t){
-
- var item = t.parentNode;
- var tag = item.firstChild.innerHTML;
-
- this.fireEvent('selectKeyword', tag);
-
- // Prevent the link href from being followed
- Ext.EventObject.stopEvent(e);
- } - /**************************************************************************/ - ,getWeight : function(weight){
- var nmax = 100; - var nmin = 0; - - var styles = new Array('smallest','smaller','small','medium','large','larger','largest'); - var value = weight / (nmax - nmin) * 6;
- if(value >= 6.0)
- return styles[6];
- if(value <= 0.0)
- return styles[0];
-
- return styles[Math.round(value)];
- }
- /**************************************************************************/ - ,CanShift: function(direction) {
- if (!this.curPage){
- this.offsetLeft=this.divImages.getLeft();
- }
- var newPage=(direction=='right' ? this.curPage+1 : this.curPage-1 );
- if (newPage<0 || newPage >= this.maxPages){
- return -1;
- } - return newPage; - }
- - ,Shift: function(direction) { - var newPage = this.CanShift(direction); - if (newPage<0 || newPage >= this.maxPages){
- return;
- }
- this.curPage=newPage;
- var newLocation=(this.pageSize*this.curPage)*-1+this.offsetLeft;
- this.divImages.shift({ x:newLocation, duration: this.duration || .7 });
- }
});
-Ext.reg('slide', Ext.xxv.slide); +Ext.reg('RecHeader', Ext.xxv.RecHeader); + /******************************************************************************/ @@ -846,8 +668,11 @@ Ext.extend(Ext.xxv.recordingsDataView, Ext.DataView, { }, DetailsItem : function(record) { - if(record.data.priority - || record.data.id == 'up') { + if(record.data.id == 'up') { + return; + } + if(record.data.priority) { //use cached data + this.preview.update(record); return; } var toDetails = ''; @@ -1276,34 +1101,58 @@ function createRecordingsView(viewer,id) { } } }); - + var preview = new Ext.Panel({
id: 'preview-recordings',
region: 'south',
cls:'preview',
autoScroll: true,
stateful:true, - timefield : timefield,
- items: [ - { - id: 'preview-recordings-frame',
- xtype:'slide', - wrapMarginY:0,
- wrapMarginX:0,
- imageHeight:120,
- imageWidth:160, - autoWidth: true, - listeners:{ - selected: function(slide, time, e, ele){ - this.ownerCt.timefield.setValue(time); - } - ,'selectKeyword': function(tag) { - viewer.gridRecordings.doSelectKeyword(tag); - }
- },
- images:[]
- }], -
+ timefield : timefield, + layout: { + type:'vbox' + ,padding:'0' + ,align:'stretch' + ,autoScroll: true + } + ,defaults:{margins:'0 0 0 0'}
+ ,items: [ + { //header + xtype:'container' + ,height: 50 + ,items: [{ + autoWidth: true, + xtype:'RecHeader'} + ] + },{ //images + id: 'preview-recordings-images' + ,xtype: 'box' + ,height: 130 + ,listeners:{ 'SelectImage': function(slide, time, e, ele){ viewer.gridRecordings.preview.timefield.setValue(time); } } + },{ //timeslide + id:'preview-recordings-slide' + ,margins:'0 16 0 16' + ,height: 32 + ,baseCls : 'x-slide' + ,items: [{ + xtype:'MarksSlider' + ,duration: 100 + ,listeners:{ 'MoveSlider': function(slide, time, e, ele){ viewer.gridRecordings.preview.timefield.setValue(time); } } + }] + },{ //content + id: 'preview-recordings-frame' + ,cls: 'preview-body'
+ ,xtype: 'box' + ,flex: 3 + },{ // keywords + xtype:'container' + ,height: 80 + ,items: [{ + autoWidth: true + ,xtype:'TagClouds' + ,listeners:{ 'selectKeyword': function(tag) { viewer.gridRecordings.doSelectKeyword(tag); } } + }] + }], tbar: [ {
id:'s'
@@ -1356,52 +1205,18 @@ function createRecordingsView(viewer,id) { ,handler: function(){ this.gridRecordings.onPlay(this.gridRecordings.preview.record, this.gridRecordings.preview.timefield.getValue() ); }
} , timefield - ,{
- id:'recordings-shift-left'
- ,iconCls: 'x-tbar-page-prev'
- ,scope: viewer
- ,disabled:false
- ,handler: function() { - this.gridRecordings.preview.items.items[0].Shift('left'); - this.gridRecordings.preview.canshift(); - }
- } - ,{ - id:'recordings-shift-right'
- ,iconCls: 'x-tbar-page-next'
- ,scope: viewer
- ,disabled:false
- ,handler: function(){ - this.gridRecordings.preview.items.items[0].Shift('right'); - this.gridRecordings.preview.canshift(); - }
- } ] - ,canshift : function(){ - var items = this.topToolbar.items;
- if(items) { - if(this.items.items[0].CanShift('right') != -1) { - items.get('recordings-shift-right').enable(); - } else { - items.get('recordings-shift-right').disable(); - } - if(this.items.items[0].CanShift('left') != -1) { - items.get('recordings-shift-left').enable(); - } else { - items.get('recordings-shift-left').disable(); - } - } - } ,content : function(record){
if(record && this.record != record && record.data.isrecording - && this.body - && this.ownerCt.isVisible()) { - this.body.update(''); - this.items.items[0].setvalue(record.data,true); - this.doLayout(); + //&& this.body + //&& this.ownerCt.isVisible() + ) { this.record = record; + //header + this.get(0).get(0).setvalue(record.data); + this.timefield.maxValue = new Date((this.timefield.minValue.getTime())+(record.data.duration * 1000)); this.timefield.setValue(this.timefield.minValue); @@ -1409,9 +1224,21 @@ function createRecordingsView(viewer,id) { // Enable all toolbar buttons var items = this.topToolbar.items;
if(items) { - items.eachKey(function(key, f){if(XXV.help.cmdAllowed(key) || -1 == key.search(/shift/)) f.enable();},items); + items.eachKey(function(key, f) + { + if(key == 'timeline' + && (XXV.help.cmdAllowed('pre') || XXV.help.cmdAllowed('rpv'))) { + f.enable(); + } else if(XXV.help.cmdAllowed(key)) + f.enable(); + } + ,items); } - this.canshift(); + + var content = Ext.get("preview-recordings-frame"); + content.dom.innerHTML = record.data.description.replace(/\r\n/g, '<br />'); + + this.doLayout(); } } ,update : function(record) { @@ -1419,20 +1246,85 @@ function createRecordingsView(viewer,id) { && record.data.isrecording && this.body && this.ownerCt.isVisible()) { - this.body.update(''); - this.items.items[0].setvalue(record.data,false); - this.doLayout(); this.record = record; + + this.get(0).get(0).setvalue(record.data); + + if(!this.tplimg) { + this.tplimg = new Ext.Template('{day:date} - {start} ({period})'); + this.tplimg.compile(); + } + + var frames = record.data.preview.split(","); + if(frames && frames.length > 0) { + this.remove(1); + var pic = new Array(); + var frames = record.data.preview.split(","); + Ext.each(frames, function(frame){ + var u = "?cmd=ri&data="+record.data.id+"_"+frame; + var d = new Date(record.data.day.getTime() + (frame * 40)); + var t = SecondsToHMS((frame * 40)/1000); + var q = this.tplimg.applyTemplate({ + day: d + ,start: d.dateFormat('H:i') + ,period: t + }); + pic.push({ + frame: frame + ,width: 160 + ,html: "<img width='160px' src='"+ u + "' 'ext:qtip='" + q + "'>" + }); + },this); + + this.insert(1,new Ext.Container( { + id: 'preview-recordings-images' + ,height: 130 + ,layoutConfig: { + scrollButtonPosition:'split', + marginScrollButtons: 1, + pagedScroll: false + } + ,layout: 'carousel' + ,items: pic + })); + + } + + this.get(2).get(0).setvalue(record.data.marks,record.data.duration); + // Keywords + this.get(4).get(0).setvalue(record.data.keywords); + var height = record.data.keywords && record.data.keywords.length ? 80 : 0; + if(this.get(4).getHeight() != height) { + this.get(4).suspendEvents(false); + this.get(4).setHeight(height); + this.get(4).resumeEvents(); + } + this.doLayout(); +/* + var root = Ext.getCmp('preview-recordings-images'); + var images = root.select('img'); + Ext.each(images, function(image){ + this.get(1).on("click", function(e, ele){
+ if (!image.onSelected || !(image.onSelected.call(this, image, e, ele )===false)){
+ this.fireEvent('selected', this, new Date(minTime().getTime()+(image.frame * 40)), e, ele); + + var slider = this.get(2).get(0).getSlider('cutpoint_thumb'); + slider.value = pic.frame/25; + this.get(2).get(0).slider.initSliderPosition(slider); + }
+ },this); + }); +*/ } }
,clear: function(){ if(this) {
- if(this.body) - this.body.update(''); + //if(this.body) + // this.body.update(''); this.record = null; // Disable all toolbar buttons var items = this.topToolbar.items;
- if(items) { + if(items) { items.eachKey(function(key, f){f.disable();},items); } diff --git a/skins/jason/timers.js b/skins/jason/timers.js index 46c5c1c..71473d7 100644 --- a/skins/jason/timers.js +++ b/skins/jason/timers.js @@ -108,7 +108,6 @@ Ext.xxv.timerGrid = function(viewer) { ,dataIndex: 'title'
,width: 250 ,renderer: this.formatTitle
- //,editor: new Ext.form.TextField({allowBlank: false}) }, this.activeColumn,
this.vpsColumn, @@ -118,18 +117,20 @@ Ext.xxv.timerGrid = function(viewer) { ,dataIndex: 'day'
,width: 50
,renderer: Ext.util.Format.dateRenderer(this.szColDayFormat)
- //,editor: new Ext.form.DateField({ minValue: Ext.util.Format.date(new Date()) }) ,hidden: true },{
header: this.szColStart
,dataIndex: 'start'
,width: 50 - //,editor: new Ext.form.TimeField()
},{
header: this.szColStop
,dataIndex: 'stop'
,width: 50
- //,editor: new Ext.form.TimeField()
+ },{
+ header: this.szColDuration
+ ,dataIndex: 'duration'
+ ,width: 50 + ,renderer: this.formatDuration
},{
header: this.szHost
,dataIndex: 'host'
@@ -207,6 +208,7 @@ Ext.extend(Ext.xxv.timerGrid, Ext.grid.GridPanel, { // Ext.grid.EditorGridPanel ,szColChannel : "Channel" ,szColStart : "Start"
,szColStop : "Stop" + ,szColDuration : "Duration" ,szHost : "Host" ,szColDayFormat : "l, m/d/Y" ,szSelChEmptyText: "Select a channel..."
@@ -323,6 +325,9 @@ Ext.extend(Ext.xxv.timerGrid, Ext.grid.GridPanel, { // Ext.grid.EditorGridPanel '<div class="topic{1}"><b>{0}</b></div>',
title, style
); + } + ,formatDuration: function(value, p, record) { + return new Date(minTime().getTime()+(value * 1000)).dateFormat('H:i'); }
/******************************************************************************/ ,onToggleSuccess : function( response,options ) diff --git a/skins/jason/ux/Carousel.css b/skins/jason/ux/Carousel.css new file mode 100644 index 0000000..36c7e2d --- /dev/null +++ b/skins/jason/ux/Carousel.css @@ -0,0 +1,67 @@ + .x-carousel-layout { + overflow: hidden; + position: relative; + zoom: 1; + } + + .x-carousel-left-scrollbutton { + width: 10px; + position: absolute; + top: 0px; + background: url(../pic/slide-left.png) no-repeat 0px center; + height: 100%; + cursor:hand; + } + + .x-carousel-layout.x-scroll-button-position-right .x-carousel-left-scrollbutton { + right: 5px; + } + .x-carousel-layout.x-scroll-button-position-left .x-carousel-left-scrollbutton, + .x-carousel-layout.x-scroll-button-position-split .x-carousel-left-scrollbutton { + left: 0px; + } + + .x-carousel-right-scrollbutton { + width: 10px; + position: absolute; + top:0px; + background: url(../pic/slide-right.png) no-repeat 0px center; + height:100%; + cursor:hand; + } + + .x-carousel-layout.x-scroll-button-position-right .x-carousel-right-scrollbutton, + .x-carousel-layout.x-scroll-button-position-split .x-carousel-right-scrollbutton { + right: 0px; + } + + .x-carousel-layout.x-scroll-button-position-left .x-carousel-right-scrollbutton { + left: 23px; + } + + .x-carousel-scroller { + overflow: hidden; + position: relative; + left: 5px + } + + .x-carousel-layout.x-scroll-button-position-left .x-carousel-scroller { + left: 41px; + } + + .x-carousel-layout.x-scroll-button-position-split .x-carousel-scroller { + left: 10px; + } + + .x-carousel-body { + width: 10000px; + overflow: hidden; + zoom: 1; + } + + .x-carousel-scroller .x-carousel-body .x-carousel-item { + float: left; + overflow: hidden; + zoom: 1 + } + diff --git a/skins/jason/ux/Carousel.js b/skins/jason/ux/Carousel.js new file mode 100644 index 0000000..bd1626d --- /dev/null +++ b/skins/jason/ux/Carousel.js @@ -0,0 +1,457 @@ +/*(c) Copyright 2008 Licensed under LGPL3. See details below*/ +var o = Ext.Container.prototype.lookupComponent; +Ext.override(Ext.Container, { + + // Override of our container's method to allow raw Elements to be added. + // This is called in the context of the container. + lookupComponent: function(comp) { + if (comp instanceof Ext.Element) { + return comp; + } else if (comp.nodeType && (comp.nodeType == 1)) { + return Ext.get(comp); + } else { + return o.call(this, comp); + } + } +}); + +Ext.namespace('Ext.ux.layout'); + +/** + * Carousel Layout. + * <br> + * <br>See the following for a <a href="http://extjs-ux.org/repo/authors/jerrybrown5/trunk/Ext/ux/layout/Carousel/Demo.html">demo</a> + * <br> + * <br> Example Usage + * <pre> + * margins: '5 5 5 0', + * title: 'Photos', + * layoutConfig: { + * pagedScroll: true + * }, + * layout: '<b>carousel</b>', + * items: [{ + * title: "First", + * style: { + * margin: '5px 5px 5px 5px' + * }, + * width: 120, + * html: "<img src='../view/images/thumbs/dance_fever.jpg'>" + * }] + * </pre> + * <br>Forum thread: <a href="http://extjs.com/forum/showthread.php?t=47672">http://extjs.com/forum/showthread.php?t=47672</a> + * @class Ext.ux.layout.Carousel + * @author Nigel White aka Animal; updated by Jerry Brown, published by SamuraiJack + * @license Ext.ux.layout.Carousel is licensed under the terms of + * the Open Source <a href="http://www.gnu.org/licenses/lgpl.html">LGPL 3.0 license</a>. Commercial use is permitted to the extent + * that the code/component(s) do NOT become part of another Open Source or Commercially + * licensed development library or toolkit without explicit permission. + * @version 0.2 + */ +Ext.ux.layout.Carousel = Ext.extend(Ext.layout.ContainerLayout, { + constructor: function(config) { + config = config || {}; + +// Non-chunked, then animation makes no sense. + if (!(config.chunkedScroll || config.pagedScroll)) { + Ext.applyIf(config, { + scrollIncrement: 10, + scrollRepeatInterval: 10, + marginScrollButtons: 12, + animScroll: false + }); + } + Ext.ux.layout.Carousel.superclass.constructor.call(this, config); + +// Set up animation config depending upon animation requirements. + if (this.chunkedScroll || this.pagedScroll) { + this.scrollRepeatInterval = this.scrollDuration * 1000; + this.scrollAnimationConfig = { + duration: this.chunkedScroll ? this.scrollDuration : this.scrollDuration * 2, + callback: this.updateScrollButtons, + scope: this + } + } else { + this.scrollAnimationConfig = this.animScroll ? { + duration: this.scrollDuration, + callback: this.updateScrollButtons, + scope: this + } : false; + } + +// if (Ext.isIE){ +// if (!this.defaults) { this.defaults={} } +// if (!this.defaults.bodyStyle) { this.defaults.bodyStyle={} } +// this.defaults.bodyStyle.position='static'; +// } + + }, + + /** + * @cfg {Number} marginScrollButtons This is to set aside space for the left and right navigation buttons. + */ + + marginScrollButtons : 10, + /** + * @cfg scrollElementTag {String} The tag name of the carousel item container. If each item's main Element + * is an <LI> then this could be specified as '<UL>. Defaults to '<DIV>'. + /** + * @cfg {Number} scrollIncrement The number of pixels to scroll each time a tab scroll button is pressed (defaults + * to 10, or if {@link #Ext.ux.layout.Carousel-resizeTabs} = true, the calculated tab width). + */ + scrollIncrement : 10, + /** + * @cfg {Number} scrollRepeatInterval Number of milliseconds between each scroll while a scroll button is + * continuously pressed (defaults to 10). + */ + scrollRepeatInterval : 10, + /** + * @cfg {Float} scrollDuration The number of seconds that each scroll animation should last (defaults to .35). + * Only applies when {@link #Ext.ux.layout.Carousel-animScroll} = true. + */ + scrollDuration : .35, + /** + * @cfg {Boolean} animScroll True to animate tab scrolling so that hidden items slide smoothly into view (defaults + * to true). Only applies when {@link #Ext.ux.layout.Carousel-enableTabScroll} = true. + */ + animScroll : true, + + /** + * @cfg {Boolean} chunkedScroll To control scrolling more than one image at a time + */ + + chunkedScroll: false, + + /** + * @cfg {Boolean} pageScroll Scroll full pages + */ + pagedScroll: false, + + /** + * @cfg {Boolean} loopCount This does an intro page loop this many times after render + */ + loopCount: 0, + /** + * @cfg {Boolean} loopPictureDelay This controls the delay on each picture during the intro page loop + */ + loopPictureDelay: 5, + + // private + monitorResize: true, + + /** + * @cfg scrollButtonPosition (split or right) This determines where the scroll bar buttons will be. Matching style elements need to be in place. + */ + scrollButtonPosition: 'right', + + + + loopImages: function(){ + + if (this.loopCount <= 0){ return } + + var s = this.getScrollTo(1); + if (s) { + s = Math.min(this.getMaxScrollPos(), s); + if(s != this.getScrollPos()) { + this.scrollTo(s); + }else{ + return; /*it should not get here*/ + } + }else{ + this.scrollTo(0); + this.loopCount--; + if (this.loopCount <= 0){ return } + } + + this.loopImages.defer(this.loopPictureDelay * 1000, this); + }, + + + // private + onLayout : function(ct, target){ + var cs = ct.items.items, len = cs.length, c, i; + + if(!this.scrollWrap){ + this.scrollWrap = target.createChild({ + cls: 'x-carousel-layout', + cn: [ + { + tag: this.scrollElementTag || 'div', + cls: 'x-carousel-scroller', + cn: { + cls: 'x-carousel-body' + } + }, { + cls: 'x-carousel-left-scrollbutton', + style: { + height: '100%' + } + }, { + cls: 'x-carousel-right-scrollbutton', + style: { + height: '100%' + } + }] + }); + +// Add the class that defines element positions + this.scrollWrap.addClass('x-scroll-button-position-' + this.scrollButtonPosition); + + this.scrollLeft = this.scrollWrap.child('.x-carousel-left-scrollbutton'); + this.scrollRight = this.scrollWrap.child('.x-carousel-right-scrollbutton'); + this.scroller = this.scrollWrap.child('.x-carousel-scroller'); + this.strip = this.scroller.child('.x-carousel-body'); + + if (this.pagedScroll) { + this.scrollLeft.on('click',this.onScrollLeftClick, this); + this.scrollRight.on('click',this.onScrollRightClick, this); + } else { + this.leftRepeater = new Ext.util.ClickRepeater(this.scrollLeft, { + interval : this.pagedScroll ? 10000 : this.scrollRepeatInterval, + delay: 0, + handler: this.onScrollLeftClick, + scope: this + }); + this.rightRepeater = new Ext.util.ClickRepeater(this.scrollRight, { + interval : this.pagedScroll ? 10000 : this.scrollRepeatInterval, + delay: 0, + handler: this.onScrollRightClick, + scope: this + }); + } + this.renderAll(ct, this.strip); + } + this.scroller.setWidth(this.container.getLayoutTarget().getWidth() - (this.scrollLeft.getWidth() + this.scrollRight.getWidth() + this.marginScrollButtons)); + this.updateScrollButtons.defer(10, this); + + + if (this.loopCount > 0 && (this.chunkedScroll || this.pagedScroll) && !this.startedLoop){ + this.startedLoop=true; /*this var is important since onLayout can be called more than once*/ + this.loopImages.defer(this.loopPictureDelay * 1000, this); + } + + }, + + // private + renderItem : function(c, position, target){ + if(c) { + if (c.initialConfig) { + if (c.rendered){ + if(typeof position == 'number'){ + position = target.dom.childNodes[position]; + } + target.dom.insertBefore(c.getEl().dom, position || null); + } else { + c.render(target, position); + } + } else if (c instanceof Ext.Element) { + c.el = c; + if(typeof position == 'number'){ + position = target.dom.childNodes[position]; + } + target.dom.insertBefore(c.dom, position || null); + } + } + c.el.addClass('x-carousel-item'); + }, + + // private + onResize : function(c, position, target){ + Ext.ux.layout.Carousel.superclass.onResize.apply(this, arguments); + if (Ext.isIE) { + this.scrollLeft.setHeight(this.scroller.getHeight()); + this.scrollRight.setHeight(this.scroller.getHeight()); + } + + this.setItemsEdges(); + +// If width increase has introduced spare space to the right, close it up. + var r = this.getMaxScrollPos(); + if (this.getScrollPos() > r) { + this.scrollTo(r); + } + + + }, + + setItemsEdges:function(){ +// Register strip-relative left/right edges for easy chunked scrolling + var stripLeft = this.strip.getLeft(); + var t = this.container.items.items; + var lt = t.length; + for (var i = 0; i < lt; i++) { + var c = t[i]; + var e = c.el; + var b = e.getBox(); + var l = b.x - stripLeft; + var r = b.right - stripLeft; + +// "left" is the leftmost visible pixel. +// "leftAnchor" is the postition to scroll to to bring the +// item correctly into view with half the inter-item gap visible. +// Same principle applies to "right" + c.edges = { + left: l, + leftAnchor: l, + right: r, + rightAnchor: r + }; + +// Adjust anchors to be halfway between items. + if (i == 0) { + e.setStyle({'margin-left': '0px'}); + } else { + if (i == t.length - 1) { + e.setStyle({'margin-right': '0px'}); + } + var prev = t[i - 1]; + var halfGap = ((l - prev.edges.right) / 2); + prev.edges.rightAnchor += halfGap; + c.edges.leftAnchor -= halfGap; + } + } + +// Work out average item width + this.itemWidth = t[lt - 1].edges.rightAnchor / lt; + + }, + getNextOnLeft: function() { + var t = this.container.items.items; + if (t.length) { + for (var i = t.length - 1; i > -1; i--) { + if (t[i].edges.left < this.getScrollPos()) { + return t[i]; + } + } + } + }, + + getNextOnRight: function() { + var t = this.container.items.items; + if (t.length) { + var scrollRight = this.scroller.dom.scrollLeft + this.getClientWidth(); + for (var i = 0, l = t.length; i < l; i++) { + if (t[i].edges.right > scrollRight) { + return t[i]; + } + } + } + }, + +/** + * Called when a click event is fired by the right scroll button. + * May also be used to programatically trigger a right scroll event. + */ + + onScrollRightClick : function(){ + this.loopCount=0; + var s = this.getScrollTo(1); + if (s) { + s = Math.min(this.getMaxScrollPos(), s); + if(s != this.getScrollPos()) { + this.scrollTo(s); + } + } + }, + +/** + * Called when a click event is fired by the right scroll button. + * May also be used to programatically trigger a left scroll event. + */ + + onScrollLeftClick : function(){ + this.loopCount=0; + var s = Math.max(0, this.getScrollTo(-1)); + if(s != this.getScrollPos()) { + this.scrollTo(s); + } + }, + + // private + scrollTo : function(pos){ + +// Calculate scroll duration based on how far we have to scroll. + if (this.scrollAnimationConfig) { + var distance = Math.abs(this.getScrollPos() - pos); + this.scrollAnimationConfig.duration = this.scrollDuration * (distance / this.itemWidth); + } + + this.scroller.scrollTo('left', pos, this.scrollAnimationConfig); + +// Scroll animation will have called this in its callback. + if(!this.scrollAnimationConfig){ + this.updateScrollButtons(); + } + }, + + // private + updateScrollButtons : function(){ + var pos = this.getScrollPos(); + this.scrollLeft[(pos == 0) ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled'); + this.scrollRight[(pos >= this.getMaxScrollPos()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled'); + }, + + getScrollWidth : function(){ + var t = this.container.items.items; + + if (t.length && ! t[0].edges){ + this.setItemsEdges(); + } + + return t.length ? t[t.length - 1].edges.rightAnchor : 0; + }, + + // private + getScrollPos : function(){ + return this.scroller.dom.scrollLeft || 0; + }, + + getMaxScrollPos: function() { + return this.getScrollWidth() - this.getClientWidth(); + }, + + // private + getClientWidth : function(){ + return this.scroller.dom.clientWidth || 0; + }, + + // private + getScrollTo : function(dir){ + var pos = this.getScrollPos(); + + if (this.chunkedScroll || this.pagedScroll) { +// -1 for left, 1 for right + if (dir == -1) { + var nextLeft = this.getNextOnLeft(); + if (nextLeft) { + if (this.pagedScroll) { + return nextLeft.edges.rightAnchor - this.getClientWidth(); + } else { + return nextLeft.edges.leftAnchor; + } + } + } else { + var nextRight = this.getNextOnRight(); + if (nextRight) { + if (this.pagedScroll) { + return nextRight.edges.leftAnchor; + } else { + return (nextRight.edges.rightAnchor - this.getClientWidth()); + } + } + } + } else { + return (dir == -1) ? pos - this.scrollIncrement : pos + this.scrollIncrement; + } + }, + + // private + isValidParent : function(c, target){ + return true; + } + +}); + +Ext.Container.LAYOUTS['carousel'] = Ext.ux.layout.Carousel; + |
