Notifications
Clear all

[Closed] max calculator help

Recently i wrote a script that allow you to use the calculator inside 3ds max.
Now I have a few questions about two things:
#1 How to force the drop down to be open all the time.
#2 Is it possible to activate all keys of the numpad to be able to works like with standard Windows Calculator. (enter = equals)
This is the code


(
	try(destroydialog ::CalcRoll) catch() 
	rollout CalcRoll " maxCalculator v1.0" width:(if (maxVersion())[1] == 14000 then (208) else (220)) height:20
	(
		dotNetControl mxsPnl "MaxCustomControls.MaxUserControl" pos:[0,0]
		fn defPoint x y = (dotNetObject "System.Drawing.Point" x y)
		fn defSize x y = (dotNetObject "System.Drawing.Size" x y)
		fn defColor r g b = ((dotNetClass "System.Drawing.Color").FromArgb r g b)
		fn defCalcObj dxCalc Pnl w h bgClr = 
		(
			dxCalc.Location = defPoint (Pnl.pos.x) (Pnl.pos.y)
			dxCalc.Width = w ; dxCalc.Height = h ; dxCalc.BackColor = bgClr
		)
		fn DisableAccel = (enableAccelerators = false) ; fn EnableAccel = (enableAccelerators = true)
		fn dxCalcGF = (DisableAccel()) ; fn dxCalcLF = (EnableAccel())	
		local dncGC = dotNetClass "System.GC"
		local bgCol = (defColor 240 240 220)
		on CalcRoll open do
		(
			mxsPnl.Width = CalcRoll.width ; mxsPnl.Height = CalcRoll.height
			dxCalc = dotNetObject "DevExpress.XtraEditors.CalcEdit"
			defCalcObj dxCalc mxsPnl mxsPnl.Width mxsPnl.Height bgCol
			dotnet.AddEventHandler dxCalc "GotFocus" dxCalcGF
			dotnet.AddEventHandler dxCalc "LostFocus" dxCalcLF
			mxsPnl.Controls.Add(dxCalc)
		)
		on CalcRoll close do ( dncGC.collect() ; gc light:true ; clearListener() )
	)
	createDialog CalcRoll style:#(#style_titlebar, #style_sysmenu, #style_toolwindow)	
)

Thanks in advance

10 Replies

i’m curious what you need this for? do you know about the built in calculator which can be activated by clicking in the edit box of any spinner and pressing Ctrl+n ?

4 Replies
(@theonlyaaron)
Joined: 11 months ago

Posts: 0

Hot ham and cheese! How did I not know if this?
Thank you!

(@denist)
Joined: 11 months ago

Posts: 0

i hate this calculator because:

it’s modal

closes after you enter the expression

doesn’t support math functions

needs Enter or Pressing Paste button to set the value…

i found it absolutely useless many years ago and never used it after that (and almost forgot about its existence :))

several times i had an idea to start writing my own calculator, but every time i just simply went to the listener, typed and executed expression that i need, and copied the result…

(@denist)
Joined: 11 months ago

Posts: 0

well… i did it


try(destroydialog ExpCalculator) catch() 
rollout ExpCalculator "Expression Calculator" width:200
(
	edittext calc pos:[12,3] width:0
	edittext rezult "=" labelOnTop:off readOnly:on pos:[4,24] fieldwidth:96
	
	timer mover active:off interval:50
	
	local start
	on mover tick do if mouse.pos != start do
	(
		setdialogpos ExpCalculator ((getdialogpos ExpCalculator) + mouse.pos - start)
		start = mouse.pos
	)
	on calc changed text do rezult.text = try ((execute text) as string) catch("")
	
	on ExpCalculator resized size do calc.width = ExpCalculator.width - 20
	on ExpCalculator lbuttondown pos do
	(
		start = mouse.pos
		mover.active = on
	)
	on ExpCalculator lbuttonup pos do mover.active = off
	on ExpCalculator rbuttonup pos do destroydialog ExpCalculator

	on ExpCalculator open do calc.width = ExpCalculator.width - 20
	on ExpCalculator close do 
	(
		mover.active = off
	)
)
createDialog ExpCalculator style:#(#style_resizing, #style_border) lockHeight:on

(@gazybara)
Joined: 11 months ago

Posts: 0

I agree to all the things you said. This calc is limited in to many ways.
By the way you have much better solution.
I set

dxCalc.Properties.ValidateOnEnterKey = true

but nothing is happening when i press Enter.

I know about Numerical Expression Evaluator, but you need always to select something to be able to activate the spinners and run it.

here is n advanced version


   try(destroydialog ExpCalculator) catch() 
