Add graphic elements and Java script
-
@d-healey Wow! David your videos are very helpful, thanks. You are very kind as always
-
I want to ask about custom script-panel "classes".
For example, I wanna to make a solid "class" of a table row. Which wrapped into a scrip panel and consists of some variable amount of buttons and knobs. I would use the methods of this complex object and have the control of its constructor.
I found that addScriptPanel within given name works fine, but sometimes several controls are added into the preset itself if the code is changed. What the best way to implement this? -
@Levitanus There are no true user classes in HISE script - it's not javascript. The closest thing we have are namespaces.
-
@d-healey I mean, we can return an object with custom methods, contains other objects. For my taste, this is enough to make some OOP-like abstractions.
-
@Levitanus said in Add graphic elements and Java script:
@d-healey I mean, we can return an object with custom methods, contains other objects.
Do you have an example?
-
@d-healey a bit durty:
Content.makeFrontInterface(200,200); Console.clear(); namespace GuiVE{ //const var note_names = new Object(); inline function create(name, min, max, ve_mode){ const var arrowsWidth = 7; const var p = { name: name, bg: Content.addPanel(name, 0, 0), text: Content.addLabel(name+"Label"), mode: ve_mode, min: min, max: max, width: 100, height: 20, min: min, max: max, clickedValue: 0, set: function(parameter, value){ this.bg.set(parameter, value); this.text.set(parameter, value); }, setDimentions: function(x, y, width, height){ this.x = x; this.y = y; this.width = width; this.height = height; Content.setPropertiesFromJSON(this.name,{ "x": x, "y":y, "width":width, "height":height }); Content.setPropertiesFromJSON(this.name+"Label",{ "x": x, "y":y, "width":width, "height":height }); }, }; p.bg.set("allowCallbacks", "Clicks, Hover & Dragging"); p.bg.set("width", width); p.bg.set("height", height); p.text.set("parentComponent", name); p.text.set("width", width-arrowsWidth); p.text.set("height", height); p.bg.setColour("BG", 0xff000000); p.bg.setColour("TXT", 0xffffffff); p.bg.setPaintRoutine(function(g){ g.setColour(0xffffffff); g.drawTriangle([p.bg.getWidth()-arrowsWidth, 0, arrowsWidth, arrowsWidth], 0.0, 1.0); g.drawTriangle([p.bg.getWidth()-arrowsWidth, p.bg.getHeight()-arrowsWidth, arrowsWidth, arrowsWidth], 3.14, 1.0); }); p.setValue = function(value){ p.text.set("text", value); }; p.getValue = function(){ var value = parseInt(p.text.get("text"),10); return value }; p.bg.setMouseCallback(function(event){ if (event.clicked == 1){ p.clickedValue = p.getValue(); if (event.doubleClick == 1){ p.setValue(p.defaultValue); }; if (event.mouseDownX > (p.bg.getWidth()-arrowsWidth)){ if (event.mouseDownY < (p.bg.getHeight()/3)){ p.setValue(p.clickedValue+1); } else{ p.setValue(p.clickedValue-1); }; }; }; if (event.drag == 1){ var value = p.clickedValue - Math.floor(event.dragY/3); p.setValue(value); }; }); p.text.set("text", 1); p.text.set("saveInPreset", false); return p } } const var testVe = GuiVE.create("myve", 0, 100, false); Console.print(testVe.text.getValue()); testVe.setDimentions(10,10,100,20); //testVe.set("width", 50);
-
@Levitanus I see, so you're using a namespace to return an object. Looks fine to me.
solid "class" of a table row
Are you trying to create something like a mixer channel?
-
@d-healey said in Add graphic elements and Java script:
Are you trying to create something like a mixer channel?
-
Probably the easiest way is to create it in a panel in the interface designer then duplicate with CTRL+D. I used to do everything in script but I find the HISE way (interface designer) works more reliably. Or if you know C++ do it that way.
-
@d-healey said in Add graphic elements and Java script:
Or if you know C++ do it that way.
While I read tutorials, I see it's just a language, But looking to a real project I feel Bjorn made cpp as a custom type of torch machine.
In the ID way I afraid of losing the reusability of code. You know... Wanna just write a "class" and use it for the rest of life :D
-
In the ID way I afraid of losing the reusability of code. You know... Wanna just write a "class" and use it for the rest of life :D
It's all saved in XML so you could reuse it I think
-
slowly going))
namespace midiMatrix{ inline function make_header(obj, name){ local header = { frame: Content.addPanel(name + '.header',0,0), cells: { _:30, Ch: 30, LED: 30, DivisiParts: 100, Articulations: 100, Group: 40, IsMaster: 100 }, labels: {}, setWidth: function(width){ this.frame.set('width', width); local sum = 0; for (cell in this.cells){ sum += this.cells[cell]; } local ratio = width / sum; local offset = 0; for (cell in this.cells){ this.labels[cell].set('x', offset); this.labels[cell].set('width', this.cells[cell] * ratio); offset += this.cells[cell] * ratio; } }, }; header.frame.set('parentComponent', name); header.frame.set('height', 30); local offset = 0; local label; for (cell in header.cells){ label = Content.addLabel(name + '.header.' + cell,offset,0); label.set('parentComponent', name+'.header'); label.set('saveInPreset',false); label.setEditable(false); label.set('text', cell); label.set('width', header.cells[cell]); header.labels[cell] = label; offset += header.cells[cell]; }; return header } inline function add(name, max_channels, visible_cells){ local obj = { table: Content.getComponent(name), scrollbar: Content.addPanel(name+'.scroll',0,0), header: make_header(this, name), max_channels: max_channels, visible_cells: visible_cells, data: [], scrollWidth: 10, configure_cells: function(cell){ Console.assertIsDefined(cell['divParts']); Console.assertIsDefined(cell['artics']); for (var i = 0; i < this.max_channels; i++) { this.data[i] = cell; } }, update_dimentions: function(){ local width = this.table.get('width'); local height = this.table.get('height'); local x = this.table.get('x'); local y = this.table.get('y'); this.scrollbar.set('width', this.scrollWidth); this.scrollbar.set('height', height); this.scrollbar.set('y', y); this.scrollbar.set('x', width - this.scrollWidth); this.header.setWidth(width - this.scrollWidth); }, }; obj.scrollbar.set('parentComponent',name); return obj } }
-
Without going into the gory details: David is right. HISEScript is not suited for "real" object-oriented programming and as soon as your talking about making dynamic GUI elements you're quickly getting into hacky workarounds.
There is one design paradigm in HISEScript which will get in your way pretty quickly and that is that every UI element has to be declared on script initialisations. This has implications on the user preset system, plugin parameter automation, state saving etc. In C++ it is no problem creating other UI elements if you press a button, because you can easily decouple the data from the UI elements.
Moreover, there's an uncanny value where any scripting language becomes a burden, because you start relying on industry grade debugging tools, and even if HISEScript tries to push that a little further than other scripting languages (which is why I bothered with breakpoint, local variable watch etc.) at a certain point the efficiency compared to C++ goes towards zero.
Once you get past the
Bjorn-don't-torture-me-with-<thisTemplateSyntax>
state, C++ (and especially with the new C++11 / C++14 enhancements) will quickly become the language of your choice for anything audio-related - and KSP really starts to look like assembly from the 1980s :).
JUCE also does a marvellous job of nudging you into a good coding style, which is why I decided to open the C++ API in HISE.I don't know you personally, but from what I've read from you in the past (here and on VI-Control) you should be able to grasp the basics of JUCE/C++ pretty quickly and leverage the full flexibility of true object orientated programming (plus being able to write C++ is a very valuable skill). The screenshot you posted is trivial to implement in C++ BTW.
On the other hand, I won't stop you from playing around and trying to push the limits of what's doable. The code you posted looks reasonable (and I must contradict David here and say "leave the interface designer alone for this kind of stuff or you will shuffle pixels around forever").