Notifications
Clear all

[Closed] Drag-to-select interface possible?

That is a great idea Lo,

It would be cool to be able to go into edit mode and have something along the lines of like a “list” which could be populated with item/s which would be selected if that dotNet control was selected.

Makes it very universal. Could almost make the whole thing just customizeable.
Having and add and remove button so users could then build a ui to their liking on the fly.

 lo1

@John : Yes this is exactly what I mean. I’ve attached two images (operational mode and design mode) of my implementation of this sort of customizable interface – in this case, a face rig control UI. I’ve blurred out parts I can not show, but they are irrelevant to the subject.

Wow Lo,
That is quite a badass tool.
That seems like it could be so so versital. I’d love to spend time learning the process of how that was built and begin to build on myself.

 lo1

I would release the code if I could, unfortunately I do not own the copyright. I will be happy to give advice in this thread though.

Alright. Well maybe im jump on board into this thread and not just follow but help build this script as well.

Would i have to do this in is c# or can i do it in dotnet in max?
That is the first question.

What would be the first steps you would recommend me starting with first?

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

Posts: 0

First of all you must decide what your tool will be doing, what it will control, etc. Will the points need to move or only be selected?

Regarding c# vs maxscript… the only major thing you can do in c# is create new classes. And when I say c# that includes on-the-fly c# code compiled in maxscript (there are many examples on this forum, most notably by denisT).

What I like about c# is that it is much more comfortable to develop these kind of controls (and usually more performant). Nevertheless, you may be able to achieve your goals with pure maxscript.

Sadly I do not know c# well enough to create this type of tool in there.

Aside from that it may not be as complex as i think.
Breaking it down it really is just figuring out to create one control and that’s really it.

Current progress:

Code is a right mess, but basic drag-rectangle functionality is there. I don’t know if using a label is the best/fastest way to go though!


/*
CREDIT WHERE IT'S DUE:
Most of this was taken from/started out as Paul Neale's excellent tutorial on Dotnet forms in MaxScript
 http://paulneale.com/tutorials/dotNet/form/index.htm 



*/


fn formatProps dn=
(
	if classOf dn==dotNetObject or classOf dn==dotNetClass then
	(
		clearListener()
		format "Properties:
"
		showProperties dn
		format "
Methods:
"
		showMethods dn
		format "
Events:
"
		showEvents dn
	)else
	(
		format "% is not a dotNetObject or dotNetClass
" dn
	)
)

