You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by jk...@apache.org on 2006/06/10 15:59:38 UTC
svn commit: r413300 [12/16] - in /tapestry/tapestry4/trunk/framework/src/js:
dojo/ dojo/src/ dojo/src/animation/ dojo/src/collections/ dojo/src/compat/
dojo/src/crypto/ dojo/src/data/ dojo/src/data/format/
dojo/src/data/provider/ dojo/src/debug/ dojo/s...
Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SlideShow.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SlideShow.js?rev=413300&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SlideShow.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SlideShow.js Sat Jun 10 06:59:28 2006
@@ -0,0 +1,132 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.SlideShow");
+dojo.provide("dojo.widget.html.SlideShow");
+
+dojo.require("dojo.event");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.lfx.*");
+dojo.require("dojo.style");
+
+dojo.widget.defineWidget(
+ "dojo.widget.html.SlideShow",
+ dojo.widget.HtmlWidget,
+ {
+ templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlSlideShow.html"),
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlSlideShow.css"),
+
+ // over-ride some defaults
+ isContainer: false,
+ widgetType: "SlideShow",
+
+ // useful properties
+ imgUrls: [], // the images we'll go through
+ imgUrlBase: "",
+ urlsIdx: 0, // where in the images we are
+ delay: 4000, // give it 4 seconds
+ transitionInterval: 2000, // 2 seconds
+ imgWidth: 800, // img width
+ imgHeight: 600, // img height
+ background: "img2", // what's in the bg
+ foreground: "img1", // what's in the fg
+ stopped: false, // should I stay or should I go?
+ fadeAnim: null, // references our animation
+
+ // our DOM nodes:
+ imagesContainer: null,
+ startStopButton: null,
+ controlsContainer: null,
+ img1: null,
+ img2: null,
+
+ fillInTemplate: function(){
+ dojo.style.setOpacity(this.img1, 0.9999);
+ dojo.style.setOpacity(this.img2, 0.9999);
+ with(this.imagesContainer.style){
+ width = this.imgWidth+"px";
+ height = this.imgHeight+"px";
+ }
+ with(this.img1.style){
+ width = this.imgWidth+"px";
+ height = this.imgHeight+"px";
+ }
+ with(this.img2.style){
+ width = this.imgWidth+"px";
+ height = this.imgHeight+"px";
+ }
+ if(this.imgUrls.length>1){
+ this.img2.src = this.imgUrlBase+this.imgUrls[this.urlsIdx++];
+ this.endTransition();
+ }else{
+ this.img1.src = this.imgUrlBase+this.imgUrls[this.urlsIdx++];
+ }
+ },
+
+ togglePaused: function(){
+ if(this.stopped){
+ this.stopped = false;
+ this.backgroundImageLoaded();
+ this.startStopButton.value= "pause";
+ }else{
+ this.stopped = true;
+ this.startStopButton.value= "play";
+ }
+ },
+
+ backgroundImageLoaded: function(){
+ // start fading out the foreground image
+ if(this.stopped){ return; }
+
+ // actually start the fadeOut effect
+ // NOTE: if we wanted to use other transition types, we'd set them up
+ // here as well
+ if(this.fadeAnim) {
+ this.fadeAnim.stop();
+ }
+ this.fadeAnim = dojo.lfx.fadeOut(this[this.foreground],
+ this.transitionInterval, null);
+ dojo.event.connect(this.fadeAnim,"onEnd",this,"endTransition");
+ this.fadeAnim.play();
+ },
+
+ endTransition: function(){
+ // move the foreground image to the background
+ with(this[this.background].style){ zIndex = parseInt(zIndex)+1; }
+ with(this[this.foreground].style){ zIndex = parseInt(zIndex)-1; }
+
+ // fg/bg book-keeping
+ var tmp = this.foreground;
+ this.foreground = this.background;
+ this.background = tmp;
+
+ // keep on truckin
+ this.loadNextImage();
+ },
+
+ loadNextImage: function(){
+ // load a new image in that container, and make sure it informs
+ // us when it finishes loading
+ dojo.event.kwConnect({
+ srcObj: this[this.background],
+ srcFunc: "onload",
+ adviceObj: this,
+ adviceFunc: "backgroundImageLoaded",
+ once: true, // make sure we only ever hear about it once
+ delay: this.delay
+ });
+ dojo.style.setOpacity(this[this.background], 1.0);
+ this[this.background].src = this.imgUrlBase+this.imgUrls[this.urlsIdx++];
+ if(this.urlsIdx>(this.imgUrls.length-1)){
+ this.urlsIdx = 0;
+ }
+ }
+ }
+);
Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SlideShow.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SortableTable.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SortableTable.js?rev=413300&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SortableTable.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SortableTable.js Sat Jun 10 06:59:28 2006
@@ -0,0 +1,38 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.SortableTable");
+dojo.require("dojo.widget.*");
+dojo.requireAfterIf("html", "dojo.widget.html.SortableTable");
+dojo.widget.tags.addParseTreeHandler("dojo:sortableTable");
+
+// set up the general widget
+dojo.widget.SortableTable=function(){
+ // summary
+ // base class for the SortableTable
+ dojo.widget.Widget.call(this);
+ this.widgetType="SortableTable";
+ this.isContainer=false;
+
+ // custom properties
+ this.enableMultipleSelect=false;
+ this.maximumNumberOfSelections=0; // 0 for unlimited, is the default.
+ this.enableAlternateRows=false;
+ this.minRows=0; // 0 means ignore.
+ this.defaultDateFormat="%D";
+ this.data=[];
+ this.selected=[]; // always an array to handle multiple selections.
+ this.columns=[];
+ this.sortIndex=0; // index of the column sorted on, first is the default.
+ this.sortDirection=0; // 0==asc, 1==desc
+ this.valueField="Id"; // if a JSON structure is parsed and there is a field of this name,
+ // a value attribute will be added to the row (tr value="{Id}")
+};
+dojo.inherits(dojo.widget.SortableTable, dojo.widget.Widget);
Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SortableTable.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Spinner.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Spinner.js?rev=413300&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Spinner.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Spinner.js Sat Jun 10 06:59:28 2006
@@ -0,0 +1,194 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Spinner");
+dojo.provide("dojo.widget.AdjustableIntegerTextbox");
+
+dojo.require("dojo.widget.validate.IntegerTextbox");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.event.*");
+
+/*
+ ****** AdjustableIntegerTextbox ******
+
+ A subclass of IntegerTextbox.
+*/
+dojo.widget.AdjustableIntegerTextbox = function(node) {
+ // this property isn't a primitive and needs to be created on a per-item basis.
+ this.flags = {};
+}
+dojo.inherits(dojo.widget.AdjustableIntegerTextbox, dojo.widget.validate.IntegerTextbox);
+dojo.lang.extend(dojo.widget.AdjustableIntegerTextbox, {
+ // new subclass properties
+ widgetType: "AdjustableIntegerTextbox",
+ delta: "1",
+
+ adjustValue: function(direction, x){
+ var val = this.getValue().replace(/[^\-+\d]/g, "");
+ if(val.length == 0){ return; }
+
+ num = Math.min(Math.max((parseInt(val)+(parseInt(this.delta) * direction)), this.flags.min), this.flags.max);
+ val = (new Number(num)).toString();
+
+ if(num >= 0){
+ val = ((this.flags.signed == true)?'+':' ')+val; // make sure first char is a nondigit
+ }
+
+ if(this.flags.separator.length > 0){
+ for (var i=val.length-3; i > 1; i-=3){
+ val = val.substr(0,i)+this.flags.separator+val.substr(i);
+ }
+ }
+
+ if(val.substr(0,1) == ' '){ val = val.substr(1); } // remove space
+
+ this.setValue(val);
+
+ return val.length;
+ }
+});
+dojo.widget.tags.addParseTreeHandler("dojo:AdjustableIntegerTextbox");
+
+/*
+ ****** AdjustableRealNumberTextbox ******
+
+ A subclass of RealNumberTextbox.
+ @attr places The exact number of decimal places. If omitted, it's unlimited and optional.
+ @attr exponent Can be true or false. If omitted the exponential part is optional.
+ @attr eSigned Is the exponent signed? Can be true or false, if omitted the sign is optional.
+*/
+dojo.widget.AdjustableRealNumberTextbox = function(node) {
+ // this property isn't a primitive and needs to be created on a per-item basis.
+ this.flags = {};
+}
+dojo.inherits(dojo.widget.AdjustableRealNumberTextbox, dojo.widget.validate.RealNumberTextbox);
+dojo.lang.extend(dojo.widget.AdjustableRealNumberTextbox, {
+ // new subclass properties
+ widgetType: "AdjustableRealNumberTextbox",
+ delta: "1e1",
+
+ adjustValue: function(direction, x){
+ var val = this.getValue().replace(/[^\-+\.eE\d]/g, "");
+ if(!val.length){ return; }
+
+ var num = parseFloat(val);
+ if(isNaN(num)){ return; }
+ var delta = this.delta.split(/[eE]/);
+ if(!delta.length){
+ delta = [1, 1];
+ }else{
+ delta[0] = parseFloat(delta[0].replace(/[^\-+\.\d]/g, ""));
+ if(isNaN(delta[0])){ delta[0] = 1; }
+ if(delta.length > 1){
+ delta[1] = parseInt(delta[1]);
+ }
+ if(isNaN(delta[1])){ delta[1] = 1; }
+ }
+ val = this.getValue().split(/[eE]/);
+ if(!val.length){ return; }
+ var numBase = parseFloat(val[0].replace(/[^\-+\.\d]/g, ""));
+ if(val.length == 1){
+ var numExp = 0;
+ }else{
+ var numExp = parseInt(val[1].replace(/[^\-+\d]/g, ""));
+ }
+ if(x <= val[0].length){
+ x = 0;
+ numBase += delta[0] * direction;
+ }else{
+ x = Number.MAX_VALUE;
+ numExp += delta[1] * direction;
+ if(this.flags.eSigned == false && numExp < 0){
+ numExp = 0;
+ }
+ }
+ num = Math.min(Math.max((numBase * Math.pow(10,numExp)), this.flags.min), this.flags.max);
+ if((this.flags.exponent == true || (this.flags.exponent != false && x != 0)) && num.toExponential){
+ if (isNaN(this.flags.places) || this.flags.places == Infinity){
+ val = num.toExponential();
+ }else{
+ val = num.toExponential(this.flags.places);
+ }
+ }else if(num.toFixed && num.toPrecision){
+ if(isNaN(this.flags.places)){
+ val = num.toPrecision((1/3).toString().length-1);
+ }else{
+ val = num.toFixed(this.flags.places);
+ }
+ }else{
+ val = num.toString();
+ }
+
+ if(num >= 0){
+ if(this.flags.signed == true){
+ val = '+' + val;
+ }
+ }
+ val = val.split(/[eE]/);
+ if(this.flags.separator.length > 0){
+ if(num >= 0 && val[0].substr(0,1) != '+'){
+ val[0] = ' ' + val[0]; // make sure first char is nondigit for easy algorithm
+ }
+ var i = val[0].lastIndexOf('.');
+ if(i >= 0){
+ i -= 3;
+ }else{
+ i = val[0].length-3;
+ }
+ for (; i > 1; i-=3){
+ val[0] = val[0].substr(0,i)+this.flags.separator+val[0].substr(i);
+ }
+ if(val[0].substr(0,1) == ' '){ val[0] = val[0].substr(1); } // remove space
+ }
+ if(val.length > 1){
+ if((this.flags.eSigned == true)&&(val[1].substr(0,1) != '+')){
+ val[1] = '+' + val[1];
+ }else if((!this.flags.eSigned)&&(val[1].substr(0,1) == '+')){
+ val[1] = val[1].substr(1);
+ }else if((!this.flags.eSigned)&&(val[1].substr(0,1) == '-')&&(num.toFixed && num.toPrecision)){
+ if(isNaN(this.flags.places)){
+ val[0] = num.toPrecision((1/3).toString().length-1);
+ }else{
+ val[0] = num.toFixed(this.flags.places).toString();
+ }
+ val[1] = "0";
+ }
+ val[0] += 'e' + val[1];
+ }
+ this.setValue(val[0]);
+ if(x > val[0].length){ x = val[0].length; }
+ return x;
+ }
+});
+dojo.widget.tags.addParseTreeHandler("dojo:AdjustableRealNumberTextbox");
+
+dojo.widget.Spinner = function(){
+ dojo.widget.Widget.call(this);
+}
+
+dojo.inherits(dojo.widget.Spinner, dojo.widget.Widget);
+
+dojo.widget.Spinner.defaults = {
+ widgetType: "Spinner",
+ isContainer: false
+};
+
+dojo.lang.extend(dojo.widget.Spinner, dojo.widget.Spinner.defaults);
+
+dojo.widget.DomSpinner = function(){
+ dojo.widget.Spinner.call(this);
+ dojo.widget.DomWidget.call(this, true);
+}
+
+dojo.inherits(dojo.widget.DomSpinner, dojo.widget.DomWidget);
+dojo.widget.tags.addParseTreeHandler("dojo:Spinner");
+
+// render-specific includes
+dojo.requireAfterIf("html", "dojo.widget.html.Spinner");
Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Spinner.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SplitContainer.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SplitContainer.js?rev=413300&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SplitContainer.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SplitContainer.js Sat Jun 10 06:59:28 2006
@@ -0,0 +1,579 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.SplitContainer");
+dojo.provide("dojo.widget.SplitContainerPanel");
+dojo.provide("dojo.widget.html.SplitContainer");
+dojo.provide("dojo.widget.html.SplitContainerPanel");
+
+//
+// TODO
+// make it prettier
+// active dragging upwards doesn't always shift other bars (direction calculation is wrong in this case)
+//
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.LayoutContainer");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.html");
+dojo.require("dojo.style");
+dojo.require("dojo.dom");
+dojo.require("dojo.io"); // workaround dojo bug. dojo.io.cookie requires dojo.io but it still doesn't get pulled in
+dojo.require("dojo.io.cookie");
+
+dojo.widget.html.SplitContainer = function(){
+
+ dojo.widget.HtmlWidget.call(this);
+
+ this.sizers = [];
+}
+
+dojo.inherits(dojo.widget.html.SplitContainer, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.SplitContainer, {
+ widgetType: "SplitContainer",
+ isContainer: true,
+
+ virtualSizer: null,
+ isHorizontal: 0,
+ paneBefore: null,
+ paneAfter: null,
+ isSizing: false,
+ dragOffset: null,
+ startPoint: null,
+ lastPoint: null,
+ sizingSplitter: null,
+ isActiveResize: 0,
+ offsetX: 0,
+ offsetY: 0,
+ isDraggingLeft: 0,
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlSplitContainer.css"),
+ originPos: null,
+ persist: true, // save splitter positions in a cookie
+
+ activeSizing: '',
+ sizerWidth: 15,
+ orientation: 'horizontal',
+
+ debugName: '',
+
+ fillInTemplate: function(){
+
+ dojo.style.insertCssFile(this.templateCssPath, null, true);
+ dojo.html.addClass(this.domNode, "dojoSplitContainer");
+ this.domNode.style.overflow='hidden'; // workaround firefox bug
+
+ this.paneWidth = dojo.style.getContentWidth(this.domNode);
+ this.paneHeight = dojo.style.getContentHeight(this.domNode);
+
+ this.isHorizontal = (this.orientation == 'horizontal') ? 1 : 0;
+ this.isActiveResize = (this.activeSizing == '1') ? 1 : 0;
+
+ //dojo.debug("fillInTemplate for "+this.debugName);
+ },
+
+ onResized: function(e){
+ this.paneWidth = dojo.style.getContentWidth(this.domNode);
+ this.paneHeight = dojo.style.getContentHeight(this.domNode);
+ this.layoutPanels();
+ },
+
+ postCreate: function(args, fragment, parentComp){
+
+ // dojo.debug("post create for "+this.debugName);
+
+ // attach the children and create the draggers
+ for(var i=0; i<this.children.length; i++){
+ with(this.children[i].domNode.style){
+ position = "absolute";
+ }
+ dojo.html.addClass(this.children[i].domNode,
+ "dojoSplitPane");
+
+ if(i == this.children.length-1){
+ break;
+ }
+
+ this._addSizer();
+ }
+
+ // create the fake dragger
+ this.virtualSizer = document.createElement('div');
+ this.virtualSizer.style.position = 'absolute';
+ this.virtualSizer.style.display = 'none';
+ //this.virtualSizer.style.backgroundColor = 'lime';
+ this.virtualSizer.style.zIndex = 10;
+ this.virtualSizer.className = this.isHorizontal ? 'dojoSplitContainerVirtualSizerH' : 'dojoSplitContainerVirtualSizerV';
+ this.domNode.appendChild(this.virtualSizer);
+
+ dojo.html.disableSelection(this.virtualSizer);
+
+ if(this.persist){
+ this.restoreState();
+ }
+
+ // size the panels once the browser has caught up
+ this.resizeSoon();
+ },
+
+ _injectChild: function(child) {
+ with(child.domNode.style){
+ position = "absolute";
+ }
+ dojo.html.addClass(child.domNode,
+ "dojoSplitPane");
+ },
+
+ _addSizer: function() {
+ var i = this.sizers.length;
+
+ this.sizers[i] = document.createElement('div');
+ this.sizers[i].style.position = 'absolute';
+ this.sizers[i].className = this.isHorizontal ? 'dojoSplitContainerSizerH' : 'dojoSplitContainerSizerV';
+
+ var self = this;
+ var handler = (function(){ var sizer_i = i; return function(e){ self.beginSizing(e, sizer_i); } })();
+ dojo.event.connect(this.sizers[i], "onmousedown", handler);
+
+ this.domNode.appendChild(this.sizers[i]);
+ dojo.html.disableSelection(this.sizers[i]);
+ },
+
+ removeChild: function(widget){
+ // Remove sizer, but only if widget is really our child and
+ // we have at least one sizer to throw away
+ if (this.sizers.length > 0) {
+ for(var x=0; x<this.children.length; x++){
+ if(this.children[x] === widget){
+ var i = this.sizers.length - 1;
+ this.domNode.removeChild(this.sizers[i]);
+ this.sizers.length = i;
+ break;
+ }
+ }
+ }
+
+ // Remove widget and repaint
+ dojo.widget.html.SplitContainer.superclass.removeChild.call(this, widget, arguments);
+ this.onResized();
+ },
+
+ addChild: function(widget, overrideContainerNode, pos, ref, insertIndex){
+ dojo.widget.html.SplitContainer.superclass.addChild.call(this, widget, overrideContainerNode, pos, ref, insertIndex);
+ this._injectChild(widget);
+
+ if (this.children.length > 1) {
+ this._addSizer();
+ }
+
+ this.layoutPanels();
+ },
+
+ layoutPanels: function(){
+ if (this.children.length == 0){ return; }
+
+ //
+ // calculate space
+ //
+
+ var space = this.isHorizontal ? this.paneWidth : this.paneHeight;
+
+ if (this.children.length > 1){
+
+ space -= this.sizerWidth * (this.children.length - 1);
+ }
+
+
+ //
+ // calculate total of SizeShare values
+ //
+
+ var out_of = 0;
+
+ for(var i=0; i<this.children.length; i++){
+
+ out_of += this.children[i].sizeShare;
+ }
+
+
+ //
+ // work out actual pixels per sizeshare unit
+ //
+
+ var pix_per_unit = space / out_of;
+
+
+ //
+ // set the SizeActual member of each pane
+ //
+
+ var total_size = 0;
+
+ for(var i=0; i<this.children.length-1; i++){
+
+ var size = Math.round(pix_per_unit * this.children[i].sizeShare);
+ this.children[i].sizeActual = size;
+ total_size += size;
+ }
+ this.children[this.children.length-1].sizeActual = space - total_size;
+
+ //
+ // make sure the sizes are ok
+ //
+
+ this.checkSizes();
+
+
+ //
+ // now loop, positioning each pane and letting children resize themselves
+ //
+
+ var pos = 0;
+ var size = this.children[0].sizeActual;
+ this.movePanel(this.children[0].domNode, pos, size);
+ this.children[0].position = pos;
+ this.children[0].checkSize();
+ pos += size;
+
+ for(var i=1; i<this.children.length; i++){
+
+ // first we position the sizing handle before this pane
+ this.movePanel(this.sizers[i-1], pos, this.sizerWidth);
+ this.sizers[i-1].position = pos;
+ pos += this.sizerWidth;
+
+ size = this.children[i].sizeActual;
+ this.movePanel(this.children[i].domNode, pos, size);
+ this.children[i].position = pos;
+ this.children[i].checkSize();
+ pos += size;
+ }
+ },
+
+ movePanel: function(panel, pos, size){
+ if (this.isHorizontal){
+ panel.style.left = pos + 'px';
+ panel.style.top = 0;
+
+ dojo.style.setOuterWidth(panel, size);
+ dojo.style.setOuterHeight(panel, this.paneHeight);
+ }else{
+ panel.style.left = 0;
+ panel.style.top = pos + 'px';
+
+ dojo.style.setOuterWidth(panel, this.paneWidth);
+ dojo.style.setOuterHeight(panel, size);
+ }
+ },
+
+ growPane: function(growth, pane){
+
+ if (growth > 0){
+ if (pane.sizeActual > pane.sizeMin){
+ if ((pane.sizeActual - pane.sizeMin) > growth){
+
+ // stick all the growth in this pane
+ pane.sizeActual = pane.sizeActual - growth;
+ growth = 0;
+ }else{
+ // put as much growth in here as we can
+ growth -= pane.sizeActual - pane.sizeMin;
+ pane.sizeActual = pane.sizeMin;
+ }
+ }
+ }
+ return growth;
+ },
+
+ checkSizes: function(){
+
+ var total_min_size = 0;
+ var total_size = 0;
+
+ for(var i=0; i<this.children.length; i++){
+
+ total_size += this.children[i].sizeActual;
+ total_min_size += this.children[i].sizeMin;
+ }
+
+ // only make adjustments if we have enough space for all the minimums
+
+ if (total_min_size <= total_size){
+
+ var growth = 0;
+
+ for(var i=0; i<this.children.length; i++){
+
+ if (this.children[i].sizeActual < this.children[i].sizeMin){
+
+ growth += this.children[i].sizeMin - this.children[i].sizeActual;
+ this.children[i].sizeActual = this.children[i].sizeMin;
+ }
+ }
+
+ if (growth > 0){
+ if (this.isDraggingLeft){
+ for(var i=this.children.length-1; i>=0; i--){
+ growth = this.growPane(growth, this.children[i]);
+ }
+ }else{
+ for(var i=0; i<this.children.length; i++){
+ growth = this.growPane(growth, this.children[i]);
+ }
+ }
+ }
+ }else{
+
+ for(var i=0; i<this.children.length; i++){
+ this.children[i].sizeActual = Math.round(total_size * (this.children[i].sizeMin / total_min_size));
+ }
+ }
+ },
+
+ beginSizing: function(e, i){
+ var clientX = e.layerX;
+ var clientY = e.layerY;
+ var screenX = e.pageX;
+ var screenY = e.pageY;
+
+ this.paneBefore = this.children[i];
+ this.paneAfter = this.children[i+1];
+
+ this.isSizing = true;
+ this.sizingSplitter = this.sizers[i];
+ this.originPos = dojo.style.getAbsolutePosition(this.domNode, true);
+ this.dragOffset = {'x':clientX, 'y':clientY};
+ this.startPoint = {'x':screenX, 'y':screenY};
+ this.lastPoint = {'x':screenX, 'y':screenY};
+
+ this.offsetX = screenX - clientX;
+ this.offsetY = screenY - clientY;
+
+ if (!this.isActiveResize){
+ this.showSizingLine();
+ }
+
+ //
+ // attach mouse events
+ //
+
+ dojo.event.connect(document.documentElement, "onmousemove", this, "changeSizing");
+ dojo.event.connect(document.documentElement, "onmouseup", this, "endSizing");
+ },
+
+ changeSizing: function(e){
+ var screenX = e.pageX;
+ var screenY = e.pageY;
+
+ if (this.isActiveResize){
+ this.lastPoint = {'x':screenX, 'y':screenY};
+ this.movePoint();
+ this.updateSize();
+ }else{
+ this.lastPoint = {'x':screenX, 'y':screenY};
+ this.movePoint();
+ this.moveSizingLine();
+ }
+ },
+
+ endSizing: function(e){
+
+ if (!this.isActiveResize){
+ this.hideSizingLine();
+ }
+
+ this.updateSize();
+
+ this.isSizing = false;
+
+ dojo.event.disconnect(document.documentElement, "onmousemove", this, "changeSizing");
+ dojo.event.disconnect(document.documentElement, "onmouseup", this, "endSizing");
+
+ if(this.persist){
+ this.saveState(this);
+ }
+ },
+
+ movePoint: function(){
+
+ // make sure FLastPoint is a legal point to drag to
+ var p = this.screenToMainClient(this.lastPoint);
+
+ if (this.isHorizontal){
+
+ var a = p.x - this.dragOffset.x;
+ a = this.legaliseSplitPoint(a);
+ p.x = a + this.dragOffset.x;
+ }else{
+ var a = p.y - this.dragOffset.y;
+ a = this.legaliseSplitPoint(a);
+ p.y = a + this.dragOffset.y;
+ }
+
+ this.lastPoint = this.mainClientToScreen(p);
+ },
+
+ screenToClient: function(pt){
+
+ pt.x -= (this.offsetX + this.sizingSplitter.position);
+ pt.y -= (this.offsetY + this.sizingSplitter.position);
+
+ return pt;
+ },
+
+ clientToScreen: function(pt){
+
+ pt.x += (this.offsetX + this.sizingSplitter.position);
+ pt.y += (this.offsetY + this.sizingSplitter.position);
+
+ return pt;
+ },
+
+ screenToMainClient: function(pt){
+
+ pt.x -= this.offsetX;
+ pt.y -= this.offsetY;
+
+ return pt;
+ },
+
+ mainClientToScreen: function(pt){
+
+ pt.x += this.offsetX;
+ pt.y += this.offsetY;
+
+ return pt;
+ },
+
+ legaliseSplitPoint: function(a){
+
+ a += this.sizingSplitter.position;
+
+ this.isDraggingLeft = (a > 0) ? 1 : 0;
+
+ if (!this.isActiveResize){
+
+ if (a < this.paneBefore.position + this.paneBefore.sizeMin){
+
+ a = this.paneBefore.position + this.paneBefore.sizeMin;
+ }
+
+ if (a > this.paneAfter.position + (this.paneAfter.sizeActual - (this.sizerWidth + this.paneAfter.sizeMin))){
+
+ a = this.paneAfter.position + (this.paneAfter.sizeActual - (this.sizerWidth + this.paneAfter.sizeMin));
+ }
+ }
+
+ a -= this.sizingSplitter.position;
+
+ this.checkSizes();
+
+ return a;
+ },
+
+ updateSize: function(){
+
+ var p = this.clientToScreen(this.lastPoint);
+ var p = this.screenToClient(this.lastPoint);
+
+ var pos = this.isHorizontal ? p.x - (this.dragOffset.x + this.originPos.x) : p.y - (this.dragOffset.y + this.originPos.y);
+
+ var start_region = this.paneBefore.position;
+ var end_region = this.paneAfter.position + this.paneAfter.sizeActual;
+
+ this.paneBefore.sizeActual = pos - start_region;
+ this.paneAfter.position = pos + this.sizerWidth;
+ this.paneAfter.sizeActual = end_region - this.paneAfter.position;
+
+ for(var i=0; i<this.children.length; i++){
+
+ this.children[i].sizeShare = this.children[i].sizeActual;
+ }
+
+ this.layoutPanels();
+ },
+
+ showSizingLine: function(){
+
+ this.moveSizingLine();
+
+ if (this.isHorizontal){
+ dojo.style.setOuterWidth(this.virtualSizer, this.sizerWidth);
+ dojo.style.setOuterHeight(this.virtualSizer, this.paneHeight);
+ }else{
+ dojo.style.setOuterWidth(this.virtualSizer, this.paneWidth);
+ dojo.style.setOuterHeight(this.virtualSizer, this.sizerWidth);
+ }
+
+ this.virtualSizer.style.display = 'block';
+ },
+
+ hideSizingLine: function(){
+
+ this.virtualSizer.style.display = 'none';
+ },
+
+ moveSizingLine: function(){
+
+ var origin = {'x':0, 'y':0};
+
+ if (this.isHorizontal){
+ origin.x += (this.lastPoint.x - this.startPoint.x) + this.sizingSplitter.position;
+ }else{
+ origin.y += (this.lastPoint.y - this.startPoint.y) + this.sizingSplitter.position;
+ }
+
+ this.virtualSizer.style.left = origin.x + 'px';
+ this.virtualSizer.style.top = origin.y + 'px';
+ },
+
+ _getCookieName: function(i) {
+ return this.widgetId + "_" + i;
+ },
+
+ restoreState: function () {
+ for(var i=0; i<this.children.length; i++) {
+ var cookieName = this._getCookieName(i);
+ var cookieValue = dojo.io.cookie.getCookie(cookieName);
+ if (cookieValue != null) {
+ var pos = parseInt(cookieValue);
+ this.children[i].sizeShare=pos;
+ }
+ }
+ },
+
+ saveState: function (){
+ for(var i=0; i<this.children.length; i++) {
+ var cookieName = this._getCookieName(i);
+ dojo.io.cookie.setCookie(cookieName, this.children[i].sizeShare, null, null, null, null);
+ }
+ }
+});
+
+// These arguments can be specified for the children of a SplitContainer.
+// Since any widget can be specified as a SplitContainer child, mix them
+// into the base widget class. (This is a hack, but it's effective.)
+dojo.lang.extend(dojo.widget.Widget, {
+ sizeMin: 10,
+ sizeShare: 10
+});
+
+// Deprecated class for split pane children.
+// Actually any widget can be the child of a split pane
+dojo.widget.html.SplitContainerPanel = function(){
+ dojo.widget.html.LayoutContainer.call(this);
+}
+dojo.inherits(dojo.widget.html.SplitContainerPanel, dojo.widget.html.LayoutContainer);
+dojo.lang.extend(dojo.widget.html.SplitContainerPanel, {
+ widgetType: "SplitContainerPanel"
+});
+
+dojo.widget.tags.addParseTreeHandler("dojo:SplitContainer");
+dojo.widget.tags.addParseTreeHandler("dojo:SplitContainerPanel");
Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/SplitContainer.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/TabContainer.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/TabContainer.js?rev=413300&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/TabContainer.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/TabContainer.js Sat Jun 10 06:59:28 2006
@@ -0,0 +1,261 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.TabContainer");
+dojo.provide("dojo.widget.html.TabContainer");
+dojo.provide("dojo.widget.Tab");
+
+dojo.require("dojo.lang.func");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.event.*");
+dojo.require("dojo.html");
+dojo.require("dojo.style");
+dojo.require("dojo.html.layout");
+
+//////////////////////////////////////////
+// TabContainer -- a set of Tabs
+//////////////////////////////////////////
+dojo.widget.html.TabContainer = function() {
+ dojo.widget.HtmlWidget.call(this);
+}
+
+dojo.inherits(dojo.widget.html.TabContainer, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.TabContainer, {
+ widgetType: "TabContainer",
+ isContainer: true,
+
+ // Constructor arguments
+ labelPosition: "top",
+ closeButton: "none",
+
+ useVisibility: false, // true-->use visibility:hidden instead of display:none
+
+ // if false, TabContainers size changes according to size of currently selected tab
+ doLayout: true,
+
+ templatePath: dojo.uri.dojoUri("src/widget/templates/HtmlTabContainer.html"),
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlTabContainer.css"),
+
+ selectedTab: "", // initially selected tab (widgetId)
+
+ fillInTemplate: function(args, frag) {
+ // Copy style info from input node to output node
+ var source = this.getFragNodeRef(frag);
+ dojo.html.copyStyle(this.domNode, source);
+
+ dojo.widget.html.TabContainer.superclass.fillInTemplate.call(this, args, frag);
+ },
+
+ postCreate: function(args, frag) {
+ // Load all the tabs, creating a label for each one
+ for(var i=0; i<this.children.length; i++){
+ this._setupTab(this.children[i]);
+ }
+
+ if (this.closeButton=="pane") {
+ var div = document.createElement("div");
+ dojo.html.addClass(div, "dojoTabPanePaneClose");
+ var self = this;
+ dojo.event.connect(div, "onclick", function(){ self._runOnCloseTab(self.selectedTabWidget); });
+ dojo.event.connect(div, "onmouseover", function(){ dojo.html.addClass(div, "dojoTabPanePaneCloseHover"); });
+ dojo.event.connect(div, "onmouseout", function(){ dojo.html.removeClass(div, "dojoTabPanePaneCloseHover"); });
+ this.dojoTabLabels.appendChild(div);
+ }
+
+ if(this.doLayout){
+ dojo.html.addClass(this.dojoTabLabels, "dojoTabLabels-"+this.labelPosition);
+ } else {
+ dojo.html.addClass(this.dojoTabLabels, "dojoTabLabels-"+this.labelPosition+"-noLayout");
+ }
+
+ this._doSizing();
+
+ // Display the selected tab
+ if(this.selectedTabWidget){
+ this.selectTab(this.selectedTabWidget, true);
+ }
+ },
+
+ addChild: function(child, overrideContainerNode, pos, ref, insertIndex){
+ this._setupTab(child);
+ dojo.widget.html.TabContainer.superclass.addChild.call(this,child, overrideContainerNode, pos, ref, insertIndex);
+
+ // in case the tab labels have overflowed from one line to two lines
+ this._doSizing();
+ },
+
+ _setupTab: function(tab){
+ tab.domNode.style.display="none";
+
+ // Create label
+ tab.div = document.createElement("div");
+ dojo.widget.wai.setAttr(tab.div, "waiRole", "tab");
+ dojo.html.addClass(tab.div, "dojoTabPaneTab");
+ var span = document.createElement("span");
+ span.innerHTML = tab.label;
+ dojo.html.disableSelection(span);
+ if (this.closeButton=="tab") {
+ var img = document.createElement("div");
+ dojo.html.addClass(img, "dojoTabPaneTabClose");
+ var self = this;
+ dojo.event.connect(img, "onclick", function(evt){ self._runOnCloseTab(tab); dojo.event.browser.stopEvent(evt); });
+ dojo.event.connect(img, "onmouseover", function(){ dojo.html.addClass(img,"dojoTabPaneTabCloseHover"); });
+ dojo.event.connect(img, "onmouseout", function(){ dojo.html.removeClass(img,"dojoTabPaneTabCloseHover"); });
+ span.appendChild(img);
+ }
+ tab.div.appendChild(span);
+ this.dojoTabLabels.appendChild(tab.div);
+
+ var self = this;
+ dojo.event.connect(tab.div, "onclick", function(){ self.selectTab(tab); });
+
+ if(!this.selectedTabWidget || this.selectedTab==tab.widgetId || tab.selected){
+ this.selectedTabWidget = tab;
+ } else {
+ this._hideTab(tab);
+ }
+
+ dojo.html.addClass(tab.domNode, "dojoTabPane");
+ with(tab.domNode.style){
+ top = dojo.style.getPixelValue(this.containerNode, "padding-top", true);
+ left = dojo.style.getPixelValue(this.containerNode, "padding-left", true);
+ }
+ },
+
+ // Configure the content pane to take up all the space except for where the tab labels are
+ _doSizing: function(){
+ // position the labels and the container node
+ var labelAlign=this.labelPosition.replace(/-h/,"");
+ var children = [
+ {domNode: this.dojoTabLabels, layoutAlign: labelAlign},
+ {domNode: this.containerNode, layoutAlign: "client"}
+ ];
+
+
+ if (this.doLayout) {
+ dojo.html.layout(this.domNode, children);
+ }
+
+ // size the current tab
+ // TODO: should have ptr to current tab rather than searching
+ var cw=dojo.style.getContentWidth(this.containerNode);
+ var ch=dojo.style.getContentHeight(this.containerNode);
+ dojo.lang.forEach(this.children, function(child){
+ //if (this.doLayout) {
+ if(child.selected){
+ child.resizeTo(cw, ch);
+ }
+ //} else {
+ // child.onResized();
+ //}
+ });
+
+ },
+
+ removeChild: function(tab) {
+
+ // remove tab event handlers
+ dojo.event.disconnect(tab.div, "onclick", function () { });
+ if (this.closeButton=="tab") {
+ var img = tab.div.lastChild.lastChild;
+ if (img) {
+ dojo.html.removeClass(img, "dojoTabPaneTabClose", function () { });
+ dojo.event.disconnect(img, "onclick", function () { });
+ dojo.event.disconnect(img, "onmouseover", function () { });
+ dojo.event.disconnect(img, "onmouseout", function () { });
+ }
+ }
+
+ dojo.widget.html.TabContainer.superclass.removeChild.call(this, tab);
+
+ dojo.html.removeClass(tab.domNode, "dojoTabPane");
+ this.dojoTabLabels.removeChild(tab.div);
+ delete(tab.div);
+
+ if (this.selectedTabWidget === tab) {
+ this.selectedTabWidget = undefined;
+ if (this.children.length > 0) {
+ this.selectTab(this.children[0], true);
+ }
+ }
+
+ // in case the tab labels have overflowed from one line to two lines
+ this._doSizing();
+ },
+
+ selectTab: function(tab, _noRefresh) {
+ // Deselect old tab and select new one
+ if (this.selectedTabWidget) {
+ this._hideTab(this.selectedTabWidget);
+ }
+ this.selectedTabWidget = tab;
+ this._showTab(tab, _noRefresh);
+ },
+
+ _showTab: function(tab, _noRefresh) {
+ dojo.html.addClass(tab.div, "current");
+ tab.selected=true;
+ if ( this.useVisibility && !dojo.render.html.ie ) {
+ tab.domNode.style.visibility="visible";
+ } else {
+ // make sure we dont refresh onClose and on postCreate
+ // speeds up things a bit when using refreshOnShow and fixes #646
+ if(_noRefresh && tab.refreshOnShow){
+ var tmp = tab.refreshOnShow;
+ tab.refreshOnShow = false;
+ tab.show();
+ tab.refreshOnShow = tmp;
+ }else{
+ tab.show();
+ }
+
+ tab.resizeTo(
+ dojo.style.getContentWidth(this.containerNode),
+ dojo.style.getContentHeight(this.containerNode)
+ );
+ }
+ },
+
+ _hideTab: function(tab) {
+ dojo.html.removeClass(tab.div, "current");
+ tab.selected=false;
+ if( this.useVisibility ){
+ tab.domNode.style.visibility="hidden";
+ }else{
+ tab.hide();
+ }
+ },
+
+ _runOnCloseTab: function(tab) {
+ var onc = tab.extraArgs.onClose || tab.extraArgs.onclose;
+ var fcn = dojo.lang.isFunction(onc) ? onc : window[onc];
+ var remove = dojo.lang.isFunction(fcn) ? fcn(this,tab) : true;
+ if(remove) {
+ this.removeChild(tab);
+ // makes sure we can clean up executeScripts in ContentPane onUnLoad
+ tab.destroy();
+ }
+ },
+
+ onResized: function() {
+ this._doSizing();
+ }
+});
+dojo.widget.tags.addParseTreeHandler("dojo:TabContainer");
+
+// These arguments can be specified for the children of a TabContainer.
+// Since any widget can be specified as a TabContainer child, mix them
+// into the base widget class. (This is a hack, but it's effective.)
+dojo.lang.extend(dojo.widget.Widget, {
+ label: "",
+ selected: false // is this tab currently selected?
+});
Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/TitlePane.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/TitlePane.js?rev=413300&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/TitlePane.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/TitlePane.js Sat Jun 10 06:59:28 2006
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.TitlePane");
+dojo.requireAfterIf("html", "dojo.widget.html.TitlePane");
Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/TitlePane.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Toolbar.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Toolbar.js?rev=413300&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Toolbar.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Toolbar.js Sat Jun 10 06:59:28 2006
@@ -0,0 +1,935 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.ToolbarContainer");
+dojo.provide("dojo.widget.html.ToolbarContainer");
+dojo.provide("dojo.widget.Toolbar");
+dojo.provide("dojo.widget.html.Toolbar");
+dojo.provide("dojo.widget.ToolbarItem");
+dojo.provide("dojo.widget.html.ToolbarButtonGroup");
+dojo.provide("dojo.widget.html.ToolbarButton");
+dojo.provide("dojo.widget.html.ToolbarDialog");
+dojo.provide("dojo.widget.html.ToolbarMenu");
+dojo.provide("dojo.widget.html.ToolbarSeparator");
+dojo.provide("dojo.widget.html.ToolbarSpace");
+dojo.provide("dojo.widget.Icon");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.html");
+
+/* ToolbarContainer
+ *******************/
+dojo.widget.tags.addParseTreeHandler("dojo:toolbarContainer");
+dojo.widget.html.ToolbarContainer = function() {
+ dojo.widget.HtmlWidget.call(this);
+}
+dojo.inherits(dojo.widget.html.ToolbarContainer, dojo.widget.HtmlWidget);
+dojo.lang.extend(dojo.widget.html.ToolbarContainer, {
+ widgetType: "ToolbarContainer",
+ isContainer: true,
+
+ templateString: '<div class="toolbarContainer" dojoAttachPoint="containerNode"></div>',
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlToolbar.css"),
+
+ getItem: function(name) {
+ if(name instanceof dojo.widget.ToolbarItem) { return name; }
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.html.Toolbar) {
+ var item = child.getItem(name);
+ if(item) { return item; }
+ }
+ }
+ return null;
+ },
+
+ getItems: function() {
+ var items = [];
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.html.Toolbar) {
+ items = items.concat(child.getItems());
+ }
+ }
+ return items;
+ },
+
+ enable: function() {
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.html.Toolbar) {
+ child.enable.apply(child, arguments);
+ }
+ }
+ },
+
+ disable: function() {
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.html.Toolbar) {
+ child.disable.apply(child, arguments);
+ }
+ }
+ },
+
+ select: function(name) {
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.html.Toolbar) {
+ child.select(arguments);
+ }
+ }
+ },
+
+ deselect: function(name) {
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.html.Toolbar) {
+ child.deselect(arguments);
+ }
+ }
+ },
+
+ getItemsState: function() {
+ var values = {};
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.html.Toolbar) {
+ dojo.lang.mixin(values, child.getItemsState());
+ }
+ }
+ return values;
+ },
+
+ getItemsActiveState: function() {
+ var values = {};
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.html.Toolbar) {
+ dojo.lang.mixin(values, child.getItemsActiveState());
+ }
+ }
+ return values;
+ },
+
+ getItemsSelectedState: function() {
+ var values = {};
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.html.Toolbar) {
+ dojo.lang.mixin(values, child.getItemsSelectedState());
+ }
+ }
+ return values;
+ }
+});
+
+/* Toolbar
+ **********/
+dojo.widget.tags.addParseTreeHandler("dojo:toolbar");
+dojo.widget.html.Toolbar = function() {
+ dojo.widget.HtmlWidget.call(this);
+}
+dojo.inherits(dojo.widget.html.Toolbar, dojo.widget.HtmlWidget);
+dojo.lang.extend(dojo.widget.html.Toolbar, {
+ widgetType: "Toolbar",
+ isContainer: true,
+
+ templateString: '<div class="toolbar" dojoAttachPoint="containerNode" unselectable="on" dojoOnMouseover="_onmouseover" dojoOnMouseout="_onmouseout" dojoOnClick="_onclick" dojoOnMousedown="_onmousedown" dojoOnMouseup="_onmouseup"></div>',
+ //templateString: '<div class="toolbar" dojoAttachPoint="containerNode" unselectable="on"></div>',
+
+ // given a node, tries to find it's toolbar item
+ _getItem: function(node) {
+ var start = new Date();
+ var widget = null;
+ while(node && node != this.domNode) {
+ if(dojo.html.hasClass(node, "toolbarItem")) {
+ var widgets = dojo.widget.manager.getWidgetsByFilter(function(w) { return w.domNode == node; });
+ if(widgets.length == 1) {
+ widget = widgets[0];
+ break;
+ } else if(widgets.length > 1) {
+ dojo.raise("Toolbar._getItem: More than one widget matches the node");
+ }
+ }
+ node = node.parentNode;
+ }
+ return widget;
+ },
+
+ _onmouseover: function(e) {
+ var widget = this._getItem(e.target);
+ if(widget && widget._onmouseover) { widget._onmouseover(e); }
+ },
+
+ _onmouseout: function(e) {
+ var widget = this._getItem(e.target);
+ if(widget && widget._onmouseout) { widget._onmouseout(e); }
+ },
+
+ _onclick: function(e) {
+ var widget = this._getItem(e.target);
+ if(widget && widget._onclick){
+ widget._onclick(e);
+ }
+ },
+
+ _onmousedown: function(e) {
+ var widget = this._getItem(e.target);
+ if(widget && widget._onmousedown) { widget._onmousedown(e); }
+ },
+
+ _onmouseup: function(e) {
+ var widget = this._getItem(e.target);
+ if(widget && widget._onmouseup) { widget._onmouseup(e); }
+ },
+
+ addChild: function(item, pos, props) {
+ var widget = dojo.widget.ToolbarItem.make(item, null, props);
+ var ret = dojo.widget.html.Toolbar.superclass.addChild.call(this, widget, null, pos, null);
+ return ret;
+ },
+
+ push: function() {
+ for(var i = 0; i < arguments.length; i++) {
+ this.addChild(arguments[i]);
+ }
+ },
+
+ getItem: function(name) {
+ if(name instanceof dojo.widget.ToolbarItem) { return name; }
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.ToolbarItem
+ && child._name == name) { return child; }
+ }
+ return null;
+ },
+
+ getItems: function() {
+ var items = [];
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.ToolbarItem) {
+ items.push(child);
+ }
+ }
+ return items;
+ },
+
+ getItemsState: function() {
+ var values = {};
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.ToolbarItem) {
+ values[child._name] = {
+ selected: child._selected,
+ enabled: child._enabled
+ };
+ }
+ }
+ return values;
+ },
+
+ getItemsActiveState: function() {
+ var values = this.getItemsState();
+ for(var item in values) {
+ values[item] = values[item].enabled;
+ }
+ return values;
+ },
+
+ getItemsSelectedState: function() {
+ var values = this.getItemsState();
+ for(var item in values) {
+ values[item] = values[item].selected;
+ }
+ return values;
+ },
+
+ enable: function() {
+ var items = arguments.length ? arguments : this.children;
+ for(var i = 0; i < items.length; i++) {
+ var child = this.getItem(items[i]);
+ if(child instanceof dojo.widget.ToolbarItem) {
+ child.enable(false, true);
+ }
+ }
+ },
+
+ disable: function() {
+ var items = arguments.length ? arguments : this.children;
+ for(var i = 0; i < items.length; i++) {
+ var child = this.getItem(items[i]);
+ if(child instanceof dojo.widget.ToolbarItem) {
+ child.disable();
+ }
+ }
+ },
+
+ select: function() {
+ for(var i = 0; i < arguments.length; i++) {
+ var name = arguments[i];
+ var item = this.getItem(name);
+ if(item) { item.select(); }
+ }
+ },
+
+ deselect: function() {
+ for(var i = 0; i < arguments.length; i++) {
+ var name = arguments[i];
+ var item = this.getItem(name);
+ if(item) { item.disable(); }
+ }
+ },
+
+ setValue: function() {
+ for(var i = 0; i < arguments.length; i += 2) {
+ var name = arguments[i], value = arguments[i+1];
+ var item = this.getItem(name);
+ if(item) {
+ if(item instanceof dojo.widget.ToolbarItem) {
+ item.setValue(value);
+ }
+ }
+ }
+ }
+});
+
+/* ToolbarItem hierarchy:
+ - ToolbarItem
+ - ToolbarButton
+ - ToolbarDialog
+ - ToolbarMenu
+ - ToolbarSeparator
+ - ToolbarSpace
+ - ToolbarFlexibleSpace
+*/
+
+
+/* ToolbarItem
+ **************/
+dojo.widget.ToolbarItem = function() {
+ dojo.widget.HtmlWidget.call(this);
+}
+dojo.inherits(dojo.widget.ToolbarItem, dojo.widget.HtmlWidget);
+dojo.lang.extend(dojo.widget.ToolbarItem, {
+ templateString: '<span unselectable="on" class="toolbarItem"></span>',
+
+ _name: null,
+ getName: function() { return this._name; },
+ setName: function(value) { return this._name = value; },
+ getValue: function() { return this.getName(); },
+ setValue: function(value) { return this.setName(value); },
+
+ _selected: false,
+ isSelected: function() { return this._selected; },
+ setSelected: function(is, force, preventEvent) {
+ if(!this._toggleItem && !force) { return; }
+ is = Boolean(is);
+ if(force || this._enabled && this._selected != is) {
+ this._selected = is;
+ this.update();
+ if(!preventEvent) {
+ this._fireEvent(is ? "onSelect" : "onDeselect");
+ this._fireEvent("onChangeSelect");
+ }
+ }
+ },
+ select: function(force, preventEvent) {
+ return this.setSelected(true, force, preventEvent);
+ },
+ deselect: function(force, preventEvent) {
+ return this.setSelected(false, force, preventEvent);
+ },
+
+ _toggleItem: false,
+ isToggleItem: function() { return this._toggleItem; },
+ setToggleItem: function(value) { this._toggleItem = Boolean(value); },
+
+ toggleSelected: function(force) {
+ return this.setSelected(!this._selected, force);
+ },
+
+ _enabled: true,
+ isEnabled: function() { return this._enabled; },
+ setEnabled: function(is, force, preventEvent) {
+ is = Boolean(is);
+ if(force || this._enabled != is) {
+ this._enabled = is;
+ this.update();
+ if(!preventEvent) {
+ this._fireEvent(this._enabled ? "onEnable" : "onDisable");
+ this._fireEvent("onChangeEnabled");
+ }
+ }
+ return this._enabled;
+ },
+ enable: function(force, preventEvent) {
+ return this.setEnabled(true, force, preventEvent);
+ },
+ disable: function(force, preventEvent) {
+ return this.setEnabled(false, force, preventEvent);
+ },
+ toggleEnabled: function(force, preventEvent) {
+ return this.setEnabled(!this._enabled, force, preventEvent);
+ },
+
+ _icon: null,
+ getIcon: function() { return this._icon; },
+ setIcon: function(value) {
+ var icon = dojo.widget.Icon.make(value);
+ if(this._icon) {
+ this._icon.setIcon(icon);
+ } else {
+ this._icon = icon;
+ }
+ var iconNode = this._icon.getNode();
+ if(iconNode.parentNode != this.domNode) {
+ if(this.domNode.hasChildNodes()) {
+ this.domNode.insertBefore(iconNode, this.domNode.firstChild);
+ } else {
+ this.domNode.appendChild(iconNode);
+ }
+ }
+ return this._icon;
+ },
+
+ // TODO: update the label node (this.labelNode?)
+ _label: "",
+ getLabel: function() { return this._label; },
+ setLabel: function(value) {
+ var ret = this._label = value;
+ if(!this.labelNode) {
+ this.labelNode = document.createElement("span");
+ this.domNode.appendChild(this.labelNode);
+ }
+ this.labelNode.innerHTML = "";
+ this.labelNode.appendChild(document.createTextNode(this._label));
+ this.update();
+ return ret;
+ },
+
+ // fired from: setSelected, setEnabled, setLabel
+ update: function() {
+ if(this._enabled) {
+ dojo.html.removeClass(this.domNode, "disabled");
+ if(this._selected) {
+ dojo.html.addClass(this.domNode, "selected");
+ } else {
+ dojo.html.removeClass(this.domNode, "selected");
+ }
+ } else {
+ this._selected = false;
+ dojo.html.addClass(this.domNode, "disabled");
+ dojo.html.removeClass(this.domNode, "down");
+ dojo.html.removeClass(this.domNode, "hover");
+ }
+ this._updateIcon();
+ },
+
+ _updateIcon: function() {
+ if(this._icon) {
+ if(this._enabled) {
+ if(this._cssHover) {
+ this._icon.hover();
+ } else if(this._selected) {
+ this._icon.select();
+ } else {
+ this._icon.enable();
+ }
+ } else {
+ this._icon.disable();
+ }
+ }
+ },
+
+ _fireEvent: function(evt) {
+ if(typeof this[evt] == "function") {
+ var args = [this];
+ for(var i = 1; i < arguments.length; i++) {
+ args.push(arguments[i]);
+ }
+ this[evt].apply(this, args);
+ }
+ },
+
+ _onmouseover: function(e) {
+ if(!this._enabled) { return };
+ dojo.html.addClass(this.domNode, "hover");
+ },
+
+ _onmouseout: function(e) {
+ dojo.html.removeClass(this.domNode, "hover");
+ dojo.html.removeClass(this.domNode, "down");
+ if(!this._selected) {
+ dojo.html.removeClass(this.domNode, "selected");
+ }
+ },
+
+ _onclick: function(e) {
+ // FIXME: buttons never seem to have this._enabled set to true on Opera 9
+ // dojo.debug("widget:", this.widgetType, ":", this.getName(), ", enabled:", this._enabled);
+ if(this._enabled && !this._toggleItem) {
+ this._fireEvent("onClick");
+ }
+ },
+
+ _onmousedown: function(e) {
+ if(e.preventDefault) { e.preventDefault(); }
+ if(!this._enabled) { return };
+ dojo.html.addClass(this.domNode, "down");
+ if(this._toggleItem) {
+ if(this.parent.preventDeselect && this._selected) {
+ return;
+ }
+ this.toggleSelected();
+ }
+ },
+
+ _onmouseup: function(e) {
+ dojo.html.removeClass(this.domNode, "down");
+ },
+
+ fillInTemplate: function(args, frag) {
+ if(args.name) { this._name = args.name; }
+ if(args.selected) { this.select(); }
+ if(args.disabled) { this.disable(); }
+ if(args.label) { this.setLabel(args.label); }
+ if(args.icon) { this.setIcon(args.icon); }
+ if(args.toggleitem||args.toggleItem) { this.setToggleItem(true); }
+ }
+});
+
+dojo.widget.ToolbarItem.make = function(wh, whIsType, props) {
+ var item = null;
+
+ if(wh instanceof Array) {
+ item = dojo.widget.createWidget("ToolbarButtonGroup", props);
+ item.setName(wh[0]);
+ for(var i = 1; i < wh.length; i++) {
+ item.addChild(wh[i]);
+ }
+ } else if(wh instanceof dojo.widget.ToolbarItem) {
+ item = wh;
+ } else if(wh instanceof dojo.uri.Uri) {
+ item = dojo.widget.createWidget("ToolbarButton",
+ dojo.lang.mixin(props||{}, {icon: new dojo.widget.Icon(wh.toString())}));
+ } else if(whIsType) {
+ item = dojo.widget.createWidget(wh, props)
+ } else if(typeof wh == "string" || wh instanceof String) {
+ switch(wh.charAt(0)) {
+ case "|":
+ case "-":
+ case "/":
+ item = dojo.widget.createWidget("ToolbarSeparator", props);
+ break;
+ case " ":
+ if(wh.length == 1) {
+ item = dojo.widget.createWidget("ToolbarSpace", props);
+ } else {
+ item = dojo.widget.createWidget("ToolbarFlexibleSpace", props);
+ }
+ break;
+ default:
+ if(/\.(gif|jpg|jpeg|png)$/i.test(wh)) {
+ item = dojo.widget.createWidget("ToolbarButton",
+ dojo.lang.mixin(props||{}, {icon: new dojo.widget.Icon(wh.toString())}));
+ } else {
+ item = dojo.widget.createWidget("ToolbarButton",
+ dojo.lang.mixin(props||{}, {label: wh.toString()}));
+ }
+ }
+ } else if(wh && wh.tagName && /^img$/i.test(wh.tagName)) {
+ item = dojo.widget.createWidget("ToolbarButton",
+ dojo.lang.mixin(props||{}, {icon: wh}));
+ } else {
+ item = dojo.widget.createWidget("ToolbarButton",
+ dojo.lang.mixin(props||{}, {label: wh.toString()}));
+ }
+ return item;
+}
+
+/* ToolbarButtonGroup
+ *********************/
+dojo.widget.tags.addParseTreeHandler("dojo:toolbarButtonGroup");
+dojo.widget.html.ToolbarButtonGroup = function() {
+ dojo.widget.ToolbarItem.call(this);
+}
+dojo.inherits(dojo.widget.html.ToolbarButtonGroup, dojo.widget.ToolbarItem);
+dojo.lang.extend(dojo.widget.html.ToolbarButtonGroup, {
+ widgetType: "ToolbarButtonGroup",
+ isContainer: true,
+
+ templateString: '<span unselectable="on" class="toolbarButtonGroup" dojoAttachPoint="containerNode"></span>',
+
+ // if a button has the same name, it will be selected
+ // if this is set to a number, the button at that index will be selected
+ defaultButton: "",
+
+ postCreate: function() {
+ for (var i = 0; i < this.children.length; i++) {
+ this._injectChild(this.children[i]);
+ }
+ },
+
+ addChild: function(item, pos, props) {
+ var widget = dojo.widget.ToolbarItem.make(item, null, dojo.lang.mixin(props||{}, {toggleItem:true}));
+ var ret = dojo.widget.html.ToolbarButtonGroup.superclass.addChild.call(this, widget, null, pos, null);
+ this._injectChild(widget);
+ return ret;
+ },
+
+ _injectChild: function(widget) {
+ dojo.event.connect(widget, "onSelect", this, "onChildSelected");
+ dojo.event.connect(widget, "onDeselect", this, "onChildDeSelected");
+ if(widget._name == this.defaultButton
+ || (typeof this.defaultButton == "number"
+ && this.children.length-1 == this.defaultButton)) {
+ widget.select(false, true);
+ }
+ },
+
+ getItem: function(name) {
+ if(name instanceof dojo.widget.ToolbarItem) { return name; }
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.ToolbarItem
+ && child._name == name) { return child; }
+ }
+ return null;
+ },
+
+ getItems: function() {
+ var items = [];
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.ToolbarItem) {
+ items.push(child);
+ }
+ }
+ return items;
+ },
+
+ onChildSelected: function(e) {
+ this.select(e._name);
+ },
+
+ onChildDeSelected: function(e) {
+ this._fireEvent("onChangeSelect", this._value);
+ },
+
+ enable: function(force, preventEvent) {
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.ToolbarItem) {
+ child.enable(force, preventEvent);
+ if(child._name == this._value) {
+ child.select(force, preventEvent);
+ }
+ }
+ }
+ },
+
+ disable: function(force, preventEvent) {
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.ToolbarItem) {
+ child.disable(force, preventEvent);
+ }
+ }
+ },
+
+ _value: "",
+ getValue: function() { return this._value; },
+
+ select: function(name, force, preventEvent) {
+ for(var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ if(child instanceof dojo.widget.ToolbarItem) {
+ if(child._name == name) {
+ child.select(force, preventEvent);
+ this._value = name;
+ } else {
+ child.deselect(true, true);
+ }
+ }
+ }
+ if(!preventEvent) {
+ this._fireEvent("onSelect", this._value);
+ this._fireEvent("onChangeSelect", this._value);
+ }
+ },
+ setValue: this.select,
+
+ preventDeselect: false // if true, once you select one, you can't have none selected
+});
+
+/* ToolbarButton
+ ***********************/
+dojo.widget.tags.addParseTreeHandler("dojo:toolbarButton");
+dojo.widget.html.ToolbarButton = function() {
+ dojo.widget.ToolbarItem.call(this);
+}
+dojo.inherits(dojo.widget.html.ToolbarButton, dojo.widget.ToolbarItem);
+dojo.lang.extend(dojo.widget.html.ToolbarButton, {
+ widgetType: "ToolbarButton",
+
+ fillInTemplate: function(args, frag) {
+ dojo.widget.html.ToolbarButton.superclass.fillInTemplate.call(this, args, frag);
+ dojo.html.addClass(this.domNode, "toolbarButton");
+ if(this._icon) {
+ this.setIcon(this._icon);
+ }
+ if(this._label) {
+ this.setLabel(this._label);
+ }
+
+ if(!this._name) {
+ if(this._label) {
+ this.setName(this._label);
+ } else if(this._icon) {
+ var src = this._icon.getSrc("enabled").match(/[\/^]([^\.\/]+)\.(gif|jpg|jpeg|png)$/i);
+ if(src) { this.setName(src[1]); }
+ } else {
+ this._name = this._widgetId;
+ }
+ }
+ }
+});
+
+/* ToolbarDialog
+ **********************/
+dojo.widget.tags.addParseTreeHandler("dojo:toolbarDialog");
+dojo.widget.html.ToolbarDialog = function() {
+ dojo.widget.html.ToolbarButton.call(this);
+}
+dojo.inherits(dojo.widget.html.ToolbarDialog, dojo.widget.html.ToolbarButton);
+dojo.lang.extend(dojo.widget.html.ToolbarDialog, {
+ widgetType: "ToolbarDialog",
+
+ fillInTemplate: function (args, frag) {
+ dojo.widget.html.ToolbarDialog.superclass.fillInTemplate.call(this, args, frag);
+ dojo.event.connect(this, "onSelect", this, "showDialog");
+ dojo.event.connect(this, "onDeselect", this, "hideDialog");
+ },
+
+ showDialog: function (e) {
+ dojo.lang.setTimeout(dojo.event.connect, 1, document, "onmousedown", this, "deselect");
+ },
+
+ hideDialog: function (e) {
+ dojo.event.disconnect(document, "onmousedown", this, "deselect");
+ }
+
+});
+
+/* ToolbarMenu
+ **********************/
+dojo.widget.tags.addParseTreeHandler("dojo:toolbarMenu");
+dojo.widget.html.ToolbarMenu = function() {
+ dojo.widget.html.ToolbarDialog.call(this);
+
+ this.widgetType = "ToolbarMenu";
+}
+dojo.inherits(dojo.widget.html.ToolbarMenu, dojo.widget.html.ToolbarDialog);
+
+/* ToolbarMenuItem
+ ******************/
+dojo.widget.ToolbarMenuItem = function() {
+}
+
+/* ToolbarSeparator
+ **********************/
+dojo.widget.tags.addParseTreeHandler("dojo:toolbarSeparator");
+dojo.widget.html.ToolbarSeparator = function() {
+ dojo.widget.ToolbarItem.call(this);
+}
+dojo.inherits(dojo.widget.html.ToolbarSeparator, dojo.widget.ToolbarItem);
+dojo.lang.extend(dojo.widget.html.ToolbarSeparator, {
+ widgetType: "ToolbarSeparator",
+ templateString: '<span unselectable="on" class="toolbarItem toolbarSeparator"></span>',
+
+ defaultIconPath: new dojo.uri.dojoUri("src/widget/templates/buttons/-.gif"),
+
+ fillInTemplate: function(args, frag, skip) {
+ dojo.widget.html.ToolbarSeparator.superclass.fillInTemplate.call(this, args, frag);
+ this._name = this.widgetId;
+ if(!skip) {
+ if(!this._icon) {
+ this.setIcon(this.defaultIconPath);
+ }
+ this.domNode.appendChild(this._icon.getNode());
+ }
+ },
+
+ // don't want events!
+ _onmouseover: null,
+ _onmouseout: null,
+ _onclick: null,
+ _onmousedown: null,
+ _onmouseup: null
+});
+
+/* ToolbarSpace
+ **********************/
+dojo.widget.tags.addParseTreeHandler("dojo:toolbarSpace");
+dojo.widget.html.ToolbarSpace = function() {
+ dojo.widget.html.ToolbarSeparator.call(this);
+}
+dojo.inherits(dojo.widget.html.ToolbarSpace, dojo.widget.html.ToolbarSeparator);
+dojo.lang.extend(dojo.widget.html.ToolbarSpace, {
+ widgetType: "ToolbarSpace",
+
+ fillInTemplate: function(args, frag, skip) {
+ dojo.widget.html.ToolbarSpace.superclass.fillInTemplate.call(this, args, frag, true);
+ if(!skip) {
+ dojo.html.addClass(this.domNode, "toolbarSpace");
+ }
+ }
+});
+
+/* ToolbarSelect
+ ******************/
+
+dojo.widget.tags.addParseTreeHandler("dojo:toolbarSelect");
+dojo.widget.html.ToolbarSelect = function() {
+ dojo.widget.ToolbarItem.call(this);
+}
+dojo.inherits(dojo.widget.html.ToolbarSelect, dojo.widget.ToolbarItem);
+dojo.lang.extend(dojo.widget.html.ToolbarSelect, {
+ widgetType: "ToolbarSelect",
+ templateString: '<span class="toolbarItem toolbarSelect" unselectable="on"><select dojoAttachPoint="selectBox" dojoOnChange="changed"></select></span>',
+
+ fillInTemplate: function(args, frag) {
+ dojo.widget.html.ToolbarSelect.superclass.fillInTemplate.call(this, args, frag, true);
+ var keys = args.values;
+ var i = 0;
+ for(var val in keys) {
+ var opt = document.createElement("option");
+ opt.setAttribute("value", keys[val]);
+ opt.innerHTML = val;
+ this.selectBox.appendChild(opt);
+ }
+ },
+
+ changed: function(e) {
+ this._fireEvent("onSetValue", this.selectBox.value);
+ },
+
+ setEnabled: function(is, force, preventEvent) {
+ var ret = dojo.widget.html.ToolbarSelect.superclass.setEnabled.call(this, is, force, preventEvent);
+ this.selectBox.disabled = !this._enabled;
+ return ret;
+ },
+
+ // don't want events!
+ _onmouseover: null,
+ _onmouseout: null,
+ _onclick: null,
+ _onmousedown: null,
+ _onmouseup: null
+});
+
+/* Icon
+ *********/
+// arguments can be IMG nodes, Image() instances or URLs -- enabled is the only one required
+dojo.widget.Icon = function(enabled, disabled, hover, selected){
+ if(!arguments.length){
+ // FIXME: should this be dojo.raise?
+ throw new Error("Icon must have at least an enabled state");
+ }
+ var states = ["enabled", "disabled", "hover", "selected"];
+ var currentState = "enabled";
+ var domNode = document.createElement("img");
+
+ this.getState = function(){ return currentState; }
+ this.setState = function(value){
+ if(dojo.lang.inArray(value, states)){
+ if(this[value]){
+ currentState = value;
+ domNode.setAttribute("src", this[currentState].src);
+ }
+ }else{
+ throw new Error("Invalid state set on Icon (state: " + value + ")");
+ }
+ }
+
+ this.setSrc = function(state, value){
+ if(/^img$/i.test(value.tagName)){
+ this[state] = value;
+ }else if(typeof value == "string" || value instanceof String
+ || value instanceof dojo.uri.Uri){
+ this[state] = new Image();
+ this[state].src = value.toString();
+ }
+ return this[state];
+ }
+
+ this.setIcon = function(icon){
+ for(var i = 0; i < states.length; i++){
+ if(icon[states[i]]){
+ this.setSrc(states[i], icon[states[i]]);
+ }
+ }
+ this.update();
+ }
+
+ this.enable = function(){ this.setState("enabled"); }
+ this.disable = function(){ this.setState("disabled"); }
+ this.hover = function(){ this.setState("hover"); }
+ this.select = function(){ this.setState("selected"); }
+
+ this.getSize = function(){
+ return {
+ width: domNode.width||domNode.offsetWidth,
+ height: domNode.height||domNode.offsetHeight
+ };
+ }
+
+ this.setSize = function(w, h){
+ domNode.width = w;
+ domNode.height = h;
+ return { width: w, height: h };
+ }
+
+ this.getNode = function(){
+ return domNode;
+ }
+
+ this.getSrc = function(state){
+ if(state){ return this[state].src; }
+ return domNode.src||"";
+ }
+
+ this.update = function(){
+ this.setState(currentState);
+ }
+
+ for(var i = 0; i < states.length; i++){
+ var arg = arguments[i];
+ var state = states[i];
+ this[state] = null;
+ if(!arg){ continue; }
+ this.setSrc(state, arg);
+ }
+
+ this.enable();
+}
+
+dojo.widget.Icon.make = function(a,b,c,d){
+ for(var i = 0; i < arguments.length; i++){
+ if(arguments[i] instanceof dojo.widget.Icon){
+ return arguments[i];
+ }
+ }
+
+ return new dojo.widget.Icon(a,b,c,d);
+}
Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Toolbar.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Tooltip.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Tooltip.js?rev=413300&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Tooltip.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Tooltip.js Sat Jun 10 06:59:28 2006
@@ -0,0 +1,14 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Tooltip");
+dojo.require("dojo.widget.Widget");
+
+dojo.requireAfterIf("html", "dojo.widget.html.Tooltip");
Added: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Tree.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Tree.js?rev=413300&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Tree.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Tree.js Sat Jun 10 06:59:28 2006
@@ -0,0 +1,569 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+/**
+ * Tree model does all the drawing, visual node management etc.
+ * Throws events about clicks on it, so someone may catch them and process
+ * Tree knows nothing about DnD stuff, covered in TreeDragAndDrop and (if enabled) attached by controller
+*/
+
+/**
+ * TODO: use domNode.cloneNode instead of createElement for grid
+ * Should be faster (lyxsus)
+ */
+dojo.provide("dojo.widget.Tree");
+
+dojo.require("dojo.event.*");
+dojo.require("dojo.io.*");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.TreeNode");
+
+
+
+// make it a tag
+dojo.widget.tags.addParseTreeHandler("dojo:Tree");
+
+
+dojo.widget.Tree = function() {
+ dojo.widget.HtmlWidget.call(this);
+
+ this.eventNames = {};
+
+ this.tree = this;
+ this.DNDAcceptTypes = [];
+ this.actionsDisabled = [];
+
+}
+dojo.inherits(dojo.widget.Tree, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.Tree, {
+ widgetType: "Tree",
+
+ eventNamesDefault: {
+ // new child does not get domNode filled in (only template draft)
+ // until addChild->createDOMNode is called(program way) OR createDOMNode (html-way)
+ // hook events to operate on new DOMNode, create dropTargets etc
+ createDOMNode: "createDOMNode",
+ // tree created.. Perform tree-wide actions if needed
+ treeCreate: "treeCreate",
+ treeDestroy: "treeDestroy",
+ // expand icon clicked
+ treeClick: "treeClick",
+ // node icon clicked
+ iconClick: "iconClick",
+ // node title clicked
+ titleClick: "titleClick",
+
+ moveFrom: "moveFrom",
+ moveTo: "moveTo",
+ addChild: "addChild",
+ removeNode: "removeNode",
+ expand: "expand",
+ collapse: "collapse"
+ },
+
+ isContainer: true,
+
+ DNDMode: "off",
+
+ lockLevel: 0, // lock ++ unlock --, so nested locking works fine
+
+ strictFolders: true,
+
+ DNDModes: {
+ BETWEEN: 1,
+ ONTO: 2
+ },
+
+ DNDAcceptTypes: "",
+
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/images/Tree/Tree.css"),
+
+ templateString: '<div class="dojoTree"></div>',
+
+ isExpanded: true, // consider this "root node" to be always expanded
+
+ isTree: true,
+
+ objectId: "",
+
+ // autoCreate if not "off"
+ // used to get the autocreated controller ONLY.
+ // generally, tree DOES NOT KNOW about its CONTROLLER, it just doesn't care
+ // controller gets messages via dojo.event
+ controller: "",
+
+ // autoCreate if not "off"
+ // used to get the autocreated selector ONLY.
+ // generally, tree DOES NOT KNOW its SELECTOR
+ // binding is made with dojo.event
+ selector: "",
+
+ // used ONLY at initialization time
+ menu: "", // autobind menu if menu's widgetId is set here
+
+ expandLevel: "", // expand to level automatically
+
+ //
+ // these icons control the grid and expando buttons for the whole tree
+ //
+
+ blankIconSrc: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_blank.gif"),
+
+ gridIconSrcT: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_t.gif"), // for non-last child grid
+ gridIconSrcL: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_l.gif"), // for last child grid
+ gridIconSrcV: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_v.gif"), // vertical line
+ gridIconSrcP: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_p.gif"), // for under parent item child icons
+ gridIconSrcC: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_c.gif"), // for under child item child icons
+ gridIconSrcX: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_x.gif"), // grid for sole root item
+ gridIconSrcY: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_y.gif"), // grid for last rrot item
+ gridIconSrcZ: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_z.gif"), // for under root parent item child icon
+
+ expandIconSrcPlus: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_expand_plus.gif"),
+ expandIconSrcMinus: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_expand_minus.gif"),
+ expandIconSrcLoading: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_loading.gif"),
+
+
+ iconWidth: 18,
+ iconHeight: 18,
+
+
+ //
+ // tree options
+ //
+
+ showGrid: true,
+ showRootGrid: true,
+
+ actionIsDisabled: function(action) {
+ var _this = this;
+ return dojo.lang.inArray(_this.actionsDisabled, action)
+ },
+
+
+ actions: {
+ ADDCHILD: "ADDCHILD"
+ },
+
+
+ getInfo: function() {
+ var info = {
+ widgetId: this.widgetId,
+ objectId: this.objectId
+ }
+
+ return info;
+ },
+
+ initializeController: function() {
+ if (this.controller != "off") {
+ if (this.controller) {
+ this.controller = dojo.widget.byId(this.controller);
+ }
+ else {
+ // create default controller here
+ dojo.require("dojo.widget.TreeBasicController");
+ this.controller = dojo.widget.createWidget("TreeBasicController",
+ { DNDController: (this.DNDMode ? "create" : ""), dieWithTree: true }
+ );
+
+ }
+ this.controller.listenTree(this); // controller listens to my events
+
+ } else {
+ this.controller = null;
+ }
+ },
+
+ initializeSelector: function() {
+
+ if (this.selector != "off") {
+ if (this.selector) {
+ this.selector = dojo.widget.byId(this.selector);
+ }
+ else {
+ // create default controller here
+ dojo.require("dojo.widget.TreeSelector");
+ this.selector = dojo.widget.createWidget("TreeSelector", {dieWithTree: true});
+ }
+
+ this.selector.listenTree(this);
+
+ } else {
+ this.selector = null;
+ }
+ },
+
+ initialize: function(args, frag){
+
+ var _this = this;
+
+ for(name in this.eventNamesDefault) {
+ if (dojo.lang.isUndefined(this.eventNames[name])) {
+ this.eventNames[name] = this.widgetId+"/"+this.eventNamesDefault[name];
+ }
+ }
+
+ for(var i=0; i<this.actionsDisabled.length; i++) {
+ this.actionsDisabled[i] = this.actionsDisabled[i].toUpperCase();
+ }
+
+ if (this.DNDMode == "off") {
+ this.DNDMode = 0;
+ } else if (this.DNDMode == "between") {
+ this.DNDMode = this.DNDModes.ONTO | this.DNDModes.BETWEEN;
+ } else if (this.DNDMode == "onto") {
+ this.DNDMode = this.DNDModes.ONTO;
+ }
+
+ this.expandLevel = parseInt(this.expandLevel);
+
+ this.initializeSelector();
+ this.initializeController();
+
+ if (this.menu) {
+ this.menu = dojo.widget.byId(this.menu);
+ this.menu.listenTree(this);
+ }
+
+
+ this.containerNode = this.domNode;
+
+ },
+
+
+ postCreate: function() {
+ this.createDOMNode();
+ },
+
+
+ createDOMNode: function() {
+
+ dojo.html.disableSelection(this.domNode);
+
+ for(var i=0; i<this.children.length; i++){
+ this.children[i].parent = this; // root nodes have tree as parent
+
+ var node = this.children[i].createDOMNode(this, 0);
+
+
+ this.domNode.appendChild(node);
+ }
+
+
+ if (!this.showRootGrid){
+ for(var i=0; i<this.children.length; i++){
+ this.children[i].expand();
+ }
+ }
+
+ dojo.event.topic.publish(this.eventNames.treeCreate, { source: this } );
+
+ },
+
+
+ destroy: function() {
+ dojo.event.topic.publish(this.tree.eventNames.treeDestroy, { source: this } );
+
+ return dojo.widget.HtmlWidget.prototype.destroy.apply(this, arguments);
+ },
+
+
+ addChild: function(child, index) {
+
+// dojo.debug("doAddChild "+index+" called for "+child);
+
+ var message = {
+ child: child,
+ index: index,
+ parent: this,
+ // remember if dom was already initialized
+ // initialized => no createDOMNode => no createDOMNode event
+ domNodeInitialized: child.domNodeInitialized
+ }
+
+ this.doAddChild.apply(this, arguments);
+
+ dojo.event.topic.publish(this.tree.eventNames.addChild, message);
+ },
+
+
+ // not called for initial tree building. See createDOMNode instead.
+ // builds child html node if needed
+ // index is "last node" by default
+ /**
+ * FIXME: Is it possible that removeNode from the tree will cause leaks cause of attached events ?
+ * if yes, then only attach events in addChild and detach in remove.. Seems all ok yet.
+ */
+ doAddChild: function(child, index){
+
+ if (dojo.lang.isUndefined(index)) {
+ index = this.children.length;
+ }
+
+ if (!child.isTreeNode){
+ dojo.raise("You can only add TreeNode widgets to a "+this.widgetType+" widget!");
+ return;
+ }
+
+ // usually it is impossible to change "isFolder" state, but if anyone wants to add a child to leaf,
+ // it is possible program-way.
+ if (this.isTreeNode){
+ if (!this.isFolder) { // just became a folder.
+ //dojo.debug("becoming folder "+this);
+ this.setFolder();
+ }
+ }
+
+ // adjust tree
+ var _this = this;
+ dojo.lang.forEach(child.getDescendants(), function(elem) { elem.tree = _this.tree; });
+
+ // fix parent
+ child.parent = this;
+
+
+ // no dynamic loading for those who become parents
+ if (this.isTreeNode) {
+ this.state = this.loadStates.LOADED;
+ }
+
+ // add new child into DOM after it was added into children
+ if (index < this.children.length) { // children[] already has child
+ //dojo.debug("Inserting before "+this.children[index].title);
+ dojo.dom.insertBefore(child.domNode, this.children[index].domNode);
+ } else {
+ this.containerNode.appendChild(child.domNode);
+ if (this.isExpanded && this.isTreeNode) {
+ /* When I add children to hidden containerNode => show container w/ them */
+ this.showChildren();
+ }
+ }
+
+
+ this.children.splice(index, 0, child);
+
+ //dojo.debugShallow(this.children);
+
+
+ // if node exists - adjust its depth, otherwise build it
+ if (child.domNodeInitialized) {
+ var d = this.isTreeNode ? this.depth : -1;
+ child.adjustDepth( d - child.depth + 1 );
+
+
+ // update icons to link generated dom with Tree => updateParentGrid
+ // if I moved child from LastNode inside the tree => need to link it up'n'down =>
+ // updateExpandGridColumn
+ // if I change depth => need to update all grid..
+ child.updateIconTree();
+ } else {
+ //dojo.debug("Create domnode ");
+ child.depth = this.isTreeNode ? this.depth+1 : 0;
+ child.createDOMNode(child.tree, child.depth);
+ }
+
+
+
+ // Use-case:
+ // When previous sibling was created => it was last, no children after it
+ // so it did not create link down => let's add it for all descendants
+ // Use-case:
+ // a child was moved down under the last node so last node should be updated
+ var prevSibling = child.getPreviousSibling();
+ if (child.isLastNode() && prevSibling) {
+ prevSibling.updateExpandGridColumn();
+ }
+
+
+ //dojo.debug("Added child "+child);
+
+
+
+ },
+
+
+
+
+ makeBlankImg: function() {
+ var img = document.createElement('img');
+
+ img.style.width = this.iconWidth + 'px';
+ img.style.height = this.iconHeight + 'px';
+ img.src = this.blankIconSrc;
+ img.style.verticalAlign = 'middle';
+
+ return img;
+ },
+
+
+ updateIconTree: function(){
+
+ //dojo.debug("Update icons for "+this)
+ if (!this.isTree) {
+ this.updateIcons();
+ }
+
+ for(var i=0; i<this.children.length; i++){
+ this.children[i].updateIconTree();
+ }
+
+ },
+
+ toString: function() {
+ return "["+this.widgetType+" ID:"+this.widgetId+"]"
+ },
+
+
+
+
+ /**
+ * Move child to newParent as last child
+ * redraw tree and update icons.
+ *
+ * Called by target, saves source in event.
+ * events are published for BOTH trees AFTER update.
+ */
+ move: function(child, newParent, index) {
+
+ //dojo.debug(child+" "+newParent+" at "+index);
+
+ var oldParent = child.parent;
+ var oldTree = child.tree;
+
+ this.doMove.apply(this, arguments);
+
+ var newParent = child.parent;
+ var newTree = child.tree;
+
+ var message = {
+ oldParent: oldParent, oldTree: oldTree,
+ newParent: newParent, newTree: newTree,
+ child: child
+ };
+
+ /* publish events here about structural changes for both source and target trees */
+ dojo.event.topic.publish(oldTree.eventNames.moveFrom, message);
+ dojo.event.topic.publish(newTree.eventNames.moveTo, message);
+
+ },
+
+
+ /* do actual parent change here. Write remove child first */
+ doMove: function(child, newParent, index) {
+ //var parent = child.parent;
+ child.parent.doRemoveNode(child);
+
+ newParent.doAddChild(child, index);
+ },
+
+
+
+// ================================ removeNode ===================================
+
+ removeNode: function(child) {
+ if (!child.parent) return;
+
+ var oldTree = child.tree;
+ var oldParent = child.parent;
+
+ var removedChild = this.doRemoveNode.apply(this, arguments);
+
+
+ dojo.event.topic.publish(this.tree.eventNames.removeNode,
+ { child: removedChild, tree: oldTree, parent: oldParent }
+ );
+
+ return removedChild;
+ },
+
+
+ doRemoveNode: function(child) {
+ if (!child.parent) return;
+
+ var parent = child.parent;
+
+ var children = parent.children;
+
+
+ var index = child.getParentIndex();
+ if (index < 0) {
+ dojo.raise("Couldn't find node "+child+" for removal");
+ }
+
+
+ children.splice(index,1);
+ dojo.dom.removeNode(child.domNode);
+
+ if (parent.children.length == 0) {
+ parent.containerNode.style.display = "none";
+ }
+
+ // if WAS last node (children.length decreased already) and has prevSibling
+ if (index == children.length && index>0) {
+ children[index-1].updateExpandGridColumn();
+ }
+ // if it WAS first node in WHOLE TREE -
+ // update link up of its former lower neighbour(if exists still)
+ if (parent instanceof dojo.widget.Tree && index == 0 && children.length>0) {
+ children[0].updateExpandGrid();
+ }
+
+ //parent.updateIconTree();
+
+
+ child.parent = child.tree = null;
+
+ return child;
+ },
+
+ markLoading: function() {
+ // no way to mark tree loading
+ },
+
+ unMarkLoading: function() {
+ // no way to show that tree finished loading
+ },
+
+
+ lock: function() {
+ !this.lockLevel && this.markLoading();
+ this.lockLevel++;
+ },
+ unlock: function() {
+ if (!this.lockLevel) {
+ dojo.raise("unlock: not locked");
+ }
+ this.lockLevel--;
+ !this.lockLevel && this.unMarkLoading();
+ },
+
+ isLocked: function() {
+ var node = this;
+ while (true) {
+ if (node.lockLevel) {
+ return true;
+ }
+ if (node instanceof dojo.widget.Tree) {
+ break;
+ }
+ node = node.parent;
+ }
+
+ return false;
+ },
+
+ flushLock: function() {
+ this.lockLevel = 0;
+ this.unMarkLoading();
+ }
+});
+
+
Propchange: tapestry/tapestry4/trunk/framework/src/js/dojo/src/widget/Tree.js
------------------------------------------------------------------------------
svn:eol-style = native