      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