|
|
|
12-31-2022, 07:02 AM
|
#41
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by OLSHALOM
Does deleting 0x1000000 from those lines make any difference?
|
Quote:
Originally Posted by cfillion
0x1000000 is the color enable bit for tracks/items/markers/etc in REAPER. Without it the color is stored but unused.
|
Deleting it didn't make a difference, still reddish.
|
|
|
12-31-2022, 07:05 AM
|
#42
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by cfillion
(Note that HSV with alpha=1.0 + RgbaToArgb essentially does |0xff000000 - RgbaToArgb can probably be replaced with just "HSV(...) >> 8" to erase alpha instead of moving it).
For red vs blue order on Windows, ColorConvertNative must be called once when receiving a color from REAPER to ImGui, and once when transferring from ImGui to REAPER. Anything less or more will result in swapped red/blue.
(ColorConvertNative leaves the color enable bit (the entire MSB in fact) unmodified.)
|
Thank you for chiming in again. Appreciate your knowledge and willing to share it with us. I remembered Windows and macOS have R and B swapped, but didn't remember how to avoid it.
|
|
|
01-01-2023, 03:22 AM
|
#43
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
That's not what I was writing about.
I was writing about using some of rodilab's code fragments for your palette.
|
Happy new year!!
I know. It already has !
Quote:
Originally Posted by vitalker
I don't know whether it possible, but changing someone's settings is not a good idea, you could instead recommend users to activate this setting, so they'll be able to use independent take coloring.
|
What I meant was to only read the tinttcpvalue, not to change it. And dependent by it's state, takecoloring is active when the value is >=1921, or turned off.
Codewise I already made it happen.
This way, the palette could be used also with "ordinary" coloring-settings for example with the default theme without changing anything else.
I try my luck with a feature request.
All the best
|
|
|
01-01-2023, 03:50 AM
|
#44
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by OLSHALOM
Happy new year!!
I know. It already has !
What I meant was to only read the tinttcpvalue, not to change it. And dependent by it's state, takecoloring is active when the value is >=1921, or turned off.
Codewise I already made it happen.
This way, the palette could be used also with "ordinary" coloring-settings for example with the default theme without changing anything else.
I try my luck with a feature request.
All the best
|
Happy new year! That's great!
Ah, yes. For some reason I was thinking of reaper.ini, not rtconfig.txt.
Okay, good luck! Maybe this feature is not needed after all?
|
|
|
01-04-2023, 03:14 PM
|
#45
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
Happy new year! That's great!
Ah, yes. For some reason I was thinking of reaper.ini, not rtconfig.txt.
Okay, good luck! Maybe this feature is not needed after all?
|
@Vitalker,
here are gifs of the actual palette after more development:
|
|
|
01-04-2023, 03:17 PM
|
#46
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
Happy new year! That's great!
Ah, yes. For some reason I was thinking of reaper.ini, not rtconfig.txt.
Okay, good luck! Maybe this feature is not needed after all?
|
@Vitalker,
and here's the code:
Code:
-- CONSOLE OUTPUT --
reaper.ShowConsoleMsg("")
local function Msg(param)
reaper.ShowConsoleMsg(tostring(param).."\n")
end
--retval2, tcptint = reaper.BR_Win32_GetPrivateProfileString("REAPER", "tinttcp", "", reaper.get_ini_file())
--Msg(tcptint)
--tinttcp = tonumber(tcptint)
--tcp_value = 1920
--color_mode = false
--if tinttcp > tcp_value then
--color_mode = true
--Msg(color_mode)
--end
--CurSetting = reaper.SNM_GetIntConfigVar( "tinttcp", -666 )
--Msg(CurSetting)
r = reaper
dofile(reaper.GetResourcePath() ..
'/Scripts/ReaTeam Extensions/API/imgui.lua')('0.8')
local ctx = reaper.ImGui_CreateContext('My script')
local sans_serif = reaper.ImGui_CreateFont('sans-serif', 15)
reaper.ImGui_Attach(ctx, sans_serif)
local function RgbaToArgb(rgba)
return (rgba >> 8 & 0x00FFFFFF) | (rgba << 24 & 0xFF000000)
end
function ArgbToRgba(argb)
return (argb << 8 & 0xFFFFFF00) | (argb >> 24 & 0xFF)
end
local function hslToRgb(h, s, l)
if s == 0 then return l, l, l end
local function to(p, q, t)
if t < 0 then t = t + 1 end
if t > 1 then t = t - 1 end
if t < .16667 then return p + (q - p) * 6 * t end
if t < .5 then return q end
if t < .66667 then return p + (q - p) * (.66667 - t) * 6 end
return p
end
local q = l < .5 and l * (1 + s) or l + s - l * s
local p = 2 * l - q
return to(p, q, h + .33334), to(p, q, h), to(p, q, h - .33334)
end
local function HSL(h, s, l, a)
local r, g, b = hslToRgb(h, s, l)
return reaper.ImGui_ColorConvertDouble4ToU32(r, g, b, a or 1.0)
end
local function rgbToHsl(r, g, b)
local max, min = math.max(r, g, b), math.min(r, g, b)
local b = max + min
local h = b / 2
if max == min then return 0, 0, h end
local s, l = h, h
local d = max - min
s = l > .5 and d / (2 - b) or d / b
if max == r then h = (g - b) / d + (g < b and 6 or 0)
elseif max == g then h = (b - r) / d + 2
elseif max == b then h = (r - g) / d + 4
end
return h * .16667, s, l
end
local function HSV(h, s, v, a)
local r, g, b = reaper.ImGui_ColorConvertHSVtoRGB(h, s, v)
return reaper.ImGui_ColorConvertDouble4ToU32(r, g, b, a or 1.0)
end
function demoShowExampleMenuFile()
local rv
if r.ImGui_BeginMenu(ctx, 'Options') then
rv,demomenuenabled = r.ImGui_MenuItem(ctx, 'Enabled', '', demomenuenabled)
if r.ImGui_BeginChild(ctx, 'child', 0, 60, true) then
for i = 0, 9 do
r.ImGui_Text(ctx, ('Scrolling Text %d'):format(i))
end
r.ImGui_EndChild(ctx)
end
rv,demomenuf = r.ImGui_SliderDouble(ctx, 'Value', demomenuf, 0.0, 1.0)
rv,demomenuf = r.ImGui_InputDouble(ctx, 'Input', demomenuf, 0.1)
rv,demomenun = r.ImGui_Combo(ctx, 'Combo', demomenun, 'Yes\0No\0Maybe\0')
r.ImGui_EndMenu(ctx)
end
-- Here we demonstrate appending again to the "Options" menu (which we already created above)
-- Of course in this demo it is a little bit silly that this function calls BeginMenu("Options") twice.
-- In a real code-base using it would make senses to use this feature from very different code locations.
if r.ImGui_BeginMenu(ctx, 'Options') then -- <-- Append!
rv,demomenub = r.ImGui_Checkbox(ctx, 'SomeOption', demomenub)
r.ImGui_EndMenu(ctx)
end
if r.ImGui_BeginMenu(ctx, 'Disabled', false) then -- Disabled
error('never called')
end
if r.ImGui_MenuItem(ctx, 'Checked', nil, true) then end
if r.ImGui_MenuItem(ctx, 'Quit', 'Alt+F4') then end
end
-- get selected items or tracks colors --
function get_sel_items_or_tracks_colors()
sel_colors = {}
sel_items = reaper.CountSelectedMediaItems(0)
sel_tracks = reaper.CountSelectedTracks(0)
if sel_items > 0 then
for i=0, sel_items -1 do
local item = reaper.GetSelectedMediaItem(0,i)
local itemcolor = reaper.GetMediaItemInfo_Value(item,"I_CUSTOMCOLOR")
local r, g, b = reaper.ColorFromNative(itemcolor)
items_colors = reaper.ImGui_ColorConvertDouble4ToU32(r/255, g/255, b/255, a or 1.0)
table.insert(sel_colors, items_colors)
end
else if sel_tracks > 0 then
for i=0, sel_tracks -1 do
local track = reaper.GetSelectedTrack(0,i)
local trackcolor = reaper.GetMediaTrackInfo_Value(track,"I_CUSTOMCOLOR")
-- tracks_colors = ArgbToRgba(trackcolor)
-- tracks_colors = reaper.ImGui_ColorConvertNative(tracks_colors)
local r, g, b = reaper.ColorFromNative(trackcolor)
tracks_colors = reaper.ImGui_ColorConvertDouble4ToU32(r/255, g/255, b/255, a or 1.0)
table.insert(sel_colors, tracks_colors)
end
end
end
return sel_colors
end
local function Palette()
saved_palette = {}
for n = 0, 25 do
table.insert(saved_palette, HSL(n / 26+0.69, saturation, lightness, 1))
end
for n = 0, 25 do
table.insert(saved_palette, HSL(n / 26+0.69, saturation, 0.75 - ((1-lightness)/4*3)+(darkness/4), 1))
end
for n = 0, 25 do
table.insert(saved_palette, HSL(n / 26+0.69, saturation, 0.5 - ((1-lightness)/2)+(darkness/2), 1))
end
for n = 0, 25 do
table.insert(saved_palette, HSL(n / 26+0.69, saturation, 0.25 - ((1-lightness)/4)+(darkness/4*3), 1))
end
for n = 0, 25 do
table.insert(saved_palette, HSL(n / 26+0.69, saturation, darkness , 1))
end
return saved_palette
end
-- Coloring --
local function coloring()
if widgetscolorsrgba then
argb = RgbaToArgb(widgetscolorsrgba)
widgetscolorsrgba2 = widgetscolorsrgba >>8
local color = reaper.ImGui_ColorConvertNative(widgetscolorsrgba2)|0x1000000
r3, g, b = reaper.ColorFromNative(argb)
h, s, v = reaper.ImGui_ColorConvertRGBtoHSV(r3/255,g/255,b/255, 1.0)
s=s/3.7
v=v+0.5
if v>0.88 then v = 0.88 end
local brighten = HSV(h, s, v, 1.0) >> 8
local color2 = reaper.ImGui_ColorConvertNative(brighten)|0x1000000
sel_items = reaper.CountSelectedMediaItems(0)
sel_tracks = reaper.CountSelectedTracks(0)
if sel_items > 0 then
for i = 0, sel_items -1 do
local item = reaper.GetSelectedMediaItem(0,i)
reaper.SetMediaItemInfo_Value(item,"I_CUSTOMCOLOR", color)
if widgetsbasicradio == 1 then
take =reaper.GetActiveTake(item)
reaper.SetMediaItemTakeInfo_Value(take,"I_CUSTOMCOLOR", color2)
reaper.UpdateItemInProject( item )
else if widgetsbasicradio == 0 then
take =reaper.GetActiveTake(item)
reaper.SetMediaItemTakeInfo_Value(take,"I_CUSTOMCOLOR", color)
reaper.UpdateItemInProject( item )
end
end
if reaper.ImGui_IsKeyDown(ctx, reaper.ImGui_Mod_Shortcut()) then
if sel_tracks > 0 then
for i = 0, sel_tracks -1 do
local track = reaper.GetSelectedTrack(0,i)
reaper.SetMediaTrackInfo_Value(track,"I_CUSTOMCOLOR", color)
end
end
end
end
else
if sel_tracks > 0 then
for i = 0, sel_tracks -1 do
local track = reaper.GetSelectedTrack(0,i)
reaper.SetMediaTrackInfo_Value(track,"I_CUSTOMCOLOR", color)
if reaper.ImGui_IsKeyDown(ctx, reaper.ImGui_Mod_Shortcut()) then
cnt_items = reaper.CountTrackMediaItems(track)
if cnt_items > 0 then
for i = 0, cnt_items -1 do
local new_item = reaper.GetTrackMediaItem( track, i )
reaper.SetMediaItemInfo_Value(new_item,"I_CUSTOMCOLOR", color)
new_take =reaper.GetActiveTake(new_item)
if widgetsbasicradio == 1 then
reaper.SetMediaItemTakeInfo_Value(new_take,"I_CUSTOMCOLOR", color2)
reaper.UpdateItemInProject( new_item )
else if widgetsbasicradio == 0 then
reaper.SetMediaItemTakeInfo_Value(new_take,"I_CUSTOMCOLOR", color)
reaper.UpdateItemInProject( new_item )
end
end
end
end
end
end
end
end
end
end
-- THE COLORPALETTE --
local function ColorPalette()
local rv
w, h = reaper.ImGui_GetWindowSize(ctx)
max_button_w = (w-2*26)/27
if max_button_w *5+90 > h then
size = (h-2*5-50)/6
else
size = max_button_w
end
if not saturation then
saturation = 0.8 end
if not lightness then
lightness =0.65 end
if not darkness then
darkness =0.20 end
r.ImGui_BeginMenuBar(ctx)
if r.ImGui_BeginMenu(ctx, 'Palette-Settings') then
rv, saturation = r.ImGui_SliderDouble(ctx, 'Saturation', saturation, 0.0, 1.0, '%.3f', reaper.ImGui_SliderFlags_None())
rv,darkness,lightness = r.ImGui_SliderDouble2(ctx, 'darkness - lightness', darkness, lightness, 0.0, 1.0)
--rv,lightness = r.ImGui_SliderDouble(ctx, 'Lightness', lightness, 0.0, 1.0, '%.4f', reaper.ImGui_SliderFlags_None())
--rv,darkness = r.ImGui_SliderDouble(ctx, 'Darkness', darkness, 0.0, 1.0, '%.4f', reaper.ImGui_SliderFlags_None())
rv,demomenuf = r.ImGui_SliderDouble(ctx, 'Value', demomenuf, 0.0, 1.0)
rv,demomenuf = r.ImGui_InputDouble(ctx, 'Input', demomenuf, 0.1)
rv,demomenun = r.ImGui_Combo(ctx, 'Combo', demomenun, 'Yes\0No\0Maybe\0')
r.ImGui_EndMenu(ctx)
end
r.ImGui_EndMenuBar(ctx)
if w-400 < 0 then element_position = 0 else element_position = w-400 end
reaper.ImGui_Spacing(ctx)
reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_ItemSpacing(), element_position, 8)
-- template for additional functions added later --
reaper.ImGui_Text(ctx, '')
reaper.ImGui_SameLine(ctx)
reaper.ImGui_PopStyleVar(ctx)
rv, widgetsbasicradio = reaper.ImGui_RadioButtonEx(ctx, 'normal-mode', widgetsbasicradio, 0); reaper.ImGui_SameLine(ctx)
--rv, widgetsbasicradio = reaper.ImGui_RadioButtonEx(ctx, 'protools-mode (experimental)', widgetsbasicradio, 1)
if reaper.ImGui_RadioButtonEx(ctx, 'protools-mode (experimental)', widgetsbasicradio, 1) then
--if widgetsbasicradio ==1 then
-- if r.ImGui_Button(ctx, 'Delete..') then
r.ImGui_OpenPopup(ctx, 'Delete?')
end
-- Always center this window when appearing
local center = {r.ImGui_Viewport_GetCenter(r.ImGui_GetWindowViewport(ctx))}
r.ImGui_SetNextWindowPos(ctx, center[1], center[2], r.ImGui_Cond_Appearing(), 0.5, 0.5)
if r.ImGui_BeginPopupModal(ctx, 'Delete?', nil, r.ImGui_WindowFlags_AlwaysAutoResize()) then
r.ImGui_Text(ctx, 'To use the full potentual of ProTools-Mode,\nmake sure the CustomColor-Preferences are set correctly\nor the actual used theme provides the value 1921/1922\nfor tinttcp inside its rtconfig-file!\nMore Infos: http//...\n\nContinue with ProTools-Mode?\n\n')
r.ImGui_Separator(ctx)
--static int unused_i = 0;
--r.ImGui_Combo("Combo", &unused_i, "Delete\0Delete harder\0");
r.ImGui_PushStyleVar(ctx, r.ImGui_StyleVar_FramePadding(), 0, 0)
rv,popupsmodaldont_ask_me_next_time =
r.ImGui_Checkbox(ctx, "Don't ask me next time", popupsmodaldont_ask_me_next_time)
r.ImGui_PopStyleVar(ctx)
if r.ImGui_Button(ctx, 'OK', 120, 0) then r.ImGui_CloseCurrentPopup(ctx); widgetsbasicradio = 1 end
r.ImGui_SetItemDefaultFocus(ctx)
r.ImGui_SameLine(ctx)
if r.ImGui_Button(ctx, 'Cancel', 120, 0) then r.ImGui_CloseCurrentPopup(ctx); widgetsbasicradio = 0 end
r.ImGui_EndPopup(ctx)
end
reaper.ImGui_Separator(ctx)
reaper.ImGui_Text(ctx, '')
-- calling functions --
saved_palette = Palette()
sel_colors = get_sel_items_or_tracks_colors()
-- color palette --
local distinct_col = {}
for n, c in ipairs(saved_palette) do
reaper.ImGui_PushID(ctx, n)
if ((n - 1) % 26) ~= 0 then
reaper.ImGui_SameLine(ctx, 0.0, 2)
else retval = reaper.ImGui_GetCursorPosY(ctx)
reaper.ImGui_SetCursorPosY(ctx, retval -2)
end
local highlight = false
local palette_button_flags =
reaper.ImGui_ColorEditFlags_NoPicker() |
reaper.ImGui_ColorEditFlags_NoTooltip()
for k, v in ipairs(sel_colors) do
if v==c then
if #distinct_col == 0 then
table.insert(distinct_col, v)
reaper.ImGui_PushStyleColor(ctx,reaper.ImGui_Col_Border(),0xffffffff)
reaper.ImGui_PushStyleVar(ctx,reaper.ImGui_StyleVar_FrameBorderSize(),1)
highlight = true
else
for col_n, color in ipairs(distinct_col) do
if v == color then
else
if col_n == #distinct_col then
table.insert(distinct_col, v)
reaper.ImGui_PushStyleColor(ctx,reaper.ImGui_Col_Border(),0xffffffff)
reaper.ImGui_PushStyleVar(ctx,reaper.ImGui_StyleVar_FrameBorderSize(),1)
highlight = true
break
end
end
end
end
end
end
if highlight == false then
palette_button_flags = palette_button_flags |
reaper.ImGui_ColorEditFlags_NoBorder()
end
-- buttons coloring--
if reaper.ImGui_ColorButton(ctx, '##palette', c, palette_button_flags, size, size) then
widgetscolorsrgba = (c) | (widgetscolorsrgba & 0xff) -- Preserve alpha!
coloring()
end
-- end
-- Allow user to drop colors into each palette entry. Note that ColorButton() is already a
-- drag source by default, unless specifying the ImGuiColorEditFlags_NoDragDrop flag.
--if reaper.ImGui_BeginDragDropTarget(ctx) then
--local drop_color
--rv,drop_color = reaper.ImGui_AcceptDragDropPayloadRGB(ctx)
--if rv then
--saved_palette[n] = drop_color
--end
--rv,drop_color = reaper.ImGui_AcceptDragDropPayloadRGBA(ctx)
--if rv then
--saved_palette[n] = drop_color >> 8
--end
--reaper.ImGui_EndDragDropTarget(ctx)
--end
if highlight == true then
reaper.ImGui_PopStyleColor(ctx,1)
reaper.ImGui_PopStyleVar(ctx,1)
end
reaper.ImGui_PopID(ctx)
end
reaper.ImGui_Text(ctx, '')
custom_color_flags = reaper.ImGui_ColorEditFlags_NoPicker()|
reaper.ImGui_ColorEditFlags_DisplayHSV()|
reaper.ImGui_ColorEditFlags_NoSmallPreview()--|
-- reaper.ImGui_ColorEditFlags_NoAlpha()
rv,widgetscolorsrgba = reaper.ImGui_ColorEdit4(ctx, '##2', widgetscolorsrgba, custom_color_flags)
reaper.ImGui_SameLine(ctx, 0.0, 8)
if reaper.ImGui_ColorButton(ctx, 'press = apply##3', widgetscolorsrgba, reaper.ImGui_ColorEditFlags_NoBorder(), 21, 21) then
coloring()
end
reaper.ImGui_Separator(ctx)
reaper.UpdateArrange()
end
local function loop()
reaper.ImGui_PushFont(ctx, sans_serif)
local window_flags = r.ImGui_WindowFlags_None() | r.ImGui_WindowFlags_MenuBar()
reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_TitleBgActive(), 0x1b3542ff)
reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_FrameBg(), 0x1b3542ff)
reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_SliderGrab(), 0x47aaaaff)
reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_CheckMark(), 0xffa436ff)
reaper.ImGui_PushStyleVar(ctx,reaper.ImGui_StyleVar_WindowRounding(),12)
reaper.ImGui_SetNextWindowSize(ctx, 400, 140, reaper.ImGui_Cond_FirstUseEver())
local visible, open = reaper.ImGui_Begin(ctx, 'ColorPalette', true, window_flags)
if visible then
ColorPalette()
reaper.ImGui_End(ctx)
end
reaper.ImGui_PopFont(ctx)
reaper.ImGui_PopStyleColor(ctx, 4)
reaper.ImGui_PopStyleVar(ctx)
if open then
reaper.defer(loop)
end
end
loop()
May I ask you, to check the coloring on a Windows-System?
|
|
|
01-04-2023, 03:23 PM
|
#47
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by OLSHALOM
@Vitalker,
here are gifs of the actual palette after more development:
|
Looks promising! Haha, PT mode
Not sure what that darkness - lightness thing may mean. It's confusing. Is it a range? Like left is the darkest value and right is the lightest?
|
|
|
01-04-2023, 03:25 PM
|
#48
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
Looks promising! Haha, PT mode
Not sure what that darkness - lightness thing may mean. It's confusing. Is it a range? Like left is the darkest value and right is the lightest?
|
Yes, exactly
|
|
|
01-04-2023, 03:26 PM
|
#49
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by OLSHALOM
May I ask you, to check the coloring on a Windows-System?
|
You may not.
Awesome, you fixed it! Congratulations!!!
|
|
|
01-04-2023, 03:32 PM
|
#50
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
You may not.
Awesome, you fixed it! Congratulations!!!
|
Cool, thanks for checking.
|
|
|
01-04-2023, 03:33 PM
|
#51
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Ooh, those sexy round corners.
These ranges should be >0 and <1, so you won't see black and white.
Regarding more colors: now these white frames don't mean much, because when you change any parameter, you can no longer see selected items' colors in the palette. Another good thing would be a button, which Reset these Saturation, darkness, lightness, so you can always see the default colors. Value slider seems doesn't do anything.
Actually I was thinking about white frames and their appearance for bright colors. Perhaps a good solution would be to use complementary colors? https://www.canva.com/colors/color-wheel/
|
|
|
01-04-2023, 03:38 PM
|
#52
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
And one thing:
Try to avoid global variables, because they may break your code without you understanding where is the problem. This is not good, because you already use "r" for red. Not sure whether all of them are local, but still I'd try to avoid same name variables and make them a little bit longer (more characters), so you won't mix them up.
use instead:
Also I don't recommend this thing while you are still making the script, because you can't longer use autocomplete function and the color is different, so you don't know whether somewhere in these r.GetTarck you have a typo.
You could do this when finished, but still I don't see much sense in it, only to save some space on disk or to make it look shorter.
|
|
|
01-04-2023, 03:45 PM
|
#53
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Another great thing is using indentations. Maybe you think that it is not important and you always will remember which line is responsible for what, but believe me, you won't! And it is much easier to find something, when you have everything visually organized. Use Tab (perhaps on macOS it's the same) for each deeper layer.
I can't say whether rv is a local variable for this function or for the whole script. I mean visually of course. No need to waste your energy on remembering all these things, just tab and tab.
Code:
local function ColorPalette()
local rv
But when you do like this, you already know.
Code:
local function ColorPalette()
local rv
Also try don't forget about space after ",", so you won't get lost in it.
Last edited by vitalker; 01-04-2023 at 03:54 PM.
|
|
|
01-04-2023, 04:02 PM
|
#54
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Regarding ReaImGui and style vars/colors. I don't want to remember how many of these I pushed and how many I should pop. I've just created such a function:
Code:
function push_style()
local n = 0
reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_WindowPadding(), 3,3) n=n+1
reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_FramePadding(), 0,0) n=n+1
reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_ItemSpacing(), 2,5) n=n+1
reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_WindowRounding(), 12) n=n+1
return n
end
As you can see I am incrementing n each time I add a variable. Because the function returns n, I simply use "style_n = push_style()" and then reaper.ImGui_PopStyleVar(ctx, style_n).
Same for colors:
Code:
function push_color()
local n = 0
reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_WindowBg(), hsv(0,0,0.05,1)) n=n+1
reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_TitleBgActive(), hsv(0,0,0,1)) n=n+1
reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_TitleBg(), hsv(0,0,0.5,1)) n=n+1
return n
end
|
|
|
01-04-2023, 04:07 PM
|
#55
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
Ooh, those sexy round corners.
These ranges should be >0 and <1, so you won't see black and white.
Regarding more colors: now these white frames don't mean much, because when you change any parameter, you can no longer see selected items' colors in the palette. Another good thing would be a button, which Reset these Saturation, darkness, lightness, so you can always see the default colors. Value slider seems doesn't do anything.
Actually I was thinking about white frames and their appearance for bright colors. Perhaps a good solution would be to use complementary colors? https://www.canva.com/colors/color-wheel/
|
Thanks for responding.
Yes, I love round corners too!
I come along with ReaImGui and it's really fun and great!
Narrow down the range values permanently is easy to do.
Yes, certain sliders are just placeholders and for reminding about them.
Reset button for settings a must. I will work on it. Good Idea, thanks.
For sure, if you change a parameter, the white boxes...
but maybe someone is finding his settings and doesn't want to touch it for a certain project or theme... I like them a lot and think they are really useful for somebody's workflow.
For example, logic's color palette is missing this feature and bothers a lot of users.
Something like complimentary colors for "too-bright"-buttons would be great.
I was thinking about something like that too...
Saving settings would be great to implement:
-Last used (now it resets)
-Maybe a "Combo-Box" for different saved palettes
-the option to save palettes along/with different projects
BTW, it's Cfillions advice about alpha channel, which fixed the coloring issue. Great Guy!!!
|
|
|
01-04-2023, 04:09 PM
|
#56
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by vitalker
And one thing:
Try to avoid global variables, because they may break your code without you understanding where is the problem. This is not good, because you already use "r" for red. Not sure whether all of them are local, but still I'd try to avoid same name variables and make them a little bit longer (more characters), so you won't mix them up.
|
You have a little helper on the right part of IDE with global variables with filter box in the bottom-right corner.
|
|
|
01-04-2023, 04:09 PM
|
#57
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by OLSHALOM
Reset button for settings a must. I will work on it. Good Idea, thanks.
|
I could help you with it.
|
|
|
01-04-2023, 04:11 PM
|
#58
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by OLSHALOM
For sure, if you change a parameter, the white boxes...
but maybe someone is finding his settings and doesn't want to touch it for a certain project or theme... I like them a lot and think they are really useful for somebody's workflow.
For example, logic's color palette is missing this feature and bothers a lot of users.
Something like complimentary colors for "too-bright"-buttons would be great.
I was thinking about something like that too...
BTW, it's Cfillions advice about alpha channel, which fixed the coloring issue. Great Guy!!!
|
I'll think how to implement it. Perhaps it will be needed to combine two functions into one or use global variables to allow getting pallete colors.
Yeah, I know he knows.
|
|
|
01-04-2023, 04:22 PM
|
#59
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
And one thing:
Try to avoid global variables, because they may break your code without you understanding where is the problem. This is not good, because you already use "r" for red. Not sure whether all of them are local, but still I'd try to avoid same name variables and make them a little bit longer (more characters), so you won't mix them up.
use instead:
Also I don't recommend this thing while you are still making the script, because you can't longer use autocomplete function and the color is different, so you don't know whether somewhere in these r.GetTarck you have a typo.
You could do this when finished, but still I don't see much sense in it, only to save some space on disk or to make it look shorter.
|
Got you!!
I ran in this circumstance a few times, while r=red :-/
But while a lot is copy/paste code snippets, it was easier to use r = reaper
I change it.
Thanks for the advice.
|
|
|
01-04-2023, 04:22 PM
|
#60
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
Regarding ReaImGui and style vars/colors. I don't want to remember how many of these I pushed and how many I should pop. I've just created such a function:
Code:
function push_style()
local n = 0
reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_WindowPadding(), 3,3) n=n+1
reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_FramePadding(), 0,0) n=n+1
reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_ItemSpacing(), 2,5) n=n+1
reaper.ImGui_PushStyleVar(ctx, reaper.ImGui_StyleVar_WindowRounding(), 12) n=n+1
return n
end
As you can see I am incrementing n each time I add a variable. Because the function returns n, I simply use "style_n = push_style()" and then reaper.ImGui_PopStyleVar(ctx, style_n).
Same for colors:
Code:
function push_color()
local n = 0
reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_WindowBg(), hsv(0,0,0.05,1)) n=n+1
reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_TitleBgActive(), hsv(0,0,0,1)) n=n+1
reaper.ImGui_PushStyleColor(ctx, reaper.ImGui_Col_TitleBg(), hsv(0,0,0.5,1)) n=n+1
return n
end
|
Great one!!
|
|
|
01-04-2023, 04:27 PM
|
#61
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
I could help you with it.
|
Thanks for help, but this one is doable by myself.
But for saving settings I have no clue about.
Using Extstate?
Generate a file, where settings are saved?
I never did such a thing, start from scratch...
|
|
|
01-04-2023, 04:40 PM
|
#62
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by OLSHALOM
But for saving settings I have no clue about.
Using Extstate?
Generate a file, where settings are saved?
I never did such a thing, start from scratch...
|
Yes or projextstate. If you want, I can bring some code tomorrow, so you'll quickly understand.
|
|
|
01-04-2023, 04:42 PM
|
#63
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
Yes or projextstate. If you want, I can bring some code tomorrow, so you'll quickly understand.
|
Sounds great!
Thanks a lot!
|
|
|
01-05-2023, 11:39 AM
|
#64
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
I changed some things for better understanding. So the script has a default setting for this color thing. And we can also specify its value for each project independently. Firstly we check whether the project has this variable's ( color) value.
"vitalker script_name" is just a name of a section, which will appear inside the project file. Your script may have many variables, but all of them will be under one section (vitalker script_name).
We are checking whether the variable exist and its value is not empty. If it's true, then we assign its value to your variable in code. Remember: all variables in extstate are strings, so you need to convert them (if they are not strings) when you want to keep them in extstate or want to receive them from it.
If we don't find our variable inside project file, then we are looking inside reaper-extstate.ini. You may notice that I am not using HasProjeExtState. That's because there is no such a function, but fortunately it exists for reaper-extstate.ini. If there is such a variable ( color), then we get it (again, we should convert, if it's not a string).
If we don't saved variable inside project-/extstate, then we set our variable color to value 8 (which is default in this case). After that we putting it to reaper-extstate.ini (tostring(color) to make it work properly). After that we also putting our default value into the project. The script has independent buttons for setting value as global default or just this project.
This function is run before main loop.
PHP Code:
function get_state() local retval, color_state = reaper.GetProjExtState(0, 'vitalker script_name', 'color') if retval and color_state ~= '' then color = math.tointeger(color_state) elseif reaper.HasExtState('vitalker script_name','color') then color = math.tointeger(reaper.GetExtState('vitalker script_name','color')) else color = 8 reaper.SetExtState('vitalker script_name','color', tostring(color), true) reaper.SetProjExtState(0, 'vitalker script_name', 'color', tostring(color)) end end
get_state()
|
|
|
01-05-2023, 12:21 PM
|
#65
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Here is another example (not only about extstate):
You can create a table and assign new values to its elements instead of having many independent variables. Some info about tables:
https://www.lua.org/pil/2.5.html
https://www.lua.org/pil/3.6.html
PHP Code:
script = {} --this is table script.name = "vitalker script_name" script.x = 300 script.y = 300
Don't know whether you used this, but there is one very helpful function (reaper.atexit( func_name)). The best way to use it is to put a function inside as I just did. So you can have any instruction ( func_name function) when your script is exiting.
Another cool function is APIExists. Thanks to it you can check whether some API exists and do something if so or not. It may be helpful for compatibility matter. For example, if someone is using your script, but some API is missing (e.g. older version of Reaper). So in this case a user doens't get an error, but can't use some features because of lack of API.
PHP Code:
if reaper.APIExists('JS_Window_Find') then pin_window = reaper.JS_Window_Find("script_name", true) if pin_window then reaper.JS_Window_AttachTopmostPin(pin_window) end end
Instead of independent variables you can put an obfuscated string to extstate file. Here is how it works:
PHP Code:
pExtState = {} --our table pExtStateStr = "" --our future secret string
--Saves pExtState table in the project pExtStateStr = pickle(pExtState) --obfuscate/compress/encode etc. into one string reaper.SetProjExtState(0, script.name, "pExtState", pExtStateStr)
--how to unpack it: _, pExtStateStr = reaper.GetProjExtState(0, script.name, "pExtState") if pExtStateStr ~= "" then pExtState = unpickle(pExtStateStr) --getting our table again end
I hope everything is clear.
|
|
|
01-05-2023, 02:31 PM
|
#66
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
The script has independent buttons for setting value as global default or just this project.
|
Wow, that needs a year to implement for me :-)
Do you mean two buttons something like:
load/save settings
-with project
-as global default
Do I understand right?
|
|
|
01-05-2023, 02:38 PM
|
#67
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by OLSHALOM
Wow, that needs a year to implement for me :-)
Do you mean two buttons something like:
load/save settings
-with project
-as global default
Do I understand right?
|
No, it will take maybe an hour, if you have many things to save. I guess for many variable you'd like to use table way with pickle/unpickle function.
Well in my case it was color (not color, just an analogy). So it was set to some value and when I changed it I could save it as project default or as global default.
|
|
|
01-05-2023, 02:44 PM
|
#68
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
I hope everything is clear.
|
I think, I got it :-/
We will see...
In relation to save settings, what does this do?:
PHP Code:
if reaper.APIExists('JS_Window_Find') then
pin_window = reaper.JS_Window_Find("script_name", true)
if pin_window then reaper.JS_Window_AttachTopmostPin(pin_window) end
end
|
|
|
01-05-2023, 02:53 PM
|
#69
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,630
|
It's just an example of how to use ApiExists, if I got it right...
|
|
|
01-05-2023, 02:55 PM
|
#70
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by OLSHALOM
I think, I got it :-/
We will see...
In relation to save settings, what does this do?:
PHP Code:
if reaper.APIExists('JS_Window_Find') then pin_window = reaper.JS_Window_Find("script_name", true) if pin_window then reaper.JS_Window_AttachTopmostPin(pin_window) end end
|
As Meo-Ada Mespotine wrote. I will quote myself from the place just above that code
It does nothing regarding saving, just a side fact.
Quote:
Another cool function is APIExists. Thanks to it you can check whether some API exists and do something if so or not. It may be helpful for compatibility matter. For example, if someone is using your script, but some API is missing (e.g. older version of Reaper). So in this case a user doens't get an error, but can't use some features because of lack of API.
|
|
|
|
01-05-2023, 02:56 PM
|
#71
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,630
|
Quote:
Originally Posted by OLSHALOM
Thanks for help, but this one is doable by myself.
But for saving settings I have no clue about.
Using Extstate?
Generate a file, where settings are saved?
I never did such a thing, start from scratch...
|
Are the settings project related or global for all projects?
|
|
|
01-05-2023, 02:58 PM
|
#72
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by Meo-Ada Mespotine
Are the settings project related or global for all projects?
|
I guess it will be project-dependent. But probably some global settins would be used, too.
|
|
|
01-05-2023, 02:59 PM
|
#73
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,630
|
And are the settings numbers, strings or something else?
|
|
|
01-05-2023, 03:01 PM
|
#74
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by Meo-Ada Mespotine
And are the settings numbers, strings or something else?
|
I don't know yet, but I already described how to deal with numbers.
I am not sure OLSHALOM was thinking about it. I guess this pro tools setting could be project-dependent.
|
|
|
01-05-2023, 03:04 PM
|
#75
|
Human being with feelings
Join Date: May 2017
Location: Leipzig
Posts: 6,630
|
Ok, let OLSHALOM describe it. I guess it shouldn't be hard to put them on the right track to do it within hours or less, once this is cleared up.
|
|
|
01-05-2023, 03:08 PM
|
#76
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by Meo-Ada Mespotine
Ok, let OLSHALOM describe it. I guess it shouldn't be hard to put them on the right track to do it within hours or less, once this is cleared up.
|
Yeah, we can deal with it.
|
|
|
01-05-2023, 03:31 PM
|
#77
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by Meo-Ada Mespotine
Ok, let OLSHALOM describe it. I guess it shouldn't be hard to put them on the right track to do it within hours or less, once this is cleared up.
|
Thanks to both of you for jumping in here to help.
It means a lot to me!
Please give me another moment to think about, what a good and convenient concept to save settings would be.
|
|
|
01-05-2023, 03:37 PM
|
#78
|
Human being with feelings
Join Date: Dec 2012
Posts: 13,336
|
Quote:
Originally Posted by OLSHALOM
Please give me another moment to think about, what a good and convenient concept to save settings would be.
|
We are running out of time! It's time to save the world
|
|
|
01-05-2023, 03:39 PM
|
#79
|
Human being with feelings
Join Date: Sep 2019
Location: Austria
Posts: 461
|
Quote:
Originally Posted by vitalker
We are running out of time! It's time to save the world
|
Really true
|
|
|
01-06-2023, 02:30 PM
|
#80
|
Human being with feelings
Join Date: Dec 2019
Posts: 589
|
I'm following.
|
|
|
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:08 AM.
|