| 1 | ///////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: include/wx/vscroll.h |
| 3 | // Purpose: Variable scrolled windows (wx[V/H/HV]ScrolledWindow) |
| 4 | // Author: Vadim Zeitlin |
| 5 | // Modified by: Brad Anderson, Bryan Petty |
| 6 | // Created: 30.05.03 |
| 7 | // RCS-ID: $Id$ |
| 8 | // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwidgets.org> |
| 9 | // Licence: wxWindows licence |
| 10 | ///////////////////////////////////////////////////////////////////////////// |
| 11 | |
| 12 | #ifndef _WX_VSCROLL_H_ |
| 13 | #define _WX_VSCROLL_H_ |
| 14 | |
| 15 | #include "wx/panel.h" |
| 16 | #include "wx/position.h" |
| 17 | |
| 18 | class WXDLLIMPEXP_FWD_CORE wxVarScrollHelperEvtHandler; |
| 19 | |
| 20 | |
| 21 | // Using the same techniques as the wxScrolledWindow class | |
| 22 | // hierarchy, the wx[V/H/HV]ScrolledWindow classes are slightly | |
| 23 | // more complex (compare with the diagram outlined in | |
| 24 | // scrolwin.h) for the purpose of reducing code duplication | |
| 25 | // through the use of mix-in classes. | |
| 26 | // | |
| 27 | // wxVarScrollHelperBase | |
| 28 | // / \ | |
| 29 | // / \ | |
| 30 | // V V | |
| 31 | // wxVarHScrollHelper wxVarVScrollHelper | |
| 32 | // | \ / | | |
| 33 | // | \ / | | |
| 34 | // | V V | | |
| 35 | // | wxVarHVScrollHelper | | |
| 36 | // | | | | |
| 37 | // | | V | |
| 38 | // | wxPanel | wxVarVScrollLegacyAdaptor | |
| 39 | // | / \ \ | | | |
| 40 | // | / \ `-----|----------. | | |
| 41 | // | / \ | \ | | |
| 42 | // | / \ | \ | | |
| 43 | // V V \ | V V | |
| 44 | // wxHScrolledWindow \ | wxVScrolledWindow | |
| 45 | // V V | |
| 46 | // wxHVScrolledWindow | |
| 47 | // | |
| 48 | // | |
| 49 | // Border added to suppress GCC multi-line comment warnings ->| |
| 50 | |
| 51 | |
| 52 | // =========================================================================== |
| 53 | // wxVarScrollHelperBase |
| 54 | // =========================================================================== |
| 55 | |
| 56 | // Provides all base common scroll calculations needed for either orientation, |
| 57 | // automatic scrollbar functionality, saved scroll positions, functionality |
| 58 | // for changing the target window to be scrolled, as well as defining all |
| 59 | // required virtual functions that need to be implemented for any orientation |
| 60 | // specific work. |
| 61 | |
| 62 | class WXDLLIMPEXP_CORE wxVarScrollHelperBase |
| 63 | { |
| 64 | public: |
| 65 | // constructors and such |
| 66 | // --------------------- |
| 67 | |
| 68 | wxVarScrollHelperBase(wxWindow *winToScroll); |
| 69 | virtual ~wxVarScrollHelperBase(); |
| 70 | |
| 71 | // operations |
| 72 | // ---------- |
| 73 | |
| 74 | // with physical scrolling on, the device origin is changed properly when |
| 75 | // a wxPaintDC is prepared, children are actually moved and laid out |
| 76 | // properly, and the contents of the window (pixels) are actually moved |
| 77 | void EnablePhysicalScrolling(bool scrolling = true) |
| 78 | { m_physicalScrolling = scrolling; } |
| 79 | |
| 80 | // wxNOT_FOUND if none, i.e. if it is below the last item |
| 81 | int VirtualHitTest(wxCoord coord) const; |
| 82 | |
| 83 | // recalculate all our parameters and redisplay all units |
| 84 | virtual void RefreshAll(); |
| 85 | |
| 86 | // accessors |
| 87 | // --------- |
| 88 | |
| 89 | // get the first currently visible unit |
| 90 | size_t GetVisibleBegin() const { return m_unitFirst; } |
| 91 | |
| 92 | // get the last currently visible unit |
| 93 | size_t GetVisibleEnd() const |
| 94 | { return m_unitFirst + m_nUnitsVisible; } |
| 95 | |
| 96 | // is this unit currently visible? |
| 97 | bool IsVisible(size_t unit) const |
| 98 | { return unit >= m_unitFirst && unit < GetVisibleEnd(); } |
| 99 | |
| 100 | // translate between scrolled and unscrolled coordinates |
| 101 | int CalcScrolledPosition(int coord) const |
| 102 | { return DoCalcScrolledPosition(coord); } |
| 103 | int CalcUnscrolledPosition(int coord) const |
| 104 | { return DoCalcUnscrolledPosition(coord); } |
| 105 | |
| 106 | virtual int DoCalcScrolledPosition(int coord) const; |
| 107 | virtual int DoCalcUnscrolledPosition(int coord) const; |
| 108 | |
| 109 | // update the thumb size shown by the scrollbar |
| 110 | virtual void UpdateScrollbar(); |
| 111 | void RemoveScrollbar(); |
| 112 | |
| 113 | // Normally the wxScrolledWindow will scroll itself, but in some rare |
| 114 | // occasions you might want it to scroll [part of] another window (e.g. a |
| 115 | // child of it in order to scroll only a portion the area between the |
| 116 | // scrollbars (spreadsheet: only cell area will move). |
| 117 | virtual void SetTargetWindow(wxWindow *target); |
| 118 | virtual wxWindow *GetTargetWindow() const { return m_targetWindow; } |
| 119 | |
| 120 | // Override this function to draw the graphic (or just process EVT_PAINT) |
| 121 | //virtual void OnDraw(wxDC& WXUNUSED(dc)) { } |
| 122 | |
| 123 | // change the DC origin according to the scroll position. To properly |
| 124 | // forward calls to wxWindow::Layout use WX_FORWARD_TO_SCROLL_HELPER() |
| 125 | // derived class |
| 126 | virtual void DoPrepareDC(wxDC& dc); |
| 127 | |
| 128 | // the methods to be called from the window event handlers |
| 129 | void HandleOnScroll(wxScrollWinEvent& event); |
| 130 | void HandleOnSize(wxSizeEvent& event); |
| 131 | #if wxUSE_MOUSEWHEEL |
| 132 | void HandleOnMouseWheel(wxMouseEvent& event); |
| 133 | #endif // wxUSE_MOUSEWHEEL |
| 134 | |
| 135 | // these functions must be overidden in the derived class to return |
| 136 | // orientation specific data (e.g. the width for vertically scrolling |
| 137 | // derivatives in the case of GetOrientationTargetSize()) |
| 138 | virtual int GetOrientationTargetSize() const = 0; |
| 139 | virtual int GetNonOrientationTargetSize() const = 0; |
| 140 | virtual wxOrientation GetOrientation() const = 0; |
| 141 | |
| 142 | protected: |
| 143 | // all *Unit* functions are protected to be exposed by |
| 144 | // wxVarScrollHelperBase implementations (with appropriate names) |
| 145 | |
| 146 | // get the number of units this window contains (previously set by |
| 147 | // SetUnitCount()) |
| 148 | size_t GetUnitCount() const { return m_unitMax; } |
| 149 | |
| 150 | // set the number of units the helper contains: the derived class must |
| 151 | // provide the sizes for all units with indices up to the one given here |
| 152 | // in its OnGetUnitSize() |
| 153 | void SetUnitCount(size_t count); |
| 154 | |
| 155 | // redraw the specified unit |
| 156 | virtual void RefreshUnit(size_t unit); |
| 157 | |
| 158 | // redraw all units in the specified range (inclusive) |
| 159 | virtual void RefreshUnits(size_t from, size_t to); |
| 160 | |
| 161 | // scroll to the specified unit: it will become the first visible unit in |
| 162 | // the window |
| 163 | // |
| 164 | // return true if we scrolled the window, false if nothing was done |
| 165 | bool DoScrollToUnit(size_t unit); |
| 166 | |
| 167 | // scroll by the specified number of units/pages |
| 168 | virtual bool DoScrollUnits(int units); |
| 169 | virtual bool DoScrollPages(int pages); |
| 170 | |
| 171 | // this function must be overridden in the derived class and it should |
| 172 | // return the size of the given unit in pixels |
| 173 | virtual wxCoord OnGetUnitSize(size_t n) const = 0; |
| 174 | |
| 175 | // this function doesn't have to be overridden but it may be useful to do |
| 176 | // it if calculating the units' sizes is a relatively expensive operation |
| 177 | // as it gives the user code a possibility to calculate several of them at |
| 178 | // once |
| 179 | // |
| 180 | // OnGetUnitsSizeHint() is normally called just before OnGetUnitSize() but |
| 181 | // you shouldn't rely on the latter being called for all units in the |
| 182 | // interval specified here. It is also possible that OnGetUnitHeight() will |
| 183 | // be called for the units outside of this interval, so this is really just |
| 184 | // a hint, not a promise. |
| 185 | // |
| 186 | // finally note that unitMin is inclusive, while unitMax is exclusive, as |
| 187 | // usual |
| 188 | virtual void OnGetUnitsSizeHint(size_t WXUNUSED(unitMin), |
| 189 | size_t WXUNUSED(unitMax)) const |
| 190 | { } |
| 191 | |
| 192 | // when the number of units changes, we try to estimate the total size |
| 193 | // of all units which is a rather expensive operation in terms of unit |
| 194 | // access, so if the user code may estimate the average size |
| 195 | // better/faster than we do, it should override this function to implement |
| 196 | // its own logic |
| 197 | // |
| 198 | // this function should return the best guess for the total size it may |
| 199 | // make |
| 200 | virtual wxCoord EstimateTotalSize() const { return DoEstimateTotalSize(); } |
| 201 | |
| 202 | wxCoord DoEstimateTotalSize() const; |
| 203 | |
| 204 | // find the index of the unit we need to show to fit the specified unit on |
| 205 | // the opposite side either fully or partially (depending on fullyVisible) |
| 206 | size_t FindFirstVisibleFromLast(size_t last, |
| 207 | bool fullyVisible = false) const; |
| 208 | |
| 209 | // get the total size of the units between unitMin (inclusive) and |
| 210 | // unitMax (exclusive) |
| 211 | wxCoord GetUnitsSize(size_t unitMin, size_t unitMax) const; |
| 212 | |
| 213 | // get the offset of the first visible unit |
| 214 | wxCoord GetScrollOffset() const |
| 215 | { return GetUnitsSize(0, GetVisibleBegin()); } |
| 216 | |
| 217 | // get the size of the target window |
| 218 | wxSize GetTargetSize() const { return m_targetWindow->GetClientSize(); } |
| 219 | |
| 220 | void GetTargetSize(int *w, int *h) |
| 221 | { |
| 222 | wxSize size = GetTargetSize(); |
| 223 | if ( w ) |
| 224 | *w = size.x; |
| 225 | if ( h ) |
| 226 | *h = size.y; |
| 227 | } |
| 228 | |
| 229 | // calculate the new scroll position based on scroll event type |
| 230 | size_t GetNewScrollPosition(wxScrollWinEvent& event) const; |
| 231 | |
| 232 | // replacement implementation of wxWindow::Layout virtual method. To |
| 233 | // properly forward calls to wxWindow::Layout use |
| 234 | // WX_FORWARD_TO_SCROLL_HELPER() derived class |
| 235 | bool ScrollLayout(); |
| 236 | |
| 237 | #ifdef __WXMAC__ |
| 238 | // queue mac window update after handling scroll event |
| 239 | virtual void UpdateMacScrollWindow() = 0; |
| 240 | #endif // __WXMAC__ |
| 241 | |
| 242 | // change the target window |
| 243 | void DoSetTargetWindow(wxWindow *target); |
| 244 | |
| 245 | // delete the event handler we installed |
| 246 | void DeleteEvtHandler(); |
| 247 | |
| 248 | // helper function abstracting the orientation test: with vertical |
| 249 | // orientation, it assigns the first value to x and the second one to y, |
| 250 | // with horizontal orientation it reverses them, i.e. the first value is |
| 251 | // assigned to y and the second one to x |
| 252 | void AssignOrient(wxCoord& x, wxCoord& y, wxCoord first, wxCoord second); |
| 253 | |
| 254 | // similar to "oriented assignment" above but does "oriented increment": |
| 255 | // for vertical orientation, y is incremented by the given value and x if |
| 256 | // left unchanged, for horizontal orientation x is incremented |
| 257 | void IncOrient(wxCoord& x, wxCoord& y, wxCoord inc); |
| 258 | |
| 259 | private: |
| 260 | |
| 261 | // the window that receives the scroll events and the window to actually |
| 262 | // scroll, respectively |
| 263 | wxWindow *m_win, |
| 264 | *m_targetWindow; |
| 265 | |
| 266 | // the total number of (logical) units |
| 267 | size_t m_unitMax; |
| 268 | |
| 269 | // the total (estimated) size |
| 270 | wxCoord m_sizeTotal; |
| 271 | |
| 272 | // the first currently visible unit |
| 273 | size_t m_unitFirst; |
| 274 | |
| 275 | // the number of currently visible units (including the last, possibly only |
| 276 | // partly, visible one) |
| 277 | size_t m_nUnitsVisible; |
| 278 | |
| 279 | // accumulated mouse wheel rotation |
| 280 | #if wxUSE_MOUSEWHEEL |
| 281 | int m_sumWheelRotation; |
| 282 | #endif |
| 283 | |
| 284 | // do child scrolling (used in DoPrepareDC()) |
| 285 | bool m_physicalScrolling; |
| 286 | |
| 287 | // handler injected into target window to forward some useful events to us |
| 288 | wxVarScrollHelperEvtHandler *m_handler; |
| 289 | }; |
| 290 | |
| 291 | |
| 292 | |
| 293 | // =========================================================================== |
| 294 | // wxVarVScrollHelper |
| 295 | // =========================================================================== |
| 296 | |
| 297 | // Provides public API functions targeted for vertical-specific scrolling, |
| 298 | // wrapping the functionality of wxVarScrollHelperBase. |
| 299 | |
| 300 | class WXDLLIMPEXP_CORE wxVarVScrollHelper : public wxVarScrollHelperBase |
| 301 | { |
| 302 | public: |
| 303 | // constructors and such |
| 304 | // --------------------- |
| 305 | |
| 306 | // ctor must be given the associated window |
| 307 | wxVarVScrollHelper(wxWindow *winToScroll) |
| 308 | : wxVarScrollHelperBase(winToScroll) |
| 309 | { |
| 310 | } |
| 311 | |
| 312 | // operators |
| 313 | |
| 314 | void SetRowCount(size_t rowCount) { SetUnitCount(rowCount); } |
| 315 | bool ScrollToRow(size_t row) { return DoScrollToUnit(row); } |
| 316 | |
| 317 | virtual bool ScrollRows(int rows) |
| 318 | { return DoScrollUnits(rows); } |
| 319 | virtual bool ScrollRowPages(int pages) |
| 320 | { return DoScrollPages(pages); } |
| 321 | |
| 322 | virtual void RefreshRow(size_t row) |
| 323 | { RefreshUnit(row); } |
| 324 | virtual void RefreshRows(size_t from, size_t to) |
| 325 | { RefreshUnits(from, to); } |
| 326 | |
| 327 | // accessors |
| 328 | |
| 329 | size_t GetRowCount() const { return GetUnitCount(); } |
| 330 | size_t GetVisibleRowsBegin() const { return GetVisibleBegin(); } |
| 331 | size_t GetVisibleRowsEnd() const { return GetVisibleEnd(); } |
| 332 | bool IsRowVisible(size_t row) const { return IsVisible(row); } |
| 333 | |
| 334 | virtual int GetOrientationTargetSize() const |
| 335 | { return GetTargetWindow()->GetClientSize().y; } |
| 336 | virtual int GetNonOrientationTargetSize() const |
| 337 | { return GetTargetWindow()->GetClientSize().x; } |
| 338 | virtual wxOrientation GetOrientation() const { return wxVERTICAL; } |
| 339 | |
| 340 | protected: |
| 341 | // this function must be overridden in the derived class and it should |
| 342 | // return the size of the given row in pixels |
| 343 | virtual wxCoord OnGetRowHeight(size_t n) const = 0; |
| 344 | wxCoord OnGetUnitSize(size_t n) const { return OnGetRowHeight(n); } |
| 345 | |
| 346 | virtual void OnGetRowsHeightHint(size_t WXUNUSED(rowMin), |
| 347 | size_t WXUNUSED(rowMax)) const { } |
| 348 | |
| 349 | // forward calls to OnGetRowsHeightHint() |
| 350 | virtual void OnGetUnitsSizeHint(size_t unitMin, size_t unitMax) const |
| 351 | { OnGetRowsHeightHint(unitMin, unitMax); } |
| 352 | |
| 353 | // again, if not overridden, it will fall back on default method |
| 354 | virtual wxCoord EstimateTotalHeight() const |
| 355 | { return DoEstimateTotalSize(); } |
| 356 | |
| 357 | // forward calls to EstimateTotalHeight() |
| 358 | virtual wxCoord EstimateTotalSize() const { return EstimateTotalHeight(); } |
| 359 | |
| 360 | wxCoord GetRowsHeight(size_t rowMin, size_t rowMax) const |
| 361 | { return GetUnitsSize(rowMin, rowMax); } |
| 362 | }; |
| 363 | |
| 364 | |
| 365 | |
| 366 | // =========================================================================== |
| 367 | // wxVarHScrollHelper |
| 368 | // =========================================================================== |
| 369 | |
| 370 | // Provides public API functions targeted for horizontal-specific scrolling, |
| 371 | // wrapping the functionality of wxVarScrollHelperBase. |
| 372 | |
| 373 | class WXDLLIMPEXP_CORE wxVarHScrollHelper : public wxVarScrollHelperBase |
| 374 | { |
| 375 | public: |
| 376 | // constructors and such |
| 377 | // --------------------- |
| 378 | |
| 379 | // ctor must be given the associated window |
| 380 | wxVarHScrollHelper(wxWindow *winToScroll) |
| 381 | : wxVarScrollHelperBase(winToScroll) |
| 382 | { |
| 383 | } |
| 384 | |
| 385 | // operators |
| 386 | |
| 387 | void SetColumnCount(size_t columnCount) |
| 388 | { SetUnitCount(columnCount); } |
| 389 | |
| 390 | bool ScrollToColumn(size_t column) |
| 391 | { return DoScrollToUnit(column); } |
| 392 | virtual bool ScrollColumns(int columns) |
| 393 | { return DoScrollUnits(columns); } |
| 394 | virtual bool ScrollColumnPages(int pages) |
| 395 | { return DoScrollPages(pages); } |
| 396 | |
| 397 | virtual void RefreshColumn(size_t column) |
| 398 | { RefreshUnit(column); } |
| 399 | virtual void RefreshColumns(size_t from, size_t to) |
| 400 | { RefreshUnits(from, to); } |
| 401 | |
| 402 | // accessors |
| 403 | |
| 404 | size_t GetColumnCount() const |
| 405 | { return GetUnitCount(); } |
| 406 | size_t GetVisibleColumnsBegin() const |
| 407 | { return GetVisibleBegin(); } |
| 408 | size_t GetVisibleColumnsEnd() const |
| 409 | { return GetVisibleEnd(); } |
| 410 | bool IsColumnVisible(size_t column) const |
| 411 | { return IsVisible(column); } |
| 412 | |
| 413 | |
| 414 | virtual int GetOrientationTargetSize() const |
| 415 | { return GetTargetWindow()->GetClientSize().x; } |
| 416 | virtual int GetNonOrientationTargetSize() const |
| 417 | { return GetTargetWindow()->GetClientSize().y; } |
| 418 | virtual wxOrientation GetOrientation() const { return wxHORIZONTAL; } |
| 419 | |
| 420 | protected: |
| 421 | // this function must be overridden in the derived class and it should |
| 422 | // return the size of the given column in pixels |
| 423 | virtual wxCoord OnGetColumnWidth(size_t n) const = 0; |
| 424 | wxCoord OnGetUnitSize(size_t n) const { return OnGetColumnWidth(n); } |
| 425 | |
| 426 | virtual void OnGetColumnsWidthHint(size_t WXUNUSED(columnMin), |
| 427 | size_t WXUNUSED(columnMax)) const |
| 428 | { } |
| 429 | |
| 430 | // forward calls to OnGetColumnsWidthHint() |
| 431 | virtual void OnGetUnitsSizeHint(size_t unitMin, size_t unitMax) const |
| 432 | { OnGetColumnsWidthHint(unitMin, unitMax); } |
| 433 | |
| 434 | // again, if not overridden, it will fall back on default method |
| 435 | virtual wxCoord EstimateTotalWidth() const { return DoEstimateTotalSize(); } |
| 436 | |
| 437 | // forward calls to EstimateTotalWidth() |
| 438 | virtual wxCoord EstimateTotalSize() const { return EstimateTotalWidth(); } |
| 439 | |
| 440 | wxCoord GetColumnsWidth(size_t columnMin, size_t columnMax) const |
| 441 | { return GetUnitsSize(columnMin, columnMax); } |
| 442 | }; |
| 443 | |
| 444 | |
| 445 | |
| 446 | // =========================================================================== |
| 447 | // wxVarHVScrollHelper |
| 448 | // =========================================================================== |
| 449 | |
| 450 | // Provides public API functions targeted at functions with similar names in |
| 451 | // both wxVScrollHelper and wxHScrollHelper so class scope doesn't need to be |
| 452 | // specified (since we are using multiple inheritance). It also provides |
| 453 | // functions to make changing values for both orientations at the same time |
| 454 | // easier. |
| 455 | |
| 456 | class WXDLLIMPEXP_CORE wxVarHVScrollHelper : public wxVarVScrollHelper, |
| 457 | public wxVarHScrollHelper |
| 458 | { |
| 459 | public: |
| 460 | // constructors and such |
| 461 | // --------------------- |
| 462 | |
| 463 | // ctor must be given the associated window |
| 464 | wxVarHVScrollHelper(wxWindow *winToScroll) |
| 465 | : wxVarVScrollHelper(winToScroll), wxVarHScrollHelper(winToScroll) { } |
| 466 | |
| 467 | // operators |
| 468 | // --------- |
| 469 | |
| 470 | // set the number of units the window contains for each axis: the derived |
| 471 | // class must provide the widths and heights for all units with indices up |
| 472 | // to each of the one given here in its OnGetColumnWidth() and |
| 473 | // OnGetRowHeight() |
| 474 | void SetRowColumnCount(size_t rowCount, size_t columnCount); |
| 475 | |
| 476 | |
| 477 | // with physical scrolling on, the device origin is changed properly when |
| 478 | // a wxPaintDC is prepared, children are actually moved and laid out |
| 479 | // properly, and the contents of the window (pixels) are actually moved |
| 480 | void EnablePhysicalScrolling(bool vscrolling = true, bool hscrolling = true) |
| 481 | { |
| 482 | wxVarVScrollHelper::EnablePhysicalScrolling(vscrolling); |
| 483 | wxVarHScrollHelper::EnablePhysicalScrolling(hscrolling); |
| 484 | } |
| 485 | |
| 486 | // scroll to the specified row/column: it will become the first visible |
| 487 | // cell in the window |
| 488 | // |
| 489 | // return true if we scrolled the window, false if nothing was done |
| 490 | bool ScrollToRowColumn(size_t row, size_t column); |
| 491 | bool ScrollToRowColumn(const wxPosition &pos) |
| 492 | { return ScrollToRowColumn(pos.GetRow(), pos.GetColumn()); } |
| 493 | |
| 494 | // redraw the specified cell |
| 495 | virtual void RefreshRowColumn(size_t row, size_t column); |
| 496 | virtual void RefreshRowColumn(const wxPosition &pos) |
| 497 | { RefreshRowColumn(pos.GetRow(), pos.GetColumn()); } |
| 498 | |
| 499 | // redraw the specified regions (inclusive). If the target window for |
| 500 | // both orientations is the same the rectangle of cells is refreshed; if |
| 501 | // the target windows differ the entire client size opposite the |
| 502 | // orientation direction is refreshed between the specified limits |
| 503 | virtual void RefreshRowsColumns(size_t fromRow, size_t toRow, |
| 504 | size_t fromColumn, size_t toColumn); |
| 505 | virtual void RefreshRowsColumns(const wxPosition& from, |
| 506 | const wxPosition& to) |
| 507 | { |
| 508 | RefreshRowsColumns(from.GetRow(), to.GetRow(), |
| 509 | from.GetColumn(), to.GetColumn()); |
| 510 | } |
| 511 | |
| 512 | // locate the virtual position from the given device coordinates |
| 513 | wxPosition VirtualHitTest(wxCoord x, wxCoord y) const; |
| 514 | wxPosition VirtualHitTest(const wxPoint &pos) const |
| 515 | { return VirtualHitTest(pos.x, pos.y); } |
| 516 | |
| 517 | // change the DC origin according to the scroll position. To properly |
| 518 | // forward calls to wxWindow::Layout use WX_FORWARD_TO_SCROLL_HELPER() |
| 519 | // derived class. We use this version to call both base classes' |
| 520 | // DoPrepareDC() |
| 521 | virtual void DoPrepareDC(wxDC& dc); |
| 522 | |
| 523 | // replacement implementation of wxWindow::Layout virtual method. To |
| 524 | // properly forward calls to wxWindow::Layout use |
| 525 | // WX_FORWARD_TO_SCROLL_HELPER() derived class. We use this version to |
| 526 | // call both base classes' ScrollLayout() |
| 527 | bool ScrollLayout(); |
| 528 | |
| 529 | // accessors |
| 530 | // --------- |
| 531 | |
| 532 | // get the number of units this window contains (previously set by |
| 533 | // Set[Column/Row/RowColumn/Unit]Count()) |
| 534 | wxSize GetRowColumnCount() const; |
| 535 | |
| 536 | // get the first currently visible units |
| 537 | wxPosition GetVisibleBegin() const; |
| 538 | wxPosition GetVisibleEnd() const; |
| 539 | |
| 540 | // is this cell currently visible? |
| 541 | bool IsVisible(size_t row, size_t column) const; |
| 542 | bool IsVisible(const wxPosition &pos) const |
| 543 | { return IsVisible(pos.GetRow(), pos.GetColumn()); } |
| 544 | }; |
| 545 | |
| 546 | |
| 547 | |
| 548 | #if WXWIN_COMPATIBILITY_2_8 |
| 549 | |
| 550 | // =========================================================================== |
| 551 | // wxVarVScrollLegacyAdaptor |
| 552 | // =========================================================================== |
| 553 | |
| 554 | // Provides backwards compatible API for applications originally built using |
| 555 | // wxVScrolledWindow in 2.6 or 2.8. Originally, wxVScrolledWindow referred |
| 556 | // to scrolling "lines". We use "units" in wxVarScrollHelperBase to avoid |
| 557 | // implying any orientation (since the functions are used for both horizontal |
| 558 | // and vertical scrolling in derived classes). And in the new |
| 559 | // wxVScrolledWindow and wxHScrolledWindow classes, we refer to them as |
| 560 | // "rows" and "columns", respectively. This is to help clear some confusion |
| 561 | // in not only those classes, but also in wxHVScrolledWindow where functions |
| 562 | // are inherited from both. |
| 563 | |
| 564 | class WXDLLIMPEXP_CORE wxVarVScrollLegacyAdaptor : public wxVarVScrollHelper |
| 565 | { |
| 566 | public: |
| 567 | // constructors and such |
| 568 | // --------------------- |
| 569 | wxVarVScrollLegacyAdaptor(wxWindow *winToScroll) |
| 570 | : wxVarVScrollHelper(winToScroll) |
| 571 | { |
| 572 | } |
| 573 | |
| 574 | // accessors |
| 575 | // --------- |
| 576 | |
| 577 | // this is the same as GetVisibleRowsBegin(), exists to match |
| 578 | // GetLastVisibleLine() and for backwards compatibility only |
| 579 | wxDEPRECATED( size_t GetFirstVisibleLine() const ); |
| 580 | |
| 581 | // get the last currently visible line |
| 582 | // |
| 583 | // this function is unsafe as it returns (size_t)-1 (i.e. a huge positive |
| 584 | // number) if the control is empty, use GetVisibleRowsEnd() instead, this |
| 585 | // one is kept for backwards compatibility |
| 586 | wxDEPRECATED( size_t GetLastVisibleLine() const ); |
| 587 | |
| 588 | // "line" to "unit" compatibility functions |
| 589 | // ---------------------------------------- |
| 590 | |
| 591 | // get the number of lines this window contains (set by SetLineCount()) |
| 592 | wxDEPRECATED( size_t GetLineCount() const ); |
| 593 | |
| 594 | // set the number of lines the helper contains: the derived class must |
| 595 | // provide the sizes for all lines with indices up to the one given here |
| 596 | // in its OnGetLineHeight() |
| 597 | wxDEPRECATED( void SetLineCount(size_t count) ); |
| 598 | |
| 599 | // redraw the specified line |
| 600 | wxDEPRECATED( virtual void RefreshLine(size_t line) ); |
| 601 | |
| 602 | // redraw all lines in the specified range (inclusive) |
| 603 | wxDEPRECATED( virtual void RefreshLines(size_t from, size_t to) ); |
| 604 | |
| 605 | // scroll to the specified line: it will become the first visible line in |
| 606 | // the window |
| 607 | // |
| 608 | // return true if we scrolled the window, false if nothing was done |
| 609 | wxDEPRECATED( bool ScrollToLine(size_t line) ); |
| 610 | |
| 611 | // scroll by the specified number of lines/pages |
| 612 | wxDEPRECATED( virtual bool ScrollLines(int lines) ); |
| 613 | wxDEPRECATED( virtual bool ScrollPages(int pages) ); |
| 614 | |
| 615 | protected: |
| 616 | // unless the code has been updated to override OnGetRowHeight() instead, |
| 617 | // this function must be overridden in the derived class and it should |
| 618 | // return the height of the given row in pixels |
| 619 | wxDEPRECATED_BUT_USED_INTERNALLY( |
| 620 | virtual wxCoord OnGetLineHeight(size_t n) const ); |
| 621 | |
| 622 | // forwards the calls from base class pure virtual function to pure virtual |
| 623 | // OnGetLineHeight instead (backwards compatible name) |
| 624 | // note that we don't need to forward OnGetUnitSize() as it is already |
| 625 | // forwarded to OnGetRowHeight() in wxVarVScrollHelper |
| 626 | virtual wxCoord OnGetRowHeight(size_t n) const; |
| 627 | |
| 628 | // this function doesn't have to be overridden but it may be useful to do |
| 629 | // it if calculating the lines heights is a relatively expensive operation |
| 630 | // as it gives the user code a possibility to calculate several of them at |
| 631 | // once |
| 632 | // |
| 633 | // OnGetLinesHint() is normally called just before OnGetLineHeight() but you |
| 634 | // shouldn't rely on the latter being called for all lines in the interval |
| 635 | // specified here. It is also possible that OnGetLineHeight() will be |
| 636 | // called for the lines outside of this interval, so this is really just a |
| 637 | // hint, not a promise. |
| 638 | // |
| 639 | // finally note that lineMin is inclusive, while lineMax is exclusive, as |
| 640 | // usual |
| 641 | wxDEPRECATED_BUT_USED_INTERNALLY( virtual void OnGetLinesHint( |
| 642 | size_t lineMin, size_t lineMax) const ); |
| 643 | |
| 644 | // forwards the calls from base class pure virtual function to pure virtual |
| 645 | // OnGetLinesHint instead (backwards compatible name) |
| 646 | void OnGetRowsHeightHint(size_t rowMin, size_t rowMax) const; |
| 647 | }; |
| 648 | |
| 649 | #else // !WXWIN_COMPATIBILITY_2_8 |
| 650 | |
| 651 | // shortcut to avoid checking compatibility modes later |
| 652 | // remove this and all references to wxVarVScrollLegacyAdaptor once |
| 653 | // wxWidgets 2.6 and 2.8 compatibility is removed |
| 654 | typedef wxVarVScrollHelper wxVarVScrollLegacyAdaptor; |
| 655 | |
| 656 | #endif // WXWIN_COMPATIBILITY_2_8/!WXWIN_COMPATIBILITY_2_8 |
| 657 | |
| 658 | |
| 659 | // this macro must be used in declaration of wxVarScrollHelperBase-derived |
| 660 | // classes |
| 661 | #define WX_FORWARD_TO_VAR_SCROLL_HELPER() \ |
| 662 | public: \ |
| 663 | virtual void PrepareDC(wxDC& dc) { DoPrepareDC(dc); } \ |
| 664 | virtual bool Layout() { return ScrollLayout(); } |
| 665 | |
| 666 | |
| 667 | |
| 668 | // =========================================================================== |
| 669 | // wxVScrolledWindow |
| 670 | // =========================================================================== |
| 671 | |
| 672 | // In the name of this class, "V" may stand for "variable" because it can be |
| 673 | // used for scrolling rows of variable heights; "virtual", because it is not |
| 674 | // necessary to know the heights of all rows in advance -- only those which |
| 675 | // are shown on the screen need to be measured; or even "vertical", because |
| 676 | // this class only supports scrolling vertically. |
| 677 | |
| 678 | // In any case, this is a generalization of the wxScrolledWindow class which |
| 679 | // can be only used when all rows have the same heights. It lacks some other |
| 680 | // wxScrolledWindow features however, notably it can't scroll only a rectangle |
| 681 | // of the window and not its entire client area. |
| 682 | |
| 683 | class WXDLLIMPEXP_CORE wxVScrolledWindow : public wxPanel, |
| 684 | public wxVarVScrollLegacyAdaptor |
| 685 | { |
| 686 | public: |
| 687 | // constructors and such |
| 688 | // --------------------- |
| 689 | |
| 690 | // default ctor, you must call Create() later |
| 691 | wxVScrolledWindow() : wxVarVScrollLegacyAdaptor(this) { } |
| 692 | |
| 693 | // normal ctor, no need to call Create() after this one |
| 694 | // |
| 695 | // note that wxVSCROLL is always automatically added to our style, there is |
| 696 | // no need to specify it explicitly |
| 697 | wxVScrolledWindow(wxWindow *parent, |
| 698 | wxWindowID id = wxID_ANY, |
| 699 | const wxPoint& pos = wxDefaultPosition, |
| 700 | const wxSize& size = wxDefaultSize, |
| 701 | long style = 0, |
| 702 | const wxString& name = wxPanelNameStr) |
| 703 | : wxVarVScrollLegacyAdaptor(this) |
| 704 | { |
| 705 | (void)Create(parent, id, pos, size, style, name); |
| 706 | } |
| 707 | |
| 708 | // same as the previous ctor but returns status code: true if ok |
| 709 | // |
| 710 | // just as with the ctor above, wxVSCROLL style is always used, there is no |
| 711 | // need to specify it |
| 712 | bool Create(wxWindow *parent, |
| 713 | wxWindowID id = wxID_ANY, |
| 714 | const wxPoint& pos = wxDefaultPosition, |
| 715 | const wxSize& size = wxDefaultSize, |
| 716 | long style = 0, |
| 717 | const wxString& name = wxPanelNameStr) |
| 718 | { |
| 719 | return wxPanel::Create(parent, id, pos, size, style | wxVSCROLL, name); |
| 720 | } |
| 721 | |
| 722 | #if WXWIN_COMPATIBILITY_2_8 |
| 723 | // Make sure we prefer our version of HitTest rather than wxWindow's |
| 724 | // These functions should no longer be masked in favor of VirtualHitTest() |
| 725 | int HitTest(wxCoord WXUNUSED(x), wxCoord y) const |
| 726 | { return wxVarVScrollHelper::VirtualHitTest(y); } |
| 727 | int HitTest(const wxPoint& pt) const |
| 728 | { return HitTest(pt.x, pt.y); } |
| 729 | #endif // WXWIN_COMPATIBILITY_2_8 |
| 730 | |
| 731 | WX_FORWARD_TO_VAR_SCROLL_HELPER() |
| 732 | |
| 733 | #ifdef __WXMAC__ |
| 734 | protected: |
| 735 | virtual void UpdateMacScrollWindow() { Update(); } |
| 736 | #endif // __WXMAC__ |
| 737 | |
| 738 | private: |
| 739 | wxDECLARE_NO_COPY_CLASS(wxVScrolledWindow); |
| 740 | DECLARE_ABSTRACT_CLASS(wxVScrolledWindow) |
| 741 | }; |
| 742 | |
| 743 | |
| 744 | |
| 745 | // =========================================================================== |
| 746 | // wxHScrolledWindow |
| 747 | // =========================================================================== |
| 748 | |
| 749 | // In the name of this class, "H" stands for "horizontal" because it can be |
| 750 | // used for scrolling columns of variable widths. It is not necessary to know |
| 751 | // the widths of all columns in advance -- only those which are shown on the |
| 752 | // screen need to be measured. |
| 753 | |
| 754 | // This is a generalization of the wxScrolledWindow class which can be only |
| 755 | // used when all columns have the same width. It lacks some other |
| 756 | // wxScrolledWindow features however, notably it can't scroll only a rectangle |
| 757 | // of the window and not its entire client area. |
| 758 | |
| 759 | class WXDLLIMPEXP_CORE wxHScrolledWindow : public wxPanel, |
| 760 | public wxVarHScrollHelper |
| 761 | { |
| 762 | public: |
| 763 | // constructors and such |
| 764 | // --------------------- |
| 765 | |
| 766 | // default ctor, you must call Create() later |
| 767 | wxHScrolledWindow() : wxVarHScrollHelper(this) { } |
| 768 | |
| 769 | // normal ctor, no need to call Create() after this one |
| 770 | // |
| 771 | // note that wxHSCROLL is always automatically added to our style, there is |
| 772 | // no need to specify it explicitly |
| 773 | wxHScrolledWindow(wxWindow *parent, |
| 774 | wxWindowID id = wxID_ANY, |
| 775 | const wxPoint& pos = wxDefaultPosition, |
| 776 | const wxSize& size = wxDefaultSize, |
| 777 | long style = 0, |
| 778 | const wxString& name = wxPanelNameStr) |
| 779 | : wxVarHScrollHelper(this) |
| 780 | { |
| 781 | (void)Create(parent, id, pos, size, style, name); |
| 782 | } |
| 783 | |
| 784 | // same as the previous ctor but returns status code: true if ok |
| 785 | // |
| 786 | // just as with the ctor above, wxHSCROLL style is always used, there is no |
| 787 | // need to specify it |
| 788 | bool Create(wxWindow *parent, |
| 789 | wxWindowID id = wxID_ANY, |
| 790 | const wxPoint& pos = wxDefaultPosition, |
| 791 | const wxSize& size = wxDefaultSize, |
| 792 | long style = 0, |
| 793 | const wxString& name = wxPanelNameStr) |
| 794 | { |
| 795 | return wxPanel::Create(parent, id, pos, size, style | wxHSCROLL, name); |
| 796 | } |
| 797 | |
| 798 | WX_FORWARD_TO_VAR_SCROLL_HELPER() |
| 799 | |
| 800 | #ifdef __WXMAC__ |
| 801 | protected: |
| 802 | virtual void UpdateMacScrollWindow() { Update(); } |
| 803 | #endif // __WXMAC__ |
| 804 | |
| 805 | private: |
| 806 | wxDECLARE_NO_COPY_CLASS(wxHScrolledWindow); |
| 807 | DECLARE_ABSTRACT_CLASS(wxHScrolledWindow) |
| 808 | }; |
| 809 | |
| 810 | |
| 811 | |
| 812 | // =========================================================================== |
| 813 | // wxHVScrolledWindow |
| 814 | // =========================================================================== |
| 815 | |
| 816 | // This window inherits all functionality of both vertical and horizontal |
| 817 | // scrolled windows automatically handling everything needed to scroll both |
| 818 | // axis simultaneously. |
| 819 | |
| 820 | class WXDLLIMPEXP_CORE wxHVScrolledWindow : public wxPanel, |
| 821 | public wxVarHVScrollHelper |
| 822 | { |
| 823 | public: |
| 824 | // constructors and such |
| 825 | // --------------------- |
| 826 | |
| 827 | // default ctor, you must call Create() later |
| 828 | wxHVScrolledWindow() |
| 829 | : wxPanel(), |
| 830 | wxVarHVScrollHelper(this) { } |
| 831 | |
| 832 | // normal ctor, no need to call Create() after this one |
| 833 | // |
| 834 | // note that wxVSCROLL and wxHSCROLL are always automatically added to our |
| 835 | // style, there is no need to specify them explicitly |
| 836 | wxHVScrolledWindow(wxWindow *parent, |
| 837 | wxWindowID id = wxID_ANY, |
| 838 | const wxPoint& pos = wxDefaultPosition, |
| 839 | const wxSize& size = wxDefaultSize, |
| 840 | long style = 0, |
| 841 | const wxString& name = wxPanelNameStr) |
| 842 | : wxPanel(), |
| 843 | wxVarHVScrollHelper(this) |
| 844 | { |
| 845 | (void)Create(parent, id, pos, size, style, name); |
| 846 | } |
| 847 | |
| 848 | // same as the previous ctor but returns status code: true if ok |
| 849 | // |
| 850 | // just as with the ctor above, wxVSCROLL and wxHSCROLL styles are always |
| 851 | // used, there is no need to specify them |
| 852 | bool Create(wxWindow *parent, |
| 853 | wxWindowID id = wxID_ANY, |
| 854 | const wxPoint& pos = wxDefaultPosition, |
| 855 | const wxSize& size = wxDefaultSize, |
| 856 | long style = 0, |
| 857 | const wxString& name = wxPanelNameStr) |
| 858 | { |
| 859 | return wxPanel::Create(parent, id, pos, size, |
| 860 | style | wxVSCROLL | wxHSCROLL, name); |
| 861 | } |
| 862 | |
| 863 | WX_FORWARD_TO_VAR_SCROLL_HELPER() |
| 864 | |
| 865 | #ifdef __WXMAC__ |
| 866 | protected: |
| 867 | virtual void UpdateMacScrollWindow() { Update(); } |
| 868 | #endif // __WXMAC__ |
| 869 | |
| 870 | private: |
| 871 | wxDECLARE_NO_COPY_CLASS(wxHVScrolledWindow); |
| 872 | DECLARE_ABSTRACT_CLASS(wxHVScrolledWindow) |
| 873 | }; |
| 874 | |
| 875 | #endif // _WX_VSCROLL_H_ |
| 876 | |