Tag: uiml.net

Modifying a UIML interface from the application logic

As I posted in an earlier article, Uiml.net allows us to connect the application logic with the user interface.

I showed that it’s possible to create a callback that listens to certain events, optionally only coming from a specific part. In these callbacks we can examine the part that has sent the event using the Uiml.net API.

But is it also possible to modify that part?

Of course we could operate on the widget-set specific user interface object (e.g. a System.Windows.Forms.Button), but that would require different code for each target widget set. Here is how we would change a button’s label when it is clicked using this approach:

public class ModifyTest
{
  public ModifyTest()
  {
    ...
 
    // connect only to the hello button
    uimlDoc.Connect(this, "b_hello");
 
    ...
  }
 
  [UimlEventHandler("ButtonPressed")]
  public void OnButtonClicked(Part sender, UimlEventArgs e)
  {
    // get the concrete UI object
    System.Windows.Forms.Button b = (System.Windows.Forms.Button) sender.UiObject;
 
    // change its text to 'Do it again!'
    b.Text = "Do it again!";
  }
}

Uiml.net provides a property setter interface that can apply any property. We only need the renderer instance in order to access it. We could use this API to modify the user interface in a generic way, if we rely on a shared class and property among all widget set vocabularies. In our example, the Button class exists for all vocabularies that Uiml.net supports, and has a label property in each vocabulary.

Let’s have a look at the generic solution. We only list the important code:

public class ModifyTest
{
  IRenderer _renderer;
 
  ...
 
  [UimlEventHandler("ButtonPressed")]
  public void OnButtonClicked(Part sender, UimlEventArgs e)
  {
    // create a label property
    Property p = new Property();
    p.PartName = sender.Identifier;
    p.Name = "label";
 
    // set its value to 'Do it again!'
    p.Value = "Do it again!";
 
    // apply the property on the sender part
    _renderer.PropertySetter.ApplyProperty(sender, p); 
  }
}

CADUI 2006

This week, I was in Bucharest for CADUI 2006. I presented the demo paper Kris, Kristof and I submitted for the conference (A Generic Approach for Multi-Device User Interface Rendering with UIML). Actually I am still in Bucharest at the moment, tomorrow I’m flying back to Belgium.

CADUI was the first conference I ever attended. At first, I didn’t really know what to expect, but it turned out to be a very pleasant experience. I met a lot of nice people, and saw interesting talks. CADUI is a very friendly conference, which resulted in a comfortable atmosphere that only further fueled the interaction.

After the last presentation today, there were books handed out from Springer-Verlag for the best paper and best talk, and also a lottery giving away another four books amongst the participants of the conference. The best paper was A Generic Approach for Pen-based User Interface Development by S. Mancé and E. Anquetil, which describes a pretty impressive system.

First I won a book from the lottery, and then I also got the best talk award! So my backpack is going to be a bit heavier on the way back I guess

Connecting the application logic with the user interface in Uiml.net

Let me warn you first, this will be a long blog post.

Creating a cross-platform user interface with Uiml.net is one thing, actually getting it to do something useful by interacting with the application logic is another issue.

Currently, the logic element in UIML only specifies the class of object associated with a call element. This implies that the objects are stateless or static and that the UIML rendering engine will instantiate the object each time a call is made.

Here’s a simple example:

<call name="Console.println">
  <param>Uiml says hello!</param>
</call>
...
<logic>
  <d-component id="Console" maps-to="System.Console">
    <d-method id="println" returns-value="void" maps-to="WriteLine">
      <d-param id="message" type="System.String"/>
    </d-method>
  </d-component>
</logic>

Of course, in this example that’s fine, because the Console class only has static methods. It doesn’t have a state we wish to monitor in the user interface. When we want to interact with a database connection for example, things become more difficult.

One way to solve the problem would be to develop a mechanism to specify which instance of an object will be referenced by a specific call. This would allow multiple instances of the same external object to exist within the system and be referenced separately.

However, in our opinion this would only complicate the application logic binding mechanism and the UIML language itself.

