Bridging the divide
User interface projects need a development environment that supports both aesthetic design and coding activities, allowing software developers and UI designers to work cohesively. By Lars Knoll, CTO, Digia Qt.
Embedded software has an increasingly prominent role in modern equipment such as domestic appliances, industrial controls, vehicle dashboards, televisions and portable devices like smartphones and media players. With high-end user interfaces filling our every-day life, for instance through smartphones, the end users’ expectations from user interfaces is always rising. A device that is difficult to learn or use will not be tolerated; a high-quality user interface is critical for a product to be successful, including its appearance and, more importantly, how it works to help users achieve their goals. Good usability is a necessity, not just added value. Designing and coding the user interface are two different disciplines and traditionally difficult to bind seamlessly. The best results are achieved if a suitable bridge is established between these two roles.
The first stage of any good user interface design should be to define the user requirements, analyse how the user will perform the necessary tasks, and prioritise key functions. Building an understanding of the required functionality leads on to considering the look and feel of the interface and planning the underlying workflow. Storyboards and prototype visuals are a typical medium used to communicate concepts and consult with user workshops to improve subsequent iterations. Throughout, the designer should be looking to create an interface that is clear and uncluttered, intuitive and consistent in form and function. Transferring this work-phase into a re-usable output towards the UI implementation can be facilitated with proper tooling.
The latest user interface design tools enable fast prototype development but in a way that helps capture the results of work carried out at this stage directly to the final product. With the same mechanisms, modern UI design tools allow the design to be re-visited and altered even at a later phase of implementation, keeping the presentation and implementation bound but separable.
While the user requirements and task analysis are major considerations, other factors impact the user interface design and must be considered. These encompass assessing the operating environment such as expected ambient light levels, special requirements such as use with gloved hands in medical or industrial applications, and any need for portability across hardware and software platforms. Factors such as support for multiple languages or the need to integrate web functionality should also be considered at this stage.
Key concerns for coding
Diligent handling of the pre-coding considerations enables the design team to generate a robust description of the required user interface, which the software team must turn into reality. This, of course, can be much facilitated if the coders can directly use the prototype UIs created by the design team in their implementation. The choice of design environment and associated tools can make a dramatic difference, not only to the finished product but also to important commercial aspects such as project cost and time to market.
A design environment capable of bridging between the high-level aesthetic design processes and the coding of the GUI can contribute to achieving better results more quickly. In addition to supporting both of these apparently divergent requirements, the framework must also empower the team to ensure suitable graphics quality, optimise performance on constrained hardware, and port the solution quickly and efficiently across multiple platforms. Traditionally, programming for embedded devices has been done using low-level programming languages such as C. Writing the code for something resembling a real-life graspable concept, such as UI controls, using a high-abstraction level, object-oriented programming paradigm and language like C++ is more robust and much easier to approach. For each graphically represented control there is a unique object in the code level with all the features and functionality. The implementation is designed as a collection of objects, their connections and interactions. Specialised new objects can be easily created by inheriting new controls that derive all the existing features of the old ones.
An object-oriented approach is not restricted to visual elements; any component developed using an object-oriented methodology implicitly inherits the features of its component parts and passes on its features to any other components using it in a hierarchical fashion. Significantly, object-oriented software is inherently portable and thus essentially non-hardware dependent. In most cases porting object-oriented software is a simple case of re-compiling for a different architecture, assuming that no hardware or OS-specific functionality is used.
By using an object-oriented approach it is possible to create a development ‘framework’ where modular libraries contain components, or classes, for GUI widgets such as buttons, sliders, windows or dials, as well as other functional elements needed in embedded devices, such as networking, multimedia codecs and multiple-language support allowing internationalisation.
In the case of modern frameworks that offer true cross-platform support, such as Qt, such portability can minimise the development overhead of new designs and simplify the migration of existing designs while providing freedom to target different silicon price points. For example, Qt can be used to create the user interface for a portable medical device built around a low-power, cost-conscious processor, but the same code can be leveraged subsequently on more sophisticated equipment such as CAT or MRI scanners that use more powerful processors.
C++ is one of the leading object-oriented programming languages in use today, and is a natural progression for engineers familiar with C looking to adopt an object-oriented methodology. This approach, compared to using an interpreted language such as Java, can make the difference between delivering great or mediocre user experiences.
The development environment
To aid both design and coding activities, the development environment should offer a wide variety of pre-fabricated customisable user interface components, along with classes and modules that abstract common functionality in operating systems. Ideally offering more than just the GUI, these should also contain classes for XML, networking, inter-process communication (IPC), 2D and 3D graphics with hardware acceleration, threading, SQL, internationalisation and multimedia; so providing an application framework that can help speed up implementation of key functionality while allowing greater focus on creating differentiating features.
The Qt application and UI framework consists of both development tools and class libraries. It enables designers and programmers to work together using components that are easily customised, from the colour palette used to the way in which events are handled. Qt also allows faster creation of graphical elements, for example by supporting drag-and-drop UI creation as well as writing code. In addition, high-performance text rendering and pre-render fonts help to reduce processing overhead, and special web tools help build advanced user interfaces that incorporate real-time web content and services. For global deployments a dedicated linguist tool enables engineers to translate and adjust applications to different world languages, including support for Asian characters and right-to-left script.
One particular advantage of Qt lies in its top-level, cross-platform Application-Programming Interface (API), which facilitates deployment of GUI designs and applications across multiple software environments with minimal additional work. Source code from one device target, such as a desktop PC environment, can be deployed to an embedded operating system without any requirement for re-writing. This not only allows multiple deployments from a single development project but also minimises the impact of any future changes in the platform itself. This is extremely valuable, given that operating systems are subject to continual revisions and product lifetimes can sometimes be measured in months rather than years. It also future-proofs the project for possible strategic changes at a later phase; the target platform selection is not fixed but can be altered and extended later without needing to restart the development.
Together, these features of the Qt framework allow engineers to develop and deploy rich graphics with smoothly-rendered 2D and 3D animations and velvet-like transitions. Qt applications run on high-end architectures as well as on devices with relatively limited performance. Recent enhancements to Qt have added support for C++11 features and HTML5, as well as an improved QML engine, new APIs and enhanced support for graphics development with OpenGL ES, the graphics API designed specifically for embedded systems and mobile devices.