| Comments

so while waiting for a replacement hard drive in my local office (i received an event log telling me "your hard disk driver has reported imminent failure...do not save anything more to this hard disk" -- yikes), i was working on some silverlight 1.1 cross-platforms stuff...i decided to fire up itunes to listen to some ambient tunage.  lo and behold two "shared libraries" popped up (i was on a public wifi connection).  sweet, i took a look and started lurking...mtabar had the broadest selection, from 2-pac, to my all time favorite band, black sabbath (the original, not the current).

i double-clicked and started streaming right away...nice.  nothing like a little 'war pigs' to get your day going.

thanks mtabar whomever you are that is likely somewhere in downtown phoenix using the same public wifi i am!

| Comments

wooclan member and game-coder extraordinaire jason just posted about some hacking he did to provide some basic layout capabilities of textblocks, yeah, like basic as in centering.

check it out yo.

| Comments

one really great feature about silverlight is the packaging aspect of it.  what do i mean by this?  well, you can essentially put a ton of assets into a compressed file and pull them out as needed.  this would provide you the ability to have a single asset package that is compressed, and thus saving on some download time.  of course there would be tradeoffs that you'd have to consider, but for sample sake, let's assume they are good.

so how would you do that?  well let's say you have a bunch of images in a file name 'assets.zip' (here we have 2):

in our silverlight application we want to load those up and then maybe use them individually later at some point in an event.  here's the xaml i'm working with for this sample:

   1:  <Canvas
   2:      xmlns="http://schemas.microsoft.com/client/2007"
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:      Width="605" Height="314"
   5:      >
   6:      <Rectangle Stroke="#FF000000" x:Name="progressBar" Width="0" Height="18" Canvas.Top="1">
   7:          <Rectangle.Fill>
   8:              <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
   9:                  <GradientStop Color="#FFCAE8B0" Offset="0"/>
  10:                  <GradientStop Color="#FF68C51A" Offset="1"/>
  11:              </LinearGradientBrush>
  12:          </Rectangle.Fill>
  13:      </Rectangle>
  14:      <Rectangle Stroke="#FF000000" Width="600" Height="18" Canvas.Top="1"/>
  15:      <Image x:Name="logoImage" Width="318" Height="204" Canvas.Left="282" Canvas.Top="23"/>
  16:      <Canvas Width="117" Height="28" Canvas.Top="64" MouseLeftButtonUp="handleButton2Click">
  17:          <Rectangle Stroke="#FF000000" RadiusX="4" RadiusY="4" x:Name="buttonPicture2" 
Width="117" Height="25" >
  18:              <Rectangle.Fill>
  19:                  <LinearGradientBrush EndPoint="0.613,-1.095" StartPoint="0.503,1.975">
  20:                      <GradientStop Color="#FF58DD65" Offset="0.067"/>
  21:                      <GradientStop Color="#FF42BBB8" Offset="1"/>
  22:                  </LinearGradientBrush>
  23:              </Rectangle.Fill>
  24:          </Rectangle>
  25:          <TextBlock Width="57" Height="25" FontFamily="Calibri" FontSize="14" Text="Picture 2" 
                     Canvas.Left="33" Canvas.Top="3"/>
  26:      </Canvas>
  27:      <Canvas Width="118" Height="28" Canvas.Top="23" MouseLeftButtonUp="handleButton1Click">
  28:          <Rectangle Stroke="#FF000000" RadiusX="4" RadiusY="4" Width="118" Height="25" 
                     x:Name="buttonPicture1" >
  29:              <Rectangle.Fill>
  30:                  <RadialGradientBrush>
  31:                      <GradientStop Color="#FFDDB758" Offset="0.067"/>
  32:                      <GradientStop Color="#FFBBAF42" Offset="1"/>
  33:                  </RadialGradientBrush>
  34:              </Rectangle.Fill>
  35:          </Rectangle>
  36:          <TextBlock Width="57" Height="25" Canvas.Left="33" Canvas.Top="3" FontFamily="Calibri" 
                     FontSize="14" Text="Picture 1"/>
  37:      </Canvas>
  38:      <TextBlock x:Name="percentComplete" Width="110" Height="27" Canvas.Top="96" 
                     FontFamily="Calibri" FontWeight="Bold" Text="" TextWrapping="Wrap"/>
  39:  </Canvas>

i'm using the javascript programming model here and my xaml file has an associated javascript file that looks like this (minus the silverlight creation script):

   1:  var dl = null;
   2:   
   3:  function onDownloadProgressChanged(sender, eventArgs)
   4:  {
   5:      var pcnt = Math.floor(sender.downloadProgress * 100);
   6:      
   7:      sender.findName("progressBar").width = sender.downloadProgress * 600;
   8:      sender.findName("percentComplete").text = sender.downloadProgress * 100 + "%";
   9:  }
  10:   
  11:  function onDownloadCompleted(sender, eventArgs)
  12:  {
  13:      var img = sender.findName("logoImage");
  14:      img.setSource(sender, "PIC_0004.jpg");
  15:  }
  16:   
  17:  function initDownloader(host)
  18:  {
  19:      dl = host.createObject("downloader");
  20:      
  21:      dl.addEventListener("downloadProgressChanged", "onDownloadProgressChanged");
  22:      dl.addEventListener("completed", "onDownloadCompleted");
  23:      
  24:      dl.open("GET", "timfaces.zip", true);
  25:      
  26:      dl.send();
  27:  }
  28:   
  29:  function resetImage(host, imgName)
  30:  {
  31:      var img = host.content.findName("logoImage");
  32:      
  33:      if (!dl) { initDownloader(host); }
  34:      
  35:      img.setSource(dl, imgName);
  36:  }
  37:      
  38:  function handleButton1Click(sender, eventArgs)
  39:  {
  40:      var host = sender.getHost();
  41:   
  42:      resetImage(host, "PIC_0004.jpg");
  43:  }
  44:   
  45:  function handleButton2Click(sender, eventArgs)
  46:  {
  47:      var host = sender.getHost();
  48:      
  49:      resetImage(host, "PIC_0012.jpg");
  50:  }

