воскресенье, 3 июля 2011 г.

Model-View-Controller (MVC) + wxWidgets



Интерфейс "Наблюдатель" (Observer)



1 #ifndef OBSERVER_H
2 #define OBSERVER_H 1
3 class Observer
4 {
5 public:
6 virtual void update(){}
7 };
8 #endif




Описание модели (Model)



1 #ifndef MODEL_H
2 #define MODEL_H 1
3
4 #include <wx/string.h>
5 #include <set>
6
7 #include "Observer.h"
8
9 class Model
10 {
11 public:
12 Model(int d);
13 void setData(const int d);
14 int getData()const;
15 ~Model(){};
16 private:
17 int d_;
18 std::set<Observer*> registry;
19 public:
20 void attach(Observer*s);
21 void detach(Observer*s);
22 void notify();
23 // void clearRegistry();
24 };
25 #endif




Определение модели



1 #include "Model.h"
2
3 Model::Model(int d):d_(d) {};
4
5 void Model::setData(const int d)
6 {
7 d_=d;
8 notify();
9 }
10
11 int Model::getData()const
12 {
13 return d_;
14 }
15
16 void Model::attach(Observer*s)
17 {
18 registry.insert(s);
19 }
20
21 void Model::detach(Observer*s)
22 {
23 registry.erase(s);
24 }
25
26 void Model::notify()
27 {
28 std::set<Observer*>::iterator it;
29 for (it=registry.begin(); it!=registry.end(); it++)
30 (*it)->update();
31 }
32
33




Обобщенное представление (View)



1 #ifndef VIEW_H
2 #define VIEW_H 1
3 class Controller;
4 #include "Observer.h"
5 #include "Model.h"
6 #include "Controller.h"
7 class View: public Observer
8 {
9 protected:
10 Model *myModel;
11 Controller *myController;
12 public:
13 View(Model *m);
14 virtual ~View();
15 virtual void update();
16 virtual void draw();
17 virtual void initialize();
18 virtual Controller* makeController();
19 Model* getModel();
20 Controller *getController();
21 public:
22 virtual void setConroller(Controller *ctrl);
23 };
24 #endif




Определения методов класса View



1 #include "View.h"
2
3 View::View(Model *m):myModel(m),myController(0)
4 {
5 myModel->attach(this);
6 }
7
8 View::~View()
9 {
10 myModel->detach(this);
11 }
12
13 void View::initialize()
14 {
15 myController=makeController();
16 }
17
18 Controller* View::makeController()
19 {
20 return new Controller(this);
21 }
22
23 Model* View::getModel()
24 {
25 return myModel;
26 }
27
28 Controller * View::getController()
29 {
30 return myController;
31 }
32
33 void View::update()
34 {
35 this->draw();
36 }
37
38 void View::draw() {}
39
40 void View::setConroller(Controller *ctrl)
41 {
42 myController=ctrl;
43 }




Контроллер (Controller)



1 #ifndef CONTROLLER_H
2 #define CONTROLLER_H 1
3 #include <wx/event.h>
4 class View;
5 #include "Observer.h"
6 #include "View.h"
7 #include "Model.h"
8 typedef wxCommandEvent Event;
9 class Controller : public Observer
10 {
11 public:
12 virtual void handleEvent(Event *);// default = no op
13
14 Controller(View* v) ;
15 Controller() ;
16 virtual ~Controller();
17 virtual void update(); // default = no op
18 protected:
19 Model *myModel;
20 View *myView;
21 };
22 #endif




Определения методов контроллера



1 #include "Controller.h"
2 void Controller::handleEvent(Event *) {}
3 Controller::Controller(View* v) : myView(v)
4 {
5 myModel = myView->getModel();
6 myModel->attach(this);
7 }
8
9 Controller::~Controller()
10 {
11 myModel->detach(this);
12 }
13
14 void Controller::update() {}




Описание класса представления TextViewVal, реализующего отображение данных на основе wxStaticText



1 #ifndef TEXTVIEWVAL_H
2 #define TEXTVIEWVAL_H 1
3 #include <wx/stattext.h>
4 #include "View.h"
5 #include "TextControllerVal.h"
6 class TextViewVal:
public View ,public wxStaticText
7 {
8 public:
9 TextViewVal(wxWindow *parent,wxWindowID id,Model *m, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize,
long style=0, const wxString &name=wxStaticTextNameStr);
10 ~TextViewVal() ;
11 virtual void draw();
12 virtual Controller *makeController();//+
13 };
14 #endif




Определения методов класса TextViewVal



1 #include "TextViewVal.h"
2 TextViewVal::TextViewVal(wxWindow *parent,wxWindowID id,Model *m, const wxPoint &pos, const wxSize &size,
long style, const wxString &name):View(m),wxStaticText(parent,id, wxString::Format(wxT("%d"),m->getData()), pos,size,style,
name) {}
3
4 TextViewVal::~TextViewVal() {}
5
6 void TextViewVal::draw()
7 {
8 SetLabel(wxString::Format(wxT("%d"),myModel->getData()));
9 }
10
11 Controller* TextViewVal::makeController()
12 {
13 return new TextControllerVal(this->GetParent(), -1,this);
14 }




Контроллер для связи Модели с Отображением



