Autocomplete in Silverlight

Posted in Programming,Silverlight by ary on the September 26th, 2008

I’ve written a simple class to allow adding autocomplete to a TextBox. An example of how to use it is:

In the XAML file:

<TextBox x:Name="uiText" Width="100" Height="30"
    manas:Autocomplete.Suggest="DoSuggest" />

In the class file:

// The texts we want to suggest
private string[] options = new string[]
{
    "Al", "Amiko", "Angla", "Anglujo", "Ankaux", "Antaux", "Atomo", "Auxto",
    "Bebo", "Bela", "Birdo",
}

// The method we have to implement to offer suggestions
public void DoSuggest(string text, SuggestCallback callback)
{
    // Don't suggest if there's no text
    if (text.Length == 0)
    {
        callback(null);
        return;
    }

    var result = new List();

    // See which options have as a prefix the text entered by the user
    foreach (var option in options)
    {
        if (option.StartsWith(text, StringComparison.InvariantCultureIgnoreCase))
        {
            result.Add(new Suggestion() { DisplayString = option,
                                                      ReplaceString = option });
        }
    }

    callback(result.ToArray());
}

As in a previous post, I use the technique to specify an action to happen in the XAML, and it’s implementation in the class file, just like an event handler.

Of course, instead of using an hardcoded options array, these could be requested in the DoSuggest method to a web service, or requested from another class.

The suggestions are shown in an unstyled ListBox, but it should be easy to style, and even to improve the code to support icons in the suggestions, or any other control.

For this to work, the RootVisual of your application must be a Canvas, since otherwise you can’t place arbitrary floating elements on top of it.

Here’s the full code in case someone finds it useful.

(+) Show Code

Embedding YouTube videos in Silverlight

Posted in Programming,Silverlight by ary on the September 11th, 2008

There’s no straight way of embedding YouTube videos in Silverlight. What you can do, however, is to create a floating div over the Silverlight plugin, whose content will be the YouTube video control. For this purpose, I wrote a simple class to make it easier to do this.

The usage is simple:

// ZCcedd9EfHI is the id of the video to show
YouTubePlayer player = new YouTubePlayer("ZCcedd9EfHI")
{
    Top = 100,
    Left = 200,
    Width = 400,
    Height = 400
};

player.Embed();

// And, once you want to remove the video from the page...
player.Dispose();

That’s it. Of course, you’ll have to compute the Top, Left, Width and Height values if you want to center the video inside a particular Silverlight control. You can do this computation in the Loaded event of that control.

And the best thing is, you can save a reference to the YouTubePlayer instance and, in case the Silverlight plugin is resized or moved, changing the Top, Left, Width and Height properties will automatically execute javascript code to move/resize the player.

Here’s the full code in case someone finds it useful.

(+) Show Code

Adding double click support in Silverlight

Posted in Programming,Silverlight by ary on the June 24th, 2008

Silverlight Beta 2 doesn’t support double click, but since I needed it, I implemented it. I’ve created a class named Mouse. You create a Mouse instance that wraps an UIElement. The instance attaches itself to the MouseLeftDownButton and, using a timer, it allows you to recieve events when double click is performed.

Actually, you can detect as many clicks as you wish: the event arguments include the number of clicks performed by the user.

But I don’t want to attach to mouse events in code. I want to do it in XAML, like with MouseLeftButtonDown or Click. But, unfortunately, you can’t use attached properties whose type is an event handler. If you do that, you get an ugly exception.

“What a pity”, I thought, “now I need to remove some of my MouseLeftButtonDown events and replace them by code that creates Mouse instances and then attaching to Mouse events programatically”. But before doing that, I decided to give it another shot. What if I created an attached property whose type is string, and then at runtime I searched the method and invoke it?

The problem with that approach is that the method won’t be declared in the object where you are attaching the event, but probably in some parent control. For example:

<UserControl>
    <Rectangle manas:Mouse.Click="SomeMethod" />
</UserControl>

SomeMethod is probably declared in our custom UserControl, not in Rectangle. But that poses no problem at all: just go up in the visual hierarchy throught the Parent property until we find a class that declares SomeMethod with the signature of our interest.

But, alas, at the time attached properties are processed by the XAML processor, the object in question is not yet in the visual hierarchy: it doesn’t have a parent. That’s no problem at all: we attach to the Loaded event and do the lookup in that moment, and we are guaranted that we can reach the parent we are interested in.

Once I did that I was really amazed that it worked! :-)

Then, I refactored the code so I could use that trick to support other custom event handlers in XAML as well. Finally, changing the old event handlers to start firing at double clicks instead of single clicks was a matter of seconds.

Here’s the full code in case someone finds it useful.

(+) Show Code

Generating 3D trees

