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: view.cpp 35650 2005-09-23 12:56:45Z MR $ 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 31IMPLEMENT_DYNAMIC_CLASS(DrawingView, wxView) 32 33// For drawing lines in a canvas 34float xpos = -1; 35float ypos = -1; 36 37BEGIN_EVENT_TABLE(DrawingView, wxView) 38 EVT_MENU(DOODLE_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 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. 63void 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 77void 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. 98bool 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 125void 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 131IMPLEMENT_DYNAMIC_CLASS(TextEditView, wxView) 132 133bool 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 156void TextEditView::OnDraw(wxDC *WXUNUSED(dc) ) 157{ 158} 159 160void TextEditView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) ) 161{ 162} 163 164bool 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 183BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) 184 EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent) 185END_EVENT_TABLE() 186 187// Define a constructor for my canvas 188MyCanvas::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 195void 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. 203void 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 255MyTextWindow::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 262