--tColor = ((dotNetClass "system.drawing.color").transparent
selectionColor = ((dotNetClass "system.drawing.color").fromArgb 127 102 153 255)
charStudioBG = (dotNetclass "System.Drawing.Image").fromfile @"X:\3dsmax\2013\MaxScript\images\characterStudioBackground.png"
	


--Creates a dotNet form.
form=dotNetObject "system.windows.forms.form"

--You can also use the sort cut for this.
form=dotNetObject "form"

--set the backgroundImage to be equal to the charStudioBG var
form.backgroundImage = charStudioBG

--Add controls to the form. In this case a red label.
--Create the label
dnLabel=dotNetObject "label" --"system.windows.forms.label"

--Set the backColor property to red
dnLabel.backColor=selectionColor

--Set the location and size of the label using a rectangle. 
dnLabel.bounds=dotNetObject "system.drawing.rectangle" 10 10 100 100

--Add the label to the form. 
form.controls.add dnLabel

--Set the title text. 
form.text="Character Studio with Dragging Functionality"

--Set an over all opacity
--Value range is 0-1
form.Opacity=1

borderStyle=(dotNetClass "System.Windows.Forms.FormBorderStyle").Sizable
form.formBorderStyle=borderStyle

form.location=dotNetObject "system.drawing.point" 5 20
form.size=dotNetObject "System.Drawing.Size" 512 512

/*
--Set the background color
form.backColor=(dotNetClass "system.drawing.color").black

--Set the transparent color
form.TransparencyKey=(dotNetClass "system.drawing.color").black
*/

mouseIsDown=false

--hold the starting position of the drag
dragStartX = -1
dragStartY = -1

--Add event handlers for the form.
fn formMouseDown sender arg=
(
	--Check to see which mouse button is being pressed. 
	if arg.button==arg.button.left do (
		--LEFT button is down
		--formatProps arg;
		--dnLabel.backColor = selectionColor
		mouseIsDown=true
		dragStartX = arg.x
		dragStartY = arg.y
		
	)
	
	if arg.button==arg.button.right do (
		--RIGHT button is down		
		print #right
	)
)
fn formMouseUp sender arg=
(
	mouseIsDown=false
	--dnLabel.backColor = tColor
)
fn formMouseMove sender arg=
(
	if mouseIsDown do
	(
		--format "Mouse Position:[%,%]
" arg.x arg.y
		dnLabel.location=(dotNetObject "system.drawing.point" dragStartX dragStartY)
		dnLabel.size = (dotNetObject "System.Drawing.Size" (arg.x-dragStartX) (arg.y-dragStartY))
	)
)

--Add the event handlers. 
dotNet.addEventHandler form "mouseDown" formMouseDown
dotNet.addEventHandler form "mouseUp" formMouseUp
dotNet.addEventHandler form "mouseMove" formMouseMove

--Set the life time of the control to #dotNet so that it is not garbage collected with the rest of Max script. 
--For Max 2009 and previous you will need the avg extension to set this. 
dotNet.setLifeTimeControl form #dotNet

--set the form to be on top (normally rude, but ideal behaviour in this specific case)
form.topMost = true



--Show the form
form.show()

--Close the form
--form.close()

--Format all the properties to the listener. 
formatProps form

Worth making it possible to drag in all directions. Right now you can only drag top left to bottom right.

2 Replies
(@mixx)
Joined: 11 months ago

Posts: 0

I know – I’m working on that right now

 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

A nice trick in this aspect is that you don’t need to handle conditional logic, you simply pass all rectangles through this simple normalization function, where pt is the current mouse location and dragPoint (defined elsewhere in your code, or can be added as a function parameter if you prefere) is the point where dragging started:

fn NormalizeRectangle pt =
(
    local X = amin dragPoint.X loc.X
	local Y = amin dragPoint.Y pt.Y
	local w = abs (pt.X - dragPoint.X)
	local h = abs (pt.Y - dragPoint.Y)
	dotnetObject "system.drawing.rectangle" x y w h
)

Thanks lo, I modified your function a little (it’s more to my liking to pass arguments), but other than that, beautiful!


/*
CREDIT WHERE IT'S DUE:
Most of this was taken from/started out as Paul Neale's excellent tutorial on Dotnet forms in MaxScript
 http://paulneale.com/tutorials/dotNet/form/index.htm 
Also many thanks to lo on cgsociety


*/
fn NormalizeRectangle hX hY sX sY =
(
    local X = amin sX hX
	local Y = amin sY hY
	local w = abs (hX - sX)
	local h = abs (hY - sY)
	dotnetObject "system.drawing.rectangle" x y w h
)


fn formatProps dn=
(
	if classOf dn==dotNetObject or classOf dn==dotNetClass then
	(
		clearListener()
		format "Properties:
"
		showProperties dn
		format "
Methods:
"
		showMethods dn
		format "
Events:
"
		showEvents dn
	)else
	(
		format "% is not a dotNetObject or dotNetClass
" dn
	)
)

tColor = ((dotNetClass "system.drawing.color").transparent)
selectionColor = ((dotNetClass "system.drawing.color").fromArgb 127 102 153 255)
charStudioBG = (dotNetclass "System.Drawing.Image").fromfile @"X:\3dsmax\2013\MaxScript\images\characterStudioBackground.png"


--Creates a dotNet form.
form=dotNetObject "system.windows.forms.form"

--You can also use the sort cut for this.
form=dotNetObject "form"

--set the backgroundImage to be equal to the charStudioBG var
form.backgroundImage = charStudioBG

--Add controls to the form. In this case a red label.
--Create the label
dnLabel=dotNetObject "label" --"system.windows.forms.label"


--Set the backColor property to red
dnLabel.backColor=selectionColor

--Set the location and size of the label using a rectangle. 
dnLabel.bounds=dotNetObject "system.drawing.rectangle" 10 10 100 100

--Add the label to the form. 
form.controls.add dnLabel

--Set the title text. 
form.text="Character Studio with Dragging Functionality"

--Set an over all opacity
--Value range is 0-1
form.Opacity=1

borderStyle=(dotNetClass "System.Windows.Forms.FormBorderStyle").Sizable
form.formBorderStyle=borderStyle

form.location=dotNetObject "system.drawing.point" 5 20
form.size=dotNetObject "System.Drawing.Size" 512 512

/*
--Set the background color
form.backColor=(dotNetClass "system.drawing.color").black

--Set the transparent color
form.TransparencyKey=(dotNetClass "system.drawing.color").black
*/

mouseIsDown=false

--hold the starting position of the drag
dragStartX = -1
dragStartY = -1

--Add event handlers for the form.
fn formMouseDown sender arg=
(
	--Check to see which mouse button is being pressed. 
	if arg.button==arg.button.left do (
		--LEFT button is down
		--formatProps arg;
		dnLabel.backColor = selectionColor
		mouseIsDown=true
		dragStartX = arg.x
		dragStartY = arg.y
		
		
	)
	
	if arg.button==arg.button.right do (
		--RIGHT button is down		
		print #right
	)
)
fn formMouseUp sender arg=
(
	mouseIsDown=false
	dnLabel.size = (dotNetObject "System.Drawing.Size" 0 0)
	dnLabel.backColor = tColor
)
fn formMouseMove sender arg=
(
	if mouseIsDown do
	(	
		
		dnLabel.bounds=NormalizeRectangle arg.x arg.y dragStartX dragStartY
		
	)
)

--Add the event handlers. 
dotNet.addEventHandler form "mouseDown" formMouseDown
dotNet.addEventHandler form "mouseUp" formMouseUp
dotNet.addEventHandler form "mouseMove" formMouseMove

--Set the life time of the control to #dotNet so that it is not garbage collected with the rest of Max script. 
--For Max 2009 and previous you will need the avg extension to set this. 
dotNet.setLifeTimeControl form #dotNet

--set the form to be on top (normally rude, but ideal behaviour in this specific case)
form.topMost = true



--Show the form
form.show()

--Close the form
--form.close()

--Format all the properties to the listener. 
formatProps form

 lo1

Alternatively, a rectangle may also be constructed from left, top, right, bottom:

fn normalizeRect p1x p1y p2x p2y =
(
 local l = amin p1x p2x
 local t = amin p1y p2y
 local r = amax p1x p2x
 local b = amax p1y p2y
 (dotnetClass "System.Drawing.Rectangle").fromLTRB l t r b
)

This has no real value over the previous function, just wanted to mention this constructor as an aside. Notice this is not a real constructor, it’s a static method of the rectangle class which returns a new instance. This is why we call it using DotNetClass and not DotNetObject.

Page 2 / 5