]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/scroll/scroll.cpp
disable VC6 warnings before warning(push), otherwise they're reenabled by warning...
[wxWidgets.git] / samples / scroll / scroll.cpp
index 6cc25e7a4bb13e41007d77897ee58bfbc57e60e4..874783a1bbb4f179e4fbf1b5822686bcbe1703c8 100644 (file)
 
 #include "wx/sizer.h"
 #include "wx/log.h"
 
 #include "wx/sizer.h"
 #include "wx/log.h"
+#include "wx/tglbtn.h"
+
+#ifndef __WXMSW__
+    #include "../sample.xpm"
+#endif
 
 // ----------------------------------------------------------------------------
 // a trivial example
 
 // ----------------------------------------------------------------------------
 // a trivial example
@@ -449,19 +454,62 @@ public:
     MyScrolledWindowBase(wxWindow *parent)
         : wxScrolledWindow(parent, wxID_ANY,
                            wxDefaultPosition, wxDefaultSize,
     MyScrolledWindowBase(wxWindow *parent)
         : wxScrolledWindow(parent, wxID_ANY,
                            wxDefaultPosition, wxDefaultSize,
-                           wxBORDER_SUNKEN),
-          m_nLines( 100 )
+                           wxBORDER_SUNKEN)
     {
     {
+        m_nLines = 50;
+        m_winSync = NULL;
+        m_inDoSync = false;
+
         wxClientDC dc(this);
         dc.GetTextExtent("Line 17", NULL, &m_hLine);
     }
 
         wxClientDC dc(this);
         dc.GetTextExtent("Line 17", NULL, &m_hLine);
     }
 
+    // this scrolled window can be synchronized with another one: if this
+    // function is called with a non-NULL pointer, the given window will be
+    // scrolled to the same position as this one
+    void SyncWith(MyScrolledWindowBase *win)
+    {
+        m_winSync = win;
+
+        DoSyncIfNecessary();
+    }
+
+    virtual void ScrollWindow(int dx, int dy, const wxRect *rect = NULL)
+    {
+        wxScrolledWindow::ScrollWindow(dx, dy, rect);
+
+        DoSyncIfNecessary();
+    }
+
 protected:
     // the height of one line on screen
     int m_hLine;
 
     // the number of lines we draw
     size_t m_nLines;
 protected:
     // the height of one line on screen
     int m_hLine;
 
     // the number of lines we draw
     size_t m_nLines;
+
+private:
+    bool WasScrolledFirst() const { return m_inDoSync; }
+
+    void DoSyncIfNecessary()
+    {
+        if ( m_winSync && !m_winSync->WasScrolledFirst() )
+        {
+            m_inDoSync = true;
+
+            m_winSync->Scroll(GetViewStart());
+
+            m_inDoSync = false;
+        }
+    }
+
+    // the window to synchronize with this one or NULL
+    MyScrolledWindowBase *m_winSync;
+
+    // the flag preventing infinite recursion which would otherwise happen if
+    // one window synchronized the other one which in turn synchronized this
+    // one and so on
+    bool m_inDoSync;
 };
 
 // this class does "stupid" redrawing - it redraws everything each time
 };
 
 // this class does "stupid" redrawing - it redraws everything each time
@@ -576,6 +624,12 @@ private:
     void OnTestSub(wxCommandEvent& WXUNUSED(event)) { new MySubFrame(this); }
     void OnTestAuto(wxCommandEvent& WXUNUSED(event)) { new MyAutoFrame(this); }
 
     void OnTestSub(wxCommandEvent& WXUNUSED(event)) { new MySubFrame(this); }
     void OnTestAuto(wxCommandEvent& WXUNUSED(event)) { new MyAutoFrame(this); }
 
+    void OnToggleSync(wxCommandEvent& event);
+    void OnScrollbarVisibility(wxCommandEvent& event);
+
+    MyScrolledWindowBase *m_win1,
+                         *m_win2;
+
     DECLARE_EVENT_TABLE()
 };
 
     DECLARE_EVENT_TABLE()
 };
 
