Jeff's Junk

The sillynonsense and .NET musings of Jeff Putz

News

My Sites

Deep Zoom... so close!

I've been trying to put together a couple of articles on rolling your own Deep Zoom viewer, fed by a database with images all cut up for you. The image cutting I've got, the data I've got... but the MultiScaleImage control is not working as expected.

There are a couple of articles out there already that describe how to feed custom data to the control about image locations. Here's my version:

    public class ViewerSource : MultiScaleTileSource {
        public ViewerSource(int imageWidth, int imageHeight, int tileSize, int overlap, int imageID) : base(imageWidth, imageHeight, tileSize, tileSize, overlap)
        {
            ImageID = imageID;
        }

        public int ImageID { get; private set; }

        protected override void GetTileLayers(int tileLevel, int tilePositionX, int tilePositionY, System.Collections.Generic.IList<object> tileImageLayerSources)
        {
            string source = String.Format("http://localhost:2974/TileHandler.ashx?id={0}&level={1}&x={2}&y={3}", ImageID, tileLevel, tilePositionX, tilePositionY);
            Uri uri = new Uri(source, UriKind.Absolute);
            tileImageLayerSources.Add(uri);
        }
    }

If I step through the code, I can see that it's getting the URL's for the images right (I can cut and paste and see they work), but the requests are never made for them. In the constructor for the XAML page, I use this:

ViewerSource source = new ViewerSource(4372, 2906, 256, 0, 6);
msi.Source = source;

... where msi is the MultiScaleImage. For some reason, no go. Interestingly enough, when I put a break point on the .Add(uri), the IList<object> is empty, which doesn't seem right.

This is frustrating the heck out of me, because I feel like I'm pretty close. Does anyone else have experience with this? If I can't make it work, it might be an interesting exercise to try and do it in Javascript since I have the tile part all figured out.

Is LINQ to SQL too simple-minded?

I've been playing around with LINQ to SQL lately and I found an issue that I can't quite get my head around. Perhaps you can help.

As you know, there are times when you have database tables that don't have an identity field. The data typically is selected on a combination of conditions, often foreign keys and certain other data. While I'm not super anal about databases the way some people are, I don't see a need for the column or its index in these cases.

But LINQ to SQL insists on having it, or you can't even insert data. It tells you, "Can't perform Create, Update or Delete operations on 'Table(whatever)' because it has no primary key." Well, sure you can. I do all of the above on tables without primary keys. My initial suspicion is that this has to do with the concurrency checking, and I totally get that, but turning it off or rolling my own code has not changed anything. It still gives me this error. That, or I'm seriously missing something.

Yes, I know I could just add the column and move on, but it's not the right thing to do. Any suggestions?

Performant is still not an adjective

From MSDN...

 "Deep Zoom enables the ability to zoom almost arbitrarily large images in Silverlight in a performant manner."

This is still the most ridiculously over-used word in tech circles, because it's made up. It can, technically, be used as a noun, but "performer" is more common. Seriously, with so many English majors writing code these days, how does this happen?

 I guess I find its use agitant. ;)

Making a business case for Silverlight

I've been thinking a lot about Silverlight lately, for a lot of reasons. What really put me to task was my boss asking me what its impact is and if he should care about it. That certainly changed my approach and purpose for thinking about it.

As one typically does, I started by Googling around for opinions and analyst comments. There really aren't a lot of great objective opinions out there. There's a whole lot of "Flash roX0rz, Silverlight and M$ suX0rz" nonsense, written largely by Flash developers. That's not helpful, but it got me thinking a lot about Flash. I've spent a lot of time with Flash lately, experimenting with some stuff and getting to know it a little better. As an animation tool, it has a certain level of familiarity for me because I was using Adobe AfterEffects way back in 1999 to animate video. I remember the first time I saw the Flash tools, thinking that Macromedia totally ripped off Adobe (ironic since they've since bought them). What has been less obvious in my experimentation is how they arrived at the programming model. That's where I get hung up the most.

Writing code in the context of a temporal structure (the time line) is weird and unnatural. It feels like it was just glued into it because they couldn't think of anything better. It becomes even more frustrating because the predictive typing (can't call it Intellisense, really) isn't very good, and debugging isn't much fun either. Oh, and ActionScript is essentially JavaScript, which I'm sure causes pain for a lot of people. Then there's the issue that Adobe hasn't done a good job of selling Flex as a "real" IDE, and honestly I've never even seen it. Despite all of this, it's easy to appreciate the power that Flash has. For something that started as an animation tool and grew into UI/software platform, it's not terrible.

