]> git.saurik.com Git - wxWidgets.git/blame_incremental - samples/docview/view.cpp
Add a test for a tooltip for a control inside a static box.
[wxWidgets.git] / samples / docview / view.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: samples/docview/view.cpp
3// Purpose: View classes implementation
4// Author: Julian Smart
5// Modified by: Vadim Zeitlin: merge with the MDI version and general cleanup
6// Created: 04/01/98
7// Copyright: (c) 1998 Julian Smart
8// (c) 2008 Vadim Zeitlin
9// Licence: wxWindows licence
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// ----------------------------------------------------------------------------
32// DrawingView implementation
33// ----------------------------------------------------------------------------
34
35IMPLEMENT_DYNAMIC_CLASS(DrawingView, wxView)
36
37BEGIN_EVENT_TABLE(DrawingView, wxView)
38 EVT_MENU(wxID_CUT, DrawingView::OnCut)
39END_EVENT_TABLE()
40
41// What to do when a view is created. Creates actual
42// windows for displaying the view.
43bool DrawingView::OnCreate(wxDocument *doc, long flags)
44{
45 if ( !wxView::OnCreate(doc, flags) )
46 return false;
47
48 MyApp& app = wxGetApp();
49 if ( app.GetMode() != MyApp::Mode_Single )
50 {
51 // create a new window and canvas inside it
52 wxFrame* frame = app.CreateChildFrame(this, true);
53 wxASSERT(frame == GetFrame());
54 m_canvas = new MyCanvas(this);
55 frame->Show();
56 }
57 else // single document mode
58 {
59 // reuse the existing window and canvas
60 m_canvas = app.GetMainWindowCanvas();
61 m_canvas->SetView(this);
62
63 // Initialize the edit menu Undo and Redo items
64 doc->GetCommandProcessor()->SetEditMenu(app.GetMainWindowEditMenu());
65 doc->GetCommandProcessor()->Initialize();
66 }
67
68 return true;
69}
70
71// Sneakily gets used for default print/preview as well as drawing on the
72// screen.
73void DrawingView::OnDraw(wxDC *dc)
74{
75 dc->SetPen(*wxBLACK_PEN);
76
77 // simply draw all lines of all segments
78 const DoodleSegments& segments = GetDocument()->GetSegments();
79 for ( DoodleSegments::const_iterator i = segments.begin();
80 i != segments.end();
81 ++i )
82 {
83 const DoodleLines& lines = i->GetLines();
84 for ( DoodleLines::const_iterator j = lines.begin();
85 j != lines.end();
86 ++j )
87 {
88 const DoodleLine& line = *j;
89
90 dc->DrawLine(line.x1, line.y1, line.x2, line.y2);
91 }
92 }
93}
94
95DrawingDocument* DrawingView::GetDocument()
96{
97 return wxStaticCast(wxView::GetDocument(), DrawingDocument);
98}
99
100void DrawingView::OnUpdate(wxView* sender, wxObject* hint)
101{
102 wxView::OnUpdate(sender, hint);
103 if ( m_canvas )
104 m_canvas->Refresh();
105}
106
107// Clean up windows used for displaying the view.
108bool DrawingView::OnClose(bool deleteWindow)
109{
110 if ( !wxView::OnClose(deleteWindow) )
111 return false;
112
113 Activate(false);
114
115 // Clear the canvas in single-window mode in which it stays alive
116 if ( wxGetApp().GetMode() == MyApp::Mode_Single )
117 {
118 m_canvas->ClearBackground();
119 m_canvas->ResetView();
120 m_canvas = NULL;
121
122 if (GetFrame())
123 wxStaticCast(GetFrame(), wxFrame)->SetTitle(wxTheApp->GetAppDisplayName());
124 }
125 else // not single window mode
126 {
127 if ( deleteWindow )
128 {
129 GetFrame()->Destroy();
130 SetFrame(NULL);
131 }
132 }
133 return true;
134}
135
136void DrawingView::OnCut(wxCommandEvent& WXUNUSED(event) )
137{
138 DrawingDocument * const doc = GetDocument();
139
140 doc->GetCommandProcessor()->Submit(new DrawingRemoveSegmentCommand(doc));
141}
142
143// ----------------------------------------------------------------------------
144// TextEditView implementation
145// ----------------------------------------------------------------------------
146
147IMPLEMENT_DYNAMIC_CLASS(TextEditView, wxView)
148
149BEGIN_EVENT_TABLE(TextEditView, wxView)
150 EVT_MENU(wxID_COPY, TextEditView::OnCopy)
151 EVT_MENU(wxID_PASTE, TextEditView::OnPaste)
152 EVT_MENU(wxID_SELECTALL, TextEditView::OnSelectAll)
153END_EVENT_TABLE()
154
155bool TextEditView::OnCreate(wxDocument *doc, long flags)
156{
157 if ( !wxView::OnCreate(doc, flags) )
158 return false;
159
160 wxFrame* frame = wxGetApp().CreateChildFrame(this, false);
161 wxASSERT(frame == GetFrame());
162 m_text = new wxTextCtrl(frame, wxID_ANY, "",
163 wxDefaultPosition, wxDefaultSize,
164 wxTE_MULTILINE);
165 frame->Show();
166
167 return true;
168}
169
170void TextEditView::OnDraw(wxDC *WXUNUSED(dc))
171{
172 // nothing to do here, wxTextCtrl draws itself
173}
174
175bool TextEditView::OnClose(bool deleteWindow)
176{
177 if ( !wxView::OnClose(deleteWindow) )
178 return false;
179
180 Activate(false);
181
182 if ( wxGetApp().GetMode() == MyApp::Mode_Single )
183 {
184 m_text->Clear();
185 }
186 else // not single window mode
187 {
188 if ( deleteWindow )
189 {
190 GetFrame()->Destroy();
191 SetFrame(NULL);
192 }
193 }
194 return true;
195}
196
197// ----------------------------------------------------------------------------
198// MyCanvas implementation
199// ----------------------------------------------------------------------------
200
201BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
202 EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent)
203END_EVENT_TABLE()
204
205// Define a constructor for my canvas
206MyCanvas::MyCanvas(wxView *view, wxWindow *parent)
207 : wxScrolledWindow(parent ? parent : view->GetFrame())
208{
209 m_view = view;
210 m_currentSegment = NULL;
211 m_lastMousePos = wxDefaultPosition;
212
213 SetCursor(wxCursor(wxCURSOR_PENCIL));
214
215 // this is completely arbitrary and is done just for illustration purposes
216 SetVirtualSize(1000, 1000);
217 SetScrollRate(20, 20);
218
219 SetBackgroundColour(*wxWHITE);
220}
221
222MyCanvas::~MyCanvas()
223{
224 delete m_currentSegment;
225}
226
227// Define the repainting behaviour
228void MyCanvas::OnDraw(wxDC& dc)
229{
230 if ( m_view )
231 m_view->OnDraw(& dc);
232}
233
234// This implements a tiny doodling program. Drag the mouse using the left
235// button.
236void MyCanvas::OnMouseEvent(wxMouseEvent& event)
237{
238 if ( !m_view )
239 return;
240
241 wxClientDC dc(this);
242 PrepareDC(dc);
243
244 dc.SetPen(*wxBLACK_PEN);
245
246 const wxPoint pt(event.GetLogicalPosition(dc));
247
248 // is this the end of the current segment?
249 if ( m_currentSegment && event.LeftUp() )
250 {
251 if ( !m_currentSegment->IsEmpty() )
252 {
253 // We've got a valid segment on mouse left up, so store it.
254 DrawingDocument * const
255 doc = wxStaticCast(m_view->GetDocument(), DrawingDocument);
256
257 doc->GetCommandProcessor()->Submit(
258 new DrawingAddSegmentCommand(doc, *m_currentSegment));
259
260 doc->Modify(true);
261 }
262
263 wxDELETE(m_currentSegment);
264 }
265
266 // is this the start of a new segment?
267 if ( m_lastMousePos != wxDefaultPosition && event.Dragging() )
268 {
269 if ( !m_currentSegment )
270 m_currentSegment = new DoodleSegment;
271
272 m_currentSegment->AddLine(m_lastMousePos, pt);
273
274 dc.DrawLine(m_lastMousePos, pt);
275 }
276
277 m_lastMousePos = pt;
278}
279
280// ----------------------------------------------------------------------------
281// ImageCanvas implementation
282// ----------------------------------------------------------------------------
283
284// Define a constructor for my canvas
285ImageCanvas::ImageCanvas(wxView* view)
286 : wxScrolledWindow(view->GetFrame())
287{
288 m_view = view;
289 SetScrollRate( 10, 10 );
290}
291
292// Define the repainting behaviour
293void ImageCanvas::OnDraw(wxDC& dc)
294{
295 if ( m_view )
296 m_view->OnDraw(& dc);
297}
298
299// ----------------------------------------------------------------------------
300// ImageView implementation
301// ----------------------------------------------------------------------------
302
303IMPLEMENT_DYNAMIC_CLASS(ImageView, wxView)
304
305ImageDocument* ImageView::GetDocument()
306{
307 return wxStaticCast(wxView::GetDocument(), ImageDocument);
308}
309
310bool ImageView::OnCreate(wxDocument* doc, long flags)
311{
312 if ( !wxView::OnCreate(doc, flags) )
313 return false;
314
315 wxFrame* frame = wxGetApp().CreateChildFrame(this, false);
316 wxASSERT(frame == GetFrame());
317 m_canvas = new ImageCanvas(this);
318 frame->Show();
319
320 return true;
321}
322
323void ImageView::OnUpdate(wxView* sender, wxObject* hint)
324{
325 wxView::OnUpdate(sender, hint);
326 wxImage image = GetDocument()->GetImage();
327 if ( image.IsOk() )
328 {
329 m_canvas->SetVirtualSize(image.GetWidth(), image.GetHeight());
330 }
331}
332
333void ImageView::OnDraw(wxDC* dc)
334{
335 wxImage image = GetDocument()->GetImage();
336 if ( image.IsOk() )
337 {
338 dc->DrawBitmap(wxBitmap(image), 0, 0, true /* use mask */);
339 }
340}
341
342bool ImageView::OnClose(bool deleteWindow)
343{
344 if ( !wxView::OnClose(deleteWindow) )
345 return false;
346
347 Activate(false);
348
349 if ( wxGetApp().GetMode() == MyApp::Mode_Single )
350 {
351 GetDocument()->DeleteContents();
352 }
353 else // not single window mode
354 {
355 if ( deleteWindow )
356 {
357 GetFrame()->Destroy();
358 SetFrame(NULL);
359 }
360 }
361 return true;
362}
363
364// ----------------------------------------------------------------------------
365// ImageDetailsView
366// ----------------------------------------------------------------------------
367
368ImageDetailsView::ImageDetailsView(ImageDetailsDocument *doc)
369 : wxView()
370{
371 SetDocument(doc);
372
373 m_frame = wxGetApp().CreateChildFrame(this, false);
374 m_frame->SetTitle("Image Details");
375
376 wxPanel * const panel = new wxPanel(m_frame);
377 wxFlexGridSizer * const sizer = new wxFlexGridSizer(2, wxSize(5, 5));
378 const wxSizerFlags
379 flags = wxSizerFlags().Align(wxALIGN_CENTRE_VERTICAL).Border();
380
381 sizer->Add(new wxStaticText(panel, wxID_ANY, "Image &file:"), flags);
382 sizer->Add(new wxStaticText(panel, wxID_ANY, doc->GetFilename()), flags);
383
384 sizer->Add(new wxStaticText(panel, wxID_ANY, "Image &type:"), flags);
385 wxString typeStr;
386 switch ( doc->GetType() )
387 {
388 case wxBITMAP_TYPE_PNG:
389 typeStr = "PNG";
390 break;
391
392 case wxBITMAP_TYPE_JPEG:
393 typeStr = "JPEG";
394 break;
395
396 default:
397 typeStr = "Unknown";
398 }
399 sizer->Add(new wxStaticText(panel, wxID_ANY, typeStr), flags);
400
401 sizer->Add(new wxStaticText(panel, wxID_ANY, "Image &size:"), flags);
402 wxSize size = doc->GetSize();
403 sizer->Add(new wxStaticText(panel, wxID_ANY,
404 wxString::Format("%d*%d", size.x, size.y)),
405 flags);
406
407 sizer->Add(new wxStaticText(panel, wxID_ANY, "Number of unique &colours:"),
408 flags);
409 sizer->Add(new wxStaticText(panel, wxID_ANY,
410 wxString::Format("%lu", doc->GetNumColours())),
411 flags);
412
413 sizer->Add(new wxStaticText(panel, wxID_ANY, "Uses &alpha:"), flags);
414 sizer->Add(new wxStaticText(panel, wxID_ANY,
415 doc->HasAlpha() ? "Yes" : "No"), flags);
416
417 panel->SetSizer(sizer);
418 m_frame->SetClientSize(panel->GetBestSize());
419 m_frame->Show(true);
420}
421
422void ImageDetailsView::OnDraw(wxDC * WXUNUSED(dc))
423{
424 // nothing to do here, we use controls to show our information
425}
426
427bool ImageDetailsView::OnClose(bool deleteWindow)
428{
429 if ( wxGetApp().GetMode() != MyApp::Mode_Single && deleteWindow )
430 {
431 delete m_frame;
432 m_frame = NULL;
433 }
434
435 return true;
436}