CableBox component - for your modulator synth needs :)


  • administrators

    As a quick distraction from pushing around bits for HLAC I created a CableBox which is a component with sources and destinations and the ability to create connections between them:

    alt text

    It's 100% Javascript (but you need the latest HISE version because I added the path drawing for it). This is the js file:

    /** CableBox Component
    *    by Christoph Hart
    *
    *    A component with source & destination connections and the ability to create cables
    *    by dragging.
    */
    
    namespace CableBox
    {
    /** Adds a new CableBox. */
        inline function create(name, x, y)
        {
            local widget = Content.addPanel(name, x, y);
        
            Content.setPropertiesFromJSON(name, {
            "width": 180,
            "height": 180,
            "allowCallbacks": "Clicks, Hover & Dragging",
            "saveInPreset": true
            });
        
            widget.data.connections = [];
            widget.data.fadeOutAlpha = 1.0;
            widget.data.fadeOutCable = undefined;
            
            widget.setPaintRoutine(function(g)
            {
                g.fillAll(Colours.black);
            
                for(inputBox in this.data.inputBoxes)
                {
                    g.setColour(inputBox == this.data.currentDragBox ? 0x44FFFFFF : 0x22FFFFFF);
                    g.fillRoundedRectangle(inputBox, 6.0);
                    g.setColour(inputBox == this.data.currentDragBox ? 0xFFFFFFFF : 0x88FFFFFF);
                    g.drawRoundedRectangle(inputBox, 6.0, 1);
                }
            
                for(outputBox in this.data.outputBoxes)
                {
                    g.setColour(0x22FFFFFF);
                    g.fillRoundedRectangle(outputBox, 6.0);
                    g.setColour(0x88FFFFFF);
                    g.drawRoundedRectangle(outputBox, 6.0, 1);
                }
            
                if(this.data.currentDragPosition.length)
                {
                    g.setColour(Colours.white);
                
                    start = getCenter(this.data.currentDragBox);
                    end = this.data.currentDragPosition;
                
                    drawCable(g, start, end);
                }
            
                for(connection in this.data.connections)
                {
                
                    g.setColour(0x88FFFFFF);
                    drawCable(g, getCenter(this.data.inputBoxes[connection[0]]), 
                                getCenter(this.data.outputBoxes[connection[1]]) );
                
                }
                
                if(this.data.fadeOutCable)
                {
                    g.setColour(Colours.withAlpha(Colours.white, this.data.fadeOutAlpha));
                    g.drawPath(this.data.fadeOutCable, -1, 2.0);
                }
            });
        
        
            widget.setMouseCallback(function(event)
            {
                if(event.clicked)
                {
                    for(inputBox in this.data.inputBoxes)
                    {
                        if(contains([event.x, event.y], inputBox))
                        {
                            this.data.currentDragBox = inputBox;
                            this.repaint();
                            return;
                        }
                    }
                    for(outputBox in this.data.outputBoxes)
                    {
                        if(contains([event.x, event.y], outputBox))
                        {
                            var index = this.data.outputBoxes.indexOf(outputBox);
                        
                            for(connection in this.data.connections)
                            {
                                if(connection[1] == index)
                                {
                                    this.data.currentDragBox = this.data.inputBoxes[connection[0]];
                                    this.data.connections.remove(connection);
                                    this.repaint();
                                    this.setValue(this.data.connections);
                                    this.changed();
                                
                                    return;
                                }
                            }
                        }
                    }
                
                    return;
                }
                if(event.mouseUp)
                {
                    for(outputBox in this.data.outputBoxes)
                    {
                        if(contains([event.x, event.y], outputBox))
                        {
                            this.data.currentDragTarget = ouputBox;
                        
                            var start = this.data.inputBoxes.indexOf(this.data.currentDragBox);
                            var end = this.data.outputBoxes.indexOf(outputBox);
                            var connection = [start, end];
                        
                            this.data.connections.insert(-1, connection);
                            this.setValue(this.data.connections);
                            this.changed();
                        }
                    }
                    
                    if(this.data.currentDragBox)
                    {
                        this.data.fadeOutCable = CableBox.createCable(CableBox.getCenter(this.data.currentDragBox), [event.x, event.y]);
                        this.data.currentDragBox = undefined;
                        this.data.currentDragPosition = -1;
                    
                        this.data.fadeOutAlpha = 1.0;
                        this.startTimer(30);
                    
                    }
                
                    
                    this.repaint();
                    return;
                }
                if(event.drag)
                {
                    if(this.data.currentDragBox)
                    {
                        this.data.currentDragPosition = [event.x, event.y];
                        this.repaint();    
                    }
                }
            });
            
            widget.setTimerCallback(function()
            {
                this.data.fadeOutAlpha -= 0.2;
                
                if(this.data.fadeOutAlpha <= 0.0)
                {
                    this.data.fadeOutCable = undefined;
                    this.stopTimer();
                }
                    
                this.repaint();
            });
            
            return widget;
        };
        
        const var INPUT = 1;
        const var OUTPUT = 0;
        
        /** Sets the amount of boxes for the given CableBox. */
        inline function setNumBoxes(box, boxAmount, isInput)
        {
            local boxes = [];
        
            if(isInput)
            {
                box.data.numInputs = boxAmount;
                box.data.inputBoxes = boxes;    
            }
            else
            {
                box.data.numOutputs = boxAmount;
                box.data.outputBoxes = boxes;    
            }
        
            local heightPerBox = (box.getHeight()-20) / boxAmount;
        
            for(i = 0; i < boxAmount; i++)
            {
                local y = i * heightPerBox;
                boxes[i] = [(isInput ? 10 : box.getWidth() - 40), 10 + y, 15, 15];
            }    
        };
    
        /** Call this function in the onControl callback to update the graphics. */
        inline function updateCableBox(box)
        {
            box.data.connections = value;
            box.repaint();
        }
        
    
    
        /** Helper function that checks if the given point is in the rectangle. */
        inline function contains(point, area)
        {
            return point[0] > area[0] && point[0] < area[0] + area[2] &&
                point[1] > area[1] && point[1] < area[1] + area[3];
        }
    
        /** Returns the center point of the rectangle. */
        inline function getCenter(area)
        {
            return [area[0] + 0.5*area[2], area[1] + 0.5*area[3]];
        }
    
    
        /** creates a cable with the given points. */
        inline function createCable(start, end)
        {
            local midY = Math.max(start[1], end[1]) + 30 + 150.0/(end[0]-start[0]);
            local midX = start[0] + (end[0] - start[0])/2;
            
            local p = Content.createPath();
        
        
        
            p.startNewSubPath(start[0], start[1]);
            
            p.quadraticTo(midX, midY, end[0], end[1]);
            
            return p;
        }
        
        /** Draws the cable. */
        inline function drawCable(g, start, end)
        {
            local p = createCable(start, end);
            
            g.drawPath(p, -1, 2.0);
        
            g.setColour(0x88FFFFFF);
            g.fillEllipse([start[0]-2, start[1]-2, 4, 4]);
            g.fillEllipse([end[0]-2, end[1]-2, 4, 4]);
        }
    
        
    };
    

    The most convenient way to use it is to copy it in the %APPDATA%/HISE/scripts folder and include it via

    include("{GLOBAL_SCRIPT_FOLDER}CableBox.js");`
    

    Example Patch

    This is a simple example patch which uses the CableBox with the Global Modulator system to allow dynamic changing of modulation targets - however it's a sine wave so the effect of the filter won't be too drastic 🙂

    HiseSnippet 3931.3oc6bs0baabEFzxHNhNp4Rcyzz1G1QSpGRaJJPcww1JtQxxR1pU2horb5nQSJH3RRLFDfA.TRLYz68s9Z+6zG6acl9Go+CZOmcWr6BRvKRIV1oIpNTD6dNm8remK6tGrp6GF3PihBBMxcyC50gZj68Lq1yOt05src8M15IF49El6XGESCI7ldbuN1QQz5F4xM0SwFxM80MX+7e9hGa6Y66PUMYXbXfqCca21twpV+Kq9mb871ztN8.21ZTuzpa4D3udfWPWPelxzxnisyqraR20FI6ZlFm3ROMxHmk4hKTN7UUp8sqUtb4usVucVXT+21FNcCCo9wGBrajyL2+E9Im4F0ciCBqFaGSAYZ93f58p1J3Te9PenajaMOJ9PEipfNwadKe.JZX6P0Hcy.u5HffTZrdKWu56m.qQFF4dm8Uf7TbP9Vl63V2U1tBr+.VGDEG5vctqkVkudJUtxvTYk5Ykk5kSS8tNW89PypNgtchU8f51GIZcHZGuSiq82+Ty4uycHqaCpxiCNirdP6NA9.5OS96LcsdfaTnaTbPmVjmYGhMhsuFwIgLxotwsHQfOfCkbaRcZTrqucrafOPiuO0A+ZDw1uNItEkXWy0yMtGINf3DRAfg3fibjXzpGZ2roqeyxhA5EQf+zCEOLMHvnXxI1gDmZjGI04xbIUXVmZyVhXA+q3Jj4mmbVIROFeRBinw61sM7MZTAmZkHKWRIjs1c+Wb.mwpzXhe210fnnfFDW+NciiPMd4IWZ68hClHwgR7ksn9zSfd6EzkXWuNYdRHscvI.ZoggkHtwjltmPiXzgfYitddD6vP6dbqfM7nNn65yHCGiFAgsIGcD.NUNtD4nJ.HI98BvugvxiAaHSvN19j5AjSaYGSjZ0o19wkI2Y9YxOSdeH7NBB0oxY6L4+tYxidQqUuNXpI9zSUHAiqoc88b8QM12g6avMYnrJwLTEAh.oL8zdAN1dv7odS.1.ib.DBCCNfK6a6S8zYYkYxSfePtRHCrIf+dGZXrKMZyvf1+wp6sqfGl3mEjbbqYeHox8sJwZnE0sYqX8V.bL3z0gOqAIzhfdlccOW3akHOK.QjaSdhvOcVNCQ1mP2xe+PJL7.4wgcoX6mqqg7YT451w1k0MROhbzwBxRQSCHg6dciWyqSKafnJksFAULzFnpqecZC.nquBNjZCKhKPVq3mGzEhOoERLDEZh.OG4mtY4FPl9077JvypGUtlGf.IyBl7POoBLeXLaAyCyMhqKIsRiXxTHTPpvfyEnhwG8HMFE46QPE66KHVmszRax9g7P3gEVf+PwURjHpmvTAls0eN.j19M8nRgWhbuxVJZuDi9lapM52+98O5PVpSG8nCgYBxOuerCL.YAdxlGA5MwHgTXCEJl3oUZQMj4kaiBYhm6GD4hdYk8n9MiaMzIVh61osbioR2MtrmNJFV3A7sA230o354EFlsKYpPgEaFhENQi5aLvoNKFpPyRD1.Vh.RYX1PU7aZinVbsbtpOLi1BjRIxZ1pBvNRMRGYc7wEKQ3h.GiLXTy4RmyJ.mj9f6yYeNnUUOQy3sivpQrDWosrkHCHOFUES6CtucbqgLxkHygKYI8oOuuzr8krEzrcB5FQSxkqR6Aqr4Gqk5ClqrlJ6fY5o0SMEm7TdIbfxC.5XHkaTgi3RFhf3eoGrhaBiEE7IYb5glX5QRlVIEsgzNXl8BEkMGRi6F5m7H2hl7qKRJnId1H4bvoCtaMWHkxYohH0Fpxrd2qgRqTdjIwMWvnN8wWn6JWdL4OaHkzpQ7nP+IHNbkLEjR8Jy2WmlBUreVFzZJ5.7kOz1qKsP1S79I2oEj+lVufNXpfy98QjtGpunbazyfoy14oibZiQZuny.QNWkdaYZ9NvNjuWxftx3m98uP2zjEZxxPK8RG2ZObQ0+JPi0eWwplWNr0P0ZQGmgVmsSFfav9eKfYJyxQ6B4MMfuTFoT3e5NBrIs8M6T6CdfN9ZgxFmf0+gSzLf+hToGQnc5sMOLZS16.vvbUVQetOc1qqI21tFti1SrNJgEVTtwrLiz3elYNgQDDhGfNUD3kwrj8bdPnM0LSojSq6cnVgt+yivPgAWYVaQ4gfpy8HhU4EVYzaTgS5mijZkBPFp2W+NAB6UPGt4ReGGhwMCii1LkakDmjEa8b7C3epxXvp4.5krRpl4EO.Z2RvAd15pTrpAXITfDs9wXoDpg4SHPNVV6XsA7G24t0qYQMbS8vGqwDHrmjnsv7c8cRb9fHNkJahAvsFoBbEHiip9cauEuDGORI7URSiJuJmHZD2ogAtTuHZ1xcOVFyQIXs7rCJY0bhej+8og7veDIvzKOi0bghysfUQx7oGDjY19.YlEhK4y05m3d26pgE7AoGtiMxcRMXR0E15f6wHpl.kv4NqXAm2TnJuDqRQghj4HKYAo0fttKoG76kw+iG3c9zBeJgCBFJwVxQYsEE.BqRqebXfGwQDtgkepam5X82XtNg1cZ45DMDmFNkIdVHZI8QjHe5RZbBt1xJIDjJDgaIjZ8yndcngpwJFq6jSKpyqhHtMzbr6D.h.7QSlTgIGQcXUXJYKDLFKQrg0TjpsH1j0ErwMxef0M9saeaUqetr06x+1BX+LSHmlJRNqnwYEImUjbt3wh4tXZ+blBvCncXqpIlfAMlnYmZwvrlWGozaqxKeGgtWRSojMu3wJMSna7UewB4wpMKu1h8YHhFYc83qbqcN5zoTZ6V+OCNI6.myqba6y3DdDVXRfV32EAEbQziuxxP164KfsZc7bbxrDqnKE0WAhJoKfGA0Pjij94WPlTlyUGsBKx0X1YNKJBzEg6c3qVuK8zpcqwHHQhhZDfppTxcJ+McsgkeiccNHn.pWkXST9jxRM45eAhNpnBF7CK6dpvw.gwg.zCqhEoQZbhNDShTMzNzcmzmul26vKYAu5Sa3441IhV3nDzYtET3C98kf+cblbHLrKjfMoolGsLSddNtYxmXwZa+J5lgvCx2tSg6YYUBbYXpc5ZTCNYgtmwWQhUmZs0Y2dy8RVjU03F6d3Fau29aL3xx6r2Sd4y1XisgdVXk7mm03HVgp+A5oqs0tCNR6u0Aq+rAGlM2Z6C134ZCB++oH3rrd2GmMKX2PTXYFHj4Ko.VtewAeiGSFwIuPiYxqoIdMB11tF0Kcc5YMUX1jNAE6AfjVd4hqje94IGgUjWx4w4Gck60kBqXZyFSOCqw9rfwCq9Nzhrh9VKwaPVQ+EVl2PCXLv2JIx2dm0qI0eVUGUc+VriJ2Sqo3ddLhebfWcAo1dtM8aCZJ1dHa.3cztqWrKFbBcXAdqho478MOUnF0+DpGLSGNzkhBA9Uw595.XJRFKJ1u.SCkGB843F26GA3YeSaEn1Nn9KaQodCGTSQQBnduEzA0TjLVPseAlFT2In9oXu+H.T6aZqk2B1.UlXI1ALiW79vpEKeOcHD6YrHmf8u6MEx3QaLQ.Cexnkw1M1oUl.BqGDQ9rGfgpOPGRX8MVLIQBu0CJhoi1BVtd39WyBV3cIwk6UQGW3cNVfQJi25QFwDJ8p0PvUWO1EhfWGR1YoOhcqcvC5sCua3jkrnBbOIyBG3an8KyUOJhj4dJdbIYEdIDRlCK2odDiKmfwMvbptPirvwYDCsfhwM1BxzFb7PMx8JG3uaPLcO+BEy+c4mN+4CzSiFY0k3PydXweFrWQUgFJaE3W4iR7yBynysgnQ7cPnNCMVVgXguAX7FvgQqxBHoP+ry.q0YRssftvnnj64SA7hH.dnXYqRptRx.l9kov0w9qfQavUc.souWfXluAD1G.NDE.meoSHd1+1E05pcJsrgsWDUzcdlpdNfnF4lJ88m5lS18mxgmMQiv.+s7ci2qCU9L2cHoEKCoafdSJyudqLydFjoZZzWfKCQ1NCib2PvJPZL6hbMSxE4BunKFtLYblAy1Xj6iMwbLGgWYG1U3wBu5NGykWVBgkAlIj7lI6BMQVpK72Dv96alZSWWRYjZOFWJY7NlrKv3kg0aXxxNco38cM4YWxf4AuJdefoLqj9sDDU7cjARotGd3YX8ifba52LyKvUGzJyqNXV2rwIUc+PNXks9dsLzWvU90s9JtHlyXtQiFPxFkxdcyM+pK6st7xoJuKWU9MlO0KnlsmB.40ajxu8k+NQ2DY+DEAC+R49u9g+R41eZzK70PMyaI60eCbKY+g2U+WNfUJ5JH3Ly606T6Ovc61zD1YDSOee7aJkb753lgzuoK02QqwasJ5srkxYa0+1puz9DJdyP4imh8soMgwQukCns6D.a8xQ2wrZ6ff3Vt9MS6CdqUWuaTbP6Doaj62atvRkS+yI6Aez3t3Wev5rmM9degoyzS8ZSru.hwRzDQ62xSTy0Xoo9sDM9FbMNuYxl1Y55sjOdQbieQD8.al1nb51B1LRXLxjpsmPcbg0qAISG0xRSMYNTid9Mszh.I0T6QTrzIKSmVq+fMEUxbW1QHzkAONLcPn6pOg1vFNs5g8uskWKnxkdCES8SyMTvuG1M4u0.HUOXTqx9an.zD37Td3ehK4tFZ24OagOyx4R8qak7WEinyJ3y4DcVIoS8o6ufOcuoYUXCHrSPylr+J1yDLQM4oTXqICDV9Ze6I64DCi9Ag19QcBhRI3pz1tGD3iftpQHdAy38bzQJc7gcXlcAKFBywL4opcb2PlGI+83mxCbpK0evQo2oulaxOI1O0afS5XMNz7FI5aU21c7naHNKqHyjHIor0wpvqEGa67J8M67bpG0V2y8SWcaviyNL8xQWn45EX+M4lPayu1jq5DLhj7V0oQElnjyLgJ3g1gt19pZ7wlB4MSJQ53NRp95pP7D9kmXGaOo6DccYMsLxcmQbRtGlda4uVLvWFf58MSUF3qPzpznPq92bzUEd8aEJEakpp3MSHS3Rtg0qN3Z9QAWYri4W6H1aa6iarmUdRCItoo78b7yIOFIR8AloeUN+b1iQm8HAuxJ8wT+eV5Cq2DGq5R9WGunPsej49Ad85zJv20QTIedwSTMKdwsi3fOFFCVQs+5+d0uT2p1e0G9xt1dJCO4S9j+4+XzG81ZxO58DWUqO1LU8gdcrmuJudSb+dlpWS7UXn0OFyb+gl88hv+4T2iN0sDv9ovV+99UBujCT7F9TiWE0M6pXLZa6DF70N7PBL036xZAl29r+eOmoM2AelTI40NiXSaHL5qcbvUSmCPmr4XgKLGKdg4XoKLGKeg43dWXN9rKLG2eDbf4rVqabPat+tgw+CXmLfLC
    

Log in to reply
 

5
Online

337
Users

1.0k
Topics

7.0k
Posts

Looks like your connection to Forum was lost, please wait while we try to reconnect.