Notifications
Clear all

[Closed] dotNet UI

 lo1
  1. Store all child buttons in an array
  2. set the .Tag property of all buttons (including the control buttons) to the index of their group
  3. define the event handler function as myFunction sender e =
  4. within the function, you can query s.tag to determine which group was activated
  5. for c in allButtons do c.visible = c.tag == s.tag

I only have a few minutes, otherwise I’d post an example code for you

I would add all your dotNet objects into a struct so you can access them with only one global variable.

Also, no, you cannot send custom parameters to functions via dotNetEventHandlers. You can only access the sender and the event.

Please have a look at the code below:


--Create a form and display it in Max. 
--Read about this process in the form & MaxForm tutorial. 

global dotNetForm
--Create a struct to access every dotNet object from one global variable

struct dotNetFormStruct (

	form=dotNetObject "form", --A comma is required at the end of every function/variable except the very last one.
	
	btn1 = dotNetObject "system.windows.forms.button",
	btn2 = dotNetObject "system.windows.forms.button" height:50,
	btn3 = dotNetObject "system.windows.forms.button",
	btnMS1 = dotNetObject "system.windows.forms.button" ,
	btnMS2 = dotNetObject "system.windows.forms.button" ,
	btnMS3 = dotNetObject "system.windows.forms.button",
	btnMSGroup = #()
	
)
dotNetForm = dotNetFormStruct()

--Customise the dotNet objects
dotNetForm.btn1.bounds=dotNetObject "System.drawing.rectangle" 10 10 36 36
dotNetForm.btn1.flatStyle=dotNetForm.btn1.flatStyle.flat
dotNetForm.btn1.backColor=dotNetForm.btn1.backColor.darkRed
dotNetForm.btn1.text="1"

dotNetForm.btn2.bounds=dotNetObject "System.drawing.rectangle" 48 10 36 36
dotNetForm.btn2.flatStyle=dotNetForm.btn2.flatStyle.flat
dotNetForm.btn2.backColor=dotNetForm.btn2.backColor.darkGreen
dotNetForm.btn2.text="2"

dotNetForm.btn3.bounds=dotNetObject "System.drawing.rectangle" 86 10 36 36
dotNetForm.btn3.flatStyle=dotNetForm.btn3.flatStyle.flat
dotNetForm.btn3.backColor=dotNetForm.btn3.backColor.darkBlue
dotNetForm.btn3.text="3"

dotNetForm.btnMS1.bounds=dotNetObject "System.drawing.rectangle" 10 48 112 24
dotNetForm.btnMS1.flatStyle=dotNetForm.btn1.flatStyle.flat
dotNetForm.btnMS1.backColor=dotNetForm.btn1.backColor.darkRed
dotNetForm.btnMS1.text="MaxScript1.ms"
dotNetForm.btnMS1.visible = false

dotNetForm.btnMS2.bounds=dotNetObject "System.drawing.rectangle" 10 48 112 24
dotNetForm.btnMS2.flatStyle=dotNetForm.btn1.flatStyle.flat
dotNetForm.btnMS2.backColor=dotNetForm.btn1.backColor.darkGreen
dotNetForm.btnMS2.text="MaxScript2.ms"
dotNetForm.btnMS2.visible = false

dotNetForm.btnMS3.bounds=dotNetObject "System.drawing.rectangle" 10 48 112 24
dotNetForm.btnMS3.flatStyle=dotNetForm.btn1.flatStyle.flat
dotNetForm.btnMS3.backColor=dotNetForm.btn1.backColor.darkBlue
dotNetForm.btnMS3.text="MaxScript3.ms"
dotNetForm.btnMS3.visible = false	

sysPointer=dotNetObject "system.intPtr" (windows.getMaxHWND())
maxHandle=dotNetObject "maxCustomControls.win32HandleWrapper" sysPointer

