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