Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

We are developing a Qt-based application to navigate through and paint on a volume treated as a 3D pixel graphic. The layout of the app consists of three orthogonal slice views on which the user may paint stuff like dots, circles etc. and also erase already painted pixels. Think of a 3D Gimp or MS Paint.

How would you design the the architecture for the different interaction modes (i.e. paint tools)?

My idea is:

  • use the MVC pattern
  • have a separate controler for every interaction mode
  • install an event filter on all three slice views to collect all incoming user interaction events (mouse, keyboard)
  • redirect the events to the currently active interaction controler

I would appreciate critical comments on that idea.

share|improve this question
    
Are you dealing with a single user painting at a time? –  blueberryfields Sep 14 '11 at 23:28
    
Yes, it's a single user application. –  Bernhard Kausler Sep 15 '11 at 6:44
    
Can you please clarify the question a little more? Start by defining and relating the terms "slice view" and "interaction modes" (or "paint tools"). Is it like a CAD application? –  Jordão Oct 28 '11 at 3:30

3 Answers 3

Typically MVC is a style in which relatively large operations are defined. That doesn't really align well with the intricate operations that you define as painting a 3d pixel. I'd suggest taking a look at another style closely related to MVC which is MVVM. It allows for a closer binding between the object one is operating on by means of your different tools and having a view for that object.

share|improve this answer

I don't think building the interaction modes as different "controllers" will serve you well. What is your logic for this? A controller is to tie display and your user input to your model, but im imagining that this is only one canvas and one mouse pointer, so why multi controllers?

You could have the switching logic that changes between interaction modes in a model class. You probably shouldn't need to use it in more than one controller unless you're giving your user drastically different "canvas" type elements and layouts to draw on also. Either way, I think some good choices of Design Pattern would be a factory and/or a decorator or something similar.

Collect the event from the button click on the palette of interaction modes (you mean this to be a sort of Photoshop/MS Paint kind of toolbar on the side, right?). Use that event as the input to a factory. This factory will generate an instance of something adhering to the "Tool" interface (or whatever you want to call it). The newly generated Tool instance is stored in the controller somewhere to be ready to receive mouse input as the user draws, for example.

If you want to get complex - like what if some tools can be simultaneously chosen, like both a "magnetic lock" and a "draw" - your controller's reference to an instance implementing a Tool interface would need to be extended at runtime somehow, like w/ a Chain Of Responsibility pattern (or a decorator as previously mentioned). Now the factory mentioned before will make more than one Tool. The controller will "line these up" in the case of the Chain of Command before passing the user's mouse input. For example, the magnetic lock "Tool" implementation may change the users input slightly to exist on a guideline before passing it "along the chain" to the drawing tool.

share|improve this answer

Your idea is basically correct. It also gets mentioned in the Design Pattern book at the State pattern. Your editor has a current Tool object (which implements a generic Tool interface), and delegates all the relevant user interactions to it (mouseclick, key events etc.). The paint tool, selection tool etc. classes will implement the Tool interface and will be responsible for handling sequences of user events.

public interface Tool {

void HandleKeyboardEvent(...);
void HandleMouseEvent(...);

}

class RectangleTool : Tool { //accumulates drawing state }

When you change a Tool it will be just the current tool object which changes, the rest of the logic in your UI stays the same.

If you have 3 orthogonal views then you can have 3 tool objects or just one, depending on your design.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.