[Commits] r1580 - in sandbox/pgiraud/ux/ColorPicker: . examples resources ux ux/widgets ux/widgets/form

commits at geoext.org commits at geoext.org
Sun Dec 13 17:17:13 CET 2009


Author: pgiraud
Date: 2009-12-13 17:17:13 +0100 (Sun, 13 Dec 2009)
New Revision: 1580

Added:
   sandbox/pgiraud/ux/ColorPicker/examples/
   sandbox/pgiraud/ux/ColorPicker/examples/ColorPicker.html
   sandbox/pgiraud/ux/ColorPicker/examples/ColorPicker.js
   sandbox/pgiraud/ux/ColorPicker/resources/
   sandbox/pgiraud/ux/ColorPicker/resources/color-picker.ux.css
   sandbox/pgiraud/ux/ColorPicker/resources/hue.png
   sandbox/pgiraud/ux/ColorPicker/resources/mask.png
   sandbox/pgiraud/ux/ColorPicker/resources/slider-thumb-horizontal.png
   sandbox/pgiraud/ux/ColorPicker/resources/target.gif
   sandbox/pgiraud/ux/ColorPicker/ux/
   sandbox/pgiraud/ux/ColorPicker/ux/widgets/
   sandbox/pgiraud/ux/ColorPicker/ux/widgets/ColorPicker.js
   sandbox/pgiraud/ux/ColorPicker/ux/widgets/form/
   sandbox/pgiraud/ux/ColorPicker/ux/widgets/form/ColorPickerField.js
Log:
ColorPicker Ext ux working with ExtJS 2.2.1

Added: sandbox/pgiraud/ux/ColorPicker/examples/ColorPicker.html
===================================================================
--- sandbox/pgiraud/ux/ColorPicker/examples/ColorPicker.html	                        (rev 0)
+++ sandbox/pgiraud/ux/ColorPicker/examples/ColorPicker.html	2009-12-13 16:17:13 UTC (rev 1580)
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+    <title>Ext ColorPicker User Extension Demo</title>
+
+    <script type="text/javascript" src="http://extjs.cachefly.net/builds/ext-cdn-771.js"></script> 
+    <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" /> 
+    <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/examples/shared/examples.css" />
+
+    <script language="javascript" src="../ux/widgets/ColorPicker.js"></script>
+    <script language="javascript" src="../ux/widgets/form/ColorPickerField.js"></script>
+    <link rel="stylesheet" type="text/css" href="../resources/color-picker.ux.css" />
+
+    <script type="text/javascript" src="ColorPicker.js"></script>
+
+
+    <style type="text/css">
+    .x-panel-body p {
+        margin:10px;
+        font-size:12px;
+    }
+    </style>
+    
+    <style type="text/css">
+        body  {
+          margin: 25px;
+          line-height: 1.25em;
+        }
+        h1  {
+          font-size: 2em;
+        }
+        h2  {
+          font-size: 1.5em;
+        }
+        .support  {
+          overflow: hidden;
+          margin: 1em 0;
+        }
+        .support dt  {
+          font-weight: bold;
+          margin: auto .5em;
+        }
+        .support dt, dd  {
+          font-size: 1em;
+        }
+        dd  {
+          margin-left: 25px;
+        }
+        p  {
+          margin: 1em auto;
+        }
+    </style>
+    
+</head>
+<body>
+  <h1>Ext.ux.ColorPicker</h1>
+  <p>ColorField is a user extension component for the popular Javascript library, <a href='http://extjs.com'>ExtJS</a>.</p>
+  <p>The js is not minified so it is readable. See <a href="ColorPicker.js">ColorPicker.js</a>.</p>
+
+  <h2>Browser Compatibility</h2>
+  <dl class='support'>
+    <dt >IE6+ (Win)</dt>
+      <dd>Needs some position fix.</dd>
+    <dt >Firefox 3 (Linux) </dt>
+    <dt>
+  </dl>  
+  <h2>Live Demo</h2>
+    <div id="standalone">Standalone Ext.ux.ColorPicker</div><br />
+    <div id="colormenu">Picker within an Ext.ux.ColorMenu</div><br />
+    <div id="colorfield">Picker within an Ext.ux.ColorField</div>
+  <h2>Issues</h2>
+  <ul>
+    <li>Ext.ux.ColorPickerField fires the 'valid' event twice when the ColorPicker is opened and user clicks on a color</li>
+  </ul>
+</body>
+</html>

