]> git.saurik.com Git - wxWidgets.git/blob - samples/docview/view.cpp
glibc's vswprintf doesn't nul terminate on truncation.
[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 float xpos = -1;
35 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 frame = wxGetApp().CreateChildFrame(doc, this, true);
49 frame->SetTitle(_T("DrawingView"));
50
51 canvas = GetMainFrame()->CreateCanvas(this, frame);
52 #ifdef __X__
53 // X seems to require a forced resize
54 int x, y;
55 frame->GetSize(&x, &y);
56 frame->SetSize(wxDefaultCoord, wxDefaultCoord, x, y);
57 #endif
58 frame->Show(true);
59 }
60 else
61 {
62 // Single-window mode
63 frame = GetMainFrame();
64 canvas = GetMainFrame()->canvas;
65 canvas->view = this;
66
67 // Associate the appropriate frame with this view.
68 SetFrame(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 *)frame)->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 = ((DrawingDocument *)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 void DrawingView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint))
99 {
100 if (canvas)
101 canvas->Refresh();
102
103 /* Is the following necessary?
104 #ifdef __WXMSW__
105 if (canvas)
106 canvas->Refresh();
107 #else
108 if (canvas)
109 {
110 wxClientDC dc(canvas);
111 dc.Clear();
112 OnDraw(& dc);
113 }
114 #endif
115 */
116 }
117
118 // Clean up windows used for displaying the view.
119 bool DrawingView::OnClose(bool deleteWindow)
120 {
121 if (!GetDocument()->Close())
122 return false;
123
124 // Clear the canvas in case we're in single-window mode,
125 // and the canvas stays.
126 canvas->ClearBackground();
127 canvas->view = (wxView *) NULL;
128 canvas = (MyCanvas *) NULL;
129
130 wxString s(wxTheApp->GetAppName());
131 if (frame)
132 frame->SetTitle(s);
133
134 SetFrame((wxFrame *) NULL);
135
136 Activate(false);
137
138 if (deleteWindow && !singleWindowMode)
139 {
140 delete frame;
141 return true;
142 }
143 return true;
144 }
145
146 void DrawingView::OnCut(wxCommandEvent& WXUNUSED(event) )
147 {
148 DrawingDocument *doc = (DrawingDocument *)GetDocument();
149 doc->GetCommandProcessor()->Submit(new DrawingCommand(_T("Cut Last Segment"), DOODLE_CUT, doc, (DoodleSegment *) NULL));
150 }
151
152 IMPLEMENT_DYNAMIC_CLASS(TextEditView, wxView)
153
154 bool TextEditView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
155 {
156 frame = wxGetApp().CreateChildFrame(doc, this, false);
157
158 int width, height;
159 frame->GetClientSize(&width, &height);
160 textsw = new MyTextWindow(this, frame, wxPoint(0, 0), wxSize(width, height), wxTE_MULTILINE);
161 frame->SetTitle(_T("TextEditView"));
162
163 #ifdef __X__
164 // X seems to require a forced resize
165 int x, y;
166 frame->GetSize(&x, &y);
167 frame->SetSize(wxDefaultCoord, wxDefaultCoord, x, y);
168 #endif
169
170 frame->Show(true);
171 Activate(true);
172
173 return true;
174 }
175
176 // Handled by wxTextWindow
177 void TextEditView::OnDraw(wxDC *WXUNUSED(dc) )
178 {
179 }
180
181 void TextEditView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
182 {
183 }
184
185 bool TextEditView::OnClose(bool deleteWindow)
186 {
187 if (!GetDocument()->Close())
188 return false;
189
190 Activate(false);
191
192 if (deleteWindow)
193 {
194 delete frame;
195 return true;
196 }
197 return true;
198 }
199
200 /*
201 * Window implementations
202 */
203
204 BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
205 EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent)
206 END_EVENT_TABLE()
207
208 // Define a constructor for my canvas
209 MyCanvas::MyCanvas(wxView *v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style):
210 wxScrolledWindow(frame, wxID_ANY, pos, size, style)
211 {
212 view = v;
213 }
214
215 // Define the repainting behaviour
216 void MyCanvas::OnDraw(wxDC& dc)
217 {
218 if (view)
219 view->OnDraw(& dc);
220 }
221
222 // This implements a tiny doodling program. Drag the mouse using
223 // the left button.
224 void MyCanvas::OnMouseEvent(wxMouseEvent& event)
225 {
226 if (!view)
227 return;
228
229 static DoodleSegment *currentSegment = (DoodleSegment *) NULL;
230
231 wxClientDC dc(this);
232 PrepareDC(dc);
233
234 dc.SetPen(*wxBLACK_PEN);
235
236 wxPoint pt(event.GetLogicalPosition(dc));
237
238 if (currentSegment && event.LeftUp())
239 {
240 if (currentSegment->lines.GetCount() == 0)
241 {
242 delete currentSegment;
243 currentSegment = (DoodleSegment *) NULL;
244 }
245 else
246 {
247 // We've got a valid segment on mouse left up, so store it.
248 DrawingDocument *doc = (DrawingDocument *)view->GetDocument();
249
250 doc->GetCommandProcessor()->Submit(new DrawingCommand(_T("Add Segment"), DOODLE_ADD, doc, currentSegment));
251
252 view->GetDocument()->Modify(true);
253 currentSegment = (DoodleSegment *) NULL;
254 }
255 }
256
257 if (xpos > -1 && ypos > -1 && event.Dragging())
258 {
259 if (!currentSegment)
260 currentSegment = new DoodleSegment;
261
262 DoodleLine *newLine = new DoodleLine;
263 newLine->x1 = (long)xpos;
264 newLine->y1 = (long)ypos;
265 newLine->x2 = pt.x;
266 newLine->y2 = pt.y;
267 currentSegment->lines.Append(newLine);
268
269 dc.DrawLine( (long)xpos, (long)ypos, pt.x, pt.y);
270 }
271 xpos = pt.x;
272 ypos = pt.y;
273 }
274
275 // Define a constructor for my text subwindow
276 MyTextWindow::MyTextWindow(wxView *v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style):
277 wxTextCtrl(frame, wxID_ANY, _T(""), pos, size, style)
278 {
279 view = v;
280 }
281
282