@@ -719,9 +773,7 @@ void MyCanvas::OnScrollWin( wxCommandEvent &WXUNUSED(event) )
 {
     wxLogMessage("Scrolling 2 units up.\n"
                  "The white square and the controls should move equally!");
 {
     wxLogMessage("Scrolling 2 units up.\n"
                  "The white square and the controls should move equally!");
-    int x,y;
-    GetViewStart( &x, &y );
-    Scroll( wxDefaultCoord, y+2 );
+    Scroll( wxDefaultCoord, GetViewStart().y+2 );
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -786,6 +838,9 @@ const wxWindowID Scroll_Test_Sizers = wxWindow::NewControlId();
 const wxWindowID Scroll_Test_Sub    = wxWindow::NewControlId();
 const wxWindowID Scroll_Test_Auto   = wxWindow::NewControlId();
 
 const wxWindowID Scroll_Test_Sub    = wxWindow::NewControlId();
 const wxWindowID Scroll_Test_Auto   = wxWindow::NewControlId();
 
+const wxWindowID Scroll_TglBtn_Sync = wxWindow::NewControlId();
+const wxWindowID Scroll_Radio_ShowScrollbar = wxWindow::NewControlId();
+
 BEGIN_EVENT_TABLE(MyFrame,wxFrame)
     EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
     EVT_MENU(wxID_EXIT,  MyFrame::OnQuit)
 BEGIN_EVENT_TABLE(MyFrame,wxFrame)
     EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
     EVT_MENU(wxID_EXIT,  MyFrame::OnQuit)
@@ -795,11 +850,16 @@ BEGIN_EVENT_TABLE(MyFrame,wxFrame)
     EVT_MENU(Scroll_Test_Sizers, MyFrame::OnTestSizer)
     EVT_MENU(Scroll_Test_Sub, MyFrame::OnTestSub)
     EVT_MENU(Scroll_Test_Auto, MyFrame::OnTestAuto)
     EVT_MENU(Scroll_Test_Sizers, MyFrame::OnTestSizer)
     EVT_MENU(Scroll_Test_Sub, MyFrame::OnTestSub)
     EVT_MENU(Scroll_Test_Auto, MyFrame::OnTestAuto)
+
+    EVT_TOGGLEBUTTON(Scroll_TglBtn_Sync, MyFrame::OnToggleSync)
+    EVT_RADIOBOX(Scroll_Radio_ShowScrollbar, MyFrame::OnScrollbarVisibility)
 END_EVENT_TABLE()
 
 MyFrame::MyFrame()
        : wxFrame(NULL, wxID_ANY, "wxWidgets scroll sample")
 {
 END_EVENT_TABLE()
 
 MyFrame::MyFrame()
        : wxFrame(NULL, wxID_ANY, "wxWidgets scroll sample")
 {
+    SetIcon(wxICON(sample));
+
     wxMenu *menuFile = new wxMenu;
     menuFile->Append(wxID_ABOUT, "&About..");
     menuFile->AppendSeparator();
     wxMenu *menuFile = new wxMenu;
     menuFile->Append(wxID_ABOUT, "&About..");
     menuFile->AppendSeparator();
@@ -825,10 +885,12 @@ MyFrame::MyFrame()
     SetMenuBar( mbar );
 
 
     SetMenuBar( mbar );
 
 
+    wxPanel *panel = new wxPanel(this);
+
     const wxSizerFlags flagsExpand(wxSizerFlags(1).Expand());
 
     wxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
     const wxSizerFlags flagsExpand(wxSizerFlags(1).Expand());
 
     wxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
-    topsizer->Add(new wxStaticText(this, wxID_ANY,
+    topsizer->Add(new wxStaticText(panel, wxID_ANY,
         "The windows below should behave in the same way, even though\n"
         "they're implemented quite differently, see the code for details.\n"
         "\n"
         "The windows below should behave in the same way, even though\n"
         "they're implemented quite differently, see the code for details.\n"
         "\n"
@@ -837,17 +899,63 @@ MyFrame::MyFrame()
         "don't be surprised by this."),
         wxSizerFlags().Centre().Border());
 
         "don't be surprised by this."),
         wxSizerFlags().Centre().Border());
 
-    wxSizer *sizerBtm = new wxBoxSizer(wxHORIZONTAL);
-    sizerBtm->Add(new MyScrolledWindowDumb(this), flagsExpand);
-    sizerBtm->Add(new MyScrolledWindowSmart(this), flagsExpand);
-    topsizer->Add(sizerBtm, flagsExpand);
+    m_win1 = new MyScrolledWindowDumb(panel);
+    m_win2 = new MyScrolledWindowSmart(panel);
+
+    wxSizer *sizerScrollWin = new wxBoxSizer(wxHORIZONTAL);
+    sizerScrollWin->Add(m_win1, flagsExpand);
+    sizerScrollWin->Add(m_win2, flagsExpand);
+    topsizer->Add(sizerScrollWin, flagsExpand);
+
+    const wxSizerFlags
+        flagsHBorder(wxSizerFlags().Centre().Border(wxLEFT | wxRIGHT));
+
+    wxSizer *sizerBtns = new wxBoxSizer(wxHORIZONTAL);
+
+    // the radio buttons are in the same order as wxSHOW_SB_XXX values but
+    // offset by 1
+    const wxString visibilities[] = { "&never", "&default", "&always" };
+    wxRadioBox *radio = new wxRadioBox(panel, Scroll_Radio_ShowScrollbar,
+                                       "Left &scrollbar visibility: ",
+                                       wxDefaultPosition, wxDefaultSize,
+                                       WXSIZEOF(visibilities), visibilities);
+    radio->SetSelection(wxSHOW_SB_DEFAULT + 1);
+    sizerBtns->Add(radio, flagsHBorder);
+
+    sizerBtns->Add(new wxToggleButton(panel, Scroll_TglBtn_Sync, "S&ynchronize"),
+                   flagsHBorder);
+
+    topsizer->Add(sizerBtns, wxSizerFlags().Centre().Border());
 
 
-    SetSizer(topsizer);
+    panel->SetSizer(topsizer);
 
 
+    wxSize size = panel->GetBestSize();
+    SetSizeHints(size);
+    SetClientSize(2*size);
 
     Show();
 }
 
 
     Show();
 }
 
+void MyFrame::OnToggleSync(wxCommandEvent& event)
+{
+    if ( event.IsChecked() )
+    {
+        m_win1->SyncWith(m_win2);
+        m_win2->SyncWith(m_win1);
+    }
+    else
+    {
+        m_win1->SyncWith(NULL);
+        m_win2->SyncWith(NULL);
+    }
+}
+
+void MyFrame::OnScrollbarVisibility(wxCommandEvent& event)
+{
+    m_win1->ShowScrollbars(wxSHOW_SB_NEVER,
+                           wxScrollbarVisibility(event.GetSelection() - 1));
+}
+
 void MyFrame::OnQuit(wxCommandEvent &WXUNUSED(event))
 {
     Close(true);
 void MyFrame::OnQuit(wxCommandEvent &WXUNUSED(event))
 {
     Close(true);
@@ -982,20 +1090,14 @@ MyAutoScrollingWindow::DeviceCoordsToGraphicalChars(wxPoint pos) const
 {
     pos.x /= m_fontW;
     pos.y /= m_fontH;
 {
     pos.x /= m_fontW;
     pos.y /= m_fontH;
-    int vX, vY;
-    GetViewStart(&vX, &vY);
-    pos.x += vX;
-    pos.y += vY;
+    pos += GetViewStart();
     return pos;
 }
 
 wxPoint
 MyAutoScrollingWindow::GraphicalCharToDeviceCoords(wxPoint pos) const
 {
     return pos;
 }
 
 wxPoint
 MyAutoScrollingWindow::GraphicalCharToDeviceCoords(wxPoint pos) const
 {
-    int vX, vY;
-    GetViewStart(&vX, &vY);
-    pos.x -= vX;
-    pos.y -= vY;
+    pos -= GetViewStart();
     pos.x *= m_fontW;
     pos.y *= m_fontH;
     return pos;
     pos.x *= m_fontW;
     pos.y *= m_fontH;
     return pos;
@@ -1138,7 +1240,7 @@ void MyAutoScrollingWindow::OnDraw(wxDC& dc)
     dc.SetPen(*wxTRANSPARENT_PEN);
     const wxString str = sm_testData;
     size_t strLength = str.length();
     dc.SetPen(*wxTRANSPARENT_PEN);
     const wxString str = sm_testData;
     size_t strLength = str.length();
-    wxString::const_iterator str_i;
+    wxString::const_iterator str_i = str.begin();
 
     // draw the characters
     // 1. for each update region
 
     // draw the characters
     // 1. for each update region
@@ -1212,7 +1314,7 @@ void MyAutoScrollingWindow::OnMouseMove(wxMouseEvent& event)
         // set the new cursor position
         m_cursor = DeviceCoordsToGraphicalChars(event.GetPosition());
         // draw/erase selection
         // set the new cursor position
         m_cursor = DeviceCoordsToGraphicalChars(event.GetPosition());
         // draw/erase selection
-        MyRefresh();
+        // MyRefresh();
         // capture mouse to activate auto-scrolling
         if (!HasCapture()) {
             CaptureMouse();
         // capture mouse to activate auto-scrolling
         if (!HasCapture()) {
             CaptureMouse();