Run an MCR file but ignore its macroscrip header?


#12

I doubt that it would be that easy.
How about macro with such structure?

macroScript testmacro
buttonText:"testmacro"
category:"custom"
tooltip:"test macro"
icon:#("someicon",1)
(
	local state = off
			
	fn someFunction = (

		...

	)
	
	
	on isChecked do
	(
		state
	)
	
	on isEnabled do (
				
		enabled = isKindOf selection[1] Editable_Poly
		if not enabled do state = false
		enabled
		
	)

	on execute do
	(
		...
		someFunction()
		...
	)
)

#13

@Serejah, the problem I am facing here is that as long you execute a Macroscript, you’ll have a copy of it under $userScripts.
If you decide to test out bunches of scripts, you’ll end up with a heap of files and categories that needs to be cleaned up manually .

Maybe we could save out a temporary .ms file and then run that file.


#14

it’s not safe in general case because MACRO can have specific for macroscript handlers which don’t make sense outside macroscript body (e.g. on isChecked, on isIndeterminate, on execute, on drop, etc.).

Run and Clean after that is the safer way IMHO

For example all my macros run with the execute handler which makes them ‘executable’ as a marcoscript only. (So you have to check first that the macro does not use execute handler before trying to run it your way)
Also some of my macros and tools need some other macros to be loaded (registered) before their own execution.


#15

BTW
I believe that using MCR files is an outdated technique and rarely use it.
I usually define macro(s) inside a plugin or script (MS) file.


#16

I couldn’t find anything about this event. What is it for?


#17

it was my misspelling and auto-fix … it has to be isIndeterminate


#18

is it somehow related to tri-state of a macro button? I always thought it can only be on/off


#19

isIndeterminate handler is usually used for menu and quad menu items. Because you can see it in UI (see the help).

You can use it in sense of ‘tri-state’ like as an ‘available’ action for not all currently selected (visible, etc.) nodes.

For example some action works for selected geometry class nodes. But current selection also includes helpers…
So you can define ability of this action as ‘indeterminate’ - means it works but not for all.
If there is no geometry nodes in the current list you should set it to ‘disabled’, if all nodes are geometries you should set it to ‘enabled’


#20

Thanks for the explanation, Denis.
There’s not a single word in reference about this particular handler.


#21

Can you please elaborate this?
Does Max treat MS and MCR different, ie, they are not just file extensions?

OK, I understand now and agree the idea I had can’t work.

Just drag-drop macroscripts into max to try them out will need more steps than that. I will need to know what category and what name the macroscript has. Then I need to track it down, before I can run it. Thankfully, I do have a little tool that quickly lists every macroscript there is, sorted by categories. Yet, it will require me to look into the macroscript, to figure out name and category.

So let me redesign my idea then :smile:

I drag drop the macroscript onto a “catcher” (that figures out the path of the file and then fileIn it for me) or I browse for the macroscript and press run, or equivalent method.
Then we’d need the maxscript to figure out the name and category that was just created.
Is that possible?
If so, then the next step could be simply presenting [macro name] [category] [run-button]
In case there are more macroscripts in the same file, they just get listed underneath each other

[macro name1] [category] [run-button]
[macro name2] [category] [run-button]
[macro name3] [category] [run-button]

What do you say?


#22

With something like this you can all the registered MacroScripts. The last entry should the latest MacroScript you registered.

If you run it via MaxScript, then the MacroScript ID is returned and you could use it for tracking it.

(
	stream = "" as stringstream
	
	macros.list to:stream
	
	seek stream 0
	
	macroscrips = #()
	
	while not eof stream do append macroscrips (readline stream)
	
	lastentry = filterstring macroscrips[macroscrips.count] "\""
	lastentry = for j in lastentry where j != " " collect trimleft (trimright j)
	
	format "MacroScript:\n"
	format "\t           ID: %\n" lastentry[1]
	format "\t         Name: %\n" lastentry[2]
	format "\t     Category: %\n" lastentry[3]
	format "\tInt. Category: %\n" lastentry[4]
	format "\t     FileName: %\n" lastentry[5]
	format "\t    Icon File: %\n" lastentry[6]
	format "\t   Icon Index: %\n" lastentry[7]
)

#23

it’s not a correct split.
name, categories, and paths might have " " (space) too


#24

MCR file expects only macros in it. MS file doesn’t have this expectation. But both of them will be just executed by the system


#25

I tried this out just now.
When I put an MCR under $userMacros, they get loaded upon max start, or when I load them with macros.load().
Putting an MS file either under $userScripts or $userMacros don’t get loaded until I drag-drop them into max or load them somehow.
I was hoping that comments and stuff outside the macroscript would be left intact when I work with MS, but the effect was just the same.

So I dont really get the benefit. What am I doing wrong or what am I misunderstanding?


#26

Can confirm that it didn’t work properly because of a space in my category name.

What if the MCR-file has multiple Macroscripts like some developers do? Can I catch that?
Or maybe if we had a “catcher UI”, ie a window that says “drop your script here”, we could keep track of everything that was dropped here?


#27

I had the feeling something was wrong as well as me lazy. :slight_smile:
I think it’s fixed now.


#28

Every MacroScript, regardless if they are in the same or different files, will have a new entry, so if you run a file with 3 MacroScripts in it you’ll have to delete the latest 3 entries not just the last one.

I don’t know if there is a callback to catch when a new MacroScript is registered. A quick workaround could be to monitor the Users MacroScript folder and record how many additional files are in there since you started the Max session.


#29

thank you, works great now :smile:

About monitoring, I propose an easier way. What your script does is giving us the last ID.

  1. We keep track of that ID
  2. We drop the files onto max (I think we dont even need a “drop your files here”-GUI anymore)
  3. We check what the last ID is now.
  4. We list all the created Macroscripts, the category and a run-button

[ Macroscript name ] [Category name ] [ Run ]

I guess this would only work if we had the tool interface open, so that we can start tracking the IDs


#30

Yes, much better.

BTW, I just noticed that the naming convention of the registered MacroScripts is not always “correct” according to the documentation (Category + “-” + MacroScript name).

For example, if the Category Name starts with “–”, the registered Category is correct in the Max UI, but the registered filename will start with “__”.

I don’t know what other characters could be replaced.

.

Perhaps you could record the last ID with a script in the startup folder and query it anytime you need?


#31

Apparently, any none alphanumeric or space characters in the Category name are converted to underscore character for the filename.

There is a SDK method in the MacroDir class to validate this name MakeCategoryValid().

If you happen to be on Max 2014+ you could use something like this to make a valid filename for the registered user MacroScript:

(
	categoryName = "-- My Category"
	
	gi = (dotnetclass "Autodesk.Max.GlobalInterface").instance
	gi.MacroScriptDir.MakeCategoryValid categoryName
)