X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4ca24f185f870295a7041c64a4f375bed8d75d57..1978421a6d8b81c1f8a961da4b8ddf544fec7b1b:/src/gtk/scrolwin.cpp diff --git a/src/gtk/scrolwin.cpp b/src/gtk/scrolwin.cpp index fe7bf353ea..9232d1e543 100644 --- a/src/gtk/scrolwin.cpp +++ b/src/gtk/scrolwin.cpp @@ -2,11 +2,11 @@ // Name: gtk/scrolwin.cpp // Purpose: wxScrolledWindow implementation // Author: Julian Smart -// Modified by: +// Modified by: Ron Lee // Created: 01/02/97 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// Copyright: (c) Julian Smart +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -17,7 +17,7 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "scrolwin.h" #endif @@ -202,8 +202,6 @@ void wxScrolledWindow::Init() m_yScrollingEnabled = TRUE; m_xScrollPosition = 0; m_yScrollPosition = 0; - m_xScrollLines = 0; - m_yScrollLines = 0; m_xScrollLinesPerPage = 0; m_yScrollLinesPerPage = 0; m_targetWindow = (wxWindow*) NULL; @@ -315,7 +313,7 @@ bool wxScrolledWindow::Create(wxWindow *parent, PostCreation(); Show( TRUE ); - + return TRUE; } @@ -323,51 +321,59 @@ bool wxScrolledWindow::Create(wxWindow *parent, // setting scrolling parameters // ---------------------------------------------------------------------------- +void wxScrolledWindow::DoSetVirtualSize( int x, int y ) +{ + wxPanel::DoSetVirtualSize( x, y ); + AdjustScrollbars(); + +#if wxUSE_CONSTRAINTS + if (GetAutoLayout()) + Layout(); +#endif +} + /* * pixelsPerUnitX/pixelsPerUnitY: number of pixels per unit (e.g. pixels per text line) * noUnitsX/noUnitsY: : no. units per scrollbar */ -void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY, - int noUnitsX, int noUnitsY, - int xPos, int yPos, bool noRefresh ) +void wxScrolledWindow::SetScrollbars( int pixelsPerUnitX, int pixelsPerUnitY, + int noUnitsX, int noUnitsY, + int xPos, int yPos, bool noRefresh ) { - int old_x = m_xScrollPixelsPerLine * m_xScrollPosition; - int old_y = m_yScrollPixelsPerLine * m_yScrollPosition; + int xs, ys; + GetViewStart (& xs, & ys); + + int old_x = m_xScrollPixelsPerLine * xs; + int old_y = m_yScrollPixelsPerLine * ys; m_xScrollPixelsPerLine = pixelsPerUnitX; m_yScrollPixelsPerLine = pixelsPerUnitY; - m_xScrollLines = noUnitsX; - m_yScrollLines = noUnitsY; - m_xScrollPosition = xPos; - m_yScrollPosition = yPos; - m_hAdjust->lower = 0.0; - m_hAdjust->upper = noUnitsX; - m_hAdjust->value = xPos; - m_hAdjust->step_increment = 1.0; - m_hAdjust->page_increment = 2.0; + m_hAdjust->value = m_xScrollPosition = xPos; + m_vAdjust->value = m_yScrollPosition = yPos; - m_vAdjust->lower = 0.0; - m_vAdjust->upper = noUnitsY; - m_vAdjust->value = yPos; - m_vAdjust->step_increment = 1.0; - m_vAdjust->page_increment = 2.0; + // Setting hints here should arguably be deprecated, but without it + // a sizer might override this manual scrollbar setting in old code. + m_targetWindow->SetVirtualSizeHints( noUnitsX * pixelsPerUnitX, noUnitsY * pixelsPerUnitY ); - AdjustScrollbars(); + m_targetWindow->SetVirtualSize( noUnitsX * pixelsPerUnitX, noUnitsY * pixelsPerUnitY ); if (!noRefresh) { int new_x = m_xScrollPixelsPerLine * m_xScrollPosition; int new_y = m_yScrollPixelsPerLine * m_yScrollPosition; - m_targetWindow->ScrollWindow( old_x-new_x, old_y-new_y ); + m_targetWindow->ScrollWindow( old_x - new_x, old_y - new_y ); } } void wxScrolledWindow::AdjustScrollbars() { int w, h; + int vw, vh; + m_targetWindow->GetClientSize( &w, &h ); + m_targetWindow->GetVirtualSize( &vw, &vh ); if (m_xScrollPixelsPerLine == 0) { @@ -376,21 +382,23 @@ void wxScrolledWindow::AdjustScrollbars() } else { + m_hAdjust->upper = vw / m_xScrollPixelsPerLine; m_hAdjust->page_size = (w / m_xScrollPixelsPerLine); - int max = (int)(m_hAdjust->upper - m_hAdjust->page_size + 0.5); - if (max < 0) max = 0; - - int x_pos = m_xScrollPosition; - if (x_pos > max) x_pos = max; - if (x_pos < 0) x_pos = 0; - - int old_x = m_xScrollPosition; - m_xScrollPosition = x_pos; - m_hAdjust->value = x_pos; + // If the scrollbar hits the right side, move the window + // right to keep it from over extending. - if (x_pos != old_x) - m_targetWindow->ScrollWindow( (old_x-m_xScrollPosition)*m_xScrollPixelsPerLine, 0 ); + if ((m_hAdjust->value != 0.0) && (m_hAdjust->value + m_hAdjust->page_size > m_hAdjust->upper)) + { + m_hAdjust->value = m_hAdjust->upper - m_hAdjust->page_size; + if (m_hAdjust->value < 0.0) + m_hAdjust->value = 0.0; + + if (GetChildren().GetCount() == 0) + m_xScrollPosition = (int)m_hAdjust->value; // This is enough without child windows + else + gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" ); // Actually scroll window + } } if (m_yScrollPixelsPerLine == 0) @@ -400,21 +408,20 @@ void wxScrolledWindow::AdjustScrollbars() } else { + m_vAdjust->upper = vh / m_yScrollPixelsPerLine; m_vAdjust->page_size = (h / m_yScrollPixelsPerLine); - int max = (int)(m_vAdjust->upper - m_vAdjust->page_size + 0.5); - if (max < 0) max = 0; - - int y_pos = m_yScrollPosition; - if (y_pos > max) y_pos = max; - if (y_pos < 0) y_pos = 0; - - int old_y = m_yScrollPosition; - m_yScrollPosition = y_pos; - m_vAdjust->value = y_pos; - - if (y_pos != old_y) - m_targetWindow->ScrollWindow( 0, (old_y-m_yScrollPosition)*m_yScrollPixelsPerLine ); + if ((m_vAdjust->value != 0.0) && (m_vAdjust->value + m_vAdjust->page_size > m_vAdjust->upper)) + { + m_vAdjust->value = m_vAdjust->upper - m_vAdjust->page_size; + if (m_vAdjust->value < 0.0) + m_vAdjust->value = 0.0; + + if (GetChildren().GetCount() == 0) + m_yScrollPosition = (int)m_vAdjust->value; + else + gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" ); + } } m_xScrollLinesPerPage = (int)(m_hAdjust->page_size + 0.5); @@ -424,6 +431,7 @@ void wxScrolledWindow::AdjustScrollbars() gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); } + // ---------------------------------------------------------------------------- // target window handling // ---------------------------------------------------------------------------- @@ -447,6 +455,22 @@ void wxScrolledWindow::PrepareDC(wxDC& dc) -m_yScrollPosition * m_yScrollPixelsPerLine ); } +void wxScrolledWindow::SetScrollRate( int xstep, int ystep ) +{ + int old_x = m_xScrollPixelsPerLine * m_xScrollPosition; + int old_y = m_yScrollPixelsPerLine * m_yScrollPosition; + + m_xScrollPixelsPerLine = xstep; + m_yScrollPixelsPerLine = ystep; + + int new_x = m_xScrollPixelsPerLine * m_xScrollPosition; + int new_y = m_yScrollPixelsPerLine * m_yScrollPosition; + + m_targetWindow->ScrollWindow( old_x - new_x, old_y - new_y ); + + AdjustScrollbars(); +} + void wxScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const { if ( x_unit ) @@ -516,8 +540,7 @@ void wxScrolledWindow::OnScroll(wxScrollWinEvent& event) void wxScrolledWindow::Scroll( int x_pos, int y_pos ) { - if (!m_targetWindow) - return; + wxASSERT_MSG( m_targetWindow != 0, _T("No target window") ); if (((x_pos == -1) || (x_pos == m_xScrollPosition)) && ((y_pos == -1) || (y_pos == m_yScrollPosition))) return; @@ -565,8 +588,7 @@ void wxScrolledWindow::Scroll( int x_pos, int y_pos ) void wxScrolledWindow::GtkVScroll( float value, unsigned int scroll_type ) { - if (!m_targetWindow) - return; + wxASSERT_MSG( m_targetWindow != 0, _T("No target window") ); if (m_yScrollPixelsPerLine == 0) return; @@ -585,8 +607,7 @@ void wxScrolledWindow::GtkVScroll( float value, unsigned int scroll_type ) void wxScrolledWindow::GtkHScroll( float value, unsigned int scroll_type ) { - if (!m_targetWindow) - return; + wxASSERT_MSG( m_targetWindow != 0, _T("No target window") ); if (m_xScrollPixelsPerLine == 0) return; @@ -609,28 +630,6 @@ void wxScrolledWindow::EnableScrolling (bool x_scroll, bool y_scroll) m_yScrollingEnabled = y_scroll; } -void wxScrolledWindow::GetVirtualSize (int *x, int *y) const -{ - wxSize sz(0, 0); - if (m_targetWindow) - sz = m_targetWindow->GetClientSize(); - - if ( x ) - { - if (m_xScrollPixelsPerLine == 0) - *x = sz.x; - else - *x = m_xScrollPixelsPerLine * m_xScrollLines; - } - if ( y ) - { - if (m_yScrollPixelsPerLine == 0) - *y = sz.y; - else - *y = m_yScrollPixelsPerLine * m_yScrollLines; - } -} - // Where the current view starts from void wxScrolledWindow::GetViewStart (int *x, int *y) const { @@ -642,18 +641,24 @@ void wxScrolledWindow::GetViewStart (int *x, int *y) const void wxScrolledWindow::DoCalcScrolledPosition(int x, int y, int *xx, int *yy) const { + int xs, ys; + GetViewStart (& xs, & ys); + if ( xx ) - *xx = x - m_xScrollPosition * m_xScrollPixelsPerLine; + *xx = x - xs * m_xScrollPixelsPerLine; if ( yy ) - *yy = y - m_yScrollPosition * m_yScrollPixelsPerLine; + *yy = y - ys * m_yScrollPixelsPerLine; } void wxScrolledWindow::DoCalcUnscrolledPosition(int x, int y, int *xx, int *yy) const { + int xs, ys; + GetViewStart (& xs, & ys); + if ( xx ) - *xx = x + m_xScrollPosition * m_xScrollPixelsPerLine; + *xx = x + xs * m_xScrollPixelsPerLine; if ( yy ) - *yy = y + m_yScrollPosition * m_yScrollPixelsPerLine; + *yy = y + ys * m_yScrollPixelsPerLine; } int wxScrolledWindow::CalcScrollInc(wxScrollWinEvent& event) @@ -672,9 +677,9 @@ int wxScrolledWindow::CalcScrollInc(wxScrollWinEvent& event) if (event.GetEventType() == wxEVT_SCROLLWIN_BOTTOM) { if (orient == wxHORIZONTAL) - nScrollInc = m_xScrollLines - m_xScrollPosition; + nScrollInc = GetVirtualSize().GetWidth() / m_xScrollPixelsPerLine - m_xScrollPosition; else - nScrollInc = m_yScrollLines - m_yScrollPosition; + nScrollInc = GetVirtualSize().GetHeight() / m_yScrollPixelsPerLine - m_yScrollPosition; } else if (event.GetEventType() == wxEVT_SCROLLWIN_LINEUP) { @@ -813,12 +818,13 @@ void wxScrolledWindow::GtkVDisconnectEvent() (GtkSignalFunc) gtk_scrolled_window_vscroll_callback, (gpointer) this ); } - bool wxScrolledWindow::Layout() { - if (GetSizer()) + if (GetSizer() && m_targetWindow == this) { - // Take into account the virtual size and scrolled position of the window + // If we're the scroll target, take into account the + // virtual size and scrolled position of the window. + int x, y, w, h; CalcScrolledPosition(0,0, &x,&y); GetVirtualSize(&w, &h); @@ -836,12 +842,24 @@ bool wxScrolledWindow::Layout() // Default OnSize resets scrollbars, if any void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event)) { -#if wxUSE_CONSTRAINTS - if (GetAutoLayout()) - Layout(); -#endif + if( GetAutoLayout() || m_targetWindow->GetAutoLayout() ) + { + if( m_targetWindow != this ) + m_targetWindow->FitInside(); - AdjustScrollbars(); + FitInside(); + + // FIXME: Something is really weird here... This should be + // called by FitInside above (and apparently is), yet the + // scrollsub sample will get the scrollbar wrong if resized + // quickly. This masks the bug, but is surely not the right + // answer at all. + AdjustScrollbars(); + } + else + { + AdjustScrollbars(); + } } // This calls OnDraw, having adjusted the origin according to the current @@ -864,7 +882,7 @@ void wxScrolledWindow::OnChar(wxKeyEvent& event) szx, szy, // view size (total) clix, cliy; // view size (on screen) - ViewStart(&stx, &sty); + GetViewStart(&stx, &sty); GetClientSize(&clix, &cliy); GetVirtualSize(&szx, &szy); @@ -893,7 +911,7 @@ void wxScrolledWindow::OnChar(wxKeyEvent& event) yScrollOld = GetScrollPos(wxVERTICAL); int dsty; - switch ( event.KeyCode() ) + switch ( event.GetKeyCode() ) { case WXK_PAGEUP: case WXK_PRIOR: @@ -955,3 +973,5 @@ void wxScrolledWindow::OnChar(wxKeyEvent& event) } } + +// vi:sts=4:sw=4:et