colorpicker.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. // Copyright 2007 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview A color picker component. A color picker can compose several
  16. * instances of goog.ui.ColorPalette.
  17. *
  18. * NOTE: The ColorPicker is in a state of transition towards the common
  19. * component/control/container interface we are developing. If the API changes
  20. * we will do our best to update your code. The end result will be that a
  21. * color picker will compose multiple color palettes. In the simple case this
  22. * will be one grid, but may consistute 3 distinct grids, a custom color picker
  23. * or even a color wheel.
  24. *
  25. */
  26. goog.provide('goog.ui.ColorPicker');
  27. goog.provide('goog.ui.ColorPicker.EventType');
  28. goog.require('goog.ui.ColorPalette');
  29. goog.require('goog.ui.Component');
  30. /**
  31. * Create a new, empty color picker.
  32. *
  33. * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
  34. * @param {goog.ui.ColorPalette=} opt_colorPalette Optional color palette to
  35. * use for this color picker.
  36. * @extends {goog.ui.Component}
  37. * @constructor
  38. * @final
  39. */
  40. goog.ui.ColorPicker = function(opt_domHelper, opt_colorPalette) {
  41. goog.ui.Component.call(this, opt_domHelper);
  42. /**
  43. * The color palette used inside the color picker.
  44. * @type {goog.ui.ColorPalette?}
  45. * @private
  46. */
  47. this.colorPalette_ = opt_colorPalette || null;
  48. this.getHandler().listen(
  49. this, goog.ui.Component.EventType.ACTION, this.onColorPaletteAction_);
  50. };
  51. goog.inherits(goog.ui.ColorPicker, goog.ui.Component);
  52. /**
  53. * Default number of columns in the color palette. May be overridden by calling
  54. * setSize.
  55. *
  56. * @type {number}
  57. */
  58. goog.ui.ColorPicker.DEFAULT_NUM_COLS = 5;
  59. /**
  60. * Constants for event names.
  61. * @enum {string}
  62. */
  63. goog.ui.ColorPicker.EventType = {
  64. CHANGE: 'change'
  65. };
  66. /**
  67. * Whether the component is focusable.
  68. * @type {boolean}
  69. * @private
  70. */
  71. goog.ui.ColorPicker.prototype.focusable_ = true;
  72. /**
  73. * Gets the array of colors displayed by the color picker.
  74. * Modifying this array will lead to unexpected behavior.
  75. * @return {Array<string>?} The colors displayed by this widget.
  76. */
  77. goog.ui.ColorPicker.prototype.getColors = function() {
  78. return this.colorPalette_ ? this.colorPalette_.getColors() : null;
  79. };
  80. /**
  81. * Sets the array of colors to be displayed by the color picker.
  82. * @param {Array<string>} colors The array of colors to be added.
  83. */
  84. goog.ui.ColorPicker.prototype.setColors = function(colors) {
  85. // TODO(user): Don't add colors directly, we should add palettes and the
  86. // picker should support multiple palettes.
  87. if (!this.colorPalette_) {
  88. this.createColorPalette_(colors);
  89. } else {
  90. this.colorPalette_.setColors(colors);
  91. }
  92. };
  93. /**
  94. * Sets the array of colors to be displayed by the color picker.
  95. * @param {Array<string>} colors The array of colors to be added.
  96. * @deprecated Use setColors.
  97. */
  98. goog.ui.ColorPicker.prototype.addColors = function(colors) {
  99. this.setColors(colors);
  100. };
  101. /**
  102. * Sets the size of the palette. Will throw an error after the picker has been
  103. * rendered.
  104. * @param {goog.math.Size|number} size The size of the grid.
  105. */
  106. goog.ui.ColorPicker.prototype.setSize = function(size) {
  107. // TODO(user): The color picker should contain multiple palettes which will
  108. // all be resized at this point.
  109. if (!this.colorPalette_) {
  110. this.createColorPalette_([]);
  111. }
  112. this.colorPalette_.setSize(size);
  113. };
  114. /**
  115. * Gets the number of columns displayed.
  116. * @return {goog.math.Size?} The size of the grid.
  117. */
  118. goog.ui.ColorPicker.prototype.getSize = function() {
  119. return this.colorPalette_ ? this.colorPalette_.getSize() : null;
  120. };
  121. /**
  122. * Sets the number of columns. Will throw an error after the picker has been
  123. * rendered.
  124. * @param {number} n The number of columns.
  125. * @deprecated Use setSize.
  126. */
  127. goog.ui.ColorPicker.prototype.setColumnCount = function(n) {
  128. this.setSize(n);
  129. };
  130. /**
  131. * @return {number} The index of the color selected.
  132. */
  133. goog.ui.ColorPicker.prototype.getSelectedIndex = function() {
  134. return this.colorPalette_ ? this.colorPalette_.getSelectedIndex() : -1;
  135. };
  136. /**
  137. * Sets which color is selected. A value that is out-of-range means that no
  138. * color is selected.
  139. * @param {number} ind The index in this.colors_ of the selected color.
  140. */
  141. goog.ui.ColorPicker.prototype.setSelectedIndex = function(ind) {
  142. if (this.colorPalette_) {
  143. this.colorPalette_.setSelectedIndex(ind);
  144. }
  145. };
  146. /**
  147. * Gets the color that is currently selected in this color picker.
  148. * @return {?string} The hex string of the color selected, or null if no
  149. * color is selected.
  150. */
  151. goog.ui.ColorPicker.prototype.getSelectedColor = function() {
  152. return this.colorPalette_ ? this.colorPalette_.getSelectedColor() : null;
  153. };
  154. /**
  155. * Sets which color is selected. Noop if the color palette hasn't been created
  156. * yet.
  157. * @param {string} color The selected color.
  158. */
  159. goog.ui.ColorPicker.prototype.setSelectedColor = function(color) {
  160. // TODO(user): This will set the color in the first available palette that
  161. // contains it
  162. if (this.colorPalette_) {
  163. this.colorPalette_.setSelectedColor(color);
  164. }
  165. };
  166. /**
  167. * Returns true if the component is focusable, false otherwise. The default
  168. * is true. Focusable components always have a tab index and allocate a key
  169. * handler to handle keyboard events while focused.
  170. * @return {boolean} True iff the component is focusable.
  171. */
  172. goog.ui.ColorPicker.prototype.isFocusable = function() {
  173. return this.focusable_;
  174. };
  175. /**
  176. * Sets whether the component is focusable. The default is true.
  177. * Focusable components always have a tab index and allocate a key handler to
  178. * handle keyboard events while focused.
  179. * @param {boolean} focusable True iff the component is focusable.
  180. */
  181. goog.ui.ColorPicker.prototype.setFocusable = function(focusable) {
  182. this.focusable_ = focusable;
  183. if (this.colorPalette_) {
  184. this.colorPalette_.setSupportedState(
  185. goog.ui.Component.State.FOCUSED, focusable);
  186. }
  187. };
  188. /**
  189. * ColorPickers cannot be used to decorate pre-existing html, since the
  190. * structure they build is fairly complicated.
  191. * @param {Element} element Element to decorate.
  192. * @return {boolean} Returns always false.
  193. * @override
  194. */
  195. goog.ui.ColorPicker.prototype.canDecorate = function(element) {
  196. return false;
  197. };
  198. /**
  199. * Renders the color picker inside the provided element. This will override the
  200. * current content of the element.
  201. * @override
  202. */
  203. goog.ui.ColorPicker.prototype.enterDocument = function() {
  204. goog.ui.ColorPicker.superClass_.enterDocument.call(this);
  205. if (this.colorPalette_) {
  206. this.colorPalette_.render(this.getElement());
  207. }
  208. this.getElement().unselectable = 'on';
  209. };
  210. /** @override */
  211. goog.ui.ColorPicker.prototype.disposeInternal = function() {
  212. goog.ui.ColorPicker.superClass_.disposeInternal.call(this);
  213. if (this.colorPalette_) {
  214. this.colorPalette_.dispose();
  215. this.colorPalette_ = null;
  216. }
  217. };
  218. /**
  219. * Sets the focus to the color picker's palette.
  220. */
  221. goog.ui.ColorPicker.prototype.focus = function() {
  222. if (this.colorPalette_) {
  223. this.colorPalette_.getElement().focus();
  224. }
  225. };
  226. /**
  227. * Handles actions from the color palette.
  228. *
  229. * @param {goog.events.Event} e The event.
  230. * @private
  231. */
  232. goog.ui.ColorPicker.prototype.onColorPaletteAction_ = function(e) {
  233. e.stopPropagation();
  234. this.dispatchEvent(goog.ui.ColorPicker.EventType.CHANGE);
  235. };
  236. /**
  237. * Create a color palette for the color picker.
  238. * @param {Array<string>} colors Array of colors.
  239. * @private
  240. */
  241. goog.ui.ColorPicker.prototype.createColorPalette_ = function(colors) {
  242. // TODO(user): The color picker should eventually just contain a number of
  243. // palettes and manage the interactions between them. This will go away then.
  244. var cp = new goog.ui.ColorPalette(colors, null, this.getDomHelper());
  245. cp.setSize(goog.ui.ColorPicker.DEFAULT_NUM_COLS);
  246. cp.setSupportedState(goog.ui.Component.State.FOCUSED, this.focusable_);
  247. // TODO(user): Use addChild(cp, true) and remove calls to render.
  248. this.addChild(cp);
  249. this.colorPalette_ = cp;
  250. if (this.isInDocument()) {
  251. this.colorPalette_.render(this.getElement());
  252. }
  253. };
  254. /**
  255. * Returns an unrendered instance of the color picker. The colors and layout
  256. * are a simple color grid, the same as the old Gmail color picker.
  257. * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
  258. * @return {!goog.ui.ColorPicker} The unrendered instance.
  259. */
  260. goog.ui.ColorPicker.createSimpleColorGrid = function(opt_domHelper) {
  261. var cp = new goog.ui.ColorPicker(opt_domHelper);
  262. cp.setSize(7);
  263. cp.setColors(goog.ui.ColorPicker.SIMPLE_GRID_COLORS);
  264. return cp;
  265. };
  266. /**
  267. * Array of colors for a 7-cell wide simple-grid color picker.
  268. * @type {Array<string>}
  269. */
  270. goog.ui.ColorPicker.SIMPLE_GRID_COLORS = [
  271. // grays
  272. '#ffffff', '#cccccc', '#c0c0c0', '#999999', '#666666', '#333333', '#000000',
  273. // reds
  274. '#ffcccc', '#ff6666', '#ff0000', '#cc0000', '#990000', '#660000', '#330000',
  275. // oranges
  276. '#ffcc99', '#ff9966', '#ff9900', '#ff6600', '#cc6600', '#993300', '#663300',
  277. // yellows
  278. '#ffff99', '#ffff66', '#ffcc66', '#ffcc33', '#cc9933', '#996633', '#663333',
  279. // olives
  280. '#ffffcc', '#ffff33', '#ffff00', '#ffcc00', '#999900', '#666600', '#333300',
  281. // greens
  282. '#99ff99', '#66ff99', '#33ff33', '#33cc00', '#009900', '#006600', '#003300',
  283. // turquoises
  284. '#99ffff', '#33ffff', '#66cccc', '#00cccc', '#339999', '#336666', '#003333',
  285. // blues
  286. '#ccffff', '#66ffff', '#33ccff', '#3366ff', '#3333ff', '#000099', '#000066',
  287. // purples
  288. '#ccccff', '#9999ff', '#6666cc', '#6633ff', '#6600cc', '#333399', '#330099',
  289. // violets
  290. '#ffccff', '#ff99ff', '#cc66cc', '#cc33cc', '#993399', '#663366', '#330033'
  291. ];