tags:

views:

517

answers:

6

We are developing in an embedded type environment and find ourselves needing to create our own UI framework.

I have done this before, but I am interested in doing a little bit of research around common design patterns for frameworks.

Types of things that I am thinking of as patterns (somewhat far reaching):

  • Widget Focus / defocus
  • Widget Animation
  • Data sharing between elements
  • Attaching commands to widgets
  • Saving state (MVC?)

What recommended reading do you have for GUI Framework patterns?

+3  A: 

I have two for you, the callback or notification, maybe this is what you call "attaching commands to widgets", somehow you want to react to changes in state in your UI element. The controller needs to be informed that a change has occured.

Cocoa/UIKit has a pattern that is called "Delegation" and notifications to accomplish this, others use callback functions or objects (Java Swing) or "signals and slots" (QT).

I very useful pattern that does not occur in the wild very often is the ability to prevent a state change, the easiest use case for this is input validation, you want to prevent the loss of focus from a widget when the text in the widget does not concur with what you would expect. Windows Forms used to have that on some elements, not all, Cocoa can do this. This can be accomplished by using return values or reference parameters (or pointers) in the callbacks where the callee can communicate back to the originating widget

These days applying styles to ui elements, i.e. changing the look without changing the functionality has also become very popular QT can do this and I am sure a lot of other libraries

The Gang of Four Decorator pattern is also used sometimes for enhancing the capabilities of a widget, making something scrollable could be done via a decorator. It all depends on how far you will need to go with your UI elements. Good Luck, it is not an easy task

EDT: Apply MVC wherever you can. The first candidates are any kind of list displays, don't make them responsible for keeping the items they are displaying. This definitely goes for the combo box, a list box, tables and trees, you could implement this for text inputs but that might not be worth the overhead.

Harald Scheirich
+1  A: 

Some things I learnt by helping to develop SingStar PS3

  • It helps to keep your component logic (how a button works) and your visual logic (how to render an image) separate. This is especially nice when you come up with an totally new way of rendering something and it works with your old button controls transparently.
  • Set up a flexible way of binding a datasource in your application to a page full of components, so the same components can show all songs on one page or all photos on another. This is where MVC came in for SingStar
  • Event dispatch / event receiving models (i.e you subscribe to a button's click) is a pretty nice way to bind a page layout to your code. It can become spagetti if you are not careful.
  • Don't invent another programming language to describe your logic, your current programming language is probably fine.
  • Consider the steps when changing from one page to another. A lot of this comes down to your memory usage but there might be a moment where either two pages are loaded or no pages are loaded. Think about inter-page communication here.
  • Data-drive the layout of your page. Allow hot-swapping of the layout (press a key to reload it from your pc) as you will iterate on it heavily.
Tom Leys
A: 

Study XAML, especially bindings.

Microsoft have done a really nice job on a clean XML language to describe GUI layout and if you use a simplified version of XAML for your UI description you will be able to use their tools for designers to mock-up the UI.

Andy Dent
+2  A: 

Just a few pointers on classic design patterns; I think these are related to GUI building:

  • MVC pattern obvisously.
  • Observer pattern; for example, View needs to observe Model (to know when its state changes) and Controller needs to observe View (to know when a button is clicked).
  • Strategy pattern; in a way, using a controller as a glue between View and Model is choosing a Strategy. In theory, you should be able to switch Controller transparently.
  • Composite pattern; Your view is like a tree of panes, widgets and so on. Having a common interface and a way to iterate over this collection is useful when you need to call something like "view.paint()".

I know you asked about patterns for frameworks, but still you should rely on these patterns since developers will probably use your framework with these concepts in mind.

Do you have requirements/specific needs for your framework? You'll probably want to loose a couple of "good principles" if your target platform is limited in memory/CPU.

Brian Clozel
+1  A: 

The Chain of Command pattern.

Example in the context of GUIs:

interface IWidget
{
    bool HandleEvent(Event event); // returns true if event was handled
                                   // or false if event was ignored
}

class Button : IWidget
{
    public override bool HandleEvent(Event event)
    {
        switch(event.Type)
        {
            case EventType.MousePressed: DoStuff(); return true;
            case EventType.MouseScrolled: return false;
        }
    }
}

Here, Buttons don't care about scroll events, so they let their parents (the chain of command) handle them. So, if you have a Button in e.g. a HTML page, and the user scrolls over the button, this is handled by the parent widget (the HTML view) and the whole page scrolls.

For an example of real world usage in the Qt framework, see bool QWidget::event(QEvent*) and the documentation on event filters.

Also see: Design Patterns in KDE. KDE is a cross-platform, open source collection of object oriented C++ libraries and software, very popular as a Linux desktop environment. Those are slides from a 2003 KDE conference.

Stefan Monov
A: 

Dependency Injection can be of use sometimes.

Helper Method