dotNetForm.form.show maxHandle
dotNetForm.form.bounds=dotNetObject "system.drawing.rectangle" 10 90 400 400
dotNetForm.form.text="DotNet UI"

--Functions (These can also be added to the stuct, but if you add them an event handler can not access them directly. Instead you must link to them through a function. See below)
	-- function showGroup1Link sender e = dotNetForm.showGroup1 sender e
	-- dotNet.addEventHandler showGroup1Link

function ShowGroup1 sender e = 
(
	print sender --this will give you access to the button that caused the event
	print e --this will give you the event with various things you can do, such as cancel the event.
	
	dotNetForm.btnMS1.visible = true
	dotNetForm.btnMS2.visible = false
	dotNetForm.btnMS3.visible = false
)

function ShowGroup2 sender e= 
(
	dotNetForm.btnMS1.visible = false
	dotNetForm.btnMS2.visible = true
	dotNetForm.btnMS3.visible = false
)

function ShowGroup3 sender e = 
(
	dotNetForm.btnMS1.visible = false
	dotNetForm.btnMS2.visible = false
	dotNetForm.btnMS3.visible = true
)
	
--Add the pictureBox to the form
dotNetForm.form.controls.add dotNetForm.btn1
	dotNetForm.form.controls.add dotNetForm.btnMS1
dotNetForm.form.controls.add dotNetForm.btn2
	dotNetForm.form.controls.add dotNetForm.btnMS2
dotNetForm.form.controls.add dotNetForm.btn3
	dotNetForm.form.controls.add dotNetForm.btnMS3

--//Button actions
dotNet.addEventHandler dotNetForm.btn1 "click" ShowGroup1
dotNet.addEventHandler dotNetForm.btn2 "click" ShowGroup2
dotNet.addEventHandler dotNetForm.btn3 "click" ShowGroup3

Hmm odd, when I paste in the code it adds a few spaces between some words. “.flatstyle” has become “.flatstyl e”! Has anyone seen this before?

I’ve attached it below. lol at having to put it in a zip to upload it! You would have thought .ms would be a valid file format

 lo1

This is how I usually build my dotnet tools. I use a control factory to avoid all that long repetitive code.
Of course all the functions can be customized to your needs.

global exampleDotNetTool
struct exampleDotNetToolStr
(
	
	--components
	form,
	parentBtns,
	childBtns,
	
	--handlers
	fn parentClicked s e =
	(
		for b in exampleDotNetTool.childBtns do b.visible = b.tag == s.tag
	),
	
	fn childClicked s e =
	(
		format "child of group % pressed
" s.tag
	),
	
	--initialization functions
	fn controlFactory type text backColor X Y W H tag =
	(
		local ctr = dotNetObject type
		ctr.text = text
		ctr.bounds = dotNetObject "System.Drawing.Rectangle" X Y W H
		ctr.backColor = (dotNetClass "System.Drawing.Color").fromArgb backColor.a backColor.r backColor.g backColor.b
		ctr.tag = tag
		ctr
	),	
	
	fn initializeForm =
	(
		form = dotNetObject "maxCustomControls.maxForm"		
		form.showInTaskbar = false
		form.text = "Dotnet Tool Example"
		form.bounds = dotNetObject "System.Drawing.Rectangle" 100 100 200 300
		form.controls.addRange parentBtns
		form.controls.addRange childBtns		
		local sysPointer = dotNetObject "System.IntPtr" (windows.getMaxHWND())
		local maxHandle = dotNetObject "maxCustomControls.win32HandleWrapper" sysPointer
		form.show maxHandle
	),
	
	fn initializeControls =
	(		
		local parentBtnDefs = #( \
			#("Button", "Parent 1", red, 10, 10, 50, 50, 1), 
			#("Button", "Parent 2", green, 70, 10, 50, 50, 2), 
			#("Button", "Parent 3", blue, 130, 10, 50, 50, 3)
		)
		local childBtnDefs = #( \			
			#("Button", "Child 1A", red, 10, 70, 50, 50, 1),
			#("Button", "Child 1B", red, 70, 70, 50, 50, 1),
			#("Button", "Child 2A", green, 10, 130, 50, 50, 2),
			#("Button", "Child 2B", green, 70, 130, 50, 50, 2),
			#("Button", "Child 3A", blue, 10, 190, 50, 50, 3),
			#("Button", "Child 3B", blue, 70, 190, 50, 50, 3)
		)
		parentBtns = for b in parentBtnDefs collect (controlFactory b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8])
		for b in parentBtns do dotnet.addEventHandler b "Click" parentClicked		
		childBtns = for b in childBtnDefs collect (controlFactory b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8])
		for b in childBtns do dotnet.addEventHandler b "Click" childClicked
		initializeForm()		
	),	
	
	init_trigger = initializeControls() --auto-initialize the controls on struct creation
)

