HISE Logo Forum
    • Categories
    • Register
    • Login

    Problems with persistent panel data?

    Scheduled Pinned Locked Moved Scripting
    10 Posts 3 Posters 80 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • VirtualVirginV
      VirtualVirgin
      last edited by VirtualVirgin

      Some data I am trying to save in the panel for persistence is not reloading on 2nd compile.

      In this snippet, the first compile uses the .setValue() method to save an initialized object to a panel which has been set to
      ("saveInPreset", true)
      Then the .getValue() method is used to retrieve the values inside, which then print to the console to show that the values have been stored properly.

      When the project is compiled again, the same .getValue() method is used and returns the correct values immediately,
      but the values get wiped after a 50 ms timer (.getValue() returns "0.0").

      By the 3rd compile, all Console printouts read "0.0" for the value.

      I'm at a loss as to what is going on.
      Am I getting something totally wrong or is there a bug of some sort?

      HiseSnippet 1068.3ocsV8+ahaCE2okLMx1IsSZ+A3wOAanJnE3ZuoocqTXCs0Vz3V0jNUcxMwA7ZhcjsSuhp3+48ev1yNIPXPUug5EUUgee8SduO98xXovmpTBIxw6sySnHmuzcxbtdV+YDFGM5LjSW2IbVRBUiCnwBtRKIZFeJNgvoQ3.hlfSnRESoobeJloToTE5z4IDkhFfbb1+mMgxoZEj84u+wSIQDvzUhPnqDLe5uwhY5URG+lekEEMjDPeKKtj0cdyHeAuuHRjBvde2VnDh+sjozKHFy1yE8KD0Ljy2518vi76D7pfCOr6I87I8nmDRBCaeTPmN8N9j1GcBoyw8ns5hb9rAALsPNQSz.3cpbpHX9jYhOvyRvULE6lHp4PazDHyYhGJhBLuhFon9yXQAiKpmJDDkwqpt6mUc+Z2yYArkxWUk+JqB7JOJW.c1ac3s+ZvqcY30pD71BjbJAoJYP5ktS7krD8JMF77Eti3ZpLj.8oxPIyVzdKp31W.Vv0GDStkNTBGV5Q8dsZ0DC+qw264cGQhATqGa3KvYVHt92T36TptuHNQvgC0qszrZMZ38fW0kmw+.tvCRPfUTYqahgzYR1JONPQg.pH2QGwGKovIvJsLkZrxqpETPTGvmx3zC7kTnxZnYxKu4un9551fYBhUXeRTzM.IqdXJ2WyD72sLQPTutdCup.bWO6WQhRo0AoFMX3QJ9vYvskWieW6lG17nqalKOjEA0sLU4hLtX+g4olhRj9yrwqF903Td.MDPcPy+iUQ.voACsgyZspFjrqW2rDhTyHQCtm3qMQq13LA0V2rXF+oRXL49MMwXwB3eKLEPnPWE5aJQD8fDIasVLVADZ3RKffuCZLFVypx2zhxWiFEwAZFZQhsa.MGnPsHuEoA7mItaKqBO3uEdzHE06A71IQOJsyRNdFf7hbd+SPw9+vvdv9l8bTN81nXtHCKqJksM2cwEXAK3WHzzK44vXg2FpBC2pNSAWJhhL4YKpyQvi6XcdZ7MTYS7cF7uzPX305SDce7IhkGX6m0+KYnfOhyzWlP4O1XbTNowL8LGUfoZ6ryWTL6zTlQr.ybykkcjEyk2xg9iQlq4EQBBJjHX4olYdGbNidGrELapbU2ynpaglj01bpJ7d9wj26A6bLoadwOJOGzHyJbyUAvRHQPZDQu9lIy96bEPyYs0AlQ9bESOu798ms0UerP7ktiYZ+YaGi6sELBcfOEXLeI+KbGDFB2vWAvJtC+yOMazQ+tH074XmSzRloweQZ7D3Ci7oP14.avb4vYOCMN6bqBNwDJOvd3efmbksKHGFksKThhI9Rw68yH+lOi3ysR.LwsexUU2yMmws2jxGCeUy688WOTa33g6piGsqN1YWcr6t5Xuc0wWsqNd7S6n4iN+oTsHN6ZCBc93A1QTNNC3DfAZYqn+UZmK2Q
      

      If the initial "setValue()" object is replaced with just "1". The value persists through compiles.

      HiseSnippet 986.3ocsV00aiTCE0SRFDYfUhUhe.d6SIPUTRZZZKqPrzzTHBZaDYoBIDZk6L2IwzYrGM1SgnU4I9Cy+.354iLS1ltaIpLODEe88iiO95i8zXoKnTxXhkyqWFADqO0d1RgdwnELtfL4Lh0Q1yD7nHPS8fPoPoiYZtXNMhIf.pGSynQPrhqzfvEnbkJATz9jSWFwTJviXYU+6LIypYCR52e+MmxBXnyklHjqkbW3G4gbco0ou5G3AAmy7fWyCq38fWMwUJFICjIHvqa2kDwbukMGtjYbqlM46YpEDquv9v9G3Nv6Hu98O7jgtrgvI9Le+dG3MXvviOo2AmvFb7Pn6gDqOZrGWKimoYZPQrZbpza4rEx+PjUfq4J9MAfYPOxLrxYlOWF3YVhFqjQK3AdSKXTEAyxzR9sdF+941Wv83qsWxyeV5DzxHpRfV01Dd02.d8pButUf2VfjUEH0HCRO2dlaLORWNiAOeh8DgFh8Y39TUnj4Ko1eU2djD8Pn6DxtENOFGrNhVC61ceJ9S6W53bGKlhnVO0zwfi49zVunH14fdjLLRJvAs1asa60tsyacZtdL8qoEQv77RMU068oX4LEqLhNJ.SnhcGLQLMFvQnW53Dv3kSyTPgYcrXNW.cbiAjYMsYwWcyuCt5VoIyjjTiiXAA2fMYs7SDtZtT7qqKDl0eqUamlHb2r5WyBRfV8LIB+vevUfRF.chh4arXoJbqEae+J5deIBQC+Uln4EIpc6zLYpRGLfnTbgvj5zbUNX0r3L315PjLnMcV4.AJv4szsSkOH4mRQOAvcU9t+Gfn+uvyHM67jfslN2iHWkgkRZrmoClVfEpTboTCWIxgwJm6Mku+VmyP3wxf.Sc1xz4H3gCrkHI7FHde5cF7u1Q7H7l5B1OrtPUYK2r8+JNJESDb8UQf3gDyH4MMFMjbTgtpSUPdVgBhglIbOi5wZZmjh4px+jedxY38FEYBSJVH7RDM2rFrNCtCuKHSapo8Yf5VbSJ027VUbc9Xp6eh9YYp3xh+TUMvXK038EDQoXoWR.Suo9r4Vr7IvMmMDEMBeBEWur5x7cEsa73Dse+2o7Xg6ysmx0tK1NdqsE7h6F+ei27q.el8Xee7jeIXaXe9u7duu6oAJ+jLw7zkKX5Xto43xjvY3SHbADIBriwb.xploUOab2h9lYfvKcv+fe4S1qnAxLYuhIIgL2X4abyNfXtv8iSsfXRj93jl1WXFS68tGKHjP79+235tYptWf820.OXWCbvtF3g6ZfC20.OZWC73Obflmm8sIZYX1wIB4hoiSkwrrFKXX2XZmK4eAZo8bC
      
      d.healeyD 1 Reply Last reply Reply Quote 0
      • d.healeyD
        d.healey @VirtualVirgin
        last edited by

        @VirtualVirgin

        This looks janky if (!Content.getComponent("testPanel")) and triggers an error so I don't think you'll get the behaviour you're expecting.

        8f33753e-8735-40f7-996d-0d8eb08c38b5-image.png

        You should use Content.componentExists().

        Component references should be const

        Libre Wave - Freedom respecting instruments and effects
        My Patreon - HISE tutorials
        YouTube Channel - Public HISE tutorials

        VirtualVirginV 1 Reply Last reply Reply Quote 0
        • VirtualVirginV
          VirtualVirgin @d.healey
          last edited by

          @d-healey said in Problems with persistent panel data?:

          Content.componentExists()

          Works here without any errors.

          d.healeyD 1 Reply Last reply Reply Quote 0
          • d.healeyD
            d.healey @VirtualVirgin
            last edited by

            @VirtualVirgin

            You're saying this works if (!Content.getComponent("testPanel")) ?

            Delete the panel and then hit compile, you should get an error.

            Libre Wave - Freedom respecting instruments and effects
            My Patreon - HISE tutorials
            YouTube Channel - Public HISE tutorials

            VirtualVirginV 1 Reply Last reply Reply Quote 0
            • VirtualVirginV
              VirtualVirgin @d.healey
              last edited by VirtualVirgin

              @d-healey No error. I've done it dozens of times over here.

              Also, I used var because I can't use const.
              That throws errors:

              Screenshot 2025-05-10 at 7.53.34 PM.png

              I can't put the const before the if/else because then I can't reassign it.

              d.healeyD 1 Reply Last reply Reply Quote 0
              • d.healeyD
                d.healey @VirtualVirgin
                last edited by d.healey

                @VirtualVirgin

                No error. I've done it dozens of times over here.

                That's a different line of code (in your image) - you've switched to componentExists() which is correct.

                The whole structure of your script seems a bit weird. If the component doesn't exist then create the component - which guarantees after the first compile it will always exist, so why not just add the component and store it in a const and forget about this weird if statement?

                Components can't be created dynamically in the compiled plugin anyway.

                Libre Wave - Freedom respecting instruments and effects
                My Patreon - HISE tutorials
                YouTube Channel - Public HISE tutorials

                ulrikU VirtualVirginV 2 Replies Last reply Reply Quote 0
                • ulrikU
                  ulrik @d.healey
                  last edited by

                  @d-healey @VirtualVirgin I have also had some problems to make this work smoothly, so I made a test, and this is my findings:

                  • If a panels value is NOT an object, you can't set the panel to store an object if it has "saveInPreset" enabled
                  • The object to save to a panel, should not be undefined or an empty array

                  The order which is working for me is:

                  1. create the object to store (see to it that it contains some values)
                  2. add the object to the panel.setValue(object);
                  3. enable the panels "saveInPreset" property

                  I've made some comments inside the snippet
                  Please correct me if I'm wrong

                  HiseSnippet 1342.3ocsW01aaaCDlJIJnVacXEX+.H7mrGLRsUdoMKHXY4ssrsjJLmErWvPAiDUDWjIMDoSpQQ.1O48OX6NQIK4Fk1.iV+ACSduvm63yw6bPlJjq0pLhi24SGyINet6voRSxAILgjbxgDmuzMfmoEZCWZNjYXj8mNlo07HhiyxeOpkSqUH4e92uceVJSFxq1hPtPIB4+rXjvTsavd+jHM8XVD+bwnZZuwdmDpjGnRUS.DsraexXV30rq3mwP0Vxk7CLcBw4qc2ze8vMhdQju+lauUHaK91wr33AqGswFa8xsGr91rMd4V79aRbV8nHgQkMzvLbMwYk8UQSGlntUZOfKDZwkobbw.xP3jsaerJMBCQbWxAIhznfxTkl.dInJwsrMw8UtmJhDy1udBDEPqrndBzYo4g2xyAuA0gW+ZvqAH4TCRqXgzybGFlIFapjf34ybOQZ3YwL3dpNTr5RV5OV08.kDutWaD6Z9wYvhYVzYq986Qgu5timmPlJjbZ7DYnQnjTVTzPHVf6q.ljm1QD0iFATltdu0qkHl1ozugpQiUR3WG8FfXoAE610qUqLtYRljVp0UbyAkJhprCnhWqTUHKkhdft6LUgSt5HA.hvqEpyZZt4BV5DdmbfTa2Nsuwlaa2iFyR0bTnWqm+7VfPZaM6F94pfLNrpMMhmxlxinJSBO6VglSgejqr5x+lGZnFEEsfdKvqoRkgdImpgbAXiPhJSGi3q53Qhe1ArzzKAFdmxTXGHM.4pVlDg1BRzqmHKvQOpIaRNPKzvnFm6nN3d2Yi.6IXXY1ynyf942Vfjh7KpvNd244Ave2xOTLpsAidVzDqxpvtlt67excPv.pPmaboQLYgefjgIgxnSjQ7XfnDQuAuI.EhPk3iFalRYYYroniv.xdP1jXpxlkorwiSEUFGCLQJvIxCCQp0copqJj2es9dvaHZCEP1t2iR1NX.jEeaaMVu09apvVOZajg.a8m+ElHyiM+OXr0XjkGSVMBsDzYAXdn0L2fxzTggpSTSRiJiA+FiA+4hgb1aM72VqFgmPlPdEn3K5QG3uV+0sg08JZUxfAXYTlJsyr5xd1.JuvEDpUo70FC9yzwjguBLSQrH0Ve0sa2bRUv.j3V3wYD7ZmxCgB+Opnv+APgecTz.LNmqMuWffuiUrJuTsIfA4f4QzCnl+6p1cd2A3pwG.aiHqc2lCqZnFbSsv4Lkg+J7YE.pPdg9thhiaTVguRwWVZPbwaNOrgcjSFcIOqddCUD5LMe6N2GtcW8twEUQ0TTIOQJLuZLW9P8nIEYQn03REnBT0j2X7okMFw5Ih.Z+shav.RNXqO6B4QYneoga59iCe0YUEl8eLEkDxudR9bUPO3BHCgwXdlQfYHmC42.CPYan2x8Pt9Z3Qe.PyXFDmmXA2WT.t8mXLJYN5V0EYFj2TET+9dSms3etXuaEQlj5RS3hqRpMp1g6UuCj85PnOEBFIzhYZY1uBLq9dSw.RbcP+Ns7G2TdkaWN+o453XuFdTt2eAc+8mbBlYSEMIkYlePNbb2BA.cetomvIjjZgYZ8wg+nMc2iEhOyMPXBSZFiK0.FwpiOAXrXl3m5dTbLzsrBfq3d7u8oY.XxunlXfhqSYPMFxCNaxngv+iHjCmtDmeAuuWBYS108K4DC4xn7E+G7oP3fRxAJbPoPxHVXl50g1WEvoteR9N.lj4+CkVtmhqoM7VxH3OA75vv4c08LzeQMb8E0vMVTC2bQMbqE0vWrnF9xOrg3+Q66lXTirkMDxoAGk+rriyQRFv.yYqj+GkIWY9C
                  

                  Hise Develop branch
                  MacOs 15.3.1, Xcode 16.2
                  http://musikboden.se

                  VirtualVirginV 1 Reply Last reply Reply Quote 2
                  • VirtualVirginV
                    VirtualVirgin @ulrik
                    last edited by VirtualVirgin

                    @ulrik Thank you! Yes, that seems to be the issue here!

                    The original initialized data object saved to .setValue() which does not persist:

                    {
                        rowData: [1,2,3],
                        filterData: 
                        {
                    	        "searchValue" : undefined,
                    	        "selectedFilterValues": [],
                    	        "partialExact" : "Partial",
                    	        "minValue" : undefined,
                    	        "maxValue" : undefined
                    	}
                    }
                    

                    A data object which uses "placeholder" to replace the undefined and empty array values which does persist:

                    {
                        rowData: [1,2,3],
                        filterData: 
                        {
                    	        "searchValue" : "placeholder",
                    	        "selectedFilterValues": ["placeholder"],
                    	        "partialExact" : "Partial",
                    	        "minValue" : "placeholder",
                    	        "maxValue" : "placeholder"
                    	}
                    }
                    
                    HiseSnippet 1149.3ocsV8+ahaCE2okLMx1IsSZ+A3wOAanJfR4ZuoocqT5M1VaQiaUS5T0I2DmhWSrirM8Jph+P1+O6On8ev1yNIj.kdWGpKBP3227m7wu2yuQRgOUoDRji2alkPQNet63Yb8j9SHLNZ3QHmW6NlyRRnZb.MVvUZIQy3WgSHbZDNfnI3DpTwTZJ2mhYJ0TpBiUSDu2XlRDMUyDbzgyRHJEM.43r8qMA2oZEj84u+9CIQDv4BQHz4BlO8WXwLcgzQu5mYQQGSBnugEWx5tuZnuf2WDIlBuHa61BkP7ulbE8ThwrsbQ+HQMA470t60YW+tAuHnSm8NnmOoG8fPRXX6cC51s29Gzd2CHc2uGs0dHmOYP.SKji0DMUgbpbnHX1X3chmtAmyTrKinlEsQigcNU7whn.yqnQJp+DVTvnbFVgfnLpfu2Nku+R2SXArExK38uvp.W3QYBzYqkg21KAu1kgWqRvaMPxoDjpjBom6N1WxRzEZL34ybGx0TYHANmJCkTaQa8mUb6K.K35chIWSOVBKV3Q8dsZ0DC+z3a87tgHw.p0iLYPvZVHt9Wk66UTceQbhfCKpWagY0Zzv6NupKVi+NbtGjf.qnxV2DCamYyJ7XGEEBnhbCcHejjBq.qzxoTiUdUsfBh5.9ULNcGeIEXVSZl7rK+CputtMXlfXE1mDEcIjjUObJ22je+1EaDD0Kp2vqJ.2k28yIQSo0AoFMX3QJd+QP8yKwuscyNM28hlYxCYQ.ukpJSjwE6eLO0TThzehMd0vuDWKIB33IlbOYslqXYD.dZvw1PZ8PUC1vkb4hk8IgH0LRzfaI9Za3GkJXkPGy3OFDDStc8lYrZtW5WC4BGBUgyTngAcmDIaoierBR1gBZHDeCbnYxnJn1qxo1FMxiCbPoEI1SJ3fCHw4YGeZ3UIU7dsrJ7fOy8nQJp2c30mf8foj1Dmm.HOOql3ij98eI66N6a1SAc5cOxbdJVJnx1l5ZbNVvB9oBM8LdFLl6cOUggqUmgvkhnHy9rF0YH3gcrNeZ7kTYS7MF7uvPnw1xcKce3tkkal6md9WxPAeHmoOKgxenV7nrjFSm0LTAlps8UeVdeUCMiXAldpKncjEyHm+x8mFe1o2UKq2PMayAbmlXn8.tVQmAPwcK0GX0hvGcs+JE7kq2KUje+vunvdEUymiP+1PCFyIAfO.NBlRPyLzuyQzafK2Surop6QT00P9k01rpL3H5wPY2B14XF.XV9eJ2d2HyJ792vA2sJBlFQzKegqYrjLEqNwh4lLthomUdrkUuEtxi6V3O7PBOV39b2QLs+j0i2sVCdgSi+uwa1LMOycPXHj5U.1JtG+6evAXdZfxuJlZlM8DhVxLIGmNMdLLSnOEPBGxXL09NaYpRSW2JOuYLkGXW7OvSlx14IPFksyUhhI9Rw67SqsMSP8oVI.l31oMq5dhYMtcdEcA+GCCz8Ne+kC08bryl53tapic2TG2aScr2l53K1TG2+i6nYd6eXpVDmVNgPmLZfsMliy.NAxFsYtn+EPi5q7U
                    

                    I had found confusion because I was saving a lot of data in arrays and objects inside the panel.setValue() already which had been working properly for some time, but then needed to add a new object and that flummoxed all of the data persistence in that panel after adding it.

                    When loading, this data gets copied over to panel.data for use and already has a system expecting "undefined" and an empty array for certain conditions, so I think what I can do here for minimum disruption here is to convert the top version to the bottom version format and back (upon saving and restoring respectively) where any values that read "placeholder" will then be converted to "undefined" and the array will just get cleared if it .contains("placeholder"). That way I should be able to keep all of my logic concerning "undefined" and empty arrays intact.

                    1 Reply Last reply Reply Quote 0
                    • VirtualVirginV
                      VirtualVirgin @d.healey
                      last edited by VirtualVirgin

                      @d-healey Sorry my example is not very clear.
                      What I meant is that the

                      if (!Content.getComponent("testPanel"))
                      

                      Works without disruptions.
                      It does throw an error to say that component does not exist, but because the "if" returns a "true", the code then proceeds without any problems.
                      The whole point of the if/else here is just an out-of-context part of factory methods that I use to create components, where the original creation will happen on the first compile and can run any code that doesn't need to be set the 2nd time around (such as properties).

                      That all takes place in an inline function like the following example:

                      // **** FACTORY RANGE SLIDER **** //
                      // "orientation" accepts "horizontal" or "vertical"
                      inline function createFactoryRangeSlider(stringName, xywArray, rangeMinMaxArray, highlightColour, orientation)
                      {
                      	local x1 = xywArray[0];
                      	local y1 = xywArray[1];
                      	local size = xywArray[2];
                      
                      	local isVertical = orientation == "vertical";
                      
                      	local sliderTrackWidth = isVertical ? size * 0.2 : size;
                      	local valueBubbleSpace = isVertical ? size * 0.4 : 0;
                      	local w = isVertical ? size * 0.5 : size;
                      	local h = isVertical ? size : size * 0.3;
                      
                      	local panel;
                      
                      	if (!Content.getComponent(stringName + "RangeSlider"))
                      	{
                      		panel = Content.addPanel(stringName + "RangeSlider", 0, 0);
                      		panel.set("allowCallbacks", "All Callbacks");
                      		panel.setPosition(x1, y1, w, h);
                      		panel.set("saveInPreset", true);
                      
                      		local t = Engine.createTimerObject();
                      		t.setTimerCallback(function[panel, t, rangeMinMaxArray]()
                      		{
                      			panel.setValue(
                      			{
                      				"minValue": rangeMinMaxArray[0],
                      				"maxValue": rangeMinMaxArray[1]
                      			});
                      			t.stopTimer();
                      		});
                      		t.startTimer(50);
                      	}
                      	else
                      	{
                      		panel = Content.getComponent(stringName + "RangeSlider");
                      	}
                      	
                      	panel.data.parentPopup = Content.getComponent(stringName + "Popup");
                      
                      	// Safe to add data here: ensures it's done on every compile
                      	if (!panel.data.rangeSliderTimer)
                      	{
                      		panel.data.rangeSliderTimer = Engine.createTimerObject();
                      
                      		panel.data.rangeSliderTimer.setTimerCallback(function[panel, stringName]()
                      		{
                      			if (panel.data.needsUpdate)
                      			{
                      				panel.data.needsUpdate = false;
                      				var parentPopup = panel.data.parentPopup;
                      				parentPopup.changed();
                      			}
                      		});
                      
                      		panel.data.rangeSliderTimer.startTimer(100);
                      	}
                      
                      	panel.data.rangeMin = rangeMinMaxArray[0];
                      	panel.data.rangeMax = rangeMinMaxArray[1];
                      
                      	panel.setPaintRoutine(function[highlightColour, isVertical, sliderTrackWidth, valueBubbleSpace](g)
                      	{
                      	    var width = this.getWidth();
                      	    var height = this.getHeight();
                      
                      	    var margin = (isVertical ? height : width) * 0.075;
                      	    var trackThickness = (isVertical ? sliderTrackWidth : height) * 0.15;
                      
                      	    var rangeStart = margin;
                      	    var rangeEnd = (isVertical ? height : width) - margin;
                      
                      	    var rangeMin = this.data.rangeMin;
                      	    var rangeMax = this.data.rangeMax;
                      	    var rangeSize = rangeMax - rangeMin;
                      
                      	    function getRatioFromValue(value)
                      	    {
                      	        return (value - rangeMin) / rangeSize;
                      	    }
                      
                      	    var minRatio = getRatioFromValue(this.getValue().minValue);
                      	    var maxRatio = getRatioFromValue(this.getValue().maxValue);
                      
                      	    var minPos = isVertical
                      	        ? rangeStart + (1.0 - minRatio) * (rangeEnd - rangeStart)
                      	        : rangeStart + minRatio * (rangeEnd - rangeStart);
                      
                      	    var maxPos = isVertical
                      	        ? rangeStart + (1.0 - maxRatio) * (rangeEnd - rangeStart)
                      	        : rangeStart + maxRatio * (rangeEnd - rangeStart);
                      
                      	    var centerX = isVertical ? width / 2 : 0;
                      
                      	    // Track
                      	    g.setColour(Colours.grey);
                      	    if (isVertical)
                      	        g.fillRoundedRectangle([centerX - trackThickness / 2, rangeStart, trackThickness, rangeEnd - rangeStart], width * 0.05);
                      	    else
                      	        g.fillRoundedRectangle([rangeStart, height / 2 - trackThickness / 2, rangeEnd - rangeStart, trackThickness], height * 0.075);
                      
                      	    // Highlight range
                      	    g.setColour(highlightColour);
                      	    if (isVertical)
                      	    {
                      	        var y = minPos;
                      	        var h1 = maxPos - minPos;
                      	        g.fillRect([centerX - trackThickness / 2, y, trackThickness, h1]);
                      	    }
                      	    else
                      	    {
                      	        var x = minPos;
                      	        var w1 = maxPos - minPos;
                      	        g.fillRect([x, height / 2 - trackThickness / 2, w1, trackThickness]);
                      	    }
                      
                      	    // Knobs
                      	    var knobRadius = (isVertical ? sliderTrackWidth : height) / 6;
                      	    g.setColour(Colours.white);
                      
                      	    if (isVertical)
                      	    {
                      	        g.fillEllipse([centerX - knobRadius, minPos - knobRadius, knobRadius * 2, knobRadius * 2]);
                      	        g.fillEllipse([centerX - knobRadius, maxPos - knobRadius, knobRadius * 2, knobRadius * 2]);
                      	    }
                      	    else
                      	    {
                      	        g.fillEllipse([minPos - knobRadius, height / 2 - knobRadius, knobRadius * 2, knobRadius * 2]);
                      	        g.fillEllipse([maxPos - knobRadius, height / 2 - knobRadius, knobRadius * 2, knobRadius * 2]);
                      	    }
                      
                      	    // Bubbles
                      	    var bubbleWidth = knobRadius * 5;
                      	    var bubbleHeight = knobRadius * 2.5;
                      	    var bubbleRadius = knobRadius;
                      
                      	    function drawValueBubble(x, y, value)
                      	    {
                      	        g.setColour(Colours.white);
                      	        g.fillRoundedRectangle([x, y, bubbleWidth, bubbleHeight], bubbleRadius);
                      
                      	        g.setColour(Colours.black);
                      	        g.setFont("Oxygen", bubbleHeight * 0.75);
                      	        g.drawAlignedText("" + Math.round(value), [x, y, bubbleWidth, bubbleHeight], "centred");
                      	    }
                      
                      	    if (isVertical)
                      	    {
                      	        drawValueBubble(centerX - knobRadius - bubbleWidth - 4, minPos - bubbleHeight / 2, this.getValue().minValue);
                      	        drawValueBubble(centerX + knobRadius + 4, maxPos - bubbleHeight / 2, this.getValue().maxValue);
                      	    }
                      	    else
                      	    {
                      	        drawValueBubble(minPos - bubbleWidth / 2, height / 2 - knobRadius - bubbleHeight - 4, this.getValue().minValue);
                      	        drawValueBubble(maxPos - bubbleWidth / 2, height / 2 - knobRadius - bubbleHeight - 4, this.getValue().maxValue);
                      	    }
                      	});
                      
                      	panel.setMouseCallback(function[isVertical, stringName](event)
                      	{
                      		var size1 = isVertical ? this.getHeight() : this.getWidth();
                      		var margin = size1 * 0.075;
                      		var rangeStart = margin;
                      		var rangeEnd = size1 - margin;
                      		var rangeMin = this.data.rangeMin;
                      		var rangeMax = this.data.rangeMax;
                      		var rangeSize = rangeMax - rangeMin;
                      
                      		var parentPopup = Content.getComponent(stringName + "Popup");
                      		var dataTableContainer = Content.getComponent(parentPopup.get("parentComponent"));
                      		var columnID = parentPopup.data.columnID;
                      		var filterData = dataTableContainer.data.filterData[columnID];
                      
                      		if (event.clicked)
                      		{
                      			var pos = isVertical ? event.y : event.x;
                      
                      			function getRatioFromValue(value) { return (value - rangeMin) / rangeSize; }
                      
                      			var minRatio = getRatioFromValue(this.getValue().minValue);
                      			var maxRatio = getRatioFromValue(this.getValue().maxValue);
                      
                      			var minPos = isVertical
                      				? rangeStart + (1.0 - minRatio) * (rangeEnd - rangeStart)
                      				: rangeStart + minRatio * (rangeEnd - rangeStart);
                      
                      			var maxPos = isVertical
                      				? rangeStart + (1.0 - maxRatio) * (rangeEnd - rangeStart)
                      				: rangeStart + maxRatio * (rangeEnd - rangeStart);
                      
                      			var distToMin = Math.abs(pos - minPos);
                      			var distToMax = Math.abs(pos - maxPos);
                      			this.data.dragTarget = distToMin < distToMax ? "min" : "max";
                      
                      			this.data.needsUpdate = true; // defer popup.changed
                      		}
                      
                      		if (event.drag)
                      		{
                      			var pos = isVertical ? event.y : event.x;
                      			var relPos = (pos - rangeStart) / (rangeEnd - rangeStart);
                      			var valRatio = isVertical ? (1.0 - relPos) : relPos;
                      			var val = rangeMin + valRatio * rangeSize;
                      			var clampedVal = Math.max(rangeMin, Math.min(rangeMax, val));
                      
                      			if (this.data.dragTarget == "min")
                      			{
                      				var minValue = Math.min(clampedVal, this.getValue().maxValue);
                      				filterData.minValue = minValue;
                      				this.getValue().minValue = minValue;
                      			}
                      			else if (this.data.dragTarget == "max")
                      			{
                      				var maxValue = Math.max(clampedVal, this.getValue().minValue);
                      				filterData.maxValue = maxValue;
                      				this.getValue().maxValue = maxValue;
                      			}
                      
                      			this.data.needsUpdate = true;
                      			this.repaint();
                      		}
                      
                      		if (event.mouseUp)
                      			this.data.dragTarget = "";
                      	});
                      
                      	return panel;
                      }
                      
                      
                      d.healeyD 1 Reply Last reply Reply Quote 0
                      • d.healeyD
                        d.healey @VirtualVirgin
                        last edited by

                        @VirtualVirgin

                        You shouldn't declare a function within a paint routine or mouse callback. I'm pretty sure that will reallocate memory for every redraw of the screen or mouse movement.

                        Functions should be declared in on init, and 99% of the time they should be inline functions.

                        For paint routines and the like for your factory functions, I would declare them outside of the factory function - unless they're really short. This is more of a code cleanliness thing though than a performance issue.

                        		local t = Engine.createTimerObject();
                        		t.setTimerCallback(function[panel, t, rangeMinMaxArray]
                        

                        Why don't you use the panel's built in timer instead of using a separate timer object?

                        Libre Wave - Freedom respecting instruments and effects
                        My Patreon - HISE tutorials
                        YouTube Channel - Public HISE tutorials

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post

                        21

                        Online

                        1.7k

                        Users

                        11.7k

                        Topics

                        101.9k

                        Posts