Notifications
Clear all

[Closed] dotNet UI

Not sure if it is the right way to handle it but I use the hit.x value to define which column the user has clicked in. If the user clicks in a value higher than 90 on the x, meaning further to the right then execute adding the material to the editor library. Where as if the clicks within a value of 0 – 90, display the bitmap image in a popup window.

I’m looking forward to hearing what you guys think.


try(destroyDialog ::roll_imatges)catch()
rollout roll_imatges "Materials" 
(
	local	dir_imatges = @"C:\Users\IEVFX\Desktop	rash\mtlTesting"
	
  	button btn_scan "Directory" width:220 height:24 pos:[10,10]
  	dotNetControl lv_imatges "System.Windows.Forms.ListView" pos:[10,40] width:220 height:400
   	
	fn myCallback = ( return false )
	
 	fn carrega_imatges paths_imatges = (
   		fn callback_abort = ( dotnetObject "System.Drawing.Image+GetThumbnailImageAbort" myCallback())
   		local ptr_callback_abort = dotNetClass "System.IntPtr"
   		Llista_Imatges	= dotNetObject "System.Windows.Forms.ImageList"
   		Llista_Imatges.ColorDepth = Llista_Imatges.ColorDepth.Depth24Bit
   		Llista_Imatges.ImageSize = dotNetObject "System.Drawing.Size" 90 90
 		for path_imatge in paths_imatges do (
   			thumb = dotNetObject "System.Drawing.Bitmap" path_imatge
  			-- Calling GetThumbnailImage this way doesn't work :(
   			-- thumb = thumb.GetThumbnailImage 160 120 (callback_abort()) (ptr_callback_abort.Zero)
   			Llista_Imatges.images.add thumb
   		)
   		return Llista_Imatges
   	)
	
 	fn inicialitzaListView lv = (
   		lv.View = (dotNetClass "System.Windows.Forms.View").Details
   		lv.borderstyle = (dotnetclass "System.Windows.Forms.BorderStyle").fixedsingle
   		lv.showitemtooltips = true
   		lv.gridlines = true
   		lv.checkboxes = false
   		lv.labeledit = false
   		lv.Columns.add "Image" 90
   		lv.Columns.add "Name" 130
   	)
	
 	fn ompleListView lv llista_imatges = (
   		lv.Clear()
   		lv.Columns.add "Image" 90
   		lv.Columns.add "Name" 130
   		lv.SmallImageList = carrega_imatges llista_imatges
  		for i = 1 to llista_imatges.count do (
   			imatge = llista_imatges[i]
   			ListViewOps.AddLvItem lv pTextItems:#("",(getFilenameFile imatge)) pImgIndex:(i-1)
   		)
   	)
	
 	on btn_scan pressed do (
   		dir_imatges = getSavePath caption:"Choose image dir:"
   		if dir_imatges != undefined do (
   			btn_scan.text = dir_imatges
   			fitxers_jpg = getFiles (dir_imatges + "\\*.jpg")
   			ompleListView lv_imatges fitxers_jpg
   		)
   	)
	
	on lv_imatges mouseDown arg do
	(
		hit=(lv_imatges.HitTest (dotNetObject "System.Drawing.Point" arg.x arg.y))
		if hit.item != undefined do
		(
			if arg.x <= 90 then (
				img = openBitmap(dir_imatges + "\\" + (hit.item.subItems.item[1].text)+".jpg")
				display img
			)else(
				print "material to editor"
			)
		)
	)
	
	on roll_imatges open do (
   		inicialitzaListView lv_imatges
		
		--//Initial Directory on open
		if dir_imatges != undefined do (
   			btn_scan.text = dir_imatges
   			fitxers_jpg = getFiles (dir_imatges + "\\*.jpg")
   			ompleListView lv_imatges fitxers_jpg
   		)
   	)	
)
createDialog roll_imatges 240 450 style:#(#style_SysMenu, #style_ToolWindow)

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

as i understood you want to know what subitem was clicked. well, use [b]ListViewItem.GetSubItemAt Method /b

I want to know whether or not the user clicks in the first or second column and as well as what row it is.

So example being
the user will click in row 3 column 2 it should print what is in that cell.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

that’s exactly what getsubitemat is about.

