![]() |
#1 |
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 5,336
|
![]()
REAPER Immediate-Mode Graphical User Interface
ReaImGui is a ReaScript binding and REAPER backend for the Dear ImGui toolkit. It adds over 390 API functions (more than 900 including constants!) for creating multi-window GPU-rendered user interfaces in Lua, C++, EEL or Python. This REAPER extension plugin can be installed using ReaPack via the default ReaTeam Extensions repository. ![]() About Dear ImGui Dear ImGui is an implementation of the immediate-mode GUI paradigm. Applications using this paradigm create their GUI on the fly without retaining and managing the UI toolkit's state themselves. This is particularly well suited to ReaScripts by making use of the global 33Hz timer to describe each UI frames. See Dear ImGui's README and FAQ for more information. Example code #1 ![]() This example shows the bare-minimum code to display a window in Lua. C++, EEL and Python examples are here. Code:
package.path = reaper.ImGui_GetBuiltinPath() .. '/?.lua' local ImGui = require 'imgui' '0.9.3' local ctx = ImGui.CreateContext('My script') local function loop() local visible, open = ImGui.Begin(ctx, 'My window', true) if visible then ImGui.Text(ctx, 'Hello World!') ImGui.End(ctx) end if open then reaper.defer(loop) end end reaper.defer(loop) ![]() This example loads a system font and receives user input. Code:
if not reaper.ImGui_GetBuiltinPath then return reaper.MB('ReaImGui is not installed or too old.', 'My script', 0) end package.path = reaper.ImGui_GetBuiltinPath() .. '/?.lua' local ImGui = require 'imgui' '0.9.3' local font = ImGui.CreateFont('sans-serif', 13) local ctx = ImGui.CreateContext('My script') ImGui.Attach(ctx, font) local click_count, text = 0, 'The quick brown fox jumps over the lazy dog' local function myWindow() local rv if ImGui.Button(ctx, 'Click me!') then click_count = click_count + 1 end if click_count % 2 == 1 then ImGui.SameLine(ctx) ImGui.Text(ctx, [[hello dear imgui! \o/]]) end rv, text = ImGui.InputText(ctx, 'text field', text) end local function loop() ImGui.PushFont(ctx, font) ImGui.SetNextWindowSize(ctx, 400, 80, ImGui.Cond_FirstUseEver) local visible, open = ImGui.Begin(ctx, 'My window', true) if visible then myWindow() ImGui.End(ctx) end ImGui.PopFont(ctx) if open then reaper.defer(loop) end end reaper.defer(loop) Dear ImGui comes with a comprehensive demo application showcasing most features. A ReaScript port is installed along with the extension as ReaImGui_Demo.lua. Use Tools > Item Picker to quickly identify the source code location of a widget using the mouse. ![]() Documentation A custom documentation is accessible via the ReaImGui menu > Documentation in the demo script or online: reaper_imgui_doc.html. It adds categorization of the entire API, default argument values, minimum ReaImGui version, improved function signatures, additional descriptions, code snippets and callback functions/variables not present in the standard ReaScript documentation. ![]() Learning resources
gfx to ReaImGui translation Lua scripts can use a translation layer to re-implement most gfx functions using ReaImGui (discussion thread): Code:
package.path = reaper.ImGui_GetBuiltinPath() .. '/?.lua' gfx = require 'gfx2imgui' Adds awareness of the Lua API with complete documentation in any editor supporting the Lua Language Server. Download the latest imgui_defs.lua or install @Perken's extension for Visual Studio Code. Minimum system requirements REAPER v5.979 (v7.15 or newer recommended) Linux, macOS 10.9 or Windows Vista Required system libraries on Linux: GDK3 3.22, freetype, libepoxy, libpng, libstdc++ for GCC 5.1 Contributing The source code is available under LGPLv3 on GitHub. Patches (including documentation edits) may be submitted as pull requests. Report bugs on the issue tracker.
__________________
🎁 Donate (PayPal) | Sponsor (GitHub) | The Endless Journey (Keyboard Ensemble) ReaPack, a package manager for REAPER | SWS 2.14 is now available in ReaPack [new!] Developer tools: Lua profiler | Interactive ReaScript | ReaPack Editor | ReaImGui Last edited by cfillion; 09-20-2024 at 11:58 PM. Reason: update for 0.9.3 |
![]() |
![]() |
![]() |
#2 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
HUGE MOMENT
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
![]() |
![]() |
![]() |
#3 |
Human being with feelings
Join Date: Oct 2017
Location: Larisa, Greece
Posts: 4,125
|
![]()
Awesome! I just wish to see in future scripts a universal size of the GUI for the docked scripts. This would be very useful and way more clean to work with.
An example is Ableton or Bitwig devices, where they have the same height in the docker and you can navigate and choose easier the parameters. |
![]() |
![]() |
![]() |
#4 |
Human being with feelings
Join Date: Oct 2017
Location: Black Forest
Posts: 5,214
|
![]()
__________________
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 |
![]() |
![]() |
![]() |
#5 |
Human being with feelings
Join Date: Jan 2007
Location: mcr:uk
Posts: 3,942
|
![]()
Awww man, not another thing to look into! LOL!
![]() |
![]() |
![]() |
![]() |
#6 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
For those who might not be familiar, brief examples of the kinds of UI's which have been built using ImGUI:
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
![]() |
![]() |
![]() |
#7 |
Human being with feelings
Join Date: Dec 2017
Location: Brazil
Posts: 2,082
|
![]()
woooooow this exemples are neat!
Thanks a lot for bringing this to reaper ! :O Can't wait to see more GUI Exemples using this, will try probably this week to do one! |
![]() |
![]() |
![]() |
#8 |
Human being with feelings
Join Date: Apr 2014
Posts: 404
|
![]()
If I understand well, this is really, REALLY cool!
Your contributions to the community are so impactful! THANK YOU! |
![]() |
![]() |
![]() |
#9 |
Human being with feelings
Join Date: Dec 2017
Location: Brazil
Posts: 2,082
|
![]()
cfillion do you know if there is a place I can look/search the functions/methods?
I am looking at their git but a little confused as the info is sparsed in pages, wondering if there is a list that I just didn't found. Also I can import images with your version? Looking at the code in the big example nice work! Thanks a lot again! |
![]() |
![]() |
![]() |
#10 |
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 5,336
|
![]()
REAPER's built-in ReaScript documentation (Help menu) is the best way to find all functions (and descriptions). All functions start with "ImGui_".
No images (or custom font) support at this time, but it's something I'd like to add.
__________________
🎁 Donate (PayPal) | Sponsor (GitHub) | The Endless Journey (Keyboard Ensemble) ReaPack, a package manager for REAPER | SWS 2.14 is now available in ReaPack [new!] Developer tools: Lua profiler | Interactive ReaScript | ReaPack Editor | ReaImGui Last edited by cfillion; 03-06-2021 at 08:01 PM. |
![]() |
![]() |
![]() |
#11 |
Human being with feelings
Join Date: Dec 2017
Location: Brazil
Posts: 2,082
|
![]()
ohh, I didn't know they would start to appear there that is coooolll! Thanks, will continue here!
![]() |
![]() |
![]() |
![]() |
#12 |
Human being with feelings
Join Date: Sep 2018
Location: China
Posts: 574
|
![]()
Is there any document about how to use it?
EDIT:Found it! Thanks! Last edited by dsyrock; 03-06-2021 at 09:39 PM. |
![]() |
![]() |
![]() |
#13 |
Human being with feelings
Join Date: Dec 2017
Location: Brazil
Posts: 2,082
|
![]()
Hey this is amazing !
I really would like to see more examples as people do, I will share mine that did for study the lib. Also having a hard time creating a menu if someone have a simple example... ![]() Code:
r = reaper local click_count, text = 0, '' local ctx = reaper.ImGui_CreateContext('Not Midi Transfer', 300, 325) layer = 1 function print(a) reaper.ShowConsoleMsg('\n'..tostring(a)) end function HelpMarker(desc) -- Function to show a ? reaper.ImGui_TextDisabled(ctx, '(?)') if reaper.ImGui_IsItemHovered(ctx) then reaper.ImGui_BeginTooltip(ctx) reaper.ImGui_PushTextWrapPos(ctx, reaper.ImGui_GetFontSize(ctx) * 35.0) reaper.ImGui_Text(ctx, desc) reaper.ImGui_PopTextWrapPos(ctx) reaper.ImGui_EndTooltip(ctx) end end function ToolTip(text) if reaper.ImGui_IsItemHovered(ctx) then reaper.ImGui_BeginTooltip(ctx) reaper.ImGui_PushTextWrapPos(ctx, reaper.ImGui_GetFontSize(ctx) * 35.0) reaper.ImGui_Text(ctx, text) reaper.ImGui_PopTextWrapPos(ctx) reaper.ImGui_EndTooltip(ctx) end end function loop() local rv if reaper.ImGui_IsCloseRequested(ctx) then reaper.ImGui_DestroyContext(ctx) return end local window_flags = reaper.ImGui_WindowFlags_MenuBar() | reaper.ImGui_WindowFlags_NoDecoration() reaper.ImGui_SetNextWindowPos(ctx, 0, 0) reaper.ImGui_SetNextWindowSize(ctx, reaper.ImGui_GetDisplaySize(ctx)) reaper.ImGui_Begin(ctx, 'Window', nil, window_flags) ---------------------------------------- ---------------------------------------² ----------------------------------------- ---- GUI if reaper.ImGui_BeginMenuBar(ctx) then if reaper.ImGui_BeginMenu(ctx, 'File') then if reaper.ImGui_MenuItem(ctx, 'Open') then reaper.ShowConsoleMsg('opening...\n') end if reaper.ImGui_MenuItem(ctx, 'Save') then reaper.ShowConsoleMsg('saving...\n') end reaper.ImGui_EndMenu(ctx) end reaper.ImGui_EndMenuBar(ctx) end if reaper.ImGui_Button(ctx, 'Click me!') then click_count = click_count + 1 reaper.ShowConsoleMsg("aaa") end reaper.ImGui_SameLine(ctx) reaper.ImGui_Text(ctx, [[\o/]]) reaper.ImGui_SameLine(ctx) HelpMarker('Need a help friend?\nI once took an arrow in the kneww') ------------ rv, text = reaper.ImGui_InputText(ctx, 'text input', 'thanks cfillion '..tostring(click_count)) ------------- Slider if not v then v = 5 end retval, v = reaper.ImGui_SliderDouble(ctx, 'Log', v, 10, 30, v, reaper.ImGui_SliderFlags_Logarithmic()) -- Window, Name, Value, Min, Max, opt string in the middle, flags for log or stuff -------------- Checkbox if not type(bol) then bol = true end rc, bol = r.ImGui_Checkbox(ctx, 'What do you want from me', bol) -------------- Radio if not val then val = 1 end rv, val = r.ImGui_RadioButtonEx(ctx, 'radio a', val, 0); r.ImGui_SameLine(ctx) rv, val = r.ImGui_RadioButtonEx(ctx, 'radio b', val, 1); r.ImGui_SameLine(ctx) rv, val = r.ImGui_RadioButtonEx(ctx, 'radio c', val, 2) -------------- Many Butto funny for i = 0, 4 do if i > 0 then r.ImGui_SameLine(ctx) end r.ImGui_PushID(ctx, i) local buttonColor = reaper.ImGui_ColorConvertHSVtoRGB(i / 7.0, 0.6, 0.6, 1.0) local hoveredColor = reaper.ImGui_ColorConvertHSVtoRGB(i / 7.0, 0.7, 0.7, 1.0) local activeColor = reaper.ImGui_ColorConvertHSVtoRGB(i / 7.0, 0.8, 0.8, 1.0) r.ImGui_PushStyleColor(ctx, r.ImGui_Col_Button(), buttonColor) r.ImGui_PushStyleColor(ctx, r.ImGui_Col_ButtonHovered(), hoveredColor) r.ImGui_PushStyleColor(ctx, r.ImGui_Col_ButtonActive(), activeColor) r.ImGui_Button(ctx, 'Click') r.ImGui_PopStyleColor(ctx, 3) r.ImGui_PopID(ctx) ToolTip('Can you eat buttons?') if reaper.ImGui_IsItemClicked( ctx) then print("You Can! But Just "..i+1) end end ------------------------------------ Above again r.ImGui_PushID(ctx, 0) if not vari then vari = 0.01 end if not hues then hues = 0 end hues = hues + vari local buttonColor = reaper.ImGui_ColorConvertHSVtoRGB( 0.1+hues, 0.6, 0.6, 1.0) local hoveredColor = reaper.ImGui_ColorConvertHSVtoRGB( 7.0, 0.7, 0.7, 1.0) local activeColor = reaper.ImGui_ColorConvertHSVtoRGB( 7.0, 0.8, 0.8, 1.0) r.ImGui_PushStyleColor(ctx, r.ImGui_Col_Button(), buttonColor) r.ImGui_PushStyleColor(ctx, r.ImGui_Col_ButtonHovered(), hoveredColor) r.ImGui_PushStyleColor(ctx, r.ImGui_Col_ButtonActive(), activeColor) r.ImGui_Button(ctx, 'Danger', 250, 100) retval, vari = reaper.ImGui_SliderDouble(ctx, 'H', vari, 0, 0.2) -- Window, Name, Value, Min, Max, opt string in the middle, flags for log or stuff r.ImGui_PopStyleColor(ctx, 3) r.ImGui_PopID(ctx) -------------------------------------- --------------------------------------- -------------------------------------- reaper.ImGui_End(ctx) reaper.defer(loop) end loop() Here another one that might help someone It is the simplest I could get, like a blank GUI, with nothing in it just open the screen (there is two options lines). Code:
function GuiInit() ctx = reaper.ImGui_CreateContext('Item Sequencer') -- Add VERSION TODO FONT = reaper.ImGui_CreateFont('sans-serif', 15) -- Create the fonts you need reaper.ImGui_AttachFont(ctx, FONT)-- Attach the fonts you need end function loop() local window_flags = reaper.ImGui_WindowFlags_MenuBar() reaper.ImGui_SetNextWindowSize(ctx, 250, 300, reaper.ImGui_Cond_Once())-- Set the size of the windows. Use in the 4th argument reaper.ImGui_Cond_FirstUseEver() to just apply at the first user run, so ImGUI remembers user resize s2 reaper.ImGui_PushFont(ctx, FONT) -- Says you want to start using a specific font local visible, open = reaper.ImGui_Begin(ctx, 'Robert Green Blue ', true, window_flags) if visible then -------- --YOUR GUI HERE -------- reaper.ImGui_End(ctx) end reaper.ImGui_PopFont(ctx) -- Pop Font if open then reaper.defer(loop) else reaper.ImGui_DestroyContext(ctx) end end GuiInit() loop() Last edited by daniellumertz; 08-26-2021 at 10:08 PM. |
![]() |
![]() |
![]() |
#14 | |
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 5,336
|
![]() Quote:
Code:
local window_flags = reaper.ImGui_WindowFlags_MenuBar() | reaper.ImGui_WindowFlags_NoDecoration() reaper.ImGui_SetNextWindowPos(ctx, 0, 0) reaper.ImGui_SetNextWindowSize(ctx, reaper.ImGui_GetDisplaySize(ctx)) reaper.ImGui_Begin(ctx, 'Window', nil, window_flags) if reaper.ImGui_BeginMenuBar(ctx) then if reaper.ImGui_BeginMenu(ctx, 'File') then if reaper.ImGui_MenuItem(ctx, 'Open') then reaper.ShowConsoleMsg('opening...\n') end if reaper.ImGui_MenuItem(ctx, 'Save') then reaper.ShowConsoleMsg('saving...\n') end reaper.ImGui_EndMenu(ctx) end reaper.ImGui_EndMenuBar(ctx) end reaper.ImGui_End(ctx)
__________________
🎁 Donate (PayPal) | Sponsor (GitHub) | The Endless Journey (Keyboard Ensemble) ReaPack, a package manager for REAPER | SWS 2.14 is now available in ReaPack [new!] Developer tools: Lua profiler | Interactive ReaScript | ReaPack Editor | ReaImGui |
|
![]() |
![]() |
![]() |
#15 |
Human being with feelings
Join Date: Dec 2017
Location: Brazil
Posts: 2,082
|
![]()
Thanks Cfillion!
![]() ![]() ![]() ![]() ![]() I was forgetting the flags! I update my example with yours here on the forum! Looking neat! Other question, if you don't mind, how would you make layers? EDIT? I said layers but meant tabs, like changing the objects you see I was thinking in putting the objects between if conditions but if it don't happen it might change objects place around, so it might need to be counted but not draw, or with 0 alpha. Thanks for the responses! Last edited by daniellumertz; 03-07-2021 at 01:12 PM. |
![]() |
![]() |
![]() |
#16 | |
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 5,336
|
![]() Quote:
__________________
🎁 Donate (PayPal) | Sponsor (GitHub) | The Endless Journey (Keyboard Ensemble) ReaPack, a package manager for REAPER | SWS 2.14 is now available in ReaPack [new!] Developer tools: Lua profiler | Interactive ReaScript | ReaPack Editor | ReaImGui |
|
![]() |
![]() |
![]() |
#17 |
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 5,336
|
![]()
Released version 0.1.1:
Code:
• Add EEL2 example using the legacy < 6.24 syntax [#1] • Fix first frame having twice the contents in the example scripts • macOS: process the first click over an unfocused window • Remove focus from ImGui input controls when the context window itself loses focus Docking bugfixes: • Fix keyboard input going to REAPER when docked • Skip rendering when docked and another docker tab is active • Linux & Windows: fix mousewheel events leaking to REAPER • Linux: fix crashes, flickering and incomplete rendering • macOS: update viewport size if it changed while another docker tab was active • Windows: don't lose focus when Tab is pressed
__________________
🎁 Donate (PayPal) | Sponsor (GitHub) | The Endless Journey (Keyboard Ensemble) ReaPack, a package manager for REAPER | SWS 2.14 is now available in ReaPack [new!] Developer tools: Lua profiler | Interactive ReaScript | ReaPack Editor | ReaImGui Last edited by cfillion; 03-08-2021 at 05:54 AM. Reason: s/5.24/6.24 |
![]() |
![]() |
![]() |
#18 |
Human being with feelings
Join Date: Apr 2016
Posts: 144
|
![]()
This was bound to happen, but huge thanks to cfillion for making the inevitable happen sooner rather than later.
![]() How long till someone codes a wasm interpreter so we could finally run Windows inside Reaper? ![]()
__________________
thirdhemisphere.studio | blog | #mixing:matrix.org chat | awesome-reaper Software: rearchiver, zrtstr, reaper-item-nudger | Scripts |
![]() |
![]() |
![]() |
#19 |
Human being with feelings
Join Date: Sep 2016
Location: Toronto
Posts: 795
|
![]()
Thank you so much for this cfillon, what an incredible toolkit! It's inspired me to finally learn scripting and I've started on something I've wanted for a long time: an item arpeggiator script. Here's a preview: https://youtu.be/BtE5hqbbdos . I need to figure out a lot of things before it's ready like presets and smarter controls.
Somethings I'm still struggling to understand, could someone post an example of a vertical slider that has these attributes? -it starts up with a definable default value -double click on the control returns it to the default value -after clicking it and releasing the mouse, it runs a function immediately -it responds to mousewheel (and shift-mousewheel for finer adjustement if possible) |
![]() |
![]() |
![]() |
#20 |
Human being with feelings
Join Date: Apr 2014
Posts: 404
|
![]()
Nice to see the first real applications! Good job Arthur!
|
![]() |
![]() |
![]() |
#21 | |
Human being with feelings
Join Date: Dec 2017
Location: Brazil
Posts: 2,082
|
![]() Quote:
One thing. If my script calls a message box (that needs input) the ImGui breaks I think... You might already know just wanna report, just in case... |
|
![]() |
![]() |
![]() |
#22 | ||
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 5,336
|
![]() Quote:
Code:
local default_value = 42 local value = default_value local reset = {} function resetOnDoubleClick(id, value, default) if reaper.ImGui_IsItemDeactivated(ctx) and reset[id] then reset[id] = nil return default elseif reaper.ImGui_IsItemHovered(ctx) and reaper.ImGui_IsMouseDoubleClicked(ctx, 0) then reset[id] = true end return value end function applyMousewheel(value, min, max) local shift = reaper.ImGui_GetKeyMods(ctx) & reaper.ImGui_KeyModFlags_Shift() ~= 0 local wheel, hwheel = reaper.ImGui_GetMouseWheel(ctx) if shift and wheel == 0 then wheel = hwheel end if wheel ~= 0 then speed = shift and 1 or 4 value = value + math.ceil(wheel * speed) return math.max(min, math.min(value, max)) end return value end function myVSliderInt(id, width, height, value, min, max, default_value) local rv rv,value = reaper.ImGui_VSliderInt(ctx, id, width, height, value, min, max) value = resetOnDoubleClick(id, value, default_value) if reaper.ImGui_IsItemHovered(ctx) then value = applyMousewheel(value, min, max) end -- or ImGui_IsItemDeactivatedAfterEdit to only do something if the value changed return reaper.ImGui_IsItemDeactivated(ctx), value end function loop() local rv -- ... rv,value = myVSliderInt('##v', 40, 160, value, 0, 100, default_value) if rv then doSomething() end -- ... end Quote:
An alternative would be to use ImGui's own modal dialog feature. See Demo > Popups & Modal windows > Modals.
__________________
🎁 Donate (PayPal) | Sponsor (GitHub) | The Endless Journey (Keyboard Ensemble) ReaPack, a package manager for REAPER | SWS 2.14 is now available in ReaPack [new!] Developer tools: Lua profiler | Interactive ReaScript | ReaPack Editor | ReaImGui Last edited by cfillion; 03-09-2021 at 06:48 AM. |
||
![]() |
![]() |
![]() |
#23 |
Human being with feelings
Join Date: Sep 2016
Location: Toronto
Posts: 795
|
![]()
Thanks so much cfillon!
Here's a bit of code testing it out, it seems like the mousewheel is lagging behind one step and displaying the last value instead of the current one, is there a way to fix that? Also, is there a better way to do multiple sliders than how I've tried it here? I just copied the code you provided and added 1 to all the values. Code:
local ctx = reaper.ImGui_CreateContext('Slider Test', 300, 600) local default_value = 0 local value = default_value local default_value2 = 0 local value2 = default_value2 local reset = {} function loop() if reaper.ImGui_IsCloseRequested(ctx) then reaper.ImGui_DestroyContext(ctx) return end reaper.ImGui_SetNextWindowPos(ctx, 0, 0)-- Don't really need but it makes it at 0 0 "Lock it" reaper.ImGui_SetNextWindowSize(ctx, reaper.ImGui_GetDisplaySize(ctx))-- Don't really need but it makes it the size of the screen reaper.ImGui_Begin(ctx, 'wnd', nil, reaper.ImGui_WindowFlags_NoDecoration()) --- GUI HERE local rv local rv2 -- ... rv,value = myVSliderInt('##v1', 40, 160, value, -24, 24, default_value) if rv then dosomething() end rv2,value2 = myVSliderInt2('##v2', 40, 160, value2, -24, 24, default_value2) if rv2 then dosomething() end -- ... reaper.ImGui_End(ctx) reaper.defer(loop) end function dosomething() reaper.ShowConsoleMsg(value) end function resetOnDoubleClick(id, value, default) if reaper.ImGui_IsItemDeactivated(ctx) and reset[id] then reset[id] = nil return default elseif reaper.ImGui_IsItemHovered(ctx) and reaper.ImGui_IsMouseDoubleClicked(ctx, 0) then reset[id] = true end return value end function applyMousewheel(value, min, max) local shift = reaper.ImGui_GetKeyMods(ctx) & reaper.ImGui_KeyModFlags_Shift() ~= 0 local wheel, hwheel = reaper.ImGui_GetMouseWheel(ctx) if shift and wheel == 0 then wheel = hwheel end if wheel ~= 0 then speed = shift and 1 or 1 value = value + math.ceil(wheel * speed) dosomething() return math.max(min, math.min(value, max)) end return value end function myVSliderInt(id, width, height, value, min, max, default_value) local rv rv,value = reaper.ImGui_VSliderInt(ctx, id, width, height, value, min, max) value = resetOnDoubleClick(id, value, default_value) if reaper.ImGui_IsItemHovered(ctx) then value = applyMousewheel(value, min, max) end -- or ImGui_IsItemDeactivatedAfterEdit to only do something if the value changed return reaper.ImGui_IsItemDeactivated(ctx), value end function myVSliderInt2(id, width, height, value2, min, max, default_value) local rv2 rv2,value2 = reaper.ImGui_VSliderInt(ctx, id, width, height, value2, min, max) value2 = resetOnDoubleClick(id, value2, default_value) if reaper.ImGui_IsItemHovered(ctx) then value2 = applyMousewheel(value2, min, max) end -- or ImGui_IsItemDeactivatedAfterEdit to only do something if the value changed return reaper.ImGui_IsItemDeactivated(ctx), value2 end loop() |
![]() |
![]() |
![]() |
#24 | ||
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 5,336
|
![]() Quote:
You could do something like this: Code:
function applyMousewheel(value, min, max) -- ... return true, math.max(min, math.min(value, max)) end return false, value end function myVSliderInt(id, width, height, value, min, max, default_value) local rv rv,value = reaper.ImGui_VSliderInt(ctx, id, width, height, value, min, max) value = resetOnDoubleClick(id, value, default_value) local changed if reaper.ImGui_IsItemHovered(ctx) then changed,value = applyMousewheel(value, min, max) end if not changed then changed = reaper.ImGui_IsItemDeactivated(ctx) end -- or ImGui_IsItemDeactivatedAfterEdit to only do something if the value changed return changed, value end Quote:
Code:
rv,value = myVSliderInt('##v1', 40, 160, value, -24, 24, default_value) if rv then dosomething() end rv,value2 = myVSliderInt('##v2', 40, 160, value2, -24, 24, default_value2) if rv then dosomething() end
__________________
🎁 Donate (PayPal) | Sponsor (GitHub) | The Endless Journey (Keyboard Ensemble) ReaPack, a package manager for REAPER | SWS 2.14 is now available in ReaPack [new!] Developer tools: Lua profiler | Interactive ReaScript | ReaPack Editor | ReaImGui |
||
![]() |
![]() |
![]() |
#25 |
Human being with feelings
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 16,726
|
![]()
Any chance for this in JSFX -> @gfx ?
-Michael |
![]() |
![]() |
![]() |
#26 |
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 5,336
|
![]()
That's not possible with the current REAPER extension API.
__________________
🎁 Donate (PayPal) | Sponsor (GitHub) | The Endless Journey (Keyboard Ensemble) ReaPack, a package manager for REAPER | SWS 2.14 is now available in ReaPack [new!] Developer tools: Lua profiler | Interactive ReaScript | ReaPack Editor | ReaImGui |
![]() |
![]() |
![]() |
#27 |
Human being with feelings
Join Date: Sep 2016
Location: Toronto
Posts: 795
|
![]()
Great, thank you!!
Here's some test slider example code based on what cfillon provided for those interested, it has: -Integer and double sliders in horizontal and vertical -Default values (double-click to reset) -Mousewheel (shift-mousewheel for fine adjustments) -Different mousewheel sensitivity variables for integer and double Code:
local ctx = reaper.ImGui_CreateContext('Slider Test', 250, 250) int_mousewheel_sensitivity = 1 int_mousewheel_sensitivity_fine = 1 double_mousewheel_sensitivity = .1 double_mousewheel_sensitivity_fine = .01 local default_value = 0 local value = default_value local default_value2 = 1 local value2 = default_value2 local default_value3 = 2 local value3 = default_value3 local default_value4 = 3 local value4 = default_value4 local reset = {} ----------------------------- TEST FUNCTION ---------------------- function dosomething() reaper.ShowConsoleMsg(test_input .. '\n') end ------------------------------------------------------------------- ------------------------- GUI ------------------------------------ ------------------------------------------------------------------- function loop() if reaper.ImGui_IsCloseRequested(ctx) then reaper.ImGui_DestroyContext(ctx) return end reaper.ImGui_SetNextWindowPos(ctx, 0, 0)-- Don't really need but it makes it at 0 0 "Lock it" reaper.ImGui_SetNextWindowSize(ctx, reaper.ImGui_GetDisplaySize(ctx))-- Don't really need but it makes it the size of the screen reaper.ImGui_Begin(ctx, 'wnd', nil, reaper.ImGui_WindowFlags_NoDecoration()) local rv ---Vertical Slider rv,value = myVSliderInt('##v1', 40, 160, value, -10, 10, default_value) if rv then test_input = value dosomething() end reaper.ImGui_SameLine(ctx) ---Vertical Slider Double rv,value2 = myVSliderDouble('##v2', 40, 160, value2, -10, 10, default_value2) if rv then test_input = value2 dosomething() end ---Horizontal Slider rv,value3 = mySliderInt('##v3', value3, -10, 10, default_value3) if rv then test_input = value3 dosomething() end ---Horizontal Slider Double rv,value4 = mySliderDouble('##v4', value4, -10, 10, default_value4) if rv then test_input = value4 dosomething() end reaper.ImGui_End(ctx) reaper.defer(loop) end -------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------- ---------------------------- DOUBLE CLICK AND MOUSEWHEEL FUNCTIONS -------------------------------- function resetOnDoubleClick(id, value, default) if reaper.ImGui_IsItemDeactivated(ctx) and reset[id] then reset[id] = nil return default elseif reaper.ImGui_IsItemHovered(ctx) and reaper.ImGui_IsMouseDoubleClicked(ctx, 0) then reset[id] = true end return value end function applyMousewheel(value, min, max) local shift = reaper.ImGui_GetKeyMods(ctx) & reaper.ImGui_KeyModFlags_Shift() ~= 0 local wheel, hwheel = reaper.ImGui_GetMouseWheel(ctx) if shift and wheel == 0 then wheel = hwheel end if wheel ~= 0 then speed = shift and int_mousewheel_sensitivity_fine or int_mousewheel_sensitivity value = value + math.ceil(wheel * speed) return true, math.max(min, math.min(value, max)) end rv=true return false, value end function applyMousewheelDouble(value, min, max) local shift = reaper.ImGui_GetKeyMods(ctx) & reaper.ImGui_KeyModFlags_Shift() ~= 0 local wheel, hwheel = reaper.ImGui_GetMouseWheel(ctx) if shift and wheel == 0 then wheel = hwheel end if wheel ~= 0 then speed = shift and double_mousewheel_sensitivity_fine or double_mousewheel_sensitivity value = value + (wheel * speed) return true, math.max(min, math.min(value, max)) end rv=true return false, value end ------------------------------------ VERTICAL SLIDER --------------------------------- function myVSliderInt(id, width, height, value, min, max, default_value) local rv rv,value = reaper.ImGui_VSliderInt(ctx, id, width, height, value, min, max) value = resetOnDoubleClick(id, value, default_value) local changed if reaper.ImGui_IsItemHovered(ctx) then changed,value = applyMousewheel(value, min, max) end if not changed then changed = reaper.ImGui_IsItemDeactivatedAfterEdit(ctx) end return changed, value end ------------------------------------ VERTICAL SLIDER DOUBLE --------------------------------- function myVSliderDouble(id, width, height, value, min, max, default_value) local rv rv,value = reaper.ImGui_VSliderDouble(ctx, id, width, height, value, min, max) value = resetOnDoubleClick(id, value, default_value) local changed if reaper.ImGui_IsItemHovered(ctx) then changed,value = applyMousewheelDouble(value, min, max) end if not changed then changed = reaper.ImGui_IsItemDeactivatedAfterEdit(ctx) end return changed, value end ----------------------------------------- HORIZONTAL SLIDER --------------------------- function mySliderInt(id, value, min, max, default_value) local rv rv,value = reaper.ImGui_SliderInt(ctx, id, value, min, max) value = resetOnDoubleClick(id, value, default_value) local changed if reaper.ImGui_IsItemHovered(ctx) then changed, value = applyMousewheel(value, min, max) end if not changed then changed = reaper.ImGui_IsItemDeactivatedAfterEdit(ctx) end return changed, value end ----------------------------------------- HORIZONTAL SLIDER DOUBLE --------------------------- function mySliderDouble(id, value, min, max, default_value) local rv rv,value = reaper.ImGui_SliderDouble(ctx, id, value, min, max) value = resetOnDoubleClick(id, value, default_value) local changed if reaper.ImGui_IsItemHovered(ctx) then changed, value = applyMousewheelDouble(value, min, max) end if not changed then changed = reaper.ImGui_IsItemDeactivatedAfterEdit(ctx) end return changed, value end ---------------------------------------------------------------------------- ----------------------------------------------------------------------------- -------------------------------------------------------------------------- loop() |
![]() |
![]() |
![]() |
#28 |
Human being with feelings
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 4,138
|
![]()
Interesting!
![]() |
![]() |
![]() |
![]() |
#29 |
Human being with feelings
Join Date: Apr 2014
Posts: 103
|
![]()
Awesome !
Did some testing with the full demo and multiple selectables: it seems the ImGui_KeyModFlags are not working: when i disable it, i am able to select multiple lines. line 1112 Code:
if r.ImGui_TreeNode(ctx, 'Selection State: Multiple Selection') then demo.HelpMarker('Hold CTRL and click to select multiple items.') for i,sel in ipairs(widgets.selectables.multiple) do if r.ImGui_Selectable(ctx, ('Object %d'):format(i-1), sel) then -- if not (r.ImGui_GetKeyMods(ctx) & r.ImGui_KeyModFlags_Ctrl()) ~= 0 then -- Clear selection when CTRL is not held -- for j = 1, #widgets.selectables.multiple do -- widgets.selectables.multiple[j] = false -- end -- end widgets.selectables.multiple[i] = not sel end end r.ImGui_TreePop(ctx) end |
![]() |
![]() |
![]() |
#30 |
Human being with feelings
Join Date: Dec 2020
Location: Miami, FL USA
Posts: 396
|
![]()
Have been studying basic C++ the past two days to try to integrate some of these third party prebuilt ImGui components with ReaImGui.
It's been entirely thanks to @cfillion Today was first success! Accomplished the following:
Tomorrow, I will try to port:
Demo of today's fruits: ![]()
__________________
Seasoned codemonkey Dunno a thing about making music (here to learn!) |
![]() |
![]() |
![]() |
#31 | |
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 5,336
|
![]() Quote:
Code:
if (r.ImGui_GetKeyMods(ctx) & r.ImGui_KeyModFlags_Ctrl()) == 0 then -- Clear selection when CTRL is not held"
__________________
🎁 Donate (PayPal) | Sponsor (GitHub) | The Endless Journey (Keyboard Ensemble) ReaPack, a package manager for REAPER | SWS 2.14 is now available in ReaPack [new!] Developer tools: Lua profiler | Interactive ReaScript | ReaPack Editor | ReaImGui |
|
![]() |
![]() |
![]() |
#32 |
Human being with feelings
Join Date: Apr 2014
Posts: 103
|
![]()
Thanks cfillion !
I commented out the lines to test multi-selection in the example i posted. With your fix, everything is working as expected! I'm really grateful for your work. |
![]() |
![]() |
![]() |
#33 | |
Human being with feelings
Join Date: Dec 2017
Location: Brazil
Posts: 2,082
|
![]() Quote:
Wow! This will end up being even bigger than what already is ! Danke! a lot mr.gxray! ![]() ![]() ![]() Even a timeline and a node based !!! This is other level GUI for scripters now |
|
![]() |
![]() |
![]() |
#34 |
Human being with feelings
Join Date: Sep 2016
Location: Toronto
Posts: 795
|
![]()
Is there any way to suppress the error:
Loading presetImGui assertion failed: (g.CurrentWindowStack.Size == 1) && "Mismatched Begin/BeginChild vs End/EndChild calls: did you forget to call End/EndChild?" When a ReaScript error pops up? |
![]() |
![]() |
![]() |
#35 | |
Human being with feelings
Join Date: May 2015
Location: Québec, Canada
Posts: 5,336
|
![]() Quote:
If preventing Lua errors from happening during the script's normal operation is not possible, you could use Lua's protected mode (pcall/xpcall functions) to catch them without crashing the script mid-frame. https://www.lua.org/pil/8.4.html
__________________
🎁 Donate (PayPal) | Sponsor (GitHub) | The Endless Journey (Keyboard Ensemble) ReaPack, a package manager for REAPER | SWS 2.14 is now available in ReaPack [new!] Developer tools: Lua profiler | Interactive ReaScript | ReaPack Editor | ReaImGui |
|
![]() |
![]() |
![]() |
#36 |
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 10,575
|
![]() ![]() Such things could be huge game changer for theming! Default windows popup is doesn't real time preview... also making copy color from other element could be done way more easily... This could be a good framework to remake the theme tweaker!
__________________
Free ReaScripts - Premium Scripts - Custom Scripts Dev - Learn ReaScript - XR Theme - Stash Files - ReaLinks - Website - ReaComics - Alien 2347 - Donation |
![]() |
![]() |
![]() |
#37 |
Human being with feelings
Join Date: Oct 2017
Location: Black Forest
Posts: 5,214
|
![]()
Goodness X-Raym, such a great idea!
![]()
__________________
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 |
![]() |
![]() |
![]() |
#38 |
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 10,575
|
![]()
@Stevie
And it is getting better such quickly !! ![]() Copy paste of colors for theme tweaker, at last!
__________________
Free ReaScripts - Premium Scripts - Custom Scripts Dev - Learn ReaScript - XR Theme - Stash Files - ReaLinks - Website - ReaComics - Alien 2347 - Donation |
![]() |
![]() |
![]() |
#39 |
Human being with feelings
Join Date: Dec 2017
Location: Brazil
Posts: 2,082
|
![]()
ahhhh great idea indeed! copy and paste will save a lot of time hahaha
|
![]() |
![]() |
![]() |
#40 |
Human being with feelings
Join Date: Oct 2017
Location: Black Forest
Posts: 5,214
|
![]()
Waaaah, do you plan to release that script?
__________________
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 |
![]() |
![]() |
![]() |
Thread Tools | |
Display Modes | |
|
|