HISE Logo Forum
    • Categories
    • Register
    • Login

    Is there a component to make the collapsible panes in HISE?

    Scheduled Pinned Locked Moved General Questions
    19 Posts 5 Posters 247 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

      Just wondering of there was a pre-built component or method for the collapse toggles like the ones in HISE:

      Screenshot 2025-01-20 at 9.12.34 PM.png

      LindonL 1 Reply Last reply Reply Quote 0
      • LindonL
        Lindon @VirtualVirgin
        last edited by

        @VirtualVirgin nope.

        HISE Development for hire.
        www.channelrobot.com

        VirtualVirginV 1 Reply Last reply Reply Quote 0
        • VirtualVirginV
          VirtualVirgin @Lindon
          last edited by

          @Lindon I figured it would be quite handy if there were. Getting panel visibility from a button is not hard, but the tricky part is getting all of the surrounding windows to change dimensions dynamically in relation to one another.

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

            @VirtualVirgin broadcasters are perfect for this

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

            ustkU 1 Reply Last reply Reply Quote 1
            • ustkU
              ustk @d.healey
              last edited by

              @d-healey Do you mean, by making a chain reaction by listening to surrounding components state or something similar?

              Can't help pressing F5 in the forum...

              1 Reply Last reply Reply Quote 0
              • A
                aaronventure
                last edited by

                you can dynamically resize a panel, so in this case you would have a top part of the panel be a place where you click to collapse/expand.

                just enable all callbacks, check for mouse y and if it's within your height limit, either expand it or collapse it, then call repaint and update the graphics.

                like David said, broadcasters are helpful here because if you have multiple in a column, you'll need to update the Y position of other panels as well. If you have a broadcaster, you can just add a function that does this for each panel that you add, letting you have a dynamic system that you can move between projects or update by easily adding or removing these panels.

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

                  @aaronventure Right! That all makes sense. I'll just have to force myself to use the broadcaster then (I went through David's tutorial but I haven't used it in my workflow yet).

                  A 1 Reply Last reply Reply Quote 0
                  • A
                    aaronventure @VirtualVirgin
                    last edited by aaronventure

                    @VirtualVirgin

                    The whole system is just three parts.

                    1. Create the broadcaster itself and get its reference into a const
                    2. Decide what you're attaching it to, if anything (if attached, it will trigger automatically, which requires a specific constructor in step 1, which is done automatically if you go through the wizard). In this case you can try attaching it to the component property change (in this case height). If not, you can call it manually from the mouse callbacks of panels.
                    3. Add functions (listeners) that will execute when it triggers
                    VirtualVirginV 1 Reply Last reply Reply Quote 1
                    • VirtualVirginV
                      VirtualVirgin @aaronventure
                      last edited by

                      @aaronventure Thanks :) Working on it now.

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

                        Here's a quick little example with two panels and a button.

                        Peek 2025-01-21 16-55.gif

                        HiseSnippet 1042.3ocsV0saaaCElxIJH1aYXEXWsqHztwYHKURyMwqcAMyNNaFqI0nNKn.CcELTzVDQhTPhNMtE4IX2rGoc4dL1CvtXuAcGperkmcShM13EB57G4m9zgmyoWrjxRRjwHiZmMNhgL9Xy9iEJ+19Dt.08HjwVlWP6QDrfyXIJTqwQjjDlGxvXsuW6hQ00Qoq+9osHADAkMUEBctjSYOiGxUS016vejGDbLwicFOrj2MNrKUJZKCji.3rloMJhPujLjcJQ6VESzOPR7QFeoomSCmAMoj8Z5zvkRcatu62rOkQFLfsmyi1uQyAMFPn1tHiM53wUx39Jhhk.aZKo2399x2HxNfy4I7KBXZAGTe3jyTiZ6yC75UvMIHjw58lxTqkwTel4IbO9D8SYrOM0.dZDkIMiJ2FjbVBHYTBRqmAoGX1mFyiTSsnwyGY1UnXw.kvlAJY9hp7WqY1VBdHT6FRtjcbLHLIh56YauCFdr8SpU6gOD2JVR7njDvL1iMfK3JtTTC9yknvWQhwWPeAKg+VF9.bGwPtfsKMlAeqkBr96r3dVOFaU3q0NXKR7vDP2OaQkgQRAfFs1qHAiXVu5F3zKbdWhRQn9mIaW334Zmpa0ZjRIEN5vrzncZ.ddS7EnlHVrZ7y3.RD.VrRStSi5MbOku9k7ufHsErKnYvHAU+cVmK7XWuCdBF2AmhvseWspwL0nXQlL9fCvN3mhaXaieL1019I0tYYIP2kgAc+vTXT9W7GfNcmmOy4HNKYgryLjq68gccWY1s.7yyyPJI9qxzlStKOjt9+N3TFHvpXOvRwoRE64h5aWCbt1M0v+aSCFrPa5qjwxf..wKxrt1Y7sEXcwnvKXwEHsvQnVwrEf139U.hlUgnjiRQWH284Qrb4ikAd5BK52mubEJuDC71O08HhhnqfkqaZ9Fn6H1UPOir5YUMOhkboRFA65jenHCSUp0OIuZW18dD2SGPdQ.z0SZr76AGNdhve91CSHWw5J5EyRXJcYPTocdyrcdqh5n5bhzMdSyrKBk1WXMtrPZ9MnXi+HWgOiOzWCWiew.g3JVXQyspa7qu5yeu1moZcKqdYvjaJllbpKFS+lwciouP8sKBSEpQy2uA5zI8FEPTy19SOXPtAHkbldN59JhDtZb4AGVhdh12ZOw6KDefYOth5uXLVYAXDRV++.i4SRrkYGXzEpZJ.W273WtpiMbGG+KjiTbwvSHpXNj3Xd5nv9vuZJCNcAjNknSNpnSAyjs0xZFnOS3kJ7dXkazQKajazovHJjPikullUHROqxloZ.LIRmkqp4IZYrCJs3TYdNDFc50T5ra0bA5tpA90qZfMV0.ezpF3dqZf6upA17tCTOY62MRICyt1fPmzqSZ0bCiNBBjAllsh9Gci.ghA
                        

                        The first broadcaster is attached to the button's value, and when it changes it updates panel1's width.

                        The second broadcaster is attached to panel1's width and when it changes it updates panel2's width and x position.

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

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

                          On a side note here I may have found a bug, or I am scripting something wrong:

                          I am doing a factory method for 2 panels and the header of is deriving it's name from a unique "name" argument, but the second panel name is overwriting the first one:

                          Content.makeFrontInterface(10000, 700);
                          
                          
                          const Panel1 = createCollapsiblePanel("Panel1", [100, 100, 800, 200], 15, 2)
                          const Panel2 = createCollapsiblePanel("Why is this overwriting the first name??", [100, 300, 800, 200], 15, 2)
                          
                          inline function createCollapsiblePanel(name, area, headerSize, margins)
                          {
                          	local panel = Content.addPanel(name,0,0);
                          	Content.setPropertiesFromJSON(name,
                          	{
                          	    "x": area[0],
                          	    "y": area[1],
                          	    "width": area[2],
                          	    "height": area[3],
                          	    "borderRadius": 0.0,
                          	    "allowCallbacks": "All Callbacks",
                          	    "opaque": true,
                          	    "visible": true
                            	});
                            	
                          	// Set the initial state to expanded
                          	panel.data.isExpanded = true;
                          	
                          	// mouse callback
                          	panel.setMouseCallback(function[area, headerSize](event)
                          	{
                          	
                          		var a = this.getLocalBounds(0);
                          		var clickHeaderArea = [a[0], a[1], a[2], headerSize];
                          		
                          		// set the expanded state data
                          		if (event.clicked && event.y <= headerSize)
                          		{
                          			this.data.isExpanded = !this.data.isExpanded;
                          	
                          		}
                          		
                          		if (event.clicked && this.data.isExpanded) 
                          		{
                          		    // Expand the panel
                          		    this.set("height", area[3]);
                          		    this.repaint();
                          		} 
                          		else if (event.clicked && !this.data.isExpanded) 
                          		{
                          		    // Collapse the panel
                          		    this.set("height", headerSize);
                          		    this.repaint();
                          		}
                          		
                          		
                          	});
                          	
                          	// paint routine	
                          	panel.setPaintRoutine(function[name, headerSize, margins](g)
                          	{
                          		var a = this.getLocalBounds(0);
                          		
                          		// fill main content area
                          		g.setColour(Colours.grey);
                          		g.fillRect(
                          		[a[0] + margins,
                          		a[1] + headerSize,
                          		a[2] - margins * 2,
                          		a[3] - headerSize -margins
                          		]);	
                          		
                          		// draw text on header
                          		g.setColour(Colours.white);	
                          		g.setFont("Oxygen", headerSize * 0.8);
                          		var textArea = 
                          		[
                          		a[0],
                          		a[1],
                          		a[2],
                          		headerSize,
                          		];
                          		g.drawAlignedText(name, textArea, "centred");	
                          		 
                          	});
                          };
                          

                          Screenshot 2025-01-21 at 12.52.02 PM.png

                          I'm not sure how "name" is not a unique argument for each paint routine.

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

                            @VirtualVirgin What do you mean by overwriting? When I load your script I see two panels created.

                            Oh I see the UI is massive, I needed to scroll along. You might want to reduce that a lot, I don't know anyone with a 10000px wide monitor.

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

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

                              @VirtualVirgin Ok the issue is that you are passing in the arguments to the paint routine as lambda values. Instead you should set them as properties of the panel, so the name is the panel's ID or its text, for the headerSize and margin you could make use of the borderSize and borderRadius properties, or just store them within the panel's data object.

                              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 said in Is there a component to make the collapsible panes in HISE?:

                                @VirtualVirgin What do you mean by overwriting? When I load your script I see two panels created.

                                Oh I see the UI is massive, I needed to scroll along. You might want to reduce that a lot, I don't know anyone with a 10000px wide monitor.

                                HAHAHA! Sorry, just an extra "0" by mistake.

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

                                  @d-healey said in Is there a component to make the collapsible panes in HISE?:

                                  @VirtualVirgin Ok the issue is that you are passing in the arguments to the paint routine as lambda values. Instead you should set them as properties of the panel, so the name is the panel's ID or its text, for the headerSize and margin you could make use of the borderSize and borderRadius properties, or just store them within the panel's data object.

                                  So what is a "lambda value"? When I look that up I get a metric for heat conductivity.

                                  Why does the inline function treat the name as unique for when creating the component ID (you can see the component names in the component list are unique) but not for the header text?

                                  Also, why is the "area" argument input seen as unique (the panels are created in different positions), but the headerSize is not (if I change the headerSize of panel2 it changes both)?

                                  I will store all of the relevant data to the panels, but just curious about this disambiguation principle of the variables involved.

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

                                    @VirtualVirgin A lambda value in this context is an outside local variable that you are passing into a function that doesn't otherwise accept additional arguments. Christoph explains a little more about it here.

                                    For the most part I avoid them and use other methods to pass data into functions, in the case of panel's you should always keep the data self contained within the panel's data object.

                                    There are a few occasions when I've found lambdas useful, like passing values in message boxes to be used in the user's response which is asynchronous.

                                    @VirtualVirgin said in Is there a component to make the collapsible panes in HISE?:

                                    Why does the inline function treat the name as unique for when creating the component ID

                                    At that point you are passing the value into the inline function. But when you get to the regular function of the paint routine some magic has happened and the value is treated differently - not sure of the exact reason, but something to do with it not being a local variable probably.

                                    @VirtualVirgin said in Is there a component to make the collapsible panes in HISE?:

                                    Also, why is the "area" argument input seen as unique (the panels are created in different positions), but the headerSize is not (if I change the headerSize of panel2 it changes both)?

                                    The area isn't being passed into the paint routine and although you're passing it into the mouse callback it isn't used there. So it's the same issue as the name, you're passing in the headerSize as a lambda.

                                    Correction, area is used in the mouse callback, but only on click and it's the same value for both panels - I suspect you will hit the same issue if you use different heights.

                                    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 Thanks but I'm still confused.

                                      Here I store the "name" argument in panel.data.text,
                                      then I use that later to draw the text and I am still getting the disambiguation problem.

                                      Also, I changed the header size to unique values for each panel and the mouseCallback definitely treats the lambdas as unique values for the 2 panels.

                                      Content.makeFrontInterface(1000, 700);
                                      
                                      
                                      const Panel1 = createCollapsiblePanel("Panel1", [100, 100, 500, 100], 15, 2)
                                      const Panel2 = createCollapsiblePanel("Why is this overwriting the first name??", [100, 300, 800, 200], 90, 2)
                                      
                                      inline function createCollapsiblePanel(name, area, headerSize, margins)
                                      {
                                      	local panel = Content.addPanel(name,0,0);
                                      	Content.setPropertiesFromJSON(name,
                                      	{
                                      	    "x": area[0],
                                      	    "y": area[1],
                                      	    "width": area[2],
                                      	    "height": area[3],
                                      	    "borderRadius": 0.0,
                                      	    "allowCallbacks": "All Callbacks",
                                      	    "opaque": true,
                                      	    "visible": true
                                        	});
                                        	panel.data.text = name;
                                        	
                                      	// Set the initial state to expanded
                                      	panel.data.isExpanded = true;
                                      	
                                      	// mouse callback
                                      	panel.setMouseCallback(function[area, headerSize](event)
                                      	{
                                      	
                                      		var a = this.getLocalBounds(0);
                                      		var clickHeaderArea = [a[0], a[1], a[2], headerSize];
                                      		
                                      		// set the expanded state data
                                      		if (event.clicked && event.y <= headerSize)
                                      		{
                                      			this.data.isExpanded = !this.data.isExpanded;
                                      	
                                      		}
                                      		
                                      		if (event.clicked && this.data.isExpanded) 
                                      		{
                                      		    // Expand the panel
                                      		    this.set("height", area[3]);
                                      		    this.repaint();
                                      		} 
                                      		else if (event.clicked && !this.data.isExpanded) 
                                      		{
                                      		    // Collapse the panel
                                      		    this.set("height", headerSize);
                                      		    this.repaint();
                                      		}
                                      		
                                      		
                                      	});
                                      	
                                      	// paint routine	
                                      	panel.setPaintRoutine(function[panel, headerSize, margins](g)
                                      	{
                                      		var a = this.getLocalBounds(0);
                                      		
                                      		// fill main content area
                                      		g.setColour(Colours.grey);
                                      		g.fillRect(
                                      		[a[0] + margins,
                                      		a[1] + headerSize,
                                      		a[2] - margins * 2,
                                      		a[3] - headerSize -margins
                                      		]);	
                                      		
                                      		var text = panel.data.text;
                                      		
                                      		// draw text on header
                                      		g.setColour(Colours.white);	
                                      		g.setFont("Oxygen", headerSize * 0.75);
                                      		var textArea = 
                                      		[
                                      		a[0],
                                      		a[1],
                                      		a[2],
                                      		headerSize,
                                      		];
                                      		g.drawAlignedText(text, textArea, "centred");	
                                      		 
                                      	});
                                      };
                                      
                                      d.healeyD 1 Reply Last reply Reply Quote 0
                                      • d.healeyD
                                        d.healey @VirtualVirgin
                                        last edited by

                                        @VirtualVirgin You need to use this.data.text

                                        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 Is there a component to make the collapsible panes in HISE?:

                                          @VirtualVirgin You need to use this.data.text

                                          Sorry, just caught that before you wrote back!!
                                          Your responses are lightning fast...

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

                                          34

                                          Online

                                          1.7k

                                          Users

                                          11.7k

                                          Topics

                                          102.1k

                                          Posts