Meteor Product Page and Release Update

I’ve been trying my absolute hardest to build up enough hubris to birth at least one extra update to this blog in between the bi-annual posts, but it’s been really difficult, but this is not the time for excuses; it’s the time for information!

So, one of the big issues that people have been raising in various awesome and not so awesome places is that my frighteningly wordy blog post updates are just not easy enough to read or decipher, so people don’t actually know what Meteor is. Well, I’ve done my absolute best to slice through the HTML/CSS doldrums to create the following piece of monochromatic “web art”:

The Officially Official Meteor Product Page

This will be the best spot to find out everything you need to know about Meteor and will eventually (when it’s ready to go) have the support and the service installer update pages. While that place is a great spot to go and check out, there are some notes to point out:

  • Aiming for a release at the end of March/early April
  • We want to get at least the service installer out to test before release but there is a possibility of getting the client out to test as well
  • We really want to get people involved in testing if they want to, but it may take another couple of weeks before this happens

Before I sign off, I wanted to throw out some links that I think are good to check out if you’re interested in Meteor.

Firstly – Twitter stuff:

Secondly – there’s a cool thread on The Green Button that has lots of info and discussion about Meteor in it. Worth a read!

Posted in Development, Projects | Tagged , , | 1 Comment

Is this what you had in mind?

It seems as though time flows like a river; history repeats itself and another of the seemingly bi-annual posts on this blog will start with an apology about not writing blog posts. We’ve had quite a lot of questions about Meteor lately such as: Is it still happening? When will it be released? What is the air-speed velocity of an unladen African swallow? All of which I intend to answer in the following post; save the last one, because I’m not clever enough to think of my own material and much to the chagrin of my English Literature teacher in grade 10 who always told me that I should never intend to write, just write.

Let’s start this story at the beginning

I’ll start this off by coining a phrase from one of the most* respected** celebrities*** in Australia but hopefully not so much that I have to deal with copyright infringement later: Meteor – where the bloody h#$% are you? The answer is that it just ran home to pick up its wallet and is totally coming back to pay for the petrol, it’s totally not done a runner, I swear! There’s no need to call the cops!

In all honesty, we’re pretty much feature complete with the app. I can’t actually believe that I can write that and keep a straight face after all of the revision and iteration we’ve done over the past few months, but believe me when I say that all of the interesting stuff is done and all that’s left to do is the boring I mean awesome stuff like performance tweaking, bug fixing and UX testing. We’re definitely almost there, but it’s going to take a bit of hard yakka, a bit of blood, sweat and tears and most assuredly some other cliche’d euphemism for “hard work” that probably involves a montage.

This phase of development should only take days weeks months uhh, a relatively short amount of time to get done, that is of course considering we can get over a couple of fairly big blockers that we’ve encountered recently. I won’t pull back the curtain too far on what’s blocking us at the moment, but it does involve scouring the Media Centre libraries with Reflector to figure out why something is doing something that it perhaps shouldn’t not be doing. I’ve just been informed that wizardly actions have been performed and del tags have been placed in blog posts and that one of the big blockers has been fixed, so we’re that much closer.

Picking your battles

So one of the problems we’re facing involves using open source or 3rd party controls. Now, we definitely aren’t afraid of using 3rd party or open source controls or services, but the amount of tweaking, fixing and re-engineering that we end up having to do in order to get things up to scratch is frankly annoying. Seriously, there are awesome tools that are provided to developers (Stylecop, FXcop, Resharper (for those that can afford it)) that make open source code projects actually readable and reduces a lot of problems.

I can’t think of how many hours we’ve lost just trying to reorder code in open source projects just so that it makes sense to me. Then again, I’m pretty used to the way that Stylecop does things, and that’s freely available, so, developers: use the thing? Please? Pretty please?

One little bugbear of ours in particular is the reliability of some of the controls found in the Silverlight Control Toolkit. Don’t get me wrong; in general, the quality of this open source project is excellent and we use quite a few of the controls found therein; but on more than one occasion we’ve found ourselves blocked because one of the controls simply breaks the functionality of standard objects or that the performance of the control itself hasn’t been up to scratch. We’ve done our best to submit patches and updates to the toolkit where we can, but the amount of time it takes to figure out how a control does things and then how to actually fix the issues really puts pressure on us releasing a product in a reasonable time frame.

I’m making it sound like that’s the only reason why we haven’t released this thing yet but I can’t exactly blame anyone else for my World of Warcraft addiction; and in fact: this acts as my first stage of recovery! Seriously, friends don’t let friends raid.

Show me the money (app)!

We’ve shown a lot of stuff running on an emulator before, and while that’s pretty awesome, it’s probably better to see what it looks like actually running on a device in a real-world situation. So, I found my little FlipHD and removed all of the videos of monkeys stealing bananas from people in a Bali rainforest and made a video, so check it out! Note that if there is a hilarious video of monkeys or a random woman having glamour pictures in a forest taken with a point-and-shoot, then I apologise – not for uploading it, but for not having shown you all sooner. So, without further ado: star wipe…!

