blob: 1be8120149bfc3a14d57dfb132e254ef8905b7c7 [file] [log] [blame]
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview A color picker component. A color picker can compose several
* instances of goog.ui.ColorPalette.
*
* NOTE: The ColorPicker is in a state of transition towards the common
* component/control/container interface we are developing. If the API changes
* we will do our best to update your code. The end result will be that a
* color picker will compose multiple color palettes. In the simple case this
* will be one grid, but may consistute 3 distinct grids, a custom color picker
* or even a color wheel.
*
*/
goog.provide('goog.ui.ColorPicker');
goog.provide('goog.ui.ColorPicker.EventType');
goog.require('goog.ui.ColorPalette');
goog.require('goog.ui.Component');
/**
* Create a new, empty color picker.
*
* @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
* @param {goog.ui.ColorPalette=} opt_colorPalette Optional color palette to
* use for this color picker.
* @extends {goog.ui.Component}
* @constructor
* @final
*/
goog.ui.ColorPicker = function(opt_domHelper, opt_colorPalette) {
goog.ui.Component.call(this, opt_domHelper);
/**
* The color palette used inside the color picker.
* @type {goog.ui.ColorPalette?}
* @private
*/
this.colorPalette_ = opt_colorPalette || null;
this.getHandler().listen(
this, goog.ui.Component.EventType.ACTION, this.onColorPaletteAction_);
};
goog.inherits(goog.ui.ColorPicker, goog.ui.Component);
/**
* Default number of columns in the color palette. May be overridden by calling
* setSize.
*
* @type {number}
*/
goog.ui.ColorPicker.DEFAULT_NUM_COLS = 5;
/**
* Constants for event names.
* @enum {string}
*/
goog.ui.ColorPicker.EventType = {
CHANGE: 'change'
};
/**
* Whether the component is focusable.
* @type {boolean}
* @private
*/
goog.ui.ColorPicker.prototype.focusable_ = true;
/**
* Gets the array of colors displayed by the color picker.
* Modifying this array will lead to unexpected behavior.
* @return {Array<string>?} The colors displayed by this widget.
*/
goog.ui.ColorPicker.prototype.getColors = function() {
return this.colorPalette_ ? this.colorPalette_.getColors() : null;
};
/**
* Sets the array of colors to be displayed by the color picker.
* @param {Array<string>} colors The array of colors to be added.
*/
goog.ui.ColorPicker.prototype.setColors = function(colors) {
// TODO(user): Don't add colors directly, we should add palettes and the
// picker should support multiple palettes.
if (!this.colorPalette_) {
this.createColorPalette_(colors);
} else {
this.colorPalette_.setColors(colors);
}
};
/**
* Sets the array of colors to be displayed by the color picker.
* @param {Array<string>} colors The array of colors to be added.
* @deprecated Use setColors.
*/
goog.ui.ColorPicker.prototype.addColors = function(colors) {
this.setColors(colors);
};
/**
* Sets the size of the palette. Will throw an error after the picker has been
* rendered.
* @param {goog.math.Size|number} size The size of the grid.
*/
goog.ui.ColorPicker.prototype.setSize = function(size) {
// TODO(user): The color picker should contain multiple palettes which will
// all be resized at this point.
if (!this.colorPalette_) {
this.createColorPalette_([]);
}
this.colorPalette_.setSize(size);
};
/**
* Gets the number of columns displayed.
* @return {goog.math.Size?} The size of the grid.
*/
goog.ui.ColorPicker.prototype.getSize = function() {
return this.colorPalette_ ? this.colorPalette_.getSize() : null;
};
/**
* Sets the number of columns. Will throw an error after the picker has been
* rendered.
* @param {number} n The number of columns.
* @deprecated Use setSize.
*/
goog.ui.ColorPicker.prototype.setColumnCount = function(n) {
this.setSize(n);
};
/**
* @return {number} The index of the color selected.
*/
goog.ui.ColorPicker.prototype.getSelectedIndex = function() {
return this.colorPalette_ ? this.colorPalette_.getSelectedIndex() : -1;
};
/**
* Sets which color is selected. A value that is out-of-range means that no
* color is selected.
* @param {number} ind The index in this.colors_ of the selected color.
*/
goog.ui.ColorPicker.prototype.setSelectedIndex = function(ind) {
if (this.colorPalette_) {
this.colorPalette_.setSelectedIndex(ind);
}
};
/**
* Gets the color that is currently selected in this color picker.
* @return {?string} The hex string of the color selected, or null if no
* color is selected.
*/
goog.ui.ColorPicker.prototype.getSelectedColor = function() {
return this.colorPalette_ ? this.colorPalette_.getSelectedColor() : null;
};
/**
* Sets which color is selected. Noop if the color palette hasn't been created
* yet.
* @param {string} color The selected color.
*/
goog.ui.ColorPicker.prototype.setSelectedColor = function(color) {
// TODO(user): This will set the color in the first available palette that
// contains it
if (this.colorPalette_) {
this.colorPalette_.setSelectedColor(color);
}
};
/**
* Returns true if the component is focusable, false otherwise. The default
* is true. Focusable components always have a tab index and allocate a key
* handler to handle keyboard events while focused.
* @return {boolean} True iff the component is focusable.
*/
goog.ui.ColorPicker.prototype.isFocusable = function() {
return this.focusable_;
};
/**
* Sets whether the component is focusable. The default is true.
* Focusable components always have a tab index and allocate a key handler to
* handle keyboard events while focused.
* @param {boolean} focusable True iff the component is focusable.
*/
goog.ui.ColorPicker.prototype.setFocusable = function(focusable) {
this.focusable_ = focusable;
if (this.colorPalette_) {
this.colorPalette_.setSupportedState(goog.ui.Component.State.FOCUSED,
focusable);
}
};
/**
* ColorPickers cannot be used to decorate pre-existing html, since the
* structure they build is fairly complicated.
* @param {Element} element Element to decorate.
* @return {boolean} Returns always false.
* @override
*/
goog.ui.ColorPicker.prototype.canDecorate = function(element) {
return false;
};
/**
* Renders the color picker inside the provided element. This will override the
* current content of the element.
* @override
*/
goog.ui.ColorPicker.prototype.enterDocument = function() {
goog.ui.ColorPicker.superClass_.enterDocument.call(this);
if (this.colorPalette_) {
this.colorPalette_.render(this.getElement());
}
this.getElement().unselectable = 'on';
};
/** @override */
goog.ui.ColorPicker.prototype.disposeInternal = function() {
goog.ui.ColorPicker.superClass_.disposeInternal.call(this);
if (this.colorPalette_) {
this.colorPalette_.dispose();
this.colorPalette_ = null;
}
};
/**
* Sets the focus to the color picker's palette.
*/
goog.ui.ColorPicker.prototype.focus = function() {
if (this.colorPalette_) {
this.colorPalette_.getElement().focus();
}
};
/**
* Handles actions from the color palette.
*
* @param {goog.events.Event} e The event.
* @private
*/
goog.ui.ColorPicker.prototype.onColorPaletteAction_ = function(e) {
e.stopPropagation();
this.dispatchEvent(goog.ui.ColorPicker.EventType.CHANGE);
};
/**
* Create a color palette for the color picker.
* @param {Array<string>} colors Array of colors.
* @private
*/
goog.ui.ColorPicker.prototype.createColorPalette_ = function(colors) {
// TODO(user): The color picker should eventually just contain a number of
// palettes and manage the interactions between them. This will go away then.
var cp = new goog.ui.ColorPalette(colors, null, this.getDomHelper());
cp.setSize(goog.ui.ColorPicker.DEFAULT_NUM_COLS);
cp.setSupportedState(goog.ui.Component.State.FOCUSED, this.focusable_);
// TODO(user): Use addChild(cp, true) and remove calls to render.
this.addChild(cp);
this.colorPalette_ = cp;
if (this.isInDocument()) {
this.colorPalette_.render(this.getElement());
}
};
/**
* Returns an unrendered instance of the color picker. The colors and layout
* are a simple color grid, the same as the old Gmail color picker.
* @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
* @return {!goog.ui.ColorPicker} The unrendered instance.
*/
goog.ui.ColorPicker.createSimpleColorGrid = function(opt_domHelper) {
var cp = new goog.ui.ColorPicker(opt_domHelper);
cp.setSize(7);
cp.setColors(goog.ui.ColorPicker.SIMPLE_GRID_COLORS);
return cp;
};
/**
* Array of colors for a 7-cell wide simple-grid color picker.
* @type {Array<string>}
*/
goog.ui.ColorPicker.SIMPLE_GRID_COLORS = [
// grays
'#ffffff', '#cccccc', '#c0c0c0', '#999999', '#666666', '#333333', '#000000',
// reds
'#ffcccc', '#ff6666', '#ff0000', '#cc0000', '#990000', '#660000', '#330000',
// oranges
'#ffcc99', '#ff9966', '#ff9900', '#ff6600', '#cc6600', '#993300', '#663300',
// yellows
'#ffff99', '#ffff66', '#ffcc66', '#ffcc33', '#cc9933', '#996633', '#663333',
// olives
'#ffffcc', '#ffff33', '#ffff00', '#ffcc00', '#999900', '#666600', '#333300',
// greens
'#99ff99', '#66ff99', '#33ff33', '#33cc00', '#009900', '#006600', '#003300',
// turquoises
'#99ffff', '#33ffff', '#66cccc', '#00cccc', '#339999', '#336666', '#003333',
// blues
'#ccffff', '#66ffff', '#33ccff', '#3366ff', '#3333ff', '#000099', '#000066',
// purples
'#ccccff', '#9999ff', '#6666cc', '#6633ff', '#6600cc', '#333399', '#330099',
// violets
'#ffccff', '#ff99ff', '#cc66cc', '#cc33cc', '#993399', '#663366', '#330033'
];