Notifications
Clear all

[Closed] Drag-to-select interface possible?

edit: nevermind! Silly me!

 lo1

If you want to really kill the form, call it’s .Close() method. If you want to close it now, but you will need it again later, call it’s .Hide() method.

Note that pressing the ‘x’ button of the form will call it’s .Close() method. If you want to prevent your user from disposing the form, you will need to override this behaviour using the FormClosing event.

1 Reply
(@mixx)
Joined: 11 months ago

Posts: 0

Thanks, yeah I made an error when referring to the form – it works just as it should now!

As far as the tool goes, it would be nice to essentially build a tool similar to your example and the one we have been talking about on here. One which allows a user to build a character control board within a ui which stores information as needed.

A universal and on the fly editable/buildable UI.

there are two big problems in this method:
#1 without some c# help there is no way to make the selection rectangle semitransparent against other controls
#2 the background will always be flickering badly. And it also can be solved with c# help only

1 Reply
(@mixx)
Joined: 11 months ago

Posts: 0

Yeah I noticed #2 – I haven’t gotten around to adding other controls yet (was my next step though) but it seems I need another way than a label – namely that child form without frame you mention. I’m not sure exactly what that is though – but I’ll try to figure it out.

Other than that, it was beginning to look the part:

So when it’s all said and done Denis your recommending that C# be the way to go?

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

no… there is another way – use a child form without frame as selection rectangle.

i also wrote a system like this a while back. I used 100% dotnet. I used XML serialization to export and build the UI on the fly. I also added a way to get the rig object’s positions from the screen.
Have a look at my write up, it may give you a few ideas!

http://lonerobot.net/?p=1476

Thanks, some food for thought there!

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

Posts: 0

That’s a really great post

Hmm, it’s definitely worse than it was – but I’m probably doing something way off. Any comments? Please try to disregard my horrible coding practices, I’m trying to learn as I go along so it’s a bit of a mess.


macroScript laniCharacterStudioDotNet category:"Lani Scripts" buttonText: "Lani Character Studio DotNet"

