Graphics Functions
-
Typical, I make a post then I get somewhere a few minutes later :p
I'll leave this here for anyone else who needs it.
Content.setHeight(150); var area = Content.addPanel("area", 0, 0); // [/JSON area] area.set("width", 150); area.set("height", 150); // Define a paint routine area.setPaintRoutine(function(g) { g.setColour(4294901730); g.drawEllipse([10, 10, 100, 100], 5); //x, y, width, height, border size g.drawEllipse([30, 40, 20, 20], 5); //x, y, width, height, border size g.drawEllipse([70, 40, 20, 20], 5); //x, y, width, height, border size g.drawTriangle([55, 60, 10, 10], 0, 3); g.drawLine(45, 75, 90, 90, 5); });
-
Its called rubber duck debugging :)
-
Is there a way to draw an elliptical drop shadow? Also is there a function that can be used to rotate a panel, basically I have a knob with a little dot that I'd like to rotate around when dragged.
Here is the image version but I'd like to do it entirely with vectors within HISE if possible. So far I've created the paint routine to draw the knob statically but I'm not 100% sure how to proceed with the rotation.
-
i also tried a bit around with the ScriptPanelTutorial > 3.4 A vectorized knob
but i think C. would have to add/implement something like:
void addRoundedRectangle
from https://www.juce.com/doc/classPath for it to work..
best,d -
Could you add a property to the
g.drawText();
function to allow us to change the horizontal alignment? -
I need to add another function as you can't "overload" methods in Javascript and I need to keep the old function prototype for backward compatibility.
But I'll add something like:
g.drawAlignedText("Put me left", [0, 0, 100, 50], "centredLeft");
using the same strings as the Label for alignment. The
g.drawText()
method stretches the font to the height of the passed in area (and I doom the day that I decided it to do so), so I wanted to add anotherg.drawText
method anyway.As for rotation, I'll add a function that rotates the whole canvas. Then you can do funny things like this:
// Rotate it by 20% g.rotate(-0.2 * Math.PI * 2); // Draw something g.fillRect([20, 80, 10, 10]); // Rotate it back g.rotate(0.2 * Math.PI * 2);
For the drop shadow, play around with
g.addDropShadowFromAlpha(int colour, int radius)
:const var Panel = Content.addPanel("Panel", 63, 9); Panel.set("height", 100); Panel.setPaintRoutine(function(g) { // 1. Draw the shape of your drop shadow g.setColour(Colours.white); g.fillEllipse([20, 20, 40, 40]); // 2. Add the drop shadow g.addDropShadowFromAlpha(Colours.white, 10.0); // 3. Draw your actual object g.setColour(Colours.black); g.fillEllipse([20, 20, 40, 40]); });
-
Excellent, I'm currently rebuilding my entire GUI with native HISE vectors. Everything's working really well and scales beautifully!
-
Just to show you what I'm up to, this is my GUI now and everything, with the exception of the knobs, has been created using panels and paint routines.
-
Alright, there you go:
https://github.com/christophhart/HISE/commit/b7d6f80e3f57eeb1fd848502e0957d5299305469
This is the example code.
Content.makeFrontInterface(600, 500); // Just so that you can see the drop shadow :) const var bg = Content.addPanel("bg", 3, 4); // [JSON bg] Content.setPropertiesFromJSON("bg", { "width": 100, "height": 100, "itemColour": 4285415745, "itemColour2": 4285547331 }); // [/JSON bg] const var Panel = Content.addPanel("Panel", 20, 20); // [JSON Panel] Content.setPropertiesFromJSON("Panel", { "width": 50, "allowCallbacks": "Clicks, Hover & Dragging" }); // [/JSON Panel] Panel.setPaintRoutine(function(g) { // 1. Draw the drop shadow g.setColour(0x88000000); g.fillEllipse([6, 2, this.getWidth()-10, this.getHeight()-10]); g.addDropShadowFromAlpha(0x88000000, 8); // 2. Draw the knob g.setColour(Colours.grey); g.setGradientFill([0xFF666666, 0.0, 0.0, 0xFF444444, 0.0, 50.0]); g.fillEllipse([5, 0, this.getWidth()-10, this.getHeight()-10]); // 3. Rotate the canvas. // Note that the pivot centre is not the mid point of the panel because the ellipse is smaller g.rotate(this.getValue() * 1.5 * Math.PI, [25, 20]);; // 4. Draw the dot g.setGradientFill([0xFF111111, 0.0, 0.0, 0xFF222222, 0.0, 50.0]); g.setColour(0xaa000000); g.drawEllipse([15, 25, 7, 7], 1.0);; g.fillEllipse([15, 25, 7, 7]); }); Panel.setMouseCallback(function(event) { if(event.clicked) { this.data.mouseDownValue = this.getValue(); } else if (event.drag) { var distance = event.dragX - event.dragY; // change this for sensitivity var normalisedDistance = distance / 200.0; var newValue = Math.range(this.data.mouseDownValue + normalisedDistance, 0.0, 1.0); this.setValue(newValue); this.changed(); this.repaintImmediately(); } });
-
Yippie!!!!
-
Nice one.
-
And I added
g.drawAlignedText()
:Content.makeFrontInterface(600, 500); const var Panel = Content.addPanel("Panel", 24, 30); // [JSON Panel] Content.setPropertiesFromJSON("Panel", { "width": 214, "height": 136 }); // [/JSON Panel] Panel.setPaintRoutine(function(g) { // I can't help myself... g.setFont("Comic Sans MS", 24.0); g.setColour(Colours.white); g.drawAlignedText("Funky Alignment", [0, 0, this.getWidth(), this.getHeight()], "centredTop"); });
-
I'm starting to love this framework more and more, these vector api calls remind me of scripting CSS3 with javascript :) . Awesome. David are those black menus HISE native or are those images???
-
The black dropdown is HISE native.
-
Ok thanks.
-
If I want the knob panel range to be -100 to 100 (or anything other than 0.0-1.0), is the best approach to leave it as 0-1 and use a linear interpolation function to convert the normalized value to the desired range? Or can I just set the knob/panel's min/max to the desired ranged and make some slight adjustment to the algorithm?
-
Just scale it using basic math:
var normalizedValue = Math.range(this.data.mouseDownValue + normalisedDistance, 0.0, 1.0); var value = this.data.min + normalizedValue * (this.data.max - this.data.min); this.setValue(value);
-
Excellent, thanks.
I did it a little differently to how you suggested so I'll paste my altered version here. I'm storing the normalized value as well as the actual value so that I can use one for the paint routine rotation and the other for setting parameters. I also added support for double click to set the knob to 0.
HiseSnippet 1494.3ocsW8+aZbCE+HMHMXCo0o8GfE+vzwFkdPfjrTUslPBsocIEU5R6TTTm4NCmUty9jOCDZU9ed+Gr8r8cbGTRVYZyJPvuu32m2yum8y8EbWRbLWXU3qe67HhUguo3f4LoeWeLkYc5wVEpT7UL9vStAGFEPrNZdDNNl3YUnvCdtRjBk11RO9ye4Hb.l4RxHYYcAm5R9UZHUlQ8Od1qnAA8vdj2RCyIc6mcpKm0kGvm.v4AEcrhvtWiGSNGqDaqhVSojYwVEbJtSqFhqaN7iG1Habjyzme36a68yC7Uj6pn0WKfk6DgfvjW.paUnXg+BFEJdhGUxECjXIAVysOh6MefOeFyX5Knwzgf+BSZZM.vjg7oLIQLB6RxIpUWeZfW+zHYrErZ8yhqOvDW+9hmQ8nKnmEe+VMCTlF4CwE159fYy6Bl83AdpE3NfWgbvaaC7dXwAtBZjLiiBaeWB06.cFlVacXohc4PjgIaDhulzS.SVDor20woNpiiSsmTobkxO9wnWNIVhh4HoOVhlymfbwLTLg.DHHOAOBE6i83yPGTqRYHk.jdJVfFNF8TTpcvdd8wLRfc0giqVGsScTSm1JK.q+kubvqOGD+pJkSEOln7rHhPRIw.9BUhjn6mpTFgpNi5I8qd.rLN00D7Izw9x7TnRRnI8Dn1t09cZ2ryds6rJyVIb6zduc1oYkx2lBqGmgq79k1OVqqo+GfvVP.rYKmkbOMu+YOLcIV1I6j3Q3f.9rtv2CgJsXfQ0tAT3W0QufOkHP+.5XAd7XJChSZEBorpG7nEQjP7MUO.l8YNYJ5pTV+KM5fDd4a3SjTFwdzDlqjxY1igsX.ak.Ua1PYsYqlE.LGqz2DbsctY+8czCkEAVifCSNIHfFESrubWHXUGVAZbiwD46TtqcM.uYzdgdaUS7pjU.B3GC1af1bpP2gAQ93bVpNZesnFb1JGNuFNZbE.Z9GXKAYdhA.lOWf8nv9TO.s1W5bSud6pG0QNMbR+Bn1VORHzA99p04lc.A1P2zf8cZfdCWcVhF8Pc2TbbCjZuzL.QNmq4BklJQhnS4RjKfbAAQiQLtgdH0CEwgcTDejQPcV7PhKdRrY0IFzpzJNDxwHBsiHz12VCTOrD2fwE.a5GIdWfClPP+HjIrK78YXoei9mVGcYqNpZ.vOxbj14SV3x6NL2TOVML2ROVSXNehFFuThlGXuE6.MUPB9rG72UP0YCGC5VYiZIwTqyslSAyUWbFGBXo0fYEFjofajTbPGYl1vUUcR7.xkTzKkEDCUqxwv8BlX3SQ2Y7UgxagOj.0dyHTxR6wm.WjnK+Wyxu5dzSgHWmmrPFvMzzsMwJCQWeLaLwyNGIAIRcJvoggDOJjEDLG3td3.m6r.GpSI8nwRU2Efoyj38nGka1uqMj5CjfXrtNLfFwEv8KrXpjNkJmmtjINEbY1wYK9B6.E5NPhwSPoKZNUxEGzYoBksruycieZMlJI2Sm3nxGt+n8+EVAJt+s3jHxTsFTFRuefDlik0AJc8IjAtjaSlsTdEb.is9tfZYVMW8qcNgfaHpA6RqnVsEaUv8Ww7.RiHA.D6TCkwe47qk4uQoYlzdn9KsDCwYpy5dMytV4OUtT4aKuJmQiVGK0MtBt57r0wU0Sq3dTylMIbHQT2rEjJGzp1xM5U9KqQOWys+4DjyNkQkuNhrXtwISo3Xsv4xSJyoxSU6LqQrLRed2kVIcj.+5yayDZ1k6MI.KWtCX0KIRX.Aqk5wT0Gopxcd9WZrAsE6r11hatNf+EB2GVrOU55ud7t0ZvKzw8+23M4QFUJdxnQDWYFX2tXu2+u8EEa.TL80MFNlRPuAdi04SBG.Wh5R.jvfK5hUu6ZKUxgYtiZtJxLfv7bReTVBylp4ERX1LkoUH1Uv+fqICT8LluRSAvDS+.wREOSMG0zRWZYvMzmB8Cttp.wi.judMZswZryFqQ6MViNarF6twZr2Fqw92iFpGxd3DIOzTVXY82vSTZpf
-
Christoph, is there way to prevent the panel knobs and sliders from resetting to zero every time the script is compiled or the preset is loaded? I've tried with the knob example you posted.
-
Panel.set("saveInPreset", true);
If you set this property, it will save the value before recompiling and executes the control callback after compilation with the stored value (after setting the value internally). By default it's disabled for ScriptPanels, so you need to enable this specifically.
The general rule of thumb is: Enable this property for everything that controls sound parameters so you want this to be restored when you load user presets), but disable this for GUI controls (like buttons that toggle the visibility of UI pages, etc.). And definitely disable those for buttons that load user presets or you get an infinite loop...