git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@56053 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			285 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        samples/docview/view.cpp
 | 
						|
// Purpose:     View classes implementation
 | 
						|
// Author:      Julian Smart
 | 
						|
// Modified by: Vadim Zeitlin: merge with the MDI version and general cleanup
 | 
						|
// Created:     04/01/98
 | 
						|
// RCS-ID:      $Id$
 | 
						|
// Copyright:   (c) 1998 Julian Smart
 | 
						|
//              (c) 2008 Vadim Zeitlin
 | 
						|
// Licence:     wxWindows license
 | 
						|
/////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// For compilers that support precompilation, includes "wx/wx.h".
 | 
						|
#include "wx/wxprec.h"
 | 
						|
 | 
						|
#ifdef __BORLANDC__
 | 
						|
    #pragma hdrstop
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef WX_PRECOMP
 | 
						|
    #include "wx/wx.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#if !wxUSE_DOC_VIEW_ARCHITECTURE
 | 
						|
    #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
 | 
						|
#endif
 | 
						|
 | 
						|
#include "docview.h"
 | 
						|
#include "doc.h"
 | 
						|
#include "view.h"
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// DrawingView implementation
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
IMPLEMENT_DYNAMIC_CLASS(DrawingView, wxView)
 | 
						|
 | 
						|
BEGIN_EVENT_TABLE(DrawingView, wxView)
 | 
						|
    EVT_MENU(wxID_CUT, DrawingView::OnCut)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
// What to do when a view is created. Creates actual
 | 
						|
// windows for displaying the view.
 | 
						|
