From b89a7ee8b956c96a1dcee995ea840feddc5d4b27 Mon Sep 17 00:00:00 2001 From: Pierre Frisch Date: Thu, 22 Dec 2011 07:25:50 -0800 Subject: First commit of Ninja to ninja-internal Signed-off-by: Valerio Virgillito --- .../gradientpicker.reel/gradientpicker.js | 405 +++++++++++++++++++++ 1 file changed, 405 insertions(+) create mode 100644 js/components/gradientpicker.reel/gradientpicker.js (limited to 'js/components/gradientpicker.reel/gradientpicker.js') diff --git a/js/components/gradientpicker.reel/gradientpicker.js b/js/components/gradientpicker.reel/gradientpicker.js new file mode 100644 index 00000000..0940be3c --- /dev/null +++ b/js/components/gradientpicker.reel/gradientpicker.js @@ -0,0 +1,405 @@ +/* +This file contains proprietary software owned by Motorola Mobility, Inc.
+No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ + +//////////////////////////////////////////////////////////////////////// +// +var Montage = require("montage/core/core").Montage, + Component = require("montage/ui/component").Component; +//////////////////////////////////////////////////////////////////////// +//Exporting as ColorWheel +exports.GradientPicker = Montage.create(Component, { + //////////////////////////////////////////////////////////////////// + // + hasTemplate: { + enumerable: true, + value: true + }, + //////////////////////////////////////////////////////////////////// + // + _updating: { + enumerable: false, + value: false + }, + //////////////////////////////////////////////////////////////////// + // + _value: { + enumerable: false, + value: null + }, + //////////////////////////////////////////////////////////////////// + // + value: { + enumerable: true, + get: function() { + return this._value; + }, + set: function(value) { + this._value = value; + } + }, + //////////////////////////////////////////////////////////////////// + // + _mode: { + enumerable: false, + value: 'linear' + }, + //////////////////////////////////////////////////////////////////// + // + mode: { + enumerable: true, + get: function() { + return this._mode; + }, + set: function(value) { + this.application.ninja.colorController.colorPopupManager.hideColorChipPopup(); + // + this._mode = value; + // + this._dispatchEvent('change', false); + } + }, + //////////////////////////////////////////////////////////////////// + // + prepareForDraw: { + enumerable: false, + value: function() { + // + } + }, + //////////////////////////////////////////////////////////////////// + // + willDraw: { + enumerable: false, + value: function() { + //Getting component views from layout + this.element._components = {trackCover: this.element.getElementsByClassName('cp_gp_slider')[0].getElementsByClassName('cover')[0], gradientTrack: this.element.getElementsByClassName('cp_gp_slider')[0].getElementsByClassName('track')[0], stopsContainer: this.element.getElementsByClassName('cp_gp_slider')[0].getElementsByClassName('chips')[0]}; + this.element._trackWidth = parseInt(getComputedStyle(this.element._components.stopsContainer).getPropertyCSSValue('width').cssText); + //TODO: Fix events and remove this hack + this.element._components.trackCover.addEventListener('mouseover', function () { + if (!this._updating) { + this.element._components.trackCover.style.display = 'none'; + } + }.bind(this), true); + // + this.element.getElementsByClassName('cp_gp_linear')[0].addEventListener('change', function (e){ + this.mode = 'linear'; + }.bind(this), true); + // + this.element.getElementsByClassName('cp_gp_radial')[0].addEventListener('change', function (e){ + this.mode = 'radial'; + }.bind(this), true); + } + }, + //////////////////////////////////////////////////////////////////// + // + draw: { + enumerable: false, + value: function() { + // + if (this.mode === 'linear') { + this.element.getElementsByClassName('cp_gp_linear')[0].checked = 'true'; + } else if (this.mode === 'radial') { + this.element.getElementsByClassName('cp_gp_radial')[0].checked = 'true'; + } + // + if (!this.value) { + this.addDefaultStops(); + } else { + //Temp holder + var stops = this.value; + //Adding stops from preset value + for (var i=0; stops[i]; i++) { + this.addStop({color: {mode: stops[i].mode, value: stops[i].value}, percent:stops[i].position}, true); + } + } + } + }, + //////////////////////////////////////////////////////////////////// + // + didDraw: { + enumerable: false, + value: function() { + // + this.element._components.gradientTrack.addEventListener('click', this, false); + + + + + + //////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////// + //TODO: Determing a better way to get screen position + var element = this.element._components.gradientTrack; + this.element._trackX = 0, this.element._trackY = 0; + // + while (element && !isNaN(element.offsetLeft) && !isNaN(element.offsetTop)) { + this.element._trackX += element.offsetLeft - element.scrollLeft; + this.element._trackY += element.offsetTop - element.scrollTop; + element = element.parentNode; + } + //////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////// + + //This is forever changing, not sure why + //console.log(this.element._trackX, this.element._trackY); + + + } + }, + //////////////////////////////////////////////////////////////////// + // + addDefaultStops: { + enumerable: false, + value: function() { + this.addStop({color: {mode: 'rgb', value: {r: 255, g: 255, b: 255, a: 1, css: 'rgb(255, 255, 255)'}}, percent: 0}, true); + this.addStop({color: {mode: 'rgb', value: {r: 0, g: 0, b: 0, a: 1, css: 'rgb(0, 0, 0)'}}, percent: 100}, true); + } + }, + //////////////////////////////////////////////////////////////////// + // + addStop: { + enumerable: false, + value: function(data, silent) { + if (this.application.ninja.colorController.colorPopupManager) { + //Hiding any open popups (of gradient buttons) + this.application.ninja.colorController.colorPopupManager.hideColorChipPopup(); + //Creating stop elements + var stop = document.createElement('div'), + holder = document.createElement('div'), + tooltip = document.createElement('span'), + button = document.createElement('button'); + //Setting up elements + stop.appendChild(tooltip); + stop.appendChild(holder); + holder.appendChild(button); + //Adding events to the stops + stop.addEventListener('mousedown', this, false); + stop.addEventListener('mouseup', this, false); + //Storing refereces to buttons and actual stop container + button.stop = stop; + stop.button = button; + //Adding stop to container + this.element._components.stopsContainer.appendChild(stop); + //Checking for bounds to add stop + if (data.percent >= 0 && data.percent <= 100) { + this.positionStop(stop, data.percent); + button.stopPosition = data.percent; + } + //Creating an instance of input chip + this.application.ninja.colorController.addButton('chip', button); + //Initialing button with color data + button.color(data.color.mode, data.color.value); + //Button popup data + button.props = {side: 'top', align: 'center', nocolor: false, wheel: true, palette: true, gradient: false, image: false, offset: -84, panel: true}; + //Listening for color events from button + button.addEventListener('change', this, false); + //Dispatching event depending on type of mode + if (!silent) { + this._dispatchEvent('change', false); + } else { + this._dispatchEvent('change', true); + } + // + } else { + //Handle Error + } + } + }, + //////////////////////////////////////////////////////////////////// + // + removeStop: { + enumerable: false, + value: function(stop) { + //Removing stops + this.element._components.stopsContainer.removeChild(stop); + //Stopping events related to this current stop + this.removeStopMoving(); + //Resetting stops if less than 2 + var i, buttons = this.element._components.stopsContainer.getElementsByTagName('button'); + if (buttons.length < 2) { + //Removing remaining stops prior to resetting + for (i=0; buttons[i]; i++) { + this.element._components.stopsContainer.removeChild(buttons[i].stop); + } + //Nulling then adding defaults + this.value = null; + this.addDefaultStops(); + this._dispatchEvent('change', false); + } + } + }, + //////////////////////////////////////////////////////////////////// + // + removeStopMoving: { + enumerable: false, + value: function() { + this._updating = false; + this.element._components.trackCover.style.display = 'none'; + this._dispatchEvent('change', false); + document.removeEventListener('mousemove', this, false); + document.removeEventListener('mouseup', this, false); + } + }, + //////////////////////////////////////////////////////////////////// + // + positionStop: { + enumerable: false, + value: function(stop, percent) { + try { + if (percent<0) { + percent = 0; + } else if (percent>100) { + percent = 100; + } + + + + + //////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////// + //TODO: toggling visibility because of a browser bug + stop.style.visibility = 'hidden'; //TODO: To be removed + var adj = (parseInt(getComputedStyle(stop).getPropertyCSSValue('width').cssText)*percent/100)/this.element._trackWidth; + stop.style.left = Math.round(percent-Math.round(adj*100))+'%'; + stop.button.stopPosition = percent; + stop.style.visibility = 'visible'; //TODO: To be removed + //////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////// + + + + + } catch (e) { + //TEMP + } + } + }, + //////////////////////////////////////////////////////////////////// + //TODO: Add color detection canvas to get actual color + handleClick: { + enumerable: false, + value: function(e) { + //Logic to get color from canvas data would go here + var data = {}; + data.mode = 'rgb'; + data.value = {r: 100, g: 100, b: 100, a: 1, css: 'rgb(100, 100, 100)'}; + // + this.addStop({color: data, percent: Math.round(100*(e._event.offsetX/e._event.target.offsetWidth))}); + } + }, + //////////////////////////////////////////////////////////////////// + // + handleMouseup: { + enumerable: false, + value: function(e) { + this.removeStopMoving(); + } + }, + //////////////////////////////////////////////////////////////////// + // + handleMousedown: { + enumerable: false, + value: function(e) { + // + var i, buttons = this.element._components.stopsContainer.getElementsByTagName('button'); + this.currentStop = e._event.target.stop; + //Looping through other stops to swap depths + for (i=0; buttons[i]; i++) { + buttons[i].stop.style.zIndex = 1; + } + //Setting the depth of the current button to the highest + this.currentStop.style.zIndex = buttons.length+1; + //Adding events for actions while moving + document.addEventListener('mousemove', this, false); + document.addEventListener('mouseup', this, false); + } + }, + //////////////////////////////////////////////////////////////////// + // + handleMousemove: { + enumerable: false, + value: function(e) { + // + this._updating = true; + // + this.application.ninja.colorController.colorPopupManager.hideColorChipPopup(); + // + if ((e._event.y+this.hack.y) > this.element._trackY+50 || (e._event.y+this.hack.y) < this.element._trackY) { + this.removeStop(this.currentStop); + } + // + if (this.currentStop.button.stopPosition !== Math.round(((e._event.x+this.hack.x)-(this.element._trackX-23))/this.element._trackWidth*100)) { + this.element._components.trackCover.style.display = 'block'; + } + // + this.positionStop(this.currentStop, Math.round(((e._event.x+this.hack.x)-(this.element._trackX-23))/this.element._trackWidth*100)); + } + }, + //////////////////////////////////////////////////////////////////// + // + handleChange: { + enumerable: false, + value: function(e) { + this.application.ninja.colorController.colorView.colorManager.input = this.application.ninja.colorController.colorView.previousInput; + this._dispatchEvent('change', false); + this.application.ninja.colorController.colorView.colorManager.input = 'chip'; + } + }, + //////////////////////////////////////////////////////////////////// + //Dispatching custom event + _dispatchEvent: { + value: function(type, userInitiated) { + // + var actionEvent = document.createEvent("CustomEvent"), buttons = this.element._components.stopsContainer.getElementsByTagName('button'), stops = [], css, previewCss = '-webkit-gradient(linear, left top, right top'; + //Preventing an events of less than 2 stops since there'll be a reset + if (buttons.length < 2) { + return; + } + //Initializing CSS string + if (this.mode === 'radial') { + css = '-webkit-radial-gradient(center, ellipse cover'; + } else { + css = '-webkit-gradient(linear, left top, right top'; + } + //Creating stops array + for (var i=0; i < buttons.length; i++) { + stops.push({value: buttons[i].colorValue, mode: buttons[i].colorMode, position: buttons[i].stopPosition}); + } + //Sorting array (must be sorted for radial gradients, at least in Chrome + stops.sort(function(a,b){return a.position - b.position}); + //Looping through stops in gradient to create CSS (actual and preview) + for (var i=0; i < stops.length; i++) { + //Addint to CSS String + if (this.mode === 'radial' && stops[i].value) { + css += ', '+stops[i].value.css+' '+stops[i].position+'% '; + //The CSS string for the preview bar is always linear + previewCss += ', color-stop('+stops[i].position+'%,'+stops[i].value.css+')'; + } else if (stops[i].value){ + css += ', color-stop('+stops[i].position+'%,'+stops[i].value.css+')'; + //The CSS string for the preview bar is always linear + previewCss += ', color-stop('+stops[i].position+'%,'+stops[i].value.css+')'; + } else { + // + } + } + //Closing the CSS strings + css += ')'; + previewCss += ')'; + //console.log(previewCss); + //Setting the preview track background + this.element._components.gradientTrack.style.background = previewCss; + //Storing the stops + this.value = stops; + //Initializing and storing data for event + actionEvent.initEvent(type, true, true); + actionEvent.type = type; + actionEvent.wasSetByCode = userInitiated; + actionEvent.gradient = {stops: this.value, mode: this.mode, css: css}; + this.dispatchEvent(actionEvent); + } + } + //////////////////////////////////////////////////////////////////// +}); \ No newline at end of file -- cgit v1.2.3