1 #ifndef TEXTCONTROLLERVAL_H
2 #define TEXTCONTROLLERVAL_H 1
3 #include <wx/textctrl.h>
4 #include "Controller.h"
5 #include "TextViewVal.h"
6 class TextViewVal;
7 class TextControllerVal : public Controller,public wxTextCtrl
8 {
9 public:
10 TextControllerVal(wxWindow* parent, wxWindowID id,TextViewVal *tv, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = 0, const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxTextCtrlNameStr) ;
11 virtual void handleEvent(Event *e);
12 };
13 #endif




Определения методов класса TextControllerVal



1 #include "TextControllerVal.h"
2 TextControllerVal::TextControllerVal(wxWindow* parent, wxWindowID id,TextViewVal *tv, const wxPoint& pos,
const wxSize& size , long style, const wxValidator& validator, const wxString& name ):Controller((View*)tv),wxTextCtrl(parent,
id, wxString::Format(wxT("%d"),tv->getModel()->getData()), pos, size, style , validator , name){}
3
4 void TextControllerVal::handleEvent(Event *e)
5 {
6 myModel->setData(wxAtoi(e->GetString().c_str()));
7 }




Описание класса диалога для размещения Представлений и Контроллера



1 #ifndef TEXTDLGVAL_H
2 #define TEXTDLGVAL_H 1
3 #include <wx/dialog.h>
4 #include "TextViewVal.h"
5 class TextDlgVal : public wxDialog
6 {
7 public:
8 TextDlgVal(wxDialog* parent,wxString& title,Model* m);
9 virtual ~TextDlgVal();
10 protected:
11 enum
12 {
13 ID_TXTVAL=1000
14 };
15
16 Model* model_;
17 TextViewVal * view_;
18 TextViewVal * view2_;
19 TextControllerVal *controller_;
20
21 private:
22 void OnClose(wxCloseEvent &event);
23 void OnText(wxCommandEvent &event);
24
25 DECLARE_EVENT_TABLE()
26 };
27 #endif




Определения класса диалога для размещения Контроллера и двух экземпляров класса Представления



1 #include "TextDlgVal.h"
2 BEGIN_EVENT_TABLE(TextDlgVal, wxDialog)
3 EVT_CLOSE(TextDlgVal::OnClose)
4 EVT_TEXT(ID_TXTVAL, TextDlgVal::OnText)
5 END_EVENT_TABLE()
6
7 TextDlgVal::TextDlgVal(wxDialog* parent,wxString& title,Model* m):wxDialog(parent,-1,title),model_(m),view_(0),controller_(0)
8 {
9 this->SetSizeHints(wxDefaultSize, wxDefaultSize);
10 wxBoxSizer* bSizer1;
11
12 bSizer1 = new wxBoxSizer(wxVERTICAL);
13
14 view_=new TextViewVal(this,-1,m);
15 view2_=new TextViewVal(this,-1,m);
16
17 view_->initialize();//Инициализируем дл� нашего пред�тавлени� контроллер
18 controller_=(TextControllerVal*) view_->getController();//
19 controller_->SetId(ID_TXTVAL);//Делаем возможным обработку �обытий от контроллера
20
21 //Св�жем пред�тавление view2_ � контроллером
22 view2_->setConroller(controller_);
23
24 bSizer1->Add(view_, 0, wxALL|wxEXPAND, 5);
25 bSizer1->Add(view2_, 0, wxALL|wxEXPAND, 5);
26
27 bSizer1->Add(controller_, 1, wxEXPAND, 5);
28
29 this->SetSizer(bSizer1);
30 this->Layout();
31 bSizer1->Fit(this);
32 }
33
34 TextDlgVal::~TextDlgVal(){}
35
36 void TextDlgVal::OnClose(wxCloseEvent &event)
37 {
38 Destroy();
39 }
40
41 void TextDlgVal::OnText(wxCommandEvent &event)
42 {
43 controller_->handleEvent(&event);
44 }
45




Класс приложения wxWidgets



1 #ifndef MVC_TAPP_H
2 #define MVC_TAPP_H
3 #include <wx/app.h>
4 class MVC_TApp : public wxApp
5 {
6 public:
7 virtual bool OnInit();
8 };
9 #endif // MVC_TAPP_H




Определение приложения



1 #ifdef WX_PRECOMP
2 #include "wx_pch.h"
3 #endif
4
5 #ifdef __BORLANDC__
6 #pragma hdrstop
7 #endif //__BORLANDC__
8
9 #include "MVC_TApp.h"
10 #include "TextDlgVal.h"
11
12 IMPLEMENT_APP(MVC_TApp);
13
14 bool MVC_TApp::OnInit()
15 {
16 Model* m_=new Model(10);
17 wxString stro=wxT("MVC TEST");
18
19 TextDlgVal* v1_ = new TextDlgVal(0L,stro,m_);
20 v1_->Show();
21
22 return true;
23 }




Модуль для прекомпиляции (можно и без него обойтись)



1 #ifndef WX_PCH_H_INCLUDED
2 #define WX_PCH_H_INCLUDED
3
4 // basic wxWidgets headers
5 #include <wx/wxprec.h>
6
7 #ifdef __BORLANDC__
8 #pragma hdrstop
9 #endif
10
11 #ifndef WX_PRECOMP
12 #include <wx/wx.h>
13 #endif
14
15 #ifdef WX_PRECOMP
16 // put here all your rarely-changing header files
17 #endif // WX_PRECOMP
18
19 #endif // WX_PCH_H_INCLUDED