Nesting string data in string stream

Nesting string data in string stream

bertv
Enthusiast Enthusiast
1,314 Views
12 Replies
Message 1 of 13

Nesting string data in string stream

bertv
Enthusiast
Enthusiast

Hey,

 

I was wondering how one can nest a string in a string?

 

Example this:

 

 

Box name:"test" width:10 height:20

 

 

 

How to  put it in a stringed format as seen below to run with the execute command:

 

 

"Box name:"test" width:10 height:20"

 

 

 

I tried the following,

 

main_ss = stringstream ""
format "Box name:% width:10 height:20" "test" to:main_ss

execute(main_ss as string)
free main_ss

 

 

But got the following error

 

-- Error occurred in anonymous codeblock; filename: ; position: 19; line: 1
-- Unable to convert: undefined to type: String
-- MAXScript callstack:
-- thread data: threadID:26704

 

0 Likes
1,315 Views
12 Replies
Replies (12)
Message 2 of 13

bertv
Enthusiast
Enthusiast

Found it by change 🙂

Parentally you can add \" in the string

 

main_ss = stringstream ""
format "Box name:\"%\" width:10 height:20" ("test" as string) to:main_ss

execute(main_ss as string)
free main_ss
0 Likes
Message 3 of 13

bertv
Enthusiast
Enthusiast

I wanted to know if you can even go deeper in nesting the string with the stringstream?

 

0 Likes
Message 4 of 13

denisT.MaxDoctor
Advisor
Advisor
(
	name_ss = stringstream ""
	wcol_ss = stringstream ""
	format "Sample_%" (timestamp()) to:name_ss
	format "(color % % %)" 255 128 128 to:wcol_ss

	exec_ss = stringstream ""

	str = "box name:\"%\" wirecolor:%" 
	format str (name_ss as string) (wcol_ss as string) to:exec_ss 

	execute (exec_ss as string)

	free #(name_ss, wcol_ss, exec_ss)
)
0 Likes
Message 5 of 13

bertv
Enthusiast
Enthusiast

Hi again Denis 😉

 

The problem is I'm trying to combine the following code from a for loop to one string and execute it once. To booste performance by only calling Execute once with the concatenated string.

 

Code below is part of a for loop:

 

nameSwatch = "swatch_" + (counter as string)
nameBmp = "bmp_" + (counter as string)
			
element_ss = stringstream ""
format "rci.addText \"local % = bitmap % % color:%\"" nameBmp swatch_width swatch_height (col_line[2] as point3) to:element_ss
execute(element_ss as string)z
free element_ss
			
param_ss = stringstream ""
format "bitmap:% tooltip:\"%\" iconSize:[%,%] pos:[%,%]" \
nameBmp col_line[1] swatch_width swatch_height swatch_x swatch_y to:param_ss
			
rci.addControl #imgTag nameSwatch "" paramstr:param_ss as string	
rci.addHandler nameSwatch #click \
codeStr:("RoFn.processSelected @" + col_line[1] as string +"-" + col_line[2] as string + "-" + col_line[3] as string + "@") filter:on
free param_ss

 

 

 

I tried the code below but there are issues with the paramStr and codeStr. Because they are 2 levels deep nested in the string and there is a problem with the string literal indication. I tried to apply your suggestion but got stuck.

 

nameSwatch = "swatch_" + (counter as string)
nameBmp = "bmp_" + (counter as string)
			
element_ss = stringstream ""
format "rci.addText \"local % = bitmap % % color:%\"" nameBmp swatch_width swatch_height (col_line[2] as point3) to:element_ss
			
param_ss = stringstream ""
format "bitmap:% tooltip:\"%\" iconSize:[%,%] pos:[%,%]" nameBmp col_line[1] swatch_width swatch_height swatch_x swatch_y to:param_ss
			
ui_ss_01 = stringstream ""
format "rci.addControl #imgTag % \"\" paramstr:\"%\"" nameSwatch (param_ss as string) to:ui_ss_01
			
