home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / samples / scroll / scroll.cpp < prev    next >
C/C++ Source or Header  |  2001-11-22  |  13KB  |  452 lines

  1. /*
  2.  * Program: scroll
  3.  *
  4.  * Author: Robert Roebling
  5.  *
  6.  * Copyright: (C) 1998, Robert Roebling
  7.  *
  8.  */
  9.  
  10. // For compilers that support precompilation, includes "wx/wx.h".
  11. #include "wx/wxprec.h"
  12.  
  13. #ifdef __BORLANDC__
  14. #pragma hdrstop
  15. #endif
  16.  
  17. #ifndef WX_PRECOMP
  18. #include "wx/wx.h"
  19. #endif
  20.  
  21. #include "wx/image.h"
  22. #include "wx/listctrl.h"
  23. #include "wx/sizer.h"
  24. #include "wx/log.h"
  25.  
  26.  
  27. // derived classes
  28.  
  29. class MyFrame;
  30. class MyApp;
  31.  
  32. // MyCanvas
  33.  
  34. class MyCanvas: public wxScrolledWindow
  35. {
  36. public:
  37.     MyCanvas() {}
  38.     MyCanvas( wxWindow *parent, wxWindowID, const wxPoint &pos, const wxSize &size );
  39.     ~MyCanvas();
  40.     void OnPaint( wxPaintEvent &event );
  41.     void OnQueryPosition( wxCommandEvent &event );
  42.     void OnAddButton( wxCommandEvent &event );
  43.     void OnDeleteButton( wxCommandEvent &event );
  44.     void OnMoveButton( wxCommandEvent &event );
  45.     void OnScrollWin( wxCommandEvent &event );
  46.     void OnMouseDown( wxMouseEvent &event );
  47.  
  48.     wxButton *m_button;
  49.  
  50.     DECLARE_DYNAMIC_CLASS(MyCanvas)
  51.     DECLARE_EVENT_TABLE()
  52. };
  53.  
  54. // ----------------------------------------------------------------------------
  55. // MyScrolledWindow classes: examples of wxScrolledWindow usage
  56. // ----------------------------------------------------------------------------
  57.  
  58. // base class for both of them
  59. class MyScrolledWindowBase : public wxScrolledWindow
  60. {
  61. public:
  62.     MyScrolledWindowBase(wxWindow *parent) : wxScrolledWindow(parent)
  63.     {
  64.         m_nLines = 100;
  65.  
  66.         InitScrollbars();
  67.     }
  68.  
  69. protected:
  70.     // set the scrollbar params
  71.     void InitScrollbars();
  72.  
  73.     // the height of one line on screen
  74.     wxCoord m_hLine;
  75.  
  76.     // the number of lines we draw
  77.     size_t m_nLines;
  78. };
  79.  
  80. // this class does "stupid" redrawing - it redraws everything each time
  81. class MyScrolledWindowDumb : public MyScrolledWindowBase
  82. {
  83. public:
  84.     MyScrolledWindowDumb(wxWindow *parent) : MyScrolledWindowBase(parent) { }
  85.  
  86.     virtual void OnDraw(wxDC& dc);
  87. };
  88.  
  89. // this class does "smart" redrawing - only redraws the lines which must be
  90. // redrawn
  91. class MyScrolledWindowSmart : public MyScrolledWindowBase
  92. {
  93. public:
  94.     MyScrolledWindowSmart(wxWindow *parent) : MyScrolledWindowBase(parent) { }
  95.  
  96.     virtual void OnDraw(wxDC& dc);
  97. };
  98.  
  99. // ----------------------------------------------------------------------------
  100. // MyFrame
  101. // ----------------------------------------------------------------------------
  102.  
  103. class MyFrame: public wxFrame
  104. {
  105. public:
  106.     MyFrame();
  107.  
  108.     void OnAbout( wxCommandEvent &event );
  109.     void OnQuit( wxCommandEvent &event );
  110.     void OnDeleteAll( wxCommandEvent &event );
  111.     void OnInsertNew( wxCommandEvent &event );
  112.  
  113.     MyCanvas         *m_canvas;
  114.     wxTextCtrl       *m_log;
  115.  
  116.     DECLARE_DYNAMIC_CLASS(MyFrame)
  117.     DECLARE_EVENT_TABLE()
  118. };
  119.  
  120. // MyApp
  121.  
  122. class MyApp: public wxApp
  123. {
  124. public:
  125.     virtual bool OnInit();
  126. };
  127.  
  128. // main program
  129.  
  130. IMPLEMENT_APP(MyApp)
  131.  
  132. // ids
  133.  
  134. #define   ID_ADDBUTTON    1
  135. #define   ID_DELBUTTON    2
  136. #define   ID_MOVEBUTTON   3
  137. #define   ID_SCROLLWIN    4
  138. #define   ID_QUERYPOS     5
  139.  
  140. #define   ID_NEWBUTTON    10
  141.  
  142. // MyCanvas
  143.  
  144. IMPLEMENT_DYNAMIC_CLASS(MyCanvas, wxScrolledWindow)
  145.  
  146. BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
  147.   EVT_PAINT(                  MyCanvas::OnPaint)
  148.   EVT_MOUSE_EVENTS(                  MyCanvas::OnMouseDown)
  149.   EVT_BUTTON( ID_QUERYPOS,    MyCanvas::OnQueryPosition)
  150.   EVT_BUTTON( ID_ADDBUTTON,   MyCanvas::OnAddButton)
  151.   EVT_BUTTON( ID_DELBUTTON,   MyCanvas::OnDeleteButton)
  152.   EVT_BUTTON( ID_MOVEBUTTON,  MyCanvas::OnMoveButton)
  153.   EVT_BUTTON( ID_SCROLLWIN,   MyCanvas::OnScrollWin)
  154. END_EVENT_TABLE()
  155.  
  156. MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id,
  157.                     const wxPoint &pos, const wxSize &size )
  158.         : wxScrolledWindow( parent, id, pos, size, wxSUNKEN_BORDER | wxTAB_TRAVERSAL, "test canvas" )
  159. {
  160.     (void) new wxButton( this, ID_ADDBUTTON, "add button", wxPoint(10,10) );
  161.     (void) new wxButton( this, ID_DELBUTTON, "del button", wxPoint(10,40) );
  162.     (void) new wxButton( this, ID_MOVEBUTTON, "move button", wxPoint(150,10) );
  163.     (void) new wxButton( this, ID_SCROLLWIN, "scroll win", wxPoint(250,10) );
  164.  
  165. #if 0
  166.  
  167.     wxString choices[] =
  168.     {
  169.         "This",
  170.         "is one of my",
  171.         "really",
  172.         "wonderful",
  173.         "examples."
  174.     };
  175.  
  176.     m_button = new wxButton( this, ID_QUERYPOS, "Query position", wxPoint(10,110) );
  177.  
  178.     (void) new wxTextCtrl( this, -1, "wxTextCtrl", wxPoint(10,150), wxSize(80,-1) );
  179.  
  180.     (void) new wxRadioButton( this, -1, "Disable", wxPoint(10,190) );
  181.  
  182.     (void) new wxComboBox( this, -1, "This", wxPoint(10,230), wxDefaultSize, 5, choices );
  183.  
  184.     (void) new wxRadioBox( this, -1, "This", wxPoint(10,310), wxDefaultSize, 5, choices, 2, wxRA_SPECIFY_COLS );
  185.  
  186.     (void) new wxRadioBox( this, -1, "This", wxPoint(10,440), wxDefaultSize, 5, choices, 2, wxRA_SPECIFY_ROWS );
  187.  
  188.     wxListCtrl *m_listCtrl = new wxListCtrl(
  189.             this, -1, wxPoint(200, 110), wxSize(180, 120),
  190.             wxLC_REPORT | wxSIMPLE_BORDER | wxLC_SINGLE_SEL );
  191.  
  192.     m_listCtrl->InsertColumn(0, "First", wxLIST_FORMAT_LEFT, 90);
  193.     m_listCtrl->InsertColumn(1, "Last", wxLIST_FORMAT_LEFT, 90);
  194.  
  195.     for ( int i=0; i < 30; i++)
  196.     {
  197.         char buf[20];
  198.         sprintf(buf, "Item %d", i);
  199.         m_listCtrl->InsertItem(i, buf);
  200.     }
  201.     m_listCtrl->SetItemState( 3, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
  202.  
  203.     (void) new wxListBox( this, -1, wxPoint(260,280), wxSize(120,120), 5, choices, wxLB_ALWAYS_SB );
  204.  
  205. #endif
  206.  
  207.     wxPanel *test = new wxPanel( this, -1, wxPoint(10, 110), wxSize(130,50), wxSIMPLE_BORDER | wxTAB_TRAVERSAL );
  208.     test->SetBackgroundColour( wxT("WHEAT") );
  209.  
  210. #if 0
  211.  
  212.     wxButton *test2 = new wxButton( test, -1, "Hallo", wxPoint(10,10) );
  213.  
  214.     test = new wxPanel( this, -1, wxPoint(160, 530), wxSize(130,120), wxSUNKEN_BORDER | wxTAB_TRAVERSAL );
  215.     test->SetBackgroundColour( wxT("WHEAT") );
  216.     test->SetCursor( wxCursor( wxCURSOR_NO_ENTRY ) );
  217.     test2 = new wxButton( test, -1, "Hallo", wxPoint(10,10) );
  218.     test2->SetCursor( wxCursor( wxCURSOR_PENCIL ) );
  219.  
  220.     test = new wxPanel( this, -1, wxPoint(310, 530), wxSize(130,120), wxRAISED_BORDER | wxTAB_TRAVERSAL );
  221.     test->SetBackgroundColour( wxT("WHEAT") );
  222.     test->SetCursor( wxCursor( wxCURSOR_PENCIL ) );
  223.     test2 = new wxButton( test, -1, "Hallo", wxPoint(10,10) );
  224.     test2->SetCursor( wxCursor( wxCURSOR_NO_ENTRY ) );
  225.  
  226. #endif
  227.  
  228.     SetBackgroundColour( wxT("BLUE") );
  229.  
  230.     SetCursor( wxCursor( wxCURSOR_IBEAM ) );
  231. }
  232.  
  233. MyCanvas::~MyCanvas()
  234. {
  235. }
  236.  
  237. void MyCanvas::OnMouseDown( wxMouseEvent &event )
  238. {
  239.     if (event.LeftDown())
  240.     {
  241.         wxPoint pt( event.GetPosition() );
  242.         int x,y;
  243.         CalcUnscrolledPosition( pt.x, pt.y, &x, &y );
  244.         wxLogMessage( wxT("Mouse down event at: %d %d, scrolled: %d %d"), pt.x, pt.y, x, y );
  245.  
  246.         if ( !event.LeftIsDown() )
  247.             wxLogMessage( wxT("Error: LeftIsDown() should be TRUE if for LeftDown()") );
  248.     }
  249. }
  250.  
  251. void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
  252. {
  253.     wxPaintDC dc( this );
  254.     PrepareDC( dc );
  255.  
  256.     dc.DrawText( "Press mouse button to test calculations!", 160, 50 );
  257.  
  258.     dc.DrawText( "Some text", 140, 140 );
  259.  
  260.     dc.DrawRectangle( 100, 160, 200, 200 );
  261. }
  262.  
  263. void MyCanvas::OnQueryPosition( wxCommandEvent &WXUNUSED(event) )
  264. {
  265.     wxPoint pt( m_button->GetPosition() );
  266.     wxLogMessage( wxT("Position of \"Query position\" is %d %d"), pt.x, pt.y );
  267.     pt = ClientToScreen( pt );
  268.     wxLogMessage( wxT("Position of \"Query position\" on screen is %d %d"), pt.x, pt.y );
  269. }
  270.  
  271. void MyCanvas::OnAddButton( wxCommandEvent &WXUNUSED(event) )
  272. {
  273.     wxLogMessage( wxT("Inserting button at position 10,70...") );
  274.     wxButton *button = new wxButton( this, ID_NEWBUTTON, "new button", wxPoint(10,70), wxSize(80,25) );
  275.     wxPoint pt( button->GetPosition() );
  276.     wxLogMessage( wxT("-> Position after inserting %d %d"), pt.x, pt.y );
  277. }
  278.  
  279. void MyCanvas::OnDeleteButton( wxCommandEvent &event )
  280. {
  281.     wxLogMessage( wxT("Deleting button inserted with \"Add button\"...") );
  282.     wxWindow *win = FindWindow( ID_NEWBUTTON );
  283.     if (win)
  284.        win->Destroy();
  285.     else
  286.        wxLogMessage( wxT("-> No window with id = ID_NEWBUTTON found.") );
  287. }
  288.  
  289. void MyCanvas::OnMoveButton( wxCommandEvent &event )
  290. {
  291.     wxLogMessage( wxT("Moving button 10 pixels downward..") );
  292.     wxWindow *win = FindWindow( event.GetId() );
  293.     wxPoint pt( win->GetPosition() );
  294.     wxLogMessage( wxT("-> Position before move is %d %d"), pt.x, pt.y );
  295.     win->Move( -1, pt.y + 10 );
  296.     pt = win->GetPosition();
  297.     wxLogMessage( wxT("-> Position after move is %d %d"), pt.x, pt.y );
  298. }
  299.  
  300. void MyCanvas::OnScrollWin( wxCommandEvent &WXUNUSED(event) )
  301. {
  302.     wxLogMessage( wxT("Scrolling 2 units up.\nThe white square and the controls should move equally!") );
  303.     int x,y;
  304.     GetViewStart( &x, &y );
  305.     Scroll( -1, y+2 );
  306. }
  307.  
  308. // MyFrame
  309.  
  310. const int ID_QUIT  = 108;
  311. const int ID_ABOUT = 109;
  312. const int ID_DELETE_ALL = 110;
  313. const int ID_INSERT_NEW = 111;
  314.  
  315. IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
  316.  
  317. BEGIN_EVENT_TABLE(MyFrame,wxFrame)
  318.   EVT_MENU    (ID_DELETE_ALL, MyFrame::OnDeleteAll)
  319.   EVT_MENU    (ID_INSERT_NEW,  MyFrame::OnInsertNew)
  320.   EVT_MENU    (ID_ABOUT, MyFrame::OnAbout)
  321.   EVT_MENU    (ID_QUIT,  MyFrame::OnQuit)
  322. END_EVENT_TABLE()
  323.  
  324. MyFrame::MyFrame()
  325.        : wxFrame( (wxFrame *)NULL, -1, "wxScrolledWindow sample",
  326.                   wxPoint(20,20), wxSize(470,500) )
  327. {
  328.     wxMenu *file_menu = new wxMenu();
  329.     file_menu->Append( ID_DELETE_ALL, "Delete all");
  330.     file_menu->Append( ID_INSERT_NEW, "Insert new");
  331.     file_menu->Append( ID_ABOUT, "&About..");
  332.     file_menu->Append( ID_QUIT, "E&xit\tAlt-X");
  333.  
  334.     wxMenuBar *menu_bar = new wxMenuBar();
  335.     menu_bar->Append(file_menu, "&File");
  336.  
  337.     SetMenuBar( menu_bar );
  338.  
  339.     CreateStatusBar(2);
  340.     int widths[] = { -1, 100 };
  341.     SetStatusWidths( 2, widths );
  342.  
  343.     m_canvas = new MyCanvas( this, -1, wxPoint(0,0), wxSize(100,100) );
  344.     m_canvas->SetScrollbars( 10, 10, 50, 100 );
  345.  
  346.     wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
  347.  
  348.     topsizer->Add( m_canvas, 1, wxEXPAND );
  349.  
  350.     wxSizer *sizerBtm = new wxBoxSizer(wxHORIZONTAL);
  351.     sizerBtm->Add( new MyScrolledWindowDumb(this), 1, wxEXPAND );
  352.     sizerBtm->Add( new MyScrolledWindowSmart(this), 1, wxEXPAND );
  353.     topsizer->Add( sizerBtm, 1, wxEXPAND );
  354.  
  355.     SetAutoLayout( TRUE );
  356.     SetSizer( topsizer );
  357. }
  358.  
  359. void MyFrame::OnDeleteAll( wxCommandEvent &WXUNUSED(event) )
  360. {
  361.     m_canvas->DestroyChildren();
  362. }
  363.  
  364. void MyFrame::OnInsertNew( wxCommandEvent &WXUNUSED(event) )
  365. {
  366.     (void)new wxButton( m_canvas, -1, "Hello", wxPoint(100,100) );
  367. }
  368.  
  369. void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) )
  370. {
  371.   Close( TRUE );
  372. }
  373.  
  374. void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) )
  375. {
  376.   (void)wxMessageBox( "wxScroll demo\n"
  377.                       "Robert Roebling (c) 1998",
  378.                       "About wxScroll Demo", wxICON_INFORMATION | wxOK );
  379. }
  380.  
  381. //-----------------------------------------------------------------------------
  382. // MyApp
  383. //-----------------------------------------------------------------------------
  384.  
  385. bool MyApp::OnInit()
  386. {
  387.   wxFrame *frame = new MyFrame();
  388.   frame->Show( TRUE );
  389.  
  390.   return TRUE;
  391. }
  392.  
  393. // ----------------------------------------------------------------------------
  394. // MyScrolledWindowXXX
  395. // ----------------------------------------------------------------------------
  396.  
  397. void MyScrolledWindowBase::InitScrollbars()
  398. {
  399.     wxClientDC dc(this);
  400.     dc.GetTextExtent(_T("Line 17"), NULL, &m_hLine);
  401.  
  402.     // no horz scrolling
  403.     SetScrollbars(0, m_hLine, 0, m_nLines + 1, 0, 0, TRUE /* no refresh */);
  404. }
  405.  
  406. void MyScrolledWindowDumb::OnDraw(wxDC& dc)
  407. {
  408.     // this is useful to see which lines are redrawn
  409.     static size_t s_redrawCount = 0;
  410.     dc.SetTextForeground(s_redrawCount++ % 2 ? *wxRED : *wxBLUE);
  411.  
  412.     wxCoord y = 0;
  413.     for ( size_t line = 0; line < m_nLines; line++ )
  414.     {
  415.         wxCoord yPhys;
  416.         CalcScrolledPosition(0, y, NULL, &yPhys);
  417.  
  418.         dc.DrawText(wxString::Format(_T("Line %u (logical %d, physical %d)"),
  419.                                      line, y, yPhys), 0, y);
  420.         y += m_hLine;
  421.     }
  422. }
  423.  
  424. void MyScrolledWindowSmart::OnDraw(wxDC& dc)
  425. {
  426.     // this is useful to see which lines are redrawn
  427.     static size_t s_redrawCount = 0;
  428.     dc.SetTextForeground(s_redrawCount++ % 2 ? *wxRED : *wxBLUE);
  429.  
  430.     // update region is always in device coords, translate to logical ones
  431.     wxRect rectUpdate = GetUpdateRegion().GetBox();
  432.     CalcUnscrolledPosition(rectUpdate.x, rectUpdate.y,
  433.                            &rectUpdate.x, &rectUpdate.y);
  434.  
  435.     size_t lineFrom = rectUpdate.y / m_hLine,
  436.            lineTo = rectUpdate.GetBottom() / m_hLine;
  437.  
  438.     if ( lineTo > m_nLines - 1)
  439.         lineTo = m_nLines - 1;
  440.  
  441.     wxCoord y = lineFrom*m_hLine;
  442.     for ( size_t line = lineFrom; line <= lineTo; line++ )
  443.     {
  444.         wxCoord yPhys;
  445.         CalcScrolledPosition(0, y, NULL, &yPhys);
  446.  
  447.         dc.DrawText(wxString::Format(_T("Line %u (logical %d, physical %d)"),
  448.                                      line, y, yPhys), 0, y);
  449.         y += m_hLine;
  450.     }
  451. }
  452.