|
|
|
10-04-2019, 08:38 AM
|
#1
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Resources for making C++ extensions?
I was thinking of trying to do some extensions in C++. After a bit of searching it seems to be tough to find information about this. A lot of the resources seem to be a bit outdated.
I was wondering if anyone can post any helpful resources or info about making C++ extensions. Stuff that you would consider a must read would be very helpful to me. Thanks for any help!
|
|
|
10-04-2019, 09:03 AM
|
#2
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,621
|
Julian Sader's extension is probably a good starting point. It's structured very simple.
You can also read his threads, where he asked questions about doing an extension, as he was going through the same obstacles.
And it's probably the most recent resource on that.
If I ever have the time, I will dig through this to write a tutorial on extension-programming, but hadn't yet...
|
|
|
10-04-2019, 09:24 AM
|
#3
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by mespotine
Julian Sader's extension is probably a good starting point. It's structured very simple.
You can also read his threads, where he asked questions about doing an extension, as he was going through the same obstacles.
And it's probably the most recent resource on that.
If I ever have the time, I will dig through this to write a tutorial on extension-programming, but hadn't yet...
|
Thanks for the input! I'll take a look at that and see what I can learn.
|
|
|
10-04-2019, 09:39 AM
|
#4
|
Human being with feelings
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
|
I have a minimal extension plugin example, which I've updated fairly recently :
https://github.com/Xenakios/reaper_very_minimal
The actual extension code is in the main.cpp file. The other files are support files for building the plugin.
It's not literally the most minimal extension example that could be done, but since the most usual use case is for the extension to add new actions into Reaper, the example has that included. I've tried to add useful comments into the code. (Including the .bat file that explains the classic issue about how the built .dll must be named in order for Reaper to scan it as an extension plugin.)
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
|
|
|
10-04-2019, 09:55 AM
|
#5
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by Xenakios
I have a minimal extension plugin example, which I've updated fairly recently...
|
That looks fantastic! That will really help me get started, thank you!
|
|
|
10-04-2019, 11:29 AM
|
#6
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by Xenakios
I have a minimal extension plugin example, which I've updated fairly recently...
|
I was able to get it compiled and running.
I would like to do stuff with a GUI though. Judging by this thread, it seems like that might be really complicated.
Do you have any tips for doing stuff with a GUI?
|
|
|
10-04-2019, 11:34 AM
|
#7
|
Human being with feelings
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
|
Quote:
Originally Posted by Alkamist
it seems like that might be really complicated.
Do you have any tips for doing stuff with a GUI?
|
Unfortunately, it is very involved. I have managed to use the Juce framework to some extent within Reaper extensions, but using Juce has its own complications and limitations.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
|
|
|
10-04-2019, 11:44 AM
|
#8
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by Xenakios
Unfortunately, it is very involved. I have managed to use the Juce framework to some extent within Reaper extensions, but using Juce has its own complications and limitations.
|
Juce sounds like a decent place to start. I'll look into it and see if I can get anything to work. Unfortunately I'm no C++ guru so this will likely be an incredibly difficult task.
|
|
|
10-04-2019, 11:51 AM
|
#9
|
Human being with feelings
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
|
Quote:
Originally Posted by Alkamist
Juce sounds like a decent place to start. I'll look into it and see if I can get anything to work. Unfortunately I'm no C++ guru so this will likely be an incredibly difficult task.
|
Because building stuff with Juce and integrating Juce with Reaper is so involved, I would grudgingly suggest first trying the Windows/Microsoft win32 API instead. (Which is what Reaper itself uses and Cockos has the Swell library that implements parts of win32 for macOS and Linux.) What kind of GUI do you want to do?
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
|
|
|
10-04-2019, 12:19 PM
|
#10
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by Xenakios
Because building stuff with Juce and integrating Juce with Reaper is so involved, I would grudgingly suggest first trying the Windows/Microsoft win32 API instead. (Which is what Reaper itself uses and Cockos has the Swell library that implements parts of win32 for macOS and Linux.) What kind of GUI do you want to do?
|
I'll have to look into that as well. If you have any examples you can point me to that use the win32 API that would help a lot.
What I want to do is create a pitch correction editor. So it would have the ability to have buttons, a file menu, drawing capability to draw graphical things like lines, rectangles, and circles. Also getting input and the location of the mouse and things like that are important. Basically, I could do pretty much what I need with the functionality you get in Lua.
I've already done all of this in Lua, I just really hate working with a GUI limited to 30 fps; it feels really clunky to me.
The other reason I'm looking into C++ is because eventually I want to mess around with machine learning, to try to get it to automatically do pitch corrections for you that you can fine-tune later. Trying to do something like this with Python would probably be a nightmare as far getting it installed for other users.
|
|
|
10-04-2019, 12:39 PM
|
#11
|
Human being with feelings
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
|
Quote:
Originally Posted by Alkamist
I've already done all of this in Lua, I just really hate working with a GUI limited to 30 fps; it feels really clunky to me.
|
30 FPS should be plenty enough (people are fine with TV and movies at that frame rate or below...), are you sure it's just about the general GUI frame rate? Of course if you do expensive calculations/operations in the GUI thread, the GUI update speed will suffer...(And even C++ doesn't necessarily help you there, I've had plenty of occasions when I get absolutely crawling GUI frame rates with C++...)
One approach you could take is to keep the GUI code in Lua ReaScript, but implement the expensive operations with C++.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
|
|
|
10-04-2019, 01:01 PM
|
#12
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by Xenakios
30 FPS should be plenty enough (people are fine with TV and movies at that frame rate or below...), are you sure it's just about the general GUI frame rate? Of course if you do expensive calculations/operations in the GUI thread, the GUI update speed will suffer...(And even C++ doesn't necessarily help you there, I've had plenty of occasions when I get absolutely crawling GUI frame rates with C++...)
One approach you could take is to keep the GUI code in Lua ReaScript, but implement the expensive operations with C++.
|
30 fps is manageable, however, I tend to be way more picky than most people. I have a 144 hz monitor and play a lot of video games, so 30 fps to me is horrendous.
The calculations do slow the GUI down. I basically have to do large amounts of iterating through time/pitch data and operations on these points. I like having the graphical representation of the pitch data update in real-time when editing. Even iterating through ~500 points can slow the GUI down a ton.
To get around this I had to write all sorts of optimizations to get it to run in real time. It can probably be done way better since I'm not an expert, but it just quickly got unruly. I don't really have experience writing things on different threads, so I'm probably doing all of it on the GUI thread.
I didn't know it was possible to mix and match C++ and Lua. How would you go about doing that?
|
|
|
10-04-2019, 02:55 PM
|
#13
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 9,875
|
iPlug2 has also a template for REAPER extension.
|
|
|
10-04-2019, 03:48 PM
|
#14
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by X-Raym
iPlug2 has also a template for REAPER extension.
|
I'll look into this. Currently using the win32 api isn't working so well for me since I don't have any experience with it.
|
|
|
10-06-2019, 11:42 AM
|
#15
|
Human being with feelings
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
|
Quote:
Originally Posted by Alkamist
I don't really have experience writing things on different threads, so I'm probably doing all of it on the GUI thread.
I didn't know it was possible to mix and match C++ and Lua. How would you go about doing that?
|
Everything in ReaScript happens on the GUI thread. There are no facilities to run stuff in real different threads. (Lua has something they call "threads", but as far as I've understood, they are not actual real threads that are running in parallel on different CPU cores.)
You can do a C++ plugin that exports functions for use with ReaScript. But of course even with those, if the execution speed isn't fast enough, you will get GUI lags, if you don't explicitly implement running the functions in other threads or do some other tricks that keep the GUI responsive.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
|
|
|
10-06-2019, 01:07 PM
|
#16
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by Xenakios
Lua has something they call "threads", but as far as I've understood, they are not actual real threads that are running in parallel on different CPU cores.
|
They specifically don't call them "threads" for that reason - Lua calls them coroutines, and they're the same ideas as the generators that were recently introduced to Javascript. Basically a function that can pause itself and wait to be called again, so you could tell it "Here are 100 items to process. On each script loop, process 5 of them and then take a break."
|
|
|
10-06-2019, 01:12 PM
|
#17
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by Xenakios
Everything in ReaScript happens on the GUI thread. There are no facilities to run stuff in real different threads. (Lua has something they call "threads", but as far as I've understood, they are not actual real threads that are running in parallel on different CPU cores.)
You can do a C++ plugin that exports functions for use with ReaScript. But of course even with those, if the execution speed isn't fast enough, you will get GUI lags, if you don't explicitly implement running the functions in other threads or do some other tricks that keep the GUI responsive.
|
I see. With that in mind, working with C++ extensions seems to be what I want. A lot of my ReaScript ideas end up being doable in Lua, but tend to be clunky given the restrictions ReaScript has.
I'm currently just trying to get settled with finding a good way to get keyboard/mouse input, and a good way to do GUI stuff. I really dislike the idea of using the Win32 library directly. The documentation for my purposes is incredibly sparse and it just seems like a pain to work with to do simple things.
I'm looking into this library called SFML that might be good to use. Compiling it and using it within a reaper extension seems to be pretty complicated. I'm really new with all of these compiler settings and CMake shenanigans. There's also a ton of information to sift through.
If you have any advice for this I would be grateful! I'm not sure whether I should try to be making a batch file to run cl.exe like you did in your example, or if I should be trying to make a VS2019 project file and hook everything up from there. I don't know if I should just include the SFML source code, or if I need to build it to a dynamic or static library.
Ideally I could just have people install my extension and not have to worry about any external dependencies.
I'm sure I can figure it out eventually, it will just take a lot of patience with google searches.
|
|
|
10-06-2019, 01:20 PM
|
#18
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
It would definitely be worth trying to split your processing up with a coroutine to see if that gets the performance somewhere reasonable. They're fairly straightforward to use; if your existing code uses a loop, it's just a few extra commands.
https://www.tutorialspoint.com/lua/lua_coroutines.htm
As far as GUI, might I suggest my Lua library? (Link in my signature)
|
|
|
10-06-2019, 01:22 PM
|
#19
|
Human being with feelings
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
|
Quote:
Originally Posted by Lokasenna
They specifically don't call them "threads" for that reason - Lua calls them coroutines
|
Yes, it's confusing because the underlying primitive type in Lua is called a "thread", while what that is actually used for is coroutines. (Coroutines are not well supported with C++ at the moment, so Lua is actually a bit more powerful in that regard for implementing some things natively.)
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
|
|
|
10-06-2019, 01:25 PM
|
#20
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
Quote:
Originally Posted by Xenakios
Yes, it's confusing because the underlying primitive type in Lua is called a "thread", while what that is actually used for is coroutines.
|
I hadn't noticed that; it does seem like silly choice.
|
|
|
10-06-2019, 01:51 PM
|
#21
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
@Alkamist
Maybe looking into iPlug2 (as has been mentioned) might indeed be a good starting point as it has a Reaper extension example all set up already?
https://github.com/iPlug2/iPlug2/tre...eaperExtension
|
|
|
10-06-2019, 01:52 PM
|
#22
|
Human being with feelings
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
|
Quote:
Originally Posted by Alkamist
I really dislike the idea of using the Win32 library directly. The documentation for my purposes is incredibly sparse and it just seems like a pain to work with to do simple things.
...
I'm looking into this library called SFML that might be good to use. Compiling it and using it within a reaper extension seems to be pretty complicated.
...
whether I should try to be making a batch file to run cl.exe like you did in your example, or if I should be trying to make a VS2019 project file and hook everything up from there. I don't know if I should just include the SFML source code, or if I need to build it to a dynamic or static library.
|
The win32 API is very well documented, each API function has a long explanation at the Microsoft web pages. It will require some effort to get a basic GUI happening at first, though...Also, if you want your code compiled for macOs and/or Linux too, you will have to use a limited subset of the win32 API, as Cockos's Swell library in WDL only implements a small portion of it.
If you are going to use SFML, there's probably no-one who can help you with that when doing Reaper extensions, I am not aware of anyone who would have used that.
But if you are going to use that anyway, you should attempt to build it directly with your project, if at all possible. Dealing with static libraries, or even worse, dynamic libraries, can be quite a headache.
You will of course want to use Visual Studio for large scale development on Windows. The simple example I created used a .bat file for the build because Visual Studio is itself a complicated thing that doesn't directly have to do with Reaper extensions. (And it's kind of a pain to create a Visual Studio project that will work for sure on other people's systems...)
Like was suggested above, maybe trying out IPlug2 could be worth it. I haven't personally tried doing a Reaper extension with it yet.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Last edited by Xenakios; 10-06-2019 at 02:07 PM.
|
|
|
10-06-2019, 02:09 PM
|
#23
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by nofish
@Alkamist
Maybe looking into iPlug2 (as has been mentioned)...
|
IPlug2 seems like a decent option. I was able to get the example up and running. I'm having trouble figuring out how to use it though. I not only want to do GUI stuff, but also have the ability to get user key presses even when a GUI window isn't open. From my initial inspection, it seems like user input is tied to having a window open. I could be wrong about that however.
Quote:
Originally Posted by Xenakios
The win32 API is very well documented, each API function has a long explanation at the Microsoft web pages. It will require some effort to get a basic GUI happening at first, though...Also, if you want your code compiled for macOs and/or Linux too, you will have to use a limited subset of the win32 API, as Cockos's Swell library in WDL only implements a small portion of it.
|
It's well documented on its own, but not for use with reaper extensions. I have no idea where to put any of their example code with respect to opening a window in a reaper extension. All of their documentation seems to assume you are creating a standalone desktop app.
I would like my code to work cross-platform. Is there some sort of documentation on what parts of the win32 I'm allowed to use to maintain compatibility?
|
|
|
10-06-2019, 02:25 PM
|
#24
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
Quote:
Originally Posted by Alkamist
It's well documented on its own, but not for use with reaper extensions. I have no idea where to put any of their example code with respect to opening a window in a reaper extension. All of their documentation seems to assume you are creating a standalone desktop app.
|
Describe a dialog in a resource file (or construct it dynamically) and open it using functions such as CreateDialogParam and DialogBoxParam (for modeless and modal windows respectively).
https://docs.microsoft.com/en-us/win...x/dialog-boxes
Quote:
Originally Posted by Alkamist
I would like my code to work cross-platform. Is there some sort of documentation on what parts of the win32 I'm allowed to use to maintain compatibility?
|
These are the functions SWELL supports: https://github.com/justinfrankel/WDL...ll-functions.h. Some are exclusive to SWELL (eg. BrowseForFiles).
Quote:
Originally Posted by Alkamist
I'm looking into this library called SFML that might be good to use. Compiling it and using it within a reaper extension seems to be pretty complicated. I'm really new with all of these compiler settings and CMake shenanigans. There's also a ton of information to sift through.
|
There are projects such as Microsoft's vcpkg that are designed to help with this. vcpkg can build many libraries with a single command (it has a sfml package in its repository) and integrates into CMake (or MSBuild-based projects).
Quote:
Originally Posted by Alkamist
I not only want to do GUI stuff, but also have the ability to get user key presses even when a GUI window isn't open.
|
The REAPER API allows this: https://forum.cockos.com/showthread.php?p=2081123.
Last edited by cfillion; 10-06-2019 at 03:03 PM.
|
|
|
10-06-2019, 02:48 PM
|
#25
|
Human being with feelings
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
|
Quote:
Originally Posted by Alkamist
also have the ability to get user key presses even when a GUI window isn't open.
|
That is a very bad idea, if the key presses are not supposed to be launching Reaper actions. Users will want to have their usual keyboard shortcuts working when a plugin window isn't in focus. (If key presses are supposed to launch actions, the user should be in full control of that. The design I've decided on is that extension plugins won't register any keyboard shortcuts by default. The user will do it, if he wishes so.)
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
|
|
|
10-06-2019, 03:01 PM
|
#26
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by cfillion
Describe a dialog in a resource file...
|
Thank you for your super helpful post. I'll explore all the things you mentioned.
Quote:
Originally Posted by Xenakios
That is a very bad idea, if the key presses are not supposed to be launching Reaper actions. Users will want to have their usual keyboard shortcuts working when a plugin window isn't in focus. (If key presses are supposed to launch actions, the user should be in full control of that. The design I've decided on is that extension plugins won't register any keyboard shortcuts by default. The user will do it, if he wishes so.)
|
I wasn't super clear on my intention with that. I don't mean that I want the extension to be doing things in the background based on keyboard presses.
Basically I want to remake my Zoom Tool script I did. The way it works is you bind it to a hotkey, which activates it, and while you continue to hold the button it will do zooming based on your mouse movement. When you let go of the button, it stops. None of this opens a graphics window.
So basically I need a way to tell when the user does a key up to tell the program to stop zooming. Ideally it would be the same key that activated the script in the first place.
|
|
|
10-06-2019, 03:24 PM
|
#27
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
Quote:
Originally Posted by Alkamist
So basically I need a way to tell when the user does a key up to tell the program to stop zooming. Ideally it would be the same key that activated the script in the first place.
|
There are some actions in SWS that work like this ('continous actions'), e.g.
SWS/BR: Freehand draw envelope while snapping points to left side grid line (perform until shortcut released).
https://github.com/reaper-oss/sws/bl...nuousActions.h
https://github.com/reaper-oss/sws/bl...ousActions.cpp
|
|
|
10-06-2019, 03:47 PM
|
#28
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by nofish
|
That seems like what I would want. I'll look into it, thanks for the tip!
|
|
|
10-07-2019, 09:45 AM
|
#29
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
I have some more questions regarding C++ extensions for Reaper:
- It looks to me like the SWS extension uses a precompiled header. Is that something I should be doing? If so, how would I go about getting that set up?
- What is the workflow when wanting to use some code someone else has written? For instance, say I want to use something someone has done in the SWS extension; should I just copy the source code files and paste them into my extension directory?
- What C++ standard should I be using? I see a lot of older looking C++ code while browsing around extension source code. Is there some sort of restriction I should be aware of?
- What are some helpful classes/wrappers people have done for working with Reaper stuff? I would like to avoid reinventing the wheel wherever I can.
|
|
|
10-07-2019, 10:25 AM
|
#30
|
Human being with feelings
Join Date: May 2010
Posts: 317
|
Here's what ya might want to do - but it's kind of advanced and might be overly-complicated.
Create a minimal Reaper plug-in (a DLL), and a traditional GUI-based Win32 applicaton (an EXE). Use two message-only windows - one in the DLL, and one in the EXE for inter-process communication. You will do most of your work in the EXE then pass the results back to reaper using window messages. You'll have to create a new thread inside the plug-in's initialization routine, and then in that new thread ... that is where you create the window and pump the message loop.
Let me know if you understand me so far. Maybe you can guess where I'm gong with this. And even if you don't, maybe you can take the ideas I've given you and figure the rest out for yourself.
|
|
|
10-07-2019, 10:32 AM
|
#31
|
Human being with feelings
Join Date: May 2010
Posts: 317
|
Btw - I forgot to mention that you'll have to call CreateProcess() to launch your EXE.
There. I said it.
|
|
|
10-07-2019, 10:34 AM
|
#32
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
Quote:
Originally Posted by Alkamist
- It looks to me like the SWS extension uses a precompiled header. Is that something I should be doing? If so, how would I go about getting that set up?
|
Not required (also SWS only does that on Windows). It can help reduce compilation time when including large complex files over and over in many compilation units.
Quote:
Originally Posted by Alkamist
- What C++ standard should I be using? I see a lot of older looking C++ code while browsing around extension source code. Is there some sort of restriction I should be aware of?
|
Which features you can use depends on which operating system versions you are targeting. For instance, a C++11 standard library is only available on macOS since 10.7 (libc++).
We recently started using C++11 syntax in SWS ("next" branch), but it's limited to an older standard library because it's targeting macOS 10.5.
Quote:
Originally Posted by Alkamist
- What is the workflow when wanting to use some code someone else has written? For instance, say I want to use something someone has done in the SWS extension; should I just copy the source code files and paste them into my extension directory?
|
It depends what/how much I would say. Most source files from SWS would not be very useful once extracted (often easier/better to just rewrite the desired feature).
Quote:
Originally Posted by Alkamist
- What are some helpful classes/wrappers people have done for working with Reaper stuff? I would like to avoid reinventing the wheel wherever I can.
|
I have some wrappers in ReaPack (under LGPL) for some Win32 stuff, timer-based asynchronous cross-thread events, API function registration, action registration that should be reusable. It uses C++17 features.
ConfigVar classes coming soon in SWS (under MIT).
Last edited by cfillion; 10-07-2019 at 10:50 AM.
|
|
|
10-07-2019, 10:56 AM
|
#33
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by cfillion
Not required (also SWS only does that on Windows)...
|
Thanks for the info!
Quote:
Originally Posted by Wanda Previous
Here's what ya might want to do - but it's kind of advanced and might be overly-complicated.
Create a minimal Reaper plug-in (a DLL), and a traditional GUI-based Win32 applicaton (an EXE)...
|
That's probably a bit over my head at the moment unfortunately. Currently, I can't even get a minimal extension to build in Visual Studio, I can only do it with Xenakios' batch file.
I know a decent bit of raw C++ as far as the language is concerned, but I am completely new to doing any development like this. I am entirely self-taught so I lack a lot of foundation in areas like this.
If I can't get what I'm trying to do working, I'll try and work out your post and see if I can do it.
|
|
|
10-07-2019, 12:19 PM
|
#34
|
Human being with feelings
Join Date: Mar 2007
Location: Germany
Posts: 1,539
|
Quote:
Originally Posted by cfillion
|
Interesting thread! Is it possible to create a dynamic dialog on the fly with SWELL? If yes, is there an example?
|
|
|
10-07-2019, 12:37 PM
|
#35
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
This is how dialogs are constructed at runtime by SWELL:
Code:
#include <swell/swell.h>
#include <swell/swell-dlggen.h>
// arbitrary unique identifiers
enum DialogID { IDD_NETCONF_DIALOG = 100 };
enum ControlID { IDC_LABEL = 200, IDC_PROXY, IDC_LABEL2, IDC_STALETHRSH, IDC_VERIFYPEER };
// Register a new dialog ID
// This SWELL_DialogRegHelper object must live forever
// (or update SWELL_curmodule_dialogresource_head when destructing)
static SWELL_DialogRegHelper Register_IDD_NETCONF_DIALOG{
&SWELL_curmodule_dialogresource_head, [](HWND view, int wflags)
{
// Construct a new dialog (HWND view)
SWELL_MakeSetCurParms(1.8, 1.8, 0, 0, view, false, !(wflags&8));
SWELL_MakeLabel(-1, "Proxy:", IDC_LABEL, 5, 8, 20, 10, 0);
SWELL_MakeEditField(IDC_PROXY, 30, 5, 185, 14, ES_AUTOHSCROLL);
SWELL_MakeLabel(-1, "Example: host:port, [ipv6]:port or scheme://host:port",
IDC_LABEL2, 30, 22, 190, 10, 0);
SWELL_MakeCheckBox("&Refresh index cache when older than one week",
IDC_STALETHRSH, 5, 33, 220, 14, BS_AUTOCHECKBOX | WS_TABSTOP);
SWELL_MakeCheckBox("&Verify the authenticity of SSL/TLS certificates (advanced)",
IDC_VERIFYPEER, 5, 45, 220, 14, BS_AUTOCHECKBOX | WS_TABSTOP);
SWELL_MakeButton(1, "&OK", IDOK, 132, 61, 40, 14, 0);
SWELL_MakeButton(0, "&Cancel", IDCANCEL, 175, 61, 40, 14, 0);
},
IDD_NETCONF_DIALOG, 4|8, "Network settings", 220, 80, 1.8
};
// IDD_NETCONF_DIALOG can now be used
Last edited by cfillion; 10-07-2019 at 02:03 PM.
|
|
|
10-07-2019, 12:57 PM
|
#36
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by cfillion
|
I got your example working with simply displaying a message with the key state to the console.
If you don't mind explaining, how would you go about making an action start a loop that is broken when this detects a key up?
|
|
|
10-07-2019, 01:53 PM
|
#37
|
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
|
This uses REAPER's global 30Hz timer (most likely the same as reaper.defer in Lua scripts):
Code:
static void loop()
{
// do something
}
// Start the loop:
//plugin_register("timer", reinterpret_cast<void *>(&loop));
// Stop the loop:
//plugin_register("-timer", reinterpret_cast<void *>(&loop));
|
|
|
10-07-2019, 01:57 PM
|
#38
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by cfillion
This uses (most likely) the same 30Hz timer as reaper.defer in Lua scripts:
Code:
static void loop()
{
// do something
}
// Start the loop:
//plugin_register("timer", reinterpret_cast<void *>(&loop));
// Stop the loop:
//plugin_register("-timer", reinterpret_cast<void *>(&loop));
|
Thanks for the help. I'll see if I can get it working.
That's a shame if it's stuck on 30 Hz. It's not really worth rewriting my script if that's the case.
|
|
|
10-07-2019, 02:13 PM
|
#39
|
Human being with feelings
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
|
Quote:
Originally Posted by Alkamist
That's a shame if it's stuck on 30 Hz. It's not really worth rewriting my script if that's the case.
|
You can use the win32 API SetTimer function directly to get a faster timer on the GUI thread. But of course that doesn't necessarily help anything if you do something expensive in the timer callback function, you would get a sluggish GUI just the same.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
|
|
|
10-07-2019, 02:40 PM
|
#40
|
Human being with feelings
Join Date: Dec 2011
Posts: 506
|
Quote:
Originally Posted by Xenakios
You can use the win32 API SetTimer function directly to get a faster timer on the GUI thread. But of course that doesn't necessarily help anything if you do something expensive in the timer callback function, you would get a sluggish GUI just the same.
|
So if I use an action to start a loop that persists until a key up is received, it has to be on the GUI thread? Or are all actions on the GUI thread or something?
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 08:45 AM.
|