HISE Logo Forum
    • Categories
    • Register
    • Login

    Converting Interface Components to Vector Graphics

    Scheduled Pinned Locked Moved Solved Scripting
    10 Posts 2 Posters 286 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.
    • S
      stusmith
      last edited by

      Hello! I have created a working effects plugin using the generic interface elements in the interface designer.

      Now I want to customise the GUI. I found and adapted some bits of code to generate vector dials that are kinda what I'm after but I run into issues trying to rewire things to replace the existing interface elements.

      Is there a best method for doing this kind of thing? I'm still very nooby so I'm almost certainly missing some basic knowledge here. 😅

      Here's a bit of code I'm using to render some dials but they only output values of 0-1 without any skewing to match the parameters I want to assign them to.

      Thanks for your invaluable help!

      inline function createCircularKnob(name, x, y)
      {
          local widget = Content.addPanel(name, x, y);
      
          Content.setPropertiesFromJSON(name, {
            "width": 50,
            "height": 50,
            "allowCallbacks": "Clicks, Hover & Dragging"
          });
      
          widget.setPaintRoutine(function(g)
          {
              // Draw the knob base
              g.setColour(Colours.black); // Solid color for knob
              g.fillEllipse([0, 0, this.getWidth(), this.getHeight()]);
      
              // Calculate pointer position
              var angle = this.getValue() * 1.5 * Math.PI + Math.PI * 0.75; // Start at 7.5 o'clock, end at 4.5 o'clock
              var centerX = this.getWidth() / 2;
              var centerY = this.getHeight() / 2;
              var radius = this.getWidth() * 0.4; // Pointer radius from center
      
              var pointerX = centerX + Math.cos(angle) * radius;
              var pointerY = centerY + Math.sin(angle) * radius;
      
              // Draw the pointer
              g.setColour(0xFFFFE092); // Pointer color (#FFE092 with full opacity)
              g.fillEllipse([pointerX - 3, pointerY - 3, 6, 6]); // Small circular pointer
          });
      
          widget.setMouseCallback(function(event)
          {
              if(event.clicked)
              {
                  this.data.mouseDownValue = this.getValue();
              }
              else if (event.drag)
              {
                  var distance = event.dragX - event.dragY;
                  
                  // Adjust sensitivity
                  var normalisedDistance = distance / 200.0; 
                  
                  // Calculate and clamp the new value
                  var newValue = Math.range(this.data.mouseDownValue + normalisedDistance, 0.0, 1.0);
      
                  this.setValue(newValue);
                  this.changed();
                  this.repaintImmediately();
              }
          });
      
          return widget;
      }
      
      // Render Dials
      const var HiQ_Dial = createCircularKnob("HiQ_Dial", 130, 220);
      const var LoQ_Dial = createCircularKnob("LoQ_Dial", 190, 220);
      const var HiCut_Dial = createCircularKnob("HiCut_Dial", 250, 220);
      const var LoCut_Dial = createCircularKnob("LoCut_Dial", 310, 220);
      
      
      d.healeyD 1 Reply Last reply Reply Quote 0
      • d.healeyD
        d.healey @stusmith
        last edited by

        @stusmith said in Converting Interface Components to Vector Graphics:

        Is there a best method for doing this kind of thing?

        Start at the beginning, learn to script, take the time, relax, it's a long process.

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

        S 1 Reply Last reply Reply Quote 1
        • S
          stusmith @d.healey
          last edited by

          @d-healey Heheh... I CAN'T RELAX!

          JK. I'm chill, just keen. 🥰

          Quite pleased with the progress I've made so far but only just began with the vector interface stuff and clearly have much to learn. Wondering if I'm missing something obvious with these dials.

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

            @stusmith said in Converting Interface Components to Vector Graphics:

            Wondering if I'm missing something obvious with these dials.

            The important thing is do you understand what each line of the code you are using does? If you don't, then the first step is to get that understanding so you can have control over what it does.

            I have quite a few videos on look and feel stuff on my YouTube channel that might be useful to you.

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

            S 1 Reply Last reply Reply Quote 0
            • S
              stusmith @d.healey
              last edited by

              @d-healey Mhmm... gonna try from scratch based on one of your tuts. I had this idea that I wanted to remake everything with vectors because vectors = good... might have just been making life harder for myself instead.

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

                @stusmith said in Converting Interface Components to Vector Graphics:

                with vectors because vectors = good... might have just been making life harder for myself instead

                Vectors do have a lot of advantages over using images, so if you can use them I'd say go for it. Sometimes though an image is the way to go, really depends on the situation.

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

                S 1 Reply Last reply Reply Quote 0
                • S
                  stusmith @d.healey
                  last edited by

                  @d-healey Ok so I'm following your "Look and Feel Knobs and Sliders" video and it's exactly what I needed... I was definitely overcomplicating things.

                  Thanks! 🙏

                  1 Reply Last reply Reply Quote 1
                  • S
                    stusmith
                    last edited by

                    Sooo... @d-healey. Your videos are great. The knobs and sliders one was just what I needed to create my custom design and I ran with that and have one FX plugin basically done.

                    However, when starting a new plugin, I discovered that the code seems to also affect the knobs and sliders in the built-in modules, see below. Making them kinda unusable. 😅

                    I hadn't noticed before because I was only using Script FX.

                    Screenshot 2025-01-11 at 10.48.44.png

                    Is there a way to change the scripts to only affect interface elements in the plugin and not HISE as a whole?

                    Here's the relevant bit of script (which works great for the actual plugin!):

                    // Customise Dials
                    laf.registerFunction("drawRotarySlider", function(g, obj)
                    {
                        var a = obj.area;
                    
                        // Calculate padding as a percentage of the dial size
                        var padding = a[2] * 0.05; // % of the width
                    
                        // Background circle
                        g.setColour(secondaryColour);
                        g.fillEllipse([padding, padding, a[2] - padding * 2, a[3] - padding * 2]);
                    
                        // Define the angle range for the dial
                        var startAngle = -2.35; // Start position in radians (~135 degrees)
                        var endAngle = 2.35;    // End position in radians (~45 degrees)
                    
                        // Map valueNormalized (0-1) to the angle range
                        var angle = startAngle + (endAngle - startAngle) * obj.valueNormalized;
                    
                        // Position the circle relative to the outer edge
                        g.setColour(primaryColour);
                        var radius = a[2] / 12; // Size of the circle
                        var offset = a[2] / 3.5; // Distance from the center
                        var centerX = a[2] / 2;
                        var centerY = a[3] / 2;
                    
                        // Calculate position based on the angle and offset
                        var x = centerX + Math.sin(angle) * offset - radius;
                        var y = centerY - Math.cos(angle) * offset - radius;
                    
                        // Draw the indicator circle
                        g.fillEllipse([x, y, radius * 2, radius * 2]);
                    });
                    
                    
                    
                    
                    
                    // Customise Sliders
                    laf.registerFunction("drawLinearSlider", function(g, obj)
                    {
                        var a = obj.area;
                        g.fillAll(secondaryColour);
                        g.setColour(primaryColour);
                    
                        if (obj.style == 2) // Horizontal
                        {
                            var w = a[2] / 21;
                            var x = a[2] * obj.valueNormalized - w * obj.valueNormalized;
                            g.fillRoundedRectangle([x, -1, w + 1, a[3] + 2], 0);     
                        }
                        else // Vertical
                        {
                            var h = a[3] / 21;
                            var y = a[3] - a[3] * obj.valueNormalized - h + h * obj.valueNormalized;
                            g.fillRoundedRectangle([0, y, a[2] + 2, h + 1], 0);     
                        }
                    });
                    
                    d.healeyD 1 Reply Last reply Reply Quote 0
                    • d.healeyD
                      d.healey @stusmith
                      last edited by

                      @stusmith You need to use local look and feel instead of global look and feel - local wasn't available when I made that video.

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

                      S 1 Reply Last reply Reply Quote 1
                      • S
                        stusmith @d.healey
                        last edited by

                        @d-healey BOOM!

                        Thanks. 🙏

                        I'm quite certain I'll be signing up to your Patreon at some point. Doing reasonably well by myself so far but I'm only scratching the surface.

                        Appreciate all you are doing here!

                        1 Reply Last reply Reply Quote 1
                        • S stusmith has marked this topic as solved on
                        • First post
                          Last post

                        17

                        Online

                        1.7k

                        Users

                        11.8k

                        Topics

                        102.7k

                        Posts