use mouseclick or mousedown event. event handler returns you mouse click coordinates.
use listview’s method GetItemAt to get the item clicked. if any item was clicked use item’s method GetSubItemAt to get a subitem.


try(destroydialog SubItemTest) catch()
rollout SubItemTest "Sub Item Test" width:204 height:104
(
	dotnetcontrol lv "ListView" width:200 height:100 pos:[2,2]  

	on lv MouseDown s a do
	(
		if (item = s.GetItemAt a.x a.y) != undefined do 
		(
			sub = item.getSubItemAt a.x a.y
			format "item:% sub:%
" item.Index (item.SubItems.IndexOf sub)
		)
	)
	on SubItemTest open do 
	(
		lv.view = lv.view.Details
		lv.GridLines = lv.FullRowSelect = on
			
		lv.Columns.add "Name" 100
		lv.Columns.add "ID" 44
		lv.Columns.add "Type" 50

		(lv.Items.Add "Anna").SubItems.AddRange #("M-16", "F")
		(lv.Items.Add "John").SubItems.AddRange #("B-52", "M")
	)
)
createdialog SubItemTest

This is what I’ve got so far.
How would I evaluate the clicked item to see which column it is in.
That way I can control which action happens depending on which column the user clicks.


try(destroyDialog ::rlMtlManager)catch()
rollout rlMtlManager "Material Manager"
(
	local	matDir = @"C:\Users\IEVFX\Desktop	rash\mtlTesting"
	
	button btnGetDir "Directory" width:220 height:24 pos:[10,10]
  	dotNetControl lstMats "System.Windows.Forms.ListView" pos:[10,40] width:220 height:400
	
	
	
/*----------Functions----------*/
	fn fnLstSetup lv = (
   		lv.View = (dotNetClass "System.Windows.Forms.View").Details
   		lv.borderstyle = (dotnetclass "System.Windows.Forms.BorderStyle").fixedsingle
   		lv.showitemtooltips = true
   		lv.gridlines = true
   		lv.checkboxes = false
   		lv.labeledit = false
   		lv.Columns.add "Preview" 90
   		lv.Columns.add "Name" 130
		lv.FullRowSelect=true	--Set so full width of listView is selected and not just first column.
   	)
	
	fn fnGenerateLst lv items = (
   		lv.Clear()
   		lv.Columns.add "Preview" 90
   		lv.Columns.add "Name" 130
   		--lv.SmallImageList = carrega_imatges items
  		for i = 1 to items.count do (
   			mtl = items[i]
   			ListViewOps.AddLvItem lv pTextItems:#("jpg",(getFilenameFile mtl as string)) pImgIndex:(i-1)
   		)
   	)
	
	
	
/*----------Actions----------*/
	on lstMats mouseDown arg do
	(
		clearListener()
		--showProperties arg
		hit = (lstMats.HitTest (dotNetObject "System.Drawing.Point" arg.x arg.y))
		validHit = lstMats.GetItemAt arg.x arg.y
		if validHit != undefined do
		(
			item = hit.subItem.text
			print item
		)
	)
	
	on btnGetDir pressed do 
	(
   		matDir = getSavePath caption:"Choose image dir:"
   		if matDir != undefined do (
   			btnGetDir.text = matDir
   			matsArr = getFiles (matDir + "\\*.mat")
   			fnGenerateLst lstMats matsArr
   		)
   	)
	
	on rlMtlManager open do 
	(
   		fnLstSetup lstMats
		
		--//Populate list with items
		if matDir != undefined do (
   			btnGetDir.text = matDir
   			matsArr = getFiles (matDir + "\\*.mat")
   			fnGenerateLst lstMats matsArr
   		)
   	)
)
createDialog rlMtlManager 240 450 style:#(#style_SysMenu, #style_ToolWindow)

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

you found a better solution. HitTest works well.
lstMats.HitTest (dotNetObject “System.Drawing.Point” arg.x arg.y)
is the same as
lstMats.HitTest arg.Location

I’m checking out the script you post above.
I think I’ll be able to figure this one out.

This is it!
I’m just going to code up the save button and its a wrap.


