dotNet UI

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

REPLY TO THREAD
 
Thread Tools Search this Thread Display Modes
Old 10 October 2011   #16
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,
 
Old 10 October 2011   #17
Tim and Lo

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.fl  at
		btnMatteYellow.flatStyle=btnMatteRed.flatStyle.fla  t
		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
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
Old 10 October 2011   #18
Originally Posted by JokerMartini: 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.


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)
 
Old 10 October 2011   #19
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".
 
Old 10 October 2011   #20
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 ...
__________________
Portfolio
 
Old 10 October 2011   #21
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.
 
Old 10 October 2011   #22
Functions + variable

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()

__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
Old 10 October 2011   #23
I don't like the 'execute' function, when possible it should be avoided.

you could more easily store #(255,0,0) in the tag instead of (color 255 0 0) as string, then recreate the color as color s.tag[1] s.tag[2] s.tag[3]
 
Old 10 October 2011   #24
That is a good idea.
Execute is usually a last resort of things....super last resort.
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
Old 10 October 2011   #25
Originally Posted by lo: I don't like the 'execute' function, when possible it should be avoided.

you could more easily store #(255,0,0) in the tag instead of (color 255 0 0) as string, then recreate the color as color s.tag[1] s.tag[2] s.tag[3]


you can easily store max color in tag as dotnetmxsvalue:

  control.tag = dotnetmxsvalue red
  print control.tag.value
  


ps. i usually store structures in control's tag
 
Old 10 October 2011   #26
To better explain things.....this is what I'm after and going for.




The ability to target one master folder for example

C:\User\Scripts\
Then within it are subfolders such as Animation,Rendering,Tools
Those subfolders are (as lo put it) the parent buttons and the children are the .ms scripts.

It would be like taking this and converting it so it creates the buttons instead of an rc menu.
Just change the "dir" to a targeted directory of scripts and run it.


(
	local fullPath = undefined
	dir = @"C:\Users\Crabs User\Desktop\testScripts" --//Main Scripts directory
	dirArray = GetDirectories (dir+"/*") --//Get subfolders in directory
	foldersArray = for d in dirArray collect (trimright (filenameFromPath d) "\\") --//Array which stores just the names of the subfolders

	local cm = dotNetObject "System.Windows.Forms.ContextMenuStrip"
	local cursor = dotNetClass "System.Windows.Forms.Cursor"

	for i in foldersArray do
	(
		item = cm.Items.Add i
		item.name = i
	)

	fn onPopup s e = 
	(
		for b = 1 to foldersArray.count do
		(
			i = (s.Items.Find (foldersArray[b] as string) off)[1]
			i.DropDownItems.Clear()
			
			sFiles = #()
			sFiles = getFiles (dirArray[b] + "*.ms*")
			
			fn fnRunScript s e = --Run the selected script 
			(
				fileIn (s.tag)
			) 
			
			if sFiles.count > 0 then --//Add the scripts to appropriate list
			(
				for n in sFiles do
				(
					scriptName = getFIleNameFile n
					item = i.DropDownItems.Add scriptName
					item.name = scriptName
					item.tag = n -- variable "n" contains the fullpath extention
					
					dotnet.addEventHandler item "Click" fnRunScript
				)
			)
			else
			(
				item = i.DropDownItems.Add "No Scripts"
				item.enabled = off
			)
		) 
	)
	dotnet.addEventHandler cm "Opening" onPopup

	on execute do
	(
		cm.Show(cursor.Position)
	)
)



Now I'm going to look into how to procedural add a button on creation. Which the equivalent of that in maxscript would be rci.addControl #button #myButton "My Button"
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com

Last edited by JokerMartini : 10 October 2011 at 08:38 PM.
 
Old 10 October 2011   #27
Originally Posted by JokerMartini: No I'm going to look into how to procedural add a button on creation. Which the equivalent of that in maxscript would be rci.addControl #button #myButton "My Button"


That's easy in dotnet... just a simple loop. No need for a rollout creator.
 
Old 10 October 2011   #28
Step 1

Got step one.
Building each button based on a loop. This main buttons being the parents.
Next is building each button and then its children buttons.

For the time being I just stored a string of names in the Array instead of putting a directory. Next version I'll being referencing a directory though.



parentFolders = #("Animation","Rendering","Modeling") --Main Folders

form=dotNetObject "form"
sysPointer=dotNetObject "system.intPtr" (windows.getMaxHWND())
maxHandle=dotNetObject "maxCustomControls.win32HandleWrapper" sysPointer
form.show maxHandle
form.bounds=dotNetObject "system.drawing.rectangle" 10 90 400 400
form.text="DotNet UI" 
	
for i = 1 to parentFolders.count do (	
	btn = dotNetObject "system.windows.forms.button"
	btn.Text = (parentFolders[i] as string)
	btn.Left = 10
	btn.Top = 10 + (i*24)
 	form.Controls.Add(btn)
)


I'm starting to like this dotNet stuff more and more. I feel like I'll never want to build a ui using rollouts in max.
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
Old 10 October 2011   #29
A word of warning: currently any events you assign to your buttons will be lost with the first maxscript garbage collection. This is because there is no reference to them in maxscript, only in the dotnet form.

You have two possible solutions for this:
1) in max2010 and up, use the dotnet.setLifeTimeControl method.
2) add all dotnet controls that you need to keep events for in an array, ideally within a struct. See the example I gave earlier in this thread. This is my preferred method because it doesn't limit your script to 2010 and up.

This issue has been discussed to exhaustion in other threads on this forum, in case you seek more information on it.
 
Old 10 October 2011   #30
step 2

Here is the initial code which takes a targeted folder and scans its subfolders for scripts and puts a number value at the beginning of the name to signify which group its it. That is only for the purpose of testing for right now.

This is what I've got so far.
Any improvements or comments or suggestions are welcome!


--//Variables
dir = @"C:\Users\IEVFX\Desktop\trash\scripts" --//Main Scripts directory
dirArray = GetDirectories (dir+"/*") --//Get subfolders in directory
parentFolders = for d in dirArray collect (trimright (filenameFromPath d) "\\") --//Array which stores just the names of the subfolders


form=dotNetObject "form"
sysPointer=dotNetObject "system.intPtr" (windows.getMaxHWND())
maxHandle=dotNetObject "maxCustomControls.win32HandleWrapper" sysPointer
form.show maxHandle
form.bounds=dotNetObject "system.drawing.rectangle" 10 90 400 400
form.text="DotNet UI" 


--//Creates the Parent buttons
for i = 1 to parentFolders.count do (	
	btn = dotNetObject "system.windows.forms.button"
	btn.Text = (parentFolders[i] as string)
	btn.Left = 10
	btn.Top = 10 + (i*24)
 	form.Controls.Add(btn)
)


--//Creates children buttons
for b = 1 to parentFolders.count do
(
	sFiles = #()
	sFiles = getFiles (dirArray[b] + "*.ms*")
	
	if sFiles.count > 0 then --//Add the scripts to appropriate list
	(
		for n = 1 to sFiles.count do
		(
 			scriptName = getFIleNameFile sFiles[n]
			btn = dotNetObject "system.windows.forms.button"
			btn.Text = (b as string + "_" + scriptName as string)
			btn.Left = 90 * b
			btn.Top = 10 + (n*24)
			btn.tag = sFiles[n]
			print btn.tag
			form.Controls.Add(btn)
		)
	)
) 
__________________
____________ ___ __ _
John A. Martini
JokerMartini@hotmail.com
www.JokerMartini.com
 
reply share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 05:19 PM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.