Browsing"DotNet"

Getting the Associated Icon for a filetype in 3dsMax

Aug 18, 2010 by     1 Comment     Posted under: DotNet

Another snippet, just translated into a maxcript-friendly format.

If you need to get the file icon that is associated with a particular type, you can’t get this ordinarily from within a managed environment. There are some great examples on how to use the windows API so these can be added into maxscript by converting them into a string and sending them to the VB/C# compiler from 3dsMax. As always, thanks go to all the great information on the interwebulator, as well as Mike Biddlecombe on CGTalk who figures out all this clever stuff in the first place.

Here is a function that returns a FileIconClass. It has a public method GetIcon(Filename) that returns an image from the file type string specified as the filename argument. It’s useful for treeviews and lists etc.

fn FileTypeIconClass = 
	(
	source = ""
	source += "Imports System.Drawingn"
	source += "Imports Microsoft.VisualBasicn"
	source += "Imports System.Windows.Formsn"
	source += "Public Class FileTypeIconsn"
	source += "Dim cIcons As New System.Collections.Hashtablen"
	source += "Public Declare Auto Function SHGetFileInfo Lib "shell32.dll" (ByVal pszPath As String, ByVal dwFileAttributes As Integer, ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, ByVal uFlags As Integer) As System.IntPtrn"
	source += "Public Const SHGFI_ICON As Integer = &H100n"
	source += "Public Const SHGFI_SMALLICON As Integer = &H1n"
	source += "Structure SHFILEINFOn"
	source += "Public hIcon As System.IntPtrn"
	source += "Public iIcon As Integern"
	source += "Public dwAttributes As Integern"
	source += " Public szDisplayName As Stringn"
	source += " Public szTypeName As Stringn"
	source += "End Structuren"
	source += "Private Function RetrieveShellIcon(ByVal argPath As String) As Imagen"
	source += "Dim mShellFileInfo As SHFILEINFOn"
	source += "Dim mSmallImage As System.IntPtrn"
	source += "Dim mIcon As System.Drawing.Iconn"
	source += "Dim mCompositeImage As  System.Drawing.Imagen"
	source += "mShellFileInfo = New SHFILEINFOn"
	source += "mShellFileInfo.szDisplayName = New String(Strings.Chr(0), 260)n"
	source += "mShellFileInfo.szTypeName = New String(Strings.Chr(0), 80)n"
	source += "mSmallImage = SHGetFileInfo(argPath, 0, mShellFileInfo, System.Runtime.InteropServices.Marshal.SizeOf(mShellFileInfo), SHGFI_ICON Or SHGFI_SMALLICON)n"
	source += "Tryn"
	source += "mIcon = System.Drawing.Icon.FromHandle(mShellFileInfo.hIcon)n"
	source += "mCompositeImage = mIcon.ToBitmapn"
	source +=  "Catch ex As System.Exceptionn"
	source += "mCompositeImage = New Bitmap(16, 16)n"
	source += "End Tryn"
	source += "Return mCompositeImagen"
	source += "End Functionn"
	source += "Public Function GetIcon(ByVal argFilePath As String) As Imagen"
	source += "Dim mFileExtension As String = System.IO.Path.GetExtension(argFilePath)n"
	source += "If cIcons.ContainsKey(mFileExtension) = False Thenn"
	source += "cIcons.Add(mFileExtension, RetrieveShellIcon(argFilePath))n"
	source += "End Ifn"
	source += "Return cIcons(mFileExtension)n"
	source += "End Functionn"
	source += "End Class"

		VBProvider = dotnetobject "Microsoft.VisualBasic.VBCodeProvider"
		compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
		compilerParams.ReferencedAssemblies.add "C:WindowsMicrosoft.NETFrameworkv2.0.50727System.Drawing.dll"	
		compilerParams.ReferencedAssemblies.add "C:WindowsMicrosoft.NETFrameworkv2.0.50727System.Windows.Forms.dll"	
		compilerParams.GenerateInMemory = on
		compilerResults = VBProvider.CompileAssemblyFromSource compilerParams #(source)
		
		-- this is very useful to debug your source code and check for referencing errors
		if (compilerResults.Errors.Count > 0 ) then
		(
			errs = stringstream ""
			for i = 0 to (compilerResults.Errors.Count-1) do
			(
				err = compilerResults.Errors.Item[i]
				format "Error:% Line:% Column:% %n" err.ErrorNumber err.Line 											  
													 err.Column err.ErrorText to:errs 
			)
			MessageBox (errs as string) title: "Errors encountered while compiling VB code"
			return undefined
		) 	
			-- create a dotnetobject from the class 
		return compilerResults.CompiledAssembly.CreateInstance "FileTypeIcons"
	)
	
FileTypeIconClass()

Capturing the viewport according to render resolution.

Aug 18, 2010 by     5 Comments    Posted under: DotNet

Another snippet!

For Rig Studio, I was faced with the problem of providing a method to not only render the view to the design surface, but capture it also. I felt that sometimes a full render wouldn’t be neccesary and users would want the option of performing a viewport capture for the UI background. If you have ever used the command

gw.getViewportDib()

to retrieve a bitmap of the current viewport, you’ll notice that even if you have the safe frames/ livearea turned on, it still returns the whole viewport.

I worked out a function to calculate the correct crop margin to return a viewport bitmap according to the current render resolution.

Fn LR_CaptureRenderAspectViewport  = 
	(
	local ViewCap=undefined			
	local cv = getViewSize()
	local ratio = undefined

           case of 
           ( 
            (cv.x > cv.y):(ratio = cv.y/cv.x)
            (cv.x = cv.y):(ratio = 1)			
            (cv.x < cv.y):(ratio = cv.x/cv.y)
	   )

		VptDib =gw.getViewportDib();
                ViewCap = bitmap renderwidth renderheight color:white
                ViewportRatio = VptDib.width/VptDib.height as float
                RenderRatio = renderwidth/renderheight as float

					case of
					(
					(ViewportRatio <= RenderRatio):(
					CapturetoRenderHeightRatio =VptDib.width/RenderRatio as float
					TopEdge = ((VptDib.Height-CapturetoRenderHeightRatio)/ 2.0) as integer
					FullViewcap = bitmap vptdib.width CapturetoRenderHeightRatio color:white
					pasteBitmap VptDib FullViewcap (box2 0 TopEdge VptDib.width VptDib.height) [0,0]
					Copy FullViewcap ViewCap)
					(ViewportRatio > RenderRatio):(
					CapturetoRenderHeightRatio =VptDib.height*RenderRatio as float
					LeftEdge = ((VptDib.width-CapturetoRenderHeightRatio)/ 2.0) as integer
					FullViewcap = bitmap CapturetoRenderHeightRatio VptDib.height color:white
					pasteBitmap VptDib FullViewcap (box2 LeftEdge 0 VptDib.width VptDib.height) [0,0]
					Copy FullViewcap ViewCap)
					default:()
					)
                close VptDib
		gc()

                if viewcap != undefined then (setclipboardbitmap viewcap;close ViewCap;return true)else(return false)
	)

	tempbmp = LR_CaptureRenderAspectViewport()
	display (getclipboardbitmap())

I hope this is useful.

No Swear Box Required

Aug 13, 2010 by     No Comments    Posted under: DotNet

chunky

 

Normally, colourful language should be left in the snooker hall, but when it comes to max, there’s nothing more potty-mouth inducing when a custom UI doesn’t sit with the rest of the application. In my previous post about Rig Studio (my IDE for generating selection dialogs) I talked about using the maxtoolbar renderer to give the UI a more cohesive look. The problem with this is that although the menus are now similar in colour to the 3dsMax menus, the maxtoolbar obviously inherits from the managedrendermode. This means, that in my visually styled version of windows, the toolbar buttons end up being rendered rounded. While this doesn’t look out of place in other programs, max has has used it’s clunky square thing to good effect for the last 20 years, so it’s not about to stop soon. Also, as much as the menu are now styled correctly, you still have to manually colour the background and text according to your UI scheme.

You can control the overall look and feel of a toolstrip by specifiying the renderer property. There are four types,

System

Professional

ManagedRenderMode

Custom

You can see the differences between the Professional and Managed renderers below.

Toolstrip-Renderer

The professional renderer is more like max’s main toolbar. Unfortunately, the managed services version seems always give the manager render mode ‘look’ to toolstrip items. This is because it is inherited from the SystemRenderer for the toolstrip.

Examining the Renderer’s Constructor

If you examine the Professional toolstrip rendererer constructor, you will find that it is overloaded. This means that there multiple options to call (like having the same function with different arguments) when you create a new instance of it.

tsr

You’ll see from the constructor that it has an option to pass a dotnetobject into the New() constructor. The New() constructor is what is run whenever you create a dotnetobject -so when you call dotnetobject from a maxscript, you are calling this constructor. 

You can see that one of the methods is asking for a “ProfessionalColorTable”. This is a class that controls how the colours are applied by the toolstrip renderer. So by specifiying a different ColorTable, you can alter the look of a toolstrip. Note that you can’t just create a ColorTable class and change the properties. It does have them, but it is a read only class. In order to create a new one, you have to inherit this class and override the paint methods that you want to alter.

The initial setup of this would be as follows (assume that you have created your toolstrip and this in in the on open handler) –

Pct = dotnetobject "System.Windows.Forms.ProfessionalColorTable"
TheUltimateToolStrip.Renderer = dotnetobject "ToolStripProfessionalRenderer"

As it stands, all you would have done here is to create a toolstrip the same as if you had set the renderer property to Professional.

So, by building an inherited colortable, wouldn’t it be better to automatically decide within the class what UI colours you are running and generate the toolbar from that?

In a previous post, I worked out a method for using maxscript calls to the colorman interface from the dotnetassembly to get the max UI colours. After this post, Yannick Puech contacted me and pointed me to the CUIUpdater class in managedservices. I knew max must have had something like this, but hadn’t figured it out until now. Thanks Yannick!

Using CUIUpdater

You can’t create an instance of CUIUpdater via dotnetobject. You have to call the getinstance function instead.

dotnetcolorman = (dotnetclass "Managedservices.cuiupdater").getinstance()
--dotNetObject:ManagedServices.CuiUpdater
showmethods dotnetcolorman
--   .GetButtonDarkShadow()
--   .GetButtonLightShadow()
--   .GetButtonPressedColor()
--   .GetColor aColorIndex
--   .GetControlColor()
--   .GetEditControlColor()
--   .[static]GetInstance()
--   .GetMaxColor id
--   .GetTextColor()

As you can see, there are some useful things in there to call from an assembly.

dotnetcolorman.GetControlColor()
-- dotNetObject:System.Drawing.Color
-- this is the colour of the interface
dotnetcolorman.GetTextColor()
-- dotNetObject:System.Drawing.Color
-- the is colour of the text (if you hadn’t already guessed)

Overiding the Inherited ColorTable class

Now we have this dotnetmethod to get the max UI scheme, we can build the ColorTable. But before we do that, we will need to inherit the toolstrip renderer too before we can use it. We are going to keep much of the look and feel of the professional renderer but  we do need to change a few base rendering options in order to make it sit pretty in max.

Take a look at the following class –

Public Class MaxToolStripRenderer
    Inherits ToolStripProfessionalRenderer

    Private MaxColors As ManagedServices.CuiUpdater = ManagedServices.CuiUpdater.GetInstance()

    Public Sub New()
        MyBase.New()
    End Sub

    Public Sub New(ByVal maxcolortable As ProfessionalColorTable)
        MyBase.New(maxcolortable)
    End Sub

    Protected Overrides Sub OnRenderToolStripBorder(ByVal e As System.Windows.Forms.ToolStripRenderEventArgs)
        'Do nothing
    End Sub

    Protected Overrides Sub OnRenderArrow(ByVal e As System.Windows.Forms.ToolStripArrowRenderEventArgs)
        e.ArrowColor = MaxColors.GetTextColor
        MyBase.OnRenderArrow(e)
    End Sub

    Protected Overrides Sub OnRenderItemText(ByVal e As ToolStripItemTextRenderEventArgs)
        e.TextColor = MaxColors.GetTextColor
        MyBase.OnRenderItemText(e)
    End Sub
End Class

You can see on the first line that we are inhertiing the Professional render class. Then we have a private variable that stores our instance of max’s CUI updater. We will use this to good effect. We also  have added the two constructors, allowing us to pass a proffesionalcolortable. Even if we inherit the professionalcolortable to build our own, since it is inherited from this base class, there wont be a casting error. This is evident when you examine the new constructor – we call the base class constructor from the inherited class when specifying the colortable. This is the only way of specifying a colortable with a toolstrip, as (if you remember) the colortable property is read-only.

The final three subs override the toolstrip renderer so that we can customise the general look of the toolstrip. OnRenderToolstripBorder was covered in the previous post, which just removes the unsightly border.

OnRenderArrow and OnRenderItemText both use the CUIUpdater to retrieve the max text colour and draw the objects correctly. The arrow is for when there is a sub menu on a dropdown menu, and the itemtext covers all text on the toolstrip. You can of course change individual items to anything you want, but this is just to control the initial styling.

Now, on to the color table – Watch out, this is a biggee..

Public Class MaxUIProfessionalColorTable
    Inherits ProfessionalColorTable
    Private MaxColors As ManagedServices.CuiUpdater = ManagedServices.CuiUpdater.GetInstance()

    Public Overrides ReadOnly Property ButtonCheckedGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ButtonCheckedGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ButtonCheckedGradientMiddle() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ButtonPressedGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetButtonPressedColor
        End Get
    End Property

    Public Overrides ReadOnly Property ButtonPressedGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetButtonPressedColor
        End Get
    End Property

    Public Overrides ReadOnly Property ButtonPressedGradientMiddle() As System.Drawing.Color
        Get
            Return MaxColors.GetButtonPressedColor
        End Get
    End Property

    Public Overrides ReadOnly Property ButtonSelectedBorder() As System.Drawing.Color
        Get
            Return (MaxColors.GetButtonPressedColor())
        End Get
    End Property

    Public Overrides ReadOnly Property ButtonSelectedGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetButtonPressedColor
        End Get
    End Property

    Public Overrides ReadOnly Property ButtonSelectedGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetButtonPressedColor
        End Get
    End Property

    Public Overrides ReadOnly Property ButtonSelectedGradientMiddle() As System.Drawing.Color
        Get
            Return MaxColors.GetButtonPressedColor
        End Get
    End Property

    Public Overrides ReadOnly Property CheckBackground() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property GripDark() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property GripLight() As System.Drawing.Color
        Get
            Return MaxColors.GetTextColor
        End Get
    End Property

    Public Overrides ReadOnly Property ImageMarginGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ImageMarginGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ImageMarginGradientMiddle() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ImageMarginRevealedGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ImageMarginRevealedGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ImageMarginRevealedGradientMiddle() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property MenuBorder() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property MenuItemBorder() As System.Drawing.Color
        Get
            Return Color.FromArgb(174, 207, 247)
        End Get
    End Property

    Public Overrides ReadOnly Property MenuItemPressedGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetButtonPressedColor
        End Get
    End Property

    Public Overrides ReadOnly Property MenuItemPressedGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetButtonPressedColor
        End Get
    End Property

    Public Overrides ReadOnly Property MenuItemPressedGradientMiddle() As System.Drawing.Color
        Get
            Return MaxColors.GetButtonPressedColor
        End Get
    End Property

    Public Overrides ReadOnly Property MenuItemSelected() As System.Drawing.Color
        Get
            Return MaxColors.GetButtonPressedColor
        End Get
    End Property

    Public Overrides ReadOnly Property MenuItemSelectedGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetButtonPressedColor
        End Get
    End Property

    Public Overrides ReadOnly Property MenuItemSelectedGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetButtonPressedColor
        End Get
    End Property

    Public Overrides ReadOnly Property MenuStripGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property MenuStripGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property OverflowButtonGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetTextColor
        End Get
    End Property

    Public Overrides ReadOnly Property OverflowButtonGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetTextColor
        End Get
    End Property

    Public Overrides ReadOnly Property OverflowButtonGradientMiddle() As System.Drawing.Color
        Get
            Return MaxColors.GetTextColor
        End Get
    End Property

    Public Overrides ReadOnly Property RaftingContainerGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property RaftingContainerGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property SeparatorDark() As System.Drawing.Color
        Get
            Return MaxColors.GetTextColor
        End Get
    End Property

    Public Overrides ReadOnly Property SeparatorLight() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ToolStripBorder() As System.Drawing.Color
        Get
            Return MaxColors.GetTextColor
        End Get
    End Property


    Public Overrides ReadOnly Property ToolStripGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ToolStripGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ToolStripGradientMiddle() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ToolStripContentPanelGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ToolStripContentPanelGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get

    End Property

    Public Overrides ReadOnly Property ToolStripDropDownBackground() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property StatusStripGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property StatusStripGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

    Public Overrides ReadOnly Property ToolStripPanelGradientBegin() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property
    Public Overrides ReadOnly Property ToolStripPanelGradientEnd() As System.Drawing.Color
        Get
            Return MaxColors.GetControlColor
        End Get
    End Property

End Class

There are around 50 odd properties that you can override in this class, and you could probably get away with a much smaller implementation. This mainly makes sure that the menus are shaded correctly. I have gone for a flat style toolstrip with this colortable, It wasn’t important to me to have menus exactly like the 3dsmax main menus, just enough so that it looked swish and part of the package.

Compiling this into a new dll and using the method here –

Yes, not exactly interesting i know but the toolstrip has correctly identified the MaxUI scheme and looks rather swish.

If you noticed my class definition above, you can see that is to be used in Rig Studio. The great thing is that because of the colortable, the application looks right regardless of the scheme. Check the video, I run the app twice in the same session on max, changing the ui color inbetween.

 

 

With a little customisation, it is pretty easy to make a colortable that you can use that looks identical to the 3dsMax menu bar – this has a few more colours because there is a gradient effect over much of it.

I hope this has been useful, as much as it feels like it is a pain to have to go to extra lengths to set this up, I always feel it is better to handle this in the assembly rather than max, as it avoids any redraw issues between when the constructor is called and the inevitable flash on load. It means that your maxscript code is reduced.

I haven’t compiled this into a separate assembly as I use it primarily in Rig Studio, but if you need it, just let me know.


					

That’s Shallot

Aug 11, 2010 by     2 Comments    Posted under: DotNet

If you’ve got lots of different layers in the layer manager, its fine when you are in the actual file, but when you start having sets, characters and props in the same scene, it is sometimes difficult to navigate the interface. This is another snippet with a macro for adding a prefix to selected layers to group them so they are together when sorted alphabetically. Think of it like a sh*te version of The Onion, maybe I should call it The Shallot.

 Layer unordered

prefix dialog

 macroScript AddLayerPrefix
  category:"LoneRobot"
  toolTip:"Add Prefix to Selected Layers"
  buttontext:"LayerPrefix"