try(destroyDialog ::rlMtlManager)catch()
rollout rlMtlManager "Material Manager"
(
	local	matDir = @"C:\Users\IEVFX\Desktop	rash\mtlTesting"
	
	button btnGetDir "Directory" width:160 height:24 pos:[10,10]
	button btnSaveMtl "Save Mtl" width:60 height:24 pos:[170,10]
  	dotNetControl lstMats "System.Windows.Forms.ListView" pos:[10,40] width:220 height:400
	
	
	
/*----------Functions----------*/
	fn myCallback = ( return false )
	
	fn fnMakeTempBmp imgName = (
		bmpTemp = bitmap 90 90 color:gray
		bmpTemp.filename = imgName
		save bmpTemp
	)

	
 	fn fnPreviewThumbs imgPaths = (
   		fn callback_abort = ( dotnetObject "System.Drawing.Image+GetThumbnailImageAbort" myCallback())
   		local ptr_callback_abort = dotNetClass "System.IntPtr"
   		Llista_Imatges	= dotNetObject "System.Windows.Forms.ImageList"
   		Llista_Imatges.ColorDepth = Llista_Imatges.ColorDepth.Depth24Bit
   		Llista_Imatges.ImageSize = dotNetObject "System.Drawing.Size" 90 90
 		for path_imatge in imgPaths do (
   			thumb = dotNetObject "System.Drawing.Bitmap" path_imatge
   			Llista_Imatges.images.add thumb
   		)
   		return Llista_Imatges
   	)
	
	fn fnLstSetup lv = (
   		lv.View = (dotNetClass "System.Windows.Forms.View").Details
   		lv.borderstyle = (dotnetclass "System.Windows.Forms.BorderStyle").fixedsingle
   		lv.showitemtooltips = true
   		lv.gridlines = true
   		lv.checkboxes = false
   		lv.labeledit = false
   		lv.Columns.add "Preview" 90
   		lv.Columns.add "Name" 130
		lv.FullRowSelect=true	--Set so full width of listView is selected and not just first column.
   	)
	
	fn fnGenerateLst lv items = (
   		lv.Clear()
   		lv.Columns.add "Preview" 90
   		lv.Columns.add "Name" 130
		imgList = for mtl in items collect (substituteString mtl ".mat" ".jpg")
		for img in imgList where (doesFileExist img != true) do (fnMakeTempBmp img) --// make a gray temporary thumbnail if one doesn't already exist
   		lv.SmallImageList = fnPreviewThumbs imgList
  		for i = 1 to items.count do (
   			mtl = items[i]
   			ListViewOps.AddLvItem lv pTextItems:#("",(getFilenameFile mtl as string)) pImgIndex:(i-1)
   		)
   	)
	
	
	
/*----------Actions----------*/
	on btnSaveMtl pressed do
	(
		
		
	)
	
	on lstMats MouseDown s a do
	(
		clearlistener()
		if (item = s.GetItemAt a.x a.y) != undefined do 
		(
			sub = item.getSubItemAt a.x a.y
			matName = item.subItems.item[1].text
			
			--//Opens preview image of material
			if (item.SubItems.IndexOf sub) == 0 do (
				print (matName + " » Preview")
				img = (matDir + "\\" +matName +".jpg")
				if doesFileExist img do (
					display (openBitmap img)
				)
			)
			--//Places the material in the material editor
			if (item.SubItems.IndexOf sub) == 1 do (
				print (sub.text + " » Material Editor")
				mtl = (matDir + "\\" +matName +".mat")
				new = #()
				tmp = loadTempMaterialLibrary mtl
				
				if tmp.count > 24 then
				(
					(for i = 1 to 24 do append new tmp[i])
				)else( 
					(for i in tmp do append new i)
					for i = 1 to new.count do (setMeditMaterial activeMeditSlot new[i])
					--for i = 1 to new.count do (setMeditMaterial i new[i])
					--activeSlot = meditmaterials[medit.GetActiveMtlSlot()] = standard()
				)
				max mtledit --//open material editor
			)
		)
	)
	
	on btnGetDir pressed do 
	(
   		matDir = getSavePath caption:"Choose image dir:"
   		if matDir != undefined do (
   			btnGetDir.text = matDir
   			matsArr = getFiles (matDir + "\\*.mat")
   			fnGenerateLst lstMats matsArr
   		)
   	)
	
	on rlMtlManager open do 
	(
   		fnLstSetup lstMats
		
		--//Populate list with items
		if matDir != undefined do (
   			--btnGetDir.text = matDir
   			matsArr = getFiles (matDir + "\\*.mat")
   			fnGenerateLst lstMats matsArr
   		)
   	)
	
	on rlMtlManager resized val do
	(
		rlMtlManager.width = 240
		lstMats.height = (rlMtlManager.height - 50)
	)
)
createDialog rlMtlManager 240 450 style:#(#style_SysMenu, #style_ToolWindow,#style_resizing)

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