Posted in Programming by ary on the May 5th, 2008

The goal is to generate 3D trees programatically rather than using a design tool. A tree is a complex model, containing thousand of vertices, which are both hard to create and inneficient to store. By saving just the information necessary to generate them we save memory and make their creation easier. The steps to accomplish this are:

  • Create a language that allows specifying an L-System, and write a lexer and a parser for it.
  • Interpret the language and create a 3D model from it.
  • Give the model life: create branches and leaves.

The grammar of the L-System language is the following:

LSystem ::= ( Rule )*

Rule ::= RuleName ParenthesizedNumber? ':' Actions ';'

Actions ::=
    (
        ( f | '+' | '-' | '<' | '>' | 'v' | '^' ) ParenthesizedNumber?
    |
        ( s | h | u | l | r ) ParenthesizedNumber
    |
        RuleName
    |
        Branch
    )*

ParenthesizedNumber ::= '(' Number ')'

Branch ::= '[' Actions ']'

RuleName ::= [A-Z]

Number ::= [0-9]+ ( '.' [0-9]+ )?

A tree will be drawn by a turtle. The turtle starts at a certain position, for example (0, 0). The turtle follows the actions given by a rule of the L-System.

If it encounters f, it advances a step. +, -, <, >, v and ^ tell the turtle to turn clockwise or counterclockwise aroung a given axis relative to the turtle, for example up, left or head. A number between parenthesis indicates the ammount to step or turn. For example, f(2) advances two steps instead of one.

s, h, u, l and r are multipliers. s multiplies the current step by the given number. h, u and l multiplies the turn angle along each of the axis. r multiplies the trunk radius.

A branch tells the turtle to push it’s state into a stack, do the actions inside the branch, and then pop the state. This effectively allows making many branches from a given point.

If the name of a rule is found, it is consumed (interpreted again by the turtle). Since this may lead to infinite recursion, a number of iterations is defined: each time a rule is consumed, the number of iterations is decremented, until no further rules are consumed.

To see this in action, I first wanted to know if it worked in a 2D environment: requestor pattern in action! A TurtleCommander interprets the rules, starting by an axiom (the name of the first rule to intepret). As it interprets the rules and actions, it notifies an ITurtle what to do. An ITurtle is an interface that has methods like Advance, RotateAlongAxis, MultiplyCurrentStep, etc. In this way, the intepretation of the rules is decoupled from their processing. A 2D ITurtle will ignore the rotation axis because there is only one in a 2D plane. Also, I started without trunk radius, so these calls are ignored.

Another important aspect is to give realism to the generated trees. If the rules are obeyed without modification, the trees will look too symmetric, too perfect. To fix this, we introduce randomness when intepreting an action, so a step or a rotation becomes a little longer or shorter. This is all handled by the ITurtle implemantation.

Here are some screenshots of 2D trees, together with their L-System, step, rotation angle and number of iterations:

2D tree, 26 degrees, 1 iteration A: f[+A][-A];

1 iteration

2D tree, 26 degrees, 2 iterations A: f[+A][-A];

2 iterations

2D tree, 26 degrees, 3 iteration A: f[+A][-A];

3 iterations

2D tree, 26 degrees, 4 iterations A: f[+A][-A];

4 iterations

2D tree, 26 degrees, 4 iterations with randomness A: f[+A][-A];

4 iterations with randomness

A regular weed A: fA [+fA] fA [-fA] fA;

3 iterations

A simple bush A: fA fA +[+fA -fA -fA] – [-fA +fA +fA];

3 iterations

The next step is to make it 3D. I made another implementation of ITurtle which now understood every action except the radius change. It creates 3D instead of 2D lines. Here’s a screenshot of some early trees:

A: f[+A][-A][<A][>A];
A: f[+A][-A][A];
4 iterations
A more realistic tree
A: f [-s(0.6)C] s(0.5) f [+^C] f s(2) [+B][-B][^B][vB];
B: s(0.7)f[+B][-B][^B][vB];
C: f;
5 iterations

Next, to draw textured cylinders instead of lines:

3D tree with textures trunks
A: f [-s(0.6)C] s(0.5) f [+^C] f s(2) [+B][-B][^B][vB];
B: s(0.7)f[+B][-B][^B][vB];
C: f;
5 iterations

Finally, it starts looking like a real tree. This is being drawn with the DirectX API, but without using vertex shaders and pixel shaders.

The next step is to make use of vertex and pixel shaders to give branches a more realistic appearance. To do this, instead of just sticking branches together, I stick them and twist them. Also, radius changes are now interpreted. The result is this:

3D tree, almost real 3D tree, almost real (2)
A: f r(0.6) [+B][-B][^B][vB];
B: s(0.6) f r(0.5) [+B][-B][^B][vB];
5 iterations