::exampleDotNetTool = exampleDotNetToolStr()

Really nice code optimisation lo! Thanks for sharing, I’ll be sure to have a proper look through it a little later when I have some free time.

It’s definitely a good idea to loop through each button rather than applying settings individually in repetitive code.

Cheers,

Tim that is a good idea. Placing the buttons into the struct and then controlling them.
I noticed the spacing thing happening to me as well.
A way that I got around that was copy and pasting the code into a text document then copying it from there into the cgtalk text field.

It seems like a bummer that you can not send out custom parameters into the functions. The ability to streamline one functions versatility seems to be a bit more limited then in that case. Of course you can always just write more code to achieve the desired effect regardless.

I knew in writing the functions separately for each button was super REDUNDANT and frowned upon, but I had written that way so I would be able to ask the question about sending custom parameters through functions, in return allowing me to condense it all into one function.

Lo great work on the post. I really appreciate you sharing you code here on the thread. As well as Tim. I’m definitely picking up things the more and more this develops. I’ll do another round of revisions and developing this evening and post later today. I’ve got some cool ideas that I want to do with this UI. It also helps a lot to be able to develop this and at the same time having you guys overlooking and helping me make it efficiently written from the start. You’ve definitely condensed the code a ton. I’m going to check it out here and look into a bit more to completely understand it. Thank you for the example you’ve posted here. It will surely help.

It seems like the Tag property in dotNet is a underrated property. It makes me think of the User Defined panel in 3ds max. That is a very useful place for control objects/scenes via maxscript. Rather than storing information on scene/root nodes or tracks. Aside from that the Tag property seems like it is definitely something to become very familiar with and something to get used to using.

Just to understand a bit more on how functions work within the dotNet galaxy I was wondering how would I write one function that would change the color for an object’s wirecolor but by passing a custom variable through the function. Below is an example of what I’ve done using the maxscript + rollout + dotnet to do what I just explained. One function and one custom variable. Just simple example. My question being how would I do the equivalent of this using solely dotNet.


