From 30954328be6e8261886c60cf509cbf303fd279bf Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Sun, 29 Apr 2001 15:27:57 +0000 Subject: [PATCH] wxScrolledWindow is now a native widget under GTK. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@9928 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- distrib/msw/tmake/filelist.txt | 4 +- include/wx/gtk/scrolwin.h | 139 +++++++++ include/wx/gtk1/scrolwin.h | 139 +++++++++ include/wx/scrolwin.h | 4 + src/generic/listctrl.cpp | 5 +- src/gtk/files.lst | 2 +- src/gtk/scrolwin.cpp | 550 +++++++++++++++++++++++++++++++++ src/gtk1/files.lst | 2 +- src/gtk1/scrolwin.cpp | 550 +++++++++++++++++++++++++++++++++ 9 files changed, 1391 insertions(+), 4 deletions(-) create mode 100644 include/wx/gtk/scrolwin.h create mode 100644 include/wx/gtk1/scrolwin.h create mode 100644 src/gtk/scrolwin.cpp create mode 100644 src/gtk1/scrolwin.cpp diff --git a/distrib/msw/tmake/filelist.txt b/distrib/msw/tmake/filelist.txt index cab3542f6b..88958d7bea 100644 --- a/distrib/msw/tmake/filelist.txt +++ b/distrib/msw/tmake/filelist.txt @@ -90,7 +90,7 @@ prop.cpp G propform.cpp G proplist.cpp G sashwin.cpp G -scrolwin.cpp G +scrolwin.cpp G R splash.cpp G splitter.cpp G statline.cpp G U,R,P @@ -374,6 +374,7 @@ radiobox.cpp R radiobut.cpp R region.cpp R scrolbar.cpp R +scrolwin.cpp R settings.cpp R slider.cpp R spinbutt.cpp R @@ -806,6 +807,7 @@ radiobox.h K radiobut.h K region.h K scrolbar.h K +scrolwin.h K settings.h K slider.h K spinbutt.h K diff --git a/include/wx/gtk/scrolwin.h b/include/wx/gtk/scrolwin.h new file mode 100644 index 0000000000..f28f92c8d3 --- /dev/null +++ b/include/wx/gtk/scrolwin.h @@ -0,0 +1,139 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/generic/scrolwin.h +// Purpose: wxScrolledWindow class +// Author: Robert Roebling +// Modified by: +// Created: 01/02/97 +// RCS-ID: $Id$ +// Copyright: (c) Robert Roebling +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_GTK_SCROLLWIN_H_ +#define _WX_GTK_SCROLLWIN_H_ + +#ifdef __GNUG__ + #pragma interface "scrolwin.h" +#endif + +// ---------------------------------------------------------------------------- +// headers and constants +// ---------------------------------------------------------------------------- + +#include "wx/window.h" +#include "wx/panel.h" + +WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr; + +// default scrolled window style +#define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL) + +// ---------------------------------------------------------------------------- +// wxScrolledWindow +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxScrolledWindow : public wxPanel +{ +public: + wxScrolledWindow(); + wxScrolledWindow(wxWindow *parent, + wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxScrolledWindowStyle, + const wxString& name = wxPanelNameStr) + { + Create(parent, id, pos, size, style, name); + } + + ~wxScrolledWindow(); + + bool Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxScrolledWindowStyle, + const wxString& name = wxPanelNameStr); + + // Normally the wxScrolledWindow will scroll itself, but in + // some rare occasions you might want it to scroll another + // window (e.g. a child of it in order to scroll only a portion + // the area between the scrollbars (spreadsheet: only cell area + // will move). + virtual void SetTargetWindow( wxWindow *target ); + virtual wxWindow *GetTargetWindow(); + + // Number of pixels per user unit (0 or -1 for no scrollbar) + // Length of virtual canvas in user units + // Length of page in user units + virtual void SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, + int noUnitsX, int noUnitsY, + int xPos = 0, int yPos = 0, + bool noRefresh = FALSE ); + + // Physically scroll the window + virtual void Scroll(int x_pos, int y_pos); + + int GetScrollPageSize(int orient) const; + void SetScrollPageSize(int orient, int pageSize); + + virtual void GetScrollPixelsPerUnit(int *x_unit, int *y_unit) const; + + // Enable/disable Windows scrolling in either direction. + // If TRUE, wxWindows scrolls the canvas and only a bit of + // the canvas is invalidated; no Clear() is necessary. + // If FALSE, the whole canvas is invalidated and a Clear() is + // necessary. Disable for when the scroll increment is used + // to actually scroll a non-constant distance + virtual void EnableScrolling(bool x_scrolling, bool y_scrolling); + + // Get the view start + virtual void GetViewStart(int *x, int *y) const; + // Compatibility + void ViewStart(int *x, int *y) const + { GetViewStart( x, y ); } + + // Actual size in pixels when scrolling is taken into account + virtual void GetVirtualSize(int *x, int *y) const; + + virtual void CalcScrolledPosition(int x, int y, int *xx, int *yy) const; + virtual void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const; + + // Override this function to draw the graphic (or just process EVT_PAINT) + virtual void OnDraw(wxDC& WXUNUSED(dc)) {} + + // Override this function if you don't want to have wxScrolledWindow + // automatically change the origin according to the scroll position. + virtual void PrepareDC(wxDC& dc); + + // Adjust the scrollbars + virtual void AdjustScrollbars(); + + // implementation from now on + void OnSize(wxSizeEvent& event); + void OnPaint(wxPaintEvent& event); + void OnChar(wxKeyEvent& event); + + void GtkVScroll( float value ); + void GtkHScroll( float value ); + +protected: + wxWindow *m_targetWindow; + int m_xScrollPixelsPerLine; + int m_yScrollPixelsPerLine; + bool m_xScrollingEnabled; + bool m_yScrollingEnabled; + int m_xScrollPosition; + int m_yScrollPosition; + int m_xScrollLines; + int m_yScrollLines; + int m_xScrollLinesPerPage; + int m_yScrollLinesPerPage; + +private: + DECLARE_EVENT_TABLE() + DECLARE_ABSTRACT_CLASS(wxScrolledWindow) +}; + +#endif + // _WX_GTK_SCROLLWIN_H_ diff --git a/include/wx/gtk1/scrolwin.h b/include/wx/gtk1/scrolwin.h new file mode 100644 index 0000000000..f28f92c8d3 --- /dev/null +++ b/include/wx/gtk1/scrolwin.h @@ -0,0 +1,139 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/generic/scrolwin.h +// Purpose: wxScrolledWindow class +// Author: Robert Roebling +// Modified by: +// Created: 01/02/97 +// RCS-ID: $Id$ +// Copyright: (c) Robert Roebling +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_GTK_SCROLLWIN_H_ +#define _WX_GTK_SCROLLWIN_H_ + +#ifdef __GNUG__ + #pragma interface "scrolwin.h" +#endif + +// ---------------------------------------------------------------------------- +// headers and constants +// ---------------------------------------------------------------------------- + +#include "wx/window.h" +#include "wx/panel.h" + +WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr; + +// default scrolled window style +#define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL) + +// ---------------------------------------------------------------------------- +// wxScrolledWindow +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxScrolledWindow : public wxPanel +{ +public: + wxScrolledWindow(); + wxScrolledWindow(wxWindow *parent, + wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxScrolledWindowStyle, + const wxString& name = wxPanelNameStr) + { + Create(parent, id, pos, size, style, name); + } + + ~wxScrolledWindow(); + + bool Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxScrolledWindowStyle, + const wxString& name = wxPanelNameStr); + + // Normally the wxScrolledWindow will scroll itself, but in + // some rare occasions you might want it to scroll another + // window (e.g. a child of it in order to scroll only a portion + // the area between the scrollbars (spreadsheet: only cell area + // will move). + virtual void SetTargetWindow( wxWindow *target ); + virtual wxWindow *GetTargetWindow(); + + // Number of pixels per user unit (0 or -1 for no scrollbar) + // Length of virtual canvas in user units + // Length of page in user units + virtual void SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, + int noUnitsX, int noUnitsY, + int xPos = 0, int yPos = 0, + bool noRefresh = FALSE ); + + // Physically scroll the window + virtual void Scroll(int x_pos, int y_pos); + + int GetScrollPageSize(int orient) const; + void SetScrollPageSize(int orient, int pageSize); + + virtual void GetScrollPixelsPerUnit(int *x_unit, int *y_unit) const; + + // Enable/disable Windows scrolling in either direction. + // If TRUE, wxWindows scrolls the canvas and only a bit of + // the canvas is invalidated; no Clear() is necessary. + // If FALSE, the whole canvas is invalidated and a Clear() is + // necessary. Disable for when the scroll increment is used + // to actually scroll a non-constant distance + virtual void EnableScrolling(bool x_scrolling, bool y_scrolling); + + // Get the view start + virtual void GetViewStart(int *x, int *y) const; + // Compatibility + void ViewStart(int *x, int *y) const + { GetViewStart( x, y ); } + + // Actual size in pixels when scrolling is taken into account + virtual void GetVirtualSize(int *x, int *y) const; + + virtual void CalcScrolledPosition(int x, int y, int *xx, int *yy) const; + virtual void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const; + + // Override this function to draw the graphic (or just process EVT_PAINT) + virtual void OnDraw(wxDC& WXUNUSED(dc)) {} + + // Override this function if you don't want to have wxScrolledWindow + // automatically change the origin according to the scroll position. + virtual void PrepareDC(wxDC& dc); + + // Adjust the scrollbars + virtual void AdjustScrollbars(); + + // implementation from now on + void OnSize(wxSizeEvent& event); + void OnPaint(wxPaintEvent& event); + void OnChar(wxKeyEvent& event); + + void GtkVScroll( float value ); + void GtkHScroll( float value ); + +protected: + wxWindow *m_targetWindow; + int m_xScrollPixelsPerLine; + int m_yScrollPixelsPerLine; + bool m_xScrollingEnabled; + bool m_yScrollingEnabled; + int m_xScrollPosition; + int m_yScrollPosition; + int m_xScrollLines; + int m_yScrollLines; + int m_xScrollLinesPerPage; + int m_yScrollLinesPerPage; + +private: + DECLARE_EVENT_TABLE() + DECLARE_ABSTRACT_CLASS(wxScrolledWindow) +}; + +#endif + // _WX_GTK_SCROLLWIN_H_ diff --git a/include/wx/scrolwin.h b/include/wx/scrolwin.h index 44298184bb..86457a8b50 100644 --- a/include/wx/scrolwin.h +++ b/include/wx/scrolwin.h @@ -1,7 +1,11 @@ #ifndef _WX_SCROLWIN_H_BASE_ #define _WX_SCROLWIN_H_BASE_ +#ifdef __WXGTK__ +#include "wx/gtk/scrolwin.h" +#else #include "wx/generic/scrolwin.h" +#endif #endif // _WX_SCROLWIN_H_BASE_ diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 2f69514f23..c985d51346 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -3129,7 +3129,10 @@ void wxListMainWindow::SortItems( wxListCtrlCompare fn, long data ) void wxListMainWindow::OnScroll(wxScrollWinEvent& event) { - wxScrolledWindow::OnScroll( event ) ; +#ifndef __WXGTK__ + wxScrolledWindow::OnScroll( event ) ; +#endif + #if wxUSE_GENERIC_LIST_EXTENSIONS if (event.GetOrientation() == wxHORIZONTAL && ( m_mode & wxLC_REPORT )) diff --git a/src/gtk/files.lst b/src/gtk/files.lst index 9f1acd4669..e56c40a7f8 100644 --- a/src/gtk/files.lst +++ b/src/gtk/files.lst @@ -31,7 +31,6 @@ ALL_SOURCES = \ generic/propform.cpp \ generic/proplist.cpp \ generic/sashwin.cpp \ - generic/scrolwin.cpp \ generic/splash.cpp \ generic/splitter.cpp \ generic/statusbr.cpp \ @@ -190,6 +189,7 @@ ALL_SOURCES = \ gtk/radiobut.cpp \ gtk/region.cpp \ gtk/scrolbar.cpp \ + gtk/scrolwin.cpp \ gtk/settings.cpp \ gtk/slider.cpp \ gtk/spinbutt.cpp \ diff --git a/src/gtk/scrolwin.cpp b/src/gtk/scrolwin.cpp new file mode 100644 index 0000000000..2d64124e7c --- /dev/null +++ b/src/gtk/scrolwin.cpp @@ -0,0 +1,550 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: generic/scrolwin.cpp +// Purpose: wxScrolledWindow implementation +// Author: Julian Smart +// Modified by: +// Created: 01/02/97 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart and Markus Holzem +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "scrolwin.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/utils.h" +#include "wx/dcclient.h" + +#include "wx/gtk/scrolwin.h" +#include "wx/panel.h" + +#include +#include "wx/gtk/win_gtk.h" + +// ---------------------------------------------------------------------------- +// event tables +// ---------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(wxScrolledWindow, wxPanel) + EVT_SIZE(wxScrolledWindow::OnSize) + EVT_PAINT(wxScrolledWindow::OnPaint) + EVT_CHAR(wxScrolledWindow::OnChar) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel) + +// ============================================================================ +// implementation +// ============================================================================ + +//----------------------------------------------------------------------------- +// data +//----------------------------------------------------------------------------- + +extern bool g_blockEventsOnDrag; + +//----------------------------------------------------------------------------- +// idle system +//----------------------------------------------------------------------------- + +extern void wxapp_install_idle_handler(); +extern bool g_isIdle; + +//----------------------------------------------------------------------------- +// "value_changed" from m_vAdjust +//----------------------------------------------------------------------------- + +static void gtk_scrolled_window_vscroll_callback( GtkAdjustment *adjust, wxScrolledWindow *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + if (g_blockEventsOnDrag) return; + + if (!win->m_hasVMT) return; + + win->GtkVScroll( adjust->value ); +} + +//----------------------------------------------------------------------------- +// "value_changed" from m_hAdjust +//----------------------------------------------------------------------------- + +static void gtk_scrolled_window_hscroll_callback( GtkAdjustment *adjust, wxScrolledWindow *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + if (g_blockEventsOnDrag) return; + if (!win->m_hasVMT) return; + + win->GtkHScroll( adjust->value ); +} + +//----------------------------------------------------------------------------- +// InsertChild for wxScrolledWindow +//----------------------------------------------------------------------------- + +static void wxInsertChildInScrolledWindow( wxWindow* parent, wxWindow* child ) +{ + /* the window might have been scrolled already, do we + have to adapt the position */ + GtkPizza *pizza = GTK_PIZZA(parent->m_wxwindow); + child->m_x += pizza->xoffset; + child->m_y += pizza->yoffset; + + gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow), + GTK_WIDGET(child->m_widget), + child->m_x, + child->m_y, + child->m_width, + child->m_height ); +} + +// ---------------------------------------------------------------------------- +// wxScrolledWindow creation +// ---------------------------------------------------------------------------- + +wxScrolledWindow::wxScrolledWindow() +{ + m_xScrollPixelsPerLine = 0; + m_yScrollPixelsPerLine = 0; + m_xScrollingEnabled = TRUE; + 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; +} + +bool wxScrolledWindow::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + if (!PreCreation( parent, pos, size ) || + !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) + { + wxFAIL_MSG( wxT("wxWindow creation failed") ); + return FALSE; + } + + m_insertCallback = wxInsertChildInScrolledWindow; + + m_xScrollPixelsPerLine = 0; + m_yScrollPixelsPerLine = 0; + m_xScrollingEnabled = TRUE; + m_yScrollingEnabled = TRUE; + m_xScrollPosition = 0; + m_yScrollPosition = 0; + m_xScrollLines = 0; + m_yScrollLines = 0; + m_xScrollLinesPerPage = 0; + m_yScrollLinesPerPage = 0; + + m_targetWindow = this; + + m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); + GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); + + GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget); + + GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget) ); + scroll_class->scrollbar_spacing = 0; + + gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); + + m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(scrolledWindow->hscrollbar) ); + m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(scrolledWindow->vscrollbar) ); + + m_wxwindow = gtk_pizza_new(); + + gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); + + GtkPizza *pizza = GTK_PIZZA(m_wxwindow); + + if (HasFlag(wxRAISED_BORDER)) + { + gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_OUT ); + } + else if (HasFlag(wxSUNKEN_BORDER)) + { + gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_IN ); + } + else if (HasFlag(wxSIMPLE_BORDER)) + { + gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_THIN ); + } + else + { + gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_NONE ); + } + + GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); + m_acceptsFocus = TRUE; + + // I _really_ don't want scrollbars in the beginning + m_vAdjust->lower = 0.0; + m_vAdjust->upper = 1.0; + m_vAdjust->value = 0.0; + m_vAdjust->step_increment = 1.0; + m_vAdjust->page_increment = 1.0; + gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" ); + m_hAdjust->lower = 0.0; + m_hAdjust->upper = 1.0; + m_hAdjust->value = 0.0; + m_hAdjust->step_increment = 1.0; + m_hAdjust->page_increment = 1.0; + gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); + + // these handlers get notified when screen updates are required either when + // scrolling or when the window size (and therefore scrollbar configuration) + // has changed + gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed", + (GtkSignalFunc) gtk_scrolled_window_hscroll_callback, (gpointer) this ); + gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed", + (GtkSignalFunc) gtk_scrolled_window_vscroll_callback, (gpointer) this ); + + gtk_widget_show( m_wxwindow ); + + if (m_parent) + m_parent->DoAddChild( this ); + + PostCreation(); + + Show( TRUE ); + + return TRUE; +} + +wxScrolledWindow::~wxScrolledWindow() +{ +} + +// ---------------------------------------------------------------------------- +// setting scrolling parameters +// ---------------------------------------------------------------------------- + +/* + * 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 ) +{ + m_xScrollPixelsPerLine = pixelsPerUnitX; + m_yScrollPixelsPerLine = pixelsPerUnitY; + m_xScrollPosition = xPos; + m_yScrollPosition = yPos; + m_xScrollLines = noUnitsX; + m_yScrollLines = noUnitsY; + + m_hAdjust->lower = 0.0; + m_hAdjust->upper = noUnitsX; + m_hAdjust->value = xPos; + m_hAdjust->step_increment = 1.0; + m_hAdjust->page_increment = 1.0; + + m_vAdjust->lower = 0.0; + m_vAdjust->upper = noUnitsY; + m_vAdjust->value = yPos; + m_vAdjust->step_increment = 1.0; + m_vAdjust->page_increment = 1.0; + + AdjustScrollbars(); +} + +void wxScrolledWindow::AdjustScrollbars() +{ + int w, h; + m_targetWindow->GetClientSize( &w, &h ); + + if (m_xScrollPixelsPerLine == 0) + m_hAdjust->page_size = 1.0; + else + m_hAdjust->page_size = (w / m_xScrollPixelsPerLine); + + if (m_yScrollPixelsPerLine == 0) + m_vAdjust->page_size = 1.0; + else + m_vAdjust->page_size = (h / m_yScrollPixelsPerLine); + + gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" ); + gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); +} + +// ---------------------------------------------------------------------------- +// target window handling +// ---------------------------------------------------------------------------- + +void wxScrolledWindow::SetTargetWindow( wxWindow *target ) +{ + wxASSERT_MSG( target, wxT("target window must not be NULL") ); + m_targetWindow = target; +} + +wxWindow *wxScrolledWindow::GetTargetWindow() +{ + return m_targetWindow; +} + +// Override this function if you don't want to have wxScrolledWindow +// automatically change the origin according to the scroll position. +void wxScrolledWindow::PrepareDC(wxDC& dc) +{ + dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine, + -m_yScrollPosition * m_yScrollPixelsPerLine ); +} + +void wxScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const +{ + if ( x_unit ) + *x_unit = m_xScrollPixelsPerLine; + if ( y_unit ) + *y_unit = m_yScrollPixelsPerLine; +} + +int wxScrolledWindow::GetScrollPageSize(int orient) const +{ + if ( orient == wxHORIZONTAL ) + return m_xScrollLinesPerPage; + else + return m_yScrollLinesPerPage; +} + +void wxScrolledWindow::SetScrollPageSize(int orient, int pageSize) +{ + if ( orient == wxHORIZONTAL ) + m_xScrollLinesPerPage = pageSize; + else + m_yScrollLinesPerPage = pageSize; +} + +/* + * Scroll to given position (scroll position, not pixel position) + */ +void wxScrolledWindow::Scroll( int x_pos, int y_pos ) +{ + if (!m_targetWindow) + return; + + if (((x_pos == -1) || (x_pos == m_xScrollPosition)) && + ((y_pos == -1) || (y_pos == m_yScrollPosition))) return; + + int w, h; + m_targetWindow->GetClientSize(&w, &h); + + if ((x_pos != -1) && (m_xScrollPixelsPerLine)) + { + int old_x = m_xScrollPosition; + m_xScrollPosition = x_pos; + + // Calculate page size i.e. number of scroll units you get on the + // current client window + int noPagePositions = (int) ( (w/(double)m_xScrollPixelsPerLine) + 0.5 ); + if (noPagePositions < 1) noPagePositions = 1; + + // Correct position if greater than extent of canvas minus + // the visible portion of it or if below zero + m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition ); + m_xScrollPosition = wxMax( 0, m_xScrollPosition ); + + if (old_x != m_xScrollPosition) { + m_targetWindow->ScrollWindow( (old_x-m_xScrollPosition)*m_xScrollPixelsPerLine, 0 ); + } + } + if ((y_pos != -1) && (m_yScrollPixelsPerLine)) + { + int old_y = m_yScrollPosition; + m_yScrollPosition = y_pos; + + // Calculate page size i.e. number of scroll units you get on the + // current client window + int noPagePositions = (int) ( (h/(double)m_yScrollPixelsPerLine) + 0.5 ); + if (noPagePositions < 1) noPagePositions = 1; + + // Correct position if greater than extent of canvas minus + // the visible portion of it or if below zero + m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition ); + m_yScrollPosition = wxMax( 0, m_yScrollPosition ); + + if (old_y != m_yScrollPosition) { + m_targetWindow->ScrollWindow( 0, (old_y-m_yScrollPosition)*m_yScrollPixelsPerLine ); + } + } +} + +void wxScrolledWindow::GtkVScroll( float value ) +{ + Scroll( -1, (int)(value+0.5) ); +} + +void wxScrolledWindow::GtkHScroll( float value ) +{ + Scroll( (int)(value+0.5), -1 ); +} + +void wxScrolledWindow::EnableScrolling (bool x_scroll, bool y_scroll) +{ + m_xScrollingEnabled = x_scroll; + m_yScrollingEnabled = y_scroll; +} + +void wxScrolledWindow::GetVirtualSize (int *x, int *y) const +{ + if ( x ) + *x = m_xScrollPixelsPerLine * m_xScrollLines; + if ( y ) + *y = m_yScrollPixelsPerLine * m_yScrollLines; +} + +// Where the current view starts from +void wxScrolledWindow::GetViewStart (int *x, int *y) const +{ + if ( x ) + *x = m_xScrollPosition; + if ( y ) + *y = m_yScrollPosition; +} + +void wxScrolledWindow::CalcScrolledPosition(int x, int y, int *xx, int *yy) const +{ + if ( xx ) + *xx = x - m_xScrollPosition * m_xScrollPixelsPerLine; + if ( yy ) + *yy = y - m_yScrollPosition * m_yScrollPixelsPerLine; +} + +void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const +{ + if ( xx ) + *xx = x + m_xScrollPosition * m_xScrollPixelsPerLine; + if ( yy ) + *yy = y + m_yScrollPosition * m_yScrollPixelsPerLine; +} + +// ---------------------------------------------------------------------------- +// event handlers +// ---------------------------------------------------------------------------- + +// Default OnSize resets scrollbars, if any +void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event)) +{ +#if wxUSE_CONSTRAINTS + if (GetAutoLayout()) + Layout(); +#endif + + AdjustScrollbars(); +} + +// This calls OnDraw, having adjusted the origin according to the current +// scroll position +void wxScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event)) +{ + wxPaintDC dc(this); + PrepareDC(dc); + + OnDraw(dc); +} + +// kbd handling: notice that we use OnChar() and not OnKeyDown() for +// compatibility here - if we used OnKeyDown(), the programs which process +// arrows themselves in their OnChar() would never get the message and like +// this they always have the priority +void wxScrolledWindow::OnChar(wxKeyEvent& event) +{ + int stx, sty, // view origin + szx, szy, // view size (total) + clix, cliy; // view size (on screen) + + ViewStart(&stx, &sty); + GetClientSize(&clix, &cliy); + GetVirtualSize(&szx, &szy); + + if( m_xScrollPixelsPerLine ) + { + clix /= m_xScrollPixelsPerLine; + szx /= m_xScrollPixelsPerLine; + } + else + { + clix = 0; + szx = -1; + } + if( m_yScrollPixelsPerLine ) + { + cliy /= m_yScrollPixelsPerLine; + szy /= m_yScrollPixelsPerLine; + } + else + { + cliy = 0; + szy = -1; + } + + int dsty; + switch ( event.KeyCode() ) + { + case WXK_PAGEUP: + case WXK_PRIOR: + dsty = sty - (5 * cliy / 6); + Scroll(-1, (dsty == -1) ? 0 : dsty); + break; + + case WXK_PAGEDOWN: + case WXK_NEXT: + Scroll(-1, sty + (5 * cliy / 6)); + break; + + case WXK_HOME: + Scroll(0, event.ControlDown() ? 0 : -1); + break; + + case WXK_END: + Scroll(szx - clix, event.ControlDown() ? szy - cliy : -1); + break; + + case WXK_UP: + Scroll(-1, sty - 1); + break; + + case WXK_DOWN: + Scroll(-1, sty + 1); + break; + + case WXK_LEFT: + Scroll(stx - 1, -1); + break; + + case WXK_RIGHT: + Scroll(stx + 1, -1); + break; + + default: + // not for us + event.Skip(); + } +} diff --git a/src/gtk1/files.lst b/src/gtk1/files.lst index 9f1acd4669..e56c40a7f8 100644 --- a/src/gtk1/files.lst +++ b/src/gtk1/files.lst @@ -31,7 +31,6 @@ ALL_SOURCES = \ generic/propform.cpp \ generic/proplist.cpp \ generic/sashwin.cpp \ - generic/scrolwin.cpp \ generic/splash.cpp \ generic/splitter.cpp \ generic/statusbr.cpp \ @@ -190,6 +189,7 @@ ALL_SOURCES = \ gtk/radiobut.cpp \ gtk/region.cpp \ gtk/scrolbar.cpp \ + gtk/scrolwin.cpp \ gtk/settings.cpp \ gtk/slider.cpp \ gtk/spinbutt.cpp \ diff --git a/src/gtk1/scrolwin.cpp b/src/gtk1/scrolwin.cpp new file mode 100644 index 0000000000..2d64124e7c --- /dev/null +++ b/src/gtk1/scrolwin.cpp @@ -0,0 +1,550 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: generic/scrolwin.cpp +// Purpose: wxScrolledWindow implementation +// Author: Julian Smart +// Modified by: +// Created: 01/02/97 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart and Markus Holzem +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "scrolwin.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/utils.h" +#include "wx/dcclient.h" + +#include "wx/gtk/scrolwin.h" +#include "wx/panel.h" + +#include +#include "wx/gtk/win_gtk.h" + +// ---------------------------------------------------------------------------- +// event tables +// ---------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(wxScrolledWindow, wxPanel) + EVT_SIZE(wxScrolledWindow::OnSize) + EVT_PAINT(wxScrolledWindow::OnPaint) + EVT_CHAR(wxScrolledWindow::OnChar) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel) + +// ============================================================================ +// implementation +// ============================================================================ + +//----------------------------------------------------------------------------- +// data +//----------------------------------------------------------------------------- + +extern bool g_blockEventsOnDrag; + +//----------------------------------------------------------------------------- +// idle system +//----------------------------------------------------------------------------- + +extern void wxapp_install_idle_handler(); +extern bool g_isIdle; + +//----------------------------------------------------------------------------- +// "value_changed" from m_vAdjust +//----------------------------------------------------------------------------- + +static void gtk_scrolled_window_vscroll_callback( GtkAdjustment *adjust, wxScrolledWindow *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + if (g_blockEventsOnDrag) return; + + if (!win->m_hasVMT) return; + + win->GtkVScroll( adjust->value ); +} + +//----------------------------------------------------------------------------- +// "value_changed" from m_hAdjust +//----------------------------------------------------------------------------- + +static void gtk_scrolled_window_hscroll_callback( GtkAdjustment *adjust, wxScrolledWindow *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + if (g_blockEventsOnDrag) return; + if (!win->m_hasVMT) return; + + win->GtkHScroll( adjust->value ); +} + +//----------------------------------------------------------------------------- +// InsertChild for wxScrolledWindow +//----------------------------------------------------------------------------- + +static void wxInsertChildInScrolledWindow( wxWindow* parent, wxWindow* child ) +{ + /* the window might have been scrolled already, do we + have to adapt the position */ + GtkPizza *pizza = GTK_PIZZA(parent->m_wxwindow); + child->m_x += pizza->xoffset; + child->m_y += pizza->yoffset; + + gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow), + GTK_WIDGET(child->m_widget), + child->m_x, + child->m_y, + child->m_width, + child->m_height ); +} + +// ---------------------------------------------------------------------------- +// wxScrolledWindow creation +// ---------------------------------------------------------------------------- + +wxScrolledWindow::wxScrolledWindow() +{ + m_xScrollPixelsPerLine = 0; + m_yScrollPixelsPerLine = 0; + m_xScrollingEnabled = TRUE; + 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; +} + +bool wxScrolledWindow::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + if (!PreCreation( parent, pos, size ) || + !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) + { + wxFAIL_MSG( wxT("wxWindow creation failed") ); + return FALSE; + } + + m_insertCallback = wxInsertChildInScrolledWindow; + + m_xScrollPixelsPerLine = 0; + m_yScrollPixelsPerLine = 0; + m_xScrollingEnabled = TRUE; + m_yScrollingEnabled = TRUE; + m_xScrollPosition = 0; + m_yScrollPosition = 0; + m_xScrollLines = 0; + m_yScrollLines = 0; + m_xScrollLinesPerPage = 0; + m_yScrollLinesPerPage = 0; + + m_targetWindow = this; + + m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); + GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); + + GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget); + + GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget) ); + scroll_class->scrollbar_spacing = 0; + + gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); + + m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(scrolledWindow->hscrollbar) ); + m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(scrolledWindow->vscrollbar) ); + + m_wxwindow = gtk_pizza_new(); + + gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); + + GtkPizza *pizza = GTK_PIZZA(m_wxwindow); + + if (HasFlag(wxRAISED_BORDER)) + { + gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_OUT ); + } + else if (HasFlag(wxSUNKEN_BORDER)) + { + gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_IN ); + } + else if (HasFlag(wxSIMPLE_BORDER)) + { + gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_THIN ); + } + else + { + gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_NONE ); + } + + GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); + m_acceptsFocus = TRUE; + + // I _really_ don't want scrollbars in the beginning + m_vAdjust->lower = 0.0; + m_vAdjust->upper = 1.0; + m_vAdjust->value = 0.0; + m_vAdjust->step_increment = 1.0; + m_vAdjust->page_increment = 1.0; + gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" ); + m_hAdjust->lower = 0.0; + m_hAdjust->upper = 1.0; + m_hAdjust->value = 0.0; + m_hAdjust->step_increment = 1.0; + m_hAdjust->page_increment = 1.0; + gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); + + // these handlers get notified when screen updates are required either when + // scrolling or when the window size (and therefore scrollbar configuration) + // has changed + gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed", + (GtkSignalFunc) gtk_scrolled_window_hscroll_callback, (gpointer) this ); + gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed", + (GtkSignalFunc) gtk_scrolled_window_vscroll_callback, (gpointer) this ); + + gtk_widget_show( m_wxwindow ); + + if (m_parent) + m_parent->DoAddChild( this ); + + PostCreation(); + + Show( TRUE ); + + return TRUE; +} + +wxScrolledWindow::~wxScrolledWindow() +{ +} + +// ---------------------------------------------------------------------------- +// setting scrolling parameters +// ---------------------------------------------------------------------------- + +/* + * 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 ) +{ + m_xScrollPixelsPerLine = pixelsPerUnitX; + m_yScrollPixelsPerLine = pixelsPerUnitY; + m_xScrollPosition = xPos; + m_yScrollPosition = yPos; + m_xScrollLines = noUnitsX; + m_yScrollLines = noUnitsY; + + m_hAdjust->lower = 0.0; + m_hAdjust->upper = noUnitsX; + m_hAdjust->value = xPos; + m_hAdjust->step_increment = 1.0; + m_hAdjust->page_increment = 1.0; + + m_vAdjust->lower = 0.0; + m_vAdjust->upper = noUnitsY; + m_vAdjust->value = yPos; + m_vAdjust->step_increment = 1.0; + m_vAdjust->page_increment = 1.0; + + AdjustScrollbars(); +} + +void wxScrolledWindow::AdjustScrollbars() +{ + int w, h; + m_targetWindow->GetClientSize( &w, &h ); + + if (m_xScrollPixelsPerLine == 0) + m_hAdjust->page_size = 1.0; + else + m_hAdjust->page_size = (w / m_xScrollPixelsPerLine); + + if (m_yScrollPixelsPerLine == 0) + m_vAdjust->page_size = 1.0; + else + m_vAdjust->page_size = (h / m_yScrollPixelsPerLine); + + gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" ); + gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); +} + +// ---------------------------------------------------------------------------- +// target window handling +// ---------------------------------------------------------------------------- + +void wxScrolledWindow::SetTargetWindow( wxWindow *target ) +{ + wxASSERT_MSG( target, wxT("target window must not be NULL") ); + m_targetWindow = target; +} + +wxWindow *wxScrolledWindow::GetTargetWindow() +{ + return m_targetWindow; +} + +// Override this function if you don't want to have wxScrolledWindow +// automatically change the origin according to the scroll position. +void wxScrolledWindow::PrepareDC(wxDC& dc) +{ + dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine, + -m_yScrollPosition * m_yScrollPixelsPerLine ); +} + +void wxScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const +{ + if ( x_unit ) + *x_unit = m_xScrollPixelsPerLine; + if ( y_unit ) + *y_unit = m_yScrollPixelsPerLine; +} + +int wxScrolledWindow::GetScrollPageSize(int orient) const +{ + if ( orient == wxHORIZONTAL ) + return m_xScrollLinesPerPage; + else + return m_yScrollLinesPerPage; +} + +void wxScrolledWindow::SetScrollPageSize(int orient, int pageSize) +{ + if ( orient == wxHORIZONTAL ) + m_xScrollLinesPerPage = pageSize; + else + m_yScrollLinesPerPage = pageSize; +} + +/* + * Scroll to given position (scroll position, not pixel position) + */ +void wxScrolledWindow::Scroll( int x_pos, int y_pos ) +{ + if (!m_targetWindow) + return; + + if (((x_pos == -1) || (x_pos == m_xScrollPosition)) && + ((y_pos == -1) || (y_pos == m_yScrollPosition))) return; + + int w, h; + m_targetWindow->GetClientSize(&w, &h); + + if ((x_pos != -1) && (m_xScrollPixelsPerLine)) + { + int old_x = m_xScrollPosition; + m_xScrollPosition = x_pos; + + // Calculate page size i.e. number of scroll units you get on the + // current client window + int noPagePositions = (int) ( (w/(double)m_xScrollPixelsPerLine) + 0.5 ); + if (noPagePositions < 1) noPagePositions = 1; + + // Correct position if greater than extent of canvas minus + // the visible portion of it or if below zero + m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition ); + m_xScrollPosition = wxMax( 0, m_xScrollPosition ); + + if (old_x != m_xScrollPosition) { + m_targetWindow->ScrollWindow( (old_x-m_xScrollPosition)*m_xScrollPixelsPerLine, 0 ); + } + } + if ((y_pos != -1) && (m_yScrollPixelsPerLine)) + { + int old_y = m_yScrollPosition; + m_yScrollPosition = y_pos; + + // Calculate page size i.e. number of scroll units you get on the + // current client window + int noPagePositions = (int) ( (h/(double)m_yScrollPixelsPerLine) + 0.5 ); + if (noPagePositions < 1) noPagePositions = 1; + + // Correct position if greater than extent of canvas minus + // the visible portion of it or if below zero + m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition ); + m_yScrollPosition = wxMax( 0, m_yScrollPosition ); + + if (old_y != m_yScrollPosition) { + m_targetWindow->ScrollWindow( 0, (old_y-m_yScrollPosition)*m_yScrollPixelsPerLine ); + } + } +} + +void wxScrolledWindow::GtkVScroll( float value ) +{ + Scroll( -1, (int)(value+0.5) ); +} + +void wxScrolledWindow::GtkHScroll( float value ) +{ + Scroll( (int)(value+0.5), -1 ); +} + +void wxScrolledWindow::EnableScrolling (bool x_scroll, bool y_scroll) +{ + m_xScrollingEnabled = x_scroll; + m_yScrollingEnabled = y_scroll; +} + +void wxScrolledWindow::GetVirtualSize (int *x, int *y) const +{ + if ( x ) + *x = m_xScrollPixelsPerLine * m_xScrollLines; + if ( y ) + *y = m_yScrollPixelsPerLine * m_yScrollLines; +} + +// Where the current view starts from +void wxScrolledWindow::GetViewStart (int *x, int *y) const +{ + if ( x ) + *x = m_xScrollPosition; + if ( y ) + *y = m_yScrollPosition; +} + +void wxScrolledWindow::CalcScrolledPosition(int x, int y, int *xx, int *yy) const +{ + if ( xx ) + *xx = x - m_xScrollPosition * m_xScrollPixelsPerLine; + if ( yy ) + *yy = y - m_yScrollPosition * m_yScrollPixelsPerLine; +} + +void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const +{ + if ( xx ) + *xx = x + m_xScrollPosition * m_xScrollPixelsPerLine; + if ( yy ) + *yy = y + m_yScrollPosition * m_yScrollPixelsPerLine; +} + +// ---------------------------------------------------------------------------- +// event handlers +// ---------------------------------------------------------------------------- + +// Default OnSize resets scrollbars, if any +void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event)) +{ +#if wxUSE_CONSTRAINTS + if (GetAutoLayout()) + Layout(); +#endif + + AdjustScrollbars(); +} + +// This calls OnDraw, having adjusted the origin according to the current +// scroll position +void wxScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event)) +{ + wxPaintDC dc(this); + PrepareDC(dc); + + OnDraw(dc); +} + +// kbd handling: notice that we use OnChar() and not OnKeyDown() for +// compatibility here - if we used OnKeyDown(), the programs which process +// arrows themselves in their OnChar() would never get the message and like +// this they always have the priority +void wxScrolledWindow::OnChar(wxKeyEvent& event) +{ + int stx, sty, // view origin + szx, szy, // view size (total) + clix, cliy; // view size (on screen) + + ViewStart(&stx, &sty); + GetClientSize(&clix, &cliy); + GetVirtualSize(&szx, &szy); + + if( m_xScrollPixelsPerLine ) + { + clix /= m_xScrollPixelsPerLine; + szx /= m_xScrollPixelsPerLine; + } + else + { + clix = 0; + szx = -1; + } + if( m_yScrollPixelsPerLine ) + { + cliy /= m_yScrollPixelsPerLine; + szy /= m_yScrollPixelsPerLine; + } + else + { + cliy = 0; + szy = -1; + } + + int dsty; + switch ( event.KeyCode() ) + { + case WXK_PAGEUP: + case WXK_PRIOR: + dsty = sty - (5 * cliy / 6); + Scroll(-1, (dsty == -1) ? 0 : dsty); + break; + + case WXK_PAGEDOWN: + case WXK_NEXT: + Scroll(-1, sty + (5 * cliy / 6)); + break; + + case WXK_HOME: + Scroll(0, event.ControlDown() ? 0 : -1); + break; + + case WXK_END: + Scroll(szx - clix, event.ControlDown() ? szy - cliy : -1); + break; + + case WXK_UP: + Scroll(-1, sty - 1); + break; + + case WXK_DOWN: + Scroll(-1, sty + 1); + break; + + case WXK_LEFT: + Scroll(stx - 1, -1); + break; + + case WXK_RIGHT: + Scroll(stx + 1, -1); + break; + + default: + // not for us + event.Skip(); + } +} -- 2.45.2