no changes, just some cleanup (patch 1918720)
[wxWidgets.git] / samples / docview / 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
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif
22
23 #if !wxUSE_DOC_VIEW_ARCHITECTURE
24 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
25 #endif
26
27 #include "docview.h"
28 #include "doc.h"
29 #include "view.h"
30
31 IMPLEMENT_DYNAMIC_CLASS(DrawingView, wxView)
32
33 // For drawing lines in a canvas
34 static float xpos = -1;
35 static float ypos = -1;
36
37 BEGIN_EVENT_TABLE(DrawingView, wxView)
38 EVT_MENU(DOODLE_CUT, DrawingView::OnCut)
39 END_EVENT_TABLE()
40
41 // What to do when a view is created. Creates actual
42 // windows for displaying the view.
43 bool DrawingView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
44 {
45 if (!singleWindowMode)
46 {
47 // Multiple windows
48 m_frame = wxGetApp().CreateChildFrame(doc, this, true);
49 m_frame->SetTitle(wxT("DrawingView"));
50
51 m_canvas = GetMainFrame()->CreateCanvas(this, m_frame);
52 #ifdef __X__
53 // X seems to require a forced resize
54 int x, y;
55 m_frame->GetSize(&x, &y);
56 m_frame->SetSize(wxDefaultCoord, wxDefaultCoord, x, y);
57 #endif
58 m_frame->Show(true);
59 }
60 else
61 {
62 // Single-window mode
63 m_frame = GetMainFrame();
64 m_canvas = GetMainFrame()->m_canvas;
65 m_canvas->m_view = this;
66
67 // Associate the appropriate frame with this view.
68 SetFrame(m_frame);
69
70 // Make sure the document manager knows that this is the
71 // current view.
72 Activate(true);
73
74 // Initialize the edit menu Undo and Redo items
75 doc->GetCommandProcessor()->SetEditMenu(((MyFrame*)m_frame)->m_editMenu);
76 doc->GetCommandProcessor()->Initialize();
77 }
78
79 return true;
80 }
81
82 // Sneakily gets used for default print/preview
83 // as well as drawing on the screen.
84 void DrawingView::OnDraw(wxDC *dc)
85 {
86 dc->SetFont(*wxNORMAL_FONT);
87 dc->SetPen(*wxBLACK_PEN);
88
89 wxList::compatibility_iterator node = GetDocument()->GetDoodleSegments().GetFirst();
90 while (node)
91 {
92 DoodleSegment *seg = (DoodleSegment *)node->GetData();
93 seg->Draw(dc);
94 node = node->GetNext();
95 }
96 }
97
98 DrawingDocument* DrawingView::GetDocument()
99 {
100 return wxStaticCast(wxView::GetDocument(), DrawingDocument);
101 }
102
103 void DrawingView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint))
104 {
105 if (m_canvas)
106 m_canvas->Refresh();
107
108 /* Is the following necessary?
109 #ifdef __WXMSW__
110 if (canvas)
111 canvas->Refresh();
112 #else
113 if (canvas)
114 {
115 wxClientDC dc(canvas);
116 dc.Clear();
117 OnDraw(& dc);
118 }
119 #endif
120 */
121 }
122
123 // Clean up windows used for displaying the view.
124 bool DrawingView::OnClose(bool deleteWindow)
125 {
126 if (!GetDocument()->Close())
127 return false;
128
129 // Clear the canvas in case we're in single-window mode,
130 // and the canvas stays.
131 m_canvas->ClearBackground();
132 m_canvas->m_view = NULL;
133 m_canvas = NULL;
134
135 wxString s(wxTheApp->GetAppDisplayName());
136 if (m_frame)
137 m_frame->SetTitle(s);
138
139 SetFrame(NULL);
140
141 Activate(false);
142
143 if (deleteWindow && !singleWindowMode)
144 {
145 delete m_frame;
146 return true;
147 }
148 return true;
149 }
150
151 void DrawingView::OnCut(wxCommandEvent& WXUNUSED(event) )
152 {
153 DrawingDocument* doc = GetDocument();
154 doc->GetCommandProcessor()->Submit(new DrawingCommand(wxT("Cut Last Segment"), DOODLE_CUT, doc, NULL));
155 }
156
157 IMPLEMENT_DYNAMIC_CLASS(TextEditView, wxView)
158
159 bool TextEditView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
160 {
161 m_frame = wxGetApp().CreateChildFrame(doc, this, false);
162
163 wxSize size = m_frame->GetClientSize();
164 m_textsw = new MyTextWindow(this, m_frame, wxPoint(0, 0), size, wxTE_MULTILINE);
165 m_frame->SetTitle(wxT("TextEditView"));
166
167 #ifdef __X__
168 // X seems to require a forced resize
169 int x, y;
170 frame->GetSize(&x, &y);
171 frame->SetSize(wxDefaultCoord, wxDefaultCoord, x, y);
172 #endif
173
174 m_frame->Show(true);
175 Activate(true);
176
177 return true;
178 }
179
180 // Handled by wxTextWindow
181 void TextEditView::OnDraw(wxDC *WXUNUSED(dc) )
182 {
183 }
184
185 void TextEditView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
186 {
187 }
188
189 bool TextEditView::OnClose(bool deleteWindow)
190 {
191 if (!GetDocument()->Close())
192 return false;
193
194 Activate(false);
195
196 if (deleteWindow)
197 {
198 wxDELETE(m_frame)
199 return true;
200 }
201 return true;
202 }
203
204 bool TextEditView::ProcessEvent(wxEvent& event)
205 {
206 bool processed = false;
207 if (!processed) switch (event.GetId())
208 {
209 case wxID_COPY:
210 case wxID_PASTE:
211 case wxID_SELECTALL:
212 processed = m_textsw->ProcessEvent(event);
213 break;
214 }
215 if (!processed) processed = wxView::ProcessEvent(event);
216 return processed;
217 }
218
219 /*
220 * Window implementations
221 */
222
223 BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
224 EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent)
225 END_EVENT_TABLE()
226
227 // Define a constructor for my canvas
228 MyCanvas::MyCanvas(DrawingView* view, wxFrame* frame, const wxPoint& pos, const wxSize& size, const long style):
229 wxScrolledWindow(frame, wxID_ANY, pos, size, style)
230 {
231 m_view = view;
232 }
233
234 // Define the repainting behaviour
235 void MyCanvas::OnDraw(wxDC& dc)
236 {
237 if (m_view)
238 m_view->OnDraw(& dc);
239 }
240
241 // This implements a tiny doodling program. Drag the mouse using
242 // the left button.
243 void MyCanvas::OnMouseEvent(wxMouseEvent& event)
244 {
245 if (!m_view)
246 return;
247
248 static DoodleSegment *currentSegment = NULL;
249
250 wxClientDC dc(this);
251 PrepareDC(dc);
252
253 dc.SetPen(*wxBLACK_PEN);
254
255 wxPoint pt(event.GetLogicalPosition(dc));
256
257 if (currentSegment && event.LeftUp())
258 {
259 if (currentSegment->m_lines.GetCount() == 0)
260 {
261 delete currentSegment;
262 currentSegment = NULL;
263 }
264 else
265 {
266 // We've got a valid segment on mouse left up, so store it.
267 DrawingDocument* doc = m_view->GetDocument();
268
269 doc->GetCommandProcessor()->Submit(new DrawingCommand(wxT("Add Segment"), DOODLE_ADD, doc, currentSegment));
270
271 m_view->GetDocument()->Modify(true);
272 currentSegment = NULL;
273 }
274 }
275
276 if ( (xpos > -1) && (ypos > -1) && event.Dragging())
277 {
278 if (!currentSegment)
279 currentSegment = new DoodleSegment;
280
281 DoodleLine *newLine = new DoodleLine;
282 newLine->x1 = (long)xpos;
283 newLine->y1 = (long)ypos;
284 newLine->x2 = pt.x;
285 newLine->y2 = pt.y;
286 currentSegment->m_lines.Append(newLine);
287
288 dc.DrawLine( (long)xpos, (long)ypos, pt.x, pt.y);
289 }
290 xpos = pt.x;
291 ypos = pt.y;
292 }
293
294 // Define a constructor for my text subwindow
295 MyTextWindow::MyTextWindow(wxView* view, wxFrame* frame, const wxPoint& pos, const wxSize& size, const long style):
296 wxTextCtrl(frame, wxID_ANY, wxEmptyString, pos, size, style)
297 {
298 m_view = view;
299 }
300
301