ui_ss_02 = stringstream ""
format "rci.addHandler % #click codeStr:(\"RoFn.processSelected @\" +  % +\"-\" + % + \"-\" +  % + \"@\") filter:on" nameSwatch col_line[1] col_line[2] col_line[3] to:ui_ss_02
			
--Final execute string
format "% \n % \n % \n" (element_ss as string) (ui_ss_01 as string) (ui_ss_02 as string) to:main_ss

 

 

 

The output is as follow:

This is one part from the 1500 outputs in the concatenated string =>

 

rci.addText "local bmp_21 = bitmap 44 20 color:[47,23,26]" 
 rci.addControl #imgTag swatch_21 "" paramstr:"StringStream:"bitmap:bmp_21 tooltip:"RAL 010 40 15	" iconSize:[44,20] pos:[0,60]"" 
 rci.addHandler swatch_21 #click codeStr:("RoFn.processSelected @" +  RAL 010 40 15	 +"-" + [47,23,26] + "-" +  [118,85,91] + "@") filter:on 

 

 

 

As you can see there is a string indication problem at the paramStr and codeStr

 

 

0 Likes
Message 6 of 13

denisT.MaxDoctor
Advisor
Advisor

do you want to dynamically create a UI with 1500 controls of the same type?

0 Likes
Message 7 of 13

bertv
Enthusiast
Enthusiast

Yes,

I'm creating a tool to pick certain colors.

At the moment all works well. But it just take about 5sec to load everything.

I think it's because of the Execute command called with the creation of each color slot.

That's why I try to combine all color slot creation in one large string and only call it once with execute.

 

Below a grab of the program:

grab2.JPG

0 Likes
Message 8 of 13

denisT.MaxDoctor
Advisor
Advisor
rol = 
(
	bt_size = [24,22]
	
	bitmap_str = @"local col_% = %" 
	params_str = @"bitmap:(bitmap 1 1 color:col_%) width:% height:% pos:%"
	handle_str = 
	@"(
		c = colorPickerDlg col_% %
		if c != undefined do
		(
			col_% = c 
			bm_%.bitmap = bitmap 1 1 color:col_%
		)
	)"
	
	fn makeId index = (formattedprint index format:"04d")
	
	fn addInitColor id col =
	(
		ss = stringstream ""
		format bitmap_str id col to:ss
		
		str = ss as string
		free ss

		rcg.addText str
	)
	fn addImageTag id pos width:bt_size.x height:bt_size.y =
	(
		ss = stringstream ""
		format params_str id width height pos to:ss
		
		str = ss as string
		free ss

		rcg.addControl #imgtag ("bm_" + id) "" paramstr:(str)
	)
	fn addHandler id =
	(
		ss = stringstream ""
		format handle_str id "\"Extended Picker\"" id id id to:ss
		
		str = ss as string
		free ss
		rcg.addHandler ("bm_" + id) #click codeStr:(str)
	)
	
	seed 1
	num_rows = 10
	num_cols = 8
	offset = [10,10]
	spacing = [4,4]
	
	rollout_name = "ExtendedColorPicker"
	
	w = num_cols * (bt_size.x + spacing.x) + offset.x * 2 - spacing.x
	h = num_rows * (bt_size.y + spacing.y) + offset.y * 2 - spacing.y
	
	rcg = rolloutCreator rollout_name "Extended Picker" width:w height:h
	rcg.begin()
	
	for y = 0 to num_rows - 1 do
	(
		for x = 0 to num_cols - 1 do
		(
			col = random black white
			index = y * num_cols + x
			pos = [offset.x + x * (bt_size.x + spacing.x), offset.y + y * (bt_size.y + spacing.y)]
			
			id = makeId index
			addInitColor id col
			addImageTag id pos
			addHandler id
		)
	)

	rcg.end()
	rol = rcg.def
)
createdialog rol

 

here is the way how it can be done.

 

 

0 Likes
Message 9 of 13

bertv
Enthusiast
Enthusiast

Hi Denis,

Thanks for the help.

 

Tested the code. It works, but also takes some seconds before showing the tiles when bumping up the row count.

Not sure if this can be optimized to work faster.

 

Regards,

Bert

0 Likes
Message 10 of 13

denisT.MaxDoctor
Advisor
Advisor