This video was embedded using the YouTuber plugin by Roy Tanck. Adobe Flash Player is required to view the video.

Reflection

Throughout all of the flowery, purpleness of the words I’ve violently vomited into this post, there are a few things that you can all take to the bank; the money bank:

  • Meteor is still alive and if not feature complete, extremely close to being feature complete – guaranteed (note: guarantee is not a guarantee).
  • The next phase of development involving testing, bug fixing and performance tweaking shouldn’t take too long. Perhaps only a matter of weeks****
  • The level of garbage written in these blog posts continues, unabated!

One thing I wanted to mention here was a thankyou to Carl who may or may not be involved with a certain organisation that offered us a pretty big opportunity that unfortunately didn’t end up happening. It definitely got the fires burning again and hopefully we can work together at some point in the future!

That’s all for now, so we’ll probably see you in another few months with another post detailing how Meteor isn’t done or something equally as self-aware.

* I might have meant least
** Respected is a strong word that gets thrown around far too often, this is out of context
*** When I say celebrity, I might mean person that someone knows
**** I’m not actually embellishing about this, I just wanted to have a blog post with 4 *’s.

I like del tags, if you couldn’t already tell!

Posted in Development, Projects | Tagged , , , , | 4 Comments

The Wheels of Progress: Meteor

Was the 11th of July really the last time we put a blog post up? I think we should fire our community team for that sort of thing! Of course I’m being facetious when I say things like that – we don’t actually have a community team – but I do fully acknowledge that it hasn’t been good enough to leave everyone in the lurch about Meteor and the progress we’ve made in the months since our last update. With Windows Phone 7 just about to grace our shores; albeit in the next few months; it’s well-and-truly time to update everyone on what’s happened. With out further ado, a new video of Meteor approaches:

Meteor – Land Dolphin’s WP7 Media Center Remote Control

This video was embedded using the YouTuber plugin by Roy Tanck. Adobe Flash Player is required to view the video.

Unfortunately (or fortunately), I’m not above shameless copy-pasting, so below is the description from the video as it gives a pretty good overview of the video above:

This video is a short tour of the Meteor WP7 Media Center Remote Control. It shows off the panoramic hub that gives you access to the aspects of WMC that a user wants, including:

The Recent Section

A section that shows off the media that is currently playing and what has been recently played; all tracked by the server, so all clients are synchronised.

The New Section

You want to know what’s just been added to your library so you can quickly go to your freshly legally ripped or legally downloaded media.

The Library

You want full, simple, integrated access to all of your media. The Library makes it simple to browse and search through your library to exactly what you want, quickly.

The video shows off the fine control and response that is paramount in a Windows Phone 7 application with rich commanding and UI flare to notify the user that things have changed.

Finally, the video takes you a short tour of the library, showing the capabilities of Meteor including Music, TV and movies. Recorded TV and a full, capable EPG (TV guide) will be shown off in a future video.

So What’s Different?

There were a few things we weren’t happy with back in July and in the previous demos that we put out of Meteor, so we thought that we’d rework them.

The Panorama

We had a good look at what Microsoft had done with the Zune HD, as well as what they were doing with some of the earlier builds of the Music and Videos hub and we decided that it was a bit too complicated and confusing and didn’t fit in with the glance-and-go nature of WP7. We found that from a UI perspective, we needed to just take a step back and have a really good think about what WP7 and Metro are all about and make some changes to really make sure we embraced the spirit of the platform. WP7 apps should be Personal, Relevant and Connected, so we’ve gone to great lengths to make sure that Meteor hit the right notes.

The Recent Section

We decided pretty soon after releasing those last videos that the Now Playing section was super sweet, but there was just too much awesome going on to confine it in a Panorama section, so we decided to unleash it in its own page which not only let us get a bit more creative with it now that it was nicely abstracted away, but also made it so that the hub was far less cluttered and confusing. A good one-two punch that Rocky would be proud of. Is it worth mentioning I’ve only seen Rocky V and the latest Rocky? Probably do me more harm than good, I’d imagine.

Along with the Now Playing section, the History section needed to be reworked, and thus the Recent section was born. When you really think about it, Now Playing media and History media are all “recently played” media, so why not merge them into a single section and let the DataTemplate be the distinguishing factor? It seems completely obvious now that I think about it. I mean, what kind of idiot couldn’t see that?! I mean GEEZE! All joking aside, we decided to merge Now Playing and History into a single section and embrace the notion of “glance-able” tiles, letting the user get a quick snippet of information on the currently playing media and then make a decision from there. It also allows us to make great use of some of the awesome album art, cover art and screenshots that we utilise heavily throughout the rest of the application. The phone should be a wonderful showcase for this art, so we decided to put it front-and-centre whilst still keeping with the text-centric Metro paradigm.

The New Section

