Moving a Dialog with a button?

Become a member of the CGSociety

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

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
  05 May 2013
Moving a Dialog with a button?

Trying to find the best way to go about moving a dialog via, left click + drag (holding left mouse button) using a button within the rollout.

So far I got this. It works kind of, but it seems to crash max, and can't uncheck the button.


try (destroydialog exdialog)
catch ()
global exdialog
rollout exdialog ""
(
	checkbutton moveexdialog "Click + Drag Me" pos:[5,5] width:95 height:20
	button closedialog "Close Me" pos:[105,5] width:55 height:20
	on moveexdialog changed state do
	(
		while state == true do
		(
			origmousepos = (mouse.screenpos - (moveexdialog.pos + [42,7]))
			SetDialogPos exdialog origmousepos
		)
	)
	on closedialog pressed do
	(
		try (destroydialog exdialog)
		catch ()
	)
)
createdialog exdialog width:170 height:30 style:#(#style_sysmenu, #style_minimizebox, #style_normalbox)


Looking for a cleaner way, and something that is hold left mouse button + drag, then on release it un-checks the button.

Please anyone with a solution via maxscript reply with the maxscript.

Last edited by CG3DOpifex : 05 May 2013 at 12:21 AM.
 
  05 May 2013
Found a solution, not sure if its the best, or cleanest but here it is.


try (destroydialog exdialog)
catch ()
global exdialog
rollout exdialog ""
(
	checkbutton moveexdialog "Click + Drag Me" pos:[5,5] width:95 height:20
	button closedialog "Close Me" pos:[105,5] width:55 height:20
	timer themoverollouttimer interval:10 active:false
	on themoverollouttimer tick do
	(
		origmousepos = (mouse.screenpos - (moveexdialog.pos + [42,7]))
		if (GetDialogPos exdialog) != origmousepos do
		(
			SetDialogPos exdialog origmousepos
		)
	)
	on moveexdialog changed state do
	(
		if state == true do
		(
			themoverollouttimer.active = true
		)
		if state == false do
		(
			themoverollouttimer.active = false
		)
	)
	on closedialog pressed do
	(
		try (destroydialog exdialog)
		catch ()
	)
)
createdialog exdialog width:170 height:30 style:#(#style_sysmenu, #style_minimizebox, #style_normalbox)


But I still need to find a way for it to work on left button held on the button, check the checkbutton, then when released needs to uncheck the checkbutton.

Anyone have any ideas?
 
  05 May 2013
Here's a better idea, use a dotnet button:

try (destroydialog exdialog)catch ()
global exdialog
rollout exdialog ""
(
	local mouseOffset = [0,0]
	local dragging = off
	
	dotNetControl moveexdialog "Button" pos:[5,5] width:95 height:20
	button closedialog "Close Me" pos:[105,5] width:55 height:20

	on exDialog open do
	(
		moveexdialog.text = "Move"
	)
	
	on moveexdialog mouseMove do
	(
		if (dragging) do
		(
			local newPos = mouse.screenpos - mouseOffset
			if (GetDialogPos exdialog) != newPos do
			(
				SetDialogPos exdialog newPos
			)
		)
	)
	
	on moveexdialog mousedown do
	(
		mouseOffset = mouse.screenPos - getDialogPos exDialog
		dragging = on
	)
	
	on moveexdialog mouseUp do
	(
		dragging = off
	)
	
	on closedialog pressed do
	(
		try (destroydialog exdialog)
		catch ()
	)
)
createdialog exdialog width:170 height:30 style:#(#style_sysmenu, #style_minimizebox, #style_normalbox)
 
  05 May 2013
Originally Posted by lo: Here's a better idea, use a dotnet button:
...

Ah thanks, exactly what I wanted, but one thing, is it possible to make it into a image button instead of text?
 
  05 May 2013
Yes, use the .image property of the button, assign it a system.drawing.bitmap.
 
  05 May 2013
Isn't is useless to check if (GetDialogPos exdialog) != newPos in the mouseMove function?
 
  05 May 2013
Got it! mouseMove is fired twice each time, don't understand why!
Here the modified code for those who want to check.
By the way, love your snippet lo. So clean!
try (destroydialog exdialog)catch ()
global exdialog
rollout exdialog ""
(
	local mouseOffset = [0,0]
	local dragging = off
	
	dotNetControl moveexdialog "Button" pos:[5,5] width:95 height:20
	button closedialog "Close Me" pos:[105,5] width:55 height:20

	on exDialog open do
	(
		moveexdialog.text = "Move"
	)
	
	on moveexdialog mouseMove do
	(
		if (dragging) do
		(
			local diagPos = GetDialogPos exdialog
			local newPos = mouse.screenpos - mouseOffset
			format "% %\n" diagPos newPos 
			if diagPos != newPos then
			(
				SetDialogPos exdialog newPos
				print "moved"
			)
			else
			(
				print "no move "
			)
		)
	)
	
	on moveexdialog mousedown do
	(
		mouseOffset = mouse.screenPos - getDialogPos exDialog
		dragging = on
	)
	
	on moveexdialog mouseUp do
	(
		dragging = off
	)
	
	on closedialog pressed do
	(
		try (destroydialog exdialog)
		catch ()
	)
)
createdialog exdialog width:170 height:30 style:#(#style_sysmenu, #style_minimizebox, #style_normalbox)
 
  05 May 2013
