07-25-2021, 07:51 AM
|
#1 |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Hello REAPER scripters,
I'm happy to announce a new library called the REAPER Toolkit (rtk), a GUI and utility library for REAPER Lua scripts, which leverages REAPER's native GFX API without any external dependencies. rtk is born out of the underlying GUI code that powers Reaticulate. I had invested so much time into it that I felt it deserved to be released as an independent library. Visit the project website for documentation and download instructions: https://reapertoolkit.dev What does it look like? rtk was originally written for Reaticulate, which is shown below to serve as a demonstration of rtk's capabilities. ![]() This short screen capture demonstrates several of rtk's features, including:
How does it differ from Scythe (Lokasenna GUI v3)? I suspect this will be a FAQ, so I'll address it here. The core of rtk was written for Reaticulate many years ago so I'm afraid I've not actually used Scythe before. But based on my perusal of Scythe's documentation, I see these key differences:
Like Lokasenna, I wrote my own Lua API doc generation tool (clearly we both recognized how terrible the state of the union was ). LuaDox is available as a separate project.What's Next First and foremost, I am very interested to hear from you folks what you think. Your opinions will certainly help to influence rtk's direction. As of 2022-02-18, the API is considered stable, and there is a documented process that allows for introducing breaking API changes while also not impacting existing scripts. On the subject of widgets, these will be coming soon, mainly because I will need them for Reaticulate (and its infamous any-day-now-honest articulation map GUI editor):
If you have a feature request, feel free to ask here or open an issue on GitHub (or both). So head on over to rtk's website, sift through the tutorial, take rtk out for a spin, and let me know what you think. Happy hacking! Last edited by tack; 02-28-2022 at 05:27 PM. |
|
|
07-25-2021, 10:35 AM
|
#2 |
|
Human being with feelings
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 4,138
|
I couldn't even get past the first line of the introduction example without errors LOL! I have no clue what 'pagage.path' is but after some searching I found an example, not sure if its correct way but the window with button now opens and seems to work.
THANKS for sharing!Code:
-- Test.lua (in same folder as rtk.lua)
--
local path = ({reaper.get_action_context()})[2]:match('^.+[\\//]')
package.path = path .. '/?.lua'
local rtk = require('rtk')
...
Last edited by Edgemeal; 07-25-2021 at 10:45 AM. Reason: removed [[ ]] brackets from "/?.lua" still works |
|
|
07-25-2021, 10:43 AM
|
#3 | |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
https://reapertoolkit.dev/manual/tut...ng_the_library I will move that to the Hello World example on the front page too, to ensure it's copy-pastable. Thanks for the feedback! |
|
|
|
07-25-2021, 01:56 PM
|
#4 | |
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 11,131
|
Looks like a very solid framework, and also a very solid documentation generator, well done and thanks for sharing !
Also, written all this doc for all this tools... that is kind of a hard passionate work ! One other major thing to add to your framework is that it si currently supported, which scythe is not anymore (lokasenna left the boat for an undetermined amount of time). We have been spoiled with nice GUI framemork with cfillion ReaImGui extension these days, and now yours :P I would say that focusing on what ReaImGui can't do would make sense. Scalable text is one of them as far as know. Your box approach CSS like system seems promising. Anyway, I think the priority is to add screenshots to the doc. This would help us a lot to see what we can expect, what we can do etc. Also, I think making the examples reapack compatible could make sense so we can try out of the box. Though I'm curious about distribution model: Quote:
So how do we keep up to date version of rtk ? Does this means than any fix you made have to been pushed by other scripters too ? I think centralized distribution like scythe or reaimgui are quite interesting cause if the extension got a fixed, than all script depending on them will got one. But I guess a scripter could have his own instance of rtk, used by all his script ? Anyway, thanks for all. That is for sure a lot to explore! PS: maybe even a scripting video from scratch could be nice at this point. :P
__________________
Free ReaScripts - Premium Scripts - Custom Scripts Dev - Learn ReaScript - XR Theme - Stash Files - ReaLinks - ReaComics - Donation |
|
|
|
07-25-2021, 02:33 PM
|
#5 |
|
Human being with feelings
Join Date: Dec 2017
Location: Brazil
Posts: 2,118
|
Hey tack thanks for releasing this. I always liked the reaticulate GUI, nice we can use it now uhu!
__________________
How to Reascript| MIDI Transfer| Item Sampler| Track Snapshot| ReaShare| Sample Organizer| Microrhythms| Bartoker| Markov Chains| MIDI Toolkit| Fake Grids| Adaptative Music| It's Gonna Phase Last edited by daniellumertz; 04-03-2023 at 10:08 AM. |
|
|
07-25-2021, 02:49 PM
|
#6 | ||||||
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
![]() Quote:
![]() Quote:
Quote:
Quote:
Having a single installation that all scripts use imposes strict requirements on API stability. It simply won't do to have an rtk update break even a single script. I'm not at the stage yet where I can claim the API is stable. To be clear, I don't have any breaking changes planned, but it's only ever been my eyeballs on this thing, so I'd want to get a bunch more feedback before I make a commitment to not making breaking changes. So having script authors distribute the version of rtk they have developed and tested against in their ReaPacks seems like a reasonable compromise. It mitigates the risk of changes (which could include bug fixes, if the buggy behavior was actually relied upon) made outside the script author's control negatively affecting their scripts. I've tried to make this process relatively simple by bundling the entirety of rtk into one file for distribution. But I am receptive to arguments on this one. And as I gain more confidence with the API's stability I can see myself introducing a centralized distribution via ReaPack, giving script writers the option of whether to bundle their own copy or use the central one. Quote:
Thanks for your feedback X-Raym, I really appreciate it. |
||||||
|
|
07-25-2021, 03:46 PM
|
#7 |
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 11,131
|
@tack
Thanks for your detailed feedback! And nice to see such responsiveness to feedbacks ![]() For distribution, the good thing about having a centralized way is that it can be forked if necessary anyway , and use as if if not needed. ![]() One other question: what have you done for accessibility? tab/maj tab navigation focus between items with enter key to validate a button for eg ? @daniellumertz To not go off topic on this thread too much, I have made a doc file with available library. You will be surprise by the first one (it is note the one you are thinking about!) :P
__________________
Free ReaScripts - Premium Scripts - Custom Scripts Dev - Learn ReaScript - XR Theme - Stash Files - ReaLinks - ReaComics - Donation |
|
|
07-25-2021, 03:55 PM
|
#8 | ||
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
Reaticulate implements keyboard selection and activation of articulations at the application level, but keyboard navigation ought to be better supported in the core. I don't think it would be too hard to implement but being able to allow the user to customize tab focus order needs some consideration. Quote:
|
||
|
|
07-25-2021, 10:04 PM
|
#9 |
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 11,131
|
@tack
Link fixed! For Scythe, I managed to make a focus system with tab navigation and keyboard offset (and even ctrl+keyboard, relevant for sliders). It is simply based on a ID number for the elements and didnt required to mod it. Maybe it doesnt need to be built-in as long as the object property are flexible enough to be able to hook them like that. This would need to be tested in practice to be sure I guess As extra precision I think the first thread should mentioned that this framework is GFX based and has not his own custom render engine (which would be a big diff against ReaImGui for eg). 😊
__________________
Free ReaScripts - Premium Scripts - Custom Scripts Dev - Learn ReaScript - XR Theme - Stash Files - ReaLinks - ReaComics - Donation |
|
|
07-26-2021, 06:58 AM
|
#10 | ||
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
Quote:
Done. Thanks! |
||
|
|
07-31-2021, 04:30 PM
|
#11 |
|
Human being with feelings
Join Date: Aug 2016
Posts: 232
|
Congrats on the release Tack! Can't wait to take it on a test drive!
|
|
|
09-03-2021, 03:32 AM
|
#12 |
|
Human being with feelings
Join Date: Feb 2015
Location: Turkey
Posts: 263
|
You have the best documentation ever. Great work!
Will there be a ReaPack version for RTK? Edit: You've already answered that, sorry.
__________________
ReaKS / KeySwitch Manager for Reaper - Articulation Manager feature request Mastodon/@Ugurcan - @UgurcanFX Last edited by Kabraxis; 09-03-2021 at 04:09 AM. |
|
|
09-03-2021, 07:53 AM
|
#13 |
|
Human being with feelings
Join Date: Feb 2015
Location: Turkey
Posts: 263
|
So I went ahead and tried it with my random digital instrument suggester. It's really easy to use, much like Kivy meets Web. I'm sure I'll be using this even more in the future. Thanks @Tack!
random_instr.gif
__________________
ReaKS / KeySwitch Manager for Reaper - Articulation Manager feature request Mastodon/@Ugurcan - @UgurcanFX |
|
|
09-06-2021, 08:52 AM
|
#14 | |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Thanks!
Quote:
I'd be curious to learn about any initial confusion and headscratchers you ran into while learning the basics (assuming there were any). Obviously as I've been staring at this code for the better part of 4 years, I lack any sort of perspective on this.
|
|
|
|
09-06-2021, 02:26 PM
|
#15 |
|
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 397
|
This is amazing, quite a piece of work!
One design question I have -- had you considered a declarative format for the component definitions? Something like S-expressions or XML/HTML? My one hang-up with imperative UI is that it can get hard to follow the logic since there's no sort of hierarchical/determined visual flow for what gets rendered. And since side-effectful methods can add arbitrary components from anywhere in a codebase, as it grows in size maintainability can become difficult. As an example, some pseudo-code based loosley on Vue.js and then same component translated to pseudo-code imperative function calls: PHP Code:
PHP Code:
PHP Code:
PHP Code:
Having that as an option in the REAPER GUI ecosystem would be awesome. I started to look a while back at how to seriously do this, and the best I could come up with was to create ReaScript bindings to this: It exposes roughly HTML + CSS and uses MVC + 2-way data binding, over C++: PHP Code:
PHP Code:
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
|
|
09-06-2021, 03:42 PM
|
#16 | |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
So something like this can be made possible quite easily: Code:
local win = rtk.Window{
title='My App',
padding=10,
rtk.VBox{
spacing=10,
rtk.HBox{
spacing=5,
valign='center',
rtk.Text{'Magic Button:'},
rtk.Button{
'Click Me',
onclick=function(self)
self:attr('label', 'I was clicked')
self:animate{'color', dst='red'}
end
}
},
rtk.CheckBox{
'Enable borderless window',
onchange=function(self)
self.window:attr('borderless', self.value)
end,
},
},
}
win:open()
(Would be nice if Reaper's native XML parsing was exposed to Lua.)And the main gap that would still need to be addressed is some way to reference declared widgets in event handler functions. This is almost a problem in the onchange() handler in the above example, except that the rtk.Window happens to be accessible as an attribute on every widget, so I get away with it in my example. But suppose the onclick() handler for the button wanted to modify the rtk.CheckBox below it, this wouldn't be possible currently. (At least not without manually doing a traversal of the widget hierarchy from the window, which is lame.) So the obvious solution here is borrow more ideas from the DOM and allow a user-custom "id" attribute (which currently is just a monotonically increasing number per widget), and then offer a global function, say rtk.id(), to lookup widgets by their custom ids. I'm not sure about the ergonomics of that approach, but the real concern is that by maintaining global references to all widgets we much more easily get into dangerous territory with memory leaks (inasmuch as the program has abandoned with the widget but there remains a global reference to it). I know Lua supports weak tables, and that'd definitely be required here, but I don't know if there be dragons with weak tables. (They can get tricky in other languages.) And finally once you start building UIs that way, you're very quickly going to want something like CSS to manage the inevitable boilerplate. ![]() I think I'll go ahead and add the code to support passing children on constructors like shown above (it's only like 5 extra lines). (Edit: this is committed now). The problem of how to reference widgets declared in this way warrants some more thought, so I'd be grateful to hear opinions on that. Last edited by tack; 09-07-2021 at 04:39 PM. |
|
|
|
09-11-2021, 10:10 AM
|
#17 | ||
|
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 397
|
Quote:
I've thought this same thing, and I do see one "easy"-ish implementation. There are Lua templating engines which are self-contained and have no dependencies, the ones I could find were: With "Liluat" looking the better of the two, since it supports import of other templates and arbitrary expression evaluation (whereas Mustache is logic-less) Code:
local liluat = require("liluat")
local template = [[
<body>
<h1>Welcome to {{= title}}<h1>
<h1>Vegetables</h1>
<ul>
{{ -- write regular lua code in the template}}
{{for _,vegetable in ipairs(vegetables) do}}
<li><b>{{= vegetable}}</b></li>
{{end}}
</ul>
</body>
]]
-- values to render the template with
local values = {
title = "A fine selection of vegetables.",
vegetables = {
"carrot",
"cucumber",
"broccoli",
"tomato"
}
}
-- compile the template into lua code
local compiled_template = liluat.compile(template)
local rendered_template = liluat.render(compiled_template, values)
io.write(rendered_template)
PHP Code:
The second step is to use a self-contained Lua XML parser to parse the generated XML into Lua tables. Then, programmatically render the components the XML describes. (This requires the S-Expression capable UI library) So you could use https://github.com/manoelcampos/xml2lua Quote:
![]() So just imagine that the template was something like: Code:
local template = [[
<VBox>
<Text>Welcome to {{= title}}</Text>
<Text>Vegetables</Text>
<List>
{{ -- write regular lua code in the template}}
{{for _,vegetable in ipairs(vegetables) do}}
<ListItem><b>{{= vegetable}}</ListItem>
{{end}}
</List>
</VBox>
]]
--- I would probably write my "template" files for components separately, in like IE a ".lua.xml" file or something, and then read from it just for code cleanliness and organization
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
||
|
|
09-11-2021, 10:52 AM
|
#18 | |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
I'm somewhat debating how I want variable scoping to work with expressions in the RML, though I think I have that sorted out. (At first I went with a dynamic scope approach but decided that's probably too clever, so will stick with lexical scoping, where the environment of executed code is determined at compile time, but can be explicitly overridden by passing a table at render time.) The approach I'm taking around conditionals and loops is more inspired by Vue, which you mentioned in your earlier post, and which I myself am familiar with from other projects. So my earlier example could be rewritten as: Code:
function magic_click(self, event)
self:attr('label', 'I was clicked')
self:animate{'color', dst='red'}
end
local window = rml[[
<window title='My App' padding=10>
<vbox spacing=10>
<hbox spacing=5 valign=center>
<text>Magic Button:</text>
<button onclick=magic_click>Click Me</button>
</hbox>
<checkbox if="rtk.has_js_reascript_api" onchange="self.window:attr('borderless', self.value)">
Toggle borderless window
</checkbox>
</vbox>
</window>
]]
window:open()
Mustache syntax is supported, both in attribute values as well as element content. But not for control flow -- that would be handled by the "if" and "for" attributes, a la Vue. I still need to think about how for loops should work. Using a Lua expression is actually not straightforward to implement. I'll probably end up with a custom syntax that supports looping over tables, or iterating N times. There is a risk here that with all this capability, reactivity will be assumed. But reactive updates are a whole other level of complexity entirely, and while it would undoubtedly be cool, it's hard to justify the effort at this stage. Anyway, thanks for raising this to the foreground. I too wanted it early on, but it seemed a bit too ambitious, so I mainly just made sure to have a design to easily support S-expressions, knowing something XML-like would require it, so I could revisit this later. Now that I'm on the other side of rtk's design, implementing this doesn't seem like it will be too onerous. My code is still extremely experimental though, so who knows what dragons lurk around upcoming corners. The question of how to access arbitrary widgets from event handlers still needs to be solved. There isn't (and almost certainly won't be) a CSS-like selector capability, so something like custom ids and rtk.id() is my best idea. Interested to hear your thoughts on that. Last edited by tack; 09-11-2021 at 10:59 AM. |
|
|
|
09-11-2021, 02:52 PM
|
#19 | |||
|
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 397
|
Quote:
I've been writing Vue professionally since ~2016, right around the time Vue 2.0 was released, and I've written (nearly) everything. From oldschool server-rendered templates -> jQuery -> old Angular.js -> React before Redux et all existed, whatnot. Vue is simply the easiest/most productive and intuitive approach to modeling and building applications I've ever had the pleasure of working with. I used to speak frequently at Vue.js events. Anyways, about this point: Quote:
Then inject the dynamically evaluated result into the child template, aliased as the "for" variable in the closure If you're like me, then trying to understand anything more complex than a potato described with words is impossible to follow, so here's roughly what I am trying to say: (Note: Using EmmyLua annotations for type-safety https://emmylua.github.io/annotations/type.html) Code:
---@alias ForOfExpression {for: string, of: string}
---@type fun(expr: string): ForOfExpression
function parse_for_of_expression(expr)
-- Match "for=" content in EG: <text for="item in items">
local pattern = "(%a+) [in|of] (%a+)"
local _, _, alias, variable = string.find(expr, pattern)
---@type ForOfExpression
local for_of_expression = { for = alias, of = variable }
return for_of_expression
end
---@type fun(for_of_table: ForOfExpression): any
function get_for_of_variable_from_lexical_scope(for_of_expression)
return loadstring(for_of_expression.of)
end
function render_for_of_template(template)
local for_of_expression = parse_for_of_expression(fill_me_in)
local value_bound_to_of = get_for_of_variable_from_lexical_scope(for_of_expression)
return render_template(template)
.with_value(value_bound_to_of)
.as(for_of_expression.for)
end
Quote:
I wrote my own (shitty, just for fun) JS framework, including my own JSX rendering implementation and reactive data + rendering part, and managed to do it in about 60 lines by re-using Vue's low-level reactive() type. In reaction to data being changed, I just re-called "render()" and passed in the updated state, check this out: https://gist.github.com/GavinRay97/a...a89e9236994ca6 PHP Code:
PHP Code:
https://github.com/bjornbytes/RxLua I'm sure it's not going to be this simple, but something roughly like: Code:
local Rx = require('rx')
local state = {
name = "Person",
age = 25,
list = { 1, 2, 3 }
}
local reactive_state = Rx.Observable.of(state)
render_template(some_template, reactive_state)
reactive_state:subscribe(function(updated_state)
render_template(some_template, updated_state)
end)
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) Last edited by gxray; 09-11-2021 at 03:04 PM. |
|||
|
|
09-11-2021, 03:08 PM
|
#20 | |
|
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 397
|
Also about this:
Quote:
https://v3.vuejs.org/guide/compositi...late-refs.html You're probably familiar with them, and you can call it whatever you like, but refs were created for exactly this purpose (need to reference a component programmatically that there's no means of getting a handle to). PHP Code:
--- Oh and a random neat thing I want to point out -- EmmyLua has support for "tagging" string template types as being another language, and then your IDE will use that language for syntax highlighting: So my IDE would use proper XML highlighting inside of Lua files when writing your component templates. Amazing!
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) Last edited by gxray; 09-11-2021 at 03:19 PM. |
|
|
|
10-27-2021, 04:20 PM
|
#21 | |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
Code:
local entries = rtk.reactive({{'Background', '#2f2f2f'}, {'Foreground', '#ffffff'}})
local window = rtk.rml[[
<window>
<vbox>
<hbox for="(label, placeholder) in entries" spacing=5>
<text>{{ label }}:</text>
<entry :placeholder="placeholder"></entry>
</hbox>
</vbox>
</window>
]]
window:open()
rtk.callafter(1, function()
entries[#entries+1] = {'Accent', '#47abff'}
end)
I may have a go at it anyway, because obviously it's cool to have this level of reactivity. But my basic point is that once you dip your toes in the reactive pool, it ends up turning into a deeper lake before long.
Last edited by tack; 10-27-2021 at 04:25 PM. |
|
|
|
12-17-2021, 03:42 PM
|
#22 |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Just wanted to give a heads up that I recently committed a breaking change for rtk.scale: instead of a scalar value controlling the overall UI scale, rtk.scale is now a table that reflects the various sources that influence UI scale -- namely the OS, REAPER's custom scale modifier (in the Advanced UI/system tweaks config), and the application's own custom scale factor.
What used to be rtk.scale is now rtk.scale.user, and an explicit rtk.Window:queue_reflow() is no longer needed after setting this value. With this change, rtk apps will automatically respect the OS scale setting, at least for Windows and OS X. On Windows, system DPI changes are dynamically reflected. I'll generally try to avoid breaking changes to the API, but as I'm not aware of a lot of rtk users, I figured it was worth striking while the iron was hot. |
|
|
12-22-2021, 09:33 AM
|
#23 |
|
Human being with feelings
Join Date: Feb 2016
Location: Hollyweird
Posts: 2,796
|
Thank you so much for rtk, tack! This is AMAZING. Love the detailed documentation.
I'm thinking I might be able to draw boxes around items pretty easily with rtk, like what I was trying to do when I started this thread. Would it be possible to draw a box around some items, and allow the user to resize the box only horizontally? Obviously it would also need to follow the items' location and (zoom) size in the Arrange window... Last edited by MonkeyBars; 12-22-2021 at 09:49 AM. |
|
|
12-22-2021, 09:39 AM
|
#24 | |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
This isn't something REAPER explicitly supports, but with some elbow grease it's possible.
|
|
|
|
12-22-2021, 10:09 AM
|
#25 | |
|
Human being with feelings
Join Date: Feb 2016
Location: Hollyweird
Posts: 2,796
|
Quote:
By elbow grease, I assume you mean things like detecting item area via its position + track height etc., and setting up defer to detect Arrange zoom/scroll changes and updating the location of the rtk.Box? What about allowing only horizontal resize of a rtk.Box? |
|
|
|
12-22-2021, 10:27 AM
|
#26 | |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
To be clear, this isn't something rtk can do. Unless there's a way to use js_ReaScriptAPI to take a ReaScript gfx window and somehow chroma-key and composite it over REAPER's hwnds -- and I'm not aware of this capability -- I don't think you can use rtk for your idea. Because rtk is meant for building GUIs within separate ReaScript gfx windows, not drawing arbitrarily over REAPER-native hwnds. It's possible I've completely misunderstood what you're going for though. My reading is that you want to draw customizations over REAPER-native elements (in this case, items in the arrange view), not have a script GUI in a separate floating or docked window. If that's the case, I don't think rtk is right for this. The closest analog I could think of was Julian's multitool because it does this trick of drawing over REAPER-owned hwnds (not ReaScript gfx windows). But because of that, it's also had a history of being visually brittle, and making it work robustly has taken Julian some effort. AFAICT you want to not only draw over the arrange view, but track scrolling/zooming as well and keep things synced. My sense is this is going to be much, much harder than you think. I recommend asking Julian in the js_ReaScriptAPI thread as he's probably most qualified to comment on what kind pain would await you.
|
|
|
|
12-22-2021, 10:43 AM
|
#27 |
|
Human being with feelings
Join Date: Feb 2016
Location: Hollyweird
Posts: 2,796
|
Yes not only in code labor time, but also the hit to performance by having to run a bunch of defer code to detect all that stuff... think I'll pass!
However I look forward to diving into rtk for my script's simple settings window with checkbox options
|
|
|
12-27-2021, 10:49 AM
|
#28 |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
A couple new classes added to rtk that improve support for scalable interfaces. rtk has always emphasized responsive design through resizable container classes, and now images can be responsive as well.
The documentation is hopefully clear enough. Let me know if you have any questions. I've also added a new section to the tutorial. Of course you still need to do the work to build image packs containing different resolutions (ImageMagick makes this much easier if you're comfortable on the CLI), but once that's in place, you can use a multi-DPI image (rtk.MultiImage) for any widget attribute that takes an image, and the appropriate DPI variant is automatically selected. With this, and the recent changes to rtk.scale I mentioned a couple weeks ago, I'm pretty happy with how rtk-based applications behave on high-DPI systems. Here's a demonstration with Reaticulate. In the upcoming release, all icons will contain 1x, 1.5x, and 2x variants.
|
|
|
12-27-2021, 10:51 AM
|
#29 |
|
Human being with feelings
Join Date: Feb 2016
Location: Hollyweird
Posts: 2,796
|
Nice! Well done tack
|
|
|
01-08-2022, 12:44 PM
|
#30 | |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
rtk's current model is to have you distribute rtk with your script (either as a single bundled script file or separately, based on your preference). The main benefit of this is guaranteed compatibility. Is this an obstacle to adoption, in your opinion? Is asking your script users to install a separate ReaPack for rtk so you don't need to distribute it your preference? Thanks! |
|
|
|
01-08-2022, 01:42 PM
|
#31 | |
|
Human being with feelings
Join Date: Feb 2016
Location: Hollyweird
Posts: 2,796
|
Quote:
|
|
|
|
01-08-2022, 02:15 PM
|
#32 | |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
The reality is most things can be made backward compatible with some sacrifice to code maintenance or API ergonomics. The recent change I made to rtk.scale is an example where I broke the API by changing rtk.scale from a scalar value to a table with multiple fields. If I was desperate to avoid breaking anything, I'd have just put the new logic under rtk.scale2 or something similarly lame. But ultimately if rtk's current distribution model is hindering adoption and moving to central ReaPack-managed deployment would improve, I'm quite willing to voluntarily wear those handcuffs. I see a lot of activity on the Lokasenna GUI thread where people are raising bugs or struggling with things that are absolutely trivial with rtk, and curbing my desire to respond to each one of those posts with "well here's how you'd do it with rtk" is painful. ![]() The ReaPack model I am contemplating would work like this:
For example, the ReaPack might contain:
Scripters targeting the ReaPack deployment would import it this way: Code:
package.path = reaper.GetResourcePath() .. '/Scripts/rtk/2/?.lua' local rtk = require 'rtk' Lokasenna's approach of storing the library location via global state has the drawback in that it requires the end user to run an action first, and inflates the boilerplate for each script that uses the library. The only reason I can see for doing it this way is if install path for ReaPack content isn't guaranteed to be relative to reaper.GetResourcePath() .. '/Scripts' but I can't think of a scenario where this wouldn't be the case. I have to imagine this would be nicer for consumers of the library. But as it's more constraining for me, I really only want to do it if rtk's (few AFAICT) current users, or its potential future users would prefer this approach. |
|
|
|
01-08-2022, 03:57 PM
|
#33 | |
|
Human being with feelings
Join Date: Feb 2016
Location: Hollyweird
Posts: 2,796
|
Quote:
225kb is a bit large to have to include in one's script pack, imo. |
|
|
|
01-20-2022, 08:18 AM
|
#34 |
|
Human being with feelings
Join Date: Feb 2016
Location: Hollyweird
Posts: 2,796
|
Hello tack,
Last nite I finally got to sit down and integrate rtk into my script... and it was SUCH a pleasure to use! Extremely easy and straightforward due to the architecture and superb documentation. (To be fair, a big reason I chose it was not only due to the docs but also my background as a pro web dev.) Thank you SO much! Please DM me if you'd like to try out the beta. My usage of rtk is absolutely nothing sophisticated; I'm just happy I was able to implement my script options window in like 1 hour. Last edited by MonkeyBars; 01-20-2022 at 08:26 AM. |
|
|
01-20-2022, 10:47 AM
|
#35 |
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 11,131
|
@monkey_bars
Can you show us a screenshots ? Or is it too soon ? :P
__________________
Free ReaScripts - Premium Scripts - Custom Scripts Dev - Learn ReaScript - XR Theme - Stash Files - ReaLinks - ReaComics - Donation |
|
|
01-20-2022, 01:55 PM
|
#36 |
|
Human being with feelings
Join Date: Feb 2016
Location: Hollyweird
Posts: 2,796
|
|
|
|
01-20-2022, 02:48 PM
|
#37 |
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 11,131
|
@Monkey_Bars
I'll wait for the full show then :P Thx !
__________________
Free ReaScripts - Premium Scripts - Custom Scripts Dev - Learn ReaScript - XR Theme - Stash Files - ReaLinks - ReaComics - Donation |
|
|
01-20-2022, 07:00 PM
|
#38 | ||
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
Quote:
|
||
|
|
01-31-2022, 12:21 PM
|
#39 |
|
Human being with feelings
Join Date: Oct 2017
Location: Black Forest
Posts: 5,253
|
I'm just doing my first baby steps with rtk on my mobile coding rig (MacBook Air M1) and every time I run the hello world example from here:
https://reapertoolkit.dev/index.html#hello_world I get a huge window: https://i.imgur.com/VNFfVpX.png Yes, that window with the border is the actual scripting window. I don't see any controls at all. It's just a grey window and when I try to resize it, REAPER crashes immediately. Any ideas what could cause this?
__________________
My Reascripts forum thread | My Reascripts on GitHub If you like or use my scripts, please support the Ukraine: Ukraine Crisis Relief Fund | DirectRelief | Save The Children | Razom Last edited by _Stevie_; 02-19-2022 at 03:55 PM. |
|
|
01-31-2022, 12:32 PM
|
#40 | |
|
Human being with feelings
Join Date: Jan 2014
Location: Ontario, Canada
Posts: 1,639
|
Quote:
Stephan would you be ok opening an issue at https://github.com/jtackaberry/rtk/issues ? I anticipate some back-and-forth, if you're willing to help. My immediate thought is to try explicitly specifying the window geometry and see if that does anything different: Code:
local window = rtk.Window{x=0, y=0, w=800, h=600}
Thanks! |
|
|
|
![]() |
| Thread Tools | |
|
|