I often hear the same question when we’re sitting down to watch some shows for the night: “so… what new shows do you have?”. When I say often, I mean practically every night, without fail, all the freaking time; it’s actually a really big deal and a fairly big source of friction in our household, so we here at Land Dolphin felt that we needed to address this situation and come up with a good solution. The New Section is that solution. Using clever behind the scenes “stuff”, the Meteor service figures out what new stuff you’ve just added to your library and then the app shows it to you, you can then interact with it in exactly the same way that you interact with everything else, except this time you can just throw your partner/best friend/dog your phone and say “this is the new stuff, pick something!”. There are still some issues in the way it’s presented which I want to address, but that’s a polishing thing, the tech is there.

EPG/Guide/Epic Stuff

I’ve said it on Twitter a few times and I’ll take this opportunity to say it again: @adventful really is awesome. One of the Land Dolphin guys that we all look up to because he does some quoteunquote “Epic Stuff” is at it again and after many long hours, Meteor has the ability to act as an EPG (Electronic Program Guide). It’s not quite ready to show off just yet as there should be a bit more polish lathered upon it (as well as our need to hide our preciousssssss), but it’s looking excellent already and should be ready to demo shortly. Everyone out there who is interested in EPG/Remote scheduling/etc of TV, stay tuned.

What’s Stayed the Same and What’s to Come

One aspect of Meteor that we’ve always been very happy with has been the Library. The flow of browsing through your media, drilling into and filtering results by metadata and attributes is really satisfying and should work beautifully on a proper device. An absolute TON of work has gone into making it all run extremely smoothly and respond brilliantly to user interaction. It’s all heavily virtualised and there have been many hours put into making sure that the traffic between the phone and the server is minimal, so it should stay snappy, even with a boatload of data on the server; which we can very readily test.

As far as what’s coming up: we feel like we’re starting to get into the home stretch. There are still plenty of UI tweaks and changes to be done, definitely some work on the EPG and the flow within the Library, plenty of testing to do to make sure everything plays nicely together and a lot (and I mean alot) of usability testing to do. In fact, the major work that I see there; and some have disagreed with me on this; is usability and user experience. It’s something that is paramount to the success or failure of an app but it’s also the thing that is probably the hardest for us to actually do and the main problem is not having a physical device to test on. It’s all well and good to say “well, you can test gestures and workflows on the emulator; it’s fine”, but the emulator in no way properly replicates the experience that a user will have on a physical device. The tools are fantastic to a point, but when you reach that point, nothing but hardware will do.

User experience is one of the ways that we believe makes Meteor stand out from the crowd and the sooner we can get our hands on some actual, proper phones and get testing, the sooner we can get this app into people’s hands and get them integrating their media into their “digital lives”. I was sure that I’d manage to get a cheesy 2010 catchphrase into this post somewhere! Our next blog post definitely won’t be 4 months away, so stay tuned for more Meteor and other projects in the coming months.

Posted in Projects | Tagged , , , | 80 Comments

Data Virtualisation in Silverlight and WP7

Silverlight has some great UI virtualisation features. You can have thousands of items in an ItemsControl, and so long as you are using a VirtualizingStackPanel the UI will remain snappy and responsive. However, what if the thousands of items that you want to display in the list come from a database or web service? You certainly don’t want to request them all at once, and UI virtualisation won’t help you here – what you need is data virtualisation, and that is something that Silverlight doesn’t provide. In this post I’ll be explaining how this can be achieved (or you can just skip to the end and download my implementation).

How to do it

In WPF, data virtualisation is relatively easy (or at least well known). An excellent summary of the topic can be found on the fantastic Bea Stollnitz’s blog here. In short, you create a custom IList<T> implementation, and whenever the indexer for the collection is accessed, you asynchronously load those items from your data source, usually in chunks. The collection raises change notifications, the UI is updated, and everyone is happy. In Silverlight it is a little bit trickier, as your indexer will be called for every item in your collection as soon as you bind it to an ItemsControl, causing all the chunks to be fetched at once – right back to square one. It’s not possible to get around this restriction completely, but we can minimise its impact with a bit of trickery.

Because Silverlight always accesses the entire collection as soon as you bind to it, we can’t use the indexer as the trigger to retrieve data from the back end. So, what else can we use? UI virtualisation does pretty much what we want – it only creates the UI for the data we want to show. The trick is to use this to request data only when it is shown in the UI. Once we’ve realised this, it’s actually quite simple.

What we do is create a wrapper class that looks something like this (implementation removed for brevity):

public class VirtualItem<T> : INotifyPropertyChanged where T : class
{
    ...

    public T Item
    {
        get;
    }

    public bool IsLoading
    {
        get;
    }

    ....
}

