Through the Technical Note 2, I was able to change GUI values and create internal presets.
My questions are, How do you set two knobs to equal each other? (Like a link button on many delays.)
How do you call the checkUpdateGUI? (I am having trouble with the bold.)
I tried to call the function from inside the UserInterface change but could not figure out the argument to send CLinkedList&guiParameters.
checkUpdateGUI(int nControlIndex, float fValue, CLinkedList& guiParameters)
You don't call checkUpdateGUI( ) -- it is called on your plugin anytime a GUI control changes. If a GUI control change spawns another control change, then you do that from this function. For linking controls like that I generally suggest using the Advanced GUI API to take control of the controls. I will try to get back to this thread in a few days.
I have posted a sample project just below the Tech Note 2 here:
This project links two volume knobs together (when you press the LINK button) so that one control modifies the other. This works for both the RackAFX UI as well as a custom GUI that I designed super quickly with the GUI Designer. Have a look at the checkUpdateGUI( ) function in the sample code to see how easy this is to implement.
First I wanted to say thank you for taking the time to make that project, it made the checkGuiUpdate functionality very clear!
The link is working great!
I have been working through the advance gui modules several times over, which is do to my level of c++. I recently asked my friend who is a veteran program to help me with the implementation I mention below, and have even hired a programmer to help me understand the call functions of vstgui. I think I have a good foundation of how to utilize the classes but am still coming up short on functionality.
I don't know if you are familiar with Brainworx's EQ, but it has functionality of soloing the Q during a mouseDown event and releasing the solo with the mouseUp of endEdit events. I am curious where to change the code for the "solo" switch. Essentially making a knob into a "knob and a momentary button." I have ran out of ideas and options for this and am open to any direction or ideas you have on how to pursue this endeavor.
I was able to change a m_uMute value within the userInterfaceChange case switch, but have not found away to have the m_uMute toggle back to Off.
This last week I asked a lot of questions on the forum and plan to update my questions as I find answers also! Thanks Again
There are a couple of things you should check out:
1) use Make VST (or AU or AAX) to generate a dummy project. Look at the CKnobWP class (knobwp.h and knobwp.cpp) - this is my subclass of CAnimKnob. I did it specifically to implement a "switch knob" - a knob that acts like a rotary switch and clicks between values rather than moving continuously. There you can see me override the draw() function to implement that behavior. BTW to enable this in the GUI Designer, use KnobSwitchView as the Custom View name, and link it to a UINT control.
2) in the same VST project, look at my subclass of the CKickButton object called CKickButtonWP. If you use the GUI Designer in RackAFX and you pull up a CKickButton (momenary on/off) you will see that you can set the button to generate click messages on mouse down, or mouse up, or both mouse down and up. The default behavior of the CKickButton is to generate a mouse click event only on mouse up. This is also done with a Custom View (which is set for you when you choose the behavior). To make that work, I overrode the onMouseDown( ) and onMouseUp( ) methods.
Custom Views are a powerful paradigm in VSTGUI4 and of course subclassing objects to extend their functionality is at the core of C++ itself.
Between those two examples, you should have a better idea of how to implement your button-knob.
I had previously been working through the first example numerous times, the second example is interesting and has shed more light on this "dark" situation. I have reexamined my approach and keep coming with the same result. I have tried receiving a bool change from onMouseUp and Down events, but I do not believe I can access a bool through pKnob->Clicker. "bool Clicker being defined in the KnobWCP header"
This morning I tried passing a bool argument through the CKnobWCP class but that also created many errors, as I found my self diving deeper into changing parameter arguments in each parent classes.
I understand how to manipulate a chosen variable and even got a Ccontrol CView container to manipulate the m_uMute button, but can not get "access" to a bool change within the onMouseDown, and onMouseUp Event from GUI_CustomView, I had even tried putting the pKnob constructor in the header of the CustomViews.h file and accessing the bool from the userInterfaceChange and the checkGuiUpdate to no avail.
I had also tried sending updates through the checkGuiUpdate function based off the project you supplied circumventing Gui_CustomView. Along with many other unorthodox approach's that would probably give you a laugh.
How would you access a member variable change within CKnobWCP?
Where would that code be within our CPlugIn?
Hope my questions make sense, thanks Will.
The proper way to do this is with a VSTGUI subcontroller. See the PadController object in a MakeVST project as an example; but subcontrollers are tricky and not directly API-independent to work in AU and AAX as well. The fundamental problem is that VSTGUI controls were only meant to have one tag. I came up with my own API-independent solution for the XYPad - which requires two tags, one for X and the other for Y - by encoding the two tags in the Custom View string; you can see this easily by dragging an XYPad into the GUI Designer and assigning the two tags to it. The Custom View string will encode them. The un-encoding code is available in createCustomView( ) in a MakeVST project.
I think a decent approach here would be to create a Custom View for a knob control, encoding the two tags in the view name. Then, have a transparent CKickButton control laying on top of the knob - tricky to implement. I am super busy right now, but I may take a look at this later next week as this kind of control has been requested before.
I will explore that concept further, I agree that should solve the issue I am talking about. I removed that functionality from my plug in but plan to upload my demo as well. Because it is a powerful functionality.
I have more functionality with the checkGuiUpdate I am having problems with, I have been working with the linked controls project as basis for my functionality, with the same if (statements) within the checkGuiUpdate.
All button types and knobs, will not update the link control functionality until the gui is closed, even then the "mirrored knobs" don't work, but the button on the Rackafx api is changed. I have tried all known forms such as Kickbutton, various vicarious control's, and brute force calls.
I would love to hear, but it might be something with how "The Thread" is working. However, this is speculation blinded by the reach out of my ignorance.
Note: functionallity works perfect within rackafx, (no gui)
Note 2: I remember seeing something Will said about a function that needed to be called or trapped to execute a "functionality" like this, but can't find the thread (no pun intended)???
Not sure exactly what your problem is, however it is true that the Custom GUI does not link back to the main RackAFX GUI. When you move controls on your custom GUI, they will not alter the controls on the RAFX UI until the GUI is closed. This is normal operation.
The checkUpdateGUI ( ) works properly on the custom GUI - the linked control example I made demonstrates that.
It is a weird problem, it is acting slightly different in my plug in but essentially it looks like this.
OK I see what's happening - I should have flagged this earlier, but if you read the document on using checkUpdateGUI( ) at the beginning it says:
"If you want to link continuous controls together (like knobs or sliders) so that they move at the same time, you should not use this updating mechanism as it is a clumsy way to accomplish this - instead, use the Advanced GUI API to create custom controls that your plugin owns and can manipulate"
And this is a good example of why this is the case. I've updated both the document (you may need to refresh your browser to see the updated .PDF file) and the LinkedControls project as well, so you need to download that again - only two files changed, LinkedControls.h and LinkedControls.cpp -- I decided to keep the project to show the extra stuff you need to do this without Custom Views, and for people who just refuse to do any GUI programming at all.
The central issue is that the plugin's GUI-linked variables are updated in a thread-safe manner during the audio processing loop, which is documented on the Documents page. This means you need to declare extra variables (that is shown in the updated example project) to keep track of your link button state, independent of the GUI-linked variable m_uLinkControls.
In the RackAFX GUI, if the controls are moved/changed and no audio is flowing, I go ahead and do the preprocess operation to synchronize your variables, so that is why it worked for you when starting with the RAFX UI, then opening the custom GUI. This does not occur from the Custom GUI in RackAFX, and is not guaranteed to occur in other DAWs for other APIs.
It makes feel good to know I wasn't too far off, I had tried a "vicarious bool control" as I called it, the only difference in your project to the attempts I tried, was the line.
Which was for the case 45 linking button, I'm curious what that means?
Other than that, you answered a lot of my questions, I got so wrapped up in the problem I never even tried "playing audio" during my tests haha. This method seems somehow more stable, look forward to implementing it tonight.
I think the project cleared up the GuiParameter usage for me, I have used your book to learn C++ and DSP together. My goal is to eventually move into complete custom gui but I have found that has steepest learning curve!
if(fValue == 0.f) is checking to see if the link button's value is 0 (off) or 1 (on).
The .f tells the compiler to treat the value to check against as a float, since fValue is a float (rather than double). You could have also written if(fValue == 0.0) and would have been functionally the same, but the compiler would have treated 0.0 as a double. I've switched to the more proper use of the .f in my code when dealing with floats for both portability and efficiency.
Most Users Ever Online: 55
Currently Browsing this Page:
Guest Posters: 1
Newest Members:frankthetank, dhodgson, Wanderer, mister1234, Evan Galvanek, Rowan Fraser, patrickbarr1984, Ray C., Jon R., Pat
Moderators: W Pirkle: 344
Administrators: Tom: 69, JD Young: 80, Will Pirkle: 0, W Pirkle: 344