Added: sandbox/pgiraud/ux/ColorPicker/examples/ColorPicker.js
===================================================================
--- sandbox/pgiraud/ux/ColorPicker/examples/ColorPicker.js	                        (rev 0)
+++ sandbox/pgiraud/ux/ColorPicker/examples/ColorPicker.js	2009-12-13 16:17:13 UTC (rev 1580)
@@ -0,0 +1,79 @@
+Ext.onReady(function(){
+
+    Ext.QuickTips.init();
+    
+    var cp = new Ext.ux.ColorPicker();  // initial selected color
+//    cp.render("standalone");
+    
+    cp.on('select', function(picker, color){
+        Ext.example.msg('Color Selected', 'You chosed {0}.', color);
+    });    
+    
+    
+    var panel = new Ext.Panel({
+        items: [cp]
+    });
+    panel.render("standalone");
+
+    var colorMenu = new Ext.ux.ColorPickerMenu({
+        hideOnClick: false
+    });
+    colorMenu.on('select', function(cm, color) {
+        Ext.example.msg('Color Selected', 'You chose {0}.', color);
+    });
+    
+    
+    var button = new Ext.Button({
+        text: 'clik me',
+        menu: colorMenu
+    });
+    button.render("colormenu");
+
+
+    
+    var cpf = new Ext.ux.ColorPickerField({
+        fieldLabel: 'Choose a color',
+        value: '#0A9F50'
+    });
+    cpf.on('valid', function(field) {
+        Ext.example.msg('Color Selected', 'You chose {0}.', field.getValue());
+    });
+
+    var form = new Ext.FormPanel({
+        border: false,
+        width: 300,
+        bodyStyle: {'background': 'transparent'},
+        items: [{
+            xtype: 'fieldset',
+            autoHeight: true,
+            border: false,
+            items: [cpf]
+        }]
+    });
+
+    form.render("colorfield");
+
+});
+
+Ext.example = function(){
+    var msgCt;
+
+    function createBox(t, s){
+        return ['<div class="msg">',
+                '<div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>',
+                '<div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc"><h3>', t, '</h3>', s, '</div></div></div>',
+                '<div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>',
+                '</div>'].join('');
+    }
+    return {
+        msg : function(title, format){
+            if(!msgCt){
+                msgCt = Ext.DomHelper.insertFirst(document.body, {id:'msg-div'}, true);
+            }
+            msgCt.alignTo(document, 't-t');
+            var s = String.format.apply(String, Array.prototype.slice.call(arguments, 1));
+            var m = Ext.DomHelper.append(msgCt, {html:createBox(title, s)}, true);
+            m.slideIn('t').pause(1).ghost("t", {remove:true});
+        }
+    }   
+}();

Added: sandbox/pgiraud/ux/ColorPicker/resources/color-picker.ux.css
===================================================================
--- sandbox/pgiraud/ux/ColorPicker/resources/color-picker.ux.css	                        (rev 0)
+++ sandbox/pgiraud/ux/ColorPicker/resources/color-picker.ux.css	2009-12-13 16:17:13 UTC (rev 1580)
@@ -0,0 +1,72 @@
+.x-color-picker {
+    width: 250px;
+    height: 200px;
+}
+
+.x-cp-rgbpicker {
+    margin: 7px;
+    float: left;
+    cursor: pointer;
+    _margin: 7px 7px 7px 4px;
+}
+
+.x-cp-rgbpicker-inner {
+    position: relative;
+    background-image: url(mask.png);
+    background-repeat: no-repeat;
+    background-color: red;
+    width: 182px;
+    height: 182px;
+    _cursor: hand;
+    _behavior: expression(   /* IE only - transparency with proper handling of relative URLs */
+       this.__src = this.__src ? this.__src : this.currentStyle.backgroundImage.split('"')[1],
+       this.style.backgroundImage = "none",
+       this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=" + this.__src + ")"
+    );
+}
+
+.x-cp-rgbpicker-thumb {
+    position: absolute;
+    width: 15px;
+    height: 15px;
+    background-image: url(target.gif) !important;
+    background-repeat: no-repeat;
+    cursor: pointer;
+    _cursor: hand;
+}
+
+/*
+ * hue as a vertical slider 
+ */
+.x-cp-hueslider {
+    float: left;
+    margin: 7px 0 0 7px;
+    width: 15px;
+}
+
+.x-cp-hueslider .x-slider {
+    background: transparent !important;
+    padding-top:0px;
+}
+
+.x-cp-hueslider .x-slider-end {
+    background: transparent !important;
+    padding-bottom:0px;
+}
+
+.x-cp-hueslider .x-slider-inner {
+    background-image:url(hue.png) !important;
+    background-position: 8px 0;
+    height:183px;
+    cursor: pointer;
+    _cursor: hand;
+}
+
+.x-cp-hueslider .x-slider-thumb {
+    width: 14px;
+    height: 14px;
+    background-image: url(slider-thumb-horizontal.png) !important;
+    background-repeat: no-repeat;
+    background-position: -30px 0;
+    left: -5px;
+}
\ No newline at end of file

