Click here to Skip to main content
16,004,653 members
Articles / Programming Languages / C#

Let the context decide

Rate me:
Please Sign up or sign in to vote.
5.00/5 (5 votes)
14 Sep 2014CPOL5 min read 9.2K   211   7   1
Describes a way to manage user interaction events based on a common Context interface

Introduction 

OK, let's talk what this article is about. All developers in some moment in their lives have faced (or will be facing) the need of create a graphic editor, an ER model editor, a flowchart editor, whatever... but a common problem is that every time we start a project like these, we start without a common way to implement that, there are patterns like MVC, MVP, MVVM and others M-something. These patterns are useful but in the most of cases we find a slight line in implementation where every looks like the same, separating responsibilities is sometimes quite tricky and the more user interaction is added, the more complicated is to support these changes in developments, usually because we must to modify many components in the implementation.  Well in this article we discuss a way (maybe not the best) to solve the user interaction problems.  In general is not only useful for graphic editors but these are good examples for this article.  I hope you like it.   

Background 

Let's suppose that we must to create a shapes editor, then we start creating a class model but the user interaction behavior for every shape is different, however, the device actions set performed by users are the same for every shape.  A user can click, move, release its mouse, and is the same for other devices, the device actions are finite, but ¿why is so difficult to understand the device inputs and give a meaning to this actions? Well the answer is that the meaning for some action depends on the 'context' it is raised. Let see an example.

A user press a mouse button, if there is no shape in the mouse position a selection task must start, but if there is a shape in that position we could think that user wants to select or drag that shape, we can code this in an lazy way, but, what if this action produces different meanings depending on the shape functionality  for example, if we have a box with an expand-button? or maybe a shape with an internal draggable element?  We must to  manage all these conditions in the editor but without a well-structured way to do that all becomes a mess. 

What I propose in the title of this article is not to manage the context for that actions directly, but let the context itself decide which must be the consequences for a specific action.  Working in that way, every time a new meaning is needed or appears for a specific context is easier to maintain the code, every time a new context appears in the development is easier to create and connect with the existing development.  The  class diagram shown bellow display a general idea about the code posted for this article and it is organized to read from left to right and from top to bottom. 

Image 1 

The first class we see is the DashboardBase class which is a user control and its responsibility is to catch the control inputs for all devices (mouse, keyboard, whatever).  This class uses a Renderizer to print the view state in the control's client area Graphics. Additionally the dashboard references an InteractionManager which processes all InteractionEvent instances built by the dashboard control depending on the event raised.  The InteractionManager class uses the View class and its responsibilities are:

1. Manage the context for the view.

2. Adapt the diagram information (for example managing coordinates spaces) to the control depending on some properties like zoom, offset.

The Selection class is only a property used by the view to store the selected shapes and it is not important to show the idea. The Diagram class is the model we are creating or editing, this class contains for this example Layers and Shapes.  To keep it simple we only define a BoxShape and a LineShape.  When the view detects that an action have been performed, it analyzes whether exists a shape capable to solve the context, if a shape is found that shape must solve the context depending on its features.  In that way, if the shape is a BoxShape it can define the context depending on a drag area, a rotation glyph or a re-size corner, all these with different consequences. OK  now we have the context, so, how it is used?  That's the wonderful part, every context share a common interface called IInteractionContext. This interface contains basically three methods.  

Begin: When the context is activated a transaction is started. 

ProcessEvent; This method filters all the user interactions that this context can manage, including events available to commit or rollback the transaction modifying the view for the specified event.  

Commit: This method defines in every context, the way all data must be applied to the diagram model or how must be modified the view (in the Selection case for example). 

As you can see, we define in the top classes implementing the IInteractionContext.  These classes decide for every context which is the meaning for all the interaction events available for the context.  We can observe the following contexts:  

ShapeResizeContext: Context used to re-size a BoxShape

SelectionMoveContext: Context used to move a shape in the Diagram

MoveLineVertexContext: Context used to move the start point and end point for a line. 

SelectRectangleContext:  Context used to select all shapes in a rectangle. 

Results  

A single image about the code result.

Image 2   

Using the code 

The code in this article is not intended to be used in any serious development project, the concept could be util in some situations. 

Points of Interest 



History

Document creation.
 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Systems Engineer
Colombia Colombia
http://www.construirsoftware.blogspot.com/

Comments and Discussions

 
GeneralMy vote of 5 Pin
wilsonci13-Jun-18 5:20
wilsonci13-Jun-18 5:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.