Nice, huh? Finally, I use a billboard technique to draw leaves in the last branches. Here are some screenshots of trees:

3D tree 1 3D tree 2
3D tree 3 3D tree 4
3D tree 5 3D tree 6
3D tree 7

I really enjoyed how the look of the trees changed as I added, little by little, more details to them.

Java tips learnt from Eclipse

Posted in Design Patterns,Eclipse,Programming by ary on the November 16th, 2007

Here are some Java tips for making your code more beautiful, understandable, reliable and maintable. They are in no particular order.

  1. Suppose your code will be read by somebody else. Even if you are working on a project on your own, it’s worth commenting properly your code, using interfaces and trying to make your code understanable. That somebody else might be you: in a couple of months you won’t remember all the details of your implementation without good comments.
  2. Comment properly your code: try writing the comment of a function or class before getting into implementation details. That will also give you a better understanding of the problem. Appart from this, there are some very useful comments:
    • This interface is not intended to be implemented by clients. Sometimes interfaces are used to hide implementation details. This kind of comment is used to tell the user about this.
    • This interface may be implemented by clients. It’s almost the opposite of the previous point, except that the library may already provide some implementations.
    • This class is not intended to be instantiated by clients. Some classes are used for internal purposes or as results of method invocations. This tells the user they are expected to obtain instances of the class, not to create them.
    • This class is not intended to be subclassed. Even if the class is final, this method tells the user it’s not correct to subclass some class, because it may lead to poor performance or incorrect behaviour.
    • You can obtain an instance of this class/interface from Foo. In case of an interface or a class that is not intended to be instantiated, this helps the user get instances of them.
    • See Foo. This tells the user the referenced class is somehow related to the commented class. Even if the referenced class is already mentioned in the general comment, these kind of references are more visible than some word in a big comment.
  3. Provide clean interfaces between different modules of a system. Typical modules are UI and logic (or core). As much as possible, these modules should communicate using interfaces in order to hide implementation details.
  4. Use internal packages. Classes that are not supposed to be used outside of a module should be in a separate package hierarchy. Eclipse usually uses the name “internal” for this purpose. For example, in JDT, there’s “org.eclipse.jdt.core”, “org.eclipse.jdt.ui”, and “org.eclipse.jdt.internal.core” and “org.eclipse.jdt.internal.ui”. Note that “internal” is the root of all internal packages; you should not name the internal packages, for example, “org.eclipse.jdt.core.internal” and “org.eclipse.jdt.ui.internal”. This makes it easier for users browsing the packages to recognize internal packages.
  5. Use interfaces. Interfaces may have different purposes:
    • Provide different implementations for the same goal. The typical example is a list, which may have different implementations for different performance use cases (LinkedList, ArrayList, etc.).
    • Allow criteria modification. For example, a sort function may accept a Comparable interface in order to provide any kind of sort criteria, based on the same algorithm.
    • Hide implementation details. This also makes it easier for a user to read the comments, since in the body of the interface there are only methods, fields and comments, no long chunks of code to skip.
  6. Use the I prefix for interfaces. This maks it easier for a user to recognize an interface.
  7. Treat interfaces that have one implementation differently. Usually interfaces that are used to hide implementation details have a single implementation in the whole system. In these cases:
    • Don’t prefix a name with implementation details. For example, there could be an IUser interface which has an implementation based on a database. Don’t name it DatabaseUser if the chances of changing the implementation are very low; User is enough, with a comment saying “implementation of IUser using a databasea”. Long names are harder to read. The User class should be in an internal package.
    • Use casts without fear. You interfaces return and accept IUser instances. Since they are interfaces, you might think you need to put in the IUser interface every method needed to accomplish client tasks as well as internal tasks. This is not true. Provide interface methods for things a client might need, and in method implementations cast to the single implementation and use the internally available methods. IUser should be marked with a comment saying a client should not implement it.
  8. Implement toString() as much as possible. Ideally, every class should implement the toString() method. When you are debugging in Eclipse, it’s much easier to see important details of a class by seeing it’s toString() information instead of manually expanding lots of nodes. You should’t worry about performance details in this method.
  9. Prefer packages with lots of classes than lots of packages with two or three classes. Having too many packages makes it difficult for a user to browse the source code.
  10. Write all comments in english. Although in an ideal world I would recommend doing it so in a neutral language, like Esperanto, there’s a high chance someone from another country will need to understand your code.
  11. Write tests, even if it seems impossible to do so. For example, if you need to debug a web page, how can you test correct use of the Request and Response classes? Abstract them with an interface that only provides the methods needed by your application, and use mocks in the tests. Also, try to make your tests as short and self-explaining as possible. If you need to write utility classes just for tests, do so, you won’t be losing time.
« Previous Page