1/* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26WebInspector.Slider = function() 27{ 28 this._element = document.createElement("div"); 29 this._element.className = "slider"; 30 31 this._knob = this._element.appendChild(document.createElement("img")); 32 33 this._value = 0; 34 this._knobX = 0; 35 this.__maxX = 0; 36 37 this._element.addEventListener("mousedown", this); 38}; 39 40WebInspector.Slider.KnobWidth = 13; 41 42WebInspector.Slider.prototype = { 43 contructor: WebInspector.Slider, 44 __proto__: WebInspector.Object.prototype, 45 46 // Public 47 48 get element() 49 { 50 return this._element; 51 }, 52 53 get value() 54 { 55 return this._value; 56 }, 57 58 set value(value) 59 { 60 value = Math.max(Math.min(value, 1), 0); 61 62 if (value === this._value) 63 return; 64 65 this._value = value; 66 67 this._knobX = Math.round(value * this._maxX); 68 this._knob.style.webkitTransform = "translate3d(" + this._knobX + "px, 0, 0)"; 69 70 if (this.delegate && typeof this.delegate.sliderValueDidChange === "function") 71 this.delegate.sliderValueDidChange(this, value); 72 }, 73 74 // Protected 75 76 handleEvent: function(event) 77 { 78 switch (event.type) { 79 case "mousedown": 80 this._handleMousedown(event); 81 break; 82 case "mousemove": 83 this._handleMousemove(event); 84 break; 85 case "mouseup": 86 this._handleMouseup(event); 87 break; 88 } 89 }, 90 91 // Private 92 93 _handleMousedown: function(event) 94 { 95 if (event.target !== this._knob) 96 this.value = (this._localPointForEvent(event).x - 3) / this._maxX; 97 98 this._startKnobX = this._knobX; 99 this._startMouseX = this._localPointForEvent(event).x; 100 101 this._element.classList.add("dragging"); 102 103 window.addEventListener("mousemove", this, true); 104 window.addEventListener("mouseup", this, true); 105 }, 106 107 _handleMousemove: function(event) 108 { 109 var dx = this._localPointForEvent(event).x - this._startMouseX; 110 var x = Math.max(Math.min(this._startKnobX + dx, this._maxX), 0); 111 112 this.value = x / this._maxX; 113 }, 114 115 _handleMouseup: function(event) 116 { 117 this._element.classList.remove("dragging"); 118 119 window.removeEventListener("mousemove", this, true); 120 window.removeEventListener("mouseup", this, true); 121 }, 122 123 _localPointForEvent: function(event) 124 { 125 // We convert all event coordinates from page coordinates to local coordinates such that the slider 126 // may be transformed using CSS Transforms and interaction works as expected. 127 return window.webkitConvertPointFromPageToNode(this._element, new WebKitPoint(event.pageX, event.pageY)); 128 }, 129 130 get _maxX() 131 { 132 if (this.__maxX == 0 && document.body.contains(this._element)) 133 this.__maxX = this._element.offsetWidth - Math.ceil(WebInspector.Slider.KnobWidth / 2); 134 135 return this.__maxX; 136 } 137}; 138