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