We wrap every item (including items that we haven’t actually retrieved yet – to start off with they will be wrapping nothing, and the Item property will return null or some other default value) in the collection with one of these objects, so that we are now implementing IList<VirtualItem<T>> instead of IList<T>. Silverlight will still access the indexer for every index, forcing creation of a VirtualItem<T> for every index, but the data source is not accessed until a UI element accesses the Item property, at which point we tell the list to retrieve a chunk of items containing that item. When items are retrieved, the Item property for the relevant VirtualItem<T> objects changes to the newly retrieved item and the UI detects the property change and updates. We get several benefits from this:

  1. Firstly and most importantly, we now know when the UI needs to display a particular item, because the item must be accessed via the Item property; the getter for the Item property triggers the asynchronous request for items if they have not already been retrieved. This circumvents the problem with Silverlight accessing the indexer for every index.
  2. In an implementation without this wrapper, the collection must raise collection reset change notifications whenever a new chunk of items is retrieved, using INotifyCollectionChanged. This causes any UI bound to the collection to reset as well, losing the selected item(s). With the wrapper in place new chunks now result in simple property change notifications via INotifyPropertyChanged (most significantly the Item property), meaning that the UI can handle these changes more efficiently and with no loss of selection.
  3. The wrapper object itself can provide properties related to virtualisation that the UI can bind to – for example the UI can bind to the IsLoading property to show which items are still loading.

This is still not true data virtualisation, as Silverlight does still access the indexer for every item, forcing the creation of all the wrapper objects – if you have a massive collection, you may still see performance and memory issues when creating the collection – but it is an effective means of requesting data on demand from a web service or some other potentially slow data source.

Sample implementation

At the end of this article is a link to an asynchronous virtual list implementation that uses the method described above. To use it, you need to provide it with a data source, which we do by creating a class that implements IAsyncItemProvider<T> and passing it to the constructor of the AsyncVirtualList<T>. IAsyncItemProvider<T> is designed according to the event-based asynchronous pattern. You can then bind the list to any ItemsControl using a VirtualizingStackPanel.

The below example shows how you might use an AsyncVirtualList<T>. First, the IAsyncItemProvider<T> implementation, which just generates a string based on the index of the item (with an artificial delay to emphasise the asynchronous behaviour, and no cancellation support):

private class DummyItemProvider : IAsyncItemProvider<string>
{
    public event EventHandler<ProvideItemCountEventArgs> ProvideItemCountCompleted;
    public event EventHandler<ProvideItemsEventArgs<string>> ProvideItemsCompleted;

    public int PreferredPageSize
    {
        get
        {
            return 10;
        }
    }

    public string CreatePlaceholderValue()
    {
        return null;
    }

    public void ProvideItemCountAsync(object state)
    {
        ThreadPool.QueueUserWorkItem(
            delegate
            {
                Thread.Sleep(1000);
                OnProvideItemCountCompleted(new ProvideItemCountEventArgs(null, false, state, 3000));
            });
    }

    public void ProvideItemsAsync(int offset, int count, object state)
    {
        ThreadPool.QueueUserWorkItem(
            delegate
            {
                Thread.Sleep(500);
                var items = new string[count];
                for (int i = 0; i < count; i++)
                {
                    items[i] = string.Format("Item {0}", i + offset);
                }

                OnProvideItemsCompleted(new ProvideItemsEventArgs<string>(null, false, state, items, offset));
            });
    }

    private void OnProvideItemCountCompleted(ProvideItemCountEventArgs args)
    {
        var handler = ProvideItemCountCompleted;
        if (handler != null)
        {
            handler(this, args);
        }
    }

    private void OnProvideItemsCompleted(ProvideItemsEventArgs<string> args)
    {
        var handler = ProvideItemsCompleted;
        if (handler != null)
        {
            handler(this, args);
        }
    }

    ...
}

Now creating an AsyncVirtualList<T> using the item provider (this shows setting the DataContext of a UserControl named MainPage in its codebehind – but you’d do it using a ViewModel class, right?):

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();

        DataContext = new AsyncVirtualList<string>(new DummyItemProvider(), Dispatcher);
    }
}

And finally, binding a ListBox to the virtual list in XAML. This shows a list whose items show the dummy string that the item provider generates, and are highlighted in blue until they are finished loading:

<ListBox ItemsSource="{Binding}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <TextBlock Text="{Binding Item}" />
                <Grid
                    Opacity="0.1"
                    Background="Blue"
                    Visibility="{Binding IsLoading, Converter={StaticResource visibilityConverter}}" />
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

The sample project shows the above example in full. The project is a Silverlight 4 web project, but the AsyncVirtualList<T> works just as well in WP7.

A couple of final notes about the asynchronous list implementation:

  • IAsyncItemProvider<T> can be implemented synchronously if desired – just raise the ProvideItemCountCompleted or ProvideItemsCompleted event directly from within the ProvideItemCountAsync or ProvideItemsAsync method.
  • Items are never released once they have been retrieved. This is something that could be added – let me know if you do!

You can download the sample project here.

Posted in Development | Tagged , , | 11 Comments

A First Look at Meteor

It’s been a few weeks now since we announced the Meteor application and we’ve been feverishly procrastinating as hard as we possibly can to make sure that we lose any momentum that we gained when we first revealed what we were doing. So on the back of that wave of “Real Life” and “Actual Job” nonsense that we’ve had to put up with, it’s time to finally see Meteor in motion.

The Meteor Hub

This video was embedded using the YouTuber plugin by Roy Tanck. Adobe Flash Player is required to view the video.

Continue reading

Posted in Projects | Tagged , , , | 44 Comments

How we work

