Radiobuttons : #offsets parameter rules


#1

check this snippet:

try(destroydialog rol) catch()
rollout rol "Test Rollout" width:400
(
	label lb1 "[0,0] [0,0] [0,0]" align:#right offset:[0,10] enabled:off
	radiobuttons rb1 labels:#("Left","Center","Right") columns:3 align:#left offsets:#([0,0],[0,0],[0,0])
	
	label lb2 "[50,0] [0,0] [0,0]" align:#right offset:[0,40] enabled:off
	radiobuttons rb2 labels:#("Left","Center","Right") columns:3 align:#left offsets:#([50,0],[0,0],[0,0])
	
	label lb3 "[0,0] [50,0] [0,0]" align:#right offset:[0,40] enabled:off
	radiobuttons rb3 labels:#("Left","Center","Right") columns:3 align:#left offsets:#([0,0],[50,0],[0,0])
	
	label lb4 "[0,0] [0,0] [50,0]" align:#right offset:[0,40] enabled:off
	radiobuttons rb4 labels:#("Left","Center","Right") columns:3 align:#left offsets:#([0,0],[0,0],[50,0])
	
	label lb5 "[50,0] [50,0] [0,0]" align:#right offset:[0,40] enabled:off
	radiobuttons rb5 labels:#("Left","Center","Right") columns:3 align:#left offsets:#([50,0],[50,0],[0,0])
	
	label lb6 "[0,0] [50,0] [50,0]" align:#right offset:[0,40] enabled:off
	radiobuttons rb6 labels:#("Left","Center","Right") columns:3 align:#left offsets:#([0,0],[50,0],[50,0])
	
	label lb7 "[50,0] [0,0] [50,0]" align:#right offset:[0,40] enabled:off
	radiobuttons rb7 labels:#("Left","Center","Right") columns:3 align:#left offsets:#([50,0],[0,0],[50,0])
	
	label lb8 "[50,0] [50,0] [50,0]" align:#right offset:[0,40] enabled:off
	radiobuttons rb8 labels:#("Left","Center","Right") columns:3 align:#left offsets:#([50,0],[50,0],[50,0])
	

	on rol open do
	(
	)
)
createdialog rol

forget what the Help says about #offsets parameter…
Who can find a logic of offsets working?
:crazy_face:


#2

whatever solution you find, I bet it will not be correct and unambiguous … which I will confirm with the next snippet :stuck_out_tongue_winking_eye:


#3


maybe this could explain
the only thing should be concerned is every character has itself‘s length , so ‘L’ and ‘R’ have different length


#4

I forgot to say…

I have no idea how it works in every case. I tried but didn’t find any common logic.


#5

all offset based on the original postion , which based on the sorting of dialog , the one control offsetting , the others below it would be affected
when offset, any one in one line and behind would not offset , the other lines would
when the offset one have other controls in one line , the below lines wouldn’t offset to up , if the offset one is the only one in that line , the below could offset to up but can’t offset out of the dialog , the most x-offset < 0 is set them to the first line 's y-pos

i think this is the all rules


#6

Now, when you know the rules, answer:

We have four-buttons group of radio buttons in one row. How much will the third element be offset from its original position if only the fourth element has a specified offset of [100,0]?
:wink:


#7
	radiobuttons rb1 labels:#("1","2","3","4") columns:4 align:#left offsets:#([0,0],[0,0],[0,0],[0,0])
	radiobuttons rb2 labels:#("1","2","3","4") columns:4 align:#left offsets:#([0,0],[0,0],[0,0],[100,0])

if you mean the 3rd of rb2 offset from the 3rd of rb1 , for radiobutton , offset was limited in it’s own cell , then x-offset = 100 will expand left of 4th , and other 3 expand ringt , all 100 px , if all items’ original length are 50px , then original postion is [ 0 , 0+50 , 50+50 , 50+50+50 ] , after offset will be [0 , 0+50+100 , 0+50+100+50+100 ,0+50+100+50+100+50+100+100] ,so 3rd from 100 ->300


#8

try(destroydialog rol) catch()
rollout rol "Test Rollout" width:700
(
	local lbs = #("1","2","3","4")
	
	radiobuttons rb1 labels:lbs columns:4 align:#left
	radiobuttons rb2 labels:lbs columns:4 align:#left offsets:#([0,0],[0,0],[0,0],[100,0])

	label info align:#left enabled:off offset:[0,8]

	on rol open do
	(
		pp = for k=1 to 4 collect
		(
			p = windows.getWindowPos rb1.hwnd[k]
		)
		
		ss = stringstream ""
		dd = for k=1 to 4 collect
		(
			p = pp[k]
			d = windows.getWindowPos rb2.hwnd[k]
			
			dx = d.x - p.x 
			format "%(%,%) " dx p.w d.w to:ss

			d
		)
		info.text = ss as string
	)
)
createdialog rol

#9

There’s a RadioControl::compute_layout method in Maxscrpt.dll that is likely related to this.

Not sure if it is helpful at all, but here’s
a little part of the method from IDA (max 2014)
v56 is a float value
_val is supposedly the mxs array that holds offsets values