(

global laniCharStudio_DotnetVisible-- = false
if laniCharStudio_DotnetVisible == undefined then laniCharStudio_DotnetVisible = false
global laniCharacterStudioForm

/*
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)
	return (#(x,y,w,h))
)

fn ptWithinRect pX pY rX rY rW rH =
(
	
	local within = false
	if ((pX >= rX) AND (pX <= rX+rW)) then (
		
		--within rect X
		if ((pY >= rY) AND (pY <= rY+rH)) then (
		
		--within rect Y
		within = true
		
		)
		
	)
	return within
	
)

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 102 153 255)
selectionBorder = ((dotNetClass "system.Windows.Forms.BorderStyle").FixedSingle)
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"
form.isMDIContainer = true

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

--Create the label that will be the selection square
childform=dotNetObject "form" --"system.windows.forms.label"

--Set the backColor property to the one specified by "selectionColor"
childform.backColor=selectionColor

--Set the panel's borderstyle
--childform.BorderStyle=selectionBorder

--Set the location and size of the label using a rectangle. 
childform.Left = 80
childform.Top = 50
childform.Size = (dotNetObject "System.Drawing.Size" 75 95)

--Add the label to the form. 
childform.mdiParent = form

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

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

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

form.location=dotNetObject "system.drawing.point" mouse.screenpos[1] mouse.screenpos[2]
form.size=dotNetObject "System.Drawing.Size" 410 512

--FANCY STYLE, TURN OFF FOR DEVELOPMENT

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

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

borderStyle=(dotNetClass "System.Windows.Forms.FormBorderStyle").None
form.formBorderStyle=borderStyle
childform.formBorderStyle=borderStyle
childform.ShowInTaskbar = false

form.ShowInTaskbar = false




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;
		childform.size = (dotNetObject "System.Drawing.Size" 0 0)
		childform.Show()
		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
	childform.Hide()
)
fn formMouseMove sender arg=
(
	if mouseIsDown do
	(	
		
		normRect=NormalizeRectangle arg.x arg.y dragStartX dragStartY
		childform.Left = normRect[1]
		childform.Top = normRect[2]
		childform.size=(dotNetObject "System.Drawing.Size" normRect[3] normRect[4])
		
	)
)

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

dotNet.addEventHandler childform "mouseDown" formMouseDown
dotNet.addEventHandler childform "mouseUp" formMouseUp
dotNet.addEventHandler childform "mouseMove" formMouseMove

--Set the life time of the control to #dotNet so that it is not garbage collected with the rest of Max script. 
dotNet.setLifeTimeControl form #dotNet
--dotNet.setLifeTimeControl childform #dotNet

--Set the parent of the form to be Max. 
--Get the max handle pointer.
maxHandlePointer=(Windows.GetMAXHWND())

--Convert the HWND handle of Max to a dotNet system pointer
sysPointer = DotNetObject "System.IntPtr" maxHandlePointer

--Create a dotNet wrapper containing the maxHWND
maxHwnd = DotNetObject "MaxCustomControls.Win32HandleWrapper" sysPointer

--Show the Max form using the wrapper. 

	if (laniCharStudio_DotnetVisible == false) then (
		laniCharStudio_DotnetVisible = true
		form.Show(maxHwnd)
		laniCharacterStudioForm = form
		childform.Show()
	) else (
		laniCharStudio_DotnetVisible = false
		laniCharacterStudioForm.close()
		
	)

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

 lo1

I would not use a label nor a form, I would do it all in the paint method of the one single control. It’s the fastest way and the most controllable way.

13 Replies
(@denist)
Joined: 11 months ago

Posts: 0

what control do you use? the control must be on front of all other controls. i don’t know any way to make it semitransparent without using c#.

 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

I mean not to use a separate control for the selection rectangle, the selection rectangle will just be a graphics.fillRectangle call in the paint event of the canvas control (using a semi-transparent color).

edit: I notice this is just what the OP has done now.

(@mixx)
Joined: 11 months ago

Posts: 0

Yes, it appears much more stable than the panel method, and cleaner code too (even if it’s still a bit of a mess).

(@denist)
Joined: 11 months ago

Posts: 0

but you can’t draw over child controls… the paint event fires before drawing children.

 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

Why would I need any child controls?

(@denist)
Joined: 11 months ago

Posts: 0

probably i missed something. as i understood the idea is to have some dialog (form), some panel with controls (buttons, radiobuttons, checkboxes, etc.). using dragging be able to select these controls. for visualization use some rectangle.
you say you are using paint event of the panel. right? but what you draw will be on the back of all other child controls.
how do you draw any semitransparent object over controls?

 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

That’s not how I understand it. See the images in the original post. The OP just wants to be able to select rig control points a-la motionbuilder. For this purpose I don’t see any reason they need to be child controls, they can be ‘virtual’ controls, and handled within the logic of the panel.

(@denist)
Joined: 11 months ago

Posts: 0

do you want to say that the UI is an image only with marked points to click? so is it just a background image only? but this solution is very limited. how to highlight these points for example?

 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

That is not what I mean, I mean the points are not objects that inherit from ‘system.windows.forms.control’, they are essentially defined by rectangles of the canvas control and are drawn inside the paint method of the canvas control. They can be visually represented as anything; rectangles, circles, bitmaps, etc.

(@denist)
Joined: 11 months ago

Posts: 0

that’s definitely not how I handle this thing. I make my all this kind of UI with real controls. It’s much easier for me to handle events, change their visual style…

 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

Don’t get me wrong, in c# the sub-controls would be in their own class with its own events, settings, etc., just one that doesn’t inherit from system.windows.forms.control, and is painted using the graphics object of its parent. I find this gives me a greater degree of control (one example of this is the selection rectangle).

(@denist)
Joined: 11 months ago

Posts: 0

usually i simply don’t have time to design my own controls. all projects are going very fast. i try to use .net controls as much as possible, and add some specific functionality (methods, look, events, etc.) if necessary.

(@lonerobot)
Joined: 11 months ago

Posts: 0

this is how I approached the setup of my system (RigStudio). I used composite controls that built up the overall functionality if I wanted anything more bespoke. I then add custom events to the composite control depending on how I want it handled in max, or just trigger things like selection calls from inside the assembly (via mangedservices).

I haven’t found a way to make it semi-transparent either, other than the panel method I used a while back – but it had the massive flickering problems denisT mentioned.

Page 3 / 5