bool DrawingView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
 | 
						|
{
 | 
						|
    MyApp& app = wxGetApp();
 | 
						|
    if ( app.GetMode() != MyApp::Mode_Single )
 | 
						|
    {
 | 
						|
        // create a new window and canvas inside it
 | 
						|
        m_frame = app.CreateChildFrame(doc, this, true);
 | 
						|
        m_frame->SetTitle("Drawing View");
 | 
						|
 | 
						|
        m_canvas = new MyCanvas(this, m_frame);
 | 
						|
        m_frame->Show(true);
 | 
						|
    }
 | 
						|
    else // single document mode
 | 
						|
    {
 | 
						|
        // reuse the existing window and canvas
 | 
						|
        m_frame = wxStaticCast(app.GetTopWindow(), wxFrame);
 | 
						|
        m_canvas = app.GetMainWindowCanvas();
 | 
						|
        m_canvas->SetView(this);
 | 
						|
 | 
						|
        // Associate the appropriate frame with this view.
 | 
						|
        SetFrame(m_frame);
 | 
						|
 | 
						|
        // Make sure the document manager knows that this is the
 | 
						|
        // current view.
 | 
						|
        Activate(true);
 | 
						|
 | 
						|
        // Initialize the edit menu Undo and Redo items
 | 
						|
        doc->GetCommandProcessor()->SetEditMenu(app.GetMainWindowEditMenu());
 | 
						|
        doc->GetCommandProcessor()->Initialize();
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
// Sneakily gets used for default print/preview as well as drawing on the
 | 
						|
// screen.
 | 
						|
void DrawingView::OnDraw(wxDC *dc)
 | 
						|
{
 | 
						|
    dc->SetPen(*wxBLACK_PEN);
 | 
						|
 | 
						|
    // simply draw all lines of all segments
 | 
						|
    const DoodleSegments& segments = GetDocument()->GetSegments();
 | 
						|
    for ( DoodleSegments::const_iterator i = segments.begin();
 | 
						|
          i != segments.end();
 | 
						|
          ++i )
 | 
						|
    {
 | 
						|
        const DoodleLines& lines = i->GetLines();
 | 
						|
        for ( DoodleLines::const_iterator j = lines.begin(); 
 | 
						|
              j != lines.end();
 | 
						|
              ++j )
 | 
						|
        {
 | 
						|
            const DoodleLine& line = *j;
 | 
						|
 | 
						|
            dc->DrawLine(line.x1, line.y1, line.x2, line.y2);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
DrawingDocument* DrawingView::GetDocument()
 | 
						|
{
 | 
						|
    return wxStaticCast(wxView::GetDocument(), DrawingDocument);
 | 
						|
}
 | 
						|
 | 
						|
void DrawingView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint))
 | 
						|
{
 | 
						|
    if ( m_canvas )
 | 
						|
        m_canvas->Refresh();
 | 
						|
}
 | 
						|
 | 
						|
// Clean up windows used for displaying the view.
 | 
						|
bool DrawingView::OnClose(bool deleteWindow)
 | 
						|
{
 | 
						|
    if ( !GetDocument()->Close() )
 | 
						|
        return false;
 | 
						|
 | 
						|
    Activate(false);
 | 
						|
 | 
						|
    // Clear the canvas in single-window mode in which it stays alive
 | 
						|
    if ( wxGetApp().GetMode() == MyApp::Mode_Single )
 | 
						|
    {
 | 
						|
        m_canvas->ClearBackground();
 | 
						|
        m_canvas->ResetView();
 | 
						|
        m_canvas = NULL;
 | 
						|
 | 
						|
        if ( m_frame )
 | 
						|
            m_frame->SetTitle(wxTheApp->GetAppDisplayName());
 | 
						|
    }
 | 
						|
    else // not single window mode
 | 
						|
    {
 | 
						|
        if ( deleteWindow )
 | 
						|
            wxDELETE(m_frame);
 | 
						|
    }
 | 
						|
 | 
						|
    SetFrame(NULL);
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
void DrawingView::OnCut(wxCommandEvent& WXUNUSED(event) )
 | 
						|
{
 | 
						|
    DrawingDocument * const doc = GetDocument();
 | 
						|
 | 
						|
    doc->GetCommandProcessor()->Submit(new DrawingRemoveSegmentCommand(doc));
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// TextEditView implementation
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
IMPLEMENT_DYNAMIC_CLASS(TextEditView, wxView)
 | 
						|
 | 
						|
BEGIN_EVENT_TABLE(TextEditView, wxView)
 | 
						|
    EVT_MENU(wxID_COPY, TextEditView::OnCopy)
 | 
						|
    EVT_MENU(wxID_PASTE, TextEditView::OnPaste)
 | 
						|
    EVT_MENU(wxID_SELECTALL, TextEditView::OnSelectAll)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
bool TextEditView::OnCreate(wxDocument *doc, long WXUNUSED(flags))
 | 
						|
{
 | 
						|
    m_frame = wxGetApp().CreateChildFrame(doc, this, false);
 | 
						|
    m_text = new wxTextCtrl(m_frame, wxID_ANY, "",
 | 
						|
                            wxPoint(0, 0), m_frame->GetClientSize(),
 | 
						|
                            wxTE_MULTILINE);
 | 
						|
 | 
						|
    m_frame->SetTitle("Text View");
 | 
						|
    m_frame->Show(true);
 | 
						|
 | 
						|
    Activate(true);
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
void TextEditView::OnDraw(wxDC *WXUNUSED(dc))
 | 
						|
{
 | 
						|
    // nothing to do here, wxTextCtrl draws itself
 | 
						|
}
 | 
						|
 | 
						|
bool TextEditView::OnClose(bool deleteWindow)
 | 
						|
{
 | 
						|
    if ( !GetDocument()->Close() )
 | 
						|
        return false;
 | 
						|
 | 
						|
    Activate(false);
 | 
						|
 | 
						|
    if ( wxGetApp().GetMode() == MyApp::Mode_Single )
 | 
						|
    {
 | 
						|
        m_text->Clear();
 | 
						|
    }
 | 
						|
    else // not single window mode
 | 
						|
    {
 | 
						|
        if ( deleteWindow )
 | 
						|
            wxDELETE(m_frame);
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// MyCanvas implementation
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
 | 
						|
    EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
// Define a constructor for my canvas
 | 
						|
MyCanvas::MyCanvas(wxView *view, wxWindow *parent)
 | 
						|
    : wxScrolledWindow(parent, wxID_ANY, wxPoint(0, 0), parent->GetClientSize())
 | 
						|
{
 | 
						|
    m_view = view;
 | 
						|
    m_currentSegment = NULL;
 | 
						|
    m_lastMousePos = wxDefaultPosition;
 | 
						|
 | 
						|
    SetCursor(wxCursor(wxCURSOR_PENCIL));
 | 
						|
 | 
						|
    // this is completely arbitrary and is done just for illustration purposes
 | 
						|
    SetVirtualSize(1000, 1000);
 | 
						|
    SetScrollRate(20, 20);
 | 
						|
 | 
						|
    SetBackgroundColour(*wxWHITE);
 | 
						|
}
 | 
						|
 | 
						|
MyCanvas::~MyCanvas()
 | 
						|
{
 | 
						|
    delete m_currentSegment;
 | 
						|
}
 | 
						|
 | 
						|
// Define the repainting behaviour
 | 
						|
void MyCanvas::OnDraw(wxDC& dc)
 | 
						|
{
 | 
						|
    if ( m_view )
 | 
						|
        m_view->OnDraw(& dc);
 | 
						|
}
 | 
						|
 | 
						|
// This implements a tiny doodling program. Drag the mouse using the left
 | 
						|
// button.
 | 
						|
void MyCanvas::OnMouseEvent(wxMouseEvent& event)
 | 
						|
{
 | 
						|
    if ( !m_view )
 | 
						|
        return;
 | 
						|
 | 
						|
    wxClientDC dc(this);
 | 
						|
    PrepareDC(dc);
 | 
						|
 | 
						|
    dc.SetPen(*wxBLACK_PEN);
 | 
						|
 | 
						|
    const wxPoint pt(event.GetLogicalPosition(dc));
 | 
						|
 | 
						|
    // is this the end of the current segment?
 | 
						|
    if ( m_currentSegment && event.LeftUp() )
 | 
						|
    {
 | 
						|
        if ( !m_currentSegment->IsEmpty() )
 | 
						|
        {
 | 
						|
            // We've got a valid segment on mouse left up, so store it.
 | 
						|
            DrawingDocument * const
 | 
						|
                doc = wxStaticCast(m_view->GetDocument(), DrawingDocument);
 | 
						|
 | 
						|
            doc->GetCommandProcessor()->Submit(
 | 
						|
                new DrawingAddSegmentCommand(doc, *m_currentSegment));
 | 
						|
 | 
						|
            doc->Modify(true);
 | 
						|
        }
 | 
						|
 | 
						|
        delete m_currentSegment;
 | 
						|
        m_currentSegment = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    // is this the start of a new segment?
 | 
						|
    if ( m_lastMousePos != wxDefaultPosition && event.Dragging() )
 | 
						|
    {
 | 
						|
        if ( !m_currentSegment )
 | 
						|
            m_currentSegment = new DoodleSegment;
 | 
						|
 | 
						|
        m_currentSegment->AddLine(m_lastMousePos, pt);
 | 
						|
 | 
						|
        dc.DrawLine(m_lastMousePos, pt);
 | 
						|
    }
 | 
						|
 | 
						|
    m_lastMousePos = pt;
 | 
						|
}
 | 
						|
 |