/////////////////////////////////////////////////////////////////////////////
// Name: scroll.cpp
-// Purpose: wxScrolledWindow sample
+// Purpose: wxScrolled sample
// Author: Robert Roebling
// RCS-ID: $Id$
// Copyright: (C) 1998 Robert Roebling, 2002 Ron Lee, 2003 Matt Gregory
// (C) 2008 Vadim Zeitlin
-// Licence: wxWindows license
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#include "wx/sizer.h"
#include "wx/log.h"
+#include "wx/tglbtn.h"
+
+#ifndef wxHAS_IMAGES_IN_RESOURCES
+ #include "../sample.xpm"
+#endif
// ----------------------------------------------------------------------------
// a trivial example
// ----------------------------------------------------------------------------
// MySimpleCanvas: a scrolled window which draws a simple rectangle
-class MySimpleCanvas : public wxScrolledWindow
+class MySimpleCanvas : public wxScrolled<wxWindow>
{
public:
enum
};
MySimpleCanvas(wxWindow *parent)
- : wxScrolledWindow(parent, wxID_ANY)
+ : wxScrolled<wxWindow>(parent, wxID_ANY)
{
SetScrollRate( 10, 10 );
SetVirtualSize( WIDTH, HEIGHT );
// ----------------------------------------------------------------------
// MyCanvas
-class MyCanvas : public wxScrolledWindow
+class MyCanvas : public wxScrolled<wxPanel>
{
public:
MyCanvas(wxWindow *parent);
};
// ----------------------------------------------------------------------------
-// example using sizers with wxScrolledWindow
+// example using sizers with wxScrolled
// ----------------------------------------------------------------------------
const wxSize SMALL_BUTTON( 100, 50 );
const wxSize LARGE_BUTTON( 300, 200 );
-class MySizerScrolledWindow : public wxScrolledWindow
+class MySizerScrolledWindow : public wxScrolled<wxWindow>
{
public:
MySizerScrolledWindow(wxWindow *parent);
class MySubColLabels : public wxWindow
{
public:
- MySubColLabels(wxScrolledWindow *parent)
+ MySubColLabels(wxScrolled<wxWindow> *parent)
: wxWindow(parent, wxID_ANY)
{
m_owner = parent;
dc.DrawText("Column 3", 205, 5);
}
- wxScrolledWindow *m_owner;
+ wxScrolled<wxWindow> *m_owner;
};
class MySubRowLabels : public wxWindow
{
public:
- MySubRowLabels(wxScrolledWindow *parent)
+ MySubRowLabels(wxScrolled<wxWindow> *parent)
: wxWindow(parent, wxID_ANY)
{
m_owner = parent;
dc.DrawText("Row 6", 5, 130);
}
- wxScrolledWindow *m_owner;
+ wxScrolled<wxWindow> *m_owner;
};
class MySubCanvas : public wxPanel
{
public:
- MySubCanvas(wxScrolledWindow *parent, wxWindow *cols, wxWindow *rows)
+ MySubCanvas(wxScrolled<wxWindow> *parent, wxWindow *cols, wxWindow *rows)
: wxPanel(parent, wxID_ANY)
{
m_owner = parent;
}
}
- wxScrolledWindow *m_owner;
+ wxScrolled<wxWindow> *m_owner;
wxWindow *m_colLabels,
*m_rowLabels;
};
-class MySubScrolledWindow : public wxScrolledWindow
+class MySubScrolledWindow : public wxScrolled<wxWindow>
{
public:
enum
};
MySubScrolledWindow(wxWindow *parent)
- : wxScrolledWindow(parent, wxID_ANY)
+ : wxScrolled<wxWindow>(parent, wxID_ANY)
{
// create the children
MySubColLabels *cols = new MySubColLabels(this);
};
// ----------------------------------------------------------------------------
-// more simple examples of wxScrolledWindow usage
+// more simple examples of wxScrolled usage
// ----------------------------------------------------------------------------
// base class for both of them
-class MyScrolledWindowBase : public wxScrolledWindow
+class MyScrolledWindowBase : public wxScrolled<wxWindow>
{
public:
MyScrolledWindowBase(wxWindow *parent)
- : wxScrolledWindow(parent, wxID_ANY,
- wxDefaultPosition, wxDefaultSize,
- wxBORDER_SUNKEN),
- m_nLines( 100 )
+ : wxScrolled<wxWindow>(parent, wxID_ANY,
+ wxDefaultPosition, wxDefaultSize,
+ wxBORDER_SUNKEN)
{
+ m_nLines = 50;
+ m_winSync = NULL;
+ m_inDoSync = false;
+
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)
+ {
+ wxScrolled<wxWindow>::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;
+
+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
// functionality
// ----------------------------------------------------------------------------
-class MyAutoScrollingWindow : public wxScrolledWindow
+class MyAutoScrollingWindow : public wxScrolled<wxWindow>
{
public:
MyAutoScrollingWindow( wxWindow* parent );
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()
};
// MyCanvas
// ----------------------------------------------------------------------------
-const wxWindowID ID_ADDBUTTON = wxWindow::NewControlId();
-const wxWindowID ID_DELBUTTON = wxWindow::NewControlId();
-const wxWindowID ID_MOVEBUTTON = wxWindow::NewControlId();
-const wxWindowID ID_SCROLLWIN = wxWindow::NewControlId();
-const wxWindowID ID_QUERYPOS = wxWindow::NewControlId();
+const wxWindowIDRef ID_ADDBUTTON = wxWindow::NewControlId();
+const wxWindowIDRef ID_DELBUTTON = wxWindow::NewControlId();
+const wxWindowIDRef ID_MOVEBUTTON = wxWindow::NewControlId();
+const wxWindowIDRef ID_SCROLLWIN = wxWindow::NewControlId();
+const wxWindowIDRef ID_QUERYPOS = wxWindow::NewControlId();
-const wxWindowID ID_NEWBUTTON = wxWindow::NewControlId();
+const wxWindowIDRef ID_NEWBUTTON = wxWindow::NewControlId();
-BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
+BEGIN_EVENT_TABLE(MyCanvas, wxScrolled<wxPanel>)
EVT_PAINT( MyCanvas::OnPaint)
EVT_RIGHT_DOWN( MyCanvas::OnMouseRightDown)
EVT_MOUSEWHEEL( MyCanvas::OnMouseWheel)
END_EVENT_TABLE()
MyCanvas::MyCanvas(wxWindow *parent)
- : wxScrolledWindow(parent, wxID_ANY,
- wxDefaultPosition, wxDefaultSize,
- wxSUNKEN_BORDER | wxTAB_TRAVERSAL)
+ : wxScrolled<wxPanel>(parent, wxID_ANY,
+ wxDefaultPosition, wxDefaultSize,
+ wxSUNKEN_BORDER | wxTAB_TRAVERSAL)
{
// you can use either a single SetScrollbars() call or these 2 functions,
// usually using them is better because you normally won't need to change
{
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 );
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
MySizerScrolledWindow::MySizerScrolledWindow(wxWindow *parent)
- : wxScrolledWindow(parent)
+ : wxScrolled<wxWindow>(parent)
{
SetBackgroundColour( "GREEN" );
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)
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")
{
+ SetIcon(wxICON(sample));
+
wxMenu *menuFile = new wxMenu;
menuFile->Append(wxID_ABOUT, "&About..");
menuFile->AppendSeparator();
SetMenuBar( mbar );
+ wxPanel *panel = new wxPanel(this);
+
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"
"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();
}
+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::OnAbout( wxCommandEvent &WXUNUSED(event) )
{
- (void)wxMessageBox( "wxScrolledWindow sample\n"
+ (void)wxMessageBox( "Scrolled window sample\n"
"\n"
"Robert Roebling (c) 1998\n"
"Vadim Zeitlin (c) 2008\n"
// MyAutoScrollingWindow
// ----------------------------------------------------------------------------
-BEGIN_EVENT_TABLE(MyAutoScrollingWindow, wxScrolledWindow)
+BEGIN_EVENT_TABLE(MyAutoScrollingWindow, wxScrolled<wxWindow>)
EVT_LEFT_DOWN(MyAutoScrollingWindow::OnMouseLeftDown)
EVT_LEFT_UP(MyAutoScrollingWindow::OnMouseLeftUp)
EVT_MOTION(MyAutoScrollingWindow::OnMouseMove)
END_EVENT_TABLE()
MyAutoScrollingWindow::MyAutoScrollingWindow(wxWindow* parent)
- : wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
- wxVSCROLL | wxHSCROLL | wxSUNKEN_BORDER),
+ : wxScrolled<wxWindow>(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
+ wxVSCROLL | wxHSCROLL | wxSUNKEN_BORDER),
m_selStart(-1, -1),
m_cursor(-1, -1),
m_font(9, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL)
{
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
{
- int vX, vY;
- GetViewStart(&vX, &vY);
- pos.x -= vX;
- pos.y -= vY;
+ pos -= GetViewStart();
pos.x *= m_fontW;
pos.y *= m_fontH;
return pos;
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