rollout ExpCalculator "Expression Calculator by denisT" width:400
(
	fn isLinkable t = (iscontroller t.anim) and t.anim.keyable and (matchpattern ((classof t.anim) as string) pattern:"*_float")
	edittext calc pos:[12,3] width:0
	edittext result "=" labelOnTop:off readOnly:on pos:[4,26] fieldwidth:96
	spinner binder range:[-1e9,1e9,0] type:#float visible:off pos:[0,-20]
	checkbutton link "Link" width:40 pos:[116,24] tooltip:"Links the result to the specified controller
RC - Unlink"
	label track "" pos:[164,28] width:10000
	
	timer mover active:off interval:50
	
	fn makePickOptions =
	(
		local v = 0
		for b in #{9,10,15} do v = bit.set v b on
		v
	)
	local pickoptions = makePickOptions()
	
	local start
	on mover tick do if mouse.pos != start do
	(
		setdialogpos ExpCalculator ((getdialogpos ExpCalculator) + mouse.pos - start)
		start = mouse.pos
	)
	on calc changed text do 
	(
		val = try (execute text) catch()
		result.text = if val == undefined then "" else val as string
		if (try(val as float) catch()) != undefined do binder.value = val
	)
	on link changed state do 
	(
		if state do
		(
			t = trackView.pickTrackDlg isLinkable options:pickoptions
			if t != undefined and iscontroller t.anim do
			(
				binder.controller = t.anim
				track.text = exprForMAXObject t.anim
			)
		)
		link.state = off
	)
	on link rightclick do 
	(
		binder.controller = undefined
		track.text = ""
		link.state = off
	)
	
	fn onResized = 
	(
		calc.width = ExpCalculator.width - 20
	)
	on ExpCalculator resized size do onResized()
	on ExpCalculator lbuttondown pos do
	(
		start = mouse.pos
		mover.active = on
	)
	on ExpCalculator lbuttonup pos do mover.active = off
	on ExpCalculator rbuttonup pos do destroydialog ExpCalculator

	on ExpCalculator open do 
	(
		onResized()
	)
	on ExpCalculator close do 
	(
		mover.active = off
	)
)
createDialog ExpCalculator style:#(#style_resizing, #style_border) lockHeight:on	

   

edit: a minor bug fixed

and finaly the PRO version made as macroscript.
it remembers dialog’s position and size, and recently linked controller…


macroScript ExpCalculator
	category:"DTS"
	buttonText:"Exp CALC"
	toolTip:"Expression Calculator by denisT"
	autoUndoEnabled:off
	silentErrors:off
(
	rollout ExpCalculator "Expression Calculator by denisT" width:400
	(
		local opened
		local position = unsupplied, size = unsupplied
		
		
		fn isLinkable t = (iscontroller t.anim) and t.anim.keyable and (matchpattern ((classof t.anim) as string) pattern:"*_float")
		local anim = if anim != undefined do anim
		
		edittext calc pos:[12,3] width:0
		edittext result "=" labelOnTop:off readOnly:on pos:[4,26] fieldwidth:96
		spinner binder range:[-1e9,1e9,0] type:#float visible:off pos:[0,-20]
		checkbutton link "Link" width:40 pos:[116,24] tooltip:"Links the result to the specified controller
RC - Unlink"
		label track "" pos:[164,28] width:10000
		
		timer mover active:off interval:50
		
		fn makePickOptions =
		(
			local v = 0
			for b in #{9,10,15} do v = bit.set v b on
			v
		)
		local pickoptions = makePickOptions()
		
		local start
		on mover tick do if mouse.pos != start do
		(
			setdialogpos ExpCalculator ((getdialogpos ExpCalculator) + mouse.pos - start)
			start = mouse.pos
		)
		on calc changed text do 
		(
			val = try (execute text) catch()
			result.text = if val == undefined then "" else val as string
			if (try(val as float) catch()) != undefined do binder.value = val
		)
		on link changed state do 
		(
			if state do
			(
				t = trackView.pickTrackDlg isLinkable options:pickoptions
				if t != undefined and iscontroller t.anim do
				(
					binder.controller = anim = t.anim
					track.text = exprForMAXObject t.anim
				)
			)
			link.state = off
		)
		on link rightclick do 
		(
			binder.controller = anim = undefined
			track.text = ""
			link.state = off
		)
		
		on ExpCalculator lbuttondown pos do
		(
			start = mouse.pos
			mover.active = on
		)
		on ExpCalculator lbuttonup pos do mover.active = off
		on ExpCalculator rbuttonup pos do destroydialog ExpCalculator

		fn onResized = (calc.width = ExpCalculator.width - 20)
		on ExpCalculator resized s do onResized()
		on ExpCalculator open do 
		(
			opened = on
			onResized()
			if iscontroller anim do 
			(
				binder.controller = anim
				track.text = exprForMAXObject anim
			)
		)
		on ExpCalculator close do 
		(
			mover.active = off
			opened = off
			position = getdialogpos ExpCalculator 
			size = ExpCalculator.width
			updateToolbarButtons()
		)
	)
	local dialog = ExpCalculator
	
	on isChecked do dialog.opened
	on execute do 
	(
		if dialog.open then destroydialog dialog
		else createDialog dialog style:#(#style_resizing, #style_border) pos:dialog.position width:dialog.size lockHeight:on
	)
)

did i forget anything? any cool features to add?

2 Replies
(@gazybara)
Joined: 11 months ago

Posts: 0

No.It’s all good now. Fantastic!!!
Thanks Denis.
I guess I should give up of my attempts to make devX calcEdit to work properly.Right?

(@denist)
Joined: 11 months ago

Posts: 0

honestly i don’t like all DevX controls. i stopped using them about 3 years ago. Any customization of them makes them very slow. And their original (default) look is outmoded.