try(destroyDialog rlMattes)catch()
rollout rlMattes "Mattes"
(
	dotNetControl btnMatteRed "system.windows.forms.button" height:30 width:30 pos:[5,5]
	dotNetControl btnMatteGreen "system.windows.forms.button" height:30 width:30 pos:[40,5]
	dotNetControl btnMatteBlue "system.windows.forms.button" height:30 width:30 pos:[75,5]
	dotNetControl btnMatteBlack "system.windows.forms.button" height:30 width:30 pos:[110,5]
	dotNetControl btnMatteCyan "system.windows.forms.button" height:30 width:30 pos:[5,40]
	dotNetControl btnMatteMagenta "system.windows.forms.button" height:30 width:30 pos:[40,40]
	dotNetControl btnMatteYellow "system.windows.forms.button" height:30 width:30 pos:[75,40]
	dotNetControl btnMatteWhite "system.windows.forms.button" height:30 width:30 pos:[110,40]
	dotNetControl btnDelLites "system.windows.forms.button" height:24 width:135 pos:[5,75]
	
	fn fnMatteMat col = (
		MatteMaterial = StandardMaterial diffuse:col Selfillumination:100
		return MatteMaterial
	)
	
-- Red
	on btnMatteRed mouseDown senderArg arg do (for obj in selection do obj.material = fnMatteMat red)
-- Green
	on btnMatteGreen mouseDown senderArg arg do (for obj in selection do obj.material = fnMatteMat green)
--Blue
	on btnMatteBlue mouseDown senderArg arg do (for obj in selection do obj.material = fnMatteMat blue)
--Black
	on btnMatteBlack mouseDown senderArg arg do (for obj in selection do obj.material = fnMatteMat black)	
--Cyan	
	on btnMatteCyan mouseDown senderArg arg do (for obj in selection do obj.material = fnMatteMat (color 0 255 255))
--Magenta	
	on btnMatteMagenta mouseDown senderArg arg do (for obj in selection do obj.material = fnMatteMat (color 255 0 255))	
--Yellow	
	on btnMatteYellow mouseDown senderArg arg do (for obj in selection do obj.material = fnMatteMat yellow)	
--White	
	on btnMatteWhite mouseDown senderArg arg do (for obj in selection do obj.material = fnMatteMat white)
--Delete Lights	
	on btnDelLites mouseDown senderArg arg do (delete Lights)

	on rlMattes open do
	(
		dnColor = dotNetClass "System.Drawing.Color"
		
		btnMatteRed.flatStyle=btnMatteRed.flatStyle.flat
		btnMatteGreen.flatStyle=btnMatteRed.flatStyle.flat
		btnMatteBlue.flatStyle=btnMatteRed.flatStyle.flat
		btnMatteBlack.flatStyle=btnMatteRed.flatStyle.flat
		btnMatteCyan.flatStyle=btnMatteRed.flatStyle.flat
		btnMatteMagenta.flatStyle=btnMatteRed.flatStyle.flat
		btnMatteYellow.flatStyle=btnMatteRed.flatStyle.flat
		btnMatteWhite.flatStyle=btnMatteRed.flatStyle.flat
		btnDelLites.flatStyle = btnDelLites.flatStyle.flat
		
		dnFontStyle = dotNetClass "System.Drawing.FontStyle"
		--myFontStyle = dotnet.combineenums dnFontStyle.bold dnFontStyle.italic
		btnDelLites.font = dotNetObject "System.Drawing.Font" "Veranda" 8 --myFontStyle
		btnDelLites.text="Delete Lights"
 		btnDelLites.TextAlign= (dotNetClass "System.Drawing.ContentAlignment").MiddleCenter
		
		btnMatteRed.backColor=dnColor.FromArgb 255 0 0
			btnMatteRed.flatappearance.bordercolor = dnColor.FromArgb 128 0 0
		
		btnMatteGreen.backColor=dnColor.FromArgb 0 255 0
			btnMatteGreen.flatappearance.bordercolor = dnColor.FromArgb 0 128 0
		
		btnMatteBlue.backColor=dnColor.FromArgb 0 0 255
			btnMatteBlue.flatappearance.bordercolor = dnColor.FromArgb 0 0 128
		
		btnMatteBlack.backColor=dnColor.FromArgb 0 0 0
			btnMatteBlack.flatappearance.bordercolor = dnColor.FromArgb 128 128 128
		
		btnMatteCyan.backColor=dnColor.FromArgb 0 255 255
			btnMatteCyan.flatappearance.bordercolor = dnColor.FromArgb 0 128 128
		
		btnMatteMagenta.backColor=dnColor.FromArgb 255 0 255
			btnMatteMagenta.flatappearance.bordercolor = dnColor.FromArgb 128 0 128
			
		btnMatteYellow.backColor=dnColor.FromArgb 255 255 0
			btnMatteYellow.flatappearance.bordercolor = dnColor.FromArgb 128 128 0
			
		btnMatteWhite.backColor=dnColor.FromArgb 255 255 255
			btnMatteWhite.flatappearance.bordercolor = dnColor.FromArgb 128 128 128
	)	
)
createDialog rlMattes 145 104