Originally Posted by lanimal: Got it! mouseMove is fired twice each time, don't understand why!


Calling SetDialogPos is what fires the second mouseMove event. It can be proved using this code:

on moveexdialog mouseMove do
	(
		if (dragging) do
		(
			local diagPos = GetDialogPos exdialog
			local newPos = mouse.screenpos - mouseOffset
			format "% %\n" diagPos newPos 
			if diagPos != newPos then
			(
				dragging = off
				SetDialogPos exdialog newPos
				(dotnetClass "Application").doEvents() --process all queued messages
				dragging = on
				print "moved"
			)
			else
			(
				print "no move "
			)
		)
	)
 
  05 May 2013
OK thanks lo! I did dragable rollout before and didn't notice the double event.
At least I will know next time
 
  05 May 2013
sometimes i don't want to use any dotnet controls in my mxs dialog... so for many years this works for me:

 try(destroydialog dialog) catch()
 rollout dialog "" width:160 height:20
 (
 	groupbox border width:160 height:26 pos:[0,-6]
 	timer mover active:off interval:50
 	
 	local start
 	on mover tick do if mouse.pos != start do
 	(
 		setdialogpos dialog ((getdialogpos dialog) + mouse.pos - start)
 		start = mouse.pos
 	)
 	on dialog lbuttondown pos do
 	(
 		start = mouse.pos
 		mover.active = on
 	)
 	on dialog lbuttonup pos do mover.active = off
 	on dialog rbuttonup pos do destroydialog dialog
 )
 createDialog dialog style:#()
 

if i want to make some "visual" titlebar i use an imgTag and its events instead of the rollout's.
 
  05 May 2013
Denis, did you used the timer for optimization? (kinda overkill?)
I usually did exactly the same without the timer and a local boolean as replace.
 
  05 May 2013
Originally Posted by lanimal: Denis, did you used the timer for optimization? (kinda overkill?)
I usually did exactly the same without the timer and a local boolean as replace.

how do you catch mouse moveevent without a timer?
yes.. you can do it with rollout mousemove, but as i said i usually use imgTag

also... i did some experiments and found that with timer the motion is smoother and never being lost

Last edited by denisT : 05 May 2013 at 04:28 PM.
 
  05 May 2013
Ok denis, I didn't see the imgTag in your snippet. That's why I didn't pay attention to it.
Now I see how your rollouts must look like.
Here's my version, with "lo's double event avoidance trick"!

try(destroydialog UICAcomplete) catch()

rollout UICAcomplete "complete" width:200 height:200
(
	local screenSize = [0,0]
	local DragState = false
	local WinPos = [0,0]
	------------------------------------------------------------------------
	-- avoid out of screen rollout
	fn updatePos pos =
	(
		if (pos.x < 0) do (pos.x = 0); if (pos.y < 0) do (pos.y = 0)
		if (pos.x+UICAcomplete.width > screenSize.x) do (pos.x = screenSize.x-UICAcomplete.width)
		if (pos.y+UICAcomplete.height > screenSize.y) do (pos.y = screenSize.y-UICAcomplete.height)
		setDialogPos UICAcomplete pos
	)
	------------------------------------------------------------------------
	on UICAcomplete open do 
	(
		screenSize = [systemTools.GetScreenWidth(),systemTools.GetScreen  Height()]
		updatePos mouse.screenpos
	)
	------------------------------------------------------------------------
	-- drag
	on UICAcomplete lbuttonup mousepos do DragState = false
	on UICAcomplete lbuttondown mousepos do 
	(
		DragState = true
		WinPos = mousepos
	)
	on UICAcomplete mousemove mousepos do
	(
		if DragState == true do
		(
			localPos = mouse.screenpos-WinPos
			diagPos = GetDialogPos UICAcomplete
			if diagPos != localPos do
			(
				updatePos localPos
			)
		)
	)
	------------------------------------------------------------------------
	on UICAcomplete rbuttondown arg do (destroydialog UICAcomplete)
)

createdialog UICAcomplete style:#()
 
  05 May 2013
Thread automatically closed

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
__________________
CGTalk Policy/Legalities
Note that as CGTalk Members, you agree to the terms and conditions of using this website.
 
Thread Closed 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 04:56 PM.


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