scrlwing.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,388 行 · 第 1/3 页
CPP
1,388 行
GetScrollRect() );
}
}
}
void wxScrollHelper::EnableScrolling (bool x_scroll, bool y_scroll)
{
m_xScrollingEnabled = x_scroll;
m_yScrollingEnabled = y_scroll;
}
// Where the current view starts from
void wxScrollHelper::GetViewStart (int *x, int *y) const
{
if ( x )
*x = m_xScrollPosition;
if ( y )
*y = m_yScrollPosition;
}
#if WXWIN_COMPATIBILITY_2_2
void wxScrollHelper::ViewStart(int *x, int *y) const
{
GetViewStart( x, y );
}
#endif // WXWIN_COMPATIBILITY_2_2
void wxScrollHelper::DoCalcScrolledPosition(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 wxScrollHelper::DoCalcUnscrolledPosition(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 wxScrollHelper::HandleOnSize(wxSizeEvent& WXUNUSED(event))
{
if ( m_targetWindow->GetAutoLayout() )
{
wxSize size = m_targetWindow->GetBestVirtualSize();
// This will call ::Layout() and ::AdjustScrollbars()
m_win->SetVirtualSize( size );
}
else
{
AdjustScrollbars();
}
}
// This calls OnDraw, having adjusted the origin according to the current
// scroll position
void wxScrollHelper::HandleOnPaint(wxPaintEvent& WXUNUSED(event))
{
// don't use m_targetWindow here, this is always called for ourselves
wxPaintDC dc(m_win);
DoPrepareDC(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 wxScrollHelper::HandleOnChar(wxKeyEvent& event)
{
int stx, sty, // view origin
szx, szy, // view size (total)
clix, cliy; // view size (on screen)
GetViewStart(&stx, &sty);
GetTargetSize(&clix, &cliy);
m_targetWindow->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 xScrollOld = m_xScrollPosition,
yScrollOld = m_yScrollPosition;
int dsty;
switch ( event.GetKeyCode() )
{
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();
}
if ( m_xScrollPosition != xScrollOld )
{
wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBTRACK, m_xScrollPosition,
wxHORIZONTAL);
event.SetEventObject(m_win);
m_win->GetEventHandler()->ProcessEvent(event);
}
if ( m_yScrollPosition != yScrollOld )
{
wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBTRACK, m_yScrollPosition,
wxVERTICAL);
event.SetEventObject(m_win);
m_win->GetEventHandler()->ProcessEvent(event);
}
}
// ----------------------------------------------------------------------------
// autoscroll stuff: these functions deal with sending fake scroll events when
// a captured mouse is being held outside the window
// ----------------------------------------------------------------------------
bool wxScrollHelper::SendAutoScrollEvents(wxScrollWinEvent& event) const
{
// only send the event if the window is scrollable in this direction
wxWindow *win = (wxWindow *)event.GetEventObject();
return win->HasScrollbar(event.GetOrientation());
}
void wxScrollHelper::StopAutoScrolling()
{
#if wxUSE_TIMER
if ( m_timerAutoScroll )
{
delete m_timerAutoScroll;
m_timerAutoScroll = (wxTimer *)NULL;
}
#endif
}
void wxScrollHelper::HandleOnMouseEnter(wxMouseEvent& event)
{
StopAutoScrolling();
event.Skip();
}
void wxScrollHelper::HandleOnMouseLeave(wxMouseEvent& event)
{
// don't prevent the usual processing of the event from taking place
event.Skip();
// when a captured mouse leave a scrolled window we start generate
// scrolling events to allow, for example, extending selection beyond the
// visible area in some controls
if ( wxWindow::GetCapture() == m_targetWindow )
{
// where is the mouse leaving?
int pos, orient;
wxPoint pt = event.GetPosition();
if ( pt.x < 0 )
{
orient = wxHORIZONTAL;
pos = 0;
}
else if ( pt.y < 0 )
{
orient = wxVERTICAL;
pos = 0;
}
else // we're lower or to the right of the window
{
wxSize size = m_targetWindow->GetClientSize();
if ( pt.x > size.x )
{
orient = wxHORIZONTAL;
pos = m_xScrollLines;
}
else if ( pt.y > size.y )
{
orient = wxVERTICAL;
pos = m_yScrollLines;
}
else // this should be impossible
{
// but seems to happen sometimes under wxMSW - maybe it's a bug
// there but for now just ignore it
//wxFAIL_MSG( _T("can't understand where has mouse gone") );
return;
}
}
// only start the auto scroll timer if the window can be scrolled in
// this direction
if ( !m_targetWindow->HasScrollbar(orient) )
return;
#if wxUSE_TIMER
delete m_timerAutoScroll;
m_timerAutoScroll = new wxAutoScrollTimer
(
m_targetWindow, this,
pos == 0 ? wxEVT_SCROLLWIN_LINEUP
: wxEVT_SCROLLWIN_LINEDOWN,
pos,
orient
);
m_timerAutoScroll->Start(50); // FIXME: make configurable
#else
wxUnusedVar(pos);
#endif
}
}
#if wxUSE_MOUSEWHEEL
void wxScrollHelper::HandleOnMouseWheel(wxMouseEvent& event)
{
m_wheelRotation += event.GetWheelRotation();
int lines = m_wheelRotation / event.GetWheelDelta();
m_wheelRotation -= lines * event.GetWheelDelta();
if (lines != 0)
{
wxScrollWinEvent newEvent;
newEvent.SetPosition(0);
newEvent.SetOrientation(wxVERTICAL);
newEvent.SetEventObject(m_win);
if (event.IsPageScroll())
{
if (lines > 0)
newEvent.SetEventType(wxEVT_SCROLLWIN_PAGEUP);
else
newEvent.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN);
m_win->GetEventHandler()->ProcessEvent(newEvent);
}
else
{
lines *= event.GetLinesPerAction();
if (lines > 0)
newEvent.SetEventType(wxEVT_SCROLLWIN_LINEUP);
else
newEvent.SetEventType(wxEVT_SCROLLWIN_LINEDOWN);
int times = abs(lines);
for (; times > 0; times--)
m_win->GetEventHandler()->ProcessEvent(newEvent);
}
}
}
#endif // wxUSE_MOUSEWHEEL
// ----------------------------------------------------------------------------
// wxGenericScrolledWindow implementation
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxGenericScrolledWindow, wxPanel)
BEGIN_EVENT_TABLE(wxGenericScrolledWindow, wxPanel)
EVT_PAINT(wxGenericScrolledWindow::OnPaint)
END_EVENT_TABLE()
bool wxGenericScrolledWindow::Create(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name)
{
m_targetWindow = this;
#ifdef __WXMAC__
MacSetClipChildren( true ) ;
#endif
bool ok = wxPanel::Create(parent, id, pos, size, style|wxHSCROLL|wxVSCROLL, name);
return ok;
}
wxGenericScrolledWindow::~wxGenericScrolledWindow()
{
}
bool wxGenericScrolledWindow::Layout()
{
if (GetSizer() && m_targetWindow == this)
{
// 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);
GetSizer()->SetDimension(x, y, w, h);
return true;
}
// fall back to default for LayoutConstraints
return wxPanel::Layout();
}
void wxGenericScrolledWindow::DoSetVirtualSize(int x, int y)
{
wxPanel::DoSetVirtualSize( x, y );
AdjustScrollbars();
if (GetAutoLayout())
Layout();
}
// wxWindow's GetBestVirtualSize returns the actual window size,
// whereas we want to return the virtual size
wxSize wxGenericScrolledWindow::GetBestVirtualSize() const
{
wxSize clientSize( GetClientSize() );
if (GetSizer())
{
wxSize minSize( GetSizer()->CalcMin() );
return wxSize( wxMax( clientSize.x, minSize.x ), wxMax( clientSize.y, minSize.y ) );
}
else
return clientSize;
}
// return the size best suited for the current window
// (this isn't a virtual size, this is a sensible size for the window)
wxSize wxGenericScrolledWindow::DoGetBestSize() const
{
wxSize best;
if ( GetSizer() )
{
wxSize b = GetSizer()->GetMinSize();
// Only use the content to set the window size in the direction
// where there's no scrolling; otherwise we're going to get a huge
// window in the direction in which scrolling is enabled
int ppuX, ppuY;
GetScrollPixelsPerUnit(& ppuX, & ppuY);
wxSize minSize;
if ( GetMinSize().IsFullySpecified() )
minSize = GetMinSize();
else
minSize = GetSize();
if (ppuX > 0)
b.x = minSize.x;
if (ppuY > 0)
b.y = minSize.y;
best = b;
}
else
return wxWindow::DoGetBestSize();
// Add any difference between size and client size
wxSize diff = GetSize() - GetClientSize();
best.x += wxMax(0, diff.x);
best.y += wxMax(0, diff.y);
return best;
}
void wxGenericScrolledWindow::OnPaint(wxPaintEvent& event)
{
// the user code didn't really draw the window if we got here, so set this
// flag to try to call OnDraw() later
m_handler->ResetDrawnFlag();
event.Skip();
}
#ifdef __WXMSW__
WXLRESULT
wxGenericScrolledWindow::MSWWindowProc(WXUINT nMsg,
WXWPARAM wParam,
WXLPARAM lParam)
{
WXLRESULT rc = wxPanel::MSWWindowProc(nMsg, wParam, lParam);
#ifndef __WXWINCE__
// we need to process arrows ourselves for scrolling
if ( nMsg == WM_GETDLGCODE )
{
rc |= DLGC_WANTARROWS;
}
#endif
return rc;
}
#endif // __WXMSW__
#endif // !wxGTK
// vi:sts=4:sw=4:et
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?