patch from Dimitri fixing a few memory leaks and unTABbing the sources
[wxWidgets.git] / samples / docvwmdi / view.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: view.cpp
3 // Purpose: View classes
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 // #pragma implementation
14 #endif
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26
27 #if !wxUSE_DOC_VIEW_ARCHITECTURE
28 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
29 #endif
30
31 #include "docview.h"
32 #include "doc.h"
33 #include "view.h"
34
35 IMPLEMENT_DYNAMIC_CLASS(DrawingView, wxView)
36
37 // For drawing lines in a canvas
38 float xpos = -1;
39 float ypos = -1;
40
41 BEGIN_EVENT_TABLE(DrawingView, wxView)
42 EVT_MENU(DOODLE_CUT, DrawingView::OnCut)
43 END_EVENT_TABLE()
44
45 // What to do when a view is created. Creates actual
46 // windows for displaying the view.
47 bool DrawingView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
48 {
49 frame = wxGetApp().CreateChildFrame(doc, this, TRUE);
50 frame->SetTitle("DrawingView");
51
52 canvas = GetMainFrame()->CreateCanvas(this, frame);
53 #ifdef __X__
54 // X seems to require a forced resize
55 int x, y;
56 frame->GetSize(&x, &y);
57 frame->SetSize(-1, -1, x, y);
58 #endif
59 frame->Show(TRUE);
60 Activate(TRUE);
61
62 return TRUE;
63 }
64
65 // Sneakily gets used for default print/preview
66 // as well as drawing on the screen.
67 void DrawingView::OnDraw(wxDC *dc)
68 {
69 dc->SetFont(*wxNORMAL_FONT);
70 dc->SetPen(*wxBLACK_PEN);
71
72 wxNode *node = ((DrawingDocument *)GetDocument())->GetDoodleSegments().First();
73 while (node)
74 {
75 DoodleSegment *seg = (DoodleSegment *)node->Data();
76 seg->Draw(dc);
77 node = node->Next();
78 }
79 }
80
81 void DrawingView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint))
82 {
83 if (canvas)
84 canvas->Refresh();
85
86 /* Is the following necessary?
87 #ifdef __WXMSW__
88 if (canvas)
89 canvas->Refresh();
90 #else
91 if (canvas)
92 {
93 wxClientDC dc(canvas);
94 dc.Clear();
95 OnDraw(& dc);
96 }
97 #endif
98 */
99 }
100
101 // Clean up windows used for displaying the view.
102 bool DrawingView::OnClose(bool deleteWindow)
103 {
104 if (!GetDocument()->Close())
105 return FALSE;
106
107 // Clear the canvas in case we're in single-window mode,
108 // and the canvas stays.
109 canvas->Clear();
110 canvas->view = (wxView *) NULL;
111 canvas = (MyCanvas *) NULL;
112
113 wxString s(wxTheApp->GetAppName());
114 if (frame)
115 frame->SetTitle(s);
116
117 SetFrame((wxFrame*)NULL);
118
119 Activate(FALSE);
120
121 if (deleteWindow)
122 {
123 delete frame;
124 return TRUE;
125 }
126 return TRUE;
127 }
128
129 void DrawingView::OnCut(wxCommandEvent& WXUNUSED(event) )
130 {
131 DrawingDocument *doc = (DrawingDocument *)GetDocument();
132 doc->GetCommandProcessor()->Submit(new DrawingCommand((const wxString) "Cut Last Segment", DOODLE_CUT, doc, (DoodleSegment *) NULL));
133 }
134
135 IMPLEMENT_DYNAMIC_CLASS(TextEditView, wxView)
136
137 bool TextEditView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
138 {
139 frame = wxGetApp().CreateChildFrame(doc, this, FALSE);
140
141 int width, height;
142 frame->GetClientSize(&width, &height);
143 textsw = new MyTextWindow(this, frame, wxPoint(0, 0), wxSize(width, height), wxTE_MULTILINE);
144 frame->SetTitle("TextEditView");
145
146 #ifdef __X__
147 // X seems to require a forced resize
148 int x, y;
149 frame->GetSize(&x, &y);
150 frame->SetSize(-1, -1, x, y);
151 #endif
152
153 frame->Show(TRUE);
154 Activate(TRUE);
155
156 return TRUE;
157 }
158
159 // Handled by wxTextWindow
160 void TextEditView::OnDraw(wxDC *WXUNUSED(dc) )
161 {
162 }
163
164 void TextEditView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
165 {
166 }
167
168 bool TextEditView::OnClose(bool deleteWindow)
169 {
170 if (!GetDocument()->Close())
171 return FALSE;
172
173 Activate(FALSE);
174
175 if (deleteWindow)
176 {
177 delete frame;
178 return TRUE;
179 }
180 return TRUE;
181 }
182
183 /*
184 * Window implementations
185 */
186
187 BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
188 EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent)
189 END_EVENT_TABLE()
190
191 // Define a constructor for my canvas
192 MyCanvas::MyCanvas(wxView *v, wxFrame *frame, const wxPoint& pos, const wxSize& size, long style):
193 wxScrolledWindow(frame, -1, pos, size, style)
194 {
195 view = v;
196 }
197
198 // Define the repainting behaviour
199 void MyCanvas::OnDraw(wxDC& dc)
200 {
201 if (view)
202 view->OnDraw(& dc);
203 }
204
205 // This implements a tiny doodling program. Drag the mouse using
206 // the left button.
207 void MyCanvas::OnMouseEvent(wxMouseEvent& event)
208 {
209 if (!view)
210 return;
211
212 static DoodleSegment *currentSegment = (DoodleSegment *) NULL;
213
214 wxClientDC dc(this);
215 PrepareDC(dc);
216
217 dc.SetPen(*wxBLACK_PEN);
218
219 wxPoint pt(event.GetLogicalPosition(dc));
220
221 if (currentSegment && event.LeftUp())
222 {
223 if (currentSegment->lines.Number() == 0)
224 {
225 delete currentSegment;
226 currentSegment = (DoodleSegment *) NULL;
227 }
228 else
229 {
230 // We've got a valid segment on mouse left up, so store it.
231 DrawingDocument *doc = (DrawingDocument *)view->GetDocument();
232
233 doc->GetCommandProcessor()->Submit(new DrawingCommand("Add Segment", DOODLE_ADD, doc, currentSegment));
234
235 view->GetDocument()->Modify(TRUE);
236 currentSegment = (DoodleSegment *) NULL;
237 }
238 }
239
240 if (xpos > -1 && ypos > -1 && event.Dragging())
241 {
242 if (!currentSegment)
243 currentSegment = new DoodleSegment;
244
245 DoodleLine *newLine = new DoodleLine;
246 newLine->x1 = (long)xpos;
247 newLine->y1 = (long)ypos;
248 newLine->x2 = pt.x;
249 newLine->y2 = pt.y;
250 currentSegment->lines.Append(newLine);
251
252 dc.DrawLine( (long)xpos, (long)ypos, pt.x, pt.y);
253 }
254 xpos = pt.x;
255 ypos = pt.y;
256 }
257
258 // Define a constructor for my text subwindow
259 MyTextWindow::MyTextWindow(wxView *v, wxFrame *frame, const wxPoint& pos, const wxSize& size, long style):
260 wxTextCtrl(frame, -1, "", pos, size, style)
261 {
262 view = v;
263 }
264
265