you should use .NET or Qt ... MaxScript is not for heavy UIs

0 Likes
Message 11 of 13

bertv
Enthusiast
Enthusiast

Ok, thanks Denis

Learned a lot.

 

I'll have a look at .NET to update my code

0 Likes
Message 12 of 13

denisT.MaxDoctor
Advisor
Advisor

Why do you need to make 1500 buttons in your case? Make one bitmap for all colors at once and use it with one imgTag control... imgTag click (press/release) handle gives the click position.
One control - one handle... quick and easy.

 

try(destroydialog rol) catch()
rollout rol "RO:6D390B41" width:400
(
	local sub = rollout sub "COLORS"
	(
		imgtag colors_ig style:#bmp_center width:380 height:1800 align:#center 
	)
	
	subRollout colors_sub width:390 height:800 align:#left offset:[-8,0]

	fn fillColors = 
	(
		bmp_master = bitmap 380 1800 color:(color 1 1 1)
		for y = 0 to 99 do for x = 0 to 9 do
		(
			tag = bitmap 38 18 color:(random black white)
			pasteBitmap tag bmp_master (box2 0 0 tag.width tag.height) [x*38, y*18]  
		)
		sub.colors_ig.bitmap = bmp_master
	)
	
	on rol open do
	(
		addSubRollout colors_sub sub
		fillColors()
	)
)
createdialog rol
0 Likes
Message 13 of 13

denisT.MaxDoctor
Advisor
Advisor

here is more advanced:

 

 

try(destroydialog rol) catch()
rollout rol "RO:2ED44C08" width:400
(
	local sub = rollout sub "COLORS"
	(
		local dim = [10,100]
		local bmp_size = [380, 1800]
		local tag_size = bmp_size / dim
		
		imgtag colors_ig style:#bmp_center width:(bmp_size.x+2) height:(bmp_size.y+2) align:#center 
		
		local colors = #()
		
		fn sort_by_magnitude c1 c2 = 
		(
			if (h = int ((c1.h - c2.h) / 8)) == 0 then
			(
				--c1.v - c2.v
				length (c1 as point3) - length (c2 as point3)
			)
			else h
		)
		
		fn fillColors = 
		(
			colors = #()
			for y = 0 to dim.y - 1 do for x = 0 to dim.x - 1 do
			(
				col = random black white
				append colors col
			)
			qsort colors sort_by_magnitude
			
			bmp_master = bitmap bmp_size.x bmp_size.y color:(color 1 1 1)
			for y = 0 to dim.y - 1 do for x = 0 to dim.x - 1 do
			(
				index = y * dim.x + x + 1
				col = colors[index]
				tag = bitmap tag_size.x tag_size.y color:col
				pasteBitmap tag bmp_master (box2 0 0 tag.width tag.height) ([x, y]* tag_size)  
			)
			colors_ig.bitmap = bmp_master
		)
		
		on colors_ig lbuttondown pos flags do
		(
			coord = [int (pos.x / tag_size.x), int (pos.y / tag_size.y)]  
			index = coord.y * dim.x + coord.x + 1

			col = colors[index]

			format "pos:% coord:% index:% color:%\n" pos coord index col

			if (bit.and flags 0x8) do
			(
				-- if CTRL:
			)
		) 
		on colors_ig rbuttondown pos flags do
		(
			coord = [int (pos.x / tag_size.x), int (pos.y / tag_size.y)]  
			index = coord.y * dim.x + coord.x + 1
			col = colors[index]
			
			c = colorpickerdlg col "Pick A Color"
			if c != undefined do 
			(
				bmp_master = colors_ig.bitmap
				tag = bitmap tag_size.x tag_size.y color:c
				pasteBitmap tag bmp_master (box2 0 0 tag.width tag.height) (coord * tag_size)
				colors_ig.bitmap = bmp_master
				colors[index] = c
			)
		) 
	)
	
	subRollout colors_sub width:390 height:800 align:#left offset:[-8,30]
	
	
	on rol open do
	(
		addSubRollout colors_sub sub
		sub.fillColors()
	)
)
createdialog rol

 

0 Likes