- -  -  -  - -
         
 

Thumbnail viewer control
Download! >>
Download c# source code >>



Updates
v2.4 - Control now supports multi-selection
v2.3 - Added method to set the thumbnail item's toolTip text
- Thumbnails refresh properly when a new image path is set
- Thumbnails don't accept paths from hidden files (attempt to fix bug in Mac)
- Added right-click event for buttons
v2.2 - Added exit button to thumbnailItems
v2.1 - Fixed bug where extensions are case insensitve.
- Fixed bug when control crashes when removing the last item
- Added clearItems() method
v2.0 - Now drawing images directly on the thumbnail item instead of using the button's backgroundImage
v1.0 - Initial creation of control

About the control
This control was made in C# with the .net framework. It was tested in 3DsMax 2008, but should work fine with 2009 and 2010 versions. Feel free to give feedback about any new features or bugs. If you use it, it'll be great if you drop me a line!

If you're interested in another thumbnail viewer in Max, you may want to check out HitchHiker from LoneRobot.net. It was a big inspiration on creating my own control. Thanks, Pete!

Using the control
This control uses 2 dotnet objects that I've made: dotnetObject:maxCustomControl.thumbnailViewer and dotnetObject:maxCustomControl.thumbnailItem. Like the listView control uses a listViewItem as items, the thumbnailViewer uses a thumbnailItem as items. Multi-selection is also supported. You can hold ctrl and get a collection of thumbnail items. Here are the properties, methods and events for both .net objects:

dotnetObject "maxCustomControl.thumbnailItem"
METHODS Arguments Return value Description/notes
getBackColor1 <System.Drawing.Color> Get the backColor of the button portion
getBackColor2 <System.Drawing.Color> Get the backColor of the label portion
getExitBackColor   <System.Drawing.Color> Get the backColor of the exit button
getFilePath <string> get thumbnail's image path
getLabel <string> Get thumbnail's current text
getLabelColor <System.Drawing.Color> Get the label's color
getOverBackColor <System.Drawing.Color> Get the color when the mouse is over the thumbnail
isSelected <boolean> Returns true if the current item is selected, otherwise it returns false
setBackColor1 <System.Drawing.Color> <void> Set the backColor of the button portion
setBackColor2 <System.Drawing.Color> <void> Set the backColor of the label portion
setExitBackColor <System.Drawing.Color> <void> Set the backColor of the item's exit button
setFilePath <string> <void> Set image path of thumbnail
setLabel <string> <void> Set the text of the thumbnail's label
setLabelColor <System.Drawing.Color> <void> Set the label's color
setOverBackColor <System.Drawing.Color> <void> Set the color when the mouse is over the thumbnail
setToolTip <string> <void> Sets the text for the tool tip that pops up when the mouse is over the item
showExitButton <boolean> <void> Sets the visibility state of the item's exit button

dotnetObject "maxCustomControl.thumbnailViewer"
PROPERTIES Value Description/notes
selectedItems (read-only) <list of thumbnailItems> Returns a list of the current selected items
version (read-only) <float> The control's version

METHODS Arguments Return value Description/notes
addItem <thumbnailItem> <void> Append a thumbnailItem to the control
addRange <array of thumbnailItems> <void> Append an array of thumbnailItems. This works faster than addItem!
clearItems <void> Removes all items from the control all at once
getHighlightColor <System.Drawing.Color> Gets the current color being used for selection highlight
getItem <integer> <thumbnailItem> Get a thumbnailItem by index
getItemsCount <integer> Get the number of items
getItemsPerRow <integer> Get the number of items that appear in a row
removeItem <integer> <void> Remove an item by index
setBackColor <System.Drawing.Color> <void> Set the control's backColor
setHighlightColor <System.Drawing.Color> <void> Sets the highlight color for selected items
setItemsBackColor1 <System.Drawing.Color> <void> Set the button portion backColor to all items
setItemsBackColor2 <System.Drawing.Color> <void> Set the label portion backColor to all items
setItemsExitBackColor <System.Drawing.Color> <void> Set the backColor of all exit buttons
setItemsLabelColor <System.Drawing.Color> <void> Set all items' label color
setItemsOverBackColor <System.Drawing.Color> <void> Set the color when the mouse goes over an item to all items
setItemsPerRow <integer> <void> Set the number of items that appear in a row
showItemsExitButton <boolean> <void> Sets the visibility of all exit buttons

EVENTS Args Description/notes
on thumbEvent arg do (...) filePath <string>, index <integer>, thumbItem <thumbnailItem> Triggered when an item is left-clicked.
on thumbRightClickEvent arg do (...) filePath <string>, index <integer>, thumbItem <thumbnailItem> Triggered when an item is right-clicked.
on exitButtonEvent arg do (...) filePath <string>, index <integer>, thumbItem <thumbnailItem> Triggered whenever the exit button located in the upper-right corner is clicked.

