In software development, you need to Test.

For my application, the testing phase is achieve by my daughter Lisa, 6 years old. She is wonderful little girl and know how to use the product without any help. The icons are self described. Even if the text is in English language, it does not matter. The user interface experience is the only criteria. Drawing shapes, adding bitmaps. Every features is tested. Compared to me who only checks the UI interactions with dockable panes, tabbed view, cascaded events among ribbon that should be propagated to property grid sometimes and sometimes not. It just take a lot of time on the plumbing that could be called the “Composite UI” because all my UI elements are independent. Every pane or windows is a dedicated class. It try to not break the object oriented philosophy but sometimes, I lost my mind. The number of classes that a single guy can handle is very limited. For me, I can remember about 25 classes and around 70%. Since 2 or 3 weeks, I reorganize my classes into dedicated namespaces because there are so many of a flat namespace that…. It becomes difficult to maintain. Sometimes, I am frozen. I don’t know how to handle some UI stuff (most of the time an UI interaction); There are so many classes involved in the operations. My daughter has done a lot of testing. I am very impressed. Without her, I would never have the patience to test again and again.

Exemple: the classes that represent the visible side of the iceberg are: CView .. CDocument.. CMainFrame.. CPropertyGrid.. CFileView.. CSolutionView.. CMDIChildFrame.. CTabbedView… CModeler1View.. CSourceCodeView.. CCommentView. See the bitmaps and you can had 20 classes more to do the real stuff like  enums and structures and some global variables.

But when it comes to change a property of a visible element, you can achieve it on the Ribbon, on the property grid of on the fly with keyboard. Then, the action is different to propagate the changes in all visible part. I have put a dirty class called CElementManager where I braek the document/view of the MFC architecture to put all the real application handler into. This is this part of the application I am currently migrating under Windows 8 RT using XAML technology. The class contains a lot of things. I am currently thinking about a routing mechanism more complicated to handle the UI stuff. Software development is a really challenging activity. It is not easy. It takes a lot of time and concentration. But it is cool.

#pragma once
#include "ElementContainer.h"
#include "Element.h"
#include "ElementFactory.h"

class CElementManager : public CObject
{
public:
DECLARE_SERIAL(CElementManager);
CElementManager();
virtual ~CElementManager(void);

// Attributes
public:
// Drawing objects
CElementContainer m_objects;
// Selection objects
CElementContainer m_selection;

COLORREF m_paperColor;
// Page size in logical coordinates
CSize m_size;
CPoint m_lastPoint;
// Current working object
CString m_objectId;
// Current Select action
SelectMode m_selectMode;
// Cursor hanlde
int m_nDragHandle;
// Zoom float factor (default 1.0f)
float m_fZoomFactor;

// Attributes Current UI interaction members
public:
// Is in drawing...
BOOL m_bDrawing;
// Current selected drawing tool
ElementType m_type;
// Current selected shape type from Ribbon
ShapeType m_shapeType;

// Methods for Attributes
public:
//SelectMode GetSelectMode()     { return m_selectMode; }
const vector<shared_ptr<CElement>>& GetObjects() { return m_objects.m_objects; }

// Debugging Operations
public:
void DebugDumpObjects(CModeler1View * pView);

// Operations
public:
void ConnectToMainFrame(CModeler1View * pView);
void ConnectToPropertyGrid();
virtual void Serialize(CArchive& ar);   // overridden for document i/o
void RemoveSelectedObjects(CModeler1View * pView);
void ViewToManager(CModeler1View * pView, CPoint & point);
void ViewToManager(CModeler1View * pView, CRect & rect);
void ManagerToView(CModeler1View * pView, CPoint & point);
void ManagerToView(CModeler1View * pView, CRect & rect);
COLORREF GetPaperColor() const { return m_paperColor; }
void Invalidate(CModeler1View * pView, shared_ptr<CElement> pElement);
void Invalidate(CModeler1View * pView);
void InvalObj(CModeler1View * pView, shared_ptr<CElement> pElement);
CSize GetSize() const { return m_size; }
void UpdateFromPropertyGrid(CString objectId, CString name, CString value);
void UpdateFromPropertyGrid(CString objectId, CString name, COLORREF color);
void UpdateFromPropertyGrid(CString objectId, CString name, long value);
void ActivateView(CModeler1View * pView, bool bActivate, CView* pActiveView, CView* pDeactiveView);

// Managing Object Positions
public:
void MoveToFront(CModeler1View * pView);
void MoveForward(CModeler1View * pView);
void MoveBackward(CModeler1View * pView);
void MoveToBack(CModeler1View * pView);

// Managing Background drawing
public:
void DrawBackground(CModeler1View * pView, CDC * pDC);

// Managing UI object connections
public:
void FindAConnectionFor(shared_ptr<CElement> pElement, CPoint point, CModeler1View* pView);

// Managing UI dependencies (Ribbon UI, Property Grid, ClassView)
public:
void UpdateUI(CModeler1View * pView, shared_ptr<CElement> pElement);
void UpdateRibbonUI(CModeler1View * pView, shared_ptr<CElement> pElement);
void UpdatePropertyGrid(CModeler1View * pView, shared_ptr<CElement> pElement);
void UpdateClassView();
void UpdateClassView(shared_ptr<CElement> pElement);
void UpdateFileView();
void UpdateFileView(shared_ptr<CElement> pElement);

// Managing Object Format
public:
void FillColor(CModeler1View * pView);
void NoFillColor(CModeler1View * pView);
void LineColor(CModeler1View * pView);
void LineWidth(CModeler1View * pView, UINT nID);
void PageColor(CModeler1View * pView);

// Managing Zoom Operations
public:
void ZoomIn(CModeler1View * pView);
void ZoomOut(CModeler1View * pView);

// Load Module Operations
public:
void LoadModule(CModeler1View * pView);

// Managing Object Selection
public:
bool HasSelection();
bool IsSelected(shared_ptr<CElement> pElement);
bool Select(shared_ptr<CElement> pElement);
bool Deselect(shared_ptr<CElement> pElement);
void SelectNone();

// Overridables
public:
virtual void PrepareDC(CModeler1View * pView, CDC* pDC, CPrintInfo* pInfo);
virtual void Draw(CModeler1View * pView, CDC * pDC);
virtual void DrawEx(CModeler1View * pView, CDC * pDC);
virtual void Update(CModeler1View * pView, LPARAM lHint, CObject* pHint);

// UI Handlers
public:
virtual void OnLButtonDown(CModeler1View* pView, UINT nFlags, const CPoint& cpoint);
virtual void OnLButtonDblClk(CModeler1View* pView, UINT nFlags, const CPoint& cpoint);
virtual void OnLButtonUp(CModeler1View* pView, UINT nFlags, const CPoint& cpoint);
virtual void OnMouseMove(CModeler1View* pView, UINT nFlags, const CPoint& cpoint);
};

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: