git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10795 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
275 lines
7.8 KiB
C++
275 lines
7.8 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/univ/scrarrow.cpp
|
|
// Purpose: wxScrollArrows class implementation
|
|
// Author: Vadim Zeitlin
|
|
// Modified by:
|
|
// Created: 22.01.01
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ============================================================================
|
|
// declarations
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// headers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#ifdef __GNUG__
|
|
#pragma implementation "univscrarrow.h"
|
|
#endif
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#ifndef WX_PRECOMP
|
|
#endif
|
|
|
|
#include "wx/univ/scrtimer.h"
|
|
#include "wx/univ/scrarrow.h"
|
|
|
|
#include "wx/univ/renderer.h"
|
|
#include "wx/univ/inphand.h"
|
|
#include "wx/univ/theme.h"
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxScrollArrowCaptureData: contains the data used while the arrow is being
|
|
// pressed by the user
|
|
// ----------------------------------------------------------------------------
|
|
|
|
struct wxScrollArrowCaptureData
|
|
{
|
|
wxScrollArrowCaptureData()
|
|
{
|
|
m_arrowPressed = wxScrollArrows::Arrow_None;
|
|
m_window = NULL;
|
|
m_btnCapture = -1;
|
|
m_timerScroll = NULL;
|
|
}
|
|
|
|
~wxScrollArrowCaptureData()
|
|
{
|
|
if ( m_window )
|
|
m_window->ReleaseMouse();
|
|
|
|
delete m_timerScroll;
|
|
}
|
|
|
|
// the arrow being held pressed (may be Arrow_None)
|
|
wxScrollArrows::Arrow m_arrowPressed;
|
|
|
|
// the mouse button which started the capture (-1 if none)
|
|
int m_btnCapture;
|
|
|
|
// the window which has captured the mouse
|
|
wxWindow *m_window;
|
|
|
|
// the timer for generating the scroll events
|
|
wxScrollTimer *m_timerScroll;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxScrollArrowTimer: a wxScrollTimer which calls OnArrow()
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class wxScrollArrowTimer : public wxScrollTimer
|
|
{
|
|
public:
|
|
wxScrollArrowTimer(wxControlWithArrows *control,
|
|
wxScrollArrows::Arrow arrow)
|
|
{
|
|
m_control = control;
|
|
m_arrow = arrow;
|
|
|
|
StartAutoScroll();
|
|
}
|
|
|
|
protected:
|
|
virtual bool DoNotify()
|
|
{
|
|
return m_control->OnArrow(m_arrow);
|
|
}
|
|
|
|
wxControlWithArrows *m_control;
|
|
wxScrollArrows::Arrow m_arrow;
|
|
};
|
|
|
|
// ============================================================================
|
|
// implementation of wxScrollArrows
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// con/destruction
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxScrollArrows::wxScrollArrows(wxControlWithArrows *control)
|
|
{
|
|
m_control = control;
|
|
m_captureData = NULL;
|
|
}
|
|
|
|
wxScrollArrows::~wxScrollArrows()
|
|
{
|
|
// it should have been destroyed
|
|
wxASSERT_MSG( !m_captureData, _T("memory leak in wxScrollArrows") );
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// drawing
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxScrollArrows::DrawArrow(Arrow arrow,
|
|
wxDC& dc,
|
|
const wxRect& rect,
|
|
bool scrollbarLike) const
|
|
{
|
|
static const wxDirection arrowDirs[2][Arrow_Max] =
|
|
{
|
|
{ wxLEFT, wxRIGHT },
|
|
{ wxUP, wxDOWN }
|
|
};
|
|
|
|
void (wxRenderer::*pfn)(wxDC&, wxDirection, const wxRect&, int) =
|
|
scrollbarLike ? &wxRenderer::DrawScrollbarArrow
|
|
: &wxRenderer::DrawArrow;
|
|
|
|
(m_control->GetRenderer()->*pfn)
|
|
(
|
|
dc,
|
|
arrowDirs[m_control->IsVertical()][arrow],
|
|
rect,
|
|
m_control->GetArrowState(arrow)
|
|
);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// input handling
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxScrollArrows::UpdateCurrentFlag(Arrow arrow, Arrow arrowCur) const
|
|
{
|
|
m_control->SetArrowFlag(arrow, wxCONTROL_CURRENT, arrow == arrowCur);
|
|
}
|
|
|
|
bool wxScrollArrows::HandleMouseMove(const wxMouseEvent& event) const
|
|
{
|
|
Arrow arrow;
|
|
if ( event.Leaving() )
|
|
{
|
|
// no arrow has mouse if it left the window completely
|
|
arrow = Arrow_None;
|
|
}
|
|
else // Moving() or Entering(), treat them the same here
|
|
{
|
|
arrow = m_control->HitTest(event.GetPosition());
|
|
}
|
|
|
|
if ( m_captureData )
|
|
{
|
|
// the mouse is captured, we may want to pause scrolling if it goes
|
|
// outside the arrow or to resume it if we had paused it before
|
|
wxTimer *timer = m_captureData->m_timerScroll;
|
|
if ( !timer->IsRunning() )
|
|
{
|
|
// timer is paused
|
|
if ( arrow == m_captureData->m_arrowPressed )
|
|
{
|
|
// resume now
|
|
m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, TRUE);
|
|
timer->Start();
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
else if ( 1 ) //FIXME: m_control->ShouldPauseScrolling() )
|
|
{
|
|
// we may want to stop it
|
|
if ( arrow != m_captureData->m_arrowPressed )
|
|
{
|
|
// stop as the mouse left the arrow
|
|
m_control->SetArrowFlag(m_captureData->m_arrowPressed,
|
|
wxCONTROL_PRESSED, FALSE);
|
|
timer->Stop();
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// reset the wxCONTROL_CURRENT flag for the arrows which don't have the
|
|
// mouse and set it for the one which has
|
|
UpdateCurrentFlag(Arrow_First, arrow);
|
|
UpdateCurrentFlag(Arrow_Second, arrow);
|
|
|
|
// return TRUE if it was really an event for an arrow
|
|
return !event.Leaving() && arrow != Arrow_None;
|
|
}
|
|
|
|
bool wxScrollArrows::HandleMouse(const wxMouseEvent& event) const
|
|
{
|
|
int btn = event.GetButton();
|
|
if ( btn == -1 )
|
|
{
|
|
// we only care about button press/release events
|
|
return FALSE;
|
|
}
|
|
|
|
if ( event.ButtonDown() || event.ButtonDClick() )
|
|
{
|
|
if ( !m_captureData )
|
|
{
|
|
Arrow arrow = m_control->HitTest(event.GetPosition());
|
|
if ( arrow == Arrow_None )
|
|
{
|
|
// mouse pressed over something else
|
|
return FALSE;
|
|
}
|
|
|
|
if ( m_control->GetArrowState(arrow) & wxCONTROL_DISABLED )
|
|
{
|
|
// don't allow to press disabled arrows
|
|
return TRUE;
|
|
}
|
|
|
|
wxConstCast(this, wxScrollArrows)->m_captureData =
|
|
new wxScrollArrowCaptureData;
|
|
m_captureData->m_arrowPressed = arrow;
|
|
m_captureData->m_btnCapture = btn;
|
|
m_captureData->m_window = m_control->GetWindow();
|
|
m_captureData->m_window->CaptureMouse();
|
|
|
|
// start scrolling
|
|
m_captureData->m_timerScroll =
|
|
new wxScrollArrowTimer(m_control, arrow);
|
|
|
|
m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, TRUE);
|
|
}
|
|
//else: mouse already captured, nothing to do
|
|
}
|
|
// release mouse if the *same* button went up
|
|
else if ( m_captureData && (btn == m_captureData->m_btnCapture) )
|
|
{
|
|
Arrow arrow = m_captureData->m_arrowPressed;
|
|
|
|
delete m_captureData;
|
|
wxConstCast(this, wxScrollArrows)->m_captureData = NULL;
|
|
|
|
m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, FALSE);
|
|
}
|
|
else
|
|
{
|
|
// we don't process this
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|