We’re a small team of professional developers by most people’s standards. By day, we all work on a product using some pretty cool, modern technology and by night, we’re transformed into intergalactic space cops or horse murderers (that’s a reference to Red Dead Redemption, just to be clear). Well at least, that’s what happens when we don’t decide to work and/or procrastinate on Meteor. I thought it would be an interesting idea to let everyone know how we juggle the rigors of full time work with the trickling momentum of a project that we’re doing for fun; both the good and the bad.

Momentum

One thing that we’ve struggled with consistently is momentum. In a team of 4 guys who all have hobbies and other commitments and annoying partners (just kidding; not all of us have partners), there is always that “other thing” to do; always that rustler to hogtie, always that zombie to kill and always that hill or staircase to sprint up, and as such, a project that we’re doing for fun suffers the inevitable peaks and troughs. Generally, we’ve been fortunate in that when one of us is having a lull, another is working full-steam ahead and so on. There have been times, in the last couple of weeks, especially, however that all work has ground to a halt. There are some things that we’ve done to get around this, and in general, they’ve been effective.

Being Agile

One of the things we’ve picked up at work that I think’s been pretty effective is Agile development; Scrum in particular. It’s one of those things that’s really good for a small team like us to keep focused, but it’s also not so rigid that we can’t just flip over and try something else out if something isn’t working. Just as a warning: the next couple of paragraphs have a few terms in them that require some familiarity of Agile and Scrum to really understand. It’s not necessary though.

Now, as far as this project is concerned, we’re not following the process down to a T; more picking and choosing things that will work for us and the environment that we find ourselves in. Basically, what with full-time work and other commitments, we’re looking at having 3 hours a day per person to work on Meteor at the very most, which isn’t really an ideal work situation. As such, we’re not doing things like daily scrums as that would just be impractical and we’re not keeping daily burndown charts to see what our progress is because, again, that is pretty impractical. We are however using the Scrum way of tracking work, in chunks called “Sprints”.

Another important process that we’ve taken on at our day jobs and something we’ve adopted for our own projects is the process of creating User Stories. The link is better at explaining this than I am, but basically a User Story is an item of work, written in the perspective of an actual user that contains no implementation details, just the core “needs” or “wants” that a user has. I think it’s a very important distinction from a regular RFE which often contains bias from the reporter. It took us a really long time to convince the product owners at our actual job to remove all of their bullshit; I mean, perfectly legitimate implementation strategies; from their requests and then we can go about the job of prototyping, reassessing and then implementing. Now that it’s been fully embraced, I think it’s an absolutely excellent way to do things. Building software that fits what a user wants? What an amazing concept.

Technology

So, what we’ve done is we’ve taken some of the parts of Scrum that suit our project; like Sprints, which are “chunks” of user stories implemented over a set period of time with a particular goal in mind as well as User and Technical stories and combined them with some really good online technology and it’s managed to keep most of the momentum up across the board.

The technology aspect of how we work is obviously extremely important. We need things like source control, we need things like project tracking and we need things like work/issue tracking; I used to actually work without any of these things and it just absolutely amazes me how anything managed to get done without them. So we spent quite a long time looking through online services looking for something that fit us. We started with an account with a service called Unfuddle. It’s probably easy enough to read the website, so I won’t go into everything that they offer, but we found that for a small group of developers, they had a fairly robust set of features: source control, project management and issue tracking; basically all that we were looking for. However, there were some restrictions that we found that we couldn’t really work around, so we had to look elsewhere.

Eventually, we came across a service called Codespaces. They offer a very similar service to Unfuddle, but for about the same price, there were definitely really compelling differences. Not only do they offer unlimited subversion repositories, but their website offers a user experience that really allowed us to go “all in” with the Agile stuff that we wanted to implement. We could set up milestones (sprints) and assign chunks of user stories to them and track how they were going. It’s not perfect, but for the price, it’s absolutely compelling and it’s been working really well for us.

For reference, at work we use Atlassian’s excellent JIRA along with another product of theirs called GreenHopper for all of our Agile project management needs, and it’s actually a really good system now that it’s all been set up. That sounds like an absolute shill, but I wouldn’t recommend something if it was garbage. These things actually really help, so use them if you need them!

Filling the Gaps and Having Fun

Honestly, we’ve had far from a perfect run. We’ve had times where we’ve all been standing around a whiteboard in the middle of a day thinking “what the ef do we do now?”. Similarly, we’ve had times where we’ve just had so much to do and so much momentum going that everyone is just too busy to think about what to do next; it’s a bit of a balancing act that we haven’t really managed to get 100% right, but we’ve been doing pretty well.

One thing that we’ve done to try and get the fires burning again is what Simon assures me is called a “codejam”. Basically, what it involves is everyone getting together on a particular day and just coding – pretty much for the whole day. Most people would just call this a “day of work”, but when you’re not actually getting paid for this stuff, it’s a little bit more difficult to clear it with the partners who all think that you should be spending more time with them! In all honesty, we’ve really only had time to have one of these codejams, but it was pretty successful; though I will say that if you’re going to attend one to do some actual work, it’s probably a good idea to bring a machine that you can do work on, and not just a netbook. While they’re fantastic for doing things like browsing the internet and getting email, they’re not the best things for serious development work.

