Source: views/Tool.js

/**
 * @module ToolView
 * @description Represents a view for a tool in the application.
 * @exports ToolView
 */

define([
    'jquery',
    'underscore',
    'backbone',
    'postal',
    '../Configuration',
    '../util/clamp',
    'interactjs'
], function ($, _, Backbone, postal, Configuration, clamp, interact) {
    'use strict';

    
    /**
     * Represents a view for a tool in the application.
     * @class
     * @extends Backbone.View
     */
    var ToolView = Backbone.View.extend({
        contextMenuOpen: false,
        tagName: 'div',
        events: {
            'click #zeroButton': 'zero',
            'click #flameUp': 'incrementFlameHeight',
            'click #flameDown': 'decrementFlameHeight',
        },
        render: function(){
            var power;
            if (this.model.get("bunsenBurner")) {
                power = this.model.get("bunsenBurner").power;
            }

            let vesselName = 'None';
            if (this.model.get('vessel')) {
                vesselName =  this.model.get('vessel').get('name'); 
            }
            
            const button = `<button class="cancelTool btn">Disconnect ${vesselName}</button>`

            this.$el.html(
                `<span class="glyphicon glyphicon-menu-hamburger openToolContextMenu"></span>`+
                this.template({
                cid: this.model.cid,
                flameHeight: this.model.get("flameHeight"),
                weight: this.model.get("weight"),
                upEnabled: this.upEnabled,
                downEnabled: this.downEnabled,
                power: power
            })
        +button);
            var winWidth = $("#vlab").width();
            var scaleFactor = 1;
            if (winWidth < 768) {
                scaleFactor = .5;
            } else if (winWidth >= 768 && winWidth <= 991) {
                scaleFactor = .75;
            } else if (winWidth >= 992 && winWidth <= 1199) {
                scaleFactor = 7 / 8;
            }
            scaleFactor *= Configuration.userScaleFactor;
            var svg = this.$el.find("svg");
            var width = svg.attr("width");
            svg.attr("width", width * scaleFactor);
            var height = svg.attr("height");
            svg.attr("height", height * scaleFactor);
            var cid = this.model.cid;

            this.$el.bind("contextmenu", this.openContextMenu.bind(this));
        },

        openContextMenu: function(event) {
            event.preventDefault();
            event.stopImmediatePropagation();
            //Don't do anything if the dropzone is inactive
            if(this.$el.hasClass('dropzone-inactive')) {
                return 0;
            }
            
            // Otherwise, bring up the context menu...
            $(".removeTool").attr("id", this.model.cid);
            var menu = $(".toolContextMenu");
            menu.css({display: "block", top: event.pageY - menu.height(), left: event.pageX - menu.width()});

            setTimeout(() => {
                $(document).one('click', () => {
                $(".contextMenu").hide();
                this.contextMenuOpen = false;
                });
            }, 400);
        },
        initialize: function(){
            //this.el = $('<div class='+this.model.attributes.vessel.vesselClass+'>');
            this.upEnabled = true;
            this.downEnabled = true;

            // Position for dragging...
            this.x = 0;
            this.y = 0;

            //this.template = require("ejs!" + this.model.attributes.tool.template);
            //this.template = JST[this.model.attributes.tool.template];
            var name = this.model.attributes.tool.template;
            //console.log('name  is ' + name)
            if (name.includes('bunsenBurner')) {
              this.template = require('ejs-loader!../templates/bunsenBurner.ejs');
            }
            else if (name.includes('scale')) {
              this.template = require('ejs-loader!../templates/scale.ejs');
            }
            this.$el.attr('id', this.model.cid);
            this.$el.addClass("tool")
            this.$el.addClass('draggable')

            // Add drag and drop...


            _.bindAll(this, "render");
            this.model.bind('change', this.render);
            this.setDragAndDrop();
            $(window).resize(function(){
                this.render();
            }.bind(this));

        },
        startDrag: function (event) {
            this.el.classList.add('dragged')
            const x = parseFloat(event.target.style.left.replace('px', ''));
            const y = parseFloat(event.target.style.top.replace('px', ''));
            this.x = isNaN(x) ? this.x : x;
            this.y = isNaN(y) ? this.y : y;
            
            this.xMin = 0
            this.xMax = this.$el.parent().width() - this.$el.width();
            this.yMin = 0
            this.yMax = this.$el.parent().height() - this.$el.height();
        },

        endDrag: function (event) {
            this.el.classList.remove('dragged');
        },

        moveDrag: function (event) {
            this.x += event.dx;
            this.y += event.dy;
            
            const xDisplay = clamp(this.x, this.xMin, this.xMax);
            const yDisplay = clamp(this.y, this.yMin, this.yMax);
            
            this.el.style.left = `${xDisplay}px`;
            this.el.style.top = `${yDisplay}px`;
          },
        tap: function (event) {
                const rect = this.el.getBoundingClientRect()
                const x = event.clientX;
                const y = event.clientY;
                if ((Math.abs(x - rect.right) < 30) && 
                            (Math.abs(rect.top-y) < 30)) {
                    console.log('Opening context menu')
                    this.openContextMenu(event);
                } else {
                    console.log('normal tap: Distance from Right, Top = ')
                    console.log(Math.abs(rect.right-x))
                    console.log(Math.abs(y - rect.top))
                }
            },
        
        setDragAndDrop: function(){
            // this.$el.draggable({
            //     opacity: 0.6,
            //     scroll: false,
            //     stack: ".flask",
            //     scope: "workbench",
            //     containment: "parent"
            // });
            // The on hold stuff doesn't work now...
            interact(`#${this.el.id}.draggable`).draggable({
                listeners: {
                    start: this.startDrag.bind(this),
                    end: this.endDrag.bind(this),
                    move: this.moveDrag.bind(this)
                }
            })
            .styleCursor(false)
            .on('tap', this.tap.bind(this));
    
            this.$el.css("position", "absolute");
        },

        zero: function(){
            var channel = postal.channel("logger");
            channel.publish("update", {observable: this.model, arg: this.model.get("weight")});
            this.model.set("weight", 0);
        },
        incrementFlameHeight: function(){
            var bunsenBurner =  this.model.get("bunsenBurner");
            if (Math.floor(bunsenBurner.power * 10) / 10 < 1.6) {
                bunsenBurner.power += .1;
                this.model.set("bunsenBurner", bunsenBurner);
                var channel = postal.channel("logger");
                channel.publish("update", {observable: this.model});
            }
            if (Math.floor(bunsenBurner.power * 10) / 10 >= 1.6) {
                this.upEnabled = false;
            }
            if (!this.downEnabled) {
                this.downEnabled = true;
            }
            this.render();
        },
        decrementFlameHeight:function(){
            var bunsenBurner =  this.model.get("bunsenBurner");
            if (Math.floor(bunsenBurner.power * 10) / 10 > 0) {
                bunsenBurner.power -= .1;
                this.model.set("bunsenBurner", bunsenBurner);
                var channel = postal.channel("logger");
                channel.publish("update", {observable: this.model});
            }
            if (Math.floor(bunsenBurner.power * 10) / 10 <= 0) {
                this.downEnabled = false;
            }
            if (!this.upEnabled) {
                this.upEnabled = true;
            }
            this.render();
        }
    });

    return ToolView;
});