1 /**
  2  * SlickGrid shape editor and formatter.
  3  *
  4  * @module SlickGridScale
  5  */
  6 define([
  7     'jquery',
  8     'underscore',
  9     'view',
 10     'viewcontroller'
 11 ],
 12 function($, _, DecompositionView, ViewControllers) {
 13   /**
 14    *
 15    * @class Scale
 16    *
 17    * This class represents a range editor defined by the SlickGrid
 18    * project.
 19    * Note, this object is heavily based on classes in slick.editors.js and in
 20    * the documentation that can be found [here]{@link
 21    * https://github.com/mleibman/SlickGrid/wiki/Writing-custom-cell-editors}.
 22    *
 23    * @param {Object} args Arguments passed by SlickGrid.
 24    * @alias module:SlickGridScale.ScaleEditor
 25    */
 26   function ScaleEditor(args) {
 27     /**
 28      * Node containing the jQuery slider
 29      * @type {Node}
 30      */
 31     var $input;
 32     /**
 33      * Node containing the parent div holding the slider info
 34      * @type {Node}
 35      */
 36     var $parentDiv;
 37     /**
 38      * Node containing the textbox for showing the slider value
 39      * @type {Node}
 40      */
 41     var $viewval;
 42     /**
 43      * Initial value of the cell being edited.
 44      * @type {Float}
 45      */
 46     var defaultValue;
 47     var scope = this;
 48 
 49     /* @constructor */
 50     this.init = function() {
 51       var pos = args.grid.getActiveCell();
 52       var metaColPos = args.grid.getCellNodeBox(pos.row, pos.cell + 1);
 53       var barLength = metaColPos.right - metaColPos.left - 14;
 54 
 55       // the controller type determines the ranges
 56       var columnName = args.grid.getColumns()[0].name, min, max, step;
 57       if (columnName === 'Opacity') {
 58         min = 0;
 59         max = 1;
 60         step = 0.05;
 61       }
 62       else {
 63         min = 0.1;
 64         max = 5;
 65         step = 0.1;
 66       }
 67 
 68       $parentDiv = $('<div style="flat:left;position:absolute;height:30px;' +
 69                      'width:' + barLength + 'px;z-index:1000">');
 70       $viewval = $('<input type="text" value="' + args.item.value +
 71                    '" readonly  style="border:0;width:25px;">');
 72       var $sliderDiv = $('<div style="width:' + barLength +
 73                          'px;display:inline-block;' +
 74                          'background-color:rgb(238, 238, 238)">');
 75       $input = $sliderDiv.slider({
 76         range: 'max',
 77         min: min,
 78         max: max,
 79         step: step,
 80         value: args.item.value,
 81         slide: function(event, ui) {
 82           $viewval.val(ui.value);
 83           args.item.value = ui.value;
 84         },
 85         stop: function(event, ui) {
 86           // commit the changes as soon as a new shape is selected
 87           // https://stackoverflow.com/a/35768360/379593
 88           args.grid.getEditorLock().commitCurrentEdit();
 89           args.grid.resetActiveCell();
 90         }
 91       });
 92       // $input.find(".ui-slider-range" ).css('background', '#70caff');
 93       $input.css('background', '#70caff');
 94 
 95       $sliderDiv.appendTo($parentDiv);
 96       $viewval.appendTo(args.container);
 97 
 98       // Calculate the position for the parent div and add it to the view
 99       var container = $(args.container);
100       $parentDiv.css('top', '5px');
101       $parentDiv.css('left', container.width() + 5);
102       $parentDiv.appendTo(args.container);
103     };
104 
105     this.destroy = function() {
106       $parentDiv.remove();
107     };
108 
109     this.focus = function() {
110       $input.focus();
111     };
112 
113     this.focusout = function() {
114       $input.focusout();
115     };
116 
117     this.isValueChanged = function() {
118       return $viewval.val() !== defaultValue;
119     };
120 
121     this.serializeValue = function() {
122       return $viewval.val();
123     };
124 
125     this.loadValue = function(item) {
126       defaultValue = item[args.column.field];
127       $input.val(defaultValue);
128     };
129 
130     this.applyValue = function(item, state) {
131       item[args.column.field] = state;
132     };
133 
134     this.validate = function() {
135       return {valid: true, msg: null};
136     };
137 
138     this.init();
139   }
140 
141   /**
142    *
143    * Function to format colors for the SlickGrid object.
144    *
145    * This formatter is heavily based in the examples found in
146    * slick.formattters.js and is only intended to be used with ScaleFormatter.
147    *
148    * @param {integer} row SlickGrid row.
149    * @param {integer} cell SlickGrid cell.
150    * @param {integer|string|bool} value The value in the row.
151    * @param {object} columnDef SlickGrid column definition.
152    * @param {object} dataContext Data model of the SlickGrid object.
153    *
154    * @return {string} String with a div where the background color is set as
155    * the value that's passed in.
156    *
157    * @alias module:SlickGridColors.ScaleFormatter
158    *
159    */
160   function ScaleFormatter(row, cell, value, columnDef, dataContext) {
161     return "<div style='width:inherit;height:inherit;text-align:center;" +
162            "cursor:pointer;'>" + value + '</div>';
163   }
164 
165   return {'ScaleEditor': ScaleEditor, 'ScaleFormatter': ScaleFormatter};
166 });
167