///////////////////////////////////////////////////////////////////////////// // Name: gtk/scrolwin.cpp // Purpose: wxScrolledWindow implementation // Author: Robert Roebling // Modified by: Ron Lee // Vadim Zeitlin: removed 90% of duplicated common code // Created: 01/02/97 // RCS-ID: $Id: scrolwin.cpp 37063 2006-01-23 01:14:32Z MR $ // Copyright: (c) Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // ============================================================================ // declarations // ============================================================================ // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #include "wx/scrolwin.h" #include "wx/gtk1/private.h" // ============================================================================ // implementation // ============================================================================ // ---------------------------------------------------------------------------- // wxScrollHelper implementation // ---------------------------------------------------------------------------- void wxScrollHelperNative::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, int noUnitsX, int noUnitsY, int xPos, int yPos, bool noRefresh) { 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_win->m_hAdjust->value = m_xScrollPosition = xPos; m_win->m_vAdjust->value = m_yScrollPosition = yPos; // 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 ); int w = noUnitsX * pixelsPerUnitX; int h = noUnitsY * pixelsPerUnitY; m_targetWindow->SetVirtualSize( w ? w : wxDefaultCoord, h ? h : wxDefaultCoord); 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->m_hasScrolling = pixelsPerUnitX || pixelsPerUnitY; } void wxScrollHelperNative::DoAdjustScrollbar(GtkAdjustment *adj, int pixelsPerLine, int winSize, int virtSize, int *pos, int *lines, int *linesPerPage) { if ( pixelsPerLine == 0 ) { adj->upper = 1.0; adj->page_increment = 1.0; adj->page_size = 1.0; } else // we do have scrollbar { adj->upper = (virtSize + pixelsPerLine - 1) / pixelsPerLine; adj->page_size = winSize / pixelsPerLine; adj->page_increment = winSize / pixelsPerLine; // Special case. When client and virtual size are very close but // the client is big enough, kill scrollbar. if ((adj->page_size < adj->upper) && (winSize >= virtSize)) adj->page_size += 1.0; // If the scrollbar hits the right side, move the window // right to keep it from over extending. if ( !wxIsNullDouble(adj->value) && (adj->value + adj->page_size > adj->upper) ) { adj->value = adj->upper - adj->page_size; if (adj->value < 0.0) adj->value = 0.0; if ( m_win->GetChildren().empty() ) { // This is enough without child windows *pos = (int)adj->value; } else { // We need to actually scroll window gtk_signal_emit_by_name( GTK_OBJECT(adj), "value_changed" ); } } } *lines = (int)(adj->upper + 0.5); *linesPerPage = (int)(adj->page_increment + 0.5); gtk_signal_emit_by_name( GTK_OBJECT(adj), "changed" ); } void wxScrollHelperNative::AdjustScrollbars() { int w, h; int vw, vh; m_targetWindow->GetClientSize( &w, &h ); m_targetWindow->GetVirtualSize( &vw, &vh ); DoAdjustScrollbar(m_win->m_hAdjust, m_xScrollPixelsPerLine, w, vw, &m_xScrollPosition, &m_xScrollLines, &m_xScrollLinesPerPage); DoAdjustScrollbar(m_win->m_vAdjust, m_yScrollPixelsPerLine, h, vh, &m_yScrollPosition, &m_yScrollLines, &m_yScrollLinesPerPage); } void wxScrollHelperNative::DoScroll(int orient, GtkAdjustment *adj, int pos, int pixelsPerLine, int *posOld) { if ( pos != -1 && pos != *posOld && pixelsPerLine ) { int max = (int)(adj->upper - adj->page_size + 0.5); if (max < 0) max = 0; if (pos > max) pos = max; if (pos < 0) pos = 0; adj->value = pos; int diff = (*posOld - pos)*pixelsPerLine; m_targetWindow->ScrollWindow(orient == wxHORIZONTAL ? diff : 0, orient == wxHORIZONTAL ? 0 : diff); *posOld = pos; m_win->GtkUpdateScrollbar(orient); } } void wxScrollHelperNative::Scroll( int x_pos, int y_pos ) { wxCHECK_RET( m_targetWindow != 0, _T("No target window") ); DoScroll(wxHORIZONTAL, m_win->m_hAdjust, x_pos, m_xScrollPixelsPerLine, &m_xScrollPosition); DoScroll(wxVERTICAL, m_win->m_vAdjust, y_pos, m_yScrollPixelsPerLine, &m_yScrollPosition); }