Using TAB to switch between .NET controls in rollout


#1

In the code below, the TAB does not want to “select” next buttons.
If I delete

setFocus btn_Browse

the TAB works, but only with default max controls - the editText and the checkboxes.
How to make the scrcipt to worls as follows:

  1. run the script and the focus is on the btn_Browse button
  2. press ENTER will open the “Select folder” window
  3. press TAB will set the focus on the Save button
  4. press TAB will set the focus to the Load button
  5. press TAB will set the focus to X, then Y, then Z, then Apply
(
	global rol_test
	try(destroyDialog rol_test)catch()
	rollout rol_test "FFD Control points transfer"
	(
		local pointsDataFile = undefined
		local savePath = undefined
		local dNETopenFileDialog = dotNetObject "System.Windows.Forms.OpenFileDialog"

		dotNetControl btn_Browse "system.windows.forms.button" pos:[5,20] height:20 width:109
		edittext et_name "Name:" text:"example_01" width:105 pos:[5,40] labelontop:true
		dotNetControl btn_save "system.windows.forms.button" pos:[5,80] height:20 width:60

		dotNetControl btn_loadData "system.windows.forms.button" pos:[5,125] height:20 width:60
		
		checkbox chkbox_applyX "X" pos:[5,148] 
		checkbox chkbox_applyY "Y" pos:[44,148] 
		checkbox chkbox_applyZ "Z" pos:[82,148]
		
		dotNetControl btn_apply "system.windows.forms.button" pos:[5,175] height:20 width:109
		
		function DotNetButtonsStyle _btn _name =
		(
			_btn.flatStyle=(dotNetClass "System.Windows.Forms.FlatStyle").System 
			--Or
-- 			_btn.flatStyle = _btn.flatStyle.flat
			_btn.text = _name
-- 			_btn.TextAlign = (dotNetClass "System.Drawing.ContentAlignment").middleleft
			_btn.backColor = _btn.backColor.black
			_btn.foreColor = _btn.backColor.gray
		)
		
		function Btn_BrowsePressed =
		(
			savePath = getSavePath caption:"Select folder" initialDir:"$previews"
		)
		
		function Btn_saveFFDCPPressed =
		(
			infoFile = undefined	
-- 			infoFile = createFile (savePath + "\\" + et_name.text + ".dat")	
			local topMod = modpanel.getCurrentObject()
			if ( substring (topMod as string) 1 3 ) == "FFD" then
			(
				if (substring (topMod as string) 1 3) == "FFD" then
				(
					theMaster = topMod[#master]
					theCount = theMaster.numsubs
					animateAll topMod
					for i = 1 to theCount where theMaster[i].value != undefiend do
					(
						format "%
" (theMaster[i].value) to:infoFile
					)	
					close infoFile
					free infoFile
					lbl_info.text = "Saved"
				)
				else
					messagebox "The top modifier is not FFD" title:"Invalid Selection"
			)
			else
				messagebox "The selected object does not have applyed FFD modifier" title:"Invalid Selection"
		)
		
		function Btn_loadDataPressed =
		(
			result = dNETopenFileDialog.showDialog()
			result.ToString() 
			if (result.Equals result.OK) do 
			(
				pointsDataFile = (dNETopenFileDialog.fileNames)[1]
				btn_loadData.tooltip = pointsDataFile
				lbl_info02.text = "Loaded"
			)
			if (result.Equals result.Cancel) do
				pointsDataFile = undefined
		)
		
		function Btn_applyPressed =
		(
			if doesFileExist pointsDataFile do
				infoFile = openFile pointsDataFile
			local topMod = modpanel.getCurrentObject()
			if ( substring (topMod as string) 1 3 ) == "FFD" then
			(
				theMaster = topMod[#master]
				theCount = theMaster.numsubs
				animateAll topMod
				
				cnt = 0
				while not eof infoFile do
				(
					cnt += 1
					local ffdPpos = readLine infoFile
					local ffdPos = (execute ffdPpos)
					if chkbox_applyX.state == true and chkbox_applyY.state == true and chkbox_applyZ.state == true then
						(theMaster[cnt].value) = ffdPos
					else
					(
						if chkbox_applyX.state == true do
						(
							local curPos = (theMaster[cnt].value)
							curPos.x = ffdPos.x							
							(theMaster[cnt].value) = curPos
						)
						if chkbox_applyY.state == true do
						(
							local curPos = (theMaster[cnt].value)
							curPos.y = ffdPos.y							
							(theMaster[cnt].value) = curPos
						)
						if chkbox_applyZ.state == true do
						(
							local curPos = (theMaster[cnt].value)
							curPos.z = ffdPos.z							
							(theMaster[cnt].value) = curPos
						)
					)
				)
				close infoFile
				free infoFile
			)
			else
				messagebox "Invalid selection" title:"Invalid Selection"
		)
		
		on btn_Browse mouseUp senderArg arg do
		(
			if arg.button==arg.button.left do Btn_BrowsePressed()
		)
		on btn_Browse KeyUp evnt do
		(
			if evnt.KeyCode == (dotNetClass "System.Windows.Forms.Keys").Enter do print "Browse is pressed"
		)
		
		on btn_save mouseUp senderArg arg do
		(
			if arg.button==arg.button.left do Btn_saveFFDCPPressed()
		)
		on btn_save KeyUp evnt do
		(
			if evnt.KeyCode == (dotNetClass "System.Windows.Forms.Keys").Enter do print "Save is pressed"
		)
		
		on btn_loadData mouseUp senderArg arg do
		(
			if arg.button==arg.button.left do Btn_loadDataPressed()
		)
		on btn_loadData KeyUp evnt do
		(
			if evnt.KeyCode == (dotNetClass "System.Windows.Forms.Keys").Enter do print "Load is pressed"
		)
		
		on btn_apply mouseUp senderArg arg do
		(
			if arg.button==arg.button.left do Btn_applyPressed()
		)
		on btn_apply KeyUp evnt do
		(
			if evnt.KeyCode == (dotNetClass "System.Windows.Forms.Keys").Enter do print "Apply is pressed"
		)
		
		on rol_test open do
		(
			dNETopenFileDialog.title = "Select file"
			dNETopenFileDialog.Multiselect = false
			dNETopenFileDialog.Filter = "DAT (*.dat)|*.dat"
			dNETopenFileDialog.FilterIndex = 1
			dNETopenFileDialog.RestoreDirectory = true
			--	dotNet buttons
			DotNetButtonsStyle btn_Browse "Browse(save path)"
			DotNetButtonsStyle btn_save "Save FFD"
			DotNetButtonsStyle btn_loadData "Load FFD"
			DotNetButtonsStyle btn_apply "Apply"
			--
			setFocus btn_Browse
		)
	)
	createdialog rol_test 	width:119
)

#2

Maybe this example can help.
For more info look selectNextControl method


(
global bgaFORM
try(bgaFORM.close()) catch()
if bgaFORM != undefined do try(bgaFORM.close()) catch()
local bgaTB, bgaBtn, bgaCB1, bgaCB2, bgaCB3	
fn defColor r g b = ((dotNetClass "System.Drawing.Color").FromArgb r g b)		
fn defPoint x y = (dotNetObject "System.Drawing.Point" x y)	
fn defSize x y = (dotNetObject "System.Drawing.Size" x y)
Clr = defColor 0 0 0 ; ClrBG = defColor 60 60 60 ; ClrFG = defColor 200 200 200
fn DisableAccel = (enableAccelerators = false) ; fn EnableAccel = (enableAccelerators = true)
fn defBtn dnBtn w h locX locY txt =
(
	dnBtn.Size = defSize w h
	dnBtn.Location = defPoint locX locY
	dnBtn.Text = txt 
	dnBtn.BackColor = ClrBG
	dnBtn.ForeColor = ClrFG
	dnBtn.FlatStyle = dnBtn.FlatStyle.System
)
fn defTextBox dnTBox =
(
	dnTBox.Multiline = false
	dnTBox.Size = defSize 150 20
	dnTBox.Location = defPoint 5 40
	dnTBox.BackColor = ClrBG
	dnTBox.ForeColor = ClrFG 
	--dnTBox.BorderStyle = dnTBox.BorderStyle.None
	dnTBox.AcceptsTab = dnTBox.AcceptsReturn = dnTBox.AutoSize = true
)
fn defCheckBox dnCB w h locX locY txt =
(
	dnCB.Width = w ; dnCB.Height = h
	dnCB.BackColor = ClrBG
	dnCB.ForeColor = ClrFG
	dnCB.text = txt
	dnCB.FlatStyle = dnCB.FlatStyle.System
	dnCB.Location = defPoint locX locY 
)
fn defForm dnForm w h x y txt =
(
	dnForm.ShowInTaskbar = false ; dnForm.Text = txt ; dnForm.ClientSize = defSize w h
	dnForm.StartPosition = dnForm.StartPosition.Manual ; dnForm.DesktopLocation = defPoint x y
	dnForm.FormBorderStyle = dnForm.FormBorderStyle.FixedToolWindow
	dnForm.BackColor = ClrBG
)
fn maxHW = (dotNetObject "maxCustomControls.win32HandleWrapper" (dotNetObject "System.IntPtr" (windows.getMaxHWND())))
---------------------------------------------------------
fn bgaBtn_KU s e =
(
	if (e.keyCode.ToString()) == "Tab"	do (bgaFORM.selectnextcontrol bgaFORM.ActiveControl true true false true)
	if (e.keyCode.ToString()) == "Return"	do 
	(
		local newDir = getSavePath caption:"Browse Directory" initialDir:(getDir #maxroot)
		if newDir != undefined do bgaTB.text = newDir
		-- your code	
	)
)
fn bgaTB_KU s e = 
(
	if (e.keyCode.ToString()) == "Tab"	do (bgaFORM.selectnextcontrol bgaFORM.ActiveControl true true false true)
	-- your code
)
fn bgaCB_KU s e = 
(
	if (e.keyCode.ToString()) == "Tab"	do (bgaFORM.selectnextcontrol bgaFORM.ActiveControl true true false true)
	if (e.keyCode.ToString()) == "Return"	do s.checked = not s.checked
	-- your code
)

bgaFORM = dotnetobject "Form" ; defForm bgaFORM 160 300 10 110 "Main Form"
bgaBtn = dotnetobject "Button" ; defBtn bgaBtn 150 30 5 5 "Browse Folder"
bgaTB = dotnetobject "TextBox" ; defTextBox bgaTB 
bgaCB1 = dotnetobject "CheckBox" ; defCheckBox bgaCB1 30 16 5 65 "X"
bgaCB2 = dotnetobject "CheckBox" ; defCheckBox bgaCB2 30 16 40 65 "Y"
bgaCB3 = dotnetobject "CheckBox" ; defCheckBox bgaCB3 30 16 75 65 "Z"

dotnet.addEventHandler bgaCB1 "KeyUp" bgaCB_KU
dotnet.addEventHandler bgaCB2 "KeyUp" bgaCB_KU
dotnet.addEventHandler bgaCB3 "KeyUp" bgaCB_KU
dotnet.addEventHandler bgaTB "KeyUp" bgaTB_KU
dotnet.addEventHandler bgaBtn "KeyUp" bgaBtn_KU
dotnet.addEventHandler bgaTB "GotFocus" DisableAccel
dotnet.addEventHandler bgaTB "LostFocus" EnableAccel

bgaFORM.Controls.AddRange #(bgaBtn, bgaTB, bgaCB1, bgaCB2, bgaCB3)
bgaFORM.Show (maxHW())
bgaBtn.Focus()		
)


#3

Branko, thank you!
I need this for max9, but, unfortunately, max9 do not want to work with your code. The problem is:

-- Runtime error: Cannot resolve type: maxCustomControls.win32HandleWrapper

#4

Try now. I change only .net Form with mxs Form.
I don’t have max9 for testing. Sorry:sad:


(
global bgaFORM
try(bgaFORM.close()) catch()
if bgaFORM != undefined do try(bgaFORM.close()) catch()
local bgaTB, bgaBtn, bgaCB1, bgaCB2, bgaCB3	
fn defColor r g b = ((dotNetClass "System.Drawing.Color").FromArgb r g b)		
fn defPoint x y = (dotNetObject "System.Drawing.Point" x y)	
fn defSize x y = (dotNetObject "System.Drawing.Size" x y)
Clr = defColor 0 0 0 ; ClrBG = defColor 60 60 60 ; ClrFG = defColor 200 200 200
fn DisableAccel = (enableAccelerators = false) ; fn EnableAccel = (enableAccelerators = true)
fn defBtn dnBtn w h locX locY txt =
(
	dnBtn.Size = defSize w h
	dnBtn.Location = defPoint locX locY
	dnBtn.Text = txt 
	dnBtn.BackColor = ClrBG
	dnBtn.ForeColor = ClrFG
	dnBtn.FlatStyle = dnBtn.FlatStyle.System
)
fn defTextBox dnTBox =
(
	dnTBox.Multiline = false
	dnTBox.Size = defSize 150 20
	dnTBox.Location = defPoint 5 40
	dnTBox.BackColor = ClrBG
	dnTBox.ForeColor = ClrFG 
	--dnTBox.BorderStyle = dnTBox.BorderStyle.None
	dnTBox.AcceptsTab = dnTBox.AcceptsReturn = dnTBox.AutoSize = true
)
fn defCheckBox dnCB w h locX locY txt =
(
	dnCB.Width = w ; dnCB.Height = h
	dnCB.BackColor = ClrBG
	dnCB.ForeColor = ClrFG
	dnCB.text = txt
	dnCB.FlatStyle = dnCB.FlatStyle.System
	dnCB.Location = defPoint locX locY 
)
fn defForm dnForm w h x y txt =
(
	dnForm.ShowInTaskbar = false ; dnForm.Text = txt ; dnForm.ClientSize = defSize w h
	dnForm.StartPosition = dnForm.StartPosition.Manual ; dnForm.DesktopLocation = defPoint x y
	dnForm.FormBorderStyle = dnForm.FormBorderStyle.FixedToolWindow
	dnForm.BackColor = ClrBG
)
---------------------------------------------------------
fn bgaBtn_KU s e =
(
	if (e.keyCode.ToString()) == "Tab"	do (bgaFORM.selectnextcontrol bgaFORM.ActiveControl true true false true)
	if (e.keyCode.ToString()) == "Return"	do 
	(
		local newDir = getSavePath caption:"Browse Directory" initialDir:(getDir #maxroot)
		if newDir != undefined do bgaTB.text = newDir
		-- your code	
	)
)
fn bgaTB_KU s e = 
(
	if (e.keyCode.ToString()) == "Tab"	do (bgaFORM.selectnextcontrol bgaFORM.ActiveControl true true false true)
	-- your code
)
fn bgaCB_KU s e = 
(
	if (e.keyCode.ToString()) == "Tab"	do (bgaFORM.selectnextcontrol bgaFORM.ActiveControl true true false true)
	if (e.keyCode.ToString()) == "Return"	do s.checked = not s.checked
	-- your code
)

bgaFORM = dotnetobject "MaxCustomControls.MaxForm" ; defForm bgaFORM 160 300 10 110 "Main Form"
bgaBtn = dotnetobject "Button" ; defBtn bgaBtn 150 30 5 5 "Browse Folder"
bgaTB = dotnetobject "TextBox" ; defTextBox bgaTB 
bgaCB1 = dotnetobject "CheckBox" ; defCheckBox bgaCB1 30 16 5 65 "X"
bgaCB2 = dotnetobject "CheckBox" ; defCheckBox bgaCB2 30 16 40 65 "Y"
bgaCB3 = dotnetobject "CheckBox" ; defCheckBox bgaCB3 30 16 75 65 "Z"

dotnet.addEventHandler bgaCB1 "KeyUp" bgaCB_KU
dotnet.addEventHandler bgaCB2 "KeyUp" bgaCB_KU
dotnet.addEventHandler bgaCB3 "KeyUp" bgaCB_KU
dotnet.addEventHandler bgaTB "KeyUp" bgaTB_KU
dotnet.addEventHandler bgaBtn "KeyUp" bgaBtn_KU
dotnet.addEventHandler bgaTB "GotFocus" DisableAccel
dotnet.addEventHandler bgaTB "LostFocus" EnableAccel

bgaFORM.Controls.AddRange #(bgaBtn, bgaTB, bgaCB1, bgaCB2, bgaCB3)
bgaFORM.Show()
bgaBtn.Focus()		
)


#5

It seams that max9 do not like dotNet too much. :slight_smile:

Almost the same error:

-- Runtime error: Cannot resolve type: MaxCustomControls.MaxForm

#6

The last option - can I use the ActiveX controls - to use the TAB to selet the next control and to use the ENTER to “press” this control?


#7

I think that max9 is too old to be supported. the oldest version that I try to support now is max 2009.


#8

i want to say that the thing what you want to do is not trivial. because you use mix of mxs and dotnet controls in your UI where the top level control is max Rollout.
the changing focus from one ui control to another is not a built-in feature of every window. max realized this behavior for rollout (mxs) controls only.


#9

I agree with you, but the ActiveX will slove my problem or it is not worth wasting my time?


#10

… for dotnet controls you have to implement this behavior yourself.


#11

do you want to write two different codes - one for max9 and another for …+ ?
recent versions of max don’t like ActiveX controls


#12

I think that I can handle with max9+ with dotNet. The Branko sniped will help me. But I never used ActiveX. And the worst is that I can’t test ActiveX, because I have win7 64bit. I have to send the file to my friend to test it… Long story.


#13

that’s why i suggested to forget about max9. If you have a special max9 user make him/her an exclusive gift version of you tool. :slight_smile:


#14

He use windows2000 for work and do not want to change it. I can’t force him to change it and max2009 do not work in win2000. :slight_smile: I still wonder why he wants to use the keyboard instead of mouse :slight_smile: The scripts works in max9, but not with the ENTER key.


#15

i think you have quietly come to him from behind, gently put your hand on his shoulder, and … yell:“WAKE UP BRO! WAKE UP!!!” , and show him a calendar.


#16

:wip: :slight_smile: :slight_smile: :). This is awesome suggestion. Sorry Kostadin, i expected some other answer from Denis but this…, I can’t not stop laughing.


#17

Will not help. His arguments are: my system is tuned and works perfect, so why to change it. And the conversation ends here. :slight_smile:


#18

His PC is probably still in warranty:). Ask him
I guess this is not offended you. Sorry again.


#19

“But I tried goddammit. At least I did that.” (One Flew Over the Cuckoo’s Nest)


#20

The TurboSquid specification for CheckMate contest was support for max7 and up. :slight_smile: