I’m very happy to release VME 1.2b. Download it from the first post in this thread.
This is an upgrade from 1.2, and fixes some issues. Here's what's new:
1. nodes will inherit the mouse position when dropped in the front viewport.
2. newly created rollouts attempt to inherit their old rollout's position, for easy development.
3. imgTags are now supported, and will automatically write up and over state code based on the pngs you choose in the imgtag node's cas.
4. the nodes have been redesigned to look closer to their maxscript counterpart.
5. processing time is now reported to the listener window for every build.
- PSD files are now supplied along with the script’s .PNG files, so you can see how the script’s UI was created and formatted.
Here's what the tool looks like now:
[img] http://www.garrickcampsey.com/media/VMEv1p2bUI.jpg [/img]
Here's some visuals regarding ImgTags, the newest and probably most powerful addition to VME:
[img] http://www.garrickcampsey.com/media/VMEv1p2bimgTags.jpg [/img]
And here is a test on the ImgTag node. I've used a quick gradient as a test image for the up and over states. [i]You[/i] can use any images you want. The width and length of the ImgTag node doesn't have to match the .png dimensions. Max will stretch and squash the .png data to fit the node's width and length values.
[img] http://www.garrickcampsey.com/media/VMEv1p2boverTest.jpg [/img]
I hope to write code that parses .PSD files for layer names and content. Then uses the .PSD's width and height to create a rollout with equal width and height. Layer naming conventions could be used to allow for automatic creation of imgTag nodes, with up and over states. This would build a bridge between photoshop and max that allows for rapid development of a script's UI.
*edit 2011.03.17 – the BitmapLayerManager can parse PSDs, so I’m going to leverage that for VME. I was going to code a PSD parser (based on alternativa game’s java psd parser) but there’s really no need to re-invent the wheel.
There’s lots planned.
I am very happy to release VME version 1.2c, which has been in development for the past few days. This version converts PSD files into MS files. You can download this version from the first post in this thread.
VME 1.2c is becoming more of a UI designer's tool. Now, VME allows a designer to quickly turn a PSD file into a working MS file, with all the layers properly aligned and converted into image tags. Now you can go from PSD to MS file with a single button click, and the wait is around 4 - 10 seconds for processing, depending on the complexity of the PSD file. VME hopes to make iterating over a UI design easier and faster, and also frees a designer from digging into the code just to see a design "in context" (running as a script in max).
To access the PSD import dialog, hold shift and click on 'Build Rollout'.
[b]Naming Conventions[/b]
Basically, there are 3 rules:
1. You must have a layer named "background" that is the full size of the PSD. Photoshop does this by default - so don't delete the "background" layer, and don't name other layers "background".
2. If you want a layer to be a button (imgTag), then add "_BTN" to the layer name.
3. If you want a button to have an 'over state' (when the mouse pointer is hovering over the button), then add "_OVER" to the layer name. These layers need to match their "_BTN" counterparts in width and height and position.
If this seems complicated, trust me - it's not. Here are two examples:
1. The 'matrixy' VME ui design from earlier:
[img] http://www.garrickcampsey.com/vme/VMEv1p2c-NamingConventionsEx1.jpg [/img]
2. The 'clu' VME ui design from earlier:
[img] http://www.garrickcampsey.com/vme/VMEv1p2c-NamingConventionsEx2.jpg [/img]
The use of folders to organize layers will not affect VMEs ability to import the PSD, so nest away.
Here are the results of importing those two PSDs:
[img] http://www.garrickcampsey.com/vme/VMEv1p2c-MatrixBuild.jpg [/img]
The 'compile nodes' imgTag is showing it's 'over state'. Note how the PSD has been interpreted into VME's UI nodes. Here is the 'clu' PSD imported:
[img] http://www.garrickcampsey.com/vme/VMEv1p2c-CluBuild.jpg [/img]
VME also reports it's progress and actions to the listener window. Here are the 'logs' of the two PSDs imported:
Welcome to The Viewport Maxscript Editor...
Working on copy:C:\Documents and Settings\Administrator\Desktop\vme DEV\vme1p4\vmeTest-matrixTemp.psd
Extracting 24 layers from: C:\Documents and Settings\Administrator\Desktop\vme DEV\vme1p4\vmeTest-matrixTemp.psd
Saving layers to \scripts\myVME_IMAGES\
Found '_BTN': compileNodes_BTN
Extracting compileNodes_BTN to: \scripts\myVME_IMAGES\compileNodes_BTN.png
Image width:233, height:49
X, Y offset: [0,0,-380]
Found '_BTN': close_BTN
Extracting close_BTN to: \scripts\myVME_IMAGES\close_BTN.png
Image width:51, height:55
X, Y offset: [182,0,0]
Found '_BTN': quest_BTN
Extracting quest_BTN to: \scripts\myVME_IMAGES\quest_BTN.png
Image width:20, height:55
X, Y offset: [162,0,0]
Found '_BTN': title_BTN
Extracting title_BTN to: \scripts\myVME_IMAGES itle_BTN.png
Image width:162, height:55
X, Y offset: [0,0,0]
Found '_BTN': content_BTN
Extracting content_BTN to: \scripts\myVME_IMAGES\content_BTN.png
Image width:233, height:266
X, Y offset: [0,0,-55]
Found '_BTN': bottom_BTN
Extracting bottom_BTN to: \scripts\myVME_IMAGES\bottom_BTN.png
Image width:233, height:17
X, Y offset: [0,0,-429]
Found '_BTN': states_BTN
Extracting states_BTN to: \scripts\myVME_IMAGES\states_BTN.png
Image width:114, height:25
X, Y offset: [119,0,-321]
Found '_BTN': vals_BTN
Extracting vals_BTN to: \scripts\myVME_IMAGES\vals_BTN.png
Image width:55, height:25
X, Y offset: [64,0,-321]
Found '_BTN': ui_BTN
Extracting ui_BTN to: \scripts\myVME_IMAGES\ui_BTN.png
Image width:64, height:25
X, Y offset: [0,0,-321]
Found '_BTN': plus_BTN
Extracting plus_BTN to: \scripts\myVME_IMAGES\plus_BTN.png
Image width:61, height:23
X, Y offset: [172,0,-346]
Found '_BTN': prog_BTN
Extracting prog_BTN to: \scripts\myVME_IMAGES\prog_BTN.png
Image width:233, height:11
X, Y offset: [0,0,-369]
Found '_BTN': save_BTN
Extracting save_BTN to: \scripts\myVME_IMAGES\save_BTN.png
Image width:172, height:23
X, Y offset: [0,0,-346]
Found '_OVER': compileNodes_OVER
Matched: compileNodes to: compileNodes
Extracting compileNodes_OVER to: \scripts\myVME_IMAGES\compileNodes_OVER.png
Found '_OVER': close_OVER
Matched: close to: close
Extracting close_OVER to: \scripts\myVME_IMAGES\close_OVER.png
Found '_OVER': quest_OVER
Matched: quest to: quest
Extracting quest_OVER to: \scripts\myVME_IMAGES\quest_OVER.png
Found '_OVER': title_OVER
Matched: title to: title
Extracting title_OVER to: \scripts\myVME_IMAGES itle_OVER.png
Found '_OVER': content_OVER
Matched: content to: content
Extracting content_OVER to: \scripts\myVME_IMAGES\content_OVER.png
Found '_OVER': states_OVER
Matched: states to: states
Extracting states_OVER to: \scripts\myVME_IMAGES\states_OVER.png
Found '_OVER': vals_OVER
Matched: vals to: vals
Extracting vals_OVER to: \scripts\myVME_IMAGES\vals_OVER.png
Found '_OVER': ui_OVER
Matched: ui to: ui
Extracting ui_OVER to: \scripts\myVME_IMAGES\ui_OVER.png
Found '_OVER': plus_OVER
Matched: plus to: plus
Extracting plus_OVER to: \scripts\myVME_IMAGES\plus_OVER.png
Found '_OVER': prog_OVER
Matched: prog to: prog
Extracting prog_OVER to: \scripts\myVME_IMAGES\prog_OVER.png
Found '_OVER': save_OVER
Matched: save to: save
Extracting save_OVER to: \scripts\myVME_IMAGES\save_OVER.png
Copy Deleted.
PSD parsed in 4906 milliseconds.
Script(s) written in 296 milliseconds.
‘clu’ PSD log:
Welcome to The Viewport Maxscript Editor...
Working on copy:C:\Documents and Settings\Administrator\Desktop\vme DEV\vme1p4\vmeTest-cluTemp.psd
Extracting 33 layers from: C:\Documents and Settings\Administrator\Desktop\vme DEV\vme1p4\vmeTest-cluTemp.psd
Saving layers to \scripts\myVME_IMAGES\
Found '_BTN': bottom_BTN
Extracting bottom_BTN to: \scripts\myVME_IMAGES\bottom_BTN.png
Image width:233, height:37
X, Y offset: [0,0,-409]
Found '_BTN': divider_BTN
Extracting divider_BTN to: \scripts\myVME_IMAGES\divider_BTN.png
Image width:233, height:14
X, Y offset: [0,0,-315]
Found '_BTN': build_BTN
Extracting build_BTN to: \scripts\myVME_IMAGES\build_BTN.png
Image width:233, height:43
X, Y offset: [0,0,-366]
Found '_BTN': prog_BTN
Extracting prog_BTN to: \scripts\myVME_IMAGES\prog_BTN.png
Image width:233, height:11
X, Y offset: [0,0,-355]
Found '_BTN': plus_BTN
Extracting plus_BTN to: \scripts\myVME_IMAGES\plus_BTN.png
Image width:62, height:26
X, Y offset: [171,0,-329]
Found '_BTN': fileName_BTN
Extracting fileName_BTN to: \scripts\myVME_IMAGES\fileName_BTN.png
Image width:171, height:26
X, Y offset: [0,0,-329]
Found '_BTN': rec_BTN
Extracting rec_BTN to: \scripts\myVME_IMAGES\rec_BTN.png
Image width:233, height:24
X, Y offset: [0,0,-46]
Found '_BTN': close_BTN
Extracting close_BTN to: \scripts\myVME_IMAGES\close_BTN.png
Image width:50, height:46
X, Y offset: [183,0,0]
Found '_BTN': quest_BTN
Extracting quest_BTN to: \scripts\myVME_IMAGES\quest_BTN.png
Image width:28, height:46
X, Y offset: [155,0,0]
Found '_BTN': title_BTN
Extracting title_BTN to: \scripts\myVME_IMAGES itle_BTN.png
Image width:155, height:46
X, Y offset: [0,0,0]
Found '_BTN': row6_BTN
Extracting row6_BTN to: \scripts\myVME_IMAGES\row6_BTN.png
Image width:233, height:43
X, Y offset: [0,0,-272]
Found '_BTN': row5_BTN
Extracting row5_BTN to: \scripts\myVME_IMAGES\row5_BTN.png
Image width:233, height:40
X, Y offset: [0,0,-232]
Found '_BTN': row4_BTN
Extracting row4_BTN to: \scripts\myVME_IMAGES\row4_BTN.png
Image width:233, height:40
X, Y offset: [0,0,-192]
Found '_BTN': row3_BTN
Extracting row3_BTN to: \scripts\myVME_IMAGES\row3_BTN.png
Image width:233, height:39
X, Y offset: [0,0,-153]
Found '_BTN': row2_BTN
Extracting row2_BTN to: \scripts\myVME_IMAGES\row2_BTN.png
Image width:233, height:41
X, Y offset: [0,0,-112]
Found '_BTN': row1_BTN
Extracting row1_BTN to: \scripts\myVME_IMAGES\row1_BTN.png
Image width:233, height:42
X, Y offset: [0,0,-70]
Found '_OVER': bottom_OVER
Matched: bottom to: bottom
Extracting bottom_OVER to: \scripts\myVME_IMAGES\bottom_OVER.png
Found '_OVER': divider_OVER
Matched: divider to: divider
Extracting divider_OVER to: \scripts\myVME_IMAGES\divider_OVER.png
Found '_OVER': build_OVER
Matched: build to: build
Extracting build_OVER to: \scripts\myVME_IMAGES\build_OVER.png
Found '_OVER': prog_OVER
Matched: prog to: prog
Extracting prog_OVER to: \scripts\myVME_IMAGES\prog_OVER.png
Found '_OVER': plus_OVER
Matched: plus to: plus
Extracting plus_OVER to: \scripts\myVME_IMAGES\plus_OVER.png
Found '_OVER': fileName_OVER
Matched: fileName to: fileName
Extracting fileName_OVER to: \scripts\myVME_IMAGES\fileName_OVER.png
Found '_OVER': rec_OVER
Matched: rec to: rec
Extracting rec_OVER to: \scripts\myVME_IMAGES\rec_OVER.png
Found '_OVER': close_OVER
Matched: close to: close
Extracting close_OVER to: \scripts\myVME_IMAGES\close_OVER.png
Found '_OVER': quest_OVER
Matched: quest to: quest
Extracting quest_OVER to: \scripts\myVME_IMAGES\quest_OVER.png
Found '_OVER': title_OVER
Matched: title to: title
Extracting title_OVER to: \scripts\myVME_IMAGES itle_OVER.png
Found '_OVER': row6_OVER
Matched: row6 to: row6
Extracting row6_OVER to: \scripts\myVME_IMAGES\row6_OVER.png
Found '_OVER': row5_OVER
Matched: row5 to: row5
Extracting row5_OVER to: \scripts\myVME_IMAGES\row5_OVER.png
Found '_OVER': row4_OVER
Matched: row4 to: row4
Extracting row4_OVER to: \scripts\myVME_IMAGES\row4_OVER.png
Found '_OVER': row3_OVER
Matched: row3 to: row3
Extracting row3_OVER to: \scripts\myVME_IMAGES\row3_OVER.png
Found '_OVER': row2_OVER
Matched: row2 to: row2
Extracting row2_OVER to: \scripts\myVME_IMAGES\row2_OVER.png
Found '_OVER': row1_OVER
Matched: row1 to: row1
Extracting row1_OVER to: \scripts\myVME_IMAGES\row1_OVER.png
Copy Deleted.
PSD parsed in 6313 milliseconds.
Script(s) written in 390 milliseconds.
And on a different note, I think I’m going to shelf the plans to build node based maxscripting.
After careful consideration, I have come to agree with denisT. I also fear that node based maxscripting would introduce it’s own set of limitations and inconsistencies.
TheGrak! This is awesome! I had a similar idea a couple of weeks ago.
Not sure how you are currently doing it, but my approach was to use the slice tool to slice the PSD and then use the “Save for web” function which allows the different slices to be exported separatly as well as a css file that I would parse later on in order to create the rollout.
Where can we get the latest version!
Keep up the great work man!
@ Norman3D: Thanks man!
Not sure how you are currently doing it, but my approach was to use the slice tool to slice the PSD and then use the “Save for web” function which allows the different slices to be exported separatly as well as a css file that I would parse later on in order to create the rollout.
This is how VME processes PSDs: using the bitmapLayerManager, VME checks for naming conventions, and upon finding a layer with a proper naming convention, extracts that layer and saves it as a PNG file. Then VME creates an imgTag node, then loads that PNG’s filename into the imgTag’s custom attributes. Then the imgTags are gathered and written to a .ms file.
I didn’t want people to have to slice images and save them individually, instead I wanted the script to do that for them. VME currently has an algorithm that determines their x and y position relative to the PSD background layer, which simulates what photoshop does when it exports that CSS. Basically VME does the same thing, but with a point3 value instead of a point2 value (cause the nodes are in 3d space). But, the processes are very similar.
Where can we get the latest version!
From the first post in this thread. You can find all previous releases there as well.
This looks great, can’t wait to test it out. PSD support is a great idea.
I have two suggestions I thought of when I was looking at the screenshots.
1- You can add an option to convert the images into script itself, so that there are no png files to take care of. (Using the Bitmap2Script code I wrote a few days back)
2- You can add an option to display boxes instead of rectangles. If you texturemap the boxes with these images, it will look exactly like the final UI. (If the UI uses no images you can texturemap a default image that looks like default UI)
Now I guess you are adding the handlers. This is going to be a useful script. If you release it on scriptspot, thousands of users will be benefited.
1- You can add an option to convert the images into script itself, so that there are no png files to take care of. (Using the Bitmap2Script code I wrote a few days back)
I am undecided on if I want to include the images in the .ms file.
On one hand, supplying the images as .[PNGs]( http://en.wikipedia.org/wiki/Portable_Network_Graphics) means the user gets 100% quality with [lossless]( http://en.wikipedia.org/wiki/Lossless_data_compression) [compression]( http://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch). On the other hand, supplying the images as an array of bitmap data means the images are packaged with the .ms file. The downside I see to this is filesize bloat. If you compare an arbitrary PNG file to it's maxscript bitmap array counterpart, the PNG file is smaller - and they describe exactly the same data! So the tradeoff is between 'packaged, but bloated', and 'unpackaged, but compressed'... If one day I decide to include the bitmap data as a part of the script that is written, I'll use this code snippet:
(
b=selectbitmap() -- open image file browser
[left] bname=[color=maroon]"bitmap_"[/color]+(getfilenamefile b.filename) [font=Courier New]-- build name from filename
w=b.width [/font][font=Courier New]-- get properties of bitmap
h=b.height
format [/font][color=maroon]"----------
fn load_% = (
"[/color] bname [font=Courier New]-- start defining function
format [/font][color=maroon]"local %=bitmap % %
" [/color]bname w h [font=Courier New]-- create bitmap in function
-- write out a function that unpacks an integer into a pixel color
format "[/font][color=blue]fn unpack val = for p in val collect (r=p/256^2; g=p/256-r*256; b=mod p 256; color r g b)
"
for[/color] r=0 [color=blue]to[/color] h-1 [color=blue]do[/color][font=Courier New]-- for each row in the bitmap
-- have function write the column of pixels to the bitmap
( format "[/font][color=maroon]setpixels % [0,%] (unpack #("[/color] bname r
pixels=getpixels b [0,r] w [color=green]-- read in the column of pixels[/color][color=blue]
for[/color] c=1 [color=blue]to[/color] w [color=blue]do[/color][font=Courier New]-- loop through each pixel
( p=pixels[c] [/font][font=Courier New]-- get the pixel
-- pack the pixel into an integer and write it out
format [/font][color=maroon]"%"[/color] (((p.r [color=blue]as[/color] integer)*256+(p.g [color=blue]as[/color] integer))*256+(p.b [color=blue]as[/color] integer))[color=blue]
if[/color] c != w [color=blue]then[/color][font=Courier New]-- if not at end of data
format [/font][color=maroon]", "[/color][font=Courier New]-- write a comma
else
format [/font][color=maroon]"))
"[/color][font=Courier New]-- else close out the line
)
)
format [/font][color=maroon]"return %
"[/color] bname [font=Courier New]-- function returns the bitmap
format [/font][color=maroon]")
----------
"[/color][font=Courier New]-- finish off function definition
)[/font]
[/left]
That snippet was copyPasted from the ‘sample scripts’ section on this page.
2- You can add an option to display boxes instead of rectangles. If you texturemap the boxes with these images, it will look exactly like the final UI. (If the UI uses no images you can texturemap a default image that looks like default UI)
This is an interesting idea. I may write some code to support this.
If you release it on scriptspot, thousands of users will be benefited.
I'll post it up there this week. :)
yeah man, very interesting indeed!
one question though, i skimmed through the thread and i think you said something about making ui’s like CodeFather does.
this would mean hiding the default window bar, are you planning on implementing that, too?
as far as i saw until now you place those bitmaps in a rollout, but there is still the default window around it?