But I think that's the point at which I started to wonder if it was entirely appropriate to consider Flash and Silverlight competitors. Yes, they're both displayed via browser plug-ins, but Silverlight is an opposite in many ways to Flash. It's a UI/software platform that happens to do animation. When you define it this way, you describe it as a solution to different problems. At that point it doesn't seem like a versus debate anymore. And if you cut out the versus part, and therefore the platform religion, I think you get a clearer picture to consider.

That picture has a lot of clear pro's and con's. On the upside:

  • You can build rich UI with minimal pain to solve complex UI problems. The easy control nesting and rendering tweaks make this so silly easy.
  • Your .NET developers can start using it right now. They mostly get the programming paradigm today, with some exceptions that books and tutorials will address.
  • You can code in Visual Studio, which by most accounts is the world's best IDE. Not saying everyone agrees, but my cross-platform friends feel strongly that it's true.
  • The player is a pretty easy download.
  • Even though it's still beta, the NBC Olympics site was a pretty good case study in how well it works.
  • The code isn't a time line thing, so it's not so weird to traditional OO code monkeys.

That said, there are also some valid concerns:

  • Penetration is a mystery. Sure the Olympics helped, and we can only assume that once it ships it'll get pushed out by way of Windows Update, but having to download a plugin sucks. If this site is accurate, that's not a bad start for beta software.
  • Adobe AIR/Flex folks are even more nuts than people making PC/MAC flamewars. Like it or not, that influences people.
  • The primary design tool is Windows-only, and I'm not sure if designers would even like the tool. If Expression Blend is built on WPF, one can only wonder that if Silverlight, a subset of WPF, can run on a Mac, how hard would it be to get ALL off WPF running on a Mac? Yeah, I'm talking .NET on a Mac.
  • It hasn't shipped yet. (Well, v1 did ages ago, but I think we can agree the "real" release is v2.)