Here are some snapshots of our last codejam:

IMG_0150_cropped

I'm doing my best impression of origami in this shot. Fitting a 6'5" guy in the back of a Holden Astra is not the easiest thing ever.

IMG_0151_cropped

Here's our work area, complete with requisite iced coffee and coke bottles; a programmer's fuel.

Does this help?

The goal of this post was to let everyone know how we, as a really small team of developers, who all work day jobs manage to get things done outside of work hours. It’s not the easiest thing to do, and hopefully I’ve shed some light on our processes. We’ve spent a long time developing them both professionally and personally and find them to be really condusive to “getting things done”, and in the end, that’s what it’s all about. Getting great software done and out into people’s hands.

Posted in Development | Tagged , , , , , | 6 Comments

A More Controllable TransitioningContentControl

During our time developing for Silverlight 3 and Windows Phone 7, we found a few holes in functionality and structure that we wanted to fill. Being WPF developers by day, the gulf in functionality between the runtimes provided some challenges for us to overcome; Concepts like basic commanding and forms of UI virtualisation were things that we felt were sorely needed, especially in a limited environment like WP7, so we’ve been going about implementing stuff that we think the environment needs and we wanted to pull back the curtain and share some of what we’ve done in an effort to help the platform mature a bit. We absolutely love and want to acknowledge the importance open source communities like Codeplex, so we’d like to start giving back too where we can.

With that said, this is the first in a series of posts about things we’ve developed as a team that we think other developers would find useful. The bigger, more important things that have been implemented will come down the track as we thought we’d start out small, with a simple control that we’ve developed that we think would be useful to those that would like some finer control over a TransitioningContentControl.

Before continuing on with what this control is, how it can be used and how it can be extended, I’d like to acknowledge that there is a TransitioningContentControl as part of the Silverlight Control Toolkit, but we have come across situations where there’s a need to be able to control which part of a transition we’d like to use and be able to change that as we see fit and we also wanted to extend the number of transitions that were available and be able to easily add and remove new ones as we saw fit. This control isn’t radically different to the one available on Codeplex, but it does offer some things that the other one doesn’t, and we find those things pretty useful.

How this control is different

At a fundamental level, this control is different in the way that it can be controlled. The control itself allows the developer to define transitions easily in XAML, then with some minimal, but appropriate plumbing in code, be able to define which parts of the transition are able to be manipulated.

What we’ve found is that there are 2 parts to a TransitioningContentControl, the Out transition (where old content goes away) and the In transition (where new content comes in), so we’ve created a control that allows the developer to define an Out transition, an In transition or, if these other two transitions are not appropriate to be separated, a combined OutIn transition and then control which part is used. Transitions with both an Out and an In state can be linked together to form an OutIn transition.

How to use the control

This is the easy part! Simply use the following markup in your project:

<Controls:TransitioningContentControl
    Content="{Binding}"
    Transition="Fade"/>

<!-- Obviously you can bind to whatever content you like, this is just an example. -->

To control which part of the transition to use, simply use the TransitionPart property with either Out, In, OutIn along with a particular transition. If a transition cannot be split into separate parts, the designer will let you know.

How to create your own transitions

There are a couple of steps to this, the first is defining the transition in XAML. Note that the naming convention is important here.

<!-- The following transition will make the new content fade in and slide down from above while the old content will slide down and fade out -->
<VisualState x:Name="FadeDownTransition_OutIn">
    <Storyboard>
        <DoubleAnimation
            BeginTime="00:00:00" Duration="00:00:00.3"
            Storyboard.TargetName="PART_CurrentContentPresentationSite"
            Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
            From="-30" To="0"/>

        <DoubleAnimation
            BeginTime="00:00:00" Duration="00:00:00.3"
            Storyboard.TargetName="PART_PreviousContentPresentationSite"
            Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
            From="0" To="30"/>

        <DoubleAnimation
            BeginTime="00:00:00" Duration="00:00:00.3"
            Storyboard.TargetName="PART_CurrentContentPresentationSite"
            Storyboard.TargetProperty="(UIElement.Opacity)"
            From="0" To="1"/>   

        <DoubleAnimation
            BeginTime="00:00:00" Duration="00:00:00.3"
            Storyboard.TargetName="PART_PreviousContentPresentationSite"
            Storyboard.TargetProperty="(UIElement.Opacity)"
            From="1" To="0"/>
    </Storyboard>
</VisualState>

This is all pretty simple really, just go into the Themes/Generic.xaml file and define your transition as you’d like to see it. In this case, this is an OutIn transition as it didn’t make sense to not have these two parts linked together.

