1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        gtk/scrolwin.cpp 
   3 // Purpose:     wxScrolledWindow implementation 
   4 // Author:      Robert Roebling 
   5 // Modified by: Ron Lee 
   6 //              Vadim Zeitlin: removed 90% of duplicated common code 
   9 // Copyright:   (c) Robert Roebling 
  10 // Licence:     wxWindows licence 
  11 ///////////////////////////////////////////////////////////////////////////// 
  13 // For compilers that support precompilation, includes "wx.h". 
  14 #include "wx/wxprec.h" 
  20 #include "wx/scrolwin.h" 
  24 // ---------------------------------------------------------------------------- 
  25 // wxScrollHelper implementation 
  26 // ---------------------------------------------------------------------------- 
  28 void wxScrollHelper::SetScrollbars(int pixelsPerUnitX
, int pixelsPerUnitY
, 
  29                                    int noUnitsX
, int noUnitsY
, 
  33     m_win
->m_scrollBar
[wxWindow::ScrollDir_Horz
]->adjustment
->value 
= xPos
; 
  34     m_win
->m_scrollBar
[wxWindow::ScrollDir_Vert
]->adjustment
->value 
= yPos
; 
  35     base_type::SetScrollbars( 
  36         pixelsPerUnitX
, pixelsPerUnitY
, noUnitsX
, noUnitsY
, xPos
, yPos
, noRefresh
); 
  39 void wxScrollHelper::DoAdjustScrollbar(GtkRange
* range
, 
  52     if (pixelsPerLine 
> 0 && winSize 
> 0 && winSize 
< virtSize
) 
  54         upper 
= (virtSize 
+ pixelsPerLine 
- 1) / pixelsPerLine
; 
  55         page_size 
= winSize 
/ pixelsPerLine
; 
  57         *linesPerPage 
= page_size
; 
  61         // GtkRange won't allow upper == lower, so for disabled state use [0,1] 
  62         //   with a page size of 1. This will also clamp position to 0. 
  69     GtkAdjustment
* adj 
= range
->adjustment
; 
  70     adj
->step_increment 
= 1; 
  72     adj
->page_size 
= page_size
; 
  73     gtk_range_set_range(range
, 0, upper
); 
  75     // ensure that the scroll position is always in valid range 
  80 void wxScrollHelper::AdjustScrollbars() 
  83     m_targetWindow
->GetVirtualSize(&vw
, &vh
); 
  86     const wxSize availSize 
= GetSizeAvailableForScrollTarget( 
  87         m_win
->GetSize() - m_win
->GetWindowBorderSize()); 
  88     if ( availSize
.x 
>= vw 
&& availSize
.y 
>= vh 
) 
  93         // we know that the scrollbars will be removed 
  94         DoAdjustHScrollbar(w
, vw
); 
  95         DoAdjustVScrollbar(h
, vh
); 
 100     m_targetWindow
->GetClientSize(&w
, NULL
); 
 101     DoAdjustHScrollbar(w
, vw
); 
 103     m_targetWindow
->GetClientSize(NULL
, &h
); 
 104     DoAdjustVScrollbar(h
, vh
); 
 107     m_targetWindow
->GetClientSize(&w
, NULL
); 
 110         // It is necessary to repeat the calculations in this case to avoid an 
 111         // observed infinite series of size events, involving alternating 
 112         // changes in visibility of the scrollbars. 
 113         // At this point, GTK+ has already queued a resize, which will cause 
 114         // AdjustScrollbars() to be called again. If the scrollbar visibility 
 115         // is not correct before then, yet another resize will occur, possibly 
 116         // leading to an unending series if the sizes are just right. 
 117         DoAdjustHScrollbar(w
, vw
); 
 119         m_targetWindow
->GetClientSize(NULL
, &h
); 
 120         DoAdjustVScrollbar(h
, vh
); 
 124 void wxScrollHelper::DoScrollOneDir(int orient
, 
 129     if ( pos 
!= -1 && pos 
!= *posOld 
&& pixelsPerLine 
) 
 131         m_win
->SetScrollPos(orient
, pos
); 
 132         pos 
= m_win
->GetScrollPos(orient
); 
 134         int diff 
= (*posOld 
- pos
)*pixelsPerLine
; 
 135         m_targetWindow
->ScrollWindow(orient 
== wxHORIZONTAL 
? diff 
: 0, 
 136                                      orient 
== wxHORIZONTAL 
? 0 : diff
); 
 142 void wxScrollHelper::DoScroll( int x_pos
, int y_pos 
) 
 144     wxCHECK_RET( m_targetWindow 
!= 0, wxT("No target window") ); 
 146     DoScrollOneDir(wxHORIZONTAL
, x_pos
, m_xScrollPixelsPerLine
, &m_xScrollPosition
); 
 147     DoScrollOneDir(wxVERTICAL
, y_pos
, m_yScrollPixelsPerLine
, &m_yScrollPosition
); 
 150 // ---------------------------------------------------------------------------- 
 151 // scrollbars visibility 
 152 // ---------------------------------------------------------------------------- 
 157 GtkPolicyType 
GtkPolicyFromWX(wxScrollbarVisibility visibility
) 
 159     GtkPolicyType policy
; 
 160     switch ( visibility 
) 
 162         case wxSHOW_SB_NEVER
: 
 163             policy 
= GTK_POLICY_NEVER
; 
 166         case wxSHOW_SB_DEFAULT
: 
 167             policy 
= GTK_POLICY_AUTOMATIC
; 
 171             wxFAIL_MSG( wxS("unknown scrollbar visibility") ); 
 174         case wxSHOW_SB_ALWAYS
: 
 175             policy 
= GTK_POLICY_ALWAYS
; 
 182 } // anonymous namespace 
 184 void wxScrollHelper::DoShowScrollbars(wxScrollbarVisibility horz
, 
 185                                       wxScrollbarVisibility vert
) 
 187     GtkScrolledWindow 
* const scrolled 
= GTK_SCROLLED_WINDOW(m_win
->m_widget
); 
 188     wxCHECK_RET( scrolled
, "window must be created" ); 
 190     gtk_scrolled_window_set_policy(scrolled
, 
 191                                    GtkPolicyFromWX(horz
), 
 192                                    GtkPolicyFromWX(vert
));