here is my tool-snippet that demonstrates how to use callbacks and when constructs for real-time UI update:
global Distance_Catcher
global Distance_Catcher_Settings = if Distance_Catcher_Settings == undefined then
#(
[100,100], -- dialog pos
undefined, -- dialog size
1, -- units
#(), -- locked nodes
undefined, -- locked distance
undefined -- last distance
)
else Distance_Catcher_Settings
try(destroydialog Distance_Catcher) catch()
rollout Distance_Catcher_Rol "Distance Catcher" width:220
(
local dcs = Distance_Catcher_Settings
group "Nodes: "
(
edittext name01_et "" readonly:on width:170 across:2
checkbutton lock01_cb width:17 height:17 align:#right offset:[-4,0] tooltip:"Lock Node" checked:(isvalidnode dcs[4][1])
edittext name02_et "" readonly:on width:170 across:2
checkbutton lock02_cb width:17 height:17 align:#right offset:[-4,0] tooltip:"Lock Node" checked:(isvalidnode dcs[4][2])
)
group "Distance: "
(
label units_lb "Units:" across:2 offset:[-24,1]
radiobuttons units_rb labels:#("World", "System") default:dcs[3] columns:2 offset:[-42,0]
edittext dist_et "" readonly:on width:85 across:3
edittext lock_et "" readonly:on width:85 align:#right offset:[40,0]
checkbutton lock_cb width:17 height:17 align:#right offset:[-4,0] tooltip:"Lock Distance" checked:(dcs[5] != undefined)
)
fn getCurrentNodes =
(
nodes = getCurrentSelection()
node01 = dcs[4][1]
node02 = dcs[4][2]
if isvalidnode node01 do
(
if node01 != nodes[1] or nodes[2] == undefined do nodes[2] = nodes[1]
nodes[1] = node01
)
if isvalidnode node02 do
(
if not isvalidnode node01 and node02 == nodes[1] and nodes[2] != undefined do nodes[1] = nodes[2]
nodes[2] = node02
)
nodes
)
fn theDist d = if dcs[3] == 1 then units.formatvalue d else d as string
fn updateDistance nodes: names:on values:on =
(
if nodes == unsupplied do nodes = getCurrentNodes()
if names do
(
name01_et.text = try(nodes[1].name) catch("")
name02_et.text = try(nodes[2].name) catch("")
)
if values do
(
dcs[6] = try(distance nodes[1] nodes[2]) catch(0)
dist_et.text = theDist dcs[6]
lock_et.text = theDist (if dcs[5] != undefined then dcs[5] else dcs[6])
)
)
fn updateHandlers =
(
deleteAllChangeHandlers id:#distance_catcher
if (nodes = getCurrentNodes()).count > 0 do
(
when transform nodes change id:#distance_catcher handleAt:#redrawViews do updateDistance names:off
when name nodes change id:#distance_catcher do updateDistance values:off
)
updateDistance()
)
on lock01_cb changed state do
(
dcs[4][1] = if state then (getCurrentNodes())[1] else undefined
updateDistance()
)
on lock02_cb changed state do
(
dcs[4][2] = if state then (getCurrentNodes())[2] else undefined
updateDistance()
)
on units_rb changed state do
(
dcs[3] = state
updateDistance names:off
)
on lock_cb changed state do
(
dcs[5] = if state then dcs[6] else undefined
updateDistance names:off
)
on Distance_Catcher_Rol close do
(
deleteAllChangeHandlers id:#distance_catcher
callbacks.removescripts id:#distance_catcher
dcs[1] = getdialogpos Distance_Catcher_Rol
)
on Distance_Catcher_Rol open do
(
deleteAllChangeHandlers id:#distance_catcher
callbacks.removescripts id:#distance_catcher
callbacks.addscript #selectionSetChanged "Distance_Catcher.updateHandlers()" id:#distance_catcher
callbacks.addscript #unitsChange "Distance_Catcher.updateDistance unitsonly:on" id:#distance_catcher
updateDistance()
)
)
Distance_Catcher = Distance_Catcher_Rol
createdialog Distance_Catcher pos:Distance_Catcher_Settings[1]
the tools displays the distance between two selected (or/and locked) nodes. The node names, distance value, and distance value units updates in real-time using events system:
– names changed
– transforms changed
– selection changed
– units changed
the drawing lines between checked nodes was not my point. it’s easy to find a good sample about this matter.