From the developer angle, it's hard to argue against it. From the designer angle, it's a toss up leaning slightly against it for Mac shops (especially those who haven't upgraded to Intel machines). From a business angle, you've got the idea that you can leverage existing talent to build stuff and pit it against end user adoption. At the end of the day, it seems that the best you can do is wait and see for some point after v2 goes RTM.

Of course, if you're a developer, you probably already can think of a great many things to do with it today, and I think it's important to get out there and try that stuff. Deep zoom is a killer feature, and we could only make it more interesting by finding more novel ways to use it. But there I go making it religious again!

Why I hate Windows today

I know there are plenty of excuses that people come up with for Windows, but why does it suck so much? It always seems to get in the way of doing anything.

Today I did a fresh VM install of XP so I can use it on the new job (by the way, unattended install using Parallels for Mac is breathtakingly fast when installing against the ISO). Next task, install Visual Studio 2008. Next task, install SP1. Fail. Fail. Fail. And it's the worst kind of failure too, where it just sits there and doesn't do anything to indicate it's failing. It just says, "Download starting." Only it's not. You can push cancel and look at the log, which is useless to me because I didn't write the thing.

Yesterday my fiance is offloading some photos from the camera to her Vista laptop. It renames all of the files when it copies them, and it doesn't seem to ask you if that's OK. Then if you want to copy a bunch of photos from one folder to another, and there are duplicate names (and there will be since it renumbered them), this huge, confusing dialog opens with a bunch of wordy options on what to do. How is it that Microsoft can spend oodles of cash to find out where people get stuck in Halo but they can't find their way through simple file operations?

I was playing around even with solitaire on Vista, and when you try to do something against the rules it says something like "invalid operation." Are you kidding me?

I hate Windows. I seriously do. I need it to do one thing, develop software, and once everything works it generally seems fine. But why is getting there such a pain in the ass? I've come to realize that it isn't that I'm a big OS X or Mac fanboy, it's that I seldom realize it's there. That's what an operating system should be.

Employed again

I didn't get the job I mentioned in a fairly recent post, which was enormously disappointing. About 18 hours after that failure, I got the other job I had been after. That little negotiation made me wonder what this guy sees that the other(s) did not.

I was able to distill the reason down to one brief part of the conversation:

New boss: So why don't you just run with the things you're doing on the side?
Me: I'm not confident that I have the right business plan, and there are some experience gaps I need to fill.
NB: Well if this job fails to amuse you, I'm sure you'll have the idea a year or two from now and I'll be searching for your replacement.

Simply put, the guy gets me. At the moment, I think that's more important than the prestige factor of the company that did not hire me.

Launching QuickTime movies in the player using ASP.NET AJAX framework

As my dearest friends know, I once existed as a broadcast monkey prior to my life as a code monkey. It gives me great joy that it's finally at least somewhat practical to deliver short-form high definition video via the Internet, even if it is only a couple of minutes at a time. That said, the best bang for the buck in terms of compression is easily H.264, encoded by way of QuickTime. Flash can actually play these files, but it's not practical to do it in-browser when you're talking about something that's 1280x720 or 1920x1080. That's probably why Apple spawns the movies in the player itself. It's a pretty seamless experience, and since "everyone" has iTunes, "everyone" has QuickTime. (If you want to get into some stupid religious debate about this, please, do it elsewhere.)

What's not nearly as obvious is how Apple was doing it. It took awhile to find the right article on the subject, and even then, it didn't quite align with what the movie trailer site was doing. QT movies can begin with a "poster movie," and that can be anything QT can "play," including a still image. For reasons still not clear to me, you need one of these even if you're not going to show any of the markup as rendered stuff in the browser.

The design goal was simple: Make it so that clicking on something launches QuickTime Player and plays a movie. What follows is my first attempt. Keep in mind that it's not particularly pretty, and it needs some refactoring. It's obviously not as efficient as it could be. Comments follow...

/// <reference name="MicrosoftAjax.debug.js" />

Type.registerNamespace("Video");

Video.QuickTimePackager = function() {
        Video.QuickTimePackager.initializeBase(this);
        this._Id = null;
        this._TargetElement = null;
        this._FileUrl = null;
        this._PosterImage = null;
        this._holder = null;
}

Video.QuickTimePackager.prototype = {
    initialize: function() {
        Video.QuickTimePackager.callBaseMethod(this, "initialize");
        $addHandlers(this.get_TargetElement(), { "click":this._make }, this);
        this._holder = document.createElement("div");
        this._holder.setAttribute("id", this.get_Id());
        document.body.appendChild(this._holder);
    },
   
    _make : function(e) {
        var o = document.createElement("object");
        o.setAttribute("codebase", "http://www.apple.com/qtactivex/qtplugin.cab#version=7,3,0,0");
        o.setAttribute("height", "1");
        o.setAttribute("width", "1");
        o.setAttribute("id", "outobject");
        this._createParam(o, "src", this.get_PosterImage());
        var i = document.createElement("object");
        i.setAttribute("data", this.get_PosterImage());
        i.setAttribute("type", "video/quicktime");
        i.setAttribute("height", "1");
        i.setAttribute("width", "1");
        i.setAttribute("id", "inobject");
        this._createParam(i, "href", this.get_FileUrl());
        this._createParam(i, "target", "QuickTimePlayer");
        this._createParam(i, "controller", "false");
        this._createParam(i, "autohref", "true");
        this._createParam(o, "href", this.get_FileUrl());
        this._createParam(o, "target", "QuickTimePlayer");
        this._createParam(o, "controller", "false");
        this._createParam(o, "autohref", "true");
        o.setAttribute("classid", "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B");
        this._holder.appendChild(o);
        if (navigator.userAgent.indexOf("MSIE") == -1 || navigator.userAgent.indexOf("Opera") != -1)
            o.appendChild(i);
    },
   
    _createParam : function(parent, name, value) {
        var param = document.createElement("param");
        param.setAttribute("name", name);
        param.setAttribute("value", value);
        parent.appendChild(param);
    },

    dispose : function() {
        Video.QuickTimePackager.callBaseMethod(this, "dispose");
    },
   
    get_Id : function() {
        return this._Id;
    },
    set_Id : function(value) {
        this._Id = value;
    },
   
    get_TargetElement : function() {
        return this._TargetElement;
    },
    set_TargetElement : function(value) {
        this._TargetElement = value;
    },
   
    get_FileUrl : function() {
        return this._FileUrl;
    },
    set_FileUrl : function(value) {
        this._FileUrl = value;
    },
   
    get_PosterImage : function() {
        return this._PosterImage;
    },
    set_PosterImage : function(value) {
        this._PosterImage = value;
    }
}

Video.QuickTimePackager.registerClass("Video.QuickTimePackager", Sys.Component);

And then to wire it up to whatever object you want to be clickable:

Sys.Application.add_init(function() {
    $create(Video.QuickTimePackager, { "Id":"hd", "TargetElement":$get("fauxButton"), "FileUrl":"http://www.popw.com/video/kittehfight.mov", "PosterImage":"/images/blank.png" }, null, null, null);
});

The first piece of code is a Sys.Component, which you can drop in an external file and/or have it loaded by ScriptManager. I dumped it in a library as an embedded resource, but feel free to do it your way. The fragment at the end should live in script tags at the bottom of your page. Id is your name for the movie's container, where the object tags will be rendered, TargetElement is the actual element (not its ID) that you want to make clickable, FileUrl is the location of the movie and PosterImage is the poster movie you'll never see.

The init function simply adds a click handler to the DOM element you passed in with $create, and creates an empty div as the placeholder for the object tags. The _make method makes the object tags that force the sudden creation of a movie, specifiying the player as the target. This combination of parameters overall are necessary to get the movie to launch. Part of those requirements are the poster movie, which no one will ever see, but has to be there. I just pass in a blank 1x1 graphic.

The object within an object is a little strange, but this is how Apple does it on the trailer site as well. The outer object is what IE needs to work, while the inner one is what every other browser expects (including Opera, which impersonates IE sometimes, but we know better). Also of note is that, according to comments in the script library that Apple uses, the classid attribute has to be added last, or IE won't see the rest of the parameters. That seemed to be true as I experimented. The rendered stuff will launch the player with the movie, and off you go, spreading your glorious HD porn, er, nature video, across the Series of Tubes.

Again, it needs a little clean up, but it's a nice reusable piece for you to plant your HD, spawned QT movies in your ASP.NET page.

Three-hour marathon interview
I had three hours of phone interviews today with people from a company I'm very much hoping to work for. That was crazy. It's not any less exhausting doing it by phone. You start to get tired of talking about yourself.

But I think it went pretty well. The last time I had that kind of marathon was in Redmond. This was a lot different, because these guys seemed genuinely interested in what I was about and what I had done. That's a far cry from Microsoft, who seemed more interested in trying to stump me or give me puzzles to solve. I'm more and more convinced that's mostly useless in assessing the ability of your subject. I felt like it was OK to simply say, "I don't know," when there was something I didn't know.

From what I can gather, said company is doing some really cool things in the near future, so I'm crossing my fingers. This is the first time in a long time that I've felt pretty good about what a company does, and what it stands for. I'm crossing my fingers.
Science project no more: playing with client frameworks

Awhile back I mentioned how sometimes I get sucked into these science projects, and I end up not doing more productive things. That particular science project was me trying to build a drag-and-drop list. Sounds silly, right? Because there are existing solutions. But I had good intentions.

First off, the ReorderList control in the ASP.NET AJAX toolkit blows. It has all kinds of problems selecting stuff as you drag, the rendering forces you in to an unordered list, and it doesn't have the nice clean movement you see in other similar pieces around the Internet. The underlying code is hopelessly complex too, and I'm not sure why it has to be that way. More on that question in a moment.

My second motivation was just that, dammit, I want to see if I can do it. I remember the first time I saw the getBounds method in the AJAX framework, and I immediately thought it was a key time saver to creating a drag-and-drop list.

So what did I manage to do? I managed to do the dragging part, which came pretty easily. I managed to create a placeholder that lived where the item was coming from too. At that point, I really only had about a hundred lines of code. This object model that I had come up with, however, made it exceptionally illogical for altering the list as you were dragging. All along I already had something in mind for this control, and at this point I was just wasting time when there were solutions out there. Really, really good solutions.

Something else recently landed me on the Yahoo UI page, and I figured I'd give that a good look to see if it would do what I wanted with minimal pain. For the most part I think it can, but it wasn't nearly as easy as Scriptaculous. They use some odd naming conventions (like event handlers being called "observers"), but for the most part everything is so straight forward. The code is fairly easy to understand, and definitely has seen many rounds of refactoring. The Sortable object was exactly what I needed. I looked at JQuery as well, and it looks remarkably similar.

Why is the ASP.NET AJAX stuff so heavy? It reminds me of so many server-side controls that try to do everything but succeed at being useful only a small percentage of the time, primarily for those old-school line-of-business app developers. Although, does it really matter?

I'm not hating here, let me make that clear. The first time I wired up server-side stuff to the client-side, and then had two client-side objects interact, I totally understood why Microsoft's framework is pretty cool. It's just the stuff being built on top of it that doesn't seem to be as elegant and useful as I think it should be. But regardless, it thrills me that these frameworks can live peacefully together.

Those who can't write blogs for washed up magazine's Web sites

First this tool writes about how the London Stock Exchange crashes, and it's all the fault of using Microsoft software. He has no evidence, mind you, but that must be it.

But oh wait, no, it was a network problem.

It still seems ridiculous that people get into this religious zealotry, and people are really into it. Is it because people like me are so annoyed by it? Some tool whose byline says he's been writing about software for 30 years doesn't make him qualified to make such asinine statements. Fortunately some people called him out on it.

But hey, clueless pundits keep those of us who endeavor in consulting rolling in the cash I suppose. Maybe we should write more about it.

More Posts Next page »