Added: sandbox/pgiraud/ux/ColorPicker/resources/hue.png
===================================================================
(Binary files differ)


Property changes on: sandbox/pgiraud/ux/ColorPicker/resources/hue.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: sandbox/pgiraud/ux/ColorPicker/resources/mask.png
===================================================================
(Binary files differ)


Property changes on: sandbox/pgiraud/ux/ColorPicker/resources/mask.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: sandbox/pgiraud/ux/ColorPicker/resources/slider-thumb-horizontal.png
===================================================================
(Binary files differ)


Property changes on: sandbox/pgiraud/ux/ColorPicker/resources/slider-thumb-horizontal.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: sandbox/pgiraud/ux/ColorPicker/resources/target.gif
===================================================================
(Binary files differ)


Property changes on: sandbox/pgiraud/ux/ColorPicker/resources/target.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: sandbox/pgiraud/ux/ColorPicker/ux/widgets/ColorPicker.js
===================================================================
--- sandbox/pgiraud/ux/ColorPicker/ux/widgets/ColorPicker.js	                        (rev 0)
+++ sandbox/pgiraud/ux/ColorPicker/ux/widgets/ColorPicker.js	2009-12-13 16:17:13 UTC (rev 1580)
@@ -0,0 +1,348 @@
+/**
+ * Ext.ux.ColorPicker Extension Class for ExtJs 2.0
+ *
+ * @author Pierre GIRAUD (pierre.giraud at camptocamp.com)
+ *
+ * @class Ext.ux.ColorPicker
+ * @extends Ext.Component
+ * Simple color picker class for choosing colors.  The picker can be rendered to any container.<br />
+ * Here's an example of typical usage:
+ * <pre><code>
+var cp = new Ext.ux.ColorPicker({value:'#993300'});  // initial selected color
+cp.render('my-div');
+
+cp.on('select', function(picker, selColor){
+    // do something with selColor
+});
+</code></pre>
+ * @constructor
+ * Create a new ColorPicker
+ * @param {Object} config The config object
+ *
+ * This work has been initialy inspired by :
+ *  - http://ryanpetrello.com/ext-ux/ColorField/
+ *  - http://ux.theba.hu/colorpicker2/ and http://ux.theba.hu/cp/
+ * 
+ * 
+ * TODO (enhancements)
+ * - add HSV and RGB fields
+ * - get image with 256 pixels dimensions
+ * - allow nicer images for thumbs
+ * - improve performance by comparing values (before moving thumbs for example) or by caching some values
+ */
+Ext.ux.ColorPicker = function(config){
+    Ext.ux.ColorPicker.superclass.constructor.call(this, config);
+    this.addEvents(
+        /**
+         * @event select
+         * Fires when a color is selected
+         * @param {ColorPicker} this
+         * @param {String} color The 6-digit color hex code (without the # symbol)
+         */
+        'select'
+    );
+    
+    if (!this.value) {
+        this.value = this.defaultValue;
+    }
+
+    if (this.handler){
+        this.on("select", this.handler, this.scope, true);
+    }
+};
+Ext.extend(Ext.ux.ColorPicker, Ext.Component, {
+    /**
+     * @cfg {String} itemCls
+     * The CSS class to apply to the containing element (defaults to "x-color-picker")
+     */
+    itemCls : "x-color-picker",
+    /**
+     * @cfg {String} value
+     * The initial color to highlight (should be a valid 6-digit color hex code with the # symbol).  Note that
+     * the hex codes are case-sensitive.
+     */
+    value : null,
+    // private
+    ctype: "Ext.ux.ColorPicker",
+    
+    /**
+     * The rgb picker
+     */
+    rgbPicker: null,
+    
+    /**
+     * The hue picker
+     */
+    hueSlider: null,
+    
+    /**
+     * the hsv value
+     */
+    HSV: {
+        h: 0,
+        s: 0,
+        v: 0
+    },
+    
+    defaultValue: '#FFFFFF',
+
+    // private
+    onRender : function(container, position){
+        var el = document.createElement("div");
+        el.id = this.getId();
+        el.className = this.itemCls;
+        
+        container.dom.insertBefore(el, position);
+        this.createRgbPicker(el);
+        this.createHuePicker(el);
+        
+        this.el = Ext.get(el);
+    },
+
+    // private
+    afterRender : function(){
+        Ext.ux.ColorPicker.superclass.afterRender.call(this);
+
+        if (this.value){
+            var s = this.value;
+            this.value = null;
+            this.setColor(s);
+        }
+        
+        // Initialize RGB Picker DD
+        this.rgbDD = new Ext.dd.DD(this.rgbThumb, 'rgbPicker');
+        this.rgbDD.startDrag = (function() {
+            this.rgbDD.constrainTo(this.rgbInnerEl, - parseInt(this.halfRgbThumb), true);
+        }).createDelegate(this);
+        this.rgbDD.endDrag = this.onDragEnd.createDelegate( this );
+    },
+    
+    /**
+     *
+     * @param {String} rgb color with the '#'
+     */
+    setColor: function(hex) {
+        var hsv = this.rgbToHsv(this.hexToRgb(hex));
+        this.HSV = {
+            h: hsv[0],
+            s: hsv[1],
+            v: hsv[2]
+        }
+        this.updateColor();
+    },
+    
+    /**
+     * Creates the rgb picker and its thumb
+     */
+    createRgbPicker: function(el) {
+        this.rgbPicker = Ext.DomHelper.append(el, {
+            cls: 'x-cp-rgbpicker',
+            cn: {
+                'cls': 'x-cp-rgbpicker-inner'
+            }
+        }, true);
+        
+        this.rgbInnerEl = this.rgbPicker.first();
+                
+        this.rgbThumb = Ext.DomHelper.append(el, {
+            cls: 'x-cp-rgbpicker-thumb'
+        }, true);
+        // we admit that the thumb is square
+        this.halfRgbThumb = this.rgbThumb.getWidth()/2;
+
+        // initialize onclick on the rgb picker
+        this.rgbInnerEl.on( 'mousedown', this.rgbOnMouseDown, this);
+        // initialize start position
+        this.rgbThumb.moveTo(this.rgbPicker.getLeft() - this.halfRgbThumb,
+            this.rgbPicker.getTop() - this.halfRgbThumb);
+    },
+    
+    /**
+     * Creates the hue picker and its thumb
+     */
+    createHuePicker: function(el) {
+        var div = Ext.DomHelper.append(el, {
+            cls: 'x-cp-hueslider'
+        });
+    
+        this.hueSlider = new Ext.Slider({
+            renderTo: div,
+            vertical: true,
+            height: 183,
+            minValue: 0,
+            maxValue: 360
+        });
+        
+        this.hueSlider.on('changecomplete', function(slider, value) {
+            this.HSV.h = value;
+            this.updateColor();
+        }, this /* scope */);
+    },
+    
+    /**
+     *
+     */
+    rgbOnMouseDown: function(e) {
+        if (e.target != this.rgbThumb.dom) {
+            var el = this.rgbInnerEl;
+            var local = el.translatePoints(e.getXY());
+            this.HSV.s = local.left / el.getWidth();
+            var height = el.getHeight();
+            this.HSV.v = (height - local.top) / height;
+            this.updateColor();
+        }
+    },
+    
+    /**
+     * 
+     */
+    onDragEnd: function(e) {
+        var el = this.rgbInnerEl;
+        var local = el.translatePoints(this.rgbThumb.getXY());
+        this.HSV.s = (local.left + this.halfRgbThumb) / el.getWidth();
+        var height = el.getHeight();
+        this.HSV.v = (height - local.top - this.halfRgbThumb) / height;
+        this.updateColor();
+    },
+    
+    /**
+     *
+     * Parameters
+     * animate {Boolean] true to animate
+     * silent {Boolean} if set to true don't fire any event
+     */
+    updateColor: function(animate, silent) {
+        var rgb = this.hsvToRgb(this.HSV.h, this.HSV.s, this.HSV.v);
+        this.hueSlider.setValue(this.HSV.h);
+        this.updateRgbPosition(animate !== false);
+        this.updateRgbPickerBgColor();
+        if (!silent) {
+            this.fireEvent('select', this, '#' + this.rgbToHex(rgb));
+        }
+    },
+    
+    /**
+     *
+     */
+    updateRgbPosition: function(animate) {
+        var el = this.rgbInnerEl;
+        var x = this.HSV.s * el.getWidth();
+        var height = el.getHeight();
+        var y = height - (this.HSV.v * height);
+        this.rgbThumb.moveTo(
+            this.rgbPicker.getLeft() + x - this.halfRgbThumb,
+            this.rgbPicker.getTop() + y - this.halfRgbThumb,
+            animate
+        );
+    },
+    
+    /**
+     *
+     */
+    updateRgbPickerBgColor: function(color) {
+        this.rgbInnerEl.setStyle(
+            {'background-color': '#' + this.rgbToHex(this.hsvToRgb(this.HSV.h, 1, 1))}
+        );
+    },
+    
+    /**
+     * Convert HSV color format to RGB color format
+     * @param {Integer/Array( h, s, v )} h
+     * @param {Integer} s (optional)
+     * @param {Integer} v (optional)
+     * @return {Array}
+     */
+    hsvToRgb: function( h, s, v ) {
+        if( h instanceof Array ) { return this.hsvToRgb.call( this, h[0], h[1], h[2] ); }
+        var r, g, b, i, f, p, q, t;
+        i = Math.floor( ( h / 60 ) % 6 );
+        f = ( h / 60 ) - i;
+        p = v * ( 1 - s );
+        q = v * ( 1 - f * s );
+        t = v * ( 1 - ( 1 - f ) * s );
+        switch(i) {
+            case 0: r=v; g=t; b=p; break;
+            case 1: r=q; g=v; b=p; break;
+            case 2: r=p; g=v; b=t; break;
+            case 3: r=p; g=q; b=v; break;
+            case 4: r=t; g=p; b=v; break;
+            case 5: r=v; g=p; b=q; break;
+        }
+        return [this.realToDec( r ), this.realToDec( g ), this.realToDec( b )];
+    },
+    
+    /**
+     * Convert RGB color format to Hexa color format
+     * @param {Integer/Array( r, g, b )} r
+     * @param {Integer} g (optional)
+     * @param {Integer} b (optional)
+     * @return {String}
+     */
+    rgbToHex: function(r, g, b) {
+        if (r instanceof Array) {
+            return this.rgbToHex.call(this, r[0], r[1], r[2]);
+        }
+
+        var chars = '0123456789ABCDEF';
+
+        return (
+            chars.charAt(parseInt(r/16)) + chars.charAt(parseInt(r%16)) +
+            chars.charAt(parseInt(g/16)) + chars.charAt(parseInt(g%16)) +
+            chars.charAt(parseInt(b/16)) + chars.charAt(parseInt(b%16))
+        );
+    },
+    
+    /**
+     * Convert RGB color format to HSV color format
+     * @param {Integer/Array( r, g, b )} r
+     * @param {Integer} g (optional)
+     * @param {Integer} b (optional)
+     * @return {Array}
+     */
+    rgbToHsv: function( r, g, b ) {
+        if( r instanceof Array ) { return this.rgbToHsv.call( this, r[0], r[1], r[2] ); }
+        r = r / 255;
+        g = g / 255;
+        b = b / 255;
+        var min, max, delta, h, s, v;
+        min = Math.min( Math.min( r, g ), b );
+        max = Math.max( Math.max( r, g ), b );
+        delta = max - min;
+        switch (max) {
+            case min: h = 0; break;
+            case r:   h = 60 * ( g - b ) / delta;
+                      if ( g < b ) { h += 360; }
+                      break;
+            case g:   h = ( 60 * ( b - r ) / delta ) + 120; break;
+            case b:   h = ( 60 * ( r - g ) / delta ) + 240; break;
+        }
+        s = ( max === 0 ) ? 0 : 1 - ( min / max );
+        return [Math.round( h ), s, max];
+    },
+    
+    /**
+     * Convert a float to decimal
+     * @param {Float} n
+     * @return {Integer}
+     */
+    realToDec: function( n ) {
+        return Math.min( 255, Math.round( n * 256 ) );
+    },
+    
+    /**
+     * Convert a hexa string to RGB color format
+     * @param {String} hex
+     * @return {Array}
+     */
+    hexToRgb: function(hex) {
+        var h2d = function(d){ return parseInt(d, 16); }
+        var rgb = [
+            h2d(hex.slice(1, 3)),
+            h2d(hex.slice(3, 5)),
+            h2d(hex.slice(5))
+        ];
+
+        return rgb;
+    }
+});
+Ext.reg('colorpicker', Ext.ux.ColorPicker);

