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 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. 84void 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 98void 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. 119bool 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 146void 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 152IMPLEMENT_DYNAMIC_CLASS(TextEditView, wxView) 153 154bool 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 177void TextEditView::OnDraw(wxDC *WXUNUSED(dc) ) 178{ 179} 180 181void TextEditView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) ) 182{ 183} 184 185bool 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 204BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) 205 EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent) 206END_EVENT_TABLE() 207 208// Define a constructor for my canvas 209MyCanvas::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 216void 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. 224void 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 276MyTextWindow::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 283