SVG-Based User Interface Framework

Keywords: SVG, User Interfaces, XSLT, CSS, Graphical Stylesheet

Alastair Fettes
University of Victoria
Faculty of Engineering
Victoria
British Columbia
Canada
afettes@engr.uvic.ca
http://www.engr.uvic.ca

Biography

Alastair Fettes is currently in his final year of Computer Engineering at the University of Victoria will graduate in April of 2005. Alastair is a major contributor to the SPARK project (http://www.schemasoft.org) to create an open source SVG based user interface framework. He enjoys many physical activities including rollerblading, skateboarding, soccer, ultimate and frisbee golf.

Philip Mansfield, Ph.D.
President
SchemaSoft
Vancouver
British Columbia
Canada
philipm@schemasoft.com
http://www.schemasoft.com

Biography

After receiving his Ph.D. in Mathematical Physics from Yale University in 1989, Philip spent a year as Assistant Professor of Physics at Knox College, followed by four years as Assistant Professor of Mathematics at the University of Toronto. His background in Differential Geometry and in computer modelling of physical phenomena served as unorthodox preparation for his subsequent move into industry as a Software Engineer with an emphasis on Computer Graphics. By 1997 Philip was in charge of a software research team creating early Web technologies based on HTML, XML, CSS and Java. Philip now lives and works in Vancouver, Canada, where he is President of SchemaSoft (http://www.schemasoft.com/), a software development consulting company he co-founded in 1999. He is an Advisory Committee Representative of the World Wide Web Consortium (http://www.w3.org/), has been a member of the W3C Scalable Vector Graphics Working Group (http://www.w3.org/Graphics/SVG/) since its inception in 1998, and was chief organizer of the SVG Open 2003 conference (http://www.svgopen.org/2003/). Philip is Chair of the BC Advanced Systems Institute International Scientific Advisory Board (http://www.asi.bc.ca/). He is also a Director of the Vancouver XML Developers Association (http://www.vanx.org/), an organization that he co-founded in 2000. He regularly writes and lectures on topics related to software engineering, XML and SVG.


Abstract


The purpose of the SPARK project is to create a flexible, interoperable SVG-based user interface framework. Using well established and standardized languages including SVG, XML, Java and IDL, we went about creating a framework that could easily be used by others to rapidly develop SVG based applications or prototypes.

This project was approached as a full software engineering system architecture project. After the initial proposal the project went through a risk analysis phase to decide upon the main goals to be completed throughout the term. After the risks had been analyzed and mitigation strategies had been created, the design entered the design stage.

The design stage consisted of a number of smaller iterations. First a set of class diagrams were created. During the creation a number of design patterns were selected that would best solve many of the interoperability risks that were discovered in the risk analysis stage. The class diagrams themselves were fluid and continually updated once architecture problems had been discovered. A helpful step that was done during the creation of the class diagrams was to create Interface Definition Language (IDL) files for each of the modules. This once again was used to give us a better perspective on how the classes would work together.

Once the initial class diagrams had been created the process of creating the different interfaces and classes began. It was decided to write these in the Java programming language even though the final target language was ECMAScript. The reason for this is that ECMAScript does not support true object oriented programming. Classes in ECMAScript are not so much classes as methods (functions) with attributes and their own functions. ECMAScript also does not support interfaces and can be very hard to understand the relationship between classes. Therefore the entire framework was created in a rough draft using Java. A side benefit of this process was the ability to produce JavaDoc documentation for the framework from these completed class files.

During the design stage of the project lifecycle widgets and applications were made throughout to test the different aspects of the framework. Many problems were discovered during this prototype stage including a problem that was actually a duplicate of a problem created with the Java 1.1 language. Cascading Observer calls throughout the UI hierarchy added significant lag and efficiency reductions. It was from these trials that the final class diagram (listed within) was completed. After the widgets had been stabilized then applications could be created.

Unfortunately there were not a great number of applications created due to time limitations. On a side note a fellow by the name of Bernd Seidenspinner created his own application using an earlier version of the framework and emailed the demo to Alastair. This demonstration application was a significant example of how easy to use the UI framework was. The problems that Bernd noted had during development we had also noted and had already made steps to mitigate these problems. The fact that a great number of applications were not made is unfortunate however, the fact that someone in Germany was able to create their own application is a great testament to the flexibility and ease of use of the framework.

The final results of the project must be considered a success. An entire framework has been created and used by an individual on the other side of the world. Widgets and applications may be created independently and easily. The risks discovered during the risk analysis stage have all been mitigated and the resulting framework is complete.


Table of Contents


1. Introduction
2. Project Risks and Goals
     2.1 Cardinal Aims
     2.2 Secondary Aims
     2.3 Tertiary Aim
3. Patterns
     3.1 Model-View-Controller
         3.1.1 Model
         3.1.2 View
         3.1.3 Controller
     3.2 Container
     3.3 Observer
     3.4 Command
     3.5 Factory
     3.6 Decorator
4. Framework
     4.1 Overview
     4.2 Interfaces
         4.2.1 Observer and Subject
              4.2.1.1 API Description
         4.2.2 Command and Command Holder
              4.2.2.1 API Description
         4.2.3 SPARKFactory
              4.2.3.1 API Description
     4.3 Widget Class
         4.3.1 SVG
         4.3.2 API Description
     4.4 Atom Class
         4.4.1 SVG
         4.4.2 API
     4.5 Container Class
         4.5.1 SVG
         4.5.2 API Description
     4.6 SPARK Class
         4.6.1 API Description
     4.7 Widgets Module Class Diagram
     4.8 Widgets Module IDL Definitions
5. Skinning
     5.1 Skinning With CSS
     5.2 Skinning With XSLT
6. Framework Helpers
     6.1 SPARKHelperFactory Class
         6.1.1 API Description
     6.2 SPARKHelperDecorator Class
         6.2.1 API Description
     6.3 Helper Module UML Diagram
     6.4 Helper Module IDL Definitions
7. Future
     7.1 Framework Development
         7.1.1 Widgets
         7.1.2 Skins
         7.1.3 Applications
     7.2 sXBL
     7.3 Framework v2.0
8. Conclusion
Acknowledgements
Bibliography

1. Introduction

The purpose of this project was to create a framework that describes a set of rules and techniques for creating SVG user interface widgets. The architecture describes the interfaces that the differently widget types must follow in order for the interoperability of the widgets.

There are two distinct yet intertwined sides of the framework - SVG (Scalable Vector Graphics) [SVG] and ECMAScript (European Computer Manufacturers Association Script) [ECMAScript] . The SVG describes the Model (data) and the View (visual) while the ECMAScript describes the controller. The SVG has been structured to a certain extend to enable interoperability while leaving it flexible enough such that UI (User Interface) developers may create visually stunning and impressive applications and have full control over the look and feel. Using CSS (Cascading Style Sheets) [CSS2] in conjunction with the SVG the UI developer has even more control over the visual representation of their application.

The following paper describes the process followed during the life cycle of the project and gives a detailed account of the final results.

2. Project Risks and Goals

2.1 Cardinal Aims

This project has two main aims/goals. A failure to fulfill both these aims results in the failure of this project. They are as follows:

Cardinal Aims
  1. Component Reuse
  2. Ease of Use

The aims are defined as:

Component Reuse
Component reuse is very important to the success of the project. The goal is to create not just a framework but an entire application development kit. The term kit refers to the idea that application developers may download the kit and immediately reuse prebuilt components in their own application. A failure to have this functionality will immediately result in the failure of the project.
Ease of Use
Ease of use refers to the ease with which someone knowledgeable in the area of SVG will have with implementing the given solution. If someone who is somewhat knowledgeable with the subject has immense difficulty creating applications using the resultant framework then the project has failed.

From these two goals it is possible to construct a Cause-Effect tree:

riskdiagram.jpg

Figure 1: Cause-Effect Tree

From this Cause-Effect tree a number of other risks are deduced and are listed as secondary aims of the project.

2.2 Secondary Aims

The two major risks discovered during the risk analysis stage led to the discovery of a number of sub-risks that could result in project failure. These risks are listed as follows:

  1. Follow Software Engineering practices
  2. Interoperable
  3. Well defined
  4. Framework
  5. Declarative
  6. Well Engineered
  7. Skinnable

Therefore as these risks could result in project failure they then become secondary aims of the project. These secondary aims are then defined as follows:

Follow Software Engineering practices
Following Software Engineering practices will help mitigate the risk of the lack of component reuse. Following Object Oriented design techniques will allow the architects to discover architectural flaws before the completion of the framework and prevent such problems. Software Engineering practices include following Object Oriented software design using class diagrams and interaction diagrams. It includes well-documented code. Finally it includes using previously discovered and well-documented design patterns. This aim works to mitigate the risk of "Components not Reusable" (see Section 2.1 ).
Interoperable
Interoperability is intrinsic to the creation of reusable components. Interoperable is defined as "able to exchange and use information" [Wordnet] . For this project this pertains to the creation and subsequent reuse of created components. The idea that components may be created for one application and reused in another, thus reducing development time for SVG based applications. Also it pertains to components that work with each other in a standard way. This aim works to mitigate the risk of "Components not Reusable" (see Section 2.1 ).
Well defined
The term well defined refers to a standard that is static (as opposed to dynamic). This means that the solution has been created, is in place, requires no changes and will not change in the near future. If the solution is not well defined it is impossible to implement else many applications would become outdated and inoperable before they are completed. A well defined standard will also avoid floating requirements and the failure to complete the project. This aim works to mitigate the risk of "Software Engineering Practices not followed" (see Figure 1 ).
Framework
The term Framework is defined as follows "a simplified description of a complex entity or process; the underlying structure" [Wordnet] . For this project the framework refers to a set of API (Application Program Interface) , SVG structures and techniques that must be followed to create and use user interface components that they themselves follow this framework. Other examples of user interface frameworks include Java Swing, Microsoft MFC and Microsoft .Net frameworks. This goal works to mitigate the risk of "Not interoperable" (see Figure 1 ).
Declarative
Currently there are a number of solutions for SVG applications that are non-declarative in nature. By declarative it is meant that one may create the majority of the application by writing SVG as opposed to writing script only. Declarative solutions do not necessarily rely on script engines for viewing (only for using) and are generally easier to create and to understand. Therefore this goal works to mitigate the risk of "Not easy to use" (see Section 2.1 ).
Well Engineered
When creating system architectures there is a natural tendency to over engineer them and thus create an all too restrictive template for others to follow. This goal refers to the need to create a minimalistic approach to system architecture. Creating rigid standards yet leaving room for creativity and flexibility will let the developer have more control while retaining required facets of the architecture (such as interoperability). This goal works to mitigate the risk of "Not easy to use" (see Section 2.1 ) by retaining flexibility in the standard for the developer and thus removing as many restrictions as are deemed non-necessary to enforce the other cardinal aim of reusable components.
Skinnable
Finally it is extremely important for the architecture to allow the skinning and thus customization of the application user interface. Skinning refers to both visual structures and visual color changes. Allowing developers to customize the look and feel of the application while not changing the underlying functionality will help to increase the popularity and usability of the architecture. Examples will be given in detail later. This works to mitigate the risk of "Not easy to use" (see Section 2.1 ).

2.3 Tertiary Aim

Finally, in accordance with the W3C (World Wide Web Consortium) WAI (Web Accessibility Initiative) group the final goal of this project is to enable accessibility of applications created using the framework. Accessibility will not be strictly enforced though there will be guidelines in place to enable accessibility and attempt to lean the application developer towards creating accessible solutions.

3. Patterns

3.1 Model-View-Controller

The MVC (Model-View-Controller) architectural design pattern is a very useful, successful and widely used pattern. The idea is to separate the different parts of an application into three separate categories (layers):

There are a number of benefits from creating applications that follow this design pattern. It gives the programmer the ability to have multiple views of the same model. Another important result is code separation. Applications and components become easier to understand and fix as a change in the UI code does not affect other parts of the application. The net result of this is reduced bugs and fix times for application developers - a very important goal in any software project.

The framework uses the MVC pattern in two distinct ways: for widgets and for applications. Each widget defines its own Model, its own Controller and its own View. The application itself has its own View (the UI components), its own Controller (the logic that interacts with the components) and its own Model (state information and business logic).

3.1.1 Model

The model defines the state information or business logic of the software component. The model by itself simply contains information about the application and its current state. For this project in particular it is used to store information about UI widgets. Examples include things such as if a button is on or off, the current value of a slider, etc. For the SVG based UI framework this is implemented through the metadata element and is described in detail later.

3.1.2 View

The view gives us the visual representation of the model. An MVC based application should enable the developer to change the view without effecting the functionality of the application. Of course there are limits and this statement should not be taken out of context. The direct correlation between this and the SVG-UI framework is the idea of skinning. The ability to give the interface a different look (through the use of SVG skinning and CSS). An example could be using a rect instead of a circle for the visual representation of a radio button. The underlying code base does not need to be changed when it is changed from a circle to a rect, only the actual look of the widget itself.

3.1.3 Controller

The controller acts as the link between the Model and the View. The controller generally is in charge of handling events generated by both the user and the application. To use a metaphor, the model is the applications DNA, the View is the applications skin/hair/eye color/etc, and the controller is nervous system.

3.2 Container

The Container pattern has been chosen as an attempt to reduce the base complexity of widgets. Every widget may be broken down into either a composite (Container) or an atomic (Atom) widget. Atoms are defined as in nature such that they may contain no other Atoms. A Container is described in the fashion of molecule in nature such that it may contain Atoms and/or Containers.

The separation of duties is important for reducing the complexity of the framework. If a widget is known to be an Atom, then the widget developer may develop their widget knowing full well that it will never contain any other widgets and thus remove a great deal of code to handle this case.

Container widgets have the ability to use other widgets themselves to complete their task. Of course this does add problems for interoperability. A Container widget could expect to get notified of a particular action from an Atom or Container widget that it itself contains. If that Atoms or Container is then changed to not notify it's Observers (see Section 3.3 ) upon that action then the holding Container will now not work correctly. Therefore it is up to the widget developers to ensure that widgets keep the same notification rules for upgrades or changes to the widgets. This is left up to the widget developers to decide upon and is out of the scope of this project. This project is to create a framework such that this communication is enabled.

3.3 Observer

The Observer pattern describes a publish/subscribe relationship between software components. There is a many-to-many relationship between Observers and Subjects. An Observer may watch 0-N Subjects, and Subjects may be observed by 0-N Observers. An Observer informs another component (a Subject) that it wishes to be notified when that component changes state (does something). When the component (a Subjects) changes state in some form or another it notifies all of its Observers with this fact.

The Observer pattern is used for widget to widget communication in the framework. The rules for notification are somewhat relaxed from the original pattern specification. Due to the possibility of cascading notifications, a Subject may not always notify its observers of a change. The state changes that do signal this notification must be well documented by the widget developer. Once again this avoids cascading notifications up the Observer-Subject dependency tree and is done to mitigate any adverse efficiency problems. This problem was found in the Java 1.1 release and was then fixed with the release of Java 1.2.

The Observer pattern implementation used by the framework is described in detail in Section 4.2.1 .

3.4 Command

The Command pattern also describes public/subscribe relationship between software components. The reason that the Command pattern has been used in the framework is to accommodate widget-application communication. Widgets are known as CommandHolders and the application use cases are implemented as Commands. Once again there is a many-to-many relationship between Commands and CommandHolders. A CommandHolder may hold 0-N commands. A Command may be added to any number of CommandHolders.

The rule for execution of commands should follow the rules of the Observer pattern (see Section 3.3 ). A widget must have a well defined behaviour when it comes to execution of Commands. An example is for a button. When that button is pushed the Command should be executed. It is unlikely that a Window would execute Commands though it is very likely that its components would. This of course is up to the widget developers and is used by the application developers. There is no Command dependency tree so therefore it is not possible to have cascading Command execution.

The Command pattern implementation used by the framework is described in detail in Section 4.2.2 .

3.5 Factory

The Factory pattern is a fairly common and widely used design pattern for object instantiation. It was chosen to give the application developer the greatest flexibility when creating their application. The Factory is used to instantiate widgets and handles all decision logic that accompanies that instantiation. The Factory pattern implementation used by the framework is described in detail in Section 6.1 .

3.6 Decorator

The Decorator pattern is a perfect design patter for user interfaces and specifically the given framework and its accompanying development kit. The intent of the Decorator pattern is to "attach additional responsibilities to an object dynamically" [Design Patterns] . The Decorator is passed the widgets and adds application specific logic to individual instances of UI components. The frameworks' implementation of the Decorator pattern is described in detail in Section 6.2 .

4. Framework

4.1 Overview

The initial framework must describe all of the following: widget authoring, widget-widget communication, application-widget communication and application- server communication. Widget authoring describes the process by which a Widget ( A component of a whole - in this case refers to a user interface component ) is created. Widget-widget communication refers to the process by which widgets interact within the application amongst themselves. This communication is independent of the widget-application communication. Both of these are internal to the framework and are not dependant upon external entities such as an application.

The framework must also describe the external Communications - those Communications that travel outside of the GUI (Graphical User Interface) itself. These include widget-application interactions as well as application- server interactions. Without a standard Communication system between the GUI and the application the framework is rendered useless. Also, without a standard communication system for application-server interactions the framework may be pigeonholed and ignored.

The most important of these four initial framework definitions stated above are the widget authoring, widget-widget communications and the widget-application communication. The application-server Communication is less important specifically because initially there is no need to standardize it. This interaction may still be accomplished without a standard in place and therefore becomes less important in the creation of the framework. It is still important to standardize this at some time in the future but it is outside the scope of this initial report.

4.2 Interfaces

All interfaces used in the framework have been explained in terms of the design pattern they implement, their API and their IDL (Interface Definition Language) . The latter two are given so as to better explain in both words and in code exactly what the functions are and how to use them for developers. Some interfaces are useful only to Component developers while others are only useful to Application developers. It is however useful to be versed in the entire framework so that one may have a more thorough understanding of the interactions that are present within the application.

4.2.1 Observer and Subject

Both Observer and Subject are part of the Observer design pattern (see Section 3.3 ). These two interfaces are used as the communication medium for widget-widget interaction and communication. Containers are both Observers and Subjects at the same time while Atoms are only Subjects.

observerpattern_small.png

Figure 2: Observer Pattern UML Diagram

4.2.1.1 API Description

The following is the API description for the Observer interface:

public void update( in_subject: Subject );
The update function is used as the communication line between the Subject and the Observer. The update function will be called when the subject has some predetermined state change. It contains widget specific logic.
An example would be with a Radiobutton and Radiobutton Group widget observer -subject pair. The Radiobutton would call update when it is clicked and the Radiobutton Group, inside the update function would either directly or indirectly (through another function call) uncheck the previously checked Radiobutton.

The following is the API for the Subject interface:

public void attach( in_observer: Observer );
This function is used to add the given Observer to the list of Observers currently watching this particular Subject.
public void detach( in_observer: Observer );
This function is used to remove the given Observer from the list of Observers currently watching this particular Subject.

4.2.2 Command and Command Holder

The following is the frameworks implementation of the Command pattern (see Section 3.4 ). These interfaces are used to enable interaction between the widgets and the application. Generally speaking every Widget is a CommandHolder but does not necessarily hold any Commands. Commands are generally implemented as application use cases. They are executed when a specific state change happens in the CommandHolder.

commandpattern_small.png

Figure 3: Command Pattern UML Diagram

4.2.2.1 API Description

The following is the API for the Command interface:

public void execute();
This function is called by the CommandHolder upon a state change in that object. This method contains the application use case logic and is part of the application, not the UI framework. This is the main connection point between the framework and the application.
This function should execute application specific logic.

The following is the API for the CommandHolder interface:

public void addCommand( Command in_command );
This function is used to add Commands to a CommandHolder. The given command (in_command) is added to the CommandHolders list of Commands to execute upon a well defined state change. If the given command is already in the set of Commands that the CommandHolder contains nothing will happen.
This function is generally called through the SPARKHelperDecorator (see Section 6.2 ) class in it's decorate function.
public void removeCommand( Command in_command );
This function is used to remove Commands from a CommandHolder. The given command (in_command) is the command that will be removed. If the given command is not actually a command already stored in the CommandHolder, nothing will happen.

4.2.3 SPARKFactory

The SPARKFactory is a simple interface stub that is used in conjunction with the SPARK class (see Section 4.6 ) itself. An application developer must implement this interface and both of it's functions for the framework to work correctly. The reason for this is that widgets assume that the SPARK class contains a class of type SPARKFactory and will request it to create new widget instances at various times during the execution of the program. A standard CustomFactory is pre-build and included in the Helper package. This interface is in place in case the developer wishes to have more customization abilities over their application and the creation of their widgets.

sparkfactory_small.png

Figure 4: SPARKFactory UML Diagram

4.2.3.1 API Description

The SPARKFactory has been given a necessarily simple API . The reason for this is to make it easier for application developers to customize how their applications are loaded.

public Widget createWidget( in_node: SVGElement );
Using the given SVGElement (in_node) the Factory will attempt to instantiate the appropriate widget class and return an instance of that Widget. Failing that it will return null as the creation has failed.
public void createContents( in_node: SVGElement, in_container: Container );
Given the input SVGElement (in_node) that follows the Container- Construct (see Section 4.5 ) and the owner Container instance, the Factory will instantiate every contained widget and add it to the given Container (in_container).

4.3 Widget Class

The Widget class is the super class for all Widgets in the SPARK framework. Every widget has two distinct parts: SVG and Script. The script has been well standardized and documented in this report and is necessary to implement the Controller layer for the Widget (see Section 3.1 ).

The SVG however has been standardized for different reasons. The SVG itself contains both the view and the model for each and every widget. The structure has been standardized such that applications may be declaratively created by UI developers without any prior knowledge of how the script itself works. The net result is that entire applications may have their user interfaces completely authored in SVG alone. Then it is up to the application developer to add the use cases to implement the application logic.

A side bonus of standardizing the SVG (as has been done below) is that the framework is then ready to be used in a WYSIWYG (What you see is what you get) UI authoring application. The standard SVG structure has been created such that a WYSIWYG application can simply insert the appropriate SVG into the root document in. This then allows very, very quick prototyping and/or application development. The specific details regarding containers is discussed in Figure 11 .

widget_small.png

Figure 5: Widget UML Diagram

4.3.1 SVG

All widgets must conform to a specific SVG structure.

<g id="uniqueID" class="SPARK widgetType WidgetName CSS">
    <desc>Required - Widget accessibility description</desc>
    <metadata>Optional - Model storage location</metadata>
    ... any svg content ...
</g>

Figure 6: Widget SVG Template

The generic SVG structure has been defined in this structure for a number of reasons that are discussed below. The specific requirements are as follows:

"id" Attribute
SVG enforces unique id's throughout an entire SVG document. This lends itself well to UI definitions. Requiring every widget to have a unique id is a very standard practice and this defines the location where it is known that the id of a widget may be found.
"class" Attribute
The use of the class attribute to define a widget is an idea that Glenn MacDonald and Philip Mansfield first started using. By defining the exact structure of the ordered list in the class attribute one may confidently realize the exact widget type that is described within the group tags. This may be matched versus a regular expression and is used extensively during the dynamic loading process to connect the SVG to the script/code controller.
<desc/>
The use of the desc element is two fold. Firstly it enables applications to be accessible and secondly it allows a guaranteed anchor point for the controller to the SVG (if required). Though in the end accessibility is still the responsibility of the SVG author.
<metadata/>
This is an optional element that can be used for storing custom model information. An example would be as follows: <metadata>foo</metadata> or <metadata><SPARK pos="0.5" delta="0.1"/></metadata>. It is up to the widget author to define their own expected model structure. There is a possibility that in the future a standard model definition will be created (with the ability to customize). NOTE: The structure for metadata model information has yet to be formalized and therefore it is up to the widget author to specify exactly how the model stores information.

4.3.2 API Description

The Widget class has the following API as well as the API defined for the CommandHolder interface (defined in Section 4.2.2.1 , i.e. Widget implements CommandHolder):

public Object getState();
Retrieves the current state of the object. The Object that this returns is strictly up to the widget developer to decide and thoroughly document.
public void setState( Object in_state );
Sets the current state of the widget. The Object parameter should conform with the guidelines that the widget developer has laid out and documented.

4.4 Atom Class

The Atom is the most basic widget type in the UI framework. It is used as an endpoint with the fact that it may contain no other widgets. A simple example of an Atom widget would be a Radiobutton or a Button. A Slider would not however be considered an Atom due to the fact that a Slider may be considered to contain two buttons (left/right or up/down arrows). The Atom class inheritance UML is found in Figure 7 .

atom_small.png

Figure 7: Atom UML Diagram

4.4.1 SVG

The SVG format for the Atom widget is generally the same as the SVG format defined in Figure 6 , with a minor change to the class attribute. The class attribute is now standardized to be "SPARK atom AtomClassName", with AtomClassName being the name of the Atom class that was created and this SVG code block refers to.

<g id="uniqueID" class="SPARK atom AtomClassName">
    <desc>Required - Description</desc>
    <metadata>Optional - Model</metadata>
    ... Any SVG content (View)...
</g>

Figure 8: Atom SVG Template

Once again any SVG content is allowed once the required pieces have been added. This has been done to give the UI programmer the greatest flexibility for look and feel. They may create as much or as little SVG structure for styling the widget that they deem necessary. An example of an Atom SVG structure is shown in Figure 9 . Note how it still conforms to the basic Atom SVG structure defined in Figure 8 and is therefore valid atom-widget SVG.

<g id="button1" class="SPARK atom Button" transform="translate(100,100) scale(2)">
    <desc>This button is pressed to popup a message listed in the metadata.</desc>
    <metadata>Hello</metadata>
    <rect width="90" height="25" x="0" y="0" class="Button">
        <animate attributeName="width" from="90" to="100" dur="0.2s" 
            begin="button1.mouseover" fill="freeze"/>
        <animate attributeName="height" from="25" to="30" dur="0.2s" 
            begin="button1.mouseover" fill="freeze"/>
        <animate attributeName="x" from="0" to="-3" dur="0.2s" 
            begin="button1.mouseover" fill="freeze"/>
        <animate attributeName="y" from="0" to="-3" dur="0.2s" 
            begin="button1.mouseover" fill="freeze"/>
        <animate attributeName="width" from="100" to="90" dur="0.2s" 
            begin="button1.mouseout" fill="freeze"/>
        <animate attributeName="height" from="30" to="25" dur="0.2s" 
            begin="button1.mouseout" fill="freeze"/>
        <animate attributeName="x" from="-3" to="0" dur="0.2s" 
            begin="button1.mouseout" fill="freeze"/>
        <animate attributeName="y" from="-3" to="0" dur="0.2s" 
            begin="button1.mouseout" fill="freeze"/>
    </rect>
    <text y="15" x="5" class="Button">Demo button 1</text>
</g>

Figure 9: Atom SVG Example

Finally note: The class attribute is used by the parser (SPARKFactory) on application load to decide what class to instantiate with that particular SVG snippet. If the AtomClassName class is not found, it will be ignored and not instantiated. If it is, a new scripting object will be attached as the controller for this model/view.

4.4.2 API

The Atom class does not have its own API calls rather it is simply a concrete extension of the Widget class and implements the Subject interface (i.e. Atom extends Widget implements Subject). Therefore the API that is available for Atom widgets is defined in Section 4.3.2 (Widget) and Section 4.2.1.1 (Subject).

4.5 Container Class

Containers are defined as Widgets that may contain other widgets. Examples include Radiobutton Groups, Windows, and Sliders. The main idea for Containers is to provide Atoms a place to reside and to add any extra functionality that depends upon more than one widget.

A very good abstract example of a container is a "Moveable" harness. The harness is simply a container with no visual representation. Any widgets that it contains are then given the ability to be moved around as a group. This is a great example of a non-standard widget type that SVG based user interfaces allow.

The UML notation that defines the Container scripting object is shown in Figure 10 .

container_small.png

Figure 10: Container UML Diagram

4.5.1 SVG

Similar to the Atom widget, the Container widget has generally the same as the SVG format as defined in Figure 6 , with it's own specific class attribute requirements. The class attribute is now standardized to be "SPARK container ContainerClassName", with ContainerClassName being the name of the Container class that was created and this SVG code block refers to. It is as flexible as the Atom for customizing the look and feel. It does however have one distinct difference and that has been added to support the idea of containing other widgets.

<g id="uniqueID" class="SPARK container ContainerClassName">
    <desc>Required - Description</desc>
    <metadata>Optional - Model</metadata>
    ... Any SVG content (View)...
    ... 1 or more Contents structures (may be nested)...
</g>

Figure 11: Container SVG Template

In addition to its normal SVG structure, a Container must also contain one or more content structures. These structures are used to contain other widgets (both Atom and Container widgets). A content node is always owned by node defined by the following XPath (note: is one entire XPath statement):

ancestor::g[ contains( @class, 'SPARK container' ) ]/
    node()[ position() = count( 
        ancestor::g[ contains( @class, 'SPARK container' ) ] 
    ) ]
                    

The basic rule is that a contents node is owned by the first ancestor (in the SVG tree) that is a container widget structure. It is required that a container knows where its contents structures are located.

The following is the Container Contents structure that was listed in Figure 11 .

<g  class="SPARK contents">
    ... Any SVG content (View)... and
    ... Any number of Atom and/or Container widgets...
</g>

Figure 12: Container SVG Template

An example of combining Containers with Atom widgets can be seen in Figure 13 . Once again it may be noted that the Container has its visual representation and it may be seen that the Container contains a contents structure. Within that structure the Radiobuttons' that it contains are declared. This shows how a user interface may be declaratively created.

<g id="radiobuttongroup" transform="translate(20,100)" 
   class="SPARK container RadiobuttonGroup">
    <desc>This is a demo of a radiobutton group.</desc>
    <metadata></metadata>
    <text>
        <tspan>Select a color number</tspan>
        <tspan x="0" dy="20">the radiobutton group:</tspan>
    </text>
    <g class="SPARK contents">
        <g id="radiobutton1-1" transform="translate(20,40)" 
           class="SPARK atom Radiobutton">
            <desc>This is demo radiobutton 1.  You can click it.</desc>
            <metadata>one</metadata>
            <circle r="5" />
            <text x="8" y="3">one</text>
        </g>
        <g id="radiobutton1-2" transform="translate(20,60)" 
           class="SPARK atom Radiobutton">
            <desc>This is demo radiobutton 2.  You can click it.</desc>
            <metadata>two</metadata>
            <circle r="5" />
            <text x="8" y="3">two</text>
        </g>
    </g>
</g>

Figure 13: Container SVG Example

4.5.2 API Description

It is assumed that Container will instantiate the Atoms and Containersthat they contain (located in a specified SVG structure called "contents"). It is assumed that the Container itself is instantiated by either it's owner container (that it is contained by) or by the application itself.

public void addWidget( Widget in_widget );
This is used to add a widgets controller to the Containers controller. From that the Container itself decides if it wishes to Observer the newly added widget or not. If the widgets controller was already added then nothing happens.
public void removeWidget( Widget in_widget );
This is used to remove a widgets controller from the Containers controller. If the Container was Observing that widget it will remove itself as an Observer. If that widget was not contained by the Container, nothing will happen.

4.6 SPARK Class

The SPARK class is the most complex and useful class in the framework. This class handles many different types of duties including Event distribution, type registration, global widget registration and as a container for the Factory used in widget creation.

spark_small.png

Figure 14: SPARK UML Diagram

4.6.1 API Description

The following is the detailed description of the publically available members of the SPARK class:

public static Vector REGISTERED_WIDGETS;
This Vector contains the set of globally registered widgets. It should be used in conjunction with the registerWidget and deregisterWidget API calls. Items should only be added or removed from this list using these two API calls. The reason for this set of globally registered widgets is in the case that a widget needs information from disjoint widget that it is not an Observer of. Applications should be able to be written without using this but it has been added for future concerns and as a throwback to regular UI frameworks that have some sort of widget ID lookup.
public static boolean requestMouseFocus( Widget in_widget );
This function is called by widgets that wish to hold global mouse focus for the application. Once a widget has obtained global mouse focus, any mouse events should automatically be forwarded to that widget via the handleMouseEvent API call. If another widget already owns global mouse focus then calling this function will return false and the requesting widget will not have mouse focus. Therefore it is extremely important that widgets also release their mouse focus once they are done with it.
public static void releaseMouseFocus( Widget in_widget );
This function should be called by the widget that currently has global mouse focus so that other widgets may obtain that global mouse focus. If a widget calls this function and does not currently own global mouse focus nothing will happen.
public static void handleMouseEvent( SVGEvent evt );
The handleMouseEvent function is called to transfer a given mouse event to the widget that currently holds global mouse focus. A very good use of this function is for Sliders. The slider sets itself to control mouse focus. When the mouse moves out of the area that is container by the sliders <g/> element it will no longer receive the mouseMove events. Using this function those events may be redirected to the slider class and it may continue being moved without handling the mouse events directly.
public static void requestKeyboardFocus( Widget in_widget );
Similar to the function requestMouseFocus with a minor difference - any class may cliam global keyboard focus from any other widget. Generally, the widget that is "in focus" should have global keyboard focus. Widgets do not necessarily have to release themselves from keyboard focus as the focus may be removed once a different widget requests it.
public static void releaseKeyboardFocus( Widget in_widget );
The same as the function releaseMouseFocus except dealing with keyboard as opoposed to mouse focus.
public static void handleKeyboardEvent( SVGEvent evt );
The same as the function handleMouseEvent except dealing with keyboard events as opoposed to mouse events.
public static void registerWidgetType( String in_type );
This function is called to let the main SPARK class know that a particular widget type is supported. Example: SPARK.registerWidgetType( "Radiobutton" ). Therefore, when say a factory class calls the SPARK.isWidget function with a class attribute such as class="SPARK atom Radiobutton" the isWidget function will return true because it is known that this widget type is supported. This function is generally called during the initialization of a factory object.
public static void deregisterWidgetType( String in_type );
This function is called to remove a specific type of widget from the list of those widgets that are supported. It is unlikely that this will need to be called but part of the get/set programming paradigm used for widget types in the SPARK class.
public static boolean isWidget( String in_type );
Give a class attribute this function will return true or false depending on if the value given in the class attribute conforms to the class attribute naming rules (see Section 4.3.1 ) and the widget type is also supported. This function is generally called during instantiation of widgets. If the widget was already in that list nothing will happen (it will not be removed and a duplicate pointer will not be added).
public static void registerWidget( Widget in_widget );
This function is called to add the given widget, in_widget, to the list of globally registered widget classes stored in SPARK.REGESTERED_WIDGETS.
public static void deregisterWidget( Widget in_widget );
This function is called to remove the given widget, in_widget, from the list of globally registered widget classes stored in SPARK.REGESTERED_WIDGETS. It will no longer be available in that list of widgets. If it was not originally in the list nothing will happen.
public static void setFactory( SPARKFactory in_factory );
Call this function to give the Factory that is used to instantiate new objects. This factory will be used by Containers to instantiate their contents.
public static SPARKFactory getFactory();
Generally speaking Containers will call this function to get a reference to the factory that is used to instantiate their contents.

4.7 Widgets Module Class Diagram

The following is the UML class diagram for the Widgets Module. The class diagram does not include any helper classes (see Chapter 6 for their UML class diagrams).

widgetsmodule_small.png

Figure 15: Widgets Module Class Hierarchy

4.8 Widgets Module IDL Definitions

The following is the IDL definition for the Widgets Module. It does not include any helper classes (see Chapter 6 for their IDL definitions).

// File: Widgets.idl
#ifndef _WIDGETS_IDL_
#define _WIDGETS_IDL_

// For access to SVGElement
// see http://www.w3.org/TR/SVG11/idl.html
#include "svg.idl"

#pragma prefix "Widgets.Framework.SPARK"
#pragma javaPackage "SPARK.Framework.Widgets"

module Widgets
{
    typedef svg::SVGElement SVGElement;
    typedef svg::SVGEvent   SVGEvent;

    interface Object;

    interface Atom;
    interface Command; 
    interface CommandHolder;
    interface Container;
    interface Observer;
    interface SPARK;
    interface SPARKFactory;
    interface Subject;
    interface Widget;

    interface Command {
        void execute( );
    };

    interface CommandHolder {
        void addCommand( inout Command in_command );
        void removeCommand( inout Command in_command );
    };

    interface Observer {
        void update( inout Subject in_subect );
    };

    interface Subject {
        void attach( inout Observer in_observer );
        void detach( inout Observer in_observer );
    };

    interface Widget {
        readonly attribute string ID;
        readonly attribute string TYPE;

        void setState( in Object in_state );
        Object getState();
    };

    interface Atom : Widget, Subject { };

    interface Container : Widget, Subject, Observer {
        void addWidget( inout Widget in_widget );
        void removeWidget( inout Widget in_widget );
    };

    interface SPARK {
        typedef sequence <Widget> REGISTERED_WIDGETS;
        boolean requestMouseFocus( inout Widget in_widget );
        boolean releaseMouseFocus( inout Widget in_widget );
        void handleMouseEvent( inout SVGEvent evt );
        void requestKeyboardFocus( inout Widget in_widget );
        void releaseKeyboardFocus( inout Widget in_widget );
        void handleKeyboardEvent( inout SVGEvent evt );
        void registerWidgetType( in string in_type );
        void deregisterWidgetType( in string in_type );
        boolean isWidget( in string in_name );
        void registerWidget( inout Widget in_widget );
        void deregisterWidget( inout Widget in_widget );
        void setFactory( inout SPARKFactory in_factory );
        SPARKFactory getFactory( );
    };

    interface SPARKFactory {
        Widget createWidget( inout SVGElement in_node );
        void createContents( inout SVGElement in_node,
                             inout Container in_container );
    };
};
#endif // _WIDGETS_IDL_

Figure 16: Widgets Module IDL Definitions

5. Skinning

One of the most important parts of the framework is to give the developer the option to customize the look and feel of the user interface. There are two main ways to accomplish this goal: through SVG and through CSS.

5.1 Skinning With CSS

The easiest way to customize the visual representation of the user interface defined in the framework is through the use of CSS . Stylesheets may be replaced and swapped with no effect to the applications functionality. One application may have multiple CSS stylesheets and many applications may share the same CSS stylesheet. This idea is express in Figure 17 .

css.png

Figure 17: Using multiple CSS files for SVG applications

The fact that the class attribute is used in SVG as a space separated list can easily be harnessed by the user interface developer. Every widget in the framework has a well defined class attribute that contains not only it's class name but may also contain any other pertinent CSS styling class. An example SVG class attribute could easily be class="SPARK atom Button RedButton". CSS styles could be applied to all widgets of a certain type or widgets could be given a separate CSS class to style only certain widgets. An example CSS file is shown in Figure 18 .

*.Radiobutton
{
    stroke:       #000000;
    fill:         #dddddd;
    stroke-width: 1
}

*.Button
{
    stroke:       lightgrey;
    fill:         midnightblue;
}

*.hide
{
	display:       none;
}

*.on
{
	fill:          red;
   stroke-width:  2;
}

Figure 18: Simple CSS example for skinning an application

<g id="button1" class="SPARK atom Button hide">
    <title>A hidden button</title>
    <text>Hidden</text>
</g>
<g id="rb1" class="SPARK atom Radiobutton on">
    <title>A radiobutton that has been turned on</title>
    <metadata>true</metadata>
    <circle r="5"/>
</g>
                    

Figure 19: Example of a Widget using CSS

Using Cascading Stylesheets is a very easy way to visually style an application. Using colors, gradients, stroke widths, etc an entire application may have its look and feel change by simply updating the CSS stylesheet. CSS can also be used to control user interactions (such as the "hide" class in Figure 19 ) where the button is actually hidden from view using CSS as opposed to traditional methods of removing the SVG itself. The reasons for wanting to use CSS in styling an application are the same for using CSS in styling web pages - the ease with which visual changes are implemented.

5.2 Skinning With XSLT

The SVG construct described in Section 4.3.1 shows one option for customization of individual widgets which is important to a certain extent. There is, however, another option for customizing the user interface through the use of XSLT. These fall into two main categories: transformation for visual markup and transformation to generate the entire application.

The first and simplest form of skinning through the use of XSLT is to add custom SVG visual content to the application. The process for creating SVG from XML using XSLT and customizing the target is shown in Figure 20 .

xslt_target.png

Figure 20: Generating SVG from XSLT [XML2SVG]

The benefit of this process is that the application may be targeted for specific users, demographics or platforms. The look and feel could easily be internationalized for a different country. Or it could be created in SVG Light for mobile applications. The process by which this could be accomplished would be to author the application with a combination of custom XML markup and framework conforming SVG code:

<g id="radiobutton" transform="translate(20,100)" class="SPARK atom Radiobutton">
    <desc>This is a demo of a radiobutton.</desc>
    <metadata></metadata>
    <custom:data xmlns:custom="http://www.myurl.com">
        <text>Red</text>
    </custom:data>
</g>

In Figure 21 there is no visual representation of the Radiobutton. Using the XSLT transformation process, information from the custom markup can be combined used to dynamically add a uniform look and feel to the application. The UI programmer could simply draw out what each Radiobutton looks like without having to insert the SVG into each Radiobutton individually. Therefore to update the visual representation (i.e. use a box instead of a circle for the radiobuttons) would be as simple as rerunning the xslt.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
   xmlns:custom="http://www.myurl.com">

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:include href="external_defs.xslt"/>
    
    <xsl:template match="/">
        <xsl:apply-templates />
    </xsl:template>
    
    <!--
        Copy any uncaught element exactly.
    -->
    <xsl:template match="*">
        <xsl:copy>
            <xsl:for-each select="@*">
                <xsl:copy/>
            </xsl:for-each>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>
    
    <!--
        Used to customize any widget.
    -->
    <xsl:template match="custom:data">
        <xsl:copy>
            <!-- Insert custom Radiobutton visual SVG markup -->
            <xsl:call-template name="Customize.Widget">
                <xsl:with-param name="type" select="parent::g/@class" />
                <xsl:with-param name="data" select="."/>
            </xsl:call-template>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Figure 22: XSLT used to insert custom SVG markup

Another option for customization is to define the entire user interface in terms of XML Schema defined types (i.e. select one, boolean, string). Using knowledge of these types and an instance of the XML Schema, the XML could be input into an XSLT to dynamically produce an entire application.

xslt_flow_small.png

Figure 23: Skinning process with XSLT

Any user interface may be defined as a set of data types either nested together or individually placed within the application. The process involved will be finalized shortly.

This process is non-trivial for script-generated user interfaces. Generating script through XSLT is a very difficult task to say the least. This is by far the biggest benefit to creating a declarative SVG user interface framework.

6. Framework Helpers

One of the main goals of the project was to create a framework that is easy to use (see Section 2.1 ). Though many of the decisions done during the project were done partly towards fulfilling this goal, the idea of a Helper module is completely geared towards it. The helper module is not a necessity to use the framework itself. The only part of the framework that is actually required is the Widgets module. The Helpers module has been created simply to enable developers to create applications faster and with more ease by removing some of the tedium of UI instantiation.

The Helpers module currently consists of two classes: SPARKHelperFactory and SPARKHelperDecorator. The factory class is a concrete instance of the SPARKFactory interface defined in the Widgets module (see Section 4.2.3 ). The decorator is an added design pattern that has been used to ease the integration of application and interface. There are plans to add more classes to the Helpers module including a class that performs common Mouse functions (such as coordinate conversion). For now there are only two though and they are defined below.

6.1 SPARKHelperFactory Class

The SPARKHelperFactory has been added to the framework to help application developers have a fast track to instantiating their user interface framework controllers. With minor modifications it may be used in any application to handle all creation duties.

sparkhelperfactory_small.png

Figure 24: SPARKHelperFactory UML Diagram

6.1.1 API Description

The SPARKHelperFactory is a concrete implementation of the SPARKFactory defined in Section 4.2.3 . Once agian the API is quite simple and easy to use. The API is defined as follows:

public static SPARKHelperFactory init();
This function is called to retrieve the instance of the SPARKHelperFactory. This instance should then be added to the SPARK class by simply calling SPARK.addFactory( SPARKHelperFactory.init() ). This function must be modified by the application programmer to support all the widgets that have been used in the application by registering their type with the global SPARK class (i.e. SPARK.registerType( "Button" ); ).
public Widget createWidget( in_node: SVGElement );
Using the given SVGElement (in_node) the Factory will attempt to instantiate the appropriate widget class and return an instance of that Widget. Failing that it will return null as the creation has failed. This function is inherited from the SPARKFactory interface (see Section 4.2.3.1 ). It does not require any modification by the programmer.
public void createContents( in_node: SVGElement, in_container: Container );
Given the input SVGElement (in_node) that follows the Container- Construct (see Section 4.5 ) and the owner Container instance, the Factory will instantiate every contained widget and add it to the given Container (in_container). This function is inherited from the SPARKFactory interface (see Section 4.2.3.1 ). It does not require any modification by the programmer.
private Atom createAtom( in_node: SVGElement );
This is not a publically available function but it has been listed in the API documentation specifically due to the fact that it requires modification by the application programmer. The process of instantiation for Atoms is accomplished here and necessary code for completing this task must be added.
private Atom createContainer( in_node: SVGElement );
This is not a publically available function but it has been listed in the API documentation specifically due to the fact that it requires modification by the application programmer. The process of instantiation for Containers is accomplished here and necessary code for completing this task must be added.

Once again, application programmers should note that there are a total of three functions that must be modified in this class in order to use it in their application: init, createAtom, createContainer.

6.2 SPARKHelperDecorator Class

The SPARKHelperDecorator is a concrete implementation of the Decorator pattern described in Section 3.6 . Using a very simple interface the application programmer may add custom, application specific logic to their widgets through the use of this decorator class.

sparkhelperdecorator_small.png

Figure 25: SPARKHelperDecorator UML Diagram

6.2.1 API Description

The API of the SPARKHelperDecorator is extremely simple but using this class is extremely powerful when developing a complex application.

public void decorate( Widget in_widget );
The decorator will add custom logic to the given widget (in_widget). If there is no custom logic to be added nothing will happen. This function should be called from a factory createWidget function after the widget has finished its instantiation. This function will require modification by the UI programmer.

There are many ways to add custom logic to the widgets but the route suggested is through the Command pattern (see Section 3.4 ). As the Widget class has been declared to implement the CommandHolder interface ( Section 4.2.2 ) this can be harnessed by creating the application appropriately.

For example: suppose a developer has written their application as a set of distinct use cases, with each use case initiated by a particular user interface event. The use cases could be implemented as seperate classes that implement the Command interface defined earlier and thus simply be added to the required widget. Then, when the widget goes through a well defined state changed, the command is executed and thus the use case is initiated.

The following code would be all that is required to accomplish this feat:

SPARKHelperDecorator.prototype.decorate = function( in_widget )
{
    // only handle these two widgets
    if( in_widget.ID == "button1" )
    {
        // add the first use case to "button1"
        in_widget.addCommand( new UseCase1() );
    }
    else if( in_widget.ID == "button2" )
    {
        // add the second use case to "button2"
        in_widget.addCommand( new UseCase1() );
    }
};

function UseCase1()
{
    this.name = "Use Case 1";
}

// UseCase1 implements Command
UseCase1.prototype.execute = function()
{
    alert( this.name );
    
    // Application logic goes here
    // ...
    // 
}

function UseCase2()
{
    this.name = "Use Case 2";
}

// UseCase2 implements Command
UseCase2.prototype.execute = function()
{
    alert( this.name + " was clicked." );

    // Application logic goes here
    // ...
    // 
}

Figure 26: Example of using the SPARKHelperDecorator (ECMAScript)

As can be seen, integrating the application and interface is accomplished seamlessly with not major dependencies except for widget id's. Therefore the widget that initiates the use case is easily swapped for another by simply adjusting which id is caught in the decorate() function.

6.3 Helper Module UML Diagram

helpermodule_small.png

Figure 27: Helper Module UML Diagram

6.4 Helper Module IDL Definitions

// File: Helpers.idl
#ifndef _HELPERS_IDL_
#define _HELPERS_IDL_

// For access to SVGElement
// see http://www.w3.org/TR/SVG11/idl.html
#include "svg.idl"

// For access to Widgets
#include "Widgets.idl"

#pragma prefix "Helpers.Framework.SPARK"
#pragma javaPackage "SPARK.Framework.Helpers"

module Helpers
{
    typedef Widgets::Widget       Widget;
    typedef Widgets::Atom         Atom;
    typedef Widgets::Container    Container;
    typedef Widgets::SPARKFactory SPARKFactory;

    typedef svg::SVGElement SVGElement;

    interface SPARKHelperFactory;
    interface SPARKHelperDecorator;

    interface SPARKHelperFactory : SPARKFactory {
        void setDecorator( inout SPARKHelperDecorator in_decorator );
        SPARKHelperFactory init( );
    };

    interface SPARKHelperDecorator {
        void decorate( inout Widget in_widget );
    };
};
#endif // _HELPERS_IDL_

Figure 28: Helper Module IDL Definitions

7. Future

There are a number of current developments in the SVG community that will most definitely affect the future of this framework. Technologies such as sXBL, XAML, and user interfaces created by other groups will greatly affect the development of the next generation of the framework, hopefully for the better. The following is a short list of topics that are on the radar screen to be tackled in the very near future.

7.1 Framework Development

Currently we have a grand theme for the future of this framework as a truly open source project. It would consist of three distinct developer types all working together for the greater good of the community: widget developers, skin developers and application developers. Combining resources from all three there is a huge potential to have a very robust, widely supported and widely implemented/deployed SVG user interface framework.

7.1.1 Widgets

The fastest way to get the SVG community to adopt this framework and to start implementing applications in it is to have a plethora of ready to use, pre-authored widgets. Kevin Lindseys' site http://www.kevlindev.com is well known for the availability of widgets. Obviously the benefit of this framework is that widgets are very easy to be created and there is no "box" preventing the developer from inventing an amazing new widget.

Before these amazing widgets are invented though the basics must first be created. A very valuable widget would be a textbox and would easily be the most widely used widget in the framework and add immense popularity. Alastair had the benefit of working on a project where he had to author his own detailed, fully functional textbox SVG widget. Hopefully though he will not be the only one implementing new widgets though for the time being it does appear to be that way. Other examples of widgets that would add to the popularity of the framework would be a better window implementation, tab panel widgets and many other common widgets that may be found in normal user interface frameworks (such as Java Swing and .Net).

7.1.2 Skins

It is believed that a major area for development in relation to the framework is with respect to application skins. Skins may be developed independently of applications and do not have any scripting requirements. Therefore application skins may be created in a static environment and customized to suit the developers' wishes.

From this fact it may be deduced that a community sharing skins could easily add to the popularity of the framework. Examples of skinning applications include skins for Winamp to skins for instant messaging programs such as ICQ. It is a well known fact that some developers cherish the role of creating beautiful, functional user interfaces while other developers prefer to stick to the application logic itself. The development of skins could give these UI developers a creative outlet and a way of showing off their skills.

7.1.3 Applications

Finally, a community with emphasis on application creation is integral to the future goals of the framework and the open source project. A strong support network for new developers to expert developers to help spread the knowledge of the framework would be invaluable.

7.2 sXBL

One of the interesting features of SVG 1.2 is XBL - XML Binding Language. Depending on the functionality available and implementations, XBL has the possibility of becoming an integral part of the framework in the future for obvious reasons (binding data to the SVG widgets - view - of the data).

7.3 Framework v2.0

It has been decided that the framework v1.0 will support all of SVG 1.1. As currently there are no final release viewers for SVG 1.2 and the SVG 1.2 draft has yet to be solidified, those features specific to SVG 1.2 have been ignored for this version of the framework. It has been decided that version 2.0 will support SVG 1.2.

8. Conclusion

SVG based user interfaces are possible. It is possible to create a framework that describes the user interface components and has been described in this report. It is now up to the SVG community at large to either adopt the framework, learn from it and improve the concepts, or to ignore. From the initial reactions of members of this community the future looks bright.

We look forward to all the hard work and effort that the SVG working group puts in every week towards the newest SVG candidate recommendation. New features to this language will only make it stronger and projects such as this one will benefit greatly from the work of these hard working individuals. The more pervasive SVG gets throughout the world the more likely this framework will prosper underneath their helm.

Acknowledgements

Christopher Lewis and Chris Peto

The authors wish to acknowledge Christopher Lewis and Chris Peto for their dedication to SVG based user interfaces. They have done some truly amazing work with CGUI in the past 2 years.

Darry Fuller

Alastair had the unique privilege of working with Darryl Fuller at SchemaSoft and specifically on a client project developing SVG user interface widgets. Darryl was a constant sounding board for the ideas listed in this report and for thoughtful comments and ideas regarding SVG GUI widgets.

Kevin Lindsey

The authors wish to acknowledge Kevin Lindsey and his amazing collection of SVG GUI widgets. Mr. Lindsey can definitely be listed as the innovator in the field of SVG GUI widgets.

Bibliography

[ECMAScript]
ECMAScript Language Specification 3rd Edition, Standard ECMA-262, December 1999. Available at http://www.ecma-international.org/publications/standards/Ecma-262.htm.
[CSS2]
Cascading Style Sheets, level 2, B. Bos, H. W. Lie, C. Lilley, I. Jacobs, W3C Recommendation, 12 May 1998. Available at http://www.w3.org/TR/REC-CSS2/.
[Design Patterns]
Design Patterns - Elements of Reusable Object Oriented Software, E. Gamma, R. Helm, R. Johnson, J. Vlissides, Addison-Wesley Publishing Company, 1995.
[SVG]
Scalable Vector Graphics (SVG) 1.0 Specification, J. Ferraiolo, editor, W3C Recommendation, 4 September 2001. Available at http://www.w3.org/TR/SVG/.
[SVGOpen 2003]
SPARK, C. Lewis, A. Fettes, P. Mansfield, SVG Open Conference 2003, July 2003. Available at http://www.svgopen.org/2003/.
[Wordnet]
WordNet 2.0, Cognitive Science Laboratory, Princeton University. Available at http://wordnet.princeton.edu/.
[XML2SVG]
SVG, CSS and XSL, M. Froumentin, WDIA Bristol, October 2000. Available at http://www.w3.org/2000/10/DIAWorkshop/froumentin/bristol.pdf
[XSLT]
XSL Transformations (XSLT) Version 1.0 Specification, J. Clark, editor, W3C Recommendation, 16 November 1999. Available at http://www.w3.org/TR/xslt.

XHTML rendition created by gcapaper Web Publisher v2.0, © 2001-3 Schema Software Inc.