Added: sandbox/pgiraud/ux/ColorPicker/ux/widgets/form/ColorPickerField.js
===================================================================
--- sandbox/pgiraud/ux/ColorPicker/ux/widgets/form/ColorPickerField.js	                        (rev 0)
+++ sandbox/pgiraud/ux/ColorPicker/ux/widgets/form/ColorPickerField.js	2009-12-13 16:17:13 UTC (rev 1580)
@@ -0,0 +1,224 @@
+Ext.namespace('Ext.ux');
+
+/**
+ * Ext.ux.ColorPickerField Extension Class for ExtJs 2.0
+ *
+ * @author Pierre GIRAUD (pierre.giraud at camptocamp.com)
+ *
+ * @class Ext.ux.ColorPickerField
+ * @extends Ext.form.TriggerField
+ * A trigger field that colors its own background based on the input value.  The
+ *     value may be any one of the 16 W3C supported CSS color names
+ *     (http://www.w3.org/TR/css3-color/).  The value can also be an arbitrary
+ *     RGB hex value prefixed by a '#' (e.g. '#FFCC66').
+ *
+ *     Clicking on the trigger opens a ColorPickerMenu.
+ * 
+ * @constructor
+ * Create a new ColorPickerField
+ * @param {Object} config The config object
+ *
+ * Here's an example of typical usage:
+ * <pre><code>
+var cpf = new Ext.ux.ColorPickerField({
+    fieldLabel: 'Choose a color',
+    value: '#0A9F50'
+});
+cpf.on('valid', function(field) {
+    Ext.example.msg('Color Selected', 'You chose {0}.', field.getValue());
+});
+</code></pre>
+ *
+ */
+Ext.ux.ColorPickerField = function(config){
+    Ext.ux.ColorPickerField.superclass.constructor.call(this, config);
+
+    this.on({
+        'change': this.setStyle,
+        'valid': this.setStyle,
+        scope: this
+    });
+};
+Ext.extend(Ext.ux.ColorPickerField, Ext.form.TriggerField, {
+    
+    triggerClass : 'x-form-color-trigger',
+
+    // The Javascript RegExp object to be tested against the field value during validation (See Ext.TextField)
+    regex: /^#[0-9a-f]{6}$/i,
+
+    // The error text to display if the test fails during validation (See Ext.TextField)
+    regexText: 'This is not a valid color',
+
+    /**
+     * Property: cssColors
+     * {Object} Properties are supported CSS color names.  Values are RGB hex
+     *     strings (prefixed with '#').
+     */
+    cssColors: {
+        aqua: "#00FFFF",
+        black: "#000000",
+        blue: "#0000FF",
+        fuchsia: "#FF00FF",
+        gray: "#808080",
+        green: "#008000",
+        lime: "#00FF00",
+        maroon: "#800000",
+        navy: "#000080",
+        olive: "#808000",
+        purple: "#800080",
+        red: "#FF0000",
+        silver: "#C0C0C0",
+        teal: "#008080",
+        white: "#FFFFFF",
+        yellow: "#FFFF00"
+    },
+    
+    /**
+     * Method: isDark
+     * Determine if a color is dark by avaluating brightness according to the
+     *     W3C suggested algorithm for calculating brightness of screen colors.
+     *     http://www.w3.org/WAI/ER/WD-AERT/#color-contrast
+     *
+     * Parameters:
+     * hex - {String} A RGB hex color string (prefixed by '#').
+     *
+     * Returns:
+     * {Boolean} The color is dark.
+     */
+    isDark: function(hex) {
+        var dark = false;
+        if(hex) {
+            // convert hex color values to decimal
+            var r = parseInt(hex.substring(1, 3), 16) / 255;
+            var g = parseInt(hex.substring(3, 5), 16) / 255;
+            var b = parseInt(hex.substring(5, 7), 16) / 255;
+            // use w3C brightness measure
+            var brightness = (r * 0.299) + (g * 0.587) + (b * 0.144);
+            dark = brightness < 0.5;
+        }
+        return dark;
+    },
+    
+    setStyle: function() {
+        var color = this.getValue();
+        var hex = this.colorToHex(color) || "#ffffff";
+        this.getEl().setStyle({
+            "background": hex,
+            "color": this.isDark(hex) ? "#ffffff" : "#000000"
+        });
+    },
+    
+    /**
+     * Method: getHexValue
+     * As a compliment to the field's getValue method, this method always
+     *     returns the RGB hex string representation of the current value
+     *     in the field (given a named color or a hex string).
+     *
+     * Returns:
+     * {String} The RGB hex string for the field's value (prefixed with '#').
+     */
+    getHexValue: function() {
+        return this.colorToHex(this.getValue());
+    },
+    
+    /**
+     * Method: colorToHex
+     * Return the RGB hex representation of a color string.  If a CSS supported
+     *     named color is supplied, the hex representation will be returned.
+     *     If a non-CSS supported named color is supplied, null will be
+     *     returned.  If a RGB hex string is supplied, the same will be
+     *     returned.
+     *
+     * Returns:
+     * {String} A RGB hex color string or null if none found.
+     */
+    colorToHex: function(color) {
+        var hex;
+        if(color.match(this.regex)) {
+            hex = color;
+        } else {
+            hex = this.cssColors[color.toLowerCase()] || null;
+        }
+        return hex;
+    },
+    
+    // private
+    menuListeners : {
+        select: function(m, d){
+            this.setValue(d);
+            this.fireEvent('select', m, d);
+        },
+        show : function(){ // retain focus styling
+            this.onFocus();
+        },
+        hide : function(){
+            this.focus.defer(10, this);
+            var ml = this.menuListeners;
+            this.menu.un("select", ml.select,  this);
+            this.menu.un("show", ml.show,  this);
+            this.menu.un("hide", ml.hide,  this);
+        }
+    },
+    
+    onRender : function(ct, position){
+        Ext.ux.ColorPickerField.superclass.onRender.call(this, ct, position);
+        this.fireEvent('change', this, this.getValue());  
+    },
+    
+    // private
+    // Implements the default empty TriggerField.onTriggerClick function to display the ColorPicker
+    onTriggerClick : function(){
+        if(this.disabled){
+            return;
+        }
+        var value = this.isValid() ? this.getValue() : '#FFFFFF';
+        if(this.menu == null){
+            this.menu = new Ext.ux.ColorPickerMenu({
+                hideOnClick: false,
+                value: value
+            });
+        } else {
+            this.menu.picker.setColor(value);
+        }
+        this.menu.on(Ext.apply({}, this.menuListeners, {
+            scope:this
+        }));
+        this.menu.show(this.el);
+    }
+    
+});
+Ext.reg('ext.ux.colorpicker', Ext.ux.ColorPickerField);
+
+Ext.ux.ColorPickerMenu = function(config){
+    Ext.ux.ColorPickerMenu.superclass.constructor.call(this, config);
+    this.plain = true;
+    var ci = new Ext.ux.ColorItem(config);
+    this.add(ci);
+    /**
+     * The {@link Ext.ux.ColorPicker} instance for this ColorMenu
+     * @type ColorPicker
+     */
+    this.picker = ci.picker;
+    /**
+     * @event select
+     * @param {ColorPicker} palette
+     * @param {String} color
+     */
+    this.relayEvents(ci, ["select"]);
+};
+Ext.extend(Ext.ux.ColorPickerMenu, Ext.menu.Menu, {
+    //private
+    beforeDestroy: function(){
+        this.picker.destroy();
+    }
+});
+
+Ext.ux.ColorItem = function(config){
+    Ext.ux.ColorItem.superclass.constructor.call(this, new Ext.ux.ColorPicker(config), config);
+    this.picker = this.component;
+    this.relayEvents(this.picker, ["select"]);
+    if(this.selectHandler){
+        this.on('select', this.selectHandler, this.scope);
+    }
+};
+Ext.extend(Ext.ux.ColorItem, Ext.menu.Adapter);



More information about the Commits mailing list