Uiml.net provides an API that allows multiple object instances to be connected to the same user interface. When a call to the application logic is made, we first check if a call can be invoked on one of the connected object instances. When that fails, we’ll try to invoke it statically liked we did before.

If we call a certain method, all connected objects will invoke this method. There’s a catch though. When the call has to return a value, which return-value do we use? We suggest to use the return-value of the object that was connected last. Considering the fact that each invocation may have an effect on the other connected objects, this is the most sensible thing to do.

This API has been supported in Uiml.net for a while now (in fact, I completed the implementation during my internship in July 2004, building upon Kris ideas). Unfortunately we hadn’t communicated it very well. Hopefully this blog post is a start. I will probably also provide some example in the future.

Following is a simple example with a modification of the UIML calculator. When you hit the = button, the contents of the output entry will be sent to the Print method of an instance of the CalcInspector class. Depending on a member _times, this value is written out _times times:

<behavior>
  ...
  <rule>
    <condition>
      <event part-name="bsol" class="ButtonPressed"/>
    </condition>
    <action>
      <call name="CalcInspector.Print">
        <param>
          <property part-name="output" name="text"/>
        </param>
      </call>
    </action>
  </rule>
  ...
</behavior>
...
<logic>
  <d-component id="CalcInspector" maps-to="CalcInspector">
     <d-method id="Print" maps-to="Print">
      <d-param id="output" type="System.String"/>
    </d-method>
  </d-component>
</logic>
...
public class CalcInspector 
{
  int _times;
  public CalcInspector(int times)
  {
    _times = times;
  }
 
  /// <summary>
  /// Prints the output _times times.
  /// </summary>
  public void Print(string output)
  {
    for(int i = 0; i < _times; i++)
    {
      Console.WriteLine(output);
    }
    Console.WriteLine("...Done!");
  }
}

The relevant code when the interface is rendered:

CalcInspector small = new CalcInspector(2);
CalcInspector large = new CalcInspector(5);
 
uimlDoc.Connect(small);
uimlDoc.Connect(large);

As you can see, we created two CalcInspector instances: small and large. One will write the output two times while the other will print it five times. Following are two screenshots on a PDA, one just before pressing the = and one right after:

[img:113715576,medium]

[img:113715577,medium]

Since we connected small first, small‘s Write method will be executed first.

We also implemented a connection to other way around. It allows the application logic to subscribe to certain events from the UIML user interface. This was originally inspired by the connection mechanism of Glade. We wanted an easy and convenient way to connect with the rendered user interface. Uiml.net takes advantage of the .NET framework‘s basic support for aspect-oriented programming to realize this. Methods, classes, variables and the like can be augmented with so-called attributes. These attributes can then be queried using reflection. The instances are again connected in the same way as in the previous example.

The attribute UimlEventHandler specifies that a method can deal with user interface events. Parameters can be passed with the attribute that specify the information the method wants to receive together with the event.

[UimlEventHandler("ButtonPressed")]
public void OnButtonPressed(Part sender, UimlEventArgs a)
{
  Console.WriteLine("Received event from a part:");
  Console.WriteLine("\tApparantly it's the \"{0}\" part",
                    sender.Identifier);
  Console.WriteLine("\tIt's class is <{0}>", sender.Class);
  Console.WriteLine("\tThe UI object is of the type [{0}]",
                    sender.UiObject.GetType());
  }
}

In this example, the method would receive every ButtonPressed event. It then writes out from which part it got the event. It writes out its class, and the class of the actual underlying user interface object. So in fact the application logic queries a piece of the part tree, in which a lot of information is present.