1 Reply
 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

You can use the tag property for this too, set the .tag property of the button to the color it should set the object material to, and just use that as the function parameter. (you can even use the .backcolor property in your example, don’t need the .tag property)

 lo1

btw, the “system.windows.forms” namespace is automatically loaded in maxscript, so you don’t have to write “system.windows.forms.button”, you can just write “button”.

This is maybe a stupid idea but when you are setting your event listeners you could try to put the call of the function in a variable and then give that variable as function when adding the eventlistener

like :

local blabla = somefunction parameter1 parameter2
dotNet.addEventHandler btn1 “click” blabla

I have never tried it …

 lo1

Assuming that would work, what would that give you?
You’d still have no control over parameter1 and parameter2 based on the calling control, unless you’re querying properties of the sender, which is what you’d do if you were calling the function directly.

So you can essential still run a function with variable using dotNet but using the tag property of the button as the place to hold the variable.

I’ve written a rather simple material color changer. I wanted to us the point3 color to set the color rather that the color of the button. I did it this way just for the sake of trying it that way.

I wanted to do this just as a quick test. It’s not for anything in particular other than good practice. I wanted to make sure I’m understand the functions & variables for buttons.

I’m sure this could probably be condensed a bit and written a bit more efficiently. As i have mentioned before I’m learning dotNet so I’m not aware of all the places to condense code just yet. Any ideas or examples are more than welcome. Thanks

This is the code.


try(form.close())catch()

fn dotnetcolor r g b = (
	(dotNetClass "System.Drawing.Color").fromARGB r g b
)
font=dotNetObject "System.Drawing.Font" "Arial" 8	

fn fnMatteMat col = (
	col = execute col
	MatteMaterial = StandardMaterial diffuse:col Selfillumination:100
	return MatteMaterial
)

fn colorClicked s e =
(
	for obj in selection do obj.material = fnMatteMat s.tag
)

--//Blue button
btnBlue=dotNetObject "button"
btnBlue.flatStyle=btnBlue.flatStyle.flat
btnBlue.backColor=btnBlue.backColor.blue
btnBlue.size=dotNetObject "system.drawing.size" 50 24
btnBlue.location=dotNetObject "system.drawing.point" 10 10
btnBlue.text = "Blue"
btnBlue.foreColor = (dotnetcolor 255 255 255)
btnBlue.font = font
btnBlue.tag = (color 0 0 255) as string

--//Red button
btnRed=dotNetObject "button"
btnRed.flatStyle=btnRed.flatStyle.flat
btnRed.backColor=btnRed.backColor.red
btnRed.size=dotNetObject "system.drawing.size" 50 24
btnRed.location=dotNetObject "system.drawing.point" 60 10
btnRed.text = "Red"
btnRed.foreColor = (dotnetcolor 255 255 255)
btnRed.font = font
btnRed.tag = (color 255 0 0) as string

--//Green button
btnGreen=dotNetObject "button"
btnGreen.flatStyle=btnGreen.flatStyle.flat
btnGreen.backColor=btnGreen.backColor.green
btnGreen.size=dotNetObject "system.drawing.size" 50 24
btnGreen.location=dotNetObject "system.drawing.point" 110 10
btnGreen.text = "Green"
btnGreen.foreColor = (dotnetcolor 255 255 255)
btnGreen.font = font
btnGreen.tag = (color 0 255 0) as string

--//Event Handlers
dotnet.addEventHandler btnBlue "Click" colorClicked
dotnet.addEventHandler btnRed "Click" colorClicked
dotnet.addEventHandler btnGreen "Click" colorClicked

form=dotNetObject "form"
form.controls.add btnBlue
form.controls.add btnRed
form.controls.add btnGreen

form.show()



Page 2 / 18