it’s good that you learned how to use getitemat/getsubitemat functions… but i like your solution of the using HitTest more than mine.
i’ve checked my old tools, and i see that i moved from using getitemat/getsubitemat to hittest… just forgot it.

I noticed that when i resize the dialog that the dotnet list items disappear?
Why is that?

Alright,
I’ll end up changing it back to then that and update it.

Thanks for your help on this.

Hey guys,
Few questions here about dotNet stuff. I’ve blocked in what I’m after using a collection of resources. Here is what I’m after.

  1. A listbox which allows the drag select multiple items(working)
  2. Custom text/background color for selected items (working)
  3. Double clicking and item changes the text/background color to custom colors to help visually display it being active (not working)
  4. If an item who’s already active is double clicked, it is then reset to the original unactive color scheme. (not working)
  5. Hitting print will cycle through the list of items in the listbox and print the active items (not working)

For number 5 i’m not sure if there is some tag property or something that i can use to track its active state. I figured this would be something worth asking since its one of those things an experience user of dotNet would know the best solution for. Looking to make this as efficient as I possibly can. I’m still picking up and learning the dotNet stuff. Out of curiosity is it possible to change the text size in the listboxes? I’m assuming it is.

Thanks


try(destroydialog ::rlListView)catch()
rollout rlListView "Listview"
(
	-- This is array holds the content for our Listview items. An oversimplification, probably.
	local _itemsArr = for i = 1 to 20 collect "Item "+ i as string
		
	local dnColor = (dotNetClass "System.Drawing.Color").Black
  	local brushes = dotNetClass "System.Drawing.Brushes"
	
	local selColor = (dotNetClass "System.Drawing.Color").fromARGB 51 153 255 -- custom selection color (blue)
  	local lbBackColor = (dotNetClass "System.Drawing.Color").fromARGB 225 225 225 -- light grey
  	local selBrush = dotNetObject "System.Drawing.SolidBrush" selColor -- create a brush for the selection color
	local bgBrush = dotNetObject "System.Drawing.SolidBrush" lbBackColor -- create a brush for the backcolor
	
	--color when active (double clicked)
	local activeColor = (dotNetClass "System.Drawing.Color").fromARGB 0 255 0 -- custom selection color (blue)
	
	dotNetControl dnListBox "System.Windows.Forms.Listbox" pos:[10,10] height:200 -- the ListBox
	button btnActive "Print Active"
	
	fn fnListviewTracksSetup = (
		dnListBox.drawMode = dnListBox.drawMode.OwnerDrawFixed -- fixed seems to be faster than variable, otherwise I can't tell the difference
  		dnListBox.backcolor = lbBackColor
  		dnListBox.SelectionMode = dnListBox.SelectionMode.MultiExtended
  		dnListBox.Items.AddRange _itemsArr
	)
	
	on dnListBox DrawItem arg do --if arg.index == 0 do
	(
			-- we need to draw a background rectangle first
			stringState = arg.state.ToString() -- convert the item state to a string
			
			-- test the pattern of the string to see if it contains 'selected' since it can contain multiple states eg 'Selected, Focus'
			if matchPattern stringState pattern:"*selected*" then arg.Graphics.FillRectangle selBrush arg.bounds -- draw the selection color
			else arg.DrawBackground() -- else draw the background color
		   
			-- define a brush to paint the text color
			brush = if matchPattern stringState pattern:"*selected*" then brushes.White else brushes.Black -- choose black or white based on brightness
			arg.Graphics.DrawString dnListBox.Items.Item[arg.index] arg.font brush arg.bounds.location.x arg.bounds.location.y -- draw the text string
	)
	
	on dnListBox MouseDoubleClick e do 
	(
		dnListBox.SelectedItem.BackColor = activeColor
	)
	
	on btnActive pressed do
	(
		print "Active items..."
	)
	on rlListView open do
	(
		fnListviewTracksSetup()
	)
)
createdialog rlListView 200 270

Page 9 / 18