But we could go further:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[UimlEventHandler("ButtonPressed", "fr", "l_recent")]
public void OnButtonPressed(Part sender, UimlEventArgs a)
{
  Part fr = a.GetPart("fr");
 
  Console.WriteLine("\nPart \"{0}\" of type <{1}> has" + 
                    "the following subparts:", fr.Identifier, fr.Class);
 
  System.Collections.IEnumerator e = fr.GetSubParts();
  while(e.MoveNext())
  {
    Part sub = (Part)e.Current;
    Console.WriteLine("\t\"{0}\" of type <{1}>;",
                      sub.Identifier, sub.Class);
  }
 
  Part l_recent = a.GetPart("l_recent");
  string propertyName = "text";
  Console.WriteLine("The [{0}] property of part \"{1}\"" +
                    " is: {2}", propertyName, l_recent.Identifier, 
                    l_recent.GetProperty(propertyName));
}

Since this is a lot of code, we’ll go over it gradually.

1
[UimlEventHandler("ButtonPressed", "fr", "l_recent")]

The first line specifies that we are interested in ButtonPressed events. We also request the parts fr and l_recent from the user interface, so we can examine them. These parts will be collected in the UimlEventArgs parameter.

4
Part fr = a.GetPart("fr");

This line gets the fr part from the event arguments.

The next few lines go through all of fr‘s children, and writes them to the console:

9
10
11
12
13
14
15
System.Collections.IEnumerator e = fr.GetSubParts();
while(e.MoveNext())
{
  Part sub = (Part)e.Current;
  Console.WriteLine("\t\"{0}\" of type <{1}>;",
                    sub.Identifier, sub.Class);
}

In a similar fashion, we request the l_recent part:

17
18
19
20
21
Part l_recent = a.GetPart("l_recent");
string propertyName = "text";
Console.WriteLine("The [{0}] property of part \"{1}\"" +
                  " is: {2}", propertyName, l_recent.Identifier, 
                  l_recent.GetProperty(propertyName));

Here we write out l_recent‘s text property. So it is also possible to request properties from a part, and query their value. In fact, the whole Uiml.net API is available through this mechanism.

One might wonder, what if the application logic is only interested in certain events from a specific branch of the part tree? This is possible by adding an additional parameter to the Connect method, specifying which part and its subchildren it should connect to:

uimlDoc.Connect(this, "l_recent");

Cassowary.net 0.2.2

I released an minor update of Cassowary.net today.

Jan Meskens is currently working on the standards compliance of Uiml.net for his Bachelor’s thesis. He also generated some API documentation, which brought up a bug in Cassowary.net. I forgot to add the ClParser class to the Cassowary.Parsing namespace. It had been in the global namespace all along.

XML-RPC support for Uiml.net

I meant to blog about this a long time ago, but I never actually got to it. In August, I implemented an extension to the call mechanism in Uiml.net that allows a UIML interface to call external application logic via the XML-RPC protocol.

I made an example UIML interface, which connects to the UserLand Betty server at betty.userland.com. It then resolves the state name from a state code entered by the user. Here are some screenshots of the rendered interface:

Uiml.net XML-RPC connectivity

Uiml.net XML-RPC connectivity We use the standard UIML call tag. Here’s how we specify the behavior of the user interface:

<behavior>
  <rule>
    <condition>
      <event part-name="go" class="ButtonPressed"/>
    </condition>
    <action>
      <property part-name="stateName" name="text">
        <call name="Betty.GetStateName">
          <param>
            <property part-name="stateCode" name="text"/>
          </param>
        </call>
      </property>
    </action>
  </rule>
</behavior>

The XML-RPC web service is described in the logic part like this:

<logic>
  <d-component id="Betty" location="xmlrpc://betty.userland.com/RPC2">
    <d-method id="GetStateName" returns-value="System.String" maps-to="examples.getStateName">
      <d-param id="code" type="System.Int32"/>
    </d-method>
  </d-component>
</logic>

What has changed is that Uiml.net now checks for a protocol handler in the location attribute. If it’s xmlrpc://, we try to resolve the call using XML-RPC. Remember that local calls just specify the maps-to attribute.

We didn’t implement XML-RPC communication from scratch, but used a simple XML-RPC library for .NET: XmlRpcCS. The project seems to be dead since 2003, but it still works fine.

Takis has provided packages for XmlRpcCS (xmlrpccs) itself and for the dynamic Uiml.net XML-RPC glue library (uimlnet-xml-rpc).