1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2015, 2016 Synacor, Inc. 5 * 6 * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: https://www.zimbra.com/license 9 * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15 10 * have been added to cover use of software over a computer network and provide for limited attribution 11 * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B. 12 * 13 * Software distributed under the License is distributed on an "AS IS" basis, 14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. 15 * See the License for the specific language governing rights and limitations under the License. 16 * The Original Code is Zimbra Open Source Web Client. 17 * The Initial Developer of the Original Code is Zimbra, Inc. All rights to the Original Code were 18 * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015. 19 * 20 * All portions of the code are Copyright (C) 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2015, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 /** 25 * Creates a button 26 * @constructor 27 * @class 28 * This class ntegrates {@link DwtButton} with a popup {@link DwtColorPicker}. This class is useful to 29 * present a color picker button with an integrated drop-down for choosing from 30 * a color palette. You can use addSelectionListener to register a handler 31 * that will get called when a new color is selected. Inspect "ev.detail" to 32 * retrieve the color (guaranteed to be in #RRGGBB format). 33 * <p> 34 * The button also features a DIV that displays the currently selected color. 35 * Upon clicking that DIV, the color will be cleared (in this event, ev.detail 36 * will be the empty string in your selection listener). Note you must call 37 * showColorDisplay() in order for this DIV to be displayed. 38 * <p> 39 * All constructor arguments are passed forward to the {@link DwtButton} constructor. 40 * 41 * @extends DwtButton 42 * @author Mihai Bazon 43 * 44 * @param {hash} params a hash of parameters 45 * @param {DwtComposite} params.parent the parent widget 46 * @param {constant} params.style the button style 47 * @param {string} params.className the CSS class 48 * @param {constant} params.posStyle the positioning style 49 * @param {string} params.id the ID to use for the control's HTML element 50 * @param {number} params.index the index at which to add this control among parent's children 51 * @param {boolean} params.allowColorInput if <code>true</code>, allow a text field to allow user to input their customized RGB value 52 * @param {boolean} params.noFillLabel if <code>true</code>, do not fill label 53 * 54 * @extends DwtButton 55 */ 56 DwtButtonColorPicker = function(params) { 57 if (arguments.length == 0) { return; } 58 params = Dwt.getParams(arguments, DwtButtonColorPicker.PARAMS); 59 params.actionTiming = DwtButton.ACTION_MOUSEUP; 60 DwtButton.call(this, params); 61 62 // WARNING: we pass boolean instead of a DwtDialog because (1) we don't 63 // have a dialog right now and (2) DwtMenu doesn't seem to make use of 64 // this parameter in other ways than to establish the zIndex. That's 65 // unnecessarily complex :-( 66 var m = new DwtMenu({parent:this, style:DwtMenu.COLOR_PICKER_STYLE}); 67 this.setMenu(m); 68 var cp = new DwtColorPicker(m, null, null, params.noFillLabel, params.allowColorInput); 69 cp.addSelectionListener(new AjxListener(this, this._colorPicked)); 70 this.__colorPicker = cp ; //for xform item _DWT_COLORPICKER_ 71 // no color initially selected 72 this.__color = ""; 73 }; 74 75 DwtButtonColorPicker.PARAMS = ["parent", "style", "className", "posStyle", "id", "index", "noFillLabel", "allowColorInput"]; 76 77 DwtButtonColorPicker.prototype = new DwtButton; 78 DwtButtonColorPicker.prototype.constructor = DwtButtonColorPicker; 79 80 // 81 // Constants 82 // 83 84 DwtButtonColorPicker._RGB_RE = /rgb\(([0-9]{1,3}),\s*([0-9]{1,3}),\s*([0-9]{1,3})\)/; 85 86 DwtButtonColorPicker._hexdigits = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ]; 87 88 // 89 // Data 90 // 91 92 //MOW: DwtButtonColorPicker.prototype.TEMPLATE = "dwt.Widgets#ZButtonColorPicker"; 93 94 // 95 // Public methods 96 // 97 98 /** 99 * Utility function that converts the given integer to its hexadecimal representation. 100 * 101 * @param {number} n the number to convert 102 * @param {number} [pad] the number of digits in the final number (zero-padded if required) 103 * @return {string} the hexadecimal representation 104 */ 105 DwtButtonColorPicker.toHex = 106 function(n, pad) { 107 var digits = []; 108 while (n) { 109 var d = DwtButtonColorPicker._hexdigits[n & 15]; 110 digits.push(d); 111 n = n >> 4; 112 } 113 if (pad != null) { 114 pad -= digits.length; 115 while (pad-- > 0) 116 digits.push('0'); 117 } 118 digits.reverse(); 119 return digits.join(""); 120 }; 121 122 /** 123 * Shows the color display. Call this function to display a DIV that shows the currently 124 * selected color. This DIV also has the ability to clear the current color. 125 * 126 * @param {boolean} disableMouseOver if <code>true</code>, disable the mouse over 127 */ 128 DwtButtonColorPicker.prototype.showColorDisplay = 129 function(disableMouseOver) { 130 if (!this._colorEl) return; 131 132 if (!disableMouseOver) { 133 this._colorEl.onmouseover = DwtButtonColorPicker.__colorDisplay_onMouseOver; 134 this._colorEl.onmouseout = DwtButtonColorPicker.__colorDisplay_onMouseOut; 135 this._colorEl.onmousedown = DwtButtonColorPicker.__colorDisplay_onMouseDown; 136 } 137 }; 138 139 /** 140 * Gets the color. 141 * 142 * @return {string} the currently selected color 143 */ 144 DwtButtonColorPicker.prototype.getColor = 145 function() { 146 return this.__color; 147 }; 148 149 /** 150 * Set the current color. 151 * 152 * @param {string} color the desired color. Pass the empty string "" to clear the selection. 153 */ 154 DwtButtonColorPicker.prototype.setColor = 155 function(color) { 156 // let's make sure we keep it in #RRGGBB format 157 var rgb = color.match(DwtButtonColorPicker._RGB_RE); 158 if (rgb) { 159 color = "#" + 160 DwtButtonColorPicker.toHex(parseInt(rgb[1]), 2) + 161 DwtButtonColorPicker.toHex(parseInt(rgb[2]), 2) + 162 DwtButtonColorPicker.toHex(parseInt(rgb[3]), 2); 163 } 164 this.__color = color; 165 var colorEl = this._colorEl; 166 if (colorEl) 167 colorEl.style.backgroundColor = color; 168 }; 169 170 // 171 // Protected methods 172 // 173 174 DwtButtonColorPicker.prototype._createHtmlFromTemplate = function(templateId, data) { 175 DwtButton.prototype._createHtmlFromTemplate.call(this, templateId, data); 176 177 // set the color display bit inside the title of the widget 178 var displayHtml = AjxTemplate.expand('dwt.Widgets#ZButtonColorDisplay', data); 179 this.setText(displayHtml); 180 181 this._colorEl = document.getElementById(data.id+"_color"); 182 }; 183 184 185 // override "_setMinWidth" since that doesn't apply for this type of button 186 DwtButtonColorPicker.prototype._setMinWidth = function() {} 187 188 189 /// Protected function that is called when a color is chosen from the popup 190 /// DwtColorPicker. Sets the current color to the chosen one and calls the 191 /// DwtButton's selection handlers if any. 192 DwtButtonColorPicker.prototype._colorPicked = function(ev) { 193 194 var color = ev.detail || '#000000'; 195 this.__color = this.__detail = color; 196 var colorEl = this._colorEl; 197 if (colorEl) { 198 colorEl.style.backgroundColor = color; 199 } 200 if (this.isListenerRegistered(DwtEvent.SELECTION)) { 201 var selEv = DwtShell.selectionEvent; 202 // DwtUiEvent.copy(selEv, ev); 203 selEv.item = this; 204 selEv.detail = color; 205 this.notifyListeners(DwtEvent.SELECTION, selEv); 206 } 207 }; 208 209 // 210 // Private methods 211 // 212 213 /// When the color display DIV is hovered, we show a small "X" icon to suggest 214 /// the end user that the selected color can be cleared. 215 DwtButtonColorPicker.prototype.__colorDisplay_onMouseOver = 216 function(ev, div) { 217 if (!this.getEnabled()) 218 return; 219 Dwt.addClass(div, "ImgDisable"); 220 }; 221 222 DwtButtonColorPicker.prototype.__colorDisplay_onMouseOut = 223 function(ev, div) { 224 if (!this.getEnabled()) 225 return; 226 Dwt.delClass(div, "ImgDisable"); 227 }; 228 229 /// Clears the selected color. This function is called when the color display 230 /// DIV is clicked. 231 DwtButtonColorPicker.prototype.__colorDisplay_onMouseDown = 232 function(ev, div) { 233 if (!this.getEnabled()) 234 return; 235 var dwtev = DwtShell.mouseEvent; 236 dwtev.setFromDhtmlEvent(ev); 237 this.__color = this.__detail = div.style.backgroundColor = ""; 238 239 if (this.isListenerRegistered(DwtEvent.SELECTION)) { 240 var selEv = DwtShell.selectionEvent; 241 // DwtUiEvent.copy(selEv, ev); 242 selEv.item = this; 243 selEv.detail = ""; 244 this.notifyListeners(DwtEvent.SELECTION, selEv); 245 } 246 247 dwtev._stopPropagation = true; 248 dwtev._returnValue = false; 249 dwtev.setToDhtmlEvent(ev); 250 return false; 251 }; 252 253 // static event dispatchers 254 255 DwtButtonColorPicker.__colorDisplay_onMouseOver = 256 function(ev) { 257 var obj = DwtControl.getTargetControl(ev); 258 obj.__colorDisplay_onMouseOver(ev, this); 259 }; 260 261 DwtButtonColorPicker.__colorDisplay_onMouseOut = 262 function(ev) { 263 var obj = DwtControl.getTargetControl(ev); 264 obj.__colorDisplay_onMouseOut(ev, this); 265 }; 266 267 DwtButtonColorPicker.__colorDisplay_onMouseDown = 268 function(ev) { 269 var obj = DwtControl.getTargetControl(ev); 270 obj.__colorDisplay_onMouseDown(ev, this); 271 }; 272