Notifications
Clear all

[Closed] Tape tool as floater UI (Script Wish)

Code updated. I think everything works fine now as a MacroScript.

i suggest to replace all value outputs with readonly textbox controls to be able copy values in the clipboard.

Thanks Denis.

The fields where previously Edittext controls, but changed them to labels because they perform a lot better. There is a lag in other controls while moving the tape fast. The other native control that performs well are the spinners. Tried some .Net control but they all have a little lag. Perhaps they redraw or update when the system is idle, I don’t know.

Do you know how to make the TextBox control perform better, with no redrawing lag?

it’s not really ‘lagging’… it’s not updating UI controls during some other scripts running.

the way to update ui controls is to use windows.processPostedMessages after setting ui controls values

the SDK enough solution is MAXScript_interface->CheckMAXMessages()

I think the word “lag” isn’t completly wrong, we use it often in programming to describe some sort of delay between events, you know what I mean.

“Lag: A period of time between one event and another.”

As you said, windows.processPostedMessages() should dispatch all the messages, although it may not always ensures a UI redraw or update. If I am not wrong, it would also dispatch other messages, which may cause troubles, wouldn’t it?

In this case it updates the UI, but due to the amount of calls the controller makes, I am unsure of whether or not it is good to put it there.

If someone would like to test its stability you can just add the following line to the code below the “edt6.text = angleToPlane_ZX as string” line:

windows.processPostedMessages()

Just needed for the version that uses the .Net controls.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

I see the weakness of using windows.processPostedMessages () …
Unfortunately, this affects internal system messages too.

actually the most interesting part of the task is the finding a ‘ui lagging’ free solution.

windows.processPostedMessages() is about window messages. it doesn’t effect any system messages (like system notifications or events).

in your case it’s safe to use… slowing down is possible, but very little

.net controls will meet the same problem with update. or might be worth.

Thank you very much !

The new code works way better than the original tape
I love the copy-button

I suggest you publish it on Scriptspot as well

macroScript Popup_Tape
	category:"Tools"
	tooltip:"Popup Tape Params"
	buttontext:"POPUP TAPE"