Max example:

(
	thumbnailViewerDll = ( (getDir #maxRoot) + "thumbnailViewer.dll") -- ***Point this path to where you placed the .dll file
	if (doesFileExist thumbnailViewerDll) do
	(
		dotNet.loadAssembly thumbnailViewerDll -- Load assembly before creating control
		
		rollout dialog_thumbnailViewer "Thumbnail Viewer Example"
		(
			dotNetControl thumbnailViewer "maxCustomControl.thumbnailViewer" height:200 width:450 align:#center
			
			on dialog_thumbnailViewer open do
			(
				processStart = timeStamp()
				
				thumbnailViewer.setItemsPerRow 3
				thumbnailViewer.showItemsExitButton true
				
			-- Get images	
				mainDir = @"C:\Users\Jason\Desktop\work\c#_projects\thumbnailImages\" -- ***Set this to a directory to where you want to get images from
				imageFiles = getFiles (mainDir + "*.jpg")
				
			-- Add thumbItems
				thumbItems = #()
				for x in 1 to imageFiles.count do 
				(
				-- Create thumbnailItem and set its properties	
					thumbItem = dotNetObject "maxCustomControl.thumbnailItem"
					thumbItem.setFilepath imageFiles[x]
					fileNameOnly = (getFileNameFile imageFiles[x])
					thumbItem.setLabel fileNameOnly
					thumbItem.setToolTip fileNameOnly
					thumbItem.setBackColor2 ( (dotNetClass "System.Drawing.Color").fromArgb (random 100 255) (random 100 255) (random 100 255))
					append thumbItems thumbItem
				)
				
				thumbnailViewer.addRange thumbItems
				
				processStop = timeStamp()
				format "Took % seconds to initialize % items\n" ( (processStop - processStart) / 1000.0) (thumbnailViewer.getItemsCount())
			)
			
		-- Left-click event on an item
			on thumbnailViewer thumbEvent arg do
			(
				format "Left click: % index, %\n" arg.index arg.filePath
			)
			
		-- Right-click event on an item
			on thumbnailViewer thumbRightClickEvent arg do
			(
				format "Right click: % index, %\n" arg.index arg.filePath
			)
			
		-- Event when pressing 'x' in upper-right corner	
			on thumbnailViewer exitButtonEvent arg do
			(
				removeItem = (queryBox "Warning! Are you sure you want to delete this item?" title:"Warning")
				if (removeItem) do
				(
					thumbnailViewer.removeItem arg.index
				)
			)
		)
		createDialog dialog_thumbnailViewer 500 500
	)
)

Maya example:
Before being able to use this control in Maya, you need to enable .net to work with Python. Download this .zip file. It includes 2 files, clr.pyd and Python.Runtime.dll. Place these 2 files in your maya/bin/ directory. In order to make sure it's working, type import clr in a Python tab. If an error doesn't occur then you're good to go! This has been working for me for Maya 2009 64 bit.

For more info to integrate .net in Python, check out http://pythonnet.sourceforge.net/ and http://feihonghsu.blogspot.com/2008/02/installing-pythonnet-20-alpha-2-on.html

# Import all the modules we need
import sys
import clr
import os
from System.Windows.Forms import *

# Import the thumbnail dll
sys.path.append("C:/Users/Jason/Desktop/") # Point this to the directory where thumbnailViewer.dll is
clr.AddReference("thumbnailViewer")
import maxCustomControl

class thumbnailViewerForm(Form):
	def __init__(self):
		# Create the thumbnail control
		self.thumbControl = maxCustomControl.thumbnailViewer()
		self.thumbControl.Width = 280
		self.thumbControl.Height = 150

		# Populate the control with images
		imageDirectory = "C:/Users/Jason/Desktop/thumbnailImages/"
		if os.path.exists(imageDirectory):
			thumbnailItems = list()		
			files = os.listdir(imageDirectory)
			for f in files:
				fSplit = os.path.splitext(f)
				if (fSplit[1] == ".jpg"):
					thumbItem = maxCustomControl.thumbnailItem()
					thumbItem.setFilepath( (imageDirectory + f) )
					thumbnailItems.append(thumbItem)
	
			self.thumbControl.addRange(thumbnailItems)
		
		# Add event
		self.thumbControl.thumbEvent += self.itemClicked
		
		# Create a form
		self.f = Form()
		self.f.Text = "My form"

		self.f.Controls.Add(self.thumbControl)
		self.f.Show()
		
	# Triggered when an item is clicked
	def itemClicked(self, sender, args):
		print args.Index
		print args.FilePath

formInst = thumbnailViewerForm()