notice the two events wired up on initDownloader and the two callback events that happen when those events are completed.

take a look at the function onDownloadCompleted...this is where we leverage the compressed asset file.  for this sample, we want to use images.  so basically we are setting an image object source to an item in the zip file.  we first find the associated element, then setSource providing the name which resides in the zip file.  that's it, we are done!

in my sample here, i chose to implement "dl" as a global variable so i could access it later.  while at MIX this week i was able to get some better practices of wiring up some object prototypes and include the downloader as an object essentially of the other javascript objects.  i know it sounds confusing.  open up blend 2 preview and start a project, look at the scene.xaml.js file and you'll see what i mean...it really isn't that confusing.  i just had this working sample and wanted to share.

the concept of using a downloader in conjunction with a compressed asset file intrigues me and i hope you may find it useful.  now this isn't the only way you could use this method (picture assets), as i believe the intent actually was more of a packaging concept intended for xaml files that you can pull out and load. as an example, in the onDownloadCompleted let's assume i had a file in there called newFunction.xaml that was there for some additional layouts, etc.  i could do something like this (again, assuming in the onDownloadCompleted method):

var newXaml = sender.getResponseText("newFunction.xaml");

then with that text i can do some createObjectFromXaml functions or something like that.  pretty cool.

have fun, check out today.

| Comments

in a previous post i wrote about embedding the applications in your site using the service.  i wrote about my troubles in getting output from more complex types working in the service.  here's the skinny.  i was using expression media encoder (eme for the cool kids) and the output templates for media players.  turns out the version of eme i was using was missing a few things.  the version on microsoft.com/expression is correct and is working fine.

if you are using eme outputs and want to put them in silverlight streaming, do not use the <source> node in your manifest.xml file, but ensure you have the <loadFunction> node and put in the initializer for your player (usually the eme output is calling it 'StartWithParent').  doing these two things helped me get it to work in .

hooray .

| Comments

so what happens when you want to embed in your page?  well if you have absolute control over your site, you may not need to worry as you'll post your silverlight applications as-is.  but what if you want to just output some smaller silverlight applications in specific areas in your site, blog, etc?

enter .  this was announced at mix07 where you get 4gb storage for free.  now, there are some caveats that you should read about -- the 4gb is total storage, but the per-app upload has some limits...so be sure to read...it may not meet every need.  but if it does, you'll have to know some things.

first, the "streaming" has been throwing people off, and i think i understand why.  our techno geek brains are telling us that "streaming" means media files directly.  because of this people have been asking me they thought you'd upload a wmv file or something and the silverlight streaming would provide a player, etc. as the output.  not so.  is enabling you to host/stream the entire silverlight application.  so basically you develop the wicked-cool-super-slick and want somewhere to host it, the xaml files, associated media, etc.  boom, may be a solution to you.

now, you may have your app, go to silverlight.live.com and then say, huh, now what?  well first you should probably take a look at the sdk link (on the left), then on the right there is a link for create application (under the essential links).  there is some important information for you here.  the most important is the creation of a manifest.xml file.  this is describing your application files requires, your manifest, etc.  it will look something like this:

<SilverlightApp>      <source>Scene.xaml</source>      <width>400</width>      <height>50</height>      <jsOrder>          <js>Silverlight.js</js>          <js>Scene.xaml.js</js>          <js>Default.html.js</js>      </jsOrder>  </SilverlightApp>

once you have that, you need to zip all your files up...except certain ones :-) -- like .media, .html, .aspx, .zip (more on this one later).  you'll have a zip file that might look something like this:

once uploaded, then you'll have to follow the silverlight embed directions (a 3 step process -- or 2 if you don't want to create another file).  below i've embedded in this blog post: 

go ahead, click it :-)

the core of the functionality is in the third step the instructions provide you which will look something like this:

function CreateSilverlight() {    Sys.Silverlight.createHostedObjectEx( {      source: "streaming:/217/SimpleButtonClick",      parentElement: SimpleButtonClickWrapper});  }

okay, now for a few gotchas i've found early on.  first, the complexity of your silverlight app may get your frustrated when you upload it.  for example, i've taken an output player from expression media encoder and it didn't exactly work (although i'm still troubleshooting it, i suspect i know some problems).  one of the reasons why is that it uses some createObject funkadelicness when creating the initialization of the event handlers, etc.  because of this you'll have to look at the loadFunction and onLoad parameter nodes of the manifest file.

second, i am assuming that silverlight streaming is leveraging a feature of silverlight that enables you to compress your assets (or perhaps your entire application) in a zip file.  then using items like the downloader, you can download the zip file (which might be considerably smaller and save some bandwidth) and then pull out what you need from the zip.  it is quite cool, and i have a sample in another post (subscribe now, hint hint).  anyhow, where was i?  oh yeah, well .zip files are not allowed to exist within your .zip application...wait, does that make sense?  basically if you are using that mechanism, it might not work in the silverlight streaming scenario...quite frankly it didn't work for me...maybe more to come on that.

so start your silver-engines, and download some tools, build some apps, upload them and host them...giddyup.