<!-- SlideLeftTransition -->
<VisualState x:Name="SlideLeftTransition_In">
    <Storyboard>
        <DoubleAnimationUsingKeyFrames
           Storyboard.TargetName="PART_CurrentContentPresentationSite"
           Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)">
           <EasingDoubleKeyFrame KeyTime="00:00:00" Value="-90"/>
           <EasingDoubleKeyFrame KeyTime="00:00:00.4" Value="-90"/>
           <EasingDoubleKeyFrame KeyTime="00:00:00.7" Value="0">
               <EasingDoubleKeyFrame.EasingFunction>
                   <CircleEase EasingMode="EaseOut"/>
               </EasingDoubleKeyFrame.EasingFunction>
           </EasingDoubleKeyFrame>
        </DoubleAnimationUsingKeyFrames>

        <DoubleAnimationUsingKeyFrames
            Storyboard.TargetName="PART_CurrentContentPresentationSite"
            Storyboard.TargetProperty="(UIElement.Opacity)">
            <DiscreteDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
            <DiscreteDoubleKeyFrame KeyTime="00:00:00.4" Value="1"/>
        </DoubleAnimationUsingKeyFrames>

        <ObjectAnimationUsingKeyFrames
            Storyboard.TargetName="PART_PreviousContentPresentationSite"
            Storyboard.TargetProperty="(UIElement.Visibility)">
            <DiscreteObjectKeyFrame KeyTime="00:00:00">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>Collapsed</Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>

<VisualState x:Name="SlideLeftTransition_Out">
    <Storyboard>
        <DoubleAnimation
            BeginTime="00:00:00" Duration="00:00:00.2"
            Storyboard.TargetName="PART_PreviousContentPresentationSite"
            Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)"
            From="0" To="-90"/>

        <ObjectAnimationUsingKeyFrames
            Storyboard.TargetName="PART_CurrentContentPresentationSite"
            Storyboard.TargetProperty="(UIElement.Visibility)">
            <DiscreteObjectKeyFrame KeyTime="00:00:00">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>Collapsed</Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>

The above is an example of a transition type that can be split into an Out and an In state and be used independently. We’ve found that it’s useful to be able to just have one element slide out and hold, or just have one element slide in for example. Or in the case where there’s a blank canvas placeholder as an old content, we’d like to be able to just transition in instead of play the entire outin transition.

OK, once that’s done, it’s time to add the transition to the TransitionType enum in the control’s code, so to add the above transitions, do the following:

/// <summary>
/// Represents the type of transition that a TransitioningContentControl will perform.
/// </summary>
public enum TransitionType
{
    ...

    /// <summary>
    /// A transition that fades the new element in from the top.
    /// </summary>
    FadeDown,

    ...

    /// <summary>
    /// A transition that slides old content left and out of view, then slides new content back in from the same direction.
    /// </summary>
    SlideLeft
}

We’re almost done, there just needs to be a couple of finer details added to make sure the Control doesn’t decide to throw a fit. The developer needs to perform a check to ensure that a particular transition can be split or not. If the transition cannot be split (in the case of an OutIn transition), then it’s good practice to inform users that it cannot be split, this is done in the VerifyCanSplitTransition method. It’s a bit icky, but it provides a nice designtime experience.

private static bool VerifyCanSplitTransition(TransitionType transition, TransitionPartType transitionPart)
{
    // Check whether the TransitionPart is compatible with the current transition.
    var canSplitTransition = true;
    if (transition == TransitionType.Fade || transition == TransitionType.FadeDown)
    {
        if (transitionPart != TransitionPartType.OutIn)
        {
            throw new InvalidOperationException("Cannot split this transition.");
        }

        canSplitTransition = false;
     }

     return canSplitTransition;
}