(
	local LR_LayerPrefixRO
	local clsColor = DotNetClass "System.Drawing.Color"
	local clsBorder =dotNetClass "System.Windows.Forms.BorderStyle"
	
	fn initdotnetcontrols =
	(	
	LR_LayerPrefixRO.layerlbl.text = "Select layers"	
	LR_LayerPrefixRO.layerlbl.forecolor = clsColor.GhostWhite
	LR_LayerPrefixRO.layerlbl.backcolor = clsColor.FromARGB 51 83 102
	LR_LayerPrefixRO.layerlbl.borderstyle =	clsborder.fixedsingle 
	)
	
	fn RefreshLayerlist =
	(
	LayersStringArray=#()
	LayerListInterfaces = #()
	NumberofLayers = LayerManager.count	
	LayerListInterfaces = for i = 1 to numberoflayers collect LayerManager.getLayer i
	
	for i in LayerListInterfaces do
		(
		if i != undefined then 
			(
			append LayersStringArray i.name
			)
		)
		
	LR_LayerPrefixRO.lbxLayers.items = LayersStringArray
	)
	
	fn AddLayerPrefix StrName =
	(
			local SelectedLayers = LR_LayerPrefixRO.lbxLayers.selection
			if true then 
			(	
				for i in selectedlayers do
					(
					layer = layermanager.getLayer i
					local Layername = layer.name
					Layer.setName (StrName + " " + Layername)
					)			
			RefreshLayerlist()
			)
	)
	
	fn RemoveLayerPrefix =
	(
			local SelectedLayers = LR_LayerPrefixRO.lbxLayers.selection
		
		--	if querybox "Are you sure you want to remove the prefix of the selected layers?" title:"Layer Prefix"  then 
			(	
				for i in selectedlayers do
					(
					layer = layermanager.getLayer i
					local Layername = dotnetobject "system.string" layer.name							
					StrExtentInt = Layername.LastIndexOf "}"
						
					if StrExtentInt > -1 then
						(
						Local TrimmedStr = Layername.Remove 0 (StrExtentInt+1)		
						layer.setName (trimLeft TrimmedStr) 
						)
				
					)
			)			
			RefreshLayerlist()			
	)
	
	fn isLayerNameValid strName =
	(
		strName = trimleft strName 
		strName = trimright strName 
		--assumes that the layer name is valid, flag to false if not
		local boolIsLayerNameValid = true
		
		--checks for an empty layer name:
		if (strName == "") do boolIsLayerNameValid = false
		
		--checks for existing name in the layers list:
		if (layermanager.getlayerfromname strName) != undefined do boolIsLayerNameValid = false
		--returns the flag
		boolIsLayerNameValid
	
	)

	rollout vRollout "Enter New Layer Prefix" width:205 height:55
	(
		edittext vEdittext "Prefix" pos:[6,4] width:195 height:17 --LOC_NOTES: localize this
		button vButtonOK "OK" pos:[37,27] width:65 height:21 --LOC_NOTES: localize this
		button vButtonCancel "Cancel" pos:[134,27] width:65 height:21 --LOC_NOTES: localize this

		on vRollout open do
		(	
		setfocus vEdittext
		)
		on vEdittext entered arg do
		(
			setfocus vButtonOK 
		)--end vEdittext entered arg
		on vEdittext changed arg do
		(
			vNameLayer = arg			
			if (isLayerNameValid vNameLayer)  --prevent layers with empty names or leading spaces from being created: pfbreton 13 aout 2003
			then vButtonOK.enabled = true
			else vButtonOK.enabled = false
		)
		on vButtonOK pressed do
		(
			AddLayerPrefix  ("{"+vEdittext.text+"}")			
			destroyDialog vRollout 
		)
		on vButtonCancel pressed do
		(
			destroyDialog vRollout
		)
	)
	

rollout LR_LayerPrefixRO "Add Layer Prefix" width:365 height:511
(
	multiListBox lbxLayers "" pos:[-1,32] width:370 height:34
	dotNetControl layerlbl "label" pos:[4,2] width:335 height:30
	button AddSetPrefix "{SET} Prefix" pos:[113,480] width:77 height:26 border:false
	button btnrefresh "R" pos:[341,2] width:20 height:30 border:false tooltip:"Refresh List"
	button AddPropPrefix "{PROP} Prefix" pos:[191,480] width:84 height:26 border:false
	button btnRemovePrefix "Remove Prefix" pos:[275,480] width:86 height:26 border:false
	button AddPrefix "Add Prefix" pos:[4,480] width:105 height:26 border:false
		
	on LR_LayerPrefixRO open do
	(
		initdotnetcontrols()		
		RefreshLayerlist()	
	)
	on AddSetPrefix pressed do
		AddLayerPrefix "{SET}"
	on btnrefresh pressed do
		RefreshLayerlist()
	on AddPropPrefix pressed do
		AddLayerPrefix "{PROP}"
	on btnRemovePrefix pressed do
		RemoveLayerPrefix()
	on AddPrefix pressed do
	(
		createdialog vRollout
	)
)


createdialog LR_LayerPrefixRO  style:#(#style_toolwindow, #style_sysmenu)


)

prefixed layer manager

Get Shirty

Aug 11, 2010 by     No Comments    Posted under: DotNet

A while back there was a competition on the wonderful tech site http://tech-artists.org. Rob Galankis, Webmaster of the geek portal wanted a few designs to be made into t-shirts to give out at GDC. To cut a long story short, such is the 3D community’s affection for the humble teapot, that Piers Morgan could stick one on his head and suddenly become the nation’s sweetheart. Anyhoo, my geek inspired Teapot-shirt won and was made into a stylish piece of menswear.

tshirt logo

If you fancied owning one, head over to tech-artists.org and follow the links to the t-shirts. There are some other great designs from the users of the site, not just mine.

http://techart.spreadshirt.com/

They are reasonably priced and will make you the envy of everyone, except girls.

Just watch if you’re in the UK that you don’t get hammered by customs, like I did. ack!

Oddly enough, since I’m a fan of t-shirts generally, I had thought about making some LoneRobot inspired t-shirts a while back. If you think this is a good idea and you’d like to be seen in a bit of robot sartorial elegance, then please let me know through the contact at the top of the page or this post. If enough people express an interest, perhaps I can get something set up.