(
	global PopupTapeRollout = if PopupTapeRollout != undefined do PopupTapeRollout

	--local dialog_width = 220 
	
	rollout PopupTapeRollout "Popup Tape Params" width:220
	(
		local opened = off
		local placed = if placed != undefined do placed
		local use_units = if use_units != undefined then use_units else off
		
		local w_dl = 220
		
		local w_sh = 54
		local w_st = w_dl - w_sh - 10
		local w_tx = w_st/3
		local w_sp = 2*w_tx
		local w_bx = 3*w_tx
		
		local w_im = w_sh + 4
		local h_im = 18
		
		fn isValidTape node = (iskindof node Tape and not isdeleted node and isvalidnode node.target)
		local tape_node = if tape_node != undefined do tape_node
			
		group "Current Tape: "
		(
			label length_lb "Length:" align:#right offset:[-w_st,4]
			edittext length_ed pos:[w_sh,length_lb.pos.y-1] width:w_sp
			checkbox units_ch "Units" checked:use_units pos:([w_sh + w_sp + 6,length_lb.pos.y])

			label tape_lb "Name:" align:#right offset:[-w_st,6]
			edittext tape_name_tx pos:[w_sh,tape_lb.pos.y-1] width:w_bx
		)
		
		group "World Space Angles: "
		(
			label axis_lb "Axis:" align:#right offset:[-w_st,4]
			edittext angle_xx_ed pos:[w_sh + 0*w_tx,axis_lb.pos.y-1] width:w_tx readonly:on
			edittext angle_yy_ed pos:[w_sh + 1*w_tx,axis_lb.pos.y-1] width:w_tx readonly:on
			edittext angle_zz_ed pos:[w_sh + 2*w_tx,axis_lb.pos.y-1] width:w_tx readonly:on
			imgtag axis_im pos:[0,axis_lb.pos.y-2] width:w_im height:h_im transparent:black tooltip:"Axis X Y Z"

			label plane_lb "Plane:" align:#right offset:[-w_st,4]
			edittext angle_xy_ed pos:[w_sh + 0*w_tx,plane_lb.pos.y-1] width:w_tx readonly:on
			edittext angle_yz_ed pos:[w_sh + 1*w_tx,plane_lb.pos.y-1] width:w_tx readonly:on
			edittext angle_zx_ed pos:[w_sh + 2*w_tx,plane_lb.pos.y-1] width:w_tx readonly:on
			imgtag plane_im pos:[0,plane_lb.pos.y-2] width:w_im height:h_im transparent:black tooltip:"Plane XY YZ ZX"
		)
				
		fn updateNameUI = if isValidTape tape_node do
		(
			tape_name_tx.text = tape_node.name
		)
		
		fn roundFloat d pre:0.01 =
		(
			d = (d as float)/pre
			v = if (d - (v1 = floor d)) > ((v2 = ceil d) - d) then v2 else v1 
			v*pre
		)
		fn axisAngle dir axis calc: control: =
		(
			a = roundFloat (abs (calc (dot dir axis)))
			if control != unsupplied then
			(
				if control.text as float != a do 
				(
					control.text = (a as string)
				)
				ok
			)
			else a
		)
		fn updateDataUI = if isValidTape tape_node do
		(			
			d = distance tape_node tape_node.target
			length_ed.text = if not use_units then d as string else units.formatValue d 

			dir = tape_node.dir
			
			axisAngle dir x_axis calc:acos control:angle_xx_ed
			axisAngle dir y_axis calc:acos control:angle_yy_ed
			axisAngle dir z_axis calc:acos control:angle_zz_ed
			
			axisAngle dir z_axis calc:asin control:angle_xy_ed
			axisAngle dir x_axis calc:asin control:angle_yz_ed
			axisAngle dir y_axis calc:asin control:angle_zx_ed

			windows.processPostedMessages()
		)
		
		on units_ch changed state do 
		(
			use_units = state
			updateDataUI()
		)
		
		fn deleteHandlers =
		(
			deleteallchangehandlers id:#popup_tape
			gc light:on
		)
		fn setupHandlers =
		(
			deleteHandlers()
			
			when transform tape_node changes id:#popup_tape do updateDataUI()
			when name tape_node change id:#popup_tape do updateNameUI()
		)
		
		fn getTapeNode = if isvalidnode (node = selection[1]) do
		(
			if iskindof node Targetobject do node = refs.dependentnodes node firstonly:on
			
			if isValidTape node do
			(
				tape_node = node	
				setupHandlers() 

				updateDataUI()
				updateNameUI()
			)
		)
		
		on PopupTapeRollout close do
		(
			opened = off
			placed = getdialogpos PopupTapeRollout
			
			callbacks.removescripts id:#popup_tape
			deleteHandlers()
			updateToolbarButtons()
		)

		on PopupTapeRollout open do
		(
			opened = on
			placed = getdialogpos PopupTapeRollout
			
			callbacks.removescripts id:#popup_tape
			callbacks.addscript #selectionSetChanged "::PopupTapeRollout.getTapeNode()" id:#popup_tape
			callbacks.addscript #unitsChange "::PopupTapeRollout.updateDataUI()" id:#popup_tape
			getTapeNode()
			updateToolbarButtons()
		)
	)
	
	
	fn isOpened = (iskindof ::PopupTapeRollout RolloutClass and ::PopupTapeRollout.opened)
	on isChecked do isOpened()

	on execute do
	(
		if isOpened() then
		(
			try (::PopupTapeRollout.placed = getdialogpos ::PopupTapeRollout) catch()
			try (destroydialog ::PopupTapeRollout) catch()
		)
		else
		(
			pos = if iskindof PopupTapeRollout RolloutClass do PopupTapeRollout.placed
			pos = if iskindof pos Point2 then pos else unsupplied
			createdialog PopupTapeRollout style:#(#style_titlebar, #style_toolwindow, #style_sysmenu) pos:pos
		)
		updateToolbarButtons()
	)
)
try (destroydialog ::PopupTapeRollout) catch()

this is my version… i changed a little callbacks logic, and UI. the UI might look OFF in normal display because i tested it for 4K only (what i have at home)

also couple features added (tape name update, units option, etc.)

1 Reply
(@haider_of_sweden)
Joined: 11 months ago

Posts: 0

Thanks Denis,

Personally, I appreciate different approaches, because it reveals different possibilities.
Here is my feedback

  • I like the UI, it offers many feature. Interresting that once you click and move the target, it sticks to the mouse pointer – what was your motivation for that feature?
  • I like that the toolbar button toggles the UI, however, it does not turn on the tape for me. The toggle could include the tape tool as well. But then we would need a tape-button in the UI as well, because in Jorge’s approach, pressing the toolbar button toggles the tape alone (like in the native tape tool). The way I use the tape tool is mostly creating it and RMB click to cancel it on the fly once I got what I needed, which is measuring. After cancelling the tool, I might need it again – so pressing the toolbar button would in this case turn off the UI instead of giving me a new tape. Optionally, RMB-cancelling the tool could simply turn of the UI as well, so that I would need to press the toolbar button again to get the tool plus UI. This could work
  • Issues: I get two MAXScript Change Handler Exception: Unable to convert: undefined to type: <node> when I click the Tape Tool

Issues: I get two MAXScript Change Handler Exception: Unable to convert: undefined to type: when I click the Tape Tool

that was a bug. fixed.

about combining the pop-up tape params dialog and tape creation tool… i don’t want to combine it one tool.
the dialog binds to any newly created tape object or to any selected tape or its target.

1 Reply
(@haider_of_sweden)
Joined: 11 months ago

Posts: 0

Great!
There is one popup left – it occurs when I cancel a tape by left clicking

fixed. Thanks for debugging

Page 2 / 3