That’s pretty much it! If there are any finer changes that you’d like to make to particular transitions (such as scaling the magnitude of a transition depending on the size of a transition, it can be done in the SetTransitionDefaultValues method:

/// <summary>
/// Sets default values for certain transition types.
/// </summary>
private void SetTransitionDefaultValues()
{
   ...

    if (this.Transition == TransitionType.SlideLeft)
    {
        if (this.CompletingTransition != null)
        {
            var completingDoubleAnimation = (DoubleAnimationUsingKeyFrames)this.CompletingTransition.Children[0];
            completingDoubleAnimation.KeyFrames[1].Value = -this.ActualWidth;
        }

        if (this.StartingTransition != null)
        {
            var startingDoubleAnimation = (DoubleAnimation)this.StartingTransition.Children[0];
            startingDoubleAnimation.To = -this.ActualWidth;
        }

        return;
    }
}

Often times, the transitions will be fine with the default values set in XAML, but it might be nice for certain transitions to change them as the developer sees fit.

So that’s it for this post; it was a long one, but it’s nice to have all of the information presented right in front of you as a developer, so you don’t have to trawl through obfuscated code and poor commenting to be able to understand how to use certain things. There’s a code project associated with this so you can build it and plug it straight into your own codebase (with some default transitions that you can add to if you’d like). It’s provided “as is” so you use this at your own risk. Please enjoy!

LandDolphin.Samples

Posted in Development | Tagged , | 39 Comments

Meteor

There comes a point in every person’s life where they must ask themselves a couple of extremely important and life changing questions. Firstly, wouldn’t it be amazing if there were some way to control my Windows Media Centre using an application on my phone, and secondly, why hasn’t someone, perhaps some group of brilliant, bearded men, created this amazing application? Well question no more, mortal, for The Land Dolphin lurches forth ready to spew out said amazing application all over everyone’s faces in a vile, despicable stream. Of course by “their faces” I mean their “brand spanking new Windows Phone 7 devices”.

If that disgusting and altogether inaccurate description wasn’t enough to inform or terrify you, we’d like to take this opportunity to announce the first project to be developed by The Land Dolphin Collective: Meteor.

Now Playing

Meteor is the culmination of many months of brainstorming and torture in state of the art laboratories filled with equipment that would make Tesla and Genghis Khan both jealous and horrified in the same breath. It is an application that runs on your Windows Phone 7 device that, when coupled with a small service on your Windows Media Centre machine, allows you to remotely access and play all of your albums, TV shows and movies in a wonderful, integrated, “Metro” experience.

Meteor is personal – It’s your media library, it’s your media centre. Use it the way you like to.

Albums

Meteor is relevant – You should know what’s going on just by looking at your device. What have you already watched or listened to?

Recent

Meteor is connected – Would you like to be reminded of something when you’re not at home? Would you like to be surprised when you’re reminded of something you’d forgotten about?

Meteor is something that we’re pretty proud of, and that’s one of the things we want to emphasise. If we didn’t think this would be a cool, integrated and ultimately useful experience, then we wouldn’t do it. So we hope that you all think the same way.

Posted in Projects | Tagged , , | 54 Comments

An Inexorable Entity

Welcome to the Land Dolphin Collective. This is a spot where we can cast our collective creative unconscious onto the internet with such insurmountable and superlative force that its impact can be felt in the far reaches of the cosmos… or it might just be a spot where we can upload some posts about development and some projects we’re working on. I’m not sure which sounds more exciting or hyperbolic.

First thing’s first: what is a (the) Land Dolphin? While most would see it as a simple application of “adjective animal noun” conjunctive in the vein of a “Naughty Dog” or a “Big Rooster” or a “Battle Goat” or perhaps I’ve overestimated the amount of development companies with that kind of name; there is actually a highly uninteresting story behind it. It all goes back to the buck’s weekend of one of the Land Dolphin stalwarts, about a year ago. Cue dream-sequence theme.

I’m not sure if anyone actually remembers this, but PETA started a campaign probably 18 months ago to start bringing to our attention, the plight of our fair sea-faring friends: the fish. This isn’t exactly anything out of the ordinary for PETA, but the way they did it was most perplexing. Likely attempting to feed off the popularity of a popular internet meme; which I’ve subsequently found had a different meaning entirely; they sought to shine a spotlight on the horrific treatment of the noble “Sea Kitten”.

Like their surface-dwelling cousins, the land kittens, sea kittens enjoy being petted. Their lack of arms makes it difficult for them to pet back, but they often gently rub against each other as a sign of affection.

That quote is taken directly from PETA’s website about Sea Kittens and I’m sure you’ll agree: it’s f’ing insane; and not in the psuedo-positive context either. We would talk, sometimes at great length about how utterly ridiculous the whole concept was, in fact, this was exactly the case when the legend was conceived.

“What about pigs? Why don’t people care about pigs?” one of us, while enjoying a feast of Germanic delicacies, exclaimed. “If people should give an s about ‘Sea Kittens’, then they should certainly care about pigs!” another cried out, to which Simon; another stalwart; who is generally quite reserved, solemnly declared: “If only everyone understood the plight of the noble Land Dolphin.” The legend was born.

If you weren’t following along, basically what Simon did was take the ridiculous moniker of “Sea Kitten”; a term used to associate something not quite so cute and cuddly with something that is; break it down into its major parts and then change “Sea” to “Land”, because pigs live on land and “Kitten” to “Dolphin”, because dolphins are pretty cute and awesome and who would ever want to hurt a dolphin? You’ll have to imagine the blank look on my face as I type these words to get the full effect.

Farcical? Ridiculous? Absurd? Whatever the term, the criteria was met and Land Dolphin was born. It’s a name that we’ve attached to everything we’ve done as a group for the past year and now that something that we’ve been working on is finally almost ready to be revealed, it’s time to unleash the fury on everyone else.

What we’re about is software development. We’re aiming to create unique and personal experiences in the realms of Silverlight, Windows Phone 7, XNA and maybe a little bit of Android too. Not only that, but we’re developing things that we actually want to use and think are cool, and surely that’s the best thing that a small development group can do. This blog will be used to update everyone on the progress of the various projects that we’re undertaking as well as release some useful open source-type stuff to help other developers out because hey, we’d probably struggle a lot more than we already do if it weren’t for those things; so it’s nice to give things back.

The Land Dolphin Collective consists of four members at the moment, each more incredible and wizard-like than the other:

- Simon Palmer @sigh71
- Chris James
- Andrew Micenko
- Ben McCormick @thenoumenon

Posted in General | Tagged , , | 12 Comments