home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / samples / mdi / mdi.cpp < prev    next >
C/C++ Source or Header  |  2002-12-16  |  16KB  |  513 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        mdi.cpp
  3. // Purpose:     MDI sample
  4. // Author:      Julian Smart
  5. // Modified by:
  6. // Created:     04/01/98
  7. // RCS-ID:      $Id: mdi.cpp,v 1.44.2.2 2002/12/15 10:22:40 MBN Exp $
  8. // Copyright:   (c) Julian Smart and Markus Holzem
  9. // Licence:     wxWindows license
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ===========================================================================
  13. // declarations
  14. // ===========================================================================
  15.  
  16. // ---------------------------------------------------------------------------
  17. // headers
  18. // ---------------------------------------------------------------------------
  19.  
  20. // For compilers that support precompilation, includes "wx/wx.h".
  21. #include "wx/wxprec.h"
  22.  
  23. #ifdef __BORLANDC__
  24.     #pragma hdrstop
  25. #endif
  26.  
  27. #ifndef WX_PRECOMP
  28.     #include "wx/wx.h"
  29.     #include "wx/mdi.h"
  30. #endif
  31.  
  32. #include "wx/toolbar.h"
  33.  
  34. #if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) || defined(__WXMAC__)
  35.     #include "mondrian.xpm"
  36. #endif
  37.  
  38. #include "bitmaps/new.xpm"
  39. #include "bitmaps/open.xpm"
  40. #include "bitmaps/save.xpm"
  41. #include "bitmaps/copy.xpm"
  42. #include "bitmaps/cut.xpm"
  43. #include "bitmaps/paste.xpm"
  44. #include "bitmaps/print.xpm"
  45. #include "bitmaps/help.xpm"
  46.  
  47.  
  48. #include "mdi.h"
  49.  
  50. IMPLEMENT_APP(MyApp)
  51.  
  52. // ---------------------------------------------------------------------------
  53. // global variables
  54. // ---------------------------------------------------------------------------
  55.  
  56. MyFrame *frame = (MyFrame *) NULL;
  57. wxList my_children;
  58.  
  59. // For drawing lines in a canvas
  60. static long xpos = -1;
  61. static long ypos = -1;
  62.  
  63. static int gs_nFrames = 0;
  64.  
  65. // ---------------------------------------------------------------------------
  66. // event tables
  67. // ---------------------------------------------------------------------------
  68.  
  69. BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
  70.     EVT_MENU(MDI_ABOUT, MyFrame::OnAbout)
  71.     EVT_MENU(MDI_NEW_WINDOW, MyFrame::OnNewWindow)
  72.     EVT_MENU(MDI_QUIT, MyFrame::OnQuit)
  73.  
  74.     EVT_CLOSE(MyFrame::OnClose)
  75.  
  76.     EVT_SIZE(MyFrame::OnSize)
  77. END_EVENT_TABLE()
  78.  
  79. // Note that MDI_NEW_WINDOW and MDI_ABOUT commands get passed
  80. // to the parent window for processing, so no need to
  81. // duplicate event handlers here.
  82. BEGIN_EVENT_TABLE(MyChild, wxMDIChildFrame)
  83.     EVT_MENU(MDI_CHILD_QUIT, MyChild::OnQuit)
  84.     EVT_MENU(MDI_REFRESH, MyChild::OnRefresh)
  85.     EVT_MENU(MDI_CHANGE_TITLE, MyChild::OnChangeTitle)
  86.     EVT_MENU(MDI_CHANGE_POSITION, MyChild::OnChangePosition)
  87.     EVT_MENU(MDI_CHANGE_SIZE, MyChild::OnChangeSize)
  88.  
  89.     EVT_SIZE(MyChild::OnSize)
  90.     EVT_MOVE(MyChild::OnMove)
  91.  
  92.     EVT_CLOSE(MyChild::OnClose)
  93. END_EVENT_TABLE()
  94.  
  95. BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
  96.     EVT_MOUSE_EVENTS(MyCanvas::OnEvent)
  97. END_EVENT_TABLE()
  98.  
  99. // ===========================================================================
  100. // implementation
  101. // ===========================================================================
  102.  
  103. // ---------------------------------------------------------------------------
  104. // MyApp
  105. // ---------------------------------------------------------------------------
  106.  
  107. // Initialise this in OnInit, not statically
  108. bool MyApp::OnInit()
  109. {
  110.     // Create the main frame window
  111.  
  112.     frame = new MyFrame((wxFrame *)NULL, -1, _T("MDI Demo"),
  113.                         wxPoint(-1, -1), wxSize(500, 400),
  114.                         wxDEFAULT_FRAME_STYLE | wxHSCROLL | wxVSCROLL);
  115. #ifdef __WXMSW__
  116. #if 0
  117.     // Experimental: change the window menu
  118.     wxMenu* windowMenu = new wxMenu;
  119.     windowMenu->Append(5000, _T("My menu item!"));
  120.     frame->SetWindowMenu(windowMenu);
  121. #endif
  122. #endif
  123.  
  124.     // Give it an icon
  125. #ifdef __WXMSW__
  126.     frame->SetIcon(wxIcon(_T("mdi_icn")));
  127. #else
  128.     frame->SetIcon(wxIcon( mondrian_xpm ));
  129. #endif
  130.  
  131.     // Make a menubar
  132.     wxMenu *file_menu = new wxMenu;
  133.  
  134.     file_menu->Append(MDI_NEW_WINDOW, _T("&New window\tCtrl-N"), _T("Create a new child window"));
  135.     file_menu->Append(MDI_QUIT, _T("&Exit\tAlt-X"), _T("Quit the program"));
  136.  
  137.     wxMenu *help_menu = new wxMenu;
  138.     help_menu->Append(MDI_ABOUT, _T("&About\tF1"));
  139.  
  140.     wxMenuBar *menu_bar = new wxMenuBar;
  141.  
  142.     menu_bar->Append(file_menu, _T("&File"));
  143.     menu_bar->Append(help_menu, _T("&Help"));
  144.  
  145.     // Associate the menu bar with the frame
  146.     frame->SetMenuBar(menu_bar);
  147.  
  148.     frame->CreateStatusBar();
  149.  
  150.     frame->Show(TRUE);
  151.  
  152.     SetTopWindow(frame);
  153.  
  154.     return TRUE;
  155. }
  156.  
  157. // ---------------------------------------------------------------------------
  158. // MyFrame
  159. // ---------------------------------------------------------------------------
  160.  
  161. // Define my frame constructor
  162. MyFrame::MyFrame(wxWindow *parent,
  163.                  const wxWindowID id,
  164.                  const wxString& title,
  165.                  const wxPoint& pos,
  166.                  const wxSize& size,
  167.                  const long style)
  168.        : wxMDIParentFrame(parent, id, title, pos, size,
  169.                           style | wxNO_FULL_REPAINT_ON_RESIZE)
  170. {
  171.     textWindow = new wxTextCtrl(this, -1, _T("A help window"),
  172.                                 wxDefaultPosition, wxDefaultSize,
  173.                                 wxTE_MULTILINE | wxSUNKEN_BORDER);
  174.  
  175.     CreateToolBar(wxNO_BORDER | wxTB_FLAT | wxTB_HORIZONTAL);
  176.     InitToolBar(GetToolBar());
  177.  
  178.     // Accelerators
  179.     wxAcceleratorEntry entries[3];
  180.     entries[0].Set(wxACCEL_CTRL, (int) 'N', MDI_NEW_WINDOW);
  181.     entries[1].Set(wxACCEL_CTRL, (int) 'X', MDI_QUIT);
  182.     entries[2].Set(wxACCEL_CTRL, (int) 'A', MDI_ABOUT);
  183.     wxAcceleratorTable accel(3, entries);
  184.     SetAcceleratorTable(accel);
  185. }
  186.  
  187. void MyFrame::OnClose(wxCloseEvent& event)
  188. {
  189.     if ( event.CanVeto() && (gs_nFrames > 0) )
  190.     {
  191.         wxString msg;
  192.         msg.Printf(_T("%d windows still open, close anyhow?"), gs_nFrames);
  193.         if ( wxMessageBox(msg, _T("Please confirm"),
  194.                           wxICON_QUESTION | wxYES_NO) != wxYES )
  195.         {
  196.             event.Veto();
  197.  
  198.             return;
  199.         }
  200.     }
  201.  
  202.     event.Skip();
  203. }
  204.  
  205. void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
  206. {
  207.     Close();
  208. }
  209.  
  210. void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
  211. {
  212.     (void)wxMessageBox(_T("wxWindows 2.0 MDI Demo\n")
  213.                        _T("Author: Julian Smart (c) 1997\n")
  214.                        _T("Usage: mdi.exe"), _T("About MDI Demo"));
  215. }
  216.  
  217. void MyFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event) )
  218. {
  219.     // Make another frame, containing a canvas
  220.     MyChild *subframe = new MyChild(frame, _T("Canvas Frame"),
  221.                                     wxPoint(-1, -1), wxSize(-1, -1),
  222.                                     wxDEFAULT_FRAME_STYLE);
  223.  
  224.     wxString title;
  225.     title.Printf(_T("Canvas Frame %d"), ++gs_nFrames);
  226.  
  227.     subframe->SetTitle(title);
  228.  
  229.     // Give it an icon
  230. #ifdef __WXMSW__
  231.     subframe->SetIcon(wxIcon(_T("chrt_icn")));
  232. #else
  233.     subframe->SetIcon(wxIcon( mondrian_xpm ));
  234. #endif
  235.  
  236.     // Make a menubar
  237.     wxMenu *file_menu = new wxMenu;
  238.  
  239.     file_menu->Append(MDI_NEW_WINDOW, _T("&New window"));
  240.     file_menu->Append(MDI_CHILD_QUIT, _T("&Close child"), _T("Close this window"));
  241.     file_menu->Append(MDI_QUIT, _T("&Exit"));
  242.  
  243.     wxMenu *option_menu = new wxMenu;
  244.  
  245.     option_menu->Append(MDI_REFRESH, _T("&Refresh picture"));
  246.     option_menu->Append(MDI_CHANGE_TITLE, _T("Change &title...\tCtrl-T"));
  247.     option_menu->AppendSeparator();
  248.     option_menu->Append(MDI_CHANGE_POSITION, _T("Move frame\tCtrl-M"));
  249.     option_menu->Append(MDI_CHANGE_SIZE, _T("Resize frame\tCtrl-S"));
  250.  
  251.     wxMenu *help_menu = new wxMenu;
  252.     help_menu->Append(MDI_ABOUT, _T("&About"));
  253.  
  254.     wxMenuBar *menu_bar = new wxMenuBar;
  255.  
  256.     menu_bar->Append(file_menu, _T("&File"));
  257.     menu_bar->Append(option_menu, _T("&Child"));
  258.     menu_bar->Append(help_menu, _T("&Help"));
  259.  
  260.     // Associate the menu bar with the frame
  261.     subframe->SetMenuBar(menu_bar);
  262.  
  263.     subframe->CreateStatusBar();
  264.     subframe->SetStatusText(title);
  265.  
  266.     int width, height;
  267.     subframe->GetClientSize(&width, &height);
  268.     MyCanvas *canvas = new MyCanvas(subframe, wxPoint(0, 0), wxSize(width, height));
  269.     canvas->SetCursor(wxCursor(wxCURSOR_PENCIL));
  270.     subframe->canvas = canvas;
  271.  
  272.     // Give it scrollbars
  273.     canvas->SetScrollbars(20, 20, 50, 50);
  274.  
  275.     subframe->Show(TRUE);
  276. }
  277.  
  278. void MyFrame::OnSize(wxSizeEvent& event)
  279. {
  280.     int w, h;
  281.     GetClientSize(&w, &h);
  282.  
  283.     textWindow->SetSize(0, 0, 200, h);
  284.     GetClientWindow()->SetSize(200, 0, w - 200, h);
  285.  
  286.     // FIXME: On wxX11, we need the MDI frame to process this
  287.     // event, but on other platforms this should not
  288.     // be done.
  289. #ifdef __WXUNIVERSAL__   
  290.     event.Skip();
  291. #endif
  292. }
  293.  
  294. void MyFrame::InitToolBar(wxToolBar* toolBar)
  295. {
  296.     wxBitmap* bitmaps[8];
  297.  
  298.     bitmaps[0] = new wxBitmap( new_xpm );
  299.     bitmaps[1] = new wxBitmap( open_xpm );
  300.     bitmaps[2] = new wxBitmap( save_xpm );
  301.     bitmaps[3] = new wxBitmap( copy_xpm );
  302.     bitmaps[4] = new wxBitmap( cut_xpm );
  303.     bitmaps[5] = new wxBitmap( paste_xpm );
  304.     bitmaps[6] = new wxBitmap( print_xpm );
  305.     bitmaps[7] = new wxBitmap( help_xpm );
  306.  
  307.     int width = 24;
  308.     int currentX = 5;
  309.  
  310.     toolBar->AddTool( MDI_NEW_WINDOW, *(bitmaps[0]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _T("New file"));
  311.     currentX += width + 5;
  312.     toolBar->AddTool(1, *bitmaps[1], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _T("Open file"));
  313.     currentX += width + 5;
  314.     toolBar->AddTool(2, *bitmaps[2], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _T("Save file"));
  315.     currentX += width + 5;
  316.     toolBar->AddSeparator();
  317.     toolBar->AddTool(3, *bitmaps[3], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _T("Copy"));
  318.     currentX += width + 5;
  319.     toolBar->AddTool(4, *bitmaps[4], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _T("Cut"));
  320.     currentX += width + 5;
  321.     toolBar->AddTool(5, *bitmaps[5], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _T("Paste"));
  322.     currentX += width + 5;
  323.     toolBar->AddSeparator();
  324.     toolBar->AddTool(6, *bitmaps[6], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, _T("Print"));
  325.     currentX += width + 5;
  326.     toolBar->AddSeparator();
  327.     toolBar->AddTool(7, *bitmaps[7], wxNullBitmap, TRUE, currentX, -1, (wxObject *) NULL, _T("Help"));
  328.  
  329.     toolBar->Realize();
  330.  
  331.     int i;
  332.     for (i = 0; i < 8; i++)
  333.         delete bitmaps[i];
  334. }
  335.  
  336. // ---------------------------------------------------------------------------
  337. // MyCanvas
  338. // ---------------------------------------------------------------------------
  339.  
  340. // Define a constructor for my canvas
  341. MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size)
  342.         : wxScrolledWindow(parent, -1, pos, size,
  343.                            wxSUNKEN_BORDER |
  344.                            wxNO_FULL_REPAINT_ON_RESIZE |
  345.                            wxVSCROLL | wxHSCROLL)
  346. {
  347.     SetBackgroundColour(wxColour(_T("WHITE")));
  348.  
  349.     m_dirty = FALSE;
  350. }
  351.  
  352. // Define the repainting behaviour
  353. void MyCanvas::OnDraw(wxDC& dc)
  354. {
  355.     dc.SetFont(*wxSWISS_FONT);
  356.     dc.SetPen(*wxGREEN_PEN);
  357.     dc.DrawLine(0, 0, 200, 200);
  358.     dc.DrawLine(200, 0, 0, 200);
  359.  
  360.     dc.SetBrush(*wxCYAN_BRUSH);
  361.     dc.SetPen(*wxRED_PEN);
  362.     dc.DrawRectangle(100, 100, 100, 50);
  363.     dc.DrawRoundedRectangle(150, 150, 100, 50, 20);
  364.  
  365.     dc.DrawEllipse(250, 250, 100, 50);
  366. #if wxUSE_SPLINES
  367.     dc.DrawSpline(50, 200, 50, 100, 200, 10);
  368. #endif // wxUSE_SPLINES
  369.     dc.DrawLine(50, 230, 200, 230);
  370.     dc.DrawText(_T("This is a test string"), 50, 230);
  371.  
  372.     wxPoint points[3];
  373.     points[0].x = 200; points[0].y = 300;
  374.     points[1].x = 100; points[1].y = 400;
  375.     points[2].x = 300; points[2].y = 400;
  376.  
  377.     dc.DrawPolygon(3, points);
  378. }
  379.  
  380. // This implements a tiny doodling program! Drag the mouse using the left
  381. // button.
  382. void MyCanvas::OnEvent(wxMouseEvent& event)
  383. {
  384.     wxClientDC dc(this);
  385.     PrepareDC(dc);
  386.  
  387.     wxPoint pt(event.GetLogicalPosition(dc));
  388.  
  389.     if (xpos > -1 && ypos > -1 && event.Dragging())
  390.     {
  391.         dc.SetPen(*wxBLACK_PEN);
  392.         dc.DrawLine(xpos, ypos, pt.x, pt.y);
  393.  
  394.         m_dirty = TRUE;
  395.     }
  396.  
  397.     xpos = pt.x;
  398.     ypos = pt.y;
  399. }
  400.  
  401. // ---------------------------------------------------------------------------
  402. // MyChild
  403. // ---------------------------------------------------------------------------
  404.  
  405. MyChild::MyChild(wxMDIParentFrame *parent, const wxString& title,
  406.                  const wxPoint& pos, const wxSize& size,
  407.                  const long style)
  408.        : wxMDIChildFrame(parent, -1, title, pos, size,
  409.                          style | wxNO_FULL_REPAINT_ON_RESIZE)
  410. {
  411.     canvas = (MyCanvas *) NULL;
  412.     my_children.Append(this);
  413.  
  414.     // this should work for MDI frames as well as for normal ones
  415.     SetSizeHints(100, 100);
  416. }
  417.  
  418. MyChild::~MyChild()
  419. {
  420.     my_children.DeleteObject(this);
  421. }
  422.  
  423. void MyChild::OnQuit(wxCommandEvent& WXUNUSED(event))
  424. {
  425.     Close(TRUE);
  426. }
  427.  
  428. void MyChild::OnRefresh(wxCommandEvent& WXUNUSED(event))
  429. {
  430.     if ( canvas )
  431.         canvas->Refresh();
  432. }
  433.  
  434. void MyChild::OnChangePosition(wxCommandEvent& WXUNUSED(event))
  435. {
  436.     Move(10, 10);
  437. }
  438.  
  439. void MyChild::OnChangeSize(wxCommandEvent& WXUNUSED(event))
  440. {
  441.     SetClientSize(100, 100);
  442. }
  443.  
  444. void MyChild::OnChangeTitle(wxCommandEvent& WXUNUSED(event))
  445. {
  446. //#if wxUSE_TEXTDLG
  447.     static wxString s_title = _T("Canvas Frame");
  448.  
  449.     wxString title = wxGetTextFromUser(_T("Enter the new title for MDI child"),
  450.                                        _T("MDI sample question"),
  451.                                        s_title,
  452.                                        GetParent()->GetParent());
  453.     if ( !title )
  454.         return;
  455.  
  456.     s_title = title;
  457.     SetTitle(s_title);
  458. //#endif
  459. }
  460.  
  461. void MyChild::OnActivate(wxActivateEvent& event)
  462. {
  463.     if ( event.GetActive() && canvas )
  464.         canvas->SetFocus();
  465. }
  466.  
  467. void MyChild::OnMove(wxMoveEvent& event)
  468. {
  469.     // VZ: here everything is totally wrong under MSW, the positions are
  470.     //     different and both wrong (pos2 is off by 2 pixels for me which seems
  471.     //     to be the width of the MDI canvas border)
  472.     wxPoint pos1 = event.GetPosition(),
  473.             pos2 = GetPosition();
  474.     wxLogStatus(wxT("position from event: (%d, %d), from frame (%d, %d)"),
  475.                 pos1.x, pos1.y, pos2.x, pos2.y);
  476.  
  477.     event.Skip();
  478. }
  479.  
  480. void MyChild::OnSize(wxSizeEvent& event)
  481. {
  482.     // VZ: under MSW the size event carries the client size (quite
  483.     //     unexpectedly) *except* for the very first one which has the full
  484.     //     size... what should it really be? TODO: check under wxGTK
  485.     wxSize size1 = event.GetSize(),
  486.            size2 = GetSize(),
  487.            size3 = GetClientSize();
  488.     wxLogStatus(wxT("size from event: %dx%d, from frame %dx%d, client %dx%d"),
  489.                 size1.x, size1.y, size2.x, size2.y, size3.x, size3.y);
  490.  
  491.     event.Skip();
  492. }
  493.  
  494. void MyChild::OnClose(wxCloseEvent& event)
  495. {
  496.     if ( canvas && canvas->IsDirty() )
  497.     {
  498.         if ( wxMessageBox(_T("Really close?"), _T("Please confirm"),
  499.                           wxICON_QUESTION | wxYES_NO) != wxYES )
  500.         {
  501.             event.Veto();
  502.  
  503.             return;
  504.         }
  505.     }
  506.  
  507.     gs_nFrames--;
  508.  
  509.     event.Skip();
  510. }
  511.  
  512.  
  513.