1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/vscroll.cpp
3 // Purpose: wxVScrolledWindow implementation
4 // Author: Vadim Zeitlin
5 // Modified by: Brad Anderson
8 // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
27 #include "wx/vscroll.h"
31 // ----------------------------------------------------------------------------
33 // ----------------------------------------------------------------------------
35 BEGIN_EVENT_TABLE(wxVScrolledWindow
, wxPanel
)
36 EVT_SIZE(wxVScrolledWindow::OnSize
)
37 EVT_SCROLLWIN(wxVScrolledWindow::OnScroll
)
39 EVT_MOUSEWHEEL(wxVScrolledWindow::OnMouseWheel
)
44 // ============================================================================
46 // ============================================================================
48 IMPLEMENT_ABSTRACT_CLASS(wxVScrolledWindow
, wxPanel
)
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 void wxVScrolledWindow::Init()
56 // we're initially empty
60 // this one should always be strictly positive
66 m_sumWheelRotation
= 0;
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
74 wxCoord
wxVScrolledWindow::EstimateTotalHeight() const
76 // estimate the total height: it is impossible to call
77 // OnGetLineHeight() for every line because there may be too many of
78 // them, so we just make a guess using some lines in the beginning,
79 // some in the end and some in the middle
80 static const size_t NUM_LINES_TO_SAMPLE
= 10;
83 if ( m_lineMax
< 3*NUM_LINES_TO_SAMPLE
)
85 // in this case calculating exactly is faster and more correct than
87 heightTotal
= GetLinesHeight(0, m_lineMax
);
89 else // too many lines to calculate exactly
91 // look at some lines in the beginning/middle/end
93 GetLinesHeight(0, NUM_LINES_TO_SAMPLE
) +
94 GetLinesHeight(m_lineMax
- NUM_LINES_TO_SAMPLE
, m_lineMax
) +
95 GetLinesHeight(m_lineMax
/2 - NUM_LINES_TO_SAMPLE
/2,
96 m_lineMax
/2 + NUM_LINES_TO_SAMPLE
/2);
98 // use the height of the lines we looked as the average
99 heightTotal
= (wxCoord
)
100 (((float)heightTotal
/ (3*NUM_LINES_TO_SAMPLE
)) * m_lineMax
);
106 wxCoord
wxVScrolledWindow::GetLinesHeight(size_t lineMin
, size_t lineMax
) const
108 if ( lineMin
== lineMax
)
110 else if ( lineMin
> lineMax
)
111 return -GetLinesHeight(lineMax
, lineMin
);
112 //else: lineMin < lineMax
114 // let the user code know that we're going to need all these lines
115 OnGetLinesHint(lineMin
, lineMax
);
117 // do sum up their heights
119 for ( size_t line
= lineMin
; line
< lineMax
; line
++ )
121 height
+= OnGetLineHeight(line
);
127 size_t wxVScrolledWindow::FindFirstFromBottom(size_t lineLast
, bool full
)
129 const wxCoord hWindow
= GetClientSize().y
;
131 // go upwards until we arrive at a line such that lineLast is not visible
132 // any more when it is shown
133 size_t lineFirst
= lineLast
;
137 h
+= OnGetLineHeight(lineFirst
);
141 // for this line to be fully visible we need to go one line
142 // down, but if it is enough for it to be only partly visible then
143 // this line will do as well
161 void wxVScrolledWindow::UpdateScrollbar()
163 // see how many lines can we fit on screen
164 const wxCoord hWindow
= GetClientSize().y
;
168 for ( line
= m_lineFirst
; line
< m_lineMax
; line
++ )
173 h
+= OnGetLineHeight(line
);
176 m_nVisible
= line
- m_lineFirst
;
178 int pageSize
= m_nVisible
;
181 // last line is only partially visible, we still need the scrollbar and
182 // so we have to "fix" pageSize because if it is equal to m_lineMax the
183 // scrollbar is not shown at all under MSW
187 // set the scrollbar parameters to reflect this
188 SetScrollbar(wxVERTICAL
, m_lineFirst
, pageSize
, m_lineMax
);
191 // ----------------------------------------------------------------------------
193 // ----------------------------------------------------------------------------
195 void wxVScrolledWindow::SetLineCount(size_t count
)
197 // save the number of lines
200 // and our estimate for their total height
201 m_heightTotal
= EstimateTotalHeight();
203 // recalculate the scrollbars parameters
204 m_lineFirst
= 1; // make sure it is != 0
208 void wxVScrolledWindow::RefreshLine(size_t line
)
210 // is this line visible?
211 if ( !IsVisible(line
) )
213 // no, it is useless to do anything
217 // calculate the rect occupied by this line on screen
219 rect
.width
= GetClientSize().x
;
220 rect
.height
= OnGetLineHeight(line
);
221 for ( size_t n
= GetVisibleBegin(); n
< line
; n
++ )
223 rect
.y
+= OnGetLineHeight(n
);
230 void wxVScrolledWindow::RefreshLines(size_t from
, size_t to
)
232 wxASSERT_MSG( from
<= to
, _T("RefreshLines(): empty range") );
234 // clump the range to just the visible lines -- it is useless to refresh
236 if ( from
< GetVisibleBegin() )
237 from
= GetVisibleBegin();
239 if ( to
>= GetVisibleEnd() )
240 to
= GetVisibleEnd();
244 // calculate the rect occupied by these lines on screen
246 rect
.width
= GetClientSize().x
;
247 for ( size_t nBefore
= GetVisibleBegin(); nBefore
< from
; nBefore
++ )
249 rect
.y
+= OnGetLineHeight(nBefore
);
252 for ( size_t nBetween
= from
; nBetween
< to
; nBetween
++ )
254 rect
.height
+= OnGetLineHeight(nBetween
);
261 void wxVScrolledWindow::RefreshAll()
268 bool wxVScrolledWindow::Layout()
272 // adjust the sizer dimensions/position taking into account the
273 // virtual size and scrolled position of the window.
275 int y
, w
, h
; // x is always 0 so no variable needed
277 y
= -GetLinesHeight(0, GetFirstVisibleLine());
278 GetVirtualSize(&w
, &h
);
279 GetSizer()->SetDimension(0, y
, w
, h
);
283 // fall back to default for LayoutConstraints
284 return wxPanel::Layout();
287 int wxVScrolledWindow::HitTest(wxCoord
WXUNUSED(x
), wxCoord y
) const
289 const size_t lineMax
= GetVisibleEnd();
290 for ( size_t line
= GetVisibleBegin(); line
< lineMax
; line
++ )
292 y
-= OnGetLineHeight(line
);
300 // ----------------------------------------------------------------------------
302 // ----------------------------------------------------------------------------
304 bool wxVScrolledWindow::ScrollToLine(size_t line
)
308 // we're empty, code below doesn't make sense in this case
312 // determine the real first line to scroll to: we shouldn't scroll beyond
314 size_t lineFirstLast
= FindFirstFromBottom(m_lineMax
- 1, true);
315 if ( line
> lineFirstLast
)
316 line
= lineFirstLast
;
319 if ( line
== m_lineFirst
)
326 // remember the currently shown lines for the refresh code below
327 size_t lineFirstOld
= GetVisibleBegin();
332 // the size of scrollbar thumb could have changed
335 // finally, scroll the actual window
336 ScrollWindow(0, GetLinesHeight(GetVisibleBegin(), lineFirstOld
));
341 bool wxVScrolledWindow::ScrollLines(int lines
)
343 lines
+= m_lineFirst
;
347 return ScrollToLine(lines
);
350 bool wxVScrolledWindow::ScrollPages(int pages
)
352 bool didSomething
= false;
359 line
= GetVisibleEnd();
366 line
= FindFirstFromBottom(GetVisibleBegin());
370 didSomething
= ScrollToLine(line
);
376 // ----------------------------------------------------------------------------
378 // ----------------------------------------------------------------------------
380 void wxVScrolledWindow::OnSize(wxSizeEvent
& event
)
387 void wxVScrolledWindow::OnScroll(wxScrollWinEvent
& event
)
391 const wxEventType evtType
= event
.GetEventType();
393 if ( evtType
== wxEVT_SCROLLWIN_TOP
)
397 else if ( evtType
== wxEVT_SCROLLWIN_BOTTOM
)
399 lineFirstNew
= m_lineMax
;
401 else if ( evtType
== wxEVT_SCROLLWIN_LINEUP
)
403 lineFirstNew
= m_lineFirst
? m_lineFirst
- 1 : 0;
405 else if ( evtType
== wxEVT_SCROLLWIN_LINEDOWN
)
407 lineFirstNew
= m_lineFirst
+ 1;
409 else if ( evtType
== wxEVT_SCROLLWIN_PAGEUP
)
411 lineFirstNew
= FindFirstFromBottom(m_lineFirst
);
413 else if ( evtType
== wxEVT_SCROLLWIN_PAGEDOWN
)
415 lineFirstNew
= GetVisibleEnd();
419 else if ( evtType
== wxEVT_SCROLLWIN_THUMBRELEASE
)
421 lineFirstNew
= event
.GetPosition();
423 else if ( evtType
== wxEVT_SCROLLWIN_THUMBTRACK
)
425 lineFirstNew
= event
.GetPosition();
428 else // unknown scroll event?
430 wxFAIL_MSG( _T("unknown scroll event type?") );
434 ScrollToLine(lineFirstNew
);
443 void wxVScrolledWindow::OnMouseWheel(wxMouseEvent
& event
)
445 m_sumWheelRotation
+= event
.GetWheelRotation();
446 int delta
= event
.GetWheelDelta();
448 // how much to scroll this time
449 int units_to_scroll
= -(m_sumWheelRotation
/delta
);
450 if ( !units_to_scroll
)
453 m_sumWheelRotation
+= units_to_scroll
*delta
;
455 if ( !event
.IsPageScroll() )
456 ScrollLines( units_to_scroll
*event
.GetLinesPerAction() );
458 // scroll pages instead of lines
459 ScrollPages( units_to_scroll
);
467 // ----------------------------------------------------------------------------
468 // wxVarScrolled Window event tables
469 // ----------------------------------------------------------------------------
471 BEGIN_EVENT_TABLE(wxHVScrolledWindow
, wxPanel
)
472 EVT_SIZE(wxHVScrolledWindow::OnSize
)
473 EVT_SCROLLWIN(wxHVScrolledWindow::OnScroll
)
475 EVT_MOUSEWHEEL(wxHVScrolledWindow::OnMouseWheel
)
480 // ============================================================================
481 // wxVarScrolled implementation
482 // ============================================================================
484 IMPLEMENT_ABSTRACT_CLASS(wxHVScrolledWindow
, wxPanel
)
486 // ----------------------------------------------------------------------------
488 // ----------------------------------------------------------------------------
490 void wxHVScrolledWindow::Init()
492 // we're initially empty
498 // these should always be strictly positive
500 m_nColumnsVisible
= 1;
505 m_physicalScrolling
= true;
508 m_sumWheelRotation
= 0;
512 // ----------------------------------------------------------------------------
514 // ----------------------------------------------------------------------------
516 wxCoord
wxHVScrolledWindow::EstimateTotalHeight() const
518 // estimate the total height: it is impossible to call
519 // OnGetLineHeight() for every line because there may be too many of
520 // them, so we just make a guess using some lines in the beginning,
521 // some in the end and some in the middle
522 static const size_t NUM_LINES_TO_SAMPLE
= 10;
525 if ( m_rowsMax
< 3*NUM_LINES_TO_SAMPLE
)
527 // in this case calculating exactly is faster and more correct than
529 heightTotal
= GetRowsHeight(0, m_rowsMax
);
531 else // too many lines to calculate exactly
533 // look at some lines in the beginning/middle/end
535 GetRowsHeight(0, NUM_LINES_TO_SAMPLE
) +
536 GetRowsHeight(m_rowsMax
- NUM_LINES_TO_SAMPLE
,
538 GetRowsHeight(m_rowsMax
/2 - NUM_LINES_TO_SAMPLE
/2,
539 m_rowsMax
/2 + NUM_LINES_TO_SAMPLE
/2);
541 // use the height of the lines we looked as the average
542 heightTotal
= (wxCoord
)
543 (((float)heightTotal
/ (3*NUM_LINES_TO_SAMPLE
)) * m_rowsMax
);
549 wxCoord
wxHVScrolledWindow::EstimateTotalWidth() const
551 // estimate the total width: it is impossible to call
552 // OnGetLineWidth() for every line because there may be too many of
553 // them, so we just make a guess using some lines in the beginning,
554 // some in the end and some in the middle
555 static const size_t NUM_LINES_TO_SAMPLE
= 10;
558 if ( m_columnsMax
< 3*NUM_LINES_TO_SAMPLE
)
560 // in this case calculating exactly is faster and more correct than
562 widthTotal
= GetColumnsWidth(0, m_columnsMax
);
564 else // too many lines to calculate exactly
566 // look at some lines in the beginning/middle/end
568 GetColumnsWidth(0, NUM_LINES_TO_SAMPLE
) +
569 GetColumnsWidth(m_columnsMax
- NUM_LINES_TO_SAMPLE
,
571 GetColumnsWidth(m_columnsMax
/2 - NUM_LINES_TO_SAMPLE
/2,
572 m_columnsMax
/2 + NUM_LINES_TO_SAMPLE
/2);
574 // use the width of the lines we looked as the average
575 widthTotal
= (wxCoord
)
576 (((float)widthTotal
/ (3*NUM_LINES_TO_SAMPLE
)) * m_columnsMax
);
582 wxCoord
wxHVScrolledWindow::GetRowsHeight(size_t rowMin
, size_t rowMax
) const
584 if ( rowMin
== rowMax
)
586 else if ( rowMin
> rowMax
)
587 return -GetRowsHeight(rowMax
, rowMin
);
588 //else: lineMin < lineMax
590 // let the user code know that we're going to need all these lines
591 OnGetRowsHeightHint(rowMin
, rowMax
);
593 // do sum up their heights
595 for ( size_t row
= rowMin
; row
< rowMax
; row
++ )
597 height
+= OnGetRowHeight(row
);
603 wxCoord
wxHVScrolledWindow::GetColumnsWidth(size_t columnMin
, size_t columnMax
) const
605 if ( columnMin
== columnMax
)
607 else if ( columnMin
> columnMax
)
608 return -GetColumnsWidth(columnMax
, columnMin
);
609 //else: lineMin < lineMax
611 // let the user code know that we're going to need all these lines
612 OnGetColumnsWidthHint(columnMin
, columnMax
);
614 // do sum up their widths
616 for ( size_t column
= columnMin
; column
< columnMax
; column
++ )
618 width
+= OnGetColumnWidth(column
);
624 size_t wxHVScrolledWindow::FindFirstFromBottom(size_t rowLast
, bool full
)
626 const wxCoord hWindow
= GetClientSize().y
;
628 // go upwards until we arrive at a line such that lineLast is not visible
629 // any more when it is shown
630 size_t lineFirst
= rowLast
;
634 h
+= OnGetRowHeight(lineFirst
);
638 // for this line to be fully visible we need to go one line
639 // down, but if it is enough for it to be only partly visible then
640 // this line will do as well
658 size_t wxHVScrolledWindow::FindFirstFromRight(size_t columnLast
, bool full
)
660 const wxCoord wWindow
= GetClientSize().x
;
662 // go upwards until we arrive at a line such that lineLast is not visible
663 // any more when it is shown
664 size_t lineFirst
= columnLast
;
668 w
+= OnGetColumnWidth(lineFirst
);
672 // for this line to be fully visible we need to go one line
673 // down, but if it is enough for it to be only partly visible then
674 // this line will do as well
692 void wxHVScrolledWindow::UpdateScrollbars()
694 // see how many lines can we fit on screen (on both axes)
695 const wxCoord wWindow
= GetClientSize().x
;
696 const wxCoord hWindow
= GetClientSize().y
;
698 // first do the horizontal calculations
701 for ( column
= m_columnsFirst
; column
< m_columnsMax
; column
++ )
706 w
+= OnGetColumnWidth(column
);
709 m_nColumnsVisible
= column
- m_columnsFirst
;
711 int columnsPageSize
= m_nColumnsVisible
;
714 // last line is only partially visible, we still need the scrollbar and
715 // so we have to "fix" pageSize because if it is equal to
716 // m_horizLineMax the scrollbar is not shown at all under MSW
720 // set the scrollbar parameters to reflect this
721 SetScrollbar(wxHORIZONTAL
, m_columnsFirst
, columnsPageSize
, m_columnsMax
);
724 // now do the vertical calculations
727 for ( row
= m_rowsFirst
; row
< m_rowsMax
; row
++ )
732 h
+= OnGetRowHeight(row
);
735 m_nRowsVisible
= row
- m_rowsFirst
;
737 int rowsPageSize
= m_nRowsVisible
;
740 // last line is only partially visible, we still need the scrollbar and
741 // so we have to "fix" pageSize because if it is equal to m_vertLineMax
742 // the scrollbar is not shown at all under MSW
746 // set the scrollbar parameters to reflect this
747 SetScrollbar(wxVERTICAL
, m_rowsFirst
, rowsPageSize
, m_rowsMax
);
750 void wxHVScrolledWindow::PrepareDC(wxDC
& dc
)
752 if(m_physicalScrolling
)
754 dc
.SetDeviceOrigin(-GetColumnsWidth(0, GetVisibleColumnsBegin()),
755 -GetRowsHeight(0, GetVisibleRowsBegin()));
759 // ----------------------------------------------------------------------------
761 // ----------------------------------------------------------------------------
763 void wxHVScrolledWindow::SetRowColumnCounts(size_t rowCount
, size_t columnCount
)
765 // save the number of lines
766 m_rowsMax
= rowCount
;
767 m_columnsMax
= columnCount
;
769 // and our estimate for their total height and width
770 m_heightTotal
= EstimateTotalHeight();
771 m_widthTotal
= EstimateTotalWidth();
773 // recalculate the scrollbars parameters
774 if(m_rowsFirst
>= rowCount
)
775 m_rowsFirst
= (rowCount
> 0) ? rowCount
- 1 : 0;
777 if(m_columnsFirst
>= columnCount
)
778 m_columnsFirst
= (columnCount
> 0) ? columnCount
- 1 : 0;
781 // checks disabled due to size_t type of members
782 // but leave them here if anyone would want to do some debugging
786 if(m_columnsFirst
< 0)
790 ScrollToRowColumn(m_rowsFirst
, m_columnsFirst
);
793 void wxHVScrolledWindow::RefreshColumn(size_t column
)
795 // is this line visible?
796 if ( !IsColumnVisible(column
) )
798 // no, it is useless to do anything
802 // calculate the rect occupied by this line on screen
804 rect
.width
= OnGetColumnWidth(column
);
805 rect
.height
= GetClientSize().y
;
806 for ( size_t n
= GetVisibleColumnsBegin(); n
< column
; n
++ )
808 rect
.y
+= OnGetColumnWidth(n
);
815 void wxHVScrolledWindow::RefreshRow(size_t row
)
817 // is this line visible?
818 if ( !IsRowVisible(row
) )
820 // no, it is useless to do anything
824 // calculate the rect occupied by this line on screen
826 rect
.width
= GetClientSize().x
;
827 rect
.height
= OnGetRowHeight(row
);
828 for ( size_t n
= GetVisibleRowsBegin(); n
< row
; n
++ )
830 rect
.y
+= OnGetRowHeight(n
);
837 void wxHVScrolledWindow::RefreshRowColumn(size_t row
, size_t column
)
839 // is this line visible?
840 if ( !IsRowVisible(row
) || !IsColumnVisible(column
) )
842 // no, it is useless to do anything
846 // calculate the rect occupied by this cell on screen
848 rect
.height
= OnGetRowHeight(row
);
849 rect
.width
= OnGetColumnWidth(column
);
853 for ( n
= GetVisibleRowsBegin(); n
< row
; n
++ )
855 rect
.y
+= OnGetRowHeight(n
);
858 for ( n
= GetVisibleColumnsBegin(); n
< column
; n
++ )
860 rect
.x
+= OnGetColumnWidth(n
);
867 void wxHVScrolledWindow::RefreshRows(size_t from
, size_t to
)
869 wxASSERT_MSG( from
<= to
, _T("RefreshRows(): empty range") );
871 // clump the range to just the visible lines -- it is useless to refresh
873 if ( from
< GetVisibleRowsBegin() )
874 from
= GetVisibleRowsBegin();
876 if ( to
> GetVisibleRowsEnd() )
877 to
= GetVisibleRowsEnd();
879 // calculate the rect occupied by these lines on screen
881 rect
.width
= GetClientSize().x
;
882 for ( size_t nBefore
= GetVisibleRowsBegin();
886 rect
.y
+= OnGetRowHeight(nBefore
);
889 for ( size_t nBetween
= from
; nBetween
<= to
; nBetween
++ )
891 rect
.height
+= OnGetRowHeight(nBetween
);
898 void wxHVScrolledWindow::RefreshColumns(size_t from
, size_t to
)
900 wxASSERT_MSG( from
<= to
, _T("RefreshColumns(): empty range") );
902 // clump the range to just the visible lines -- it is useless to refresh
904 if ( from
< GetVisibleColumnsBegin() )
905 from
= GetVisibleColumnsBegin();
907 if ( to
> GetVisibleColumnsEnd() )
908 to
= GetVisibleColumnsEnd();
910 // calculate the rect occupied by these lines on screen
912 rect
.height
= GetClientSize().y
;
913 for ( size_t nBefore
= GetVisibleColumnsBegin();
917 rect
.x
+= OnGetColumnWidth(nBefore
);
920 for ( size_t nBetween
= from
; nBetween
<= to
; nBetween
++ )
922 rect
.width
+= OnGetColumnWidth(nBetween
);
929 void wxHVScrolledWindow::RefreshRowsColumns(size_t fromRow
, size_t toRow
,
930 size_t fromColumn
, size_t toColumn
)
932 wxASSERT_MSG( fromRow
<= toRow
|| fromColumn
<= toColumn
,
933 _T("RefreshRowsColumns(): empty range") );
935 // clump the range to just the visible lines -- it is useless to refresh
937 if ( fromRow
< GetVisibleRowsBegin() )
938 fromRow
= GetVisibleRowsBegin();
940 if ( toRow
> GetVisibleRowsEnd() )
941 toRow
= GetVisibleRowsEnd();
943 if ( fromColumn
< GetVisibleColumnsBegin() )
944 fromColumn
= GetVisibleColumnsBegin();
946 if ( toColumn
> GetVisibleColumnsEnd() )
947 toColumn
= GetVisibleColumnsEnd();
949 // calculate the rect occupied by these lines on screen
951 size_t nBefore
, nBetween
;
953 for ( nBefore
= GetVisibleRowsBegin();
957 rect
.y
+= OnGetRowHeight(nBefore
);
960 for ( nBetween
= fromRow
; nBetween
<= toRow
; nBetween
++ )
962 rect
.height
+= OnGetRowHeight(nBetween
);
965 for ( nBefore
= GetVisibleColumnsBegin();
966 nBefore
< fromColumn
;
969 rect
.x
+= OnGetColumnWidth(nBefore
);
972 for ( nBetween
= fromColumn
; nBetween
<= toColumn
; nBetween
++ )
974 rect
.width
+= OnGetColumnWidth(nBetween
);
981 void wxHVScrolledWindow::RefreshAll()
988 bool wxHVScrolledWindow::Layout()
990 if(GetSizer() && m_physicalScrolling
)
992 // adjust the sizer dimensions/position taking into account the
993 // virtual size and scrolled position of the window.
997 y
= -GetRowsHeight(0, GetVisibleRowsBegin());
998 x
= -GetColumnsWidth(0, GetVisibleColumnsBegin());
999 GetVirtualSize(&w
, &h
);
1000 GetSizer()->SetDimension(x
, y
, w
, h
);
1004 // fall back to default for LayoutConstraints
1005 return wxPanel::Layout();
1008 wxPoint
wxHVScrolledWindow::HitTest(wxCoord x
, wxCoord y
) const
1010 const size_t rowMax
= GetVisibleRowsEnd();
1011 const size_t columnMax
= GetVisibleColumnsEnd();
1013 wxPoint
hit(wxNOT_FOUND
, wxNOT_FOUND
);
1014 for ( size_t row
= GetVisibleRowsBegin();
1018 y
-= OnGetRowHeight(row
);
1023 for ( size_t column
= GetVisibleColumnsBegin();
1024 column
<= columnMax
;
1027 x
-= OnGetColumnWidth(column
);
1035 // ----------------------------------------------------------------------------
1037 // ----------------------------------------------------------------------------
1039 bool wxHVScrolledWindow::ScrollToRowColumn(size_t row
, size_t column
)
1041 if ( !m_rowsMax
&& !m_columnsMax
)
1043 // we're empty, code below doesn't make sense in this case
1047 bool scrolled
= false;
1048 scrolled
|= ScrollToRow(row
);
1049 scrolled
|= ScrollToColumn(column
);
1054 bool wxHVScrolledWindow::ScrollToRow(size_t row
)
1058 // we're empty, code below doesn't make sense in this case
1062 // determine the real first line to scroll to: we shouldn't scroll beyond
1064 size_t lineFirstLast
= FindFirstFromBottom(m_rowsMax
- 1, true);
1065 if ( row
> lineFirstLast
)
1066 row
= lineFirstLast
;
1069 if ( row
== m_rowsFirst
)
1076 // remember the currently shown lines for the refresh code below
1077 size_t lineFirstOld
= GetVisibleRowsBegin();
1082 // the size of scrollbar thumb could have changed
1086 // finally, scroll the actual window contents vertically
1087 if(m_physicalScrolling
)
1088 ScrollWindow(0, GetRowsHeight(GetVisibleRowsBegin(), lineFirstOld
));
1093 bool wxHVScrolledWindow::ScrollToColumn(size_t column
)
1095 if ( !m_columnsMax
)
1097 // we're empty, code below doesn't make sense in this case
1101 // determine the real first line to scroll to: we shouldn't scroll beyond
1103 size_t lineFirstLast
= FindFirstFromRight(m_columnsMax
- 1, true);
1104 if ( column
> lineFirstLast
)
1105 column
= lineFirstLast
;
1108 if ( column
== m_columnsFirst
)
1115 // remember the currently shown lines for the refresh code below
1116 size_t lineFirstOld
= GetVisibleColumnsBegin();
1118 m_columnsFirst
= column
;
1121 // the size of scrollbar thumb could have changed
1124 // finally, scroll the actual window contents horizontally
1125 if(m_physicalScrolling
)
1126 ScrollWindow(GetColumnsWidth(GetVisibleColumnsBegin(), lineFirstOld
), 0);
1131 bool wxHVScrolledWindow::ScrollRows(int rows
)
1133 rows
+= m_rowsFirst
;
1137 return ScrollToRow(rows
);
1140 bool wxHVScrolledWindow::ScrollColumns(int columns
)
1142 columns
+= m_columnsFirst
;
1146 return ScrollToColumn(columns
);
1149 bool wxHVScrolledWindow::ScrollRowsColumns(int rows
, int columns
)
1151 rows
+= m_rowsFirst
;
1155 columns
+= m_columnsFirst
;
1159 return ScrollToRowColumn(rows
, columns
);
1162 bool wxHVScrolledWindow::ScrollRowPages(int pages
)
1164 bool didSomething
= false;
1171 line
= GetVisibleRowsEnd();
1178 line
= FindFirstFromBottom(GetVisibleRowsEnd());
1182 didSomething
= ScrollToRow(line
);
1185 return didSomething
;
1188 bool wxHVScrolledWindow::ScrollColumnPages(int pages
)
1190 bool didSomething
= false;
1197 line
= GetVisibleColumnsEnd();
1204 line
= FindFirstFromRight(GetVisibleColumnsEnd());
1208 didSomething
= ScrollToColumn(line
);
1211 return didSomething
;
1214 bool wxHVScrolledWindow::ScrollPages(int rowPages
, int columnPages
)
1216 bool didSomething
= false;
1223 line
= GetVisibleRowsEnd();
1228 else // rowPages < 0
1230 line
= FindFirstFromBottom(GetVisibleRowsBegin());
1234 didSomething
= ScrollToRow(line
);
1237 while ( columnPages
)
1240 if ( columnPages
> 0 )
1242 line
= GetVisibleColumnsEnd();
1247 else // columnPages < 0
1249 line
= FindFirstFromRight(GetVisibleColumnsBegin());
1253 didSomething
|= ScrollToColumn(line
);
1256 return didSomething
;
1259 // ----------------------------------------------------------------------------
1261 // ----------------------------------------------------------------------------
1263 void wxHVScrolledWindow::OnSize(wxSizeEvent
& event
)
1271 void wxHVScrolledWindow::OnScroll(wxScrollWinEvent
& event
)
1273 if(event
.GetOrientation() == wxHORIZONTAL
)
1275 size_t columnsFirstNew
;
1276 const wxEventType evtType
= event
.GetEventType();
1278 if ( evtType
== wxEVT_SCROLLWIN_TOP
)
1280 columnsFirstNew
= 0;
1282 else if ( evtType
== wxEVT_SCROLLWIN_BOTTOM
)
1284 columnsFirstNew
= m_columnsMax
;
1286 else if ( evtType
== wxEVT_SCROLLWIN_LINEUP
)
1288 columnsFirstNew
= m_columnsFirst
? m_columnsFirst
- 1 : 0;
1290 else if ( evtType
== wxEVT_SCROLLWIN_LINEDOWN
)
1292 columnsFirstNew
= m_columnsFirst
+ 1;
1294 else if ( evtType
== wxEVT_SCROLLWIN_PAGEUP
)
1296 columnsFirstNew
= FindFirstFromRight(m_columnsFirst
);
1298 else if ( evtType
== wxEVT_SCROLLWIN_PAGEDOWN
)
1300 columnsFirstNew
= GetVisibleColumnsEnd();
1301 if ( columnsFirstNew
)
1304 else if ( evtType
== wxEVT_SCROLLWIN_THUMBRELEASE
)
1306 columnsFirstNew
= event
.GetPosition();
1308 else if ( evtType
== wxEVT_SCROLLWIN_THUMBTRACK
)
1310 columnsFirstNew
= event
.GetPosition();
1313 else // unknown scroll event?
1315 wxFAIL_MSG( _T("unknown scroll event type?") );
1319 ScrollToColumn(columnsFirstNew
);
1321 else if(event
.GetOrientation() == wxVERTICAL
)
1323 size_t rowsFirstNew
;
1324 const wxEventType evtType
= event
.GetEventType();
1326 if ( evtType
== wxEVT_SCROLLWIN_TOP
)
1330 else if ( evtType
== wxEVT_SCROLLWIN_BOTTOM
)
1332 rowsFirstNew
= m_rowsMax
;
1334 else if ( evtType
== wxEVT_SCROLLWIN_LINEUP
)
1336 rowsFirstNew
= m_rowsFirst
? m_rowsFirst
- 1 : 0;
1338 else if ( evtType
== wxEVT_SCROLLWIN_LINEDOWN
)
1340 rowsFirstNew
= m_rowsFirst
+ 1;
1342 else if ( evtType
== wxEVT_SCROLLWIN_PAGEUP
)
1344 rowsFirstNew
= FindFirstFromBottom(m_rowsFirst
);
1346 else if ( evtType
== wxEVT_SCROLLWIN_PAGEDOWN
)
1348 rowsFirstNew
= GetVisibleRowsEnd();
1352 else if ( evtType
== wxEVT_SCROLLWIN_THUMBRELEASE
)
1354 rowsFirstNew
= event
.GetPosition();
1356 else if ( evtType
== wxEVT_SCROLLWIN_THUMBTRACK
)
1358 rowsFirstNew
= event
.GetPosition();
1361 else // unknown scroll event?
1363 wxFAIL_MSG( _T("unknown scroll event type?") );
1367 ScrollToRow(rowsFirstNew
);
1376 #if wxUSE_MOUSEWHEEL
1378 void wxHVScrolledWindow::OnMouseWheel(wxMouseEvent
& event
)
1380 m_sumWheelRotation
+= event
.GetWheelRotation();
1381 int delta
= event
.GetWheelDelta();
1383 // how much to scroll this time
1384 int units_to_scroll
= -(m_sumWheelRotation
/delta
);
1385 if ( !units_to_scroll
)
1388 m_sumWheelRotation
+= units_to_scroll
*delta
;
1390 if ( !event
.IsPageScroll() )
1391 ScrollRows( units_to_scroll
*event
.GetLinesPerAction() );
1393 // scroll pages instead of lines
1394 ScrollRowPages( units_to_scroll
);