 |
|
|
05-26-2023, 05:05 AM
|
#1
|
Human being with feelings
Join Date: Dec 2021
Posts: 313
|
Packaging a python script as extension?
Is it possible to make an extension from a python script so that it would work for all users, regardless of if they have python installed?
|
|
|
05-26-2023, 06:14 AM
|
#2
|
Human being with feelings
Join Date: Dec 2012
Posts: 12,842
|
When you make it an extension, you'd have to compile the code for each OS. I'm not sure whether it will work for ReaScript, but you can compile Python code, for example using this tool: https://cython.org/
Maybe it would be easier to rewrite the script to Lua instead?
|
|
|
05-26-2023, 06:32 AM
|
#3
|
Human being with feelings
Join Date: Dec 2021
Posts: 313
|
Quote:
Originally Posted by vitalker
When you make it an extension, you'd have to compile the code for each OS. I'm not sure whether it will work for ReaScript, but you can compile Python code, for example using this tool: https://cython.org/
Maybe it would be easier to rewrite the script to Lua instead?
|
I see... unfortunately what I'm doing involves gui data like mouse position and defining co-ordinates on a plugin window that I'm pretty sure is beyond what lua can do.
I guess I'll go down the compilation route, although at first will probably be a "windows" only script... much as I would like to be inclusive.
|
|
|
05-26-2023, 06:46 AM
|
#4
|
Human being with feelings
Join Date: Jun 2009
Location: Croatia
Posts: 3,556
|
99.9% sure it can do that, and if you give us little sneak peak maybe we can help
|
|
|
05-26-2023, 07:00 AM
|
#5
|
Human being with feelings
Join Date: Dec 2012
Posts: 12,842
|
Quote:
Originally Posted by Sexan
99.9% sure it can do that, and if you give us little sneak peak maybe we can help
|
Yep, there is a native GFX + a couple of custom GUI libraries.
|
|
|
05-26-2023, 07:52 AM
|
#6
|
Human being with feelings
Join Date: Dec 2021
Posts: 313
|
Thanks... I will post back with a sneak peak once I have it in some semblance of order -- at the moment, it's a bunch of snippets which I need to tie together into one script!
|
|
|
05-26-2023, 10:15 AM
|
#7
|
Human being with feelings
Join Date: Dec 2021
Posts: 313
|
OK... here's a bit of it in python 3:
Code:
import wx
import tkinter as tk
from tkinter import *
from tkinter import ttk
def callback():
global selectionOffset, selectionSize
selectionOffset = ""
selectionSize = ""
class SelectableFrame(wx.Frame):
c1 = None
c2 = None
def __init__(self, parent=None, id=wx.ID_ANY, title=""):
wx.Frame.__init__(self, parent, id, title, size=(800,400))
self.menubar = wx.MenuBar(wx.MB_DOCKABLE)
self.filem = wx.Menu()
self.filem.Append(wx.ID_EXIT, '&Transparency')
self.menubar.Append(self.filem, '&File')
self.SetMenuBar(self.menubar)
self.Bind(wx.EVT_MOTION, self.OnMouseMove)
self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown)
self.Bind(wx.EVT_LEFT_UP, self.OnMouseUp)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_MENU, self.OnTrans)
self.SetCursor(wx.Cursor(wx.CURSOR_CROSS))
self.Show()
self.transp = False
wx.CallLater(250, self.OnTrans, None)
def OnTrans(self, event):
if self.transp == False:
self.SetTransparent(180)
self.transp = True
else:
self.SetTransparent(255)
self.transp = False
def OnMouseMove(self, event):
if event.Dragging() and event.LeftIsDown():
self.c2 = event.GetPosition()
self.Refresh()
def OnMouseDown(self, event):
self.c1 = event.GetPosition()
def OnMouseUp(self, event):
self.SetCursor(wx.Cursor(wx.CURSOR_ARROW))
self.Destroy()
def OnPaint(self, event):
global selectionOffset, selectionSize, top_left, bottom_right
if self.c1 is None or self.c2 is None: return
dc = wx.PaintDC(self)
dc.SetPen(wx.Pen('red', 1))
dc.SetBrush(wx.Brush(wx.Colour(0, 0, 0), wx.TRANSPARENT))
dc.DrawRectangle(self.c1.x, self.c1.y, self.c2.x - self.c1.x, self.c2.y - self.c1.y)
selectionOffset = str(self.c1.x) + "x" + str(self.c1.y)
selectionSize = str(abs(self.c2.x - self.c1.x)) + "x" + str(abs(self.c2.y - self.c1.y))
top_left = (self.c1.x, self.c1.y)
bottom_right = (self.c2.x - self.c1.x, self.c2.y - self.c1.y)
def PrintPosition(self, pos):
return str(pos.x) + "x" + str(pos.y)
class MyApp(wx.App):
def OnInit(self):
frame = SelectableFrame()
return True
app = MyApp(redirect=False)
app.MainLoop()
print(f"SELECTION:\n ^[ ] Top Left (x, y):\t {top_left} \n\t^ Bottom Right (x, y):\t {bottom_right}")
# root window
root = tk.Tk()
root.geometry('300x200')
root.resizable(False, False)
root.title('Preset Sleuth')
# capture button
exit_button = ttk.Button(
root,
text='Draw Capture Area',
command=callback
)
exit_button.pack(
ipadx=5,
ipady=5,
expand=True
)
root.mainloop()
I'm sure it's a bit clunky to use wxPython for one window and tkinter for another, but I'm very much new to programming and still very reliant on other people's code snippets.
Basically, this bit allows the user to draw a rectangle and the program then spits out the top-left and bottom-right co-ords.
Would be interested to know about if GFX or any custom GUI libs can do this.. I was probably too quick to assume it wasn't possible!
|
|
|
05-26-2023, 10:46 AM
|
#8
|
Human being with feelings
Join Date: Jun 2009
Location: Croatia
Posts: 3,556
|
Yes JS_API can do that, from my Area51 script which utilizes drawing over reaper with it:
Could you post a gif what it does so I can help you get started with small lua script?
Last edited by Sexan; 05-26-2023 at 10:52 AM.
|
|
|
05-26-2023, 12:34 PM
|
#9
|
Human being with feelings
Join Date: Dec 2021
Posts: 313
|
very rough mock-up:
you can guess what I'm trying to do -- the idea is to define an area of the plugin window that contains the plugin name. Those co-ords can then be fed to a freeware program called capture2text which does a pretty nifty job of capturing, doing OCR then putting the scanned text value into memory buffer to be pasted elsewhere. I can do this programmatically in python provided the user has Capture2text running in the background... to do the actual capture and OCR in Python is very much possible but seemed like re-inventing the wheel.
Needing the translucent overlay window to get the drawn rectangle is possibly superfluous, but as a novice programmer, it was my best shot at achieving the aim.
|
|
|
05-26-2023, 01:56 PM
|
#11
|
Human being with feelings
Join Date: Jun 2009
Location: Croatia
Posts: 3,556
|
If that little ocr program supports command line you can then do everything from the script
It looks bit scary because I've just copy pasted Mouse module script in it (you can use it as separate script and just call it with require) but the Main() is whole code for drawing etc.
98% of the code is just copy paste of this, but you dont need to worry about that at all its just handling mouse stuff for you:
https://github.com/GoranKovac/ReaScr...a_51_mouse.lua
Hope this will get you where you want
|
|
|
05-26-2023, 03:04 PM
|
#12
|
Human being with feelings
Join Date: Jun 2009
Location: Croatia
Posts: 3,556
|
Here is alternative version with ImGui:
Assign it to some shortcut key, hold down that key and drag away. Once you release it the script will stop
Only downside with this one is that Option "Ignore FX CHAIN keyboard shorcut..." needs to be checked (this is because the key-hold voodoo but we can remove that and make it normal script)
Code:
local r = reaper
START_TIME = reaper.time_precise()
CUR_PREF = reaper.SNM_GetIntConfigVar("alwaysallowkb", 1)
local key_state = reaper.JS_VKeys_GetState(START_TIME - 2)
for i = 1, 255 do
if key_state:byte(i) ~= 0 then
reaper.JS_VKeys_Intercept(i, 1);
KEY = i
end
end
if not KEY then return end
local function Key_held() return r.JS_VKeys_GetState(START_TIME - 2):byte(KEY) == 1 end
local function Release()
if not KEY then return end
r.JS_VKeys_Intercept(KEY, -1)
r.SNM_SetIntConfigVar("alwaysallowkb", CUR_PREF)
end
local ctx = r.ImGui_CreateContext("GUI DRAW")
local DL = r.ImGui_GetWindowDrawList( ctx )
local start_x, start_y = r.ImGui_PointConvertNative(ctx, r.GetMousePosition())
function Main()
if not Key_held() then return end
local x,y = r.ImGui_PointConvertNative(ctx, r.GetMousePosition())
r.ImGui_SetNextWindowPos( ctx, start_x - 200 , start_y - 200 )
r.ImGui_SetNextWindowSize(ctx, 1000, 1000)
if reaper.ImGui_Begin(ctx, 'ALPHA', false, r.ImGui_WindowFlags_NoBackground() | r.ImGui_WindowFlags_NoDecoration() | r.ImGui_WindowFlags_AlwaysAutoResize() | r.ImGui_WindowFlags_NoMove()) then
r.ImGui_SetNextWindowPos( ctx, start_x - 500 , start_y )
r.ImGui_SetNextWindowSizeConstraints( ctx, 200, 50, 200, 50 )
if reaper.ImGui_Begin(ctx, 'START', false) then
reaper.ImGui_Text(ctx, "START DRAGING WITH MOUSE")
r.ImGui_End(ctx)
end
if r.ImGui_IsMouseDown(ctx, 0) then
if not SX then
SX, SY = x, y
end
r.ImGui_DrawList_AddRectFilled( DL, SX, SY, x, y, 0x2222AA55 )
end
if r.ImGui_IsMouseReleased(ctx, 0) then
r.ShowConsoleMsg(("X : %d , Y : %d, XE : %d, YE : %d"):format(SX, SY, x, y) .. '\n')
end
r.ImGui_End(ctx)
end
r.defer(function() xpcall(Main, Release) end)
end
r.atexit(Release)
r.defer(Main)
Needs ReaImgui for drawing and JS_API for intercepting shortcut key
|
|
|
05-26-2023, 06:05 PM
|
#13
|
Human being with feelings
Join Date: Dec 2021
Posts: 313
|
Thank you both, brilliant stuff. Keen to check out these methods.
Yes, the Capture2Text has a CLI version, although it's windows only.
Long-run, if I get something working the way I hope, I could always look into doing the OCR in lua as well -- tesseract looks like a good bet? https://tesseract.wiki/w/Tesseract:L...rary_functions
|
|
|
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 11:45 PM.
|