tags:

views:

356

answers:

3

In a tool such as Photoshop, there is a selection of tools you can click on (e.g. pen, brush etc). Once you click on a tool, you can use that tool to paint, erase etc depending on what tool is selected.

I'm wondering how that would be best implemented in an OO design. I could only think of having a GUIManager that always knows which tool is selected, then when the Canvas (drawing area) detects a mouse click or mouse drag it asks GUIManager which tool is selected and applies that tool's behavior.

Does anyone describe a possible solution in class level detail (or in any detail if you don't have time).

+1  A: 

Take a look at the State Pattern which has exactly your example.

However, it's not actually a GUI question but more to an object-oriented approach to how to model this problem. The GUI doesn't really play into this.

Joey
+1  A: 

I'm not sure OO principles really play into this except in the sense that all graphic elements are probably derived from common base classes in your GUI of choice.

The amount of complexity in an application that needs a hierarchy of screen menus à la photoshop would presumably dwarf the difference between composition vs inheritance vs functional-style vs whatever-you-want.

Although, should you be motivated to write the program twice using different styles, it might be interesting to see the results. The ranking of various programming styles is an open question without real answers at this point, although we think that OO-styles are important in a way we haven't yet completely quantified.

DigitalRoss
+1  A: 

One idea for this would be to have a tool class. Just sketching this in C++-like pseudocode:

class Tool
{
public:
    // Keep a pointer to the "document", i.e. some representation of the
    // image you are editing
    Tool(Document *pDoc);

    // Process mouse events -- this need to be overridden to execute
    // the appropriate behaviour depending on the concrete type of tool
    virtual void OnMouseEvent(const MouseEvent &e) = 0;

    // and so on
};

You then inherit from this abstract tool class to provide the concrete tools your application needs. When a certain tool is selected, you instantiate a corresponding tool object and remember it somewhere. The window forwards mouse events to the currently active tool object, which then does the appropriate thing for the tool that was selected.

This is an implementation of the State pattern that Johannes refers to.

Martin B