Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / src / picker / Color.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * Color picker provides a simple color palette for choosing colors. The picker can be rendered to any container. The
17  * available default to a standard 40-color palette; this can be customized with the {@link #colors} config.
18  *
19  * Typically you will need to implement a handler function to be notified when the user chooses a color from the picker;
20  * you can register the handler using the {@link #select} event, or by implementing the {@link #handler} method.
21  *
22  *     @example
23  *     Ext.create('Ext.picker.Color', {
24  *         value: '993300',  // initial selected color
25  *         renderTo: Ext.getBody(),
26  *         listeners: {
27  *             select: function(picker, selColor) {
28  *                 alert(selColor);
29  *             }
30  *         }
31  *     });
32  */
33 Ext.define('Ext.picker.Color', {
34     extend: 'Ext.Component',
35     requires: 'Ext.XTemplate',
36     alias: 'widget.colorpicker',
37     alternateClassName: 'Ext.ColorPalette',
38
39     /**
40      * @cfg {String} [componentCls='x-color-picker']
41      * The CSS class to apply to the containing element.
42      */
43     componentCls : Ext.baseCSSPrefix + 'color-picker',
44
45     /**
46      * @cfg {String} [selectedCls='x-color-picker-selected']
47      * The CSS class to apply to the selected element
48      */
49     selectedCls: Ext.baseCSSPrefix + 'color-picker-selected',
50
51     /**
52      * @cfg {String} value
53      * The initial color to highlight (should be a valid 6-digit color hex code without the # symbol). Note that the hex
54      * codes are case-sensitive.
55      */
56     value : null,
57
58     /**
59      * @cfg {String} clickEvent
60      * The DOM event that will cause a color to be selected. This can be any valid event name (dblclick, contextmenu).
61      */
62     clickEvent :'click',
63
64     /**
65      * @cfg {Boolean} allowReselect
66      * If set to true then reselecting a color that is already selected fires the {@link #select} event
67      */
68     allowReselect : false,
69
70     /**
71      * @property {String[]} colors
72      * An array of 6-digit color hex code strings (without the # symbol). This array can contain any number of colors,
73      * and each hex code should be unique. The width of the picker is controlled via CSS by adjusting the width property
74      * of the 'x-color-picker' class (or assigning a custom class), so you can balance the number of colors with the
75      * width setting until the box is symmetrical.
76      *
77      * You can override individual colors if needed:
78      *
79      *     var cp = new Ext.picker.Color();
80      *     cp.colors[0] = 'FF0000';  // change the first box to red
81      *
82      * Or you can provide a custom array of your own for complete control:
83      *
84      *     var cp = new Ext.picker.Color();
85      *     cp.colors = ['000000', '993300', '333300'];
86      */
87     colors : [
88         '000000', '993300', '333300', '003300', '003366', '000080', '333399', '333333',
89         '800000', 'FF6600', '808000', '008000', '008080', '0000FF', '666699', '808080',
90         'FF0000', 'FF9900', '99CC00', '339966', '33CCCC', '3366FF', '800080', '969696',
91         'FF00FF', 'FFCC00', 'FFFF00', '00FF00', '00FFFF', '00CCFF', '993366', 'C0C0C0',
92         'FF99CC', 'FFCC99', 'FFFF99', 'CCFFCC', 'CCFFFF', '99CCFF', 'CC99FF', 'FFFFFF'
93     ],
94
95     /**
96      * @cfg {Function} handler
97      * A function that will handle the select event of this picker. The handler is passed the following parameters:
98      *
99      * - `picker` : ColorPicker
100      *
101      *   The {@link Ext.picker.Color picker}.
102      *
103      * - `color` : String
104      *
105      *   The 6-digit color hex code (without the # symbol).
106      */
107
108     /**
109      * @cfg {Object} scope
110      * The scope (`this` reference) in which the `{@link #handler}` function will be called. Defaults to this
111      * Color picker instance.
112      */
113
114     colorRe: /(?:^|\s)color-(.{6})(?:\s|$)/,
115     
116     renderTpl: [
117         '<tpl for="colors">',
118             '<a href="#" class="color-{.}" hidefocus="on">',
119                 '<em><span style="background:#{.}" unselectable="on">&#160;</span></em>',
120             '</a>',
121         '</tpl>'
122     ],
123
124     // private
125     initComponent : function(){
126         var me = this;
127
128         me.callParent(arguments);
129         me.addEvents(
130             /**
131              * @event select
132              * Fires when a color is selected
133              * @param {Ext.picker.Color} this
134              * @param {String} color The 6-digit color hex code (without the # symbol)
135              */
136             'select'
137         );
138
139         if (me.handler) {
140             me.on('select', me.handler, me.scope, true);
141         }
142     },
143
144
145     // private
146     onRender : function(container, position){
147         var me = this,
148             clickEvent = me.clickEvent;
149
150         Ext.apply(me.renderData, {
151             itemCls: me.itemCls,
152             colors: me.colors
153         });
154         me.callParent(arguments);
155
156         me.mon(me.el, clickEvent, me.handleClick, me, {delegate: 'a'});
157         // always stop following the anchors
158         if(clickEvent != 'click'){
159             me.mon(me.el, 'click', Ext.emptyFn, me, {delegate: 'a', stopEvent: true});
160         }
161     },
162
163     // private
164     afterRender : function(){
165         var me = this,
166             value;
167
168         me.callParent(arguments);
169         if (me.value) {
170             value = me.value;
171             me.value = null;
172             me.select(value, true);
173         }
174     },
175
176     // private
177     handleClick : function(event, target){
178         var me = this,
179             color;
180
181         event.stopEvent();
182         if (!me.disabled) {
183             color = target.className.match(me.colorRe)[1];
184             me.select(color.toUpperCase());
185         }
186     },
187
188     /**
189      * Selects the specified color in the picker (fires the {@link #select} event)
190      * @param {String} color A valid 6-digit color hex code (# will be stripped if included)
191      * @param {Boolean} suppressEvent (optional) True to stop the select event from firing. Defaults to false.
192      */
193     select : function(color, suppressEvent){
194
195         var me = this,
196             selectedCls = me.selectedCls,
197             value = me.value,
198             el;
199
200         color = color.replace('#', '');
201         if (!me.rendered) {
202             me.value = color;
203             return;
204         }
205
206
207         if (color != value || me.allowReselect) {
208             el = me.el;
209
210             if (me.value) {
211                 el.down('a.color-' + value).removeCls(selectedCls);
212             }
213             el.down('a.color-' + color).addCls(selectedCls);
214             me.value = color;
215             if (suppressEvent !== true) {
216                 me.fireEvent('select', me, color);
217             }
218         }
219     },
220
221     /**
222      * Get the currently selected color value.
223      * @return {String} value The selected value. Null if nothing is selected.
224      */
225     getValue: function(){
226         return this.value || null;
227     }
228 });
229