idx = 0;
index = 0i64;
if ( (val + 12) > 0 )
{
do
{
nth_offset_value = ((_val + 7) + 8 * index);
(
(nth_offset_value + 8040i64))(nth_offset_value, &v56);
LODWORD(vars10) = ffloor(v56);
HIDWORD(vars10) = ffloor(v57);

calculated_offsets[index] = vars10;
++idx;
++index;
}
while ( idx < (_val + 12) );
}
v15 = v50;
offsets = calculated_offsets;
}
v27 = 0;
v28 = 0;
LODWORD(vars10) = 0;
for ( i = 0i64; v28 < (radio + 49); ++i )
{
LODWORD(v30) = (
(**(
(v53 + 7) + 8 * i) + 7960i64))();
DLGetTextExtent(
(vars18 + 136), v30, &v59);

offsets = calculated_offsets;
v31 = LODWORD(calculated_offsets[i]) + v59.cx + 23;
if ( v31 > v27 )
v27 = LODWORD(calculated_offsets[i]) + v59.cx + 23;
LODWORD(vars10) = v31 + vars10;
++v28;
}


#10

As far as the few test I’ve done for the example given by @denisT, I came up with this very simple formula:

Control pixel position = (control index * maximum offset) + control offset
Control index is 0 based.

This formula seems to work consistently for this specific example, radio buttons, left align. Didn’t test it with other configurations.

So, for this #([0,0], [0,0], [0,0], [100,0]), the position of the third control should be 200px.

Control index = 2
Maximum offset = 100
Control offset = 0
(2*100)+0 = 200

#11

here is a universal test…

try(destroydialog rol) catch()
rollout rol "Test Rollout" width:1000
(
	local lbs = #("1","2","3","4")
	
	radiobuttons rb1 labels:lbs columns:4 align:#left --offsets:#([0,0],[0,0],[0,0],[50,0])
	radiobuttons rb2 labels:lbs columns:4 align:#left offsets:#([0,0],[200,0],[0,0],[100,0])

	label info align:#left enabled:off offset:[0,8]

	on rol open do
	(
		pp = for k=1 to 4 collect
		(
			p = windows.getWindowPos rb1.hwnd[k]
		)
		
		ss = stringstream ""
		dd = for k=1 to 4 collect
		(
			p = pp[k]
			d = windows.getWindowPos rb2.hwnd[k]
			
			dx = d.x - p.x 
			format "%(%,%) " dx p.w d.w to:ss

			d
		)
		info.text = ss as string
	)
)
createdialog rol

according to your formula the second item should be:
(1*200) + 0 = 200

but it’s on 400px


#12

Oh! my fault… we have to add item’s offset, right?

(1*200) + 200 = 400… looks right


#13

Yes, that would be it. Needs to be different for other alignments or text labels I guess.
Here is a modified version of your script to test it randomly:

try(destroydialog rol) catch()

rollout rol "Test Rollout" width:700
(
	local offsets = for j = 1 to 5 collect random [0,0] [100,0]
	local lbs = #("1","2","3","4","5")
	
	radiobuttons rb1 labels:lbs columns:5 align:#left
	radiobuttons rb2 labels:lbs columns:5 align:#left offsets:offsets

	label info  width:700 height:24 align:#left enabled:on offset:[0,8]
	label info2 width:700 height:24 align:#left enabled:on offset:[0,8]
	
	on rol open do
	(
		pp = for k=1 to 5 collect
		(
			p = windows.getWindowPos rb1.hwnd[k]
		)
		
		ss = stringstream ""
		format "Real Values\n" to:ss
		dd = for k=1 to 5 collect
		(
			p = pp[k]
			d = windows.getWindowPos rb2.hwnd[k]
			
			dx = d.x - p.x
			format "%\t" dx to:ss

			d
		)
		info.text = ss as string
		
		-- Predicted values ---------------------------------------------
		o1 = offsets[1][1] as integer
		o2 = offsets[2][1] as integer
		o3 = offsets[3][1] as integer
		o4 = offsets[4][1] as integer
		o5 = offsets[5][1] as integer
		
		ss = stringstream ""
		format "Predicted Values\n" to:ss
		
		mmax = amax o1 o2 o3 o4 o5
		
		o2 = (mmax * 1) + o2
		o3 = (mmax * 2) + o3
		o4 = (mmax * 3) + o4
		o5 = (mmax * 4) + o5
		
		format "%\t%\t%\t%\t%" o1 o2 o3 o4 o5 to:ss
		
		info2.text = ss as string
		-- Predicted values ---------------------------------------------
	)
	
)
createdialog rol

#14

the problem is how to make a horizontal group of radio buttons with a given spacing between them…
it sounds silly, but the best way to achieve this is to use a vertical group:

try(destroydialog rol) catch()
rollout rol "Test Rollout" width:700
(
	local lbs = #("1","2","3","4")
	
	radiobuttons rb1 labels:lbs columns:4 align:#left --offsets:#([0,0],[0,0],[0,0],[50,0])
	radiobuttons rb2 labels:lbs columns:1 offsets:#([0,0],[100,-15],[200,-30],[300,-45]) align:#left
	
	label info align:#left enabled:off offset:[0,8]

	on rol open do
	(
		pp = for k=1 to 4 collect
		(
			p = windows.getWindowPos rb1.hwnd[k]
		)
		
		ss = stringstream ""
		dd = for k=1 to 4 collect
		(
			p = pp[k]
			d = windows.getWindowPos rb2.hwnd[k]
			
			dx = d.x - pp[1].x 
			format "%(%,%) " dx p.w d.w to:ss

			d
		)
		info.text = ss as string
	)
)
createdialog rol