]>
git.saurik.com Git - wxWidgets.git/blob - samples/docview/view.cpp
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
8 // Copyright: (c) 1998 Julian Smart
9 // (c) 2008 Vadim Zeitlin
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
13 // For compilers that support precompilation, includes "wx/wx.h".
14 #include "wx/wxprec.h"
24 #if !wxUSE_DOC_VIEW_ARCHITECTURE
25 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
32 // ----------------------------------------------------------------------------
33 // DrawingView implementation
34 // ----------------------------------------------------------------------------
36 IMPLEMENT_DYNAMIC_CLASS(DrawingView
, wxView
)
38 BEGIN_EVENT_TABLE(DrawingView
, wxView
)
39 EVT_MENU(wxID_CUT
, DrawingView::OnCut
)
42 // What to do when a view is created. Creates actual
43 // windows for displaying the view.
44 bool DrawingView::OnCreate(wxDocument
*doc
, long flags
)
46 if ( !wxView::OnCreate(doc
, flags
) )
49 MyApp
& app
= wxGetApp();
50 if ( app
.GetMode() != MyApp::Mode_Single
)
52 // create a new window and canvas inside it
53 wxFrame
* frame
= app
.CreateChildFrame(this, true);
54 wxASSERT(frame
== GetFrame());
55 m_canvas
= new MyCanvas(this);
58 else // single document mode
60 // reuse the existing window and canvas
61 m_canvas
= app
.GetMainWindowCanvas();
62 m_canvas
->SetView(this);
64 // Initialize the edit menu Undo and Redo items
65 doc
->GetCommandProcessor()->SetEditMenu(app
.GetMainWindowEditMenu());
66 doc
->GetCommandProcessor()->Initialize();
72 // Sneakily gets used for default print/preview as well as drawing on the
74 void DrawingView::OnDraw(wxDC
*dc
)
76 dc
->SetPen(*wxBLACK_PEN
);
78 // simply draw all lines of all segments
79 const DoodleSegments
& segments
= GetDocument()->GetSegments();
80 for ( DoodleSegments::const_iterator i
= segments
.begin();
84 const DoodleLines
& lines
= i
->GetLines();
85 for ( DoodleLines::const_iterator j
= lines
.begin();
89 const DoodleLine
& line
= *j
;
91 dc
->DrawLine(line
.x1
, line
.y1
, line
.x2
, line
.y2
);
96 DrawingDocument
* DrawingView::GetDocument()
98 return wxStaticCast(wxView::GetDocument(), DrawingDocument
);
101 void DrawingView::OnUpdate(wxView
* sender
, wxObject
* hint
)
103 wxView::OnUpdate(sender
, hint
);
108 // Clean up windows used for displaying the view.
109 bool DrawingView::OnClose(bool deleteWindow
)
111 if ( !wxView::OnClose(deleteWindow
) )
116 // Clear the canvas in single-window mode in which it stays alive
117 if ( wxGetApp().GetMode() == MyApp::Mode_Single
)
119 m_canvas
->ClearBackground();
120 m_canvas
->ResetView();
124 wxStaticCast(GetFrame(), wxFrame
)->SetTitle(wxTheApp
->GetAppDisplayName());
126 else // not single window mode
130 GetFrame()->Destroy();
137 void DrawingView::OnCut(wxCommandEvent
& WXUNUSED(event
) )
139 DrawingDocument
* const doc
= GetDocument();
141 doc
->GetCommandProcessor()->Submit(new DrawingRemoveSegmentCommand(doc
));
144 // ----------------------------------------------------------------------------
145 // TextEditView implementation
146 // ----------------------------------------------------------------------------
148 IMPLEMENT_DYNAMIC_CLASS(TextEditView
, wxView
)
150 BEGIN_EVENT_TABLE(TextEditView
, wxView
)
151 EVT_MENU(wxID_COPY
, TextEditView::OnCopy
)
152 EVT_MENU(wxID_PASTE
, TextEditView::OnPaste
)
153 EVT_MENU(wxID_SELECTALL
, TextEditView::OnSelectAll
)
156 bool TextEditView::OnCreate(wxDocument
*doc
, long flags
)
158 if ( !wxView::OnCreate(doc
, flags
) )
161 wxFrame
* frame
= wxGetApp().CreateChildFrame(this, false);
162 wxASSERT(frame
== GetFrame());
163 m_text
= new wxTextCtrl(frame
, wxID_ANY
, "",
164 wxDefaultPosition
, wxDefaultSize
,
171 void TextEditView::OnDraw(wxDC
*WXUNUSED(dc
))
173 // nothing to do here, wxTextCtrl draws itself
176 bool TextEditView::OnClose(bool deleteWindow
)
178 if ( !wxView::OnClose(deleteWindow
) )
183 if ( wxGetApp().GetMode() == MyApp::Mode_Single
)
187 else // not single window mode
191 GetFrame()->Destroy();
198 // ----------------------------------------------------------------------------
199 // MyCanvas implementation
200 // ----------------------------------------------------------------------------
202 BEGIN_EVENT_TABLE(MyCanvas
, wxScrolledWindow
)
203 EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent
)
206 // Define a constructor for my canvas
207 MyCanvas::MyCanvas(wxView
*view
, wxWindow
*parent
)
208 : wxScrolledWindow(parent
? parent
: view
->GetFrame())
211 m_currentSegment
= NULL
;
212 m_lastMousePos
= wxDefaultPosition
;
214 SetCursor(wxCursor(wxCURSOR_PENCIL
));
216 // this is completely arbitrary and is done just for illustration purposes
217 SetVirtualSize(1000, 1000);
218 SetScrollRate(20, 20);
220 SetBackgroundColour(*wxWHITE
);
223 MyCanvas::~MyCanvas()
225 delete m_currentSegment
;
228 // Define the repainting behaviour
229 void MyCanvas::OnDraw(wxDC
& dc
)
232 m_view
->OnDraw(& dc
);
235 // This implements a tiny doodling program. Drag the mouse using the left
237 void MyCanvas::OnMouseEvent(wxMouseEvent
& event
)
245 dc
.SetPen(*wxBLACK_PEN
);
247 const wxPoint
pt(event
.GetLogicalPosition(dc
));
249 // is this the end of the current segment?
250 if ( m_currentSegment
&& event
.LeftUp() )
252 if ( !m_currentSegment
->IsEmpty() )
254 // We've got a valid segment on mouse left up, so store it.
255 DrawingDocument
* const
256 doc
= wxStaticCast(m_view
->GetDocument(), DrawingDocument
);
258 doc
->GetCommandProcessor()->Submit(
259 new DrawingAddSegmentCommand(doc
, *m_currentSegment
));
264 wxDELETE(m_currentSegment
);
267 // is this the start of a new segment?
268 if ( m_lastMousePos
!= wxDefaultPosition
&& event
.Dragging() )
270 if ( !m_currentSegment
)
271 m_currentSegment
= new DoodleSegment
;
273 m_currentSegment
->AddLine(m_lastMousePos
, pt
);
275 dc
.DrawLine(m_lastMousePos
, pt
);
281 // ----------------------------------------------------------------------------
282 // ImageCanvas implementation
283 // ----------------------------------------------------------------------------
285 // Define a constructor for my canvas
286 ImageCanvas::ImageCanvas(wxView
* view
)
287 : wxScrolledWindow(view
->GetFrame())
290 SetScrollRate( 10, 10 );
293 // Define the repainting behaviour
294 void ImageCanvas::OnDraw(wxDC
& dc
)
297 m_view
->OnDraw(& dc
);
300 // ----------------------------------------------------------------------------
301 // ImageView implementation
302 // ----------------------------------------------------------------------------
304 IMPLEMENT_DYNAMIC_CLASS(ImageView
, wxView
)
306 ImageDocument
* ImageView::GetDocument()
308 return wxStaticCast(wxView::GetDocument(), ImageDocument
);
311 bool ImageView::OnCreate(wxDocument
* doc
, long flags
)
313 if ( !wxView::OnCreate(doc
, flags
) )
316 wxFrame
* frame
= wxGetApp().CreateChildFrame(this, false);
317 wxASSERT(frame
== GetFrame());
318 m_canvas
= new ImageCanvas(this);
324 void ImageView::OnUpdate(wxView
* sender
, wxObject
* hint
)
326 wxView::OnUpdate(sender
, hint
);
327 wxImage image
= GetDocument()->GetImage();
330 m_canvas
->SetVirtualSize(image
.GetWidth(), image
.GetHeight());
334 void ImageView::OnDraw(wxDC
* dc
)
336 wxImage image
= GetDocument()->GetImage();
339 dc
->DrawBitmap(wxBitmap(image
), 0, 0, true /* use mask */);
343 bool ImageView::OnClose(bool deleteWindow
)
345 if ( !wxView::OnClose(deleteWindow
) )
350 if ( wxGetApp().GetMode() == MyApp::Mode_Single
)
352 GetDocument()->DeleteContents();
354 else // not single window mode
358 GetFrame()->Destroy();
365 // ----------------------------------------------------------------------------
367 // ----------------------------------------------------------------------------
369 ImageDetailsView::ImageDetailsView(ImageDetailsDocument
*doc
)
374 m_frame
= wxGetApp().CreateChildFrame(this, false);
375 m_frame
->SetTitle("Image Details");
377 wxPanel
* const panel
= new wxPanel(m_frame
);
378 wxFlexGridSizer
* const sizer
= new wxFlexGridSizer(2, wxSize(5, 5));
380 flags
= wxSizerFlags().Align(wxALIGN_CENTRE_VERTICAL
).Border();
382 sizer
->Add(new wxStaticText(panel
, wxID_ANY
, "Image &file:"), flags
);
383 sizer
->Add(new wxStaticText(panel
, wxID_ANY
, doc
->GetFilename()), flags
);
385 sizer
->Add(new wxStaticText(panel
, wxID_ANY
, "Image &type:"), flags
);
387 switch ( doc
->GetType() )
389 case wxBITMAP_TYPE_PNG
:
393 case wxBITMAP_TYPE_JPEG
:
400 sizer
->Add(new wxStaticText(panel
, wxID_ANY
, typeStr
), flags
);
402 sizer
->Add(new wxStaticText(panel
, wxID_ANY
, "Image &size:"), flags
);
403 wxSize size
= doc
->GetSize();
404 sizer
->Add(new wxStaticText(panel
, wxID_ANY
,
405 wxString::Format("%d*%d", size
.x
, size
.y
)),
408 sizer
->Add(new wxStaticText(panel
, wxID_ANY
, "Number of unique &colours:"),
410 sizer
->Add(new wxStaticText(panel
, wxID_ANY
,
411 wxString::Format("%lu", doc
->GetNumColours())),
414 sizer
->Add(new wxStaticText(panel
, wxID_ANY
, "Uses &alpha:"), flags
);
415 sizer
->Add(new wxStaticText(panel
, wxID_ANY
,
416 doc
->HasAlpha() ? "Yes" : "No"), flags
);
418 panel
->SetSizer(sizer
);
419 m_frame
->SetClientSize(panel
->GetBestSize());
423 void ImageDetailsView::OnDraw(wxDC
* WXUNUSED(dc
))
425 // nothing to do here, we use controls to show our information
428 bool ImageDetailsView::OnClose(bool deleteWindow
)
430 if ( wxGetApp().GetMode() != MyApp::Mode_Single
&& deleteWindow
)