The Hamma Posted June 17 Share Posted June 17 Hello All: Would anyone know if it would be possible to script a script to organize script palettes in the GUI. Manytimes they end up all over my workspace but it would be nice to have them stacked in an instant. Instead of this I would like this. 1 Quote Link to comment
Pat Stanford Posted June 17 Share Posted June 17 Short answer is No. Longer answer is that this used to be possible using AppleScript (if you are on a Mac), but I think the ability to find the palettes has gone away in more recent version of VW. 1 Quote Link to comment
JBenghiat Posted June 17 Share Posted June 17 I’m fairly sure there is no way to automate this. If these scripts aren’t document-specific, you can move them to plug-in commands and access from menus 1 Quote Link to comment
The Hamma Posted June 17 Author Share Posted June 17 I figured as much, Thanks Pat and Joshua! Quote Link to comment
VectorGeek Posted July 31 Share Posted July 31 I can confirm Pat and Josh's comments. IMHO, VW's palette control is a real weak spot. Moving from a 3-monitor setup (laptop/32" display/27" display is our standard setup for all staff) to "laptop only" scrambles everything. When plugging back into my dock - powering all displays - the OIP, Navigation palette, Resource Browser, Tool palette(s), and any custom script palettes need to to be moved back to their original position. Time consuming, and extremely frustrating. Also, the "Save Palette Position" command is useless. I remove it from our workspaces so as to not give staff false hope... This should be a simple fix. Screen parameters can be saved and restored (other Mac apps do this flawlessly). Can someone from VW explain why this has been an issue since the early days of MC/VW? V-G -- Former Olympic Gymnast representing Kazakhstan........NOTTTT!! 1 Quote Link to comment
Popular Post DomC Posted August 11 Popular Post Share Posted August 11 Hi Interesting Thread. Also i am also very interested to a facelift of script function palette. Some industries needs a lot of custom functions (easy ones like custom-tool in the tool menu) I have an own approach of organizing through one single palette, which have Favorite Scripts but can access to non-favorite scripts as well over the separator. Also there is a dialog, which allows to add and remove script to the favorite palette. Not finished yet (i will have to implement some presets to easy reset palettes to default) The scripts have to be numbered to keep position in they separator. Not very graceful but best i saw so far. I have a class palette_runner. Which runs a script by name. And in every seperator i call the scripts which starts with a sorting number till the next separator. And a script manager to manage the favorite sript-palette. So i have just one visible script-palette which i have to re-position. ScreenFlow.mp4 VSSM Vorgabe in Arbeit DC_bem scripts_leer.vwx 6 Quote Link to comment
The Hamma Posted August 12 Author Share Posted August 12 (edited) On 8/11/2024 at 4:28 PM, DomC said: have an own approach of organizing through one single palette, which have Favorite Scripts but can access to non-favorite scripts as well over the separator. Also there is a dialog, which allows to add and remove script to the favorite palette. Not finished yet (i will have to implement some presets to easy reset palettes to default) This is so cool! 🤯 I wish I could read it, LOL, and I had a better understanding of how this works. I have a file folder filled with external scripts and I would love to be able to adapt your dialog box to invoke those scripts so I could just have one script built into the workspace and have all the scripts live in the workgroup folder. That way they could be invoked from anywhere without having to add each one to the workspace or the drawing. Edited August 12 by The Hamma Quote Link to comment
DomC Posted August 13 Share Posted August 13 I always try to code and comment in in english (anyway the code is not good documented on this prototype script). However this is a good idea to access to the external resource and even not copy the script resource on the working document. The steps would be: 1. Read Workgroup folder in the Windows Registry or the Macintosh Application Support. Which can be done somewhere in this forum there is a workflow to read this path. 2. Adapt the script (The Starter Palette is just one column, if you have over hundred script it will fill up the screen, so this maybe has to by changed to dynamically create more columns if needed) 3. You could use the starter Script from my example. class vssmPaletteRunner(): dialog_dict = {} def run_palette(st_palette_name = 'ArgumentPalettenname', exclude_palettes=['ST Script Module'], res_path = ''): listID, numItems = vs.BuildResourceListN(49, res_path)#Symbols id_dict = {} dialog_dict = {} res_names = [] res_dict = {} for i in range(numItems): res_name = vs.GetNameFromResourceList(listID, i) if res_name != '': res_names.append(res_name) res_dict[res_name] = i dialog_dict['res_names'] = res_names def dialog_main(): def CreateDialog(): dialog = vs.CreateLayout( 'Scripte Schnellzugriff', False, 'OK', 'Abbrechen') last_item_id = 10 act_item_id = last_item_id + 1 vs.CreateStaticText( dialog, act_item_id, 'Klicke auf die gewünschte \rFunktion.\r', -1 ) #vs.SetStaticTextColorN( dialog, act_item_id, 2) vs.SetFirstLayoutItem( dialog, act_item_id ) for res_name in dialog_dict['res_names']: last_item_id = act_item_id act_item_id += 1 fill_number = 55 - len(res_name) fill_string = ' ' * fill_number #vs.AlrtDialog(str([last_item_id, act_item_id, res_name])) #vs.CreatePushButton( dialog, act_item_id, res_name + fill_string) #vs.CreatePushButton( dialog, act_item_id, ' ' * 50) vs.CreateStaticText(dialog, act_item_id, res_name, -1) vs.SetItemClickable(dialog, act_item_id, True) #vs.AlignItemEdge( dialog, act_item_id, 3, 1, 1 ) #vs.CreateStandardIconControl(dialog, act_item_id, 0) vs.SetBelowItem( dialog, last_item_id, act_item_id, 0, 0 ) if 'Elektro' in res_name: #res = vs.GetColorButton(dialog, act_item_id) vs.SetColorButton(dialog, act_item_id, 65000,0,0) #res = vs.GetColorButton(dialog, act_item_id) last_item_id = act_item_id id_dict[str(act_item_id)] = res_name last_item_id = act_item_id act_item_id += 1 vs.CreateStaticText(dialog, act_item_id, ' ', -1) vs.SetBelowItem( dialog, last_item_id, act_item_id, 0, 0 ) return dialog # Sample dialog handler # Uncomment this code if you want to display the dialog def DialogHandler(item, data): if item == 12255: #Enter Dialog for key in id_dict: id = int(key) vs.SetItemClickable(dialog, id, True) #vs.SetItemText(dialog, id, id_dict[key]) # works also #vs.SetControlText(dialog, id, id_dict[key]) #crash #vs.AlignItemEdge( dialog, id, 3, 1, 1 ) vs.SetStaticTextColorN( dialog, id, 2) #does nothing #vs.SetColorButton(dialog, id, 62000,0,0) #does nothing if 10 < item < 10000: dialog_dict['func_id'] = str(item) return 1 if item == 1: pass result = False dialog = CreateDialog() if vs.RunLayoutDialogN(dialog, DialogHandler, False) == 1: result = True return result result = dialog_main() if result: func_id = dialog_dict.get('func_id', False) if func_id: script_name = id_dict[func_id] script_id = res_dict[script_name] #vs.AlrtDialog(str([script_name, func_id, script_id])) try: existing_res = vs.GetObject(script_name) if existing_res != vs.Handle(0): vs.DelObject(existing_res) except: pass new_res = vs.ImportResToCurFileN(listID, script_id, None) vs.PythonExecute(str(vs.GetScriptResource(script_name)[1])) vs.DelObject(new_res) #GetScriptResource vssmPaletteRunner.run_palette(res_path = '/Users/dominiquecorpataux/Downloads/test2.vwx') I modified a little: 1. BuildResourceListN with a path to the file 2. Deleted the part with the palette-name-filter That is is defined as a class is not necessary for single use. Just is necessary if you want to call the function outside in another script to path values between different scripts. And the fullPath is the path to the workgroup folder Script Document. You can test with a single path to your script document. Two open things: 1. I think the script have to be temporary imported to run and deleted after which looks not very elegant 2. "vs.PythonExecute(str(vs.GetScriptResource(script_name)[1]))" runs a python script. I do not know how to run pascal code here. Quote Link to comment
The Hamma Posted August 13 Author Share Posted August 13 5 hours ago, DomC said: Two open things: 1. I think the script have to be temporary imported to run and deleted after which looks not very elegant 2. "vs.PythonExecute(str(vs.GetScriptResource(script_name)[1]))" runs a python script. I do not know how to run pascal code here. I was thinking more using this to run external pyton script that was in a text file. import _main _main.execute() https://developer.vectorworks.net/index.php/Python_Sample_Menu_Command Quote Link to comment
DomC Posted August 13 Share Posted August 13 Aha, then you could use this one. I like this idea. Also for myself i have tons of scripts and this one can help execute them fast with a menu command and one single click. Thinkable ToDoes: - What would be cool, a palette with a searchable list browser or similar. I was never able to create propper popup with search bar - maybe support for sub-folders in module directory import os import importlib dialog_dict = {} def get_py_files(directory): # Traverse the directory tree and collect all .py files without their extensions py_files = [] for root, dirs, files in os.walk(directory): for file in files: if file.endswith(".py"): # Add the file name without the .py extension to the list py_files.append(os.path.splitext(file)[0]) return py_files def run_palette(directory=''): # Set the directory to search for Python scripts vs.PythonSetSearchPath(directory) # Set the search path for Python modules dialog_dict['res_names'] = get_py_files(directory) # Get all .py files id_dict = {} def dialog_main(): def CreateDialog(): # Create the main dialog layout dialog = vs.CreateLayout('Scripte Schnellzugriff', False, 'OK', 'Abbrechen') last_item_id = 10 act_item_id = last_item_id + 1 vs.CreateStaticText(dialog, act_item_id, 'Klicke auf die gewünschte \rFunktion.\r', -1) vs.SetFirstLayoutItem(dialog, act_item_id) # Create static text items for each script name for res_name in dialog_dict['res_names']: last_item_id = act_item_id act_item_id += 1 vs.CreateStaticText(dialog, act_item_id, res_name, -1) vs.SetItemClickable(dialog, act_item_id, True) vs.SetBelowItem(dialog, last_item_id, act_item_id, 0, 0) id_dict[str(act_item_id)] = res_name # Add a spacer at the end last_item_id = act_item_id act_item_id += 1 vs.CreateStaticText(dialog, act_item_id, ' ', -1) vs.SetBelowItem(dialog, last_item_id, act_item_id, 0, 0) return dialog def DialogHandler(item, data): if 10 < item < 10000: dialog_dict['func_id'] = str(item) return 1 dialog = CreateDialog() result = vs.RunLayoutDialogN(dialog, DialogHandler, False) == 1 return result result = dialog_main() if result: func_id = dialog_dict.get('func_id', False) func_name = id_dict[func_id] if func_id: # Dynamically import and execute the selected module module = importlib.import_module(func_name) directory_with_pytho_modules '/Volumes/SD_Card/Dropbox/Entwicklung/python_scripte' # Run the palette function to start the dialog run_palette(directory = directory_with_python_modules) 1 Quote Link to comment
The Hamma Posted August 13 Author Share Posted August 13 Ob 2 hours ago, DomC said: Aha, then you could use this one. I like this idea. Also for myself i have tons of scripts and this one can help execute them fast with a menu command and one single click. Obviously you are very fluent in Python. Many of my scripts are also in Vectorscript. I have not been able to find a command to run an external vectorscript other than the "DoMenuTextByName('